How can i change the up vector of a group of object?

Hi there i have a group of planes geometry that make up a cube and i try to rotate it facing the camera after the rotation end (this will show a different texture every time the spin end).

As you can see here when the rotation ends inside generateTarget() i get the camera position and then inside the function highlightFace i rotate the group of objects.

As you can see from the codepen, the cube rotate always with the blue side of it, even trying with planesGroup.up.set(0, 0, -1) or other values, trying to change the up value to pass it inside the rotationMatrix.lookAt( point.position, planesGroup.position, planesGroup.up);.

I would like to rotate towards the face of the cube that get intersected in the raycast inside highlightFace function.

Is it possible? Or am i missing something?

Thanks in advance, i’m new to three js

I’m somewhat struggling to understand what is the expected behaviour. My guess is this:

  • There a cube with different colors of all side
  • The user can rotate the scene (via OrbitControls)
  • When the user rotation is complete, one of cube sides is approximately “looking” towards the camera
  • The goal is to rotate the cube, so that this side “looks” exactly towards the camera

Is this correct?

Also

Never end your email with “Thanks in advance” | Academic workflows on a Mac

The lookAt(target) method always let the Z axis of the object’s local space point to the target.

Because all the planes’s position in the group space are not changed, in other words, the Z axis is always the normal of the blue plane, after move the camera, the group is rotated, which results in the Z axis points to camera, the blue plane always faces camera.

In this case, the group.up is only used to rotate the blue plane around the Z axis of the group space.

Okay but how can i change the plane that will look the camera in the group? Or is there a better method?

My goal would be after the rotation end, check with a raycast which plane face the camera and face that one to the camera (not always the blue one).

It’s a group of plane because then i’d like to show an image or texture depending on the face you see at the end of the rotation.

Let me know if smt is not clear

Let me say my idea.

Suppose the raycast find a plane named as A, and its normal vector is named as a.

Rotate the scene to make a pointer to camera so that the plane faces the camera.

But how to rotate ?

First, calculate the vector a. In the plane space, the normal vector is (0, 0, 1) by defalut.

We can use the Plane(of math) help us to calculate.


const planeA; // the checked by raycast

const plane = new Plane(new Vector3(0, 0, 1), 0);

plane.applyMatrix4(planeA.matrixWorld);

const vector_a = plane.normal.clone().normalize();

Now, we get the a vector in the world space.

Secondly, we need calculate the “pointer to camera” direction vector of the camera, named as p.

Because the camera look at the origin, the vector p equals to the camera’s position.


const vector_p = camera.position.clone().normalize();

Finally, we can use a and p to calculate how to rotate.

The vector of directions that is rotated around, named as l. So, l = a \times p

The angle of rotatation is cos(\theta) = a \cdot p.


const vector_l = new Vector3().crossVectors(vector_a, vector_p);

const theta = Math.acos(new Vector3().copy(vector_a).dot(vector_p));

scene.rotateOnWorldAxis(vector_l, theta);

Hmm thanks for the explanation! It’s interesting but with this method i loose the animation and it is a bit buggy sometimes, hopefully i’implementing it correctly.

I think i’m gonna try to merge it with this codepen: https://codepen.io/woodwoerk/pen/YMKXzq

It’s kinda what i’m trying to achieve but with OrbitControls instead of ArchballControls and with a different approach that define the cameraPosition at the beginning

Is this what you try to achieve:

https://codepen.io/boytchev/full/abPVZYP

2 Likes

Yess, that’s actually the goal!
Seems so simple from your code yet i was so far :slight_smile:

I just have 2 last doubt that would be a nice to have:

  • Would be hard to have the same with ArchballControls instead of OrbitControls? The client asked if the user can spin randomly the cube on itself

  • Is it possible to make the selfRotation to end without the cube being tilted? So the cube would be perfectly horizontally places

Sorry for the yet other questions, i’m new three js!
I appreciate everyone’s kind help

  • ArcballControls: I don’t have sufficient experience with it, maybe you could try it and see whether it works.

  • Tilting: it should be possible, but it will need additional calculations. I don’t know your use case, but you may consider two other options: (1) instead of the camera, the user rotates the object manually; or (2) instead of ArcballControls, the code uses TransformControls.

So i ended up mixing the codepen from Pavel and the one i found:

Here is the result if it can help someone!
The main difference is that i register every camera position facing a cube side at the beginning and then when i click navigation button or i finish the spin rotation i will get the camera correspondent view.

The only downside is that when is rotating from opposite side of the cube (north->south, east-west,…) sometimes it goes through the cube, so i fixed it trying to put an intermediate side as a step( not always working).

NICE TO HAVE: when spinning the cube randomly would be nice, at the end of the rotation, to tilt in an horizontal position. I have no idea how to calculate that… for now :slight_smile:

I really appreciate all the help you guys gave and if you have any suggestion on this, feel free to add.
If i manage to optimize it i will update the post here