Archived

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

How would you do it?

This topic is 5132 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''m very new to Direct3D and I''m having trouble coming up with a plan of attack for my 3D game/application. The game is a FPS which includes: - Terrain. - A gun model. - A number of stationary targets. (Billboards) Basically its just a shooting range. Now what I dont know how to do is matrices and vertex buffers. How do I go about moving the gun model around with the camera over the terrain. I will have my terrain as one model and the gun as another. Do I load them both into the same vertex buffer or do I need two. Do I use matrices to move the camera or do I move the terrain around the gun? I know its very basic but I just don''t get how it all fits together yet.

Share this post


Link to post
Share on other sites
well... your camera location is going to be defined in terms of the player position... the player position is defined by where the user directs the player. On a terrain, the users location is probably only required to be 2D (ie his grid coordinates on the map). From there, you find the terrain height at that point (simple 2D point in triangle check) then set the camera height to eye level above that point. You may wish to also use quadtrees for bigger terrains.

So now we have the required camera location. We have the terrian (or rather the individual quad tree nodes which contain relevant terrain) in separate vertex arrays if you wish. You could every make their rendering be a display list. A simple cull related to the quad tree would also help improve performance (eg don't render quad tree nodes behind the user). So now we have our terrain (in world coordinates) and our known camera location... A camera also needs a direction. The easiest way to keep this information is in euler angles.... to implement this in a system... that is direction (wrt fixed world axis), defined by 3 angles, y rotation, x rotation, and z rotation (ie rotation about each of these axes). So now you have a camera with a direction (this is a prerequisite for culling quadtree elements behidn the user).

Ignore the gun for now. We'll make the camera matrix first. basically to place an object (eg the camera) in the world, we would do the following:

Translate the origin to the required location of the object.

Rotate the axes to the appropriate orientation.

A camera matrix is effectively the inverse of this matrix. We can make this matrix using some simple rules of matrix multiplication, ie:

(A.B)^-1=A^-1.B^-1

ie we must reverse the order of the individual operations, as well as inversing each one... thus:

rotate by minus z angle

rotate by minus x angle

rotate by minus y angle

translate by negative of camera location.

With this, as the modelview matrix, all objects (in world coordinates) are converted to camera coordinates (ie they'll appear correctly as the camera moves).

Another useful fact, is that the inverse of a rotation matrix, is its transpose... thus, if (before applying the translation matrix) you get the first 3 rows of your rotation matrix... they represent the Right, Up and Backward vectors (in world coordinates) of the camera... These are useful, they tell you which direction the player wants to walk, run or strafe. After this, you can compound with a matrix to make the camera sway left or right or whatever if you wish (in fact, you should do this before making hte camera matrix, but overlook that for now :S).

So what now.. well, draw all the terrain in front of the player (no additional matrix required, as the terrain is stored in world coords)... and any objects (to do these, you push the current camera matrix... apply the object transform I described... draw the model, then pop the matrix back again for use with the next object).

At this point, you'll be able to draw your world, froma camera location, and have the camera placed where the player is in the world (appropriate height). Now back to the gun. The gun model moves with the camera... so rather than messing about with special transforms etc draw the gun, before you make the camera matrix. That means its coordinates will be relative to the screen (effectively). This means that you just translate it a bit in -ve z, and down a bit along y.. then maybe rotate or whatever. You can put any gun swaying in here too.

So now.. you've got a gun, a player on the terrain, adn a terrain and some objects. All you need now is to appropriately handle the mouse and keyboard (mouse to change the camera orientation... and keyboard with those right, up, backward vectors to move)... erm, a simply raytracing method probably for bullets... and voila, and entire game. I hope that helps :D.

EDIT: The other option for pointing the camera is to use gluLookAt btw, but this way is far more instructive in my opinion, and generally handy. gluLookAt normalises the up and forward vectors so it needs 2 sqrts. This method gives you unit vectors for right, up and back implicitly so I suspect that overall its less costly, or at least more handy. Also remember the direction that rotation around a vector is defined. It's clockwise, while looking along the vector.

[edited by - dmounty on November 28, 2003 8:02:03 PM]

Share this post


Link to post
Share on other sites
Direct3D is simple for this, because it has three matrices: WORLD, VIEW and PROJECTION.

Start with the Direct3D sample framework app generated by the AppWizard in MSDEV.

Where it draws a teapot, you should instead draw some number of things:

- your ground
- your gun
- your targets

The simplest way is to model each as a .x model and load that mesh using D3DXMesh.

Rendering then looks like:


convert camera (position/orientation of player) to VIEW matrix
d3d->SetTransform( D3DTS_VIEW, &matrix );
for each entity to render
convert position/orientation of entity to WORLD matrix
d3d->SetTransform( D3DTS_WORLD, &matrix );
d3d->SetTexture( texture for mesh );
mesh->DrawSubset( 0 );


When updating physics, you move the position and rotate the orientation of the camera (which is different from the sample framework app, which rotates the actual teapot mesh).

You will find that D3DXMatrixAffineTransformation() is just the ticket for rigging up a FPS-style camera. Here''s an excerpt from my D3D camera code:


class MyCamera {
D3DXVECTOR3 pos_, posInv_;
D3DXQUATERNION ori_, oriInv_;
D3DXMATRIX mat_;
public:
inline D3DXMATRIX const & getMatrix() const
{
return mat_;
}
inline void setPosOri( D3DXVECTOR3 const & v, D3DXQUATERNION const & q )
{
pos_ = v;
ori_ = q;
oriInv_ = D3DXQUATERNION( -q.x, -q.y, -q.z, q.w );
posInv_ = D3DXVECTOR3( -v.x, -v.y, -v.z );
D3DXMatrixAffineTransformation( &mat_, 1.f, &pos_, &oriInv_, &posInv_ );
}
inline void setPosHeadingTilt( D3DXVECTOR3 const & v, float hRad, float tRad )
{
D3DXQUATERNION q;
D3DXQuaternionRotationYawPitchRoll( &q, hRad, tRad, 0 );
setPosOri( v, q );
}
};


Typical use would be:


camera_.setPosHeadingTilt( playerPos, playerHeading, 0 );
d3dDev->SetTransform( D3DTS_VIEW, &camera_.getMatrix() );

Share this post


Link to post
Share on other sites