Babylon JS - SceneLoader from Local File - javascript

New Babylon JS user, looking to get up to speed with this fantastic framework. Have had a play with the Sandbox and online Editor, worked up my own coded model from scratch using the standard components - Box, Sphere etc. My question relates to how to get more complex custom geometry loaded. Very comfortable with 3D CAD - STL/OBJ files, got some exports going from Blender to .Babylon format which import great into Babylon's online Sandbox & Editors. However, I can't seem to get the SceneLoader going to read a file from local C:/ drive. Code extract below:
// Create new Babylon Scene
var scene = new BABYLON.Scene(engine);
// Change scene background color
scene.clearColor = new BABYLON.Color3(1, 1, 1);
// Create and positions a free camera
var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 10, 0), scene);
// Target the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());
// Attach camera to the canvas
camera.attachControl(canvas, true);
// Define built-in 'box' shape.
var box = BABYLON.Mesh.CreateBox("sphere1", 1, scene);
// Define 'ground' plane
var ground = BABYLON.Mesh.CreateGround("ground1", 100, 100, 100, scene);
ground.position.y = 0;
//Load local .babylon file from root Dir
BABYLON.SceneLoader.Load("", "Test.babylon", engine, scene);
My model has a standard box for geometry with ground plane. All renders great in Babylon - until I add the SceneLoader line. When I add this I get stuck on the Babylon Loading intro splash screen (rotating Babylon logo). If I comment out the last line of code above the model renders fine with the box.
Have had a look at various forum pages on this and wrecked my brain to point of being stuck e.g: http://www.html5gamedevs.com/topic/20924-stlobj-file-loader/ & https://www.eternalcoding.com/?p=313
I believe Google Chrome may be locking out local file links for security, have tried running in -Allow-Local-File-Access mode, still stuck on loading page. Do I need a web server (I wouldn't know where to start!) or can I run Babylon scenes locally?

First issue posed by OP: Browser is not loading mesh from file system.
Solution: Use a web server such as Simple HTTP Server (Python). The way to do this is slightly different depending on your Python version. To check Python version on Windows, open command prompt and type python --version. Remember the version number for later :)
Setting up simple web server with Python with command prompt:
Navigate to the directory with your index.html file in File Explorer
Left click on to a blank space inside the path box (where it says This PC > Documents, etc...)
Type cmd and it will open Command Prompt in the current directory
Enter the appropriate command...
python -m SimpleHTTPServer [optional port number] if you are using Python 2
python -m http.server [optional port number] if you are using Python 3
I usually leave out the port number and simply type python -m http.server.
Now open your preferred browser and enter localhost:8000 into your address bar. (8000 is the default port number. If you specified a port, use the number which you specified.) It should load your mesh if the code has no errors.
Second issue posed by OP: SceneLoader.Load method overrides previously loaded meshes.
Solution:
If you only need to import a few meshes, use either BABYLON.SceneLoader.Append(...) or BABYLON.SceneLoader.ImportMesh(...). However, this method is inconvenient for managing many assets.
Alternatively, use BABYLON.AssetsManager(...). Since Babylon.js loads models in asynchronously, the asset manager allows ease of use through callback functions. In other words, you can find your assets by name by using scene.getMeshByName("yourMesh") if you type inside the callback function. Here is a simple demo.
I know this question is a few years old, but in case anyone still has issues with this I hope this answer helps.

So I’m not 100% sure about this answer, but hopefully it will help. I followed this tutorial (Skip down to the section where the scene gets loaded). One issue is definitely the cross origin thing, the other how you call the SceneLoader.Load method.
When I try the code from the tutorial with regular Chrome I see three warnings in my web console. Two errors about Test.babylon.manifest (using your example file naming) and one about Test.babylon. You can ignore the ones regarding manifests afaik. The important one is the error about Test.babylon itself. So by default Cross origin requests are not allowed and the babylon file does not load (as expected).
Now, when I close Chrome and reopen it by running open -a "Google Chrome" --args --allow-file-access-from-files in the terminal (I’m on OSX Yosemite), and then load the page, the object loads fine. I still see two errors about manifests in the web console, but they can be ignored.
Note how the BABYLON.SceneLoader.Load function is being called. The import process is asynchronous, and the last parameter looks to be a callback function for what to do once the object has successfully loaded, so I don't think you can just pass scene as in your original code. Check out the function docs.

Ok - porgress.
I got it going using SceneLoader.ImportMesh but I had to setup a simple HTTP Server using Python (v3). This link helped a lot: http://www.linuxjournal.com/content/tech-tip-really-simple-http-server-python
So you run the Python HTTP server from the directory that the Babylon index.html is based in, and it runs as if HTTP bypassing local file access constraints in Chrome.
So my problem is all but answered. I now have my mesh geometry from the Test.Baylon file into my main scene. Still having issues using SceneLoader.Load as the new scene coming in supercedes my original scene and the original geometry disappears. David - I think you're right on the function being needed, although I thought this was optional. As I said, the Tutorial example creates a newScene and renders within the function, in my case I don't know what to do in the function... maybe just 'return'?

Related

Execute bat file on client machine through Javascript

We have a web page which lists our own custom zipped files(stored at cloud).
We want those files to be unzipped the moment user downloads it.
For unzipping process we have provided a console app to user which will be stored at a known location(say C:/ProgramFiles/Company/UnZip.exe) on client machine.
We will also be saving a batch file on the client machine to execute that console app with arguments to unzip the file.
We are aware this can be done on IE using ActiveXObject, but we need a cross browser solution.
Any help/alternative will be appreciated.
try {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); //this line is optional, you can pass extra information to the app with this code
startActivityForResult(intent, 0);
} catch (Exception e) {
Uri marketUri = Uri.parse("market://details?id=com.google.zxing.client.android");
Intent marketIntent = new Intent(Intent.ACTION_VIEW,marketUri);
startActivity(marketIntent);
}
There are a variety of approaches that can be taken to solve the same problem How To Start A New Application From Another Application? Examples. The remaining options will be discussed further down.
Intent i = new Intent(MainActivity.this, MakeKey.class);
startActivity(i);
finish();
As we have seen, the issue with the How To Start A New Application From Another Application? Examples variable was resolved by making use of a variety of distinct instances.
Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.30-Jul-2019
Step 2 − Add the following code to res/layout/activity_main. xml.30-Jul-2019
Sorry for copy paste, there are some ideas how to do it in android studio.

KineticJS: Kinetic warning: Unable to get data URL

I have two Kineticjs canvases and when trying to create an image in one canvas from the other canvas I get this error after calling toImage() on the canvas with the new image:
Kinetic warning: Unable to get data URL. Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported
I am pretty sure the reason why I am getting this error is because the "toImage()
method requires that the image is hosted on a web server with the same domain as the code executing it." How can I get around this warning so that I can create objects from one canvas and add them to another?
The app I am creating will run locally and will never run online so I don't have to worry about security issues. Also I read around that I can enable cross origin resource sharing but that seems a little complex and over the top since they require the setting up of a web server I think.
So is there any trick I can do to make one canvas able to create an image in another canvas for a Chrome kineticjs web app? And then being able to successfully call toImage()?
Here is how I am creating the image in the canvas:
var folderImage = new Image();
//folderImage.crossOrigin="anonymous"; // gives me file error if unchecked
folderImage.onload = function() {
var folderPic = new Kinetic.Image({
x: 0,
y: 0,
image: folderImage,
width: sideLen,
height: sideLen
});
subFolderGroup.add(folderPic);
subTextGroup.moveToTop();
mainBody4Dynamic.draw();
};
folderImage.src = 'assets/images/folder.png';
And when I call toImage() in the other layer all I am calling is the layer.toImage()
The browser treats the user's local drive as other-domain. That's good because you don't want your browser "getting friendly" with your banking records on your hard drive.
This means running locally with local images will taint the canvas (a CORS violation).
The simplest workaround is to install a web-server on your local machine and host the web-page plus images on a single domain. (=== automatic CORS compliance). PHP and IIS both work well on a dev machine.
Another workaround is complying with CORS restrictions by hosting your images on an internet imaging host that has configured its server to deliver images in a CORS compliant manor. Then all you have to do is add myImage.crossOrigin="anonymous". I believe dropbox.com does this--or they used to.
While in development, it sometimes works to put both your .html and your images on the desktop.

Send video stream from iOS7 camera to JavaScript Canvas in web view

First a word of caution: this question is not suitable for the faint of heart. It is an interesting challenge that I have encountered recently. See if you can solve it or help in any way to get closer to an answer, at your own risk.
Here is the problem: Create an iOS application with a standard UIWebView inside. Obtain camera stream from either camera. Send each frame in a format that can be rendered into an HTML5 canvas. Make this happen efficiently so that video stream can be displayed at 720p 30fps or higher in an iOS7 device.
So far I have not found any solution that look promissing. In fact I started with the solution that looked most ridiculus which is encoding each frame in a base64 image string and passing it to web view via stringByEvaluatingJavaScriptFromString. Here is the method that does the JPEG encoding
- (NSString *)encodeToBase64StringJPEG:(UIImage *)image {
return [UIImageJPEGRepresentation(image, 0.7) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
Inside the viewDidLoad I create and configure the capture session
_output = [[AVCaptureVideoDataOutput alloc] init];
// create a queue to run the capture on
dispatch_queue_t captureQueue=dispatch_queue_create("captureQueue", NULL);
// setup output delegate
[_output setSampleBufferDelegate:self queue:captureQueue];
// configure the pixel format (could this be the problem? Is this suitable for JPEG?
_output.videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA], (id)kCVPixelBufferPixelFormatTypeKey, nil];
[_session addOutput:_output];
[_session startRunning];
The frames are captured and converted to UIImage first.
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
_image = imageFromSampleBuffer(sampleBuffer);
// here comes the ridiculus part. Attempt to encode the whole image and send it to JS land:
_base64imgCmd = [NSString stringWithFormat:#"draw('data:image/png;base64,%#');", [self encodeToBase64StringJPEG:_image]];
[self.webView stringByEvaluatingJavaScriptFromString:_base64imgCmd];
}
Guess what, it did not work. XCode is showing me this error:
DemoNativeToJS[3983:1803] bool _WebTryThreadLock(bool), 0x15e9d460: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
1 0x355435d3 WebThreadLock
2 0x3013e2f9 <redacted>
3 0x7c3a1 -[igViewController captureOutput:didOutputSampleBuffer:fromConnection:]
4 0x2c5bbe79 <redacted>
Is this error because WebView is running our of memory qouta? I should note that there is a big spike in the app memory usage just before crash. It crashes anywhere between 14MB to above 20MB depending on what the quality level is set for JPEG encoding.
I do not want to render the camera stream in native -- that wont be an interesting problem at all. I want to pass the video feed to JavaScript land and draw it inside the canvas.
For your convenience I have a minimal demo project (XCode) on github that you can use to get a guick headstart:
git clone https://github.com/arasbm/DemoNativeToJS.git
Please let me know if you have other more sane ideas for passing the data through instead of using stringByEvaluatingJavaScriptFromString. If you have other ideas or suggestions feel free to let me know in comments, but I would expect the answer to demonstrate with some code what path will work.
The crash you are experiencing is due to UIWebKit attempting to call UIKit from a background thread. The easiest way to prevent this from happening is to force stringByEvaluatingJavaScriptFromString which is making the call to UIKit to run in the main thread. You can do this by changing
[self.webView stringByEvaluatingJavaScriptFromString:_base64imgCmd];
To this
[self.webView performSelectorOnMainThread:#selector(stringByEvaluatingJavaScriptFromString:) withObject:_base64imgCmd waitUntilDone:NO];
Which will now make the call to UIKit from the main execution thread, which will be safe.

Capture Browser Web Page [duplicate]

Is it possible to to take a screenshot of a webpage with JavaScript and then submit that back to the server?
I'm not so concerned with browser security issues. etc. as the implementation would be for HTA. But is it possible?
Google is doing this in Google+ and a talented developer reverse engineered it and produced http://html2canvas.hertzen.com/ . To work in IE you'll need a canvas support library such as http://excanvas.sourceforge.net/
I have done this for an HTA by using an ActiveX control. It was pretty easy to build the control in VB6 to take the screenshot. I had to use the keybd_event API call because SendKeys can't do PrintScreen. Here's the code for that:
Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Public Const CaptWindow = 2
Public Sub ScreenGrab()
keybd_event &H12, 0, 0, 0
keybd_event &H2C, CaptWindow, 0, 0
keybd_event &H2C, CaptWindow, &H2, 0
keybd_event &H12, 0, &H2, 0
End Sub
That only gets you as far as getting the window to the clipboard.
Another option, if the window you want a screenshot of is an HTA would be to just use an XMLHTTPRequest to send the DOM nodes to the server, then create the screenshots server-side.
Another possible solution that I've discovered is http://www.phantomjs.org/ which allows one to very easily take screenshots of pages and a whole lot more. Whilst my original requirements for this question aren't valid any more (different job), I will likely integrate PhantomJS into future projects.
Pounder's if this is possible to do by setting the whole body elements into a canvase then using canvas2image ?
http://www.nihilogic.dk/labs/canvas2image/
A possible way to do this, if running on windows and have .NET installed you can do:
public Bitmap GenerateScreenshot(string url)
{
// This method gets a screenshot of the webpage
// rendered at its full size (height and width)
return GenerateScreenshot(url, -1, -1);
}
public Bitmap GenerateScreenshot(string url, int width, int height)
{
// Load the webpage into a WebBrowser control
WebBrowser wb = new WebBrowser();
wb.ScrollBarsEnabled = false;
wb.ScriptErrorsSuppressed = true;
wb.Navigate(url);
while (wb.ReadyState != WebBrowserReadyState.Complete) { Application.DoEvents(); }
// Set the size of the WebBrowser control
wb.Width = width;
wb.Height = height;
if (width == -1)
{
// Take Screenshot of the web pages full width
wb.Width = wb.Document.Body.ScrollRectangle.Width;
}
if (height == -1)
{
// Take Screenshot of the web pages full height
wb.Height = wb.Document.Body.ScrollRectangle.Height;
}
// Get a Bitmap representation of the webpage as it's rendered in the WebBrowser control
Bitmap bitmap = new Bitmap(wb.Width, wb.Height);
wb.DrawToBitmap(bitmap, new Rectangle(0, 0, wb.Width, wb.Height));
wb.Dispose();
return bitmap;
}
And then via PHP you can do:
exec("CreateScreenShot.exe -url http://.... -save C:/shots domain_page.png");
Then you have the screenshot in the server side.
This might not be the ideal solution for you, but it might still be worth mentioning.
Snapsie is an open source, ActiveX object that enables Internet Explorer screenshots to be captured and saved. Once the DLL file is registered on the client, you should be able to capture the screenshot and upload the file to the server withing JavaScript. Drawbacks: it needs to register the DLL file at the client and works only with Internet Explorer.
We had a similar requirement for reporting bugs. Since it was for an intranet scenario, we were able to use browser addons (like Fireshot for Firefox and IE Screenshot for Internet Explorer).
This question is old but maybe there's still someone interested in a state-of-the-art answer:
You can use getDisplayMedia:
https://github.com/ondras/browsershot
The SnapEngage uses a Java applet (1.5+) to make a browser screenshot. AFAIK, java.awt.Robot should do the job - the user has just to permit the applet to do it (once).
And I have just found a post about it:
Stack Overflow question JavaScript code to take a screenshot of a website without using ActiveX
Blog post How SnapABug works – and what they should do
I found that dom-to-image did a good job (much better than html2canvas). See the following question & answer: https://stackoverflow.com/a/32776834/207981
This question asks about submitting this back to the server, which should be possible, but if you're looking to download the image(s) you'll want to combine it with FileSaver.js, and if you want to download a zip with multiple image files all generated client-side take a look at jszip.
You can achieve that using HTA and VBScript. Just call an external tool to do the screenshotting. I forgot what the name is, but on Windows Vista there is a tool to do screenshots. You don't even need an extra install for it.
As for as automatic - it totally depends on the tool you use. If it has an API, I am sure you can trigger the screenshot and saving process through a couple of Visual Basic calls without the user knowing that you did what you did.
Since you mentioned HTA, I am assuming you are on Windows and (probably) know your environment (e.g. OS and version) very well.
If you are willing to do it on the server side, there are options like PhantomJS, which is now deprecated. The best way to go would be Headless Chrome with something like Puppeteer on Node.JS. Capturing a web page using Puppeteer would be as simple as follows:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
However it requires headless chrome to be able to run on your servers, which has some dependencies and might not be suitable on restricted environments. (Also, if you are not using Node.JS, you might need to handle installation / launching of browsers yourself.)
If you are willing to use a SaaS service, there are many options such as
Restpack
UrlBox
Screenshot Layer
A great solution for screenshot taking in Javascript is the one by https://grabz.it.
They have a flexible and simple-to-use screenshot API which can be used by any type of JS application.
If you want to try it, at first you should get the authorization app key + secret and the free SDK
Then, in your app, the implementation steps would be:
// include the grabzit.min.js library in the web page you want the capture to appear
<script src="grabzit.min.js"></script>
//use the key and the secret to login, capture the url
<script>
GrabzIt("KEY", "SECRET").ConvertURL("http://www.google.com").Create();
</script>
Screenshot could be customized with different parameters. For example:
GrabzIt("KEY", "SECRET").ConvertURL("http://www.google.com",
{"width": 400, "height": 400, "format": "png", "delay", 10000}).Create();
</script>
That's all.
Then simply wait a short while and the image will automatically appear at the bottom of the page, without you needing to reload the page.
There are other functionalities to the screenshot mechanism which you can explore here.
It's also possible to save the screenshot locally. For that you will need to utilize GrabzIt server side API. For more info check the detailed guide here.
As of today Apr 2020 GitHub library html2Canvas
https://github.com/niklasvh/html2canvas
GitHub 20K stars | Azure pipeles : Succeeded | Downloads 1.3M/mo |
quote : " JavaScript HTML renderer The script allows you to take "screenshots" of webpages or parts of it, directly on the users browser. The screenshot is based on the DOM and as such may not be 100% accurate to the real representation as it does not make an actual screenshot, but builds the screenshot based on the information available on the page.
I made a simple function that uses rasterizeHTML to build a svg and/or an image with page contents.
Check it out :
https://github.com/orisha/tdg-screen-shooter-pure-js

How do I turn off the console logging in App Engine Channel API?

I've implemented the Channel API w/ persistence. When I make a channel and connect the socket (this is on the real app, not the local dev_appserver), Firebug goes nuts with log messages. I want to turn these off so I can see my OWN logs but cant find any documentation on how to disable the Channel API console logging.
one thing I'm probably doing differently than most is that I'm connecting cross-domain... which the Channel API supports (note the first message in the stream... if you can view that pic)
Does anyone know?
UPDATE
I finally realized that my code was creating two channels and trying to open/connect them both at the same time... and that was why I was getting a flood of messages. I didn't mean to do this (I know the rules: https://developers.google.com/appengine/docs/python/channel/overview#Caveats )... it was a bug... and once I fixed it, the messages went back to manageable level.
yay
There doesn't appear to be a way to shutoff the Firebug timeStamp log. One way to solve this problem is to edit the code and remove this functionality yourself:
Unpack the extension to a directory in your Mozilla Firefox Profile:
Change directory to your Firefox profile extensions directory. On Ubuntu, this would be something like this:
cd ~/.mozilla/firefox/{random-string}/extensions/
The Firebug extension is identified by firebug#software.joehewitt.com.xpi. Create a new directory of the same name, but without the .xpi, and move the XPI into that directory:
mkdir firebug#software.joehewitt.com
mv firebug#software.joehewitt.com.xpi firebug#software.joehewitt.com
Next, change directories to your newly created Firebug directory, and unpack the extension:
cd firebug#software.joehewitt.com
unzip firebug#software.joehewitt.com.xpi
All of the files should be unpacked so that the extension's directories are in the current directory. Your file structure will look something like this:
$: ~/.mozilla/firefox/{random-string}/extensions/firebug#software.joehewitt.com$ l
chrome.manifest defaults/ firebug#software.joehewitt.com.xpi install.rdf locale/ skin/
content/ docs/ icons/ license.txt modules/
$: ~/.mozilla/firefox/ghlfe0bb.ff5.0/extensions/firebug#software.joehewitt.com$
Open consoleExposed.js in your text editor:
Next, change to the content/firebug/console directory:
cd content/firebug/console
Edit the consoleExposed.js file using your favorite editor:
vim consoleExposed.js
Disable console.timeStamp:
On or near line 215, you'll see the following function:
console.timeStamp = function(label)
{
label = label || "";
if (FBTrace.DBG_CONSOLE)
FBTrace.sysout("consoleExposed.timeStamp; " + label);
var now = new Date();
Firebug.NetMonitor.addTimeStamp(context, now.getTime(), label);
var formattedTime = now.getHours() + ":" + now.getMinutes() + ":" +
now.getSeconds() + "." + now.getMilliseconds();
return logFormatted([formattedTime, label], "timeStamp");
};
Right after the first curly-brace, force the function to return nothing:
console.timeStamp = function(label)
{ return ; // disable timestamp by returning
label = label || "";
if (FBTrace.DBG_CONSOLE)
Restart Firefox and enjoy a world without timeStamp:
After the edits, restart Firebug. You should no longer see the log messages for timeStamp in your console.
On the Development server, when using the ChannelAPI, it essentially degrades into a polling implementation instead of using Comet/long-polling. Thus, in your debugger, you see an endless stream of HTTP requests made to the server to continuously and methodically check for updates.
In essence, these are just AJAX requests, or as Firebug would like to think of them, XMLHttpRequests.
Since your browser is responsible for making these requests, the only way to disable them is to click the small arrow on "Console" in Firebug and uncheck the option for logging XMLHttpRequests.
Of course, this also disables logging for all of your other XMLHttpRequests. But it's a small price to pay for the clarity and serenity of a quiet, well-behaved JavaScript console.
For more helpful information on how to make the most of Firebug, see Firebug Tips and Tricks.
NOTE: This works for both users of the Python SDK as well as the Java SDK. (or Go SDK, assuming it has an equivalent ChannelAPI). This is not limited to only Python Appengine.
UPDATE:
From getFirebug:
Creates a time stamp, which can be used together with HTTP traffic timing to measure when a certain piece of code was executed.
The console.timeStamp method was released in Firebug 1.8.0. The same technique described above can also override this Firebug logging method.
console.timeStamp("This is the type of console logging statement that Google is using!");
The above logging statement would produce the olive text. This method can be disabled using the same techniques which were described in the previous section.
However, Google loads the console object inside of a closure, which means that, once Google's code is initialized, the ChannelAPI object has it's own copy of the console object.
In order to disable console.timeStamp, one would need to disable it as the very first action before anything else loads or runs. in other words, we would need to ensure that Google only gets its hands on the disabled console.timeStamp method.
For best results, load this code above the /_ah/channel/jsapi script tag to ensure the console.timeStamp method is disabled before jsapi loads:
if(window.console) console.timeStamp = function(t) { };
NOTE: Because Google invokes Firebug logging in this manner, the only solution may very well in fact require a bug report or feature request that would allow for programmatically disabling this level of logging. Alternatively, the Firebug team could provide a new version of Firebug that includes the ability to explicitly disable timeStamp log statements, similar to how they've done so with Errors, Warnings, XMLHttpRequests, and other log levels.

Categories

Resources