PDA

View Full Version : creating up/down/left/right keys by moving the camera



cg-hci_novice
11-07-2003, 06:56 PM
Hi,

I am trying to create some up/down/left/right keys by moving the camera. I understand how to do this by moving objects but it is impractical to do so in my current project. I was wondering if someone could pt me to an example in either the red book, opengl superbible or on the Web that would give me an idea on how to do this?

Thanks very much.

chowe6685
11-07-2003, 09:26 PM
I'm slightly confused by what your saying, but keep in mind that there is no camera, the only way to move the "camera" is to move all the objects in the scene according to the inverse of the "camera" position. You should keep track of when the up/down/left/right keys are pressed and use this information to store the position of the camera, then translate your scene by the inverse of this position

cg-hci_novice
11-07-2003, 09:37 PM
Thanks for the info. Still not exactly clear on how to apply it.

Clarification:

I would like to implement these keys by incrementing/decrementing arguments to gluLookAt as opposed to translating the objects that I have drawn.

Thanks a lot.

virtualchetan
11-08-2003, 06:55 AM
Here is the code I wrote seven months back to achieve the same




//Vector Maths//////////////////////////////////////////////////////////////////////////////////
struct SVector
{
double X, Y, Z;
};

SVector unit(SVector v)
{
SVector RetVector = v;
double mag = pow( pow( RetVector.X, 2) + pow( RetVector.Y, 2) + pow( RetVector.Z, 2), 0.5);

RetVector.X /= mag;
RetVector.Y /= mag;
RetVector.Z /= mag;

return RetVector;
}

SVector cross(SVector v1, SVector v2)
{
SVector RetVector;

RetVector.X = v1.Y * v2.Z - v1.Z * v2.Y;
RetVector.Y = v1.Z * v2.X - v1.X * v2.Z;
RetVector.Z = v1.X * v2.Y - v1.Y * v2.X;

return RetVector;
}

SVector rotVector(SVector rotVector, SVector abtVector, double deg)
{
//When vector Q is rotated, @ Vector P, thru angle t;
//the resultant vector R is given by:
//
// R = [P /|P|]sin(t) x [Q] + [Q]cos(t)
////////////////////////////////////////////////////////

SVector RetVector;

//add 2nd part
RetVector.X = rotVector.X * cos(deg * DEG_TO_RAD);
RetVector.Y = rotVector.Y * cos(deg * DEG_TO_RAD);
RetVector.Z = rotVector.Z * cos(deg * DEG_TO_RAD);

//calculate 1st part accumulating in abtVector
double factor = sin(deg * DEG_TO_RAD) /
pow( pow( abtVector.X, 2) + pow( abtVector.Y, 2) + pow( abtVector.Z, 2), 0.5);
abtVector.X *= factor;
abtVector.Y *= factor;
abtVector.Z *= factor;
abtVector = cross(abtVector, rotVector);

//add 1st part
RetVector.X += abtVector.X;
RetVector.Y += abtVector.Y;
RetVector.Z += abtVector.Z;

return RetVector;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////

//Camera/////////////////////////////////////////////////////
struct SCamera
{
//opengl parameters
double X, Y, Z;
double AtX, AtY, AtZ;
double UpX, UpY, UpZ;
// double FrontPlane, BackPlane;
// double Vfov;
// double Aspect;

//other parameters
// double ViewPlane;
// double WinW ~ Aspect, WinH ~ Vfov;

//extra param
// int ViewPlaneFlag; // 1 = +ve, 0 = 0, -1 = -ve;
// bool ZeroVfovFlag;

void rotate(char axis, double deg);
void translate(char axis, double dist);
};

void SCamera :: translate(char axis, double dist)
{
SVector negN, Up, unitTransAxis;
negN.X = AtX - X; negN.Y = AtY - Y; negN.Z = AtZ - Z;
Up.X = UpX; Up.Y = UpY; Up.Z = UpZ;

switch (axis)
{
case 'X':
unitTransAxis = cross(negN, Up); //U
break;

case 'Y':
unitTransAxis = cross(cross(negN, Up), negN); //V
break;

case 'Z':
unitTransAxis = negN;
}

//make unit actual unit vector
double mag = pow( pow( unitTransAxis.X, 2) + pow( unitTransAxis.Y, 2) +
pow( unitTransAxis.Z, 2), 0.5);
unitTransAxis.X /= mag;
unitTransAxis.Y /= mag;
unitTransAxis.Z /= mag;

//scale with dist
unitTransAxis.X *= dist;
unitTransAxis.Y *= dist;
unitTransAxis.Z *= dist;

//add to two cam points
X += unitTransAxis.X;
Y += unitTransAxis.Y;
Z += unitTransAxis.Z;
AtX += unitTransAxis.X;
AtY += unitTransAxis.Y;
AtZ += unitTransAxis.Z;
}

void SCamera :: rotate(char axis, double deg)
{
SVector negN, Up, RotAxis;
negN.X = AtX - X; negN.Y = AtY - Y; negN.Z = AtZ - Z;
Up.X = UpX; Up.Y = UpY; Up.Z = UpZ;

switch (axis)
{
case 'X': RotAxis = cross(negN, Up); //U
break;

case 'Y': RotAxis = cross(cross(negN, Up), negN); //V
break;

case 'Z': RotAxis = negN;
}

if (axis != 'Z')
{
negN = rotVector(negN, RotAxis, deg);
AtX = negN.X + X;
AtY = negN.Y + Y;
AtZ = negN.Z + Z;
}

//actually needed only when nefN becomes equal to Up
Up = rotVector(Up, RotAxis, deg);
UpX = Up.X;
UpY = Up.Y;
UpZ = Up.Z;
}
///////////////////////////////////////////////////////////////////////

virtualchetan
11-08-2003, 06:58 AM
The identifier names must be confusing :-P

But, basically, I determine the 3 vectors that form the Camera co-ordinate system (CS) w.r.t. the world CS and then use complex Vector maths to translate/rotate those 3 vectors which for camera CS.

- Chetan

cg-hci_novice
11-08-2003, 09:21 AM
VC,

Printing it out now.

Thanks for your help.

cg-hci_novice
11-08-2003, 09:59 AM
Does anyone know of a way this can be done using trig as well? The vector may be more than I need/have time for.

Thanks.

cg-hci_novice
11-09-2003, 10:00 PM
question has been resolved.

Thanks everyone.