Generating rotation matrix with quaternion

Hi,

I wrote down an all new camera class for one of my programs and in one of routines in the class carrying out operations on the ModelView and Projection matrices directly. The camera init function accepts some values for creating an assymetric frustum and limits the viewing volume according to these coordinates.

Consider three planes oriented in space with the following coordinates:
Plane1: TL : (-426.66, 0, 200), TR: (0, 0, 0), BL : (-426.66, 320.79, 200), BR : (0, 320.79, 0)
Plane 2: TL : (0, 0, 0), TR: (426.66, 0, 0), BL : (0, 320.79, 0), BR: (426.66, 320.79, 0)
Plane 3: TL: (426.66, 0, 0), TR: (853.32, 0, 200), BL : (426.66, 320.79, 0), BR : (853.32, 320.79, 200)
A rough picture in the real world would be as follows:

The camera that I have written can draw a scene properly when all the four corners are in the same plane. As noticed above, Plane 1 and Plane 2 have two vertices with different Z values and are hence kind of rotated (not in the same plane). I am trying to draw the scene as it would have been drawn with same Z values but then rotate the projection instead, by multiplying my frustum with a rotation matrix so that it appears as if the scene was drawn taking the vertices in different plane into consideration (not fiddling with the MV matrix here to keep it clean for separate purposes).

Consider the rotated Plane 3 for which I have four corner vectors. In order to calculate the rotation matrix, I used oF’s Quaternion.makeRotation(from, to) method as follows :

  
quat.makeRotate(ofVec3f(853.32, 320.79, 200), ofVec3f((426.66, 320.79, 0)));  

Subsequently, I generate the rotation matrix and multiply with the projection matrix as follows:

  
ofQuaternion yRotation;  
ofMatrix4x4 screenTransformationMatrix;  
void UserPerspectiveCam::begin(ofRectangle rect){  
    glMatrixMode(GL_PROJECTION);  
    glLoadIdentity();  
        glFrustum(...); //some params for glFrustum generated earlier  
            yRotation.makeRotate(ofVec3f(853.32, 320.79, 200),  
                                 ofVec3f(426.66, 320.79, 0));  
            screenTransformationMatrix.makeRotationMatrix(yRotation);  
            ofMultMatrix(screenTransformationMatrix);  
    glMatrixMode(GL_MODELVIEW);  
    glLoadIdentity();  
        gluLookAt(...); //some params generated earlier in the program  
}  

Now, this does give a rotation to me but the scene that I am drawing in not getting stitched (although I have the same MV matrix for all three cam instances inside which I draw the scene) and appears to have some weird effect with the above rotation matrix multiplication. Here’s the screencap when all the planes all having the same Z (no rotation code included):
Link: []()

And here’s the screeny showing the effect when I include the rotation code in my cam class.
Link: []()

My question is on how to generate the rotation matrix properly to rotate the projection accordingly so that the scene appears continuos as well. In OpenGL, normally this would have been done by using the the three vectors TL, BL, BR. BL-TL would up vector, BL-BR would give right vector. Cross product of two would give Z vector. Normalize all three and do a change of basis to obtain the rotation matrix to be multiplied with the projection matrix. I am sure in oF there’s much shorter way of doing this (something like I was doing with quaternions above) but haven’t quite been able to get the right effect till now. Any help would be great!
Thanks

hey harpreet, this is a fairly complex question – it’s hard to see how your code is interacting with OF and with anything else. could you post the entire, minimum amount of code necessary to recreate the screenshots you posted? then it will be easier for people to help out.

Hi Kyle,

I just made a very very quick separate dirty class to repro this and to show the problem. It’s an XCode oF project and I have uploaded it here that you can just directly run to get the output in those screenshots https://www.dropbox.com/s/fhd1x80e5azxk1e/customCamTest.zip
I have got it working separately with OpenGL directly but I do want to keep the class as much oF as possible. Let me know if I should add the code itself here in the post but didn’t do it for now to avoid creating a mess with a long-ish code that I have.

Thanks!

Hey harpeet.

thanks for your email. continuing to reply here…

to clarify, as i understand, your intention is to transform the scene into 3 separate reference frames, each where the viewport is within the z = 0 plane, therefore your issue is how to apply these rotations using the oF api.

in response to this query, i would translate the axis of rotation to be the x,z=0 line and then perform the rotation in the y axis (i.e. ofTranslate, ofRotate)

alternatively you can use the ofCamera::setupOffAxisViewPortal function (if i correctly understand your intentions).

for each screen, you’d have a separate ofCamera, you call

  
  
void ofCamera::setPosition(const ofVec3f& position);  
  
void ofCamera::setupOffAxisViewPortal	(	const ofVec3f & 	topLeft,  
const ofVec3f & 	bottomLeft,  
const ofVec3f & 	bottomRight   
);  
  

position = position of viewer in world space (same for all viewports)
topLeft = top left (from viewer perspective) 3d coordinate of view portal in world space
bottomLeft = bottom left //
bottomRight = bottom right //

1 Like

I’m trying to do a similar thing, however I can’t seem to find any good documentation on ofCamera::setupOffAxisViewPortal(), and I can’t parse what is going on in 3d/cameraLensOffsetExample. Would someone mind pointing more towards, or illustrating, a basic usage of this function, perhaps aligning two cameras to seamlessly render the same scene?