Essentially in my scene I have an entity with laser controls and a raycaster in the following structure:
<a-scene>
<a-entity laser-controls raycaster ...>
<!--<a-entity id="inventory" ...> Could be inserted here-->
</a-entity>
<!--<a-entity id="inventory" ...> Could be inserted here-->
</a-scene>
My objective is to summon the inventory at the current x,y position of the laser line, I already have access to the point corresponding to the end of the laser line. I don't want the inventory to move from that position again. If I set the inventory to be the child of the raycaster it always moves with the line. If I set the inventory to be the child of the scene whilst setting it's position to the world coordinates of the point where it's supposed to be, it just does not work.
Approaches I've tried and failed:
And finally, my current approach (with code) that still fails
1.Convering the local coordinates of the line end to world coordinates
2.Appending inventory to scene
3.Converting the world coordinates from line end into local coordinates of the scene
4.Applying the position in 3 to the inventory
let v = this.emptyVec
v.copy(this.raycaster.components.line.data.end)
this.raycaster.object3D.localToWorld(v);
this.el.appendChild(inventoryNode) //this.el is the scene
this.el.object3D.worldToLocal(v);
const {x,y} = v
inventoryNode.object3D.position.set(x,y,inventoryZDistance)
TLDR: How do I set an entity to the position of the raycaster line end at the point in time I add it to the scene and have it remain in that position forever
Ended up finding a solution. This is running on the event listener for a controller click event (point being it doesn't need to run on every tick, it's run only once)
Set the position of the inventory from the world matrix of the dummy node with the setFromMatrixPosition() method
let dummyNode = document.createElement("a-entity")
dummyNode.setAttribute("id", "dummyinventory")
dummyNode.setAttribute("visible", false) //maybe unnecessary
const {x,y} = this.raycaster.components.line.data.end
dummyNode.object3D.position.set(x,y,inventoryZDistance)
this.raycaster.appendChild(dummyNode)
inventoryNode.setAttribute('look-at', "[camera]") //if you want inventory to face the camera
this.el.appendChild(inventoryNode)
setTimeout(()=>{
let newMatrix = dummyNode.object3D.matrixWorld
inventoryNode.object3D.position.setFromMatrixPosition(newMatrix)
},50) //give the world matrix of dummyNode some time to update, with no timeout sometimes fails
The same thought process could be applied if one wanted to spawn some entity where the user is looking by having the dummy node be a child of the camera instead of the raycaster