How to move meshes in d3d

Started by
17 comments, last by hammer_bg_ 19 years, 10 months ago
D3DXMATRIXTRANSLATION(tmpmat, mesh_x, mesh_y, mesh_z);
mesh_x, mesh_y, mesh_z how do i get these, to be precise how do i get the coordinates of a mesh ?
Advertisement
When you set the world transformation, every object after that uses that same transformation. So, if you have two meshes, you would want to set the world transformation to Identity matrix after you've drawn the first mesh. That's assuming you want the second mesh to be displayed at the middle of the universe.

The identity matrix basically means no rotations, no translations, and no scaling. So, after setting the world transform to the identity matrix, the next series of meshes to be drawn will be in the center of the universe (Assuming that they were saved to file with their center at (0,0,0)).

Chris

[edited by - Supernat02 on June 12, 2004 12:22:10 AM]
Chris ByersMicrosoft DirectX MVP - 2005
okay now i am completely lost
nevertheless thanks for all the replies, i will try to do something later when i am not soo sleepy
When you get some rest, come back and explain what it is you don''t understand. The basic idea is that each object in your world will have it''s own transformation matrix associated with it.

Here''s some pseudocode to help explain how rendering would work.
for( each mesh in your scene ){  mesh.SetWorldTransform();  mesh.Render();} 

The pseudocode function SetWorldTransform just creates a matrix to position your object somewhere in 3D space and then calls the IDirect3DDevice9::SetTransform to let D3D know about the matrix.

Try not to get too frustrated. Matrix transformations are one of the more difficult topics for beginners to wrap their heads around. We all went through the same thing you''re going through at one point or another.

neneboricua
okay so its time to begin the torture
So i''m gonna start from the beginning.
The idea is to create a couple of primitives (in my case boxes) and move one of them via the directinput.

Okay so far i''ve initialized d3d, created a viewport/camera (or whatever else its called), created 2 boxes and handled the dinput.
The problem is that when i press a key thats assigned to move a box, both of the boxes move

D3DXMatrixRotationX(matRotation, (D3DX_PI/180.0)*0.0); // rotation of the object
D3DXMatrixTranslation(matTranslation, fboxx, fboxy, fboxz); // coordinates
D3DXMatrixMultiply(matFinal, matRotation, matTranslation); // i have no idea what this is for but it is needed
m_pd3dDevice.settransform(D3DTS_WORLD, matfinal); // and finally apply the matfinal matrix to the d3d world.

so my guess is thats i cant differ the matrixes or whatever d3d uses to distinguish objects, and thus all of the objects on the world move.
Someone told me that i need to create a custom class of a mesh and a matrix to contain the matrix information of the mesh.
So i ask you guys how the heck is the best way to do it?

well i think thats for now.
i''m waiting for replies.
thanks in advance.
You need to set the transformation matrix for EACH box, so for just 2 boxes, you would do that same code twice:

//// Define position and rotation for fbox1 //  (fbox1rot, fbox1x, ect..) and for fbox2,//  and modify them via your response to DInput//  appropriately//D3DXMATRIX matTranslation, matRotation, matFinal;D3DXMatrixRotationX(&matRotation, fbox1rot);D3DXMatrixTranslation(&matTranslation, fbox1x, fbox1y, fbox1z);D3DXMatrixMultiply(&matFinal, &matRotation, &matTranslation);m_pd3dDevice.settransform(D3DTS_WORLD, matfinal);//// Draw first object (fbox1) here...//D3DXMATRIX matTranslation, matRotation, matFinal;D3DXMatrixRotationX(&matRotation, fbox2rot);D3DXMatrixTranslation(&matTranslation, fbox2x, fbox2y, fbox2z);D3DXMatrixMultiply(&matFinal, &matRotation, &matTranslation);m_pd3dDevice.settransform(D3DTS_WORLD, matfinal);//// Draw second object (fbox2) here...//   


Oh, BTW you need the D3DXMatrixMultiply to apply the rotation and translation to the object via matFinal. The cool thing about these matrices is that by multiplying them together you can apply their tranforms (rotation, and then translation) in order, but with just a single matrix.

[edited by - nerdboy80 on June 13, 2004 7:42:06 PM]
Oh, and this is NOT the way you want it forever, just to get it working, in the general case you want to loop through all your objects, and store the roation (fbox*rot) and translation (fbox*x, ect...) with each mesh object (or some other object which contains the mesh as one of it's members)

[edited by - nerdboy80 on June 13, 2004 7:45:50 PM]
okay so i''ll paste some code cous i am not sure if i am doing things right.

the code is in delphi but the d3d api is the same as vc++

so here is the f() in which i update the possition of the boxes.

function CMyD3DApplication.UpdateFBox(Dimension,PlusMinus:char; value : single) : HRESULT;
var
matTranslation, matRotation, matFinal : TD3DXMATRIX;
begin
if Dimension <> ''0'' then begin
if PlusMinus = ''+'' then begin
if Dimension = ''x'' then fboxx:=fboxx+value;
if Dimension = ''y'' then fboxy:=fboxy+value;
if Dimension = ''z'' then fboxz:=fboxz+value;
end
else begin
if Dimension = ''x'' then fboxx:=fboxx-value;
if Dimension = ''y'' then fboxy:=fboxy-value;
if Dimension = ''z'' then fboxz:=fboxz-value;
end;
end;

D3DXMatrixRotationX(matRotation, (D3DX_PI/180.0)*0.0);
D3DXMatrixTranslation(matTranslation, fbox2x, fbox2y, fbox2z);
D3DXMatrixMultiply(matFinal, matRotation, matTranslation);
m_pd3dDevice.settransform(D3DTS_WORLD, matfinal);


D3DXMatrixRotationX(matRotation, (D3DX_PI/180.0)*66.0);
D3DXMatrixTranslation(matTranslation, fboxx, fboxy, fboxz);
D3DXMatrixMultiply(matFinal, matRotation, matTranslation);
m_pd3dDevice.settransform(D3DTS_WORLD, matfinal);


end;

but ofcourse both of them are moving again. i still dont understand how d3d recognize which object is where and which object is which without the matrixes.
ou and this function is called every time when a key is pressed and its assigned to move the boxes.
also its called before beginscene, and one more last thing i initialize the boxes with:

D3DXCreateBox(m_pd3dDevice,1,1,1 , fBox,nil);
D3DXCreateBox(m_pd3dDevice,2,2,0 , fBox2,nil);

Once you assign a matrix to the device, all subsequent drawing operations use that matrix. So:


  1. Set object 1''s matrix
  2. Draw object 1
  3. Set object 2''s matrix
  4. Draw object 2
  5. repeat previous steps for all distinct objects.


Direct3D device is a state machine, that is, it always uses the current rendering settings set by SetRenderState, SetTransform, SetTexture etc.. When you change these states, any drawing afterwards use the states as stored in the device object.

Niko Suni

I would suggest reading some books for beginner DirectX, because some key concepts like this are usually covered. The main one here is that you set the rendering pipeline states first, then you commit it for a series of vertices.

In other words, you tell the video card "I want you to blend things this way, move things to this spot, etc" and then you say "Okay, now draw these things like that". This is repeated for every object that isn''t similar in the game.

For instance, if you have 2 boxes that need to be moved to two different places each frame (One standing still is considered moving it to the same place it was the previous frame), then those are two separate draws, because one or more states of the render pipeline have to change between the two boxes (the state being the world transformation).

To commit a set of vertices to the states you just set on the render pipeline, you use the draw primitive calls, of which the most used are DrawPrimitive, DrawIndexedPrimitive, DrawPrimitiveUP (User Pointer I think), and something else. Anyway, those are THE functions that commit the states you just set the video card up for.

So, as Nik02 said, you set the transform (and anything else that might affect that particular object) then draw it with DrawPrimitive.

You''ll have to modify your function from being an Update function to being a Draw function. It updates the render pipeline states per object, then draws the object. This is where knowing the transform for each object will come in handy. If you know Object[1] needs to be drawn, then you can SetTransform(WORLD_TRANSFORM, ObjTransform[1]); and then DrawPrimitive(...).

Now, once you get that concept under your belt, you''ll want to learn about batching. If the texture for 10 objects is the same, then call SetTexture one time and DrawPrimitive 10 times. The idea here is to only change the states of the pipeline when you need to.

Good luck,
Chris
Chris ByersMicrosoft DirectX MVP - 2005

This topic is closed to new replies.

Advertisement