How can I get the position of an instance in a rotated/transformed InstancedMesh?

When I define a simple InstancedMesh consisting on a single instance, I can easily get the position of the instance (in this case, defined by the corner where the red, green and blue planes intersect):

Screenshot from 2022-09-13 03-16-02

However, after I mesh.rotateOnWorldAxis() and mesh.applyQuaternion() I am unable to calculate the coordinates of that same vertex:

Screenshot from 2022-09-13 03-16-17

Here is a Fiddle with the code example:

I am assuming the rotation/transformation is performed in the GPU, and that is why the coordinates of that vertex are not directly accessible, and a transformation is required.

Initially, I get the intersection from the InstancedMesh array:

intersection = new THREE.Vector3(
    mesh.instanceMatrix.array[12],
    mesh.instanceMatrix.array[13],
    mesh.instanceMatrix.array[14],
)

Which gives me the correct coordinates before the mesh is rotated/transformed.

Then I tried applying:

intersection.applyMatrix4(mesh.matrixWorld)

But that didn’t work.

How could I calculate the position of that intersection point?

Note I would like to avoid using the knowledge of the specific transformations that were performed. In this case there are only two operations performed (mesh.rotateOnWorldAxis() and mesh.applyQuaternion()), but there could be more, the order could vary and the specific matrices used for the transformations could be unknown. So the goal is to get the intersection point only with the information that is stored in the mesh attributes after all transformations are performed (if possible). :blush:

Just add mesh.updateMatrixWorld(); before you apply this matrix to the intersection point. See forked fiddle, which illustrates the outcome.

1 Like

So simple, thanks! :smile:

No problem, glad to help. It’s important that this method is taken into consideration each time you want to get the updated “properties” of an object, including the camera. The update can be forced as well, if needed, by using it like mesh.updateMatrixWorld(true);, by the way.

1 Like

Thanks for the tip! :blush:

By the way, I am now trying to get the position of all the 4 vertices in the blue face (the rotated/transformed instance). Do you have an idea on what is the easiest way to do that? Otherwise I’ll keep investigating and, if I get stuck, I may ask a separate question.

I am guessing I should apply the same updateMatrixWorld to the other 3 vertices of the instance’s blue face before the transformation. But how to get those other 3 vertices is the question then… (the first vertex is easy since it matches the instance position, but the others have their own transformation matrix and not sure if I can access the instanced mesh somehow) :joy:

I don’t know about instanced meshes, but in general, you’d use something like this:

    var desiredvertexindex = 0;
    console.log(new THREE.Vector3().fromBufferAttribute(geometry.attributes.position, desiredvertexindex));

As for whether you should apply the matrix world for them, there are 2 cases:

How you know what position index to get, that depends on the particularties of your geometry and how Three.js arranges the elements in the position array (maybe this can help here, if you don’t have a better way of figuring it out).

1 Like

Hugely useful, thanks again @Yin_Cognyto ! :heart:

No problem, glad to help! :wink: