Sign in to follow this  

Object Rotation? How To Do It?

This topic is 4861 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 trying to get a better understanding of what some of the Direct3D examples I'm working with are really doing. I have one where there are 2 cubes in my scene and I want them to rotate about the y axis in their own object space while my camera rotates around the scene. I have... D3DXMatrixIdentity(&WorldMatrix); D3DXMatrixRotationY(&WorldMatrix, theta2); pD3D_Device->SetTransform(D3DTS_WORLD, &WorldMatrix); But when I do this, both cubes rotate aroudn the y axis, not around their origins. I guess it makes sense considering that it's tagged as a world transformation. I'm not sure how to do an object transformation. I would appreciate a push in the right direction. Also, while I'm posting, I read that D3DTS_WORLD is actually a macro and that "This macro is provided to facilitate porting existing applications to Microsoft® DirectX® 9.0". Is there a new way that we should be tagging a transformation as world? Is there a better way? The docs are a bit fuzzy for someone at my level.

Share this post


Link to post
Share on other sites
you multiply matrices (order is important).
First multiply it by the rotation, and then translation, which will have it spin in your translated spot. Do it the other way around, and the cube will turn all around the y axis by an offset of the translation. Play around with it, you'll soon be able to figure it out, just remember that rotation is dependent on where the object is.

device->SetTransform(D3DTS_WORLD, &(rotation*translation));

by the way, you don't have to set the identity. it does it for you, as well as in translations through the D3DX library.

matrix slots _41, _42, and _43 make up the xyz position of the matrix, so you don't even have to multiply it by a translation at the end.

do this:

rotmatrix._41 = your x;
rotmatrix._42 = your y;
rotmatrix._43 = your z;
device->SetTransform(D3DTS_WORLD, &rotmatrix);

which is faster (by very little). =)

Share this post


Link to post
Share on other sites
as for D3DTS_WORLD, there is also D3DTS_VIEW, and D3DTS_PROJECTION. three entirely different things. View just changes the position of the camera (actually, it's an inverse matrix and moves everything in the end to give the illusion, but it isn't important right now). For each object, you're going to be setting a world matrix, unless it uses the same one as before, all until you set a new world transform. Projection manipulates the screenspace of how things look on the screen, and the culling of objects too far / near to be seen. That's about it really... just play around with things, it'll all come naturally.

Share this post


Link to post
Share on other sites
Here's why my ignorance shines through. How do I translate one object? How do I rotate one object? It seems like D3DxMatrixTranslation and D3DXMatrixRotationY do their thing on the entire vertex list?

Does this sound right?

I guess the part of this that I don't understand is how to work with the transformations. I've got a vertex list and an index list. How do I tell Direct3D that I want this cube here and this cube there? And that I want one cube to rotate and the other cube to not rotate?

I do have a book I'm reading, but I'm impatient and wanting to ork ahead a bit. :)

I need some detail on the entire Direct3D pipeline. I don't think my book goes into enough detail.

Share this post


Link to post
Share on other sites
What you have to do is do the translation / rotation etc. for an object, apply the matrices and render that object. Rinse and repeat. So redo the matrices for the next object, apply them and render.

Synex

Share this post


Link to post
Share on other sites
I see. So I can use D3DXMatrixRotationY to build a matrix that will rotate around the y axis, then multiply each vertex for a given object by that matrix. Sounds good. Thanks. :)

Is there a better way to load and store objects than a single vertex list? I would like to tell Direct3D to multiply all vertices in a given list by a given matrix rather than have to pick and choose vertices from a single vertex list.

Would you use an indexed vertex list for each object? Is ther4e a function to multiply a vertex list and a matrix? I haven't found it yet.

You guys are the goods. Thanks for the help. This DirectX business is starting to feel natural. :)

Share this post


Link to post
Share on other sites
I did try it with 2 index / vertex buffers with their own calls to SetStreamSource and DrawIndexed Primitive with their own world transformations in between and this worked.

Is this the way it should be done? Is there a better way?

Share this post


Link to post
Share on other sites
It sounds like you have two objects in the same vertex buffer. Use SetTransform for each DrawPrimitive call. Since the DrawPrimitive call actually draws BOTH objects, it will only use the last World Transform that was set for it. What you need to do is separate the single vertex buffers into two vertex buffers OR call DrawPrimitive twice with different starting vertices and only draw one object each time.

for instance:

VB1 = Object1
VB2 = Object2

SetTransform(WORLD, SomeTranslationMatrix)
Draw Object1

SetTransform(WORLD, SomeRotationMatrix)
Draw Object2

OR

VB1 = 2 Objects

SetTransform(WORLD, SomeTranslationMatrix)
DrawPrimitive(TRIANGLE_LIST, 0, 1) // Draws 1st triangle

SetTransform(WORLD, SomeRotationMatrix)
DrawPrimitive(TRIANGLE_LIST, 3, 1) // Draws 2nd triangle

EDIT: Sorry, I didn't see the post previous to this. Yes, you have the right idea. It's not the only way though. If you use D3DXLoadMeshFromX, it will create a ID3DXMesh object that you can call DrawSubset(i) where i is the value of the subset you want to draw. This is the same concept of still having a SINGLE vertex buffer, but only drawing pieces of it at once. What happens is that the exporting program (say Truespace or Panda) will call anything that requires a separate material or texture a subset. As such, you would load the mesh file into your software, load all of the textures and copy all of the materials. Then you would know which texture and material matched which subset. So you would set the texture for subset 1, set the material for subset 1, then call DrawSubset(1). You put this in a for loop and it becomes easy to use multiple textured triangles in a single buffer.

Chris

Share this post


Link to post
Share on other sites

This topic is 4861 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this