How to calculate degree at which face of a cube is facing the camera?

I have a cube that looks like this:

my camera looks at the cube like this

The cube has faces F(front), L(left), B(back), R(right)
and the top face is U(up) and bottom face is D(down)

I need to get a value that represents the current rotation of the cube VS the direction the camera is looking at it

This code does what I want, as long as the cube never “tilts”

      private float AngleFromVecToVec_IgnoringY(Vector3 cubeTransformForward, Vector3 CamTransformForward)
    {
        Vector3 cubeTransformForward_IgnoringY = new Vector3(cubeTransformForward.x, 0, cubeTransformForward.z);
        Vector3 CamTransformForward_IgnoringY = new Vector3(CamTransformForward.x, 0, CamTransformForward.z);

        return Vector3.Angle(cubeTransformForward_IgnoringY, CamTransformForward_IgnoringY) * Mathf.Sign(Vector3.Dot(Vector3.Cross(cubeTransformForward_IgnoringY.normalized, CamTransformForward_IgnoringY.normalized), Vector3.up));

    }

This code gives 180 if the cube is full on facing the camera, 0 if its completely facing away, and signed angle values for degrees of rotation in between, it allows me to pinpoint exactly how much the cube is rotated on the Y axis

The issue comes now that the cube can now be TILTED and so I can no longer ignore the y component of the transform forward vectors like Ive previously been doing

I tried this:

   private float AngleFromCubeForwardToCamDir(Vector3 cubeFwdVec, Vector3 cubeUpVec, Vector3 camDirVec)
    {
        //Vector3 partFwdVecNormalized = partFwdVec.normalized;
        Vector3 cubeFwdVec_IgnoringYNormalized = new Vector3(cubeFwdVec.x, 0, cubeFwdVec.z).normalized;
        Vector3 camDirVec_IgnoringYNormalized = new Vector3(camDirVec.x, 0, camDirVec.z).normalized;

        Vector3 upwardsAlignment = cubeUpVec;

        return Vector3.Angle(cubeFwdVec_IgnoringYNormalized, camDirVec_IgnoringYNormalized) * Mathf.Sign(Vector3.Dot(Vector3.Cross(cubeFwdVec_IgnoringYNormalized, camDirVec_IgnoringYNormalized), upwardsAlignment));
    }

but this is obviously wrong, because now being rotated on the X axis will produce an angle that is indistinguishable from rotation on the Y axis

It also doesnt actually take into account the fact that the camera is looking at the cubes from a 45º perspective, which so far I have been ignoring by eliminating the Y component of the camera transform forward, so that is obviously wrong aswell

I dont know what to try anymore, can someone give me some kind of advice?

You want to compare two basis sets to obtain the quaternion of the rotation.
Then you can extract Euler angles from that rotation to observe the per-axis differences.

The cube’s orientation is how the cube is rotated in the world space. That is known.

To obtain the other rotation you want to apply the orientation of your camera. Keep in mind that camera’s vector is aimed in the opposite direction (edit: my original wording here was confusing; think of the normal that points back to the camera, not camera’s direction per se; this is the effective orientation of the camera from the target object’s space).

To compare the two quaternions you “subtract” them by doing

var difference = Quaternion.Inverse(oppositeOfCamera) * cube.transform.rotation;

Where oppositeOfCamera can be derived (if I’m not mistaken) by negating components of camera.transform.rotation. If I am mistaken, then you can find this quaternion via Quaternion.FromToRotation(Vector3.forward, camera.transform.backward) (special care must be taken if camera is facing exactly forward or backward).

Underlying all this above are just dots and crosses, and you can do a lot with just direction vectors, but I don’t have much time rn.

1 Like

thanks for your advice, I made the cubes just for it to be visual, like you say, what i am interested is the rotation results, the cube is just a visual aid

It’s not an advice, it’s a direct solution to your problem, if somewhat abstract.
I never said that cube was important per se; the focus of my answer is in the relationship between two orientations, regardless of the shape. Perhaps you’d like to clarify if I misunderstood your problem somehow.

Here’s some terminology to help you navigate my answer better
Basis vectors
Orientation vs rotation
Quaternions vs Euler angles

Of course, if you have any specific questions, feel free to ask.

1 Like

I feel like you’ve asked this question like, two or more times before already.

If the cube is just a visual aid, give us your concrete problem that you’re trying to solve. These vague abstract descriptions make it hard to give concrete help. For a cube specifically it would be easy to hack this together by putting an empty on each face, with its z (forward axis) facing outwards, and compare that direction to the reverse forward direction of the camera.

But if it’s not a cube you’re dealing with them, what are you actually dealing with?

its for this:

https://www.youtube.com/watch?v=ybvaehpoYOs&t=1580s

So are you really asking how to get the angle between the player’s facing and the camera, so you can use the right sprite for a pseudo 3d sprite effect? Why not just say that?

Because the same principle would apply. You know what direction the player is facing, just compare that direction to the camera’s reverse forward direction, and you have your angle.

its not that simple, if it was just the player direction that is just 2 dimensional

i am asking about how a bone joint is facing the camera

if I just get one angle for that, how do i know if the angle is measuring sideways vs if its measuring upwards tilt? How do i know if its somewhere in between?

Well, we have no idea what your intentions were from your first post. You always talked about a cube facing the camera. So most people would assume some kind of dice problem which side is facing up / the camera. Now you talk about bones and that you need to know the complete orientation. It’s still not clear what your goal is.

What do you need this information for and what are you planning to do with that information? The orientation in 3d space requires either 3 angles (euler angles, which have quite a few issues) or a single direction vector plus an angle around that vector (this is essentially what a quaternion represents).

Your latest question was

i am asking about how a bone joint is facing the camera

Can you give an example answer that you would expect to get? Because “how” could mean a ton of different things. Maybe you can give some context what you need this for or what bigger problem you try to solve.

You can always transform the object’s rotation into camera space and analyse the relative rotation within the camera space. Though, again, without context I’m not sure what else we can suggest to you.

heres the values i am expecting to get:

i wanted to compare the transform of the cube with the transform of the camera, in other words, the depicted image is how the cube would look like as viewed through the camera, and the value I would expect to get based on how the cube looks

Your description is still a bit confusing, however given your example values it seems you’re mainly interested in the rotation around the up axis of the cube.

Since you mentioned the camera, the next question would be if you’re interested about the orientation relative to the camera position or the camera rotation. The difference here would be that when you pan the camera left / right but not moving the camera how the value would change. When the orientation is based on the position of the camera, the orientation value would not change. So it doesn’t matter if the cube is viewed in the left or right screen portion of the camera. If you want the value relative to the camera’s forward axis, the value would change when the camera angle changes, even though the cube and camera don’t move at all.

The easiest solution in this case would be to transform the reference vector (either the vector from the cube to the camera or the inverse of the camera’s forward vector) into the local space of the cube. In local space you can simply grab the x and z coordinates of that transformed vector and use Atan2 to calculate an angle. This assumes that “U” is actually the up axis of the cube.

Note that when you’re viewing the cube from directly above or directly below, you can not get an orientation at all since the x and z components would both be 0 in this case.

Vector3 v = cubeTransform.InverseTransformDirection(-camTransform.forward);
float a = Mathf.Atan2(v.z, v.x) * Mathf.Rad2Deg;

or

Vector3 v = cubeTransform.InverseTransformDirection(camTransform.position - cubeTransform.position);
float a = Mathf.Atan2(v.z, v.x) * Mathf.Rad2Deg;

The angle a would be in degree but may have to be adjusted to your desired range / offset.

In the second case you could also use cubeTransform.InverseTransformPoint(camTransform.position) which would transform the camera’s position into the local space of the cube which would have the same / a similar effect. I’m currently not 100% sure if the result would be identical when it comes to non-uniform scaling of the cube. Though with uniform scaling this should be the same.

2 Likes

thank you, yes it is like you say,

i want the up and bottom face of the cube to be ignored and i am looking only for the rotation on the “XZ” axis of the cube, though the “XZ plane” im interested in shifts if the cube is tilted and how to get that correction is what im trying to figure out, if you check my original post I was using a method that just ignored Y components, but it fails obviously when the cube/camera starts to tilt

and as you say aswell, I dont want panning of the camera to be considered so it would be just comparing the rotations and ignoring the positions

Thank you for your solutions, i will give them a try