webVR starter kit: how to make a focus point in Panoramic Viewer - webvr

I am trying to build a VR tour using WebVR starter kit:
Web VR Starter Kit
Web VR Starter Kit is a Javascript library for easily creating virtual reality content and making it available in web browsers on a range of devices. The library includes a simplified API for creating an manipulating 3D objects.
My Code on JS bin
var mark1 = VR.torus({radius:0.2,
tube:0.01,
color:"#efe2a2",
});
var focus = VR.torus({radius:0.02,
tube:0.01,
color:"white",
});
var img1 = "//i.imgur.com/Rp4hJKX.jpg?1";
var img2 = "http://blog.topazlabs.com/wp-content/uploads/2013/07/Screen-Shot-2013-12-11-at-10.42.18-AM.png"
var img3 = "https://i1.wp.com/www.samrohn.com/wp-content/uploads/tobacco-warehouse-panorama.jpg?fit=1000%2C500";
var imgs = [img1, img2, img3];
var i = 0;
mark1.moveTo(0,0,0);
focus.moveTo(0,1.5,0);
focus.parent=VR.body;
VR.panorama(imgs[i]);
VR.on('lookat', function(target){
if (target === mark1.object)
i = (i+1)%3;
VR.vibrate(250);
VR.panorama(imgs[i]);
});
If the player is looking at mark1, VR panoramic image will switch to the next.I try to create a focus point that indicate where the player is looking at. but I don't know how to parent the focus object (small white torus) to the camera.

var focus = VR.camera.torus({radius:0.02,
tube:0.01,
color:"white",
});
This is the way to create a child from the parent camera.
var focus = VR.camera.torus

Related

Cannot remove Object3D objects from the scene

I'm working on an augmented reality app.
I'm developing the app on top of this open source available. (https://github.com/jeromeetienne/threex.webar/blob/master/examples/basic.html)
In the above open source, when any number of markers are shown to the camera, only one image is augmented on top of it irrespective of the markers. In my scenario, I want to make one marker to be specific to one image ie., every time a marker is shown, the image specific to that marker should be augmented.
I have the following code written to meet the scenario requirement.
var markerObjects = [];
var images = ['images/cadbury.png','images/kitkat.png','images/gems.png']
for ( i=265,j=0;i<268,j<images.length;i++,j++ ) {
markerObjects.push({id:i,image:images[j],Object3D: new THREE.Object3D()})
}
markerObjects.forEach(function(objects) {
objects.Object3D.visible = false ;
})
detectMarkersStats.begin();
var markers = jsArucoMarker.detectMarkers(domElement)
detectMarkersStats.end();
markers.forEach(function(marker) {
markerObjects.forEach(function(markerObject) {
if( marker.id == markerObject.id ) {
var material = new THREE.SpriteMaterial({
map: THREE.ImageUtils.loadTexture( markerObject.image ),
});
var object3d = new THREE.Sprite(material);
object3d.scale.set( 2, 2, 1 );
markerObject.Object3D.add(object3d);
jsArucoMarker.markerToObject3D(marker, markerObject.Object3D)
scene.add( markerObject.Object3D );
markerObject.Object3D.visible = true;
}
});
});
The problem I'm facing is whenever I show a marker to camera, the image is augmented but the image remains on the scene when the marker is taken away from the camera. If multiple markers are shown, all the images are augmented but all of them remains on the scene. I want to remove those images from the scene once the markers are taken off from the camera.
Can you guys please help me to arrive at a solution?

drawWindow() broken with multiprocess Firefox (e10s)?

The Firefox drawWindow()-Function expects as first parameter a XUL content-window as provided by the low-level api tab utils.
However with the introduction of the multiprocess architecture in Firefox (codenamed electrolysis or e10s) directly accessing tabs via the low-level api is no longer possible. While there are compatibility shims available, it is explicitly stated that they do not support plattform APIs that expect DOM objects.
On the other hand drawWindow() cannot be used in a content script since it is "chrome only".
So my questions are these:
How am I supposed to use drawWindow() if I cannot use it outside of chrome and cannot get a contentWindow-object within chrome?
What are my other options to let my addon take screenshots of websites within multiprocess Firefox?
Our current approach is based on the answer to this SO question. However it will not work with multiprocess Firefox
The solution to using drawWindow() was indeed to use framescripts as Noitidart suggested in the comments. The framescript I use for the screenshots looks like this:
addMessageListener("fs/make_screenshot_from_rectangle", makeScreenshot);
function makeScreenshot(payload) {
var rectangle = payload.data;
var startX = rectangle.startX || 0;
var startY = rectangle.startY || 0;
var width = rectangle.width || content.innerWidth;
var height = rectangle.height || content.innerHeight;
// Create canvas to draw window unto
var canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = width;
canvas.height = height;
// Create context for drawing, draw the old window unto the canvas
var context = canvas.getContext("2d");
context.drawWindow(content, startX, startY, width, height, "rgb(255,255,255)");
// Save context as png
var image = canvas.toDataURL('image/png');
sendAsyncMessage("got-screenshot", image);
}
And it is called from a chrome-script with the following function:
function (rectangle) {
var tab = require("sdk/tabs").activeTab;
var xulTab = require("sdk/view/core").viewFor(tab);
var xulBrowser = require("sdk/tabs/utils").getBrowserForTab(xulTab);
var browserMM = xulBrowser.messageManager;
if ( /* framescript not yet attached to tab */ ) {
browserMM.loadFrameScript(require("sdk/self").data.url("content-scripts/frame-script.js"), false);
... // do something to remember that there is a framescript attached to the tab
browserMM.addMessageListener("got-screenshot", function (payload) {
... // handle the screenshot
});
}
browserMM.sendAsyncMessage('fs/make_screenshot_from_rectangle', rectangle);
}
Relevant reading:
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Multiprocess_Firefox_and_the_SDK
https://developer.mozilla.org/en-US/Firefox/Multiprocess_Firefox/Message_Manager/Message_manager_overview#Browser_messa

Hubtile.Title upside down

I'm using the HubTile control from the silverlight toolkit and somehow the title is displayed upside down in my own app, but also in the preview. See Screenshots below.
I'm generating the tile from code behind and adding it to a WrapPanel control:
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(stream);
var hubtile = new HubTile()
{
Source = bitmap,
Height = AppConfig.TileHeight,
Width = AppConfig.TileWidth,
Background = App.Current.Resources["PhoneAccentBrush"] as SolidColorBrush,
Margin = new Thickness(5),
IsFrozen = true,
Title = "Lorem Ipsum"
};
wpTiles.Children.Add(hubtile);
The upside down part is the back of the tile.
It is visible because you haven't set a background to the front of the tile.
Be sure to set the background of the front and back of the tile (to something that isn't transparent) to avoid this scenario.

html5: copy a canvas to image and back

I implemented a zoom in and out function on a canvas element.
it works by scaling the canvas, translating it, and then redraw the whole scene again.
the problem is that it takes a lot of time to redraw everything because i got a lot of things on my canvas.
I need a way to copy the canvas to an image object and than copy the image back to the canvas without loosing quality. what are the specific methods to copy canvas to a javascript variable, and to to copy this variable back to the canvas later?
I'll be glad if you write down the code because I couldn't find any good explanation over the internet.
thanks,
The drawImage() method can draw to a canvas using another canvas instead of an image.
You could create a 'backup' canvas, of the same size as your original, draw the first one to there and then draw that one back to the original when you need it.
e.g.
// Assume we have a main canvas
// canvas = <main canvas>
ctx = canvas.getContext('2d');
..
// create backing canvas
var backCanvas = document.createElement('canvas');
backCanvas.width = canvas.width;
backCanvas.height = canvas.height;
var backCtx = backCanvas.getContext('2d');
// save main canvas contents
backCtx.drawImage(canvas, 0,0);
..
// restore main canvas
ctx.drawImage(backCanvas, 0,0);
There are a few ways to do it theres the getImageData and putImageData methods Reference, However putImageData and getImageData are pretty slow. Another way is to save the data to an image in memory and recall it from that which is much faster, then the third way is the one above mentioned by andrewmu which involves copying to another canvas element. I have included examples for the first and second type.
Image in memory method
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
savedData = new Image();
function save(){
// get the data
savedData.src = canvas.toDataURL("image/png");
}
function restore(){
// restore the old canvas
ctx.drawImage(savedData,0,0)
}
getImageData putImageData method
// Setup our vars, make a new image to store the canvas data
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
canvasData = '';
function save(){
// get the data
canvasData = ctx.getImageData(0, 0, 100, 100);
}
function restore(){
// restore the old canvas
ctx.putImageData(canvasData, 0, 0);
}
added image into canvas
var image = new Image();
image.src = "1.jpg";
image.onload = function () {
context.drawImage(image, 0, 0);
};

Animation not working properly when three.js mixer clampwhenfinished method set true

I am trying to disassemble the gun using three.js. To do this I used an object modeled and I animized in 3dsmax. I have output them in Json 3D Loader format using cgdev json exporter.
My problem; I want to animate the charger, back and forward. I prepare an animation at 3ds max to insert the magazine and I played it, but I could not use a negative timescale because I used looponce to play back this animation. So I made the back animation in 3ds max as well, but when I use the clampwhenfinished = true code, the animation is not playing back exactly.
var step;
next ? step = animAssemble[iTween] : step = animDissamble[iTween];
var tween = new TWEEN.Tween(camera.position).to(step.camera, step.tCam);
tween.onUpdate(function () { camera.position = step.camera });
tween.start();
tween.onComplete(function () {
var mesh = meshes[step.gun], mixer = mixers[step.gun];
animation = mixer.clipAction(mesh.geometry.animations[step.i]);
animation.setLoop(THREE.LoopOnce);
animation.clampWhenFinished = true;
animation.play();
anim = true;
});
Thanks.

Resources