Sign in to follow this  
drb2k2

Discuss Object rotations

Recommended Posts

Hi all, I've been struggling with object rotations for about 2 weeks now in one of my programs. Despite some good help from this forum I haven't been able to rectify the situation. Fortunately I work at a university and have spoken to a Math doctor about the problems My issue was that whenever I tried to do rotations on all three axis, one of them was always on the wrong axis. e.g. the X rotation would rotate around the X axis the y rotation would rotate around the Y axis and the z rotation would then rotate around the X axis. I put this down to the order of matrix multiplication and can see why it happens. Now here is the crunch. My discussion with the Math guy ended with him saying that you could not simply store the entire rotations up in one matrix. i.e. if you rotate by 20 degrees on the X axis and then rotate by another 20 degrees, you would have to lock the vertexbuffer at each rotation to do that, rather than just applying one cumulative rotation of 40 degrees. My question is, is this right? When playing games like Half-life2 and halo 2 its hard to imagine that when calculating the physics for making a crate crash down a hill that its vertexbuffer is being written to every frame of code. From what experience I have locking a vertex buffer is time consuming. Or do they simply keep the vertex buffer open? Anyones comments on this would be a great help to me as I am having difficulty with it. Cheers DRB2k2

Share this post


Link to post
Share on other sites
There is no need to change the VertexBuffer for rotation, scaling and tranlation. The only thing you'd change the VertexBuffer for is internal animation like an arm moving, but if you wish, you could put the arm in a different VB and use matrix transformations to animate it. So locking the VB is kind of extreme for your purposes.

As for your rotation problem, could you perhaps show us some code? You should very well be able to rotate on the 3 axes at once.

Share this post


Link to post
Share on other sites
OK guys here is the code for you.

Note some of it may be commented out, and it may look a bit strange in places,
I was basically desperate to try virtually anything to get it to work
The user has 3 spinners, an X Y Z which change the models rotation
(Me.ObjectDetailsList(Me.WhichObj).Rotation)
The v1,v2,v3 stuff was just a test so ignore that, basically this code doesn't work so please don't nit pick over small points, There is something fundamentally wrong with this entire approach

Dim qRot As Microsoft.DirectX.Quaternion
Dim RadianRot As Microsoft.DirectX.Quaternion
Dim RotMatrix As Microsoft.DirectX.Matrix = Matrix.Identity

RadianRot.X = System.Math.PI * Me.ObjectDetailsList(Me.WhichObj).Rotation.x / 180
RadianRot.Y = System.Math.PI * Me.ObjectDetailsList(Me.WhichObj).Rotation.Y / 180
RadianRot.Z = System.Math.PI * Me.ObjectDetailsList(Me.WhichObj).Rotation.Z / 180

qRot = Quaternion.RotationYawPitchRoll(RadianRot.Y, RadianRot.X, RadianRot.Z)

Dim matX, matY, matZ As Matrix
'matX = Matrix.RotationX(RadianRot.X)
'matY = Matrix.RotationY(RadianRot.Y)
'matZ = Matrix.RotationZ(RadianRot.Z)
Dim v1, v2, v3 As Microsoft.DirectX.Vector3
v1 = New Microsoft.DirectX.Vector3(1, 0, 0)
v2 = New Microsoft.DirectX.Vector3(0, 1, 0)
v3 = New Microsoft.DirectX.Vector3(0, 0, 1)
v1.TransformCoordinate(Matrix.RotationQuaternion(qRot))
v2.TransformCoordinate(Matrix.RotationQuaternion(qRot))
v3.TransformCoordinate(Matrix.RotationQuaternion(qRot))
v1.Normalize()
v2.Normalize()
v3.Normalize()

matX = Matrix.RotationAxis(v1, RadianRot.X)
matY = Matrix.RotationAxis(v2, RadianRot.Y)
matZ = Matrix.RotationAxis(v3, RadianRot.Z)

RotMatrix = Matrix.Multiply(matX, matY)
RotMatrix = Matrix.Multiply(matZ, RotMatrix)

Dim q As Quaternion = Quaternion.RotationMatrix(RotMatrix)

q = qRot

RotMatrix = Matrix.Identity
Dim cent As Microsoft.DirectX.Vector3 = Me.ObjectDetailsList(Me.WhichObj).Center
RotMatrix.AffineTransformation(1, cent, q, New Microsoft.DirectX.Vector3(0, 0, 0))

RotMatrix = Matrix.Multiply(RotMatrix, Me.device.Transform.World)

Me.device.SetTransform(TransformType.World, RotMatrix)
Me.device.RenderState.Lighting = True
device.SetStreamSource(0, Me.ModelVertexBuffer, 0)
device.VertexFormat = CustomVertex.PositionNormal.Format
device.DrawPrimitives(PrimitiveType.TriangleList, 0, Me.FacetCount)



Cheers
DRB2k2

Share this post


Link to post
Share on other sites
Okay i've now changed the rotation code.
Basically nothing is stored in the object rotation value anymore.
Instead I just calculate a rotation matrix(RotMatrix) for each axis, with the RELATIVE amount
in degrees changed since the last rotation, then do this calculation


Dim VectorTemp As Microsoft.DirectX.Vector3
For i = 0 To verts.GetLength(0) - 1
VectorTemp = verts(i).Position
VectorTemp.TransformCoordinate(RotMatrix)
verts(i).Position = VectorTemp
Next
Me.ModelVertexBuffer.Unlock()


This method does work althoug it is a bit slow on my 80,000 vertex model, but not so much that you'd really notice.
It therefore seems to me that the matrix concatenation was the problem as suspected.
You guys say that it should be able to do rotations without needing to lock the buffer. Can any of you give me a quick explanation as to how you do this? I'm not looking to snatch code, but when I come to write some games every bit of speed helps :) and this would just slow the program down.

Cheers
DRB2k2

Share this post


Link to post
Share on other sites

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