Skip to main content
GameDev.net gamedev.net
🔒 Locked

Understanding 3D camera better

Started by tenpoundbear Aug 6, 2010 at 4:25 AM 5 replies 1.9k views
Original Post
tenpoundbear
tenpoundbear
Hi guys,

Hoping you guys can help me understand my 3D camera better.

I have it implemented and it works perfectly.

But there is just one section of code that I do not fully understand, and I hope you guys can clarify for me.

I have followed the code from "http://www.toymaker.info/Games/html/camera.html"

// ======= CAMERA HEADER ======== //#ifndef CAMERA_H#define CAMERA_H#include <d3dx9.h>class Camera{public:	Camera();	void updateViewMatrix( IDirect3DDevice9** D3DDevice );	void lookAtPos( D3DXVECTOR3* Position, D3DXVECTOR3* LookAt, D3DXVECTOR3* Up );	void setPosition( float x, float y, float z );	void setCamView( IDirect3DDevice9** D3DDevice, D3DXVECTOR3, D3DXVECTOR3, D3DXVECTOR3 );	void setCamProj( IDirect3DDevice9** D3DDevice, float w, float h );	D3DXVECTOR3 getPosition();			void roll( float angle );	void yaw( float angle );	void pitch( float angle );	void strafe( float amount );	void fly( float amount );	void mouseStrafe( float xAmount, float yAmount );	void mouseLook( float xAmount, float yAmount );	void moveForward( float amount );protected:	D3DXVECTOR3 position; // Represent camera position.	D3DXVECTOR3 lookAt;	// Represent camera lookAt orientation.	D3DXVECTOR3 right; // Represent camera right orientation.	D3DXVECTOR3 up; //Represent camera up orientation.		float pitchAmount; // Rotate around the X axis.	float yawAmount; // Rotate arounf the Y axis.	float rollAmount; // Rotate around the Z axis.	D3DXMATRIX viewTransformMatrix;};#endif// ========= HEADER END ========== //// ========= updateViewMatrix() function ============= //......float x = -D3DXVec3Dot( &right, &position );float y = -D3DXVec3Dot( &up, &position );float z = -D3DXVec3Dot( &lookAt, &position );viewTransformMatrix._11 = right.x;viewTransformMatrix._12 = up.x;viewTransformMatrix._13 = lookAt.x;viewTransformMatrix._21 = right.y;viewTransformMatrix._22 = up.y;viewTransformMatrix._23 = lookAt.y;viewTransformMatrix._31 = right.z;viewTransformMatrix._32 = up.z;viewTransformMatrix._33 = lookAt.z;// ===== I DON'T FULLY UNDERSTAND THIS PART ========= //viewTransformMatrix._41 = x;viewTransformMatrix._42 = y;viewTransformMatrix._43 = z;


Now I understand that the dot product of 2 vectors will return a scalar value that tells me how similar the 2 vectors are.

And that the subtraction is there because basically I need to get the position of the camera to be at the origin. (eg 5 - 5 = 0, ok np's this makes sense)

I just do not know how the scalar value relates to the camera's position though?

Many thanks for the assistance guys :)

[Edited by - tenpoundbear on August 6, 2010 4:41:02 AM]
GregMichael
GregMichael
The 3x3 elements in your matrix are the "rotation" and the remaining parts, _41, _42, _43 are the "translation"
tenpoundbear
tenpoundbear
Yep. I get that.

But I don't understand this.
Quote:

I just do not know how the scalar value relates to the camera's position though?


I mean... dot product = how similar the 2 vectors are
eg. 0 = perpendicular
> 0 less then 90 degress
< 0 is greater than 90 degrees.

don't know how that relates to position?
Waaayoff
Waaayoff
I'm not 100% sure about this but i think this is how it works:

The values 41, 42 and 43 in the matrix are the negative dot product of the position vector and the corresponding camera's axis (up, right and lookat)

The dot product of a vector (position) and a UNIT Vector (Up, right or LookAt) will project the position onto the unit vector.

For example, the position vector of the camera is in relation to the world's x, y and z axis. The dot product of the position vector AND one of the camera's unit axis, will create a 'new' position vector relative to the camera's LOCAL axis.

This explains what i'm talking about: (Look at the "Projection of Vector onto another Vector" part)

Clicky
"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "
Buckeye
Buckeye
The dot product of a vector A with another vector B = |a||b|cos(theta).

where |a| is the length of vector A, |b| is the length of vector B, and theta is the angle between the 2 vectors.

right, up, and lookAt are vectors describing the camera's local axes in the world.

Because those 3 vectors are unit vectors, each length = 1.

So D3DXVecDot(&right,&position) = (1)*length(position)*cos(theta), or the "portion" of the camera's position along each of its local axes.

The right, up and lookAt vectors are used to fill the rotation portion of the viewmatrix. The dot products fill in the translation portion of the viewmatrix.

When a scene is rendered, each vertex that gets rendered is multiplied by worldMatrix * viewMatrix * projectionMatrix.

So vertex*worldMatrix is the position of the vertex in the world. The viewMatrix than transforms that world position into camera space. The projectionMatrix transforms the view space coordinates into screen space.
Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly. You don't forget how to play when you grow old; you grow old when you forget how to play.
Zakwayda
Zakwayda
You've already got your answer, but just to put it another way, the 'look-at' algorithm that you're referring to basically performs a manual inversion of the transform (in addition to creating an orientation that 'looks at' the specified target).

In general, a view transform is the inverse of the corresponding world transform, as its purpose is to transform geometry from world space into view space. You could just create a world matrix using the 'orientation' part of the 'look at' algorithm, and then invert it using a general matrix inverse function. However, because the special case of inverting a rigid body transform (rotation and translation only) is somewhat simpler than the general case, it's common to just do it manually.

If you work through the math of inverting a rigid body transform by hand, you'll see where the dot products come from.
tenpoundbear
tenpoundbear
I get all the theory stuff and everything you are saying.

I have just finished obtaining a more thorough understanding of dot product.

This code does the same thing essentially? Except the rotation and translation to view space are done automatically?
D3DXMatrixLookAtLH( &viewMatrix, &position, &lookAt, &up );


Where as in the OP, I guess that is doing it manually because we have a custom camera?

This is how I understand it, that is correct?
What I had trouble with before was the geometric interruption or meaning of it.

I just couldn't visually see how it was related... but I've done a few pratice problems and i think I get it now.

And now thinking back I think I understand what Waaayoff was trying to point out with the link as well
Quote:

This explains what i'm talking about: (Look at the "Projection of Vector onto another Vector" part)


Thanks guys Buckeye, jyk and everyone :)

Can I ask 1 more question? How would I make it so that my camera is always in the middle of my sphere (sphere geometry is generated manually btw)?

Just the theory is fine, but as complete as you can make it. I start a new post with code if I have trouble implementing it.

Thanks again guys :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.