How to fix grey squares showing on gltf model in a-frame? - three.js

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.

Related

Any way to handle more than one multimarker area in AR.js / A-Frame?

I'm trying to set-up more than one multi-marker area in AR.js with A-Frame. The idea is to have 4 pattern markers laid out as a square frame for each content.
The AR.js multimarker examples make use of the learner to put the pose matrix data in the URL. Is there any way to generate different multimarker files and assign them to each a-marker? I've attached some sample code to show what I'm trying to achieve.
<a-scene>
<a-marker preset="area" id="first">
...
</a-marker>
<a-marker preset="area" id="second">
...
</a-marker>
<a-marker preset="area" id="third">
...
</a-marker>
<a-camera />
</a-scene>
It seems the name of the localstorage item with the configuration object is hardcoded here.
I was able to get multiple marker areas, but i had to modify the ar.js code. The result is in this glitch, the markers are in the assets.
First, I had to create and keep the multimarker configuration objects (see this SO thread, or this ar.js issue on custom area markers). Before creating the scene i set the configs:
// the name will correspond to the marker id
var oneMarker = { /* paths, pose matrices, etc. */ }
localStorage.setItem("oneMarkerFile", JSON.stringify(oneMarker));
Second - I've modified the Arjs.Anchor object - so it won't read a predefined localStorageObject:
// originally ARjsMultiMarkerFile
let markerId = markerParameters.markerName + "MarkerFile"
Third - I have to pass the markerParameters.markerName somehow. The Arjs.Anchor object is created in the arjs-anchor component init function. With one line you can set the above markerName property:
markerParameters.markerName = _this.el.id
// anywhere before instantiating the anchor (new ARjs.Anchor(arSession, markerParameters))

AR.js trying to synchronize scene to compass north

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)
}
})

The property of the object does not update in the scene

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

Daydream Controller Orientation

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.

aframe - Set camera position at runtime

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

Resources