A scene with a floor and an object that floats directly above it.
When I click on a face of an object I want the whole object to rotate in such a way that the clicked face faces the floor.
face
: Raycaster picks up the first face
.up
vector with the normal
of the clicked face
: object.up.copy(face.normal)
object.lookAt(floor.position)
I would expect that because of the new up
vector, the object would lookAt the floor with an orientation based on the clicked face.
However, The rotation doesn't work as expected. What am I missing?
The relevant code part:
var intersects = raycaster.intersectObject( cylinder );
if(intersects === undefined || intersects.length === 0) return;
let face = intersects[0].face;
// Set cylinders up to the normal of the intersected face to reoriented object
// to make the clicked-on face `lookAt()` the floor:
cylinder.up.copy(face.normal);
cylinder.up.normalize();
cylinder.lookAt(floor.position);
http://codepen.io/anon/pen/EWRdZq
Based on @WestLangley's answer: http://codepen.io/anon/pen/ryZOvx
You want to rotate an object so that a face's normal points in a particular direction.
In your example, the desired direction is in the direction of the negative-y axis, but you could specify any direction vector, as long as it has unit length.
You can use a pattern like so:
let direction = new THREE.Vector3( 0, - 1, 0 ); // create once and reuse
...
let object = intersects[ 0 ].object;
let normal = intersects[ 0 ].face.normal;
object.quaternion.setFromUnitVectors( normal, direction );
Note that your problem statement does not have a unique solution. For example, the object can be "spun" on an axis and still have the face oriented in the desired direction.
three.js r.84