The title doesn’t explain what I’m trying to do very well, but I didn’t want to make it too long.
I am trying to code a portal system, like zone portals in Unreal (or the portal games if you don’t know what I’m talking about). I’m using a simple shader to render the view of a second camera in the place of the portal’s “surface” object. I’ve got that working fine.
However, I’m having problems getting the second camera’s rotation and position set correctly relative to the “other” portal. At first I was using Quaternion.fromToRotation() to find the relative rotation between two portals’ forward vectors. This worked perfectly - in some cases. It seems that the further I rotated the portals from their default rotations, the more likely the camera providing the view to the scene behind the “other” portal was to be rotated and positioned improperly. I think this is because fromToRotation() only rotates a directional vector without considering how the x and z axes of the object being rotated are or will be oriented.
After searching the web, I found a solution that I thought would solve the problem. By multiplying the inverse of the rotation of the first portal by the rotation of the second portal, I can find the relative quaternion rotation between them, then multiply the player camera’s rotation by that relative rotation and, finally, set the portal camera’s rotation equal to the resulting quaternion.
Once I updated my code, the problem got worse. Now if either of the portals’ rotations are set to anything other than (0, 0, 0), the rotation axes of the portal camera get mixed around. If the player looks up, rotation around the player camera’s x axis, the portal camera might spin along it’s z axis in response. This is just one example; it seems like any conceivable combination of axes switching can be achieved by playing with the rotations of the portals.
The confusing thing is that the script does actually “work” as far as I can tell. I made a simplified version of the script and used it on four dummy objects to test various rotation schemes. I noticed that the stand in dummy object for portal camera would always have the same rotation relative to the player camera dummy as the second dummy portal to the first. And yet… when rotating in real time, the axes were still screwed up. even as the relative rotations always remained spot-on.
I’m having trouble understand what’s going on exactly, as this seems like a paradox. I’m assuming there is some property of the mathematics of rotation that I don’t understand which is causing this. I’ve been trying to figure this out myself for days, but I’m just not getting anywhere.
I would like to know why exactly this is happening out of curiousty. More importantly, though, I want to know how to get my portals to work properly.
Here are the two lines of code that matter:
rotation = Quaternion.Inverse(portalObject.transform.rotation) * referenceObject.transform.rotation;
transform.rotation = playerCamera.transform.rotation * rotation;
Though if I have to change my method entirely, as I suspect I will, I’m not sure posting the code will help much.
Oh, by the way, the script is attached to the portal camera. portalObject is the first portal (the one the player is looking at), and referenceObject is the second (destination) portal.
It is essential to the concept of this game that the script work with any two portals with any arbitrary rotations.