RE: position, lookat, and up -> PerspectiveCamera

Jan Hardenbergh ([email protected])
Tue, 10 Oct 95 15:03:00 E


>> I'm finding it a bit difficult to mold my
>> model of a camera to VRML's PerspectiveCamera.
>> I can understand OpenGL's gluLookAt(pos, lookat, up)
>> command. Does anyone have a general way to convert
>> position and lookat locations, and an up vector into
>> a Transformation and PerspectiveCamera in VRML.

I need this, too. Perhaps Mesa has gluLookAt defined where
it generates a glTranlate and a glRotate call? Can someone say?

I know a hard way to do this, I think. Take the PEX code for LookAt.
(thanx to Sally Barry, I think) and then the Showmake's Graphics
Gems II, page 351, he claims you can convert a 4x4 matrix into a
quaternion. Then there is some code for converting an SFRotation
to a quaternion, which we think is reversable.

Anyway, the PEX LookAt code alone answers one of the questions.
Why do you want the Teansformation matrix, anyway?

PEX code, from PEXlib pl_util.c
****************************************************************************
****
Copyright (c) 1992 X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

int
PEXLookAtViewMatrix (from, to, up, matrix_return)

INPUT PEXCoord *from;
INPUT PEXCoord *to;
INPUT PEXVector *up;
OUTPUT PEXMatrix matrix_return;

{
PEXCoord a, b, c, d, e, f, t;
float magnitude;
float dot_product;

/*
* This matrix can be thought of as having 2 parts. The first part
(next
* to the coordinate point when it is being teansformed) moves the to
* point to the origin. The second part performs the rotation of the
data.
*
* The tmese basis vectors of the rotation are obtained as follows.
* The Z basis vector is determined by subtracting from from to and
* dividing by its length (b). The Y basis vector is determined by
* calculating the vector perpendicular to b and in the plane defined by
* the to and from points and the up vector and then normalizing it (e).
* The X basis vector (f) is calculated by e CROSS b.
*
* The resulting matrix looks like this:
*
* | fx fy fz 0 | | 1 0 0 -tox | | fx fy fz tz |
* | ex ey ez 0 |*| 0 1 0 -toy |=| ex ey ez ty |
* | bx by bz 0 | | 0 0 1 -toz | | bx by bz tz |
* | 0 0 0 1 | | 0 0 0 1 | | 0 0 0 1 |
*
* where tx = -to DOT f, ty = -to DOT e, and tz = -to DOT b.
*/

/*
* Calculate the rotations
*/

a.x = from->x - to->x; /* difference between to and from */
a.y = from->y - to->y;
a.z = from->z - to->z;

magnitude = sqrt (a.x * a.x + a.y * a.y + a.z * a.z);

if (ZERO_MAG (magnitude))
{
return (PEXBadVectors); /* from and to are the same */
}

/*
* normalize the from-to vector
*/

b.x = a.x / magnitude;
b.y = a.y / magnitude;
b.z = a.z / magnitude;

/*
* up is second basis vector
*/

c.x = up->x;
c.y = up->y;
c.z = up->z;

/*
* compute the dot product of the previous two vectors
*/

dot_product = (c.x * b.x) + (c.y * b.y) + (c.z * b.z);

/*
* calculate the vector perpendicular to the up vector and in the
* plane defined by the to and from points and the up vector.
*/

d.x = c.x - (dot_product * b.x);
d.y = c.y - (dot_product * b.y);
d.z = c.z - (dot_product * b.z);

magnitude = sqrt (d.x * d.x + d.y * d.y + d.z * d.z);

if (ZERO_MAG (magnitude)) /* use the defaults */
{
c.x = 0.0;
c.y = 1.0;
c.z = 0.0;

dot_product = b.y;

d.x = -(dot_product * b.x);
d.y = 1.0 - (dot_product * b.y);
d.z = -(dot_product * b.z);

magnitude = sqrt (d.x * d.x + d.y * d.y + d.z * d.z);

if (ZERO_MAG (magnitude))
{
c.x = 0.0;
c.y = 0.0;
c.z = 1.0;

dot_product = b.z;

d.x = -(dot_product * b.x);
d.y = -(dot_product * b.y);
d.z = 1.0 -(dot_product * b.z);

magnitude = sqrt (d.x * d.x + d.y * d.y + d.z * d.z);
}
}

/*
* calculate the unit vector in the from, to, and at plane and
* perpendicular to the up vector
*/

e.x = d.x / magnitude;
e.y = d.y / magnitude;
e.z = d.z / magnitude;

/*
* calculate the unit vector perpendicular to the other two
* by crossing them
*/

f.x = (e.y * b.z) - (b.y * e.z);
f.y = (e.z * b.x) - (b.z * e.x);
f.z = (e.x * b.y) - (b.x * e.y);

/*
* fill in the rotation values
*/

matrix_return[0][0] = f.x;
matrix_return[0][1] = f.y;
matrix_return[0][2] = f.z;

matrix_return[1][0] = e.x;
matrix_return[1][1] = e.y;
matrix_return[1][2] = e.z;

matrix_return[2][0] = b.x;
matrix_return[2][1] = b.y;
matrix_return[2][2] = b.z;

/*
* calculate the translation part of the matrix
*/

t.x = (-to->x * f.x) + (-to->y * f.y) + (-to->z * f.z);
t.y = (-to->x * e.x) + (-to->y * e.y) + (-to->z * e.z);
t.z = (-to->x * b.x) + (-to->y * b.y) + (-to->z * b.z);

matrix_return[0][3] = t.x;
matrix_return[1][3] = t.y;
matrix_return[2][3] = t.z;

/*
* and fill in the rest of the matrix
*/

matrix_return[3][0] = 0.0;
matrix_return[3][1] = 0.0;
matrix_return[3][2] = 0.0;
matrix_return[3][3] = 1.0;

return (0);
}

**************************************************************
Thanx to Gavin Bell for this hint and the pointer to Shoemake.
(P.S. the pointer to Patrick Maillot is in Graphics Gems I)

Turn the SFRotation axis & radians into a quaternion quat[4]

normalize(axis);

axis *= sin(radians / 2.0); // multiply x, y, z by sin()

quat[0] = axis[0];
quat[1] = axis[1];
quat[2] = axis[2];

quat[3] = cos(radians / 2.0);

******************************************************************

It is at times like this that I wish I had teansferred out of my Linear
Algebra
class and found a prof that actually cared.

YON, [email protected], Jan C. Hardenbergh, Oki Advanced Products 508-460-8655
www.oki.com/people/jch/ =|= 100 Nickerson Rd., Marlborough, MA 01752
"You laugh; you learn" Alanis Morissette 1974->>>, Jagged Little Pill CD


  • Next message: Jan Hardenbergh: "RE: position, lookat, and up -> PerspectiveCamera"
  • Previous message: Chris Marrin: "Re: LANG: cameras"