Get coordinates of transformed mesh

I have a tilted triangle on a scene (represented in blue):

// Original mesh
var points = [
    new THREE.Vector3(-50, 0, 10),
    new THREE.Vector3(-10, 0, 10),
    new THREE.Vector3(-30, 50, 80),
    new THREE.Vector3(-50, 0, 10),
];
var geometry = new THREE.BufferGeometry().setFromPoints(points);
var material = new THREE.MeshBasicMaterial({color: 0x0000ff});
var original = new THREE.Mesh(geometry, material);
scene.add(original);

I then rotate it with a quaternion to make the mesh parallel to the horizontal X-Y plane, and then rotate it again around the global vertical Z axis:

// Transformed mesh
var plane = new THREE.Plane().setFromCoplanarPoints(...points);
var quaternion = new THREE.Quaternion().setFromUnitVectors(
    plane.normal,
    new THREE.Vector3(0, 0, 1),
);
var transformed = original.clone().applyQuaternion(quaternion);
transformed.rotateOnWorldAxis(new THREE.Vector3(0, 0, 1), Math.PI);
transformed.material = transformed.material.clone()
transformed.material.color.set(0xff0000)
scene.add(transformed);

How can I get the coordinates of the transformed geometry? They should all have positive X values, negative Y values and the same positive Z value.

Fiddle: https://jsfiddle.net/Peque/21xjvtp5/

I have tried to access the transformed.geometry, only to find out that the coordinates where those of the original geometry. I also tried to compute the bounding box:

var box = new THREE.Box3().setFromObject(transformed);

Which gave me expected X-Y values, so I am guessing what I am looking for is possible. Unexpectedly, the bounding box Z values were way off (I would expect the difference between max and min to be almost zero), but that is another question I guess… :joy:

The transformations of each vertex takes place in the GPU immediately before rendering, so it’s hard to extract that vertex information back into JavaScript. However, you could duplicate the point you want to track, and give it the same transformation matrix as your Mesh:

// ...

var original = new THREE.Mesh(geometry, material);
var point = new THREE.Vector3(-50, 0, 10);
var transformMat = original.matrixWorld;

point.applyMatrix4(transformMat);

Now the point will reflect the same position as the vertex in the mesh.

https://threejs.org/docs/#api/en/math/Vector3.applyMatrix4

2 Likes

@marquizzo Thanks, works great! :blush:

I guess you meant point.applyMatrix4(transformed.matrixWorld) (instead of original.matrixWorld).

So there is no way to do it in bulk without a loop?

Yeah, if you want to do several vertices you’ll need to apply the same transform matrix to them in a loop. You’ll probably see a performance hit if you want to do this 60 times per second with thousands of verts.

Alternatively, if you want to do a “hard-transform” to the vertex coordinate values, you can apply transformations to the BufferGeometry directly, instead of the Mesh. However, this is recommended only as a one-time operation because it has to re-write the coordinate array and upload the new values to the GPU, which is a slow process. This is good if you want to transform only once, not for constant animation updates. You’d then be able to access the new geometry 'position' attribute.

1 Like