How to get the Midpoint rotation (Illustration included)

I have three objects in total, 2 cubes and one billboard. The 2 cubes are placed on the outside and then the billboard is placed in the middle by taking the positions of the 2 cubes and placing in between all the time. My headache now is to also apply the correct rotation that would occur between these 2 cubes, and so far search engines have come up empty so I thought I’d try it here…

I’ve managed to make it work somewhat by having centered child objects on the cubes and use LookAt() between them and use the rotation from that on the billboard. However this makes the billboard face the wrong direction, a temporary fix has been to write +90 degrees on the y-angle of the rotation but that breaks the rotation from working as intended.

My current code:

 Transform leftcube;
Transform rightcube;
leftcube.LookAt(rightcube);
transform.rotation = Quaternion.Euler(leftcube.rotation.x, leftcube.rotation.y + 90, leftcube.rotation.z);
//Script attached to the billboard

An illustration of what I’m trying to achieve:


The red line illustrates the line drawn from the two cubes where the rotation in the center should be retrieved and applied to the billboard.

Image doesn’t work.

You want an orientation that is halfway between leftCube’s rotation and rightCube’s rotation?

billboard.rotation = Quaternion.Slerp(leftcube.rotation, rightcube.rotation, 0.5f);

Thanks, that was an easy one… Fixed the image for others who come across this thread.

Image is still not working. I would recommend uploading them to the posts directly, so you don’t need a separate site like imgur.com.

Imgur’s server was down but should be up by now…

@lordofduct

I’ve encountered an issue by using Quaternion.Slerp, it yield the results I want but my cubes are actually moving around. Which for whatever reason causes the billboard to flip 180 degrees additionally over what it’s supposed to be.

Can I see your full code for moving the cubes and updating the billboard?

The left and right cube are rightC and leftC, and the billboard is the the object that the script is attached to that as previously stated I want to be positioned in between and have the rotation based on the rightC and leftC

if (rotation) {
//empty children inside the cubes that look at each other
            lVcenter.LookAt(rightC);
            rVcenter.LookAt (leftC);
            //towardsCamera = Quaternion.LookRotation (transform.position - Camera.main.transform.position);

            transform.rotation = Quaternion.Slerp(lVcenter.rotation, rVcenter.rotation, 0.5f);

        } else {
            lookAtCamera ();
        }
        position = new Vector3 (leftC.position.x + rightC.position.x, leftC.position.y + rightC.position.y, leftC.position.z + rightC.position.z) / 2f;
        transform.position = position;

The movement is made in the Editor for now but will be controlled with actual controls later.

@lordofduct

Sorry, haven’t had a chance to get at this. Been busy with work and a funeral I have to go to.

Your problem is because you’re making lVcenter and rVcenter look at one another, and then getting a rotation half way between them. Problem is if 2 things are looking at one another, the difference in orientation between them is 180 degrees around their shared up axis.

Because of that, the shortest path can be in any direction really… so the slerp sometimes goes one direction, and other times it goes the other direction, merely as a result of the order they’re in (causing the flipping for you).

In this case, you should determine the up axis around which both rotate (probably ‘Vector3.up’ in your case), and rotate 90 degrees (halfway will always be 90 degrees) from one of the rotations.

Should be something along the lines of:

if (rotation) {
    //empty children inside the cubes that look at each other
    lVcenter.LookAt(rightC);
    rVcenter.LookAt (leftC);

    //transform.rotation = Quaternion.Slerp(lVcenter.rotation, rVcenter.rotation, 0.5f);
    transform.rotation = lVcenter.rotation * Quaternion.AngleAxis(90f, Vector3.up);
} else {
    lookAtCamera ();
}
position = new Vector3 (leftC.position.x + rightC.position.x, leftC.position.y + rightC.position.y, leftC.position.z + rightC.position.z) / 2f;
transform.position = position;

Try flipping the 90f to -90f if you want it to face the other direction.

I can’t validate that works, I’m in the middle of something right now. But it should… if I messed up, it might have to flip the order of operations:

transform.rotation = Quaternion.AngleAxis(90f, Vector3.up) * lVcenter.rotation;

I often forget my order of operations for quats… ugh, non transitive data structures.

Hopefully that helps.

Thanks for the help, I’ll check it out. And sorry for your loss.

Update: It worked great, all I had to do was change 90f to -90f and it worked flawlessly, no weird flipping now :slight_smile: