This topic is now archived and is closed to further replies.

camera movement

This topic is 5095 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am trying to get the camera to move foward towards the direction it is currently facing. My code seems to suck the camera towards the origin no matter which direction it is facing. The function to do so is CamerLH::MoveZ(float speed); My yaw pitch and roll functions seem to work ok. Anyone have any ideas on how to fix the following code?
#ifndef CAMERA_H
#define CAMERA_H

// camera.h


// A 3D camera


// Christopher Pisz

// 01/04/04


#include <d3dx9.h>

class CameraLH
	CameraLH(D3DXVECTOR3 &position = D3DXVECTOR3( 0.0f,  0.0f, -5.0f),
			float xan = 0.0f, float yan = 0.0f, float zan = 0.0f);

	// Accessors

	D3DXMATRIX * GetMatrix(D3DXMATRIX * in);

	// Mutators

	void Yaw  (float angle, bool relative);
	void Pitch(float angle, bool relative);
	void Roll (float angle, bool relative);
	void MoveZ(float speed);

	D3DXMATRIX  m_rotation;      // The rotation matrix           

    D3DXMATRIX  m_translation;   // The translation matrix


#endif //CAMERA_H


// camera.cpp


// A 3D camera


// Christopher Pisz

// 01/04/04


#include "camera.h"


CameraLH::CameraLH(D3DXVECTOR3 &position, float xan, float yan, float zan)
	m_translation._41 =  -position.x;
	m_translation._42 =  -position.y;
	m_translation._43 =  -position.z;

	D3DXMatrixRotationYawPitchRoll(&m_rotation, -yan, -xan, -zan);




void CameraLH::Yaw(float angle, bool relative)
	D3DXMatrixRotationY(&yaw, -angle);
		m_rotation = m_rotation * yaw;
		m_rotation = yaw * m_rotation;


void CameraLH::Pitch(float angle, bool relative)
	D3DXMATRIX pitch;
	D3DXMatrixRotationX(&pitch, -angle);
		m_rotation = m_rotation * pitch;
		m_rotation = pitch * m_rotation;


void CameraLH::Roll(float angle, bool relative)
	D3DXMatrixRotationZ(&roll, -angle);
		m_rotation = m_rotation * roll;
		m_rotation = roll * m_rotation;


void CameraLH::MoveZ(float speed)
	// The only data we have is the translation and rotation

	// matrices that made up the last view matrix, we want to

	// move the camera towards the point it is currently facing

	D3DXVECTOR3 axis_z, position, temp;
	// Extract the foward vector

	axis_z.x = m_rotation._31;
	axis_z.y = m_rotation._32;
	axis_z.z = m_rotation._33;

	D3DXVec3Normalize(&axis_z, &axis_z);

	m_translation._41 = m_translation._41 + (speed * axis_z.x);
	m_translation._42 = m_translation._42 + (speed * axis_z.y);
	m_translation._43 = m_translation._43 + (speed * axis_z.z);



D3DXMATRIX * CameraLH::GetMatrix(D3DXMATRIX * in)
	return D3DXMatrixMultiply(in, &m_translation , &m_rotation);


// driver.cpp


// Drawing basic primitives with Direct3D


// Christopher Pisz

// 11/06/02


CameraLH g_camera(D3DXVECTOR3( 0.0f, 200.0f, 0.0f),    // Camera object

				  PI / 2, 0, 0);

// Process Input


void ProcessInput()
	// If the 's' key is pressed move foward


	// If the 'a' key is pressed look towards the left

		g_camera.Yaw(-0.01f, true);

	// If the 'd' key is pressed look towards the right

		g_camera.Yaw( 0.01f, true);
	// If the 'w' key is pressed look up

		g_camera.Pitch(-0.01f, true);
	// If the 'x' key is pressed look up

		g_camera.Pitch( 0.01f, true);

	// If the 'e' key is pressed roll right

		g_camera.Roll(-0.01f, true);

	// If the 'q' key is pressed roll left

		g_camera.Roll(0.01f, true);




void Render()
	// Check for valid device

        throw Error("No valid device",
				"Render()", "driver.cpp");

    // Clear the backbuffer

			D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

	// Set render states

	g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 
	g_device->SetRenderState(D3DRS_LIGHTING, FALSE); 
    g_device->SetRenderState(D3DRS_AMBIENT, 0xffffffff);
	// Wireframe 

    g_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
	// Set the view matrix

	g_device->SetTransform(D3DTS_VIEW, g_camera.GetMatrix(&g_matrix_view));

	// Begin the scene

	// Draw the terrain

    // End the scene

    // Present the backbuffer contents to the display

Thanx, brekehan [edited by - brekehan on January 5, 2004 5:29:55 AM]

Share this post

Link to post
Share on other sites
hi, im talking a look at your code right now and it strikes me
that your class is very expensive performance wise..

every one of your functions operates on your matrix class, this is about 7-19 float operations per call if multiplying by a
vector and anywhere between.

what you should do is instead store the roll, pitch, yaw and
calculate everything once per frame, this way you can optimize
out redundant operations and function calls

if you did this, when you call a function to set the roll,
pitch yaw etc, all you have to do is a simple float copy so there
isnt much performance hit when compared to 16 float operations
is there ?

anyway back to figuring out your actual problem
i''ll post later if i figure it out, sorry if i was no help to
you (as of yet)..

Share this post

Link to post
Share on other sites
ok heres how you would do it the way i mentioned above..

add this code to a function nameed MoveCamera or something
and call it once before rendering (ie. when seting up the cam
matrix for the frame)

this creates the 2 vectors you need to setup the matrix
use a function like 3D3XLookAt

float cos_yaw = cos(yaw);
float sin_yaw = sin(yaw);
float sin_pitch = sin(pitch);
float cos_pitch = cos(pitch);

position.x += cos(yaw + 90.0)) * strafe_speed;
position.z += sin(yaw + 90.0)) * strafe_speed;
position.x += cosYaw) * speed;
position.z += sinYaw) * speed;

VECTOR3 view_vector; // Init a vVector for our view

// Get our view vVector (The direciton we are facing)

view_vector.x = look_at.x - position.x; // This gets the direction of the X

view_vector.y = look_at.y - position.y; // This gets the direction of the Y

view_vector.z = look_at.z - position.z; // This gets the direction of the Z

position.y += view_vector.y * speed; // Add our acceleration to our position''s Y

// added *cosPitch

look_at.x = position.x + cos_yaw * cos_pitch;
look_at.y = position.y + sin_pitch;
look_at.z = position.z + sin_yaw * cos_pitch;

im not a directx coder but i think the code (from memory)
to set the view matrix is something like this:

D3DXMATRIX mat_view;
D3DXMatrixLookAtLH( mat_view,
D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );

d3d_device->SetTransform( D3DT_VIEW, &matView );

Share this post

Link to post
Share on other sites
If I store yaw pitch and roll like you said I will not be able to turn the camera relative to its own axi, but only the world.

I didn''t want to use D3DXLookAt because it needs to know the up and has many problems when the camera looks staright up or down.

But I do think it is a good idea to use vectors instead of the matrices.

Share this post

Link to post
Share on other sites

you do realize that your "relative" flag does nothing in your yaw pitch roll funcs? m_rotation * yaw = yaw * m_rotation

oh yes it does. they are certainly not equal at all. the relative flag determines the order of multiplication which determines if we are in camera space or world space. Read the SDK..."The order in which the matrix multiplication is performed is crucial. The preceding formula reflects the left-to-right rule of matrix concatenation. That is, the visible effects of the matrices that you use to create a composite matrix occur in left-to-right order. " Not to mention I have the program right here which says otherwise unless my eyes are lieing to me, but they have always beem so faithful.


Share this post

Link to post
Share on other sites