PDA

View Full Version : Help needed for camera look-at method


scriptr
03-31-2008, 11:29 AM
Hi,

I am developing a simple car race game in j2me platform. And by the help of some online documents, i have developed the following code. But it doesn't work. Can u tell me where the problem is or do you have some working code to post here?

private void lookAtCar() {
Vector3D carPosVector = getPositionVector(car);
Vector3D cameraPosVector = getPositionVector(camera);

Transform cameraTransform = new Transform();
camera.getTransform(cameraTransform);
float[] transformMatrix = new float[16];
cameraTransform.get(transformMatrix);

cameraPosVector.substract(carPosVector);
cameraPosVector.normalize();

Vector3D rightVector = cameraPosVector.crossProduct(new Vector3D(0f,0f,1f));

transformMatrix[0] = rightVector.x;
transformMatrix[4] = rightVector.y;
transformMatrix[8] = rightVector.z;

cameraTransform.set(transformMatrix);
camera.setTransform(cameraTransform);
}


Thanks,

Reedbeta
03-31-2008, 12:27 PM
"It doesn't work" is not specific enough for us to tell anything. Please describe *precisely* what the code is supposed to do and how that differs from what it actually does?

scriptr
03-31-2008, 12:43 PM
Sorry, my mistake.

I have a camera and a car on a plane. I drive my car with navigation keys of the mobile device. And whenever i move my car in 3d space, i want my camera point the car, i mean, look at the car. This is what i want.

So i took this document (http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/lookat.html) as a reference, and implemented it in java for j2me.

When i fire my method above, my camera doesn't look at my car. It squeeze my the objects.

Any clearer code written with c,c# or java would really help.

Thanks

Goz
03-31-2008, 02:48 PM
Well you haven't set your up vector or direction vector in the transform matrix.

Assuming you are using column major matrices then you need to set

0, 4, and 8 to your right vector x.y.z
1, 5, and 9 to your up vector (You use 0, 1, 0) though stricly you should cross product your right and direction vectors for this/
2, 6, and 10 should define your camera matrix.
3, 7 and 11 should define your vertex position.
12, 13, 14,and 15 ought to be 0, 0, 0, 1 respectively.

Ok this defines the transform matrix to where your camera is from world space. However you want to move all your world vertices into camera space. So you multiply by the inverse of the camera matrix. Now all your matrices should be in camera space.

Inverse is a fairly complex transformation. So check here for a slightly quicker way of working it out

http://msdn2.microsoft.com/en-us/library/bb205343.aspx

Remeber .. D3D uses row major matrices so if you ARE using column major then you need to transpose that matrix.

scriptr
04-05-2008, 02:33 AM
Thank you very much Goz,

What do you mean with "vertex position"? For experiment, i set those 3 values to zero, but my camera doesn't look at my object. But when i move my object camera's target move also.

Kochol
04-05-2008, 12:00 PM
Hi
Write a function to recalculate the view matrix.

Set your matrix to these values.
0, 4, and 8 to your right vector x.y.z
1, 5, and 9 to your up vector
2, 6, and 10 to your view direction
12 = -(Right vector dotproduct Camera Position)
13 = -(Up vector dotproduct Camera Position)
14 = -(view direction vector dotproduct Camera Position)
3, 7, 11,and 15 ought to be 0, 0, 0, 1 respectively.

I use this matrix and its work for both opengl and direct3d.
See below code I learn this from gametutorials.com
This function also calculate up vector.

void Camera::CalcViewMatrix()
{
math::Vector Z = m_vLook - m_vPos; // Direction vector
Z.Normalize();

// calculate up vector
math::Vector vcTemp, vcUp;
float fDot = m_vUp * Z;
vcTemp = Z * fDot;
vcUp = m_vUp - vcTemp;
float fL = vcUp.GetLength();

// if too short take y axis
if (fL < 1e-6f)
{
math::Vector vcY;
vcY.set(0.0f, 1.0f, 0.0f);

vcTemp = Z * Z.y;
vcUp = vcY - vcTemp;

fL = vcUp.GetLength();

// take z axis if still too short
if (fL < 1e-6f)
{
vcY.set(0.0f, 0.0f, 1.0f);

vcTemp = Z * Z.z;
vcUp = vcY - vcTemp;

fL = vcUp.GetLength();

// we tried our best
if (fL < 1e-6f)
{
io::Logger::Log("Error: Can't calcute the up vector for camera.", io::ELM_Error);
return;
}
}
}
vcUp /= fL;

m_vRight.Cross(vcUp, Z);

m_mView._11 = m_vRight.x;
m_mView._12 = vcUp.x;
m_mView._13 = Z.x;
m_mView._21 = m_vRight.y;
m_mView._22 = vcUp.y;
m_mView._23 = Z.y;
m_mView._31 = m_vRight.z;
m_mView._32 = vcUp.z;
m_mView._33 = Z.z;
m_mView._41 = -(m_vRight * m_vPos);
m_mView._42 = -(vcUp * m_vPos);
m_mView._43 = -(Z * m_vPos);

m_bChanged = true;
} // CalcViewMatrix

Goz
04-07-2008, 12:59 AM
Thank you very much Goz,

What do you mean with "vertex position"? For experiment, i set those 3 values to zero, but my camera doesn't look at my object. But when i move my object camera's target move also.

Sorry i meant camera position in world coordinates.