1
votes

I am using AR.js and have a sphere positioned in the marker component.

<body style="margin : 0px; overflow: hidden;">
    <a-scene vr-mode-ui="enabled: false" embedded="" arjs="sourceType: webcam; debugUIEnabled: false;">
        <a-marker markerhandler id="marker" emitevents="true" cursor="rayOrigin: mouse" preset="hiro">
            <a-sphere id="sphere" color="green" radius="0.3" position="0 1 0" ></a-sphere>
        </a-marker>
        <!-- use this <a-entity camera> to support multiple-markers, otherwise use <a-marker-camera> instead of </a-marker>-->
        <a-entity camera="" id="camera">
                <a-entity geometry="primitive: plane; height: 0.1; width: 0.1" position="0.4 -0.2 -1"
                material="color: gray; opacity: 0.5"></a-entity>
                <a-entity id="sphere-button" geometry="primitive: plane; height: 0.1; width: 0.1" position="-0.4 -0.2 -1"
                material="color: green; opacity: 0.5"></a-entity>
        </a-entity>
    </a-scene>  
  </body>

When #sphere-button is clicked, the sphere should dettach from and attach to the camera. During the relocation in the DOM, the position should stay the same, but it does not. I tried this:

let v = new THREE.Vector3();
v.copy(sphere.object3D.position);
sphere.object3D.localToWorld(v);
camera.object3D.worldToLocal(v);
sphere.parentNode.removeChild(entity);
camera.appendChild(sphere);
entity.setAttribute('position', v);

How do i correctly translate the position between the two parents a-camera and a-marker?

2
Have a look at .attach() and .detach() methods of THREE.SceneUtils.prisoner849
I get the error THREE.SceneUtils has been moved to /examples/js/utils/SceneUtils.jsThmsbrhn

2 Answers

3
votes

For reparenting, I'd do it at three.js level for now and not use the DOM. Detaching and attaching on DOM atm will re-init everything and would be a mess.

let v = new THREE.Vector3();
v.copy(sphere.object3D.position);
sphere.object3D.localToWorld(v);
camera.object3D.worldToLocal(v);
camera.object3D.add(sphere.object3D);
sphere.object3D.position.copy(v);
0
votes

I've tried a different approach, using object3D.attach (as suggested by @prisoner849 in a comment) to get the position, rotation, etc. of the Three object related to the intended parent, and then cloning the entity using that position, rotation,... under the intended parent (finally, removing the original entity).

You can have a look at a component implementing this approach in this answer to "AFrame: reparenting an element keeping its world position, rotation".