Jump to content
  • Advertisement
Sign in to follow this  
Schnozzinkobenstein

My 3D Camera Implemented

This topic is 3170 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'd really appreciate some critique on my camera system if you guys could take the time. I couldn't easily find any resources on camera systems so I came up with my own. My camera system works as such: I keep track of the position of the camera in a 3d array and update that as need be. The point at which the camera is stored as an offset of the camera's position (in another 3d array),together, these two points create vector that is always of length "camRadius". I also store the camera's current rotation relative to the world in a 2d array (along two planes). So if the camera is at the world origin looking straight ahead and straight up:
camPos={0,0,0}
rot[X]=90 //facing forward
rot[Y]=90 //facing up
lookOffset = { camRadius*cos(rot[X]), camRadius*sin(rot[Y]), camRadius*sin(rot[X]) }
I decided to use an absolute point and a relative point with the angle of rotation rather than two absolute points because it got rid of the necessity of calculating the dot product to figure out camera movements due to character movement (e.g. walking, as opposed to looking elsewhere). So whenever I recalculate the camera, this is what my Eye and At are set as:
D3DXVECTOR3 Eye(camPos);
D3DXVECTOR3 At(camPos[X]+lookOffset[X],camPos[Y]+lookOffset[Y],camPos[Z]+lookOffset[Z]);
When the player moves (e.g. walks), I define an axis relative to the camera's facing (rot[X]) and find the change in value for the camPos on the horizontal plane. So, for example, when the player presses the "forward" button:
camPos[X]+=magStep*cos(rot[X]);
camPos[Z]+=magStep*sin(rot[X]);
"magStep" is just a multiplier used to reduce movement to a realistic rate. When the camera needs to look in another direction based off of mouse movement, I find the new angle of rotation for the camera in the world coordinates, based off of mouse movement:
rot[X]=rot[X]-atan2(mouseDX,camRadius);
Which gives me the new offset amount from the camera's position:
lookOffset[X]=camRadius*cos(rot[X]);
lookOffset[Z]=camRadius*sin(rot[X]);
So putting it all together:
OnMouseMove{
   //XZ axis
   rot[X]=rot[X]-atan2(dx,camRadius);
   lookOffset[X]=camRadius*cos(rot[X]);
   lookOffset[Z]=camRadius*sin(rot[X]);

   //YZ axis
   rot[Y]=rot[Y]-atan2(dy,camRadius);
   lookOffset[Y]=camRadius*sin(rot[Y]);

   D3DXVECTOR3 Eye(camPos);
   D3DXVECTOR3 At(camPos[X]+lookOffset[X],camPos[Y]+lookOffset[Y],camPos[Z]+lookOffset[Z]);
   D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
}
OnKeyPress{
        //strafe right
	if (KEYDOWN(buffer, DIK_D))
	{	
		camPos[X]+=magStep*cos(rot[X]-3.14f/2);
		camPos[Z]+=magStep*sin(rot[X]-3.14f/2);
	}
	// strafe left
	if(KEYDOWN(buffer, DIK_A))
	{
		camPos[X]-=magStep*cos(rot[X]-3.14f/2);
		camPos[Z]-=magStep*sin(rot[X]-3.14f/2);
	}
	//move forward
	if (KEYDOWN(buffer, DIK_W))
	{
		camPos[X]+=magStep*cos(rot[X]);
		camPos[Z]+=magStep*sin(rot[X]);
	}
	//move backward
	if(KEYDOWN(buffer, DIK_S))
	{
		camPos[X]-=magStep*cos(rot[X]);
		camPos[Z]-=magStep*sin(rot[X]);
	}
	D3DXVECTOR3 Eye(camPos);
	D3DXVECTOR3 At(camPos[X]+lookOffset[X],camPos[Y]+lookOffset[Y],camPos[Z]+lookOffset[Z]);
	D3DXMatrixLookAtLH( &g_View, &Eye, &At, &Up );
}

This all works. I would just appreciate some feedback on it. Is there a less computationally intensive way to do this? Is there a way that allows for easier expansion of the system if necessary in the future? Anything would be appreciated. :) P.S. My plus signs aren't showing up...?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
P.S. My plus signs aren't showing up...?
Plus signs don't show up in preview mode, but they will show up in your post.

I'll start with a simple question: why is rotation about the y axis stored in rot[X]? What does the 'X' mean in this context?

Share this post


Link to post
Share on other sites
I was thinking less about which axis it was rotating about and more about which direction it was rotating. Rotating left and right is the "X" direction, and up and down is the "Y" direction. It's just how it made sense to me when I was setting it up.

Something else I forgot to add was that I don't change lookOffset[Z] according to the Y movement of the mouse. It is not possible to do this with my current system's setup. I would have to change it so that lookOffset values are incremented rather than set to an absolute value like they are now. I didn't see a problem with this, as I have limiters implemented that limit how far up and down the camera can point. So if one was to map all possible points of lookOffset from one camPos, one would get a cylinder rather than a sphere, since the camera's "At" point only changes depth when the camera rotates along the XZ axis. I also have limiters on the value of rot[X] so that it cannot overflow from constant rotating in one direction.

Share this post


Link to post
Share on other sites
Quote:
Ever so helpful. Thanks guys.
Before responding (and perhaps being off-base), let me ask, just to be sure: are you being sarcastic?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!