Transforming Camera on guiObjectView
by Jason Farmer · in Torque Game Engine · 10/28/2005 (12:05 pm) · 9 replies
Before I attempted to move the camera position (transform not rotate) in the guiObjectView control, I thought I was reasonably intelligent... but now I feel so thick, I could be used to beat whales to death..
Could someone who understands how all this Matrix stuff works please give me a clue, or code snippet...
I'm figuring that I need to add something to the processCameraQuery function in C++ to translate my view, it's doing loads of work for Rotation and distance, but nothing to do with moving the camera up and down.. here's the current code.
say I wanted to hard code a +50 unit shift in the Y axis, what would I do?
Could someone who understands how all this Matrix stuff works please give me a clue, or code snippet...
I'm figuring that I need to add something to the processCameraQuery function in C++ to translate my view, it's doing loads of work for Rotation and distance, but nothing to do with moving the camera up and down.. here's the current code.
bool GuiObjectView::processCameraQuery( CameraQuery* query )
{
// Make sure the orbit distance is within the acceptable range:
mOrbitDist = ( mOrbitDist < mMinOrbitDist ) ? mMinOrbitDist : ( ( mOrbitDist > MaxOrbitDist ) ? MaxOrbitDist : mOrbitDist );
// Adjust the camera so that we are still facing the model:
Point3F vec;
MatrixF xRot, yRot, zRot;
xRot.set( EulerF( mCameraRot.x, 0, 0 ) );
yRot.set( EulerF( 0, mCameraRot.y, 0 ) );
zRot.set( EulerF( 0, 0, mCameraRot.z ) );
mCameraMatrix.mul( zRot, xRot );
mCameraMatrix.mul( mCameraMatrix, yRot );
mCameraMatrix.getColumn( 1, &vec );
vec *= mOrbitDist;
mCameraPos = mOrbitPos - vec;
query->nearPlane = 0.1;
query->farPlane = 2100.0;
query->fov = 3.1415 / mFOV; //1.5;
mCameraMatrix.setColumn( 3, mCameraPos );
query->cameraMatrix = mCameraMatrix;
return( true );
}say I wanted to hard code a +50 unit shift in the Y axis, what would I do?
#2
When translating the camery you just have to add some offsets to mCameraPos, before it
is submitted to the query structure.
Say you want to translate the camera 5 units along the World-y-axis, regardless of the object rotation.
You would do this by
Say you want to translate the camera 5 units along the View-y-axis, depending on the current camera rotation
(This is a kind of zoom, since you bring the camera closer to the object, along the view axis).
You would do this by
Hope that helps.
-- Markus
10/31/2005 (4:50 am)
Maybe first a rundown, of what the camera code does.bool GuiObjectView::processCameraQuery( CameraQuery* query )
{
...
// Setup of three rotation matrices.
// xRot for the rotation around the x-axis
// yRot for the rotation around the y-axis
// zRot for the rotation around the z-axis
xRot.set( EulerF( mCameraRot.x, 0, 0 ) );
yRot.set( EulerF( 0, mCameraRot.y, 0 ) );
zRot.set( EulerF( 0, 0, mCameraRot.z ) );
// Combine all three single rotation matrices into one
// This is done by multiplying z rotation matrix with the x rotation matrix
// and then multiplying the result with the y rotation matrix
mCameraMatrix.mul( zRot, xRot );
mCameraMatrix.mul( mCameraMatrix, yRot );
// mCameraMatrix now holds a rotation around the ORIGIN e.g. (0,0,0), based
// on the rotation values given in mCameraRot.x, mCameraRot.y, mCameraRot.z
// Now extract the y-axis from the rotation matrix.
// Think of the camera being positioned at the origin and being rotated according
// to mCameraMatrix. Then the y-axis is the view-direction of the camera.
// This y-axis is stored i the second column of the matrix (with index:1, x-axis is
// the first column with index:0 and z-axis is the third column with index:2)
mCameraMatrix.getColumn( 1, &vec );
// Calculate a vector with length mOrbitDistance along the
// cameras view axis (y-axis)
// This is done by multiplying the view vector with mOrbitDist.
vec *= mOrbitDist;
// Bring the camera away from the origin (mOrbitPos) along the y-axis (view direction)of the rotation
// Bring it back by the length of the vector calculated above and in the direction of
// the vector calculated above
// destination position = mOrbitPos + (- view vector)
mCameraPos = mOrbitPos - vec;
// Fill the query structure with frustum information for:
// near plane, far plane, field of view
query->nearPlane = 0.1;
query->farPlane = 2100.0;
query->fov = 3.1415 / mFOV; //1.5;
// Position the camera at the position calculated above
// This is done by setting the fourth column (index:3) of the view matrix
// to the calculated position
mCameraMatrix.setColumn( 3, mCameraPos );
// Submit the calculated matrix to the query strucutre
query->cameraMatrix = mCameraMatrix;
...
// Now the camera is placed at mCameraPos it is shifted back along the y-axis by
// the amount of mOrbitPos, directly looking at the origin.
}When translating the camery you just have to add some offsets to mCameraPos, before it
is submitted to the query structure.
Say you want to translate the camera 5 units along the World-y-axis, regardless of the object rotation.
You would do this by
...
mCameraPos = mOrbitPos - vec;
...
[b]mCaraPos + VectorF(0, 15, 0);[/b]
...
mCameraMatrix.setColumn( 3, mCameraPos );Say you want to translate the camera 5 units along the View-y-axis, depending on the current camera rotation
(This is a kind of zoom, since you bring the camera closer to the object, along the view axis).
You would do this by
... mCameraPos = mOrbitPos - vec; ... [b] vec.normalize(); // To make it of unit size mCaraPos + 15*vec; [/b] ... mCameraMatrix.setColumn( 3, mCameraPos );
Hope that helps.
-- Markus
#3
That is exactly what I wanted, an explanation of how the current code works and how to integrate the change I need into the existing code. Now I know how and why it works.
I was trying to work this stuff out using the Matrix explaination in Advanced 3D Game Programming All in One.. but he talked about setting up 3x3 matices for rotation and 4x4 matrices for transformation, I didn't understand how the matrix code was implemented.
Now I understand a whole lot more.
10/31/2005 (5:21 am)
Thanks Markus,That is exactly what I wanted, an explanation of how the current code works and how to integrate the change I need into the existing code. Now I know how and why it works.
I was trying to work this stuff out using the Matrix explaination in Advanced 3D Game Programming All in One.. but he talked about setting up 3x3 matices for rotation and 4x4 matrices for transformation, I didn't understand how the matrix code was implemented.
Now I understand a whole lot more.
#4
I'll add my change to the guiObjectView thread so others can share the work.
Thanks again Markus
11/01/2005 (1:30 am)
Applied this change last night, added a new method to the guiObjectView::SetCameraOffset Works a treat.I'll add my change to the guiObjectView thread so others can share the work.
Thanks again Markus
#6
11/02/2005 (3:09 pm)
I've added a comment to the resource if anyone's interested in this change.
#7
11/02/2005 (4:42 pm)
Awesome. I definately could use that extra code.
#8
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3659
11/02/2005 (5:38 pm)
Here's the resource I've posted the code on.www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3659
#9
One other question. Once you transform the camera to a new position the model is still rotating around the origin, which happens to be the center point of the object viewer. So it ends up creating a pretty large orbit depending on how far you shift, instead of still rotating on the center of where the object was moved to.
Because, I don't quite understand matrix rotations enough, I was wondering if it would be possible to still transform the camera (say by shifting it right so the model moves left), but when you rotate the model at its new position, it rotates around the center point of where the model currently is and not the camera position?
I've tried setting the position (4th column) of the xRot and zRot by the camera offset but nothing happens.
04/22/2009 (6:27 am)
I realize this is an older post but it's still relevant to the GuiObjectView control, and the explanation by Markus was very helpful.One other question. Once you transform the camera to a new position the model is still rotating around the origin, which happens to be the center point of the object viewer. So it ends up creating a pretty large orbit depending on how far you shift, instead of still rotating on the center of where the object was moved to.
Because, I don't quite understand matrix rotations enough, I was wondering if it would be possible to still transform the camera (say by shifting it right so the model moves left), but when you rotate the model at its new position, it rotates around the center point of where the model currently is and not the camera position?
I've tried setting the position (4th column) of the xRot and zRot by the camera offset but nothing happens.
Torque Owner Jason Farmer