I'm setting up augmented reality with AR.js, and I'm trying to get the camera/scene to be oriented to due North when the page loads.
Short example is that I'm trying to create a view that has a virtual compass with North/East/South/West displayed to the user.
I've got it working to a certain extent so far, but the calibration seems a little off at times. I'm using a MEAN stack and AR.js
Here's what I have:
view.html:
<a-scene embedded arjs='sourceType: webcam; debugUIEnabled: false;'>
<a-entity id="camera-entity" wasd-controls-enabled="false" position="0 -2 0" rotation="0 0 0" aframe-injected="">
<a-camera></a-camera>
</a-entity>
<a-text font="kelsonsans" width="6" position="0 0 -3.5" rotation="0 0 0" text="" value="North"></a-text>
</a-scene>
angular client controller (this section running only once on initialization):
var compass = event.webkitCompassHeading;
document.querySelector('#camera-entity').object3D.rotation.y = THREE.Math.degToRad(-compassdir);
Am I doing something incorrect with how I'm setting rotation on the camera-entity? Is there a better way to do this? Any suggestions?
I have compass bearing outputting to my development display, and it appears that the hardware is getting compass readings correctly.
Hardware: iPhone X
Reference:
Also, see this for reference regarding how aframe orients to relative phone position when opening:
https://github.com/aframevr/aframe/issues/349
And this for reference about a-frame rotation:
https://aframe.io/docs/0.8.0/components/rotation.html
If you want your items on the marker to be oriented compass-wise, then I'd suggest rotating the scene, not messing with the camera
<a-marker>
<a-entity id='parent' rotate-this-with-the-compass-readings>
<!-- Everything you want to rotate northwise --!>
</a-entity
</a-marker>
Preferably, with a aframe component, to be sure the element is ready:
AFRAME.registerComponent("rotate-this-with-the-compass-readings", {
init: function() {
var compassdir // however you get the compass reading
var pos = this.el.getAttribute('position')
pos.y = THREE.Math.degToRad(-compassdir);
this.el.setAttribute('position', pos)
}
})
Related
When looking at a model in aframe I see strange squares on gltf model.
I try to make an AR HTML to scan a marker and show model on top of it. When I check the model in gltf viewer online it's fine but looking through the webapp it has grey squares on it. Has anyone seen this before?
<a-scene embedded
vr-mode-ui="enabled: false"
shadow="type: pcf"
arjs='sourceType: webcam; sourceWidth:1280; sourceHeight:960;
displayWidth: 1280; displayHeight: 960; debugUIEnabled: false;'>
<!-- add your models -->
<a-asset-item id="animated-asset"
src="https://artshirtsonline.com/shanatova/models/test2.gltf" >
</a-asset-item>
</a-assets>
<a-entity animation-mixer="loop: repeat" gltf-model='#animated-asset'
scale="1 1 1"
shadow="cast: true"
rotation="-90 0 0"></a-entity>
Look up shadowMap.bias
You can adjust it to tune for shadow acne. Also make sure your shadow camera near and far closely match what your scene covers.
I'm attempting to make a rolodex menu in Aframe like this.
Here is the glitch so far https://glitch.com/edit/#!/fourth-kitten
I'm trying to get the entity to rotate into view with the camera
AFRAME.registerComponent('rotate-with-camera', {
tick: function (){
console.log(this)
if(this.el.sceneEl.camera){
const {rotation} = this.el.sceneEl.camera.parent
const containerRotation = this.el.getAttribute('rotation')
this.el.setAttribute('rotation', {...containerRotation, z: containerRotation.y -= rotation._y * 360})
}
}
})
However I can't get a nice smooth roll like this example and I'm confused as to the right maths to get it staying in front of the camera on roll up or roll down to make the next row animate into view.
Any ideas?
If you want to position it in front of the camera, then just use the parent - child DOM hierarchy:
<a-camera>
<a-entity position="0 0 -3></a-entity>
</a-camera>
This way your menu will be in front of the camera, and will be rotating with the camera.
To access outer elements, you can move the container a bit when the camera is looking right - left
Glitch here.
In the scene, I have two boxes. I am trying to make one box cloning the other one's rotation angle in real time.
<a-entity id="original" mixin="cube" position="0 1.6 -1" material="color: red" sleepy collision-filter="group: red; collidesWith: default, hands, blue" rotation="0 0 0">
<a-entity id="clone" mixin="cube" position="2 1.6 -1" material="color: blue" sleepy
collision-filter="group: blue; collidesWith: default, red" rotation="0 0 0">
I can see that the property of a cloned box updates correctly through console.log(), but in the scene the box does not change its angle. What am I missing?
The code below is my attempt to make it work.
var check = document.querySelector('.controllers');
var ori = document.getElementById('original');
var clo = document.getElementById('clone');
check.addEventListener('xbuttondown', () => {
var ori_pos = ori.getAttribute("rotation");
//console.log(ori_pos.x);
clo.object3D.rotation.set(
THREE.Math.degToRad(ori_pos.x),
THREE.Math.degToRad(ori_pos.y),
THREE.Math.degToRad(ori_pos.z)
);
console.log(clo.getAttribute("rotation"));
});
From the A-Frame FAQ: To improve performance, A-Frame does not update the HTML to save on stringification operations. This also means mutation observations will not fire. Use the debug component or .flushToDOM methods if you need to sync to the DOM
I'd like to draw a primitive where the Raycaster or the remote is pointing. I am searching for some kind of "get Orientation" method in aframe or three.js. Is there a simple and fast way to get the world coordinates, where my controller is pointing?
Thanks in advance!
Update:
Here's the code:
HTML:
[...]
<a-entity id="remote" daydream-controller raycaster="objects: .selectable">
<a-cone id="ray" color="cyan" position="0 0 -2" rotation="-90 0 0" radius bottom="0.005" radius-top="0.001" height="4"></a-cone>
<a-box id="position-guide" visible="false" position="0 0 -2"></a-box>
</a-entity
Here is the javascript to the HTML:
var rayEl = document.querySelector('#remote');
rayEl.addEventListener(
var rayElDirection = new THREE.Vector3(0,0,-1);
rayEl.object3D.getWorldDirection(rayElDirection);
console.log("Raycaster Direction: " + rayElDirection);
For getting daydream data loaded to an Object3D, I found a PR that i'm not sure is in the current build, but you could probably just load this as its own script, so long as it loads after three.js.
Once you have that, you can get the orientation of the controller - since it extends THREE.Object
You can check out Object3D's documentation to find available functions. THREE.Object.getWorldDirection() would give you a vector of where the Daydream controller is pointed.
Combine that with .getWorldPosition(), and you could, for example put a representation of the controller at that position in the scene for debugging purposes.
In a a-scene, I try to change my camera position at runtime. The DOM property changes but the camera does not move.
What could have I missed ?
my js code:
document.querySelector('#myCameraPosition').setAttribute('position', '0 0 0');
My a-scene:
<a-entity id="myCameraPosition" position="0 0 50">
<a-entity id="myCamera" camera look-controls keyboard-controls>
</a-entity>
</a-entity>
Create a wrapper entity around the camera:
<a-entity id='cameraWrapper' position="0 0 0">
<a-camera></a-camera>
</a-entity>
Then change position of the wrapper:
document.querySelector("#cameraWrapper").object3D.position.set(1, 1, 1);
Had to set "look-controls" to false for javascript rotation control, otherwise wouldn't work :
function resetView(el){
el.setAttribute('look-controls','false');
el.setAttribute('rotation',{x:0,y:0,z:0});
el.setAttribute('look-controls','true');
}
On the example below I can change the position of the camera entity's parent and it works as expected:
https://aframe.io/examples/showcase/helloworld/
Is any of the openearthview or acceleration components writing the position of the camera entitiy's parent? They might be overwritting its position.
document.getElementById('myCameraPosition').setAttribute('position', {x:0, y:0, z:0});
or
document.querySelector('#myCameraPosition').setAttribute('position', {x:0, y:0, z:0});
When it comes to position you can directly change the camera position(unlike rotation where you need a wrapper entity).
so
document.getElementById('myCameraPosition').setAttribute('position', {x:0, y:0, z:0});
should work