Implementing Quaternions
BlitzMax Forums/MiniB3D Module/Implementing Quaternions
| ||
I am going to be working on adding quaternions rotation today. I am also working with the modelview matrix scaled 0,0,-1 after the camera is oriented, because this eliminates the need for flipped positions, and gets rid of a lot of wackiness. I'll be on MSN under ___________, if anyone with a good knowledge of this is available. I have done quat -> mat and back before, but it is still going to be tricky. I'll post whatever I come up with, so you can use it with minib3d or whatever. |
| ||
Okay, my quat code worked right off the bat. Run this in Blitz3D and you will see it produces identical results: Now added additional matrix rotation methods based on quaternions: |
| ||
Okay, it seems to work when you find every instance of -rx or -z and don't flip them. The only thing I am not sure how to do is retrieve the global quaternion. I've got it pretty close here, which shows how to extract a quat from a mat, but the signs get flipped randomly: |
| ||
Well, I have been trying all day, and I can't get this to work right. Without proper rotation, animation is impossible. |
| ||
Would it be worth looking at Blit3d's Geometry code that Mark posted as a sticky in the Blitz3d programming forum? |
| ||
DAMN I finally got it working. I parented one mesh to another and randomly spun the parent around on the screen. When I click the mouse, the child mesh gets parented to either the center mesh or the world. When I change the parenting, the mesh stays perfectly in place, no matter what crazy angle is happening. Here, see for yourself: http://www.leadwerks.com/post/quat.zip It will take some time to clean this up, but the hard part is done. I'm going to go drink now. This extracts a quaternion from a matrix: Method ExtractQuat() fourWSquaredMinus1:Float = +grid[0,0]+grid[1,1]+grid[2,2] fourXSquaredMinus1:Float = +grid[0,0]-grid[1,1]-grid[2,2] fourYSquaredMinus1:Float = +grid[1,1]-grid[0,0]-grid[2,2] fourZSquaredMinus1:Float = +grid[2,2]-grid[0,0]-grid[1,1] biggestIndex=0 fourBiggestSquaredMinus1:Float=fourWSquaredMinus1 If fourXSquaredMinus1 > fourBiggestSquaredMinus1 fourBiggestSquaredMinus1 = fourXSquaredMinus1 biggestIndex=1 EndIf If fourYSquaredMinus1 > fourBiggestSquaredMinus1 fourBiggestSquaredMinus1 = fourYSquaredMinus1 biggestIndex=2 EndIf If fourZSquaredMinus1 > fourBiggestSquaredMinus1 fourBiggestSquaredMinus1 = fourZSquaredMinus1 biggestIndex=3 EndIf biggestValue:Float=Sqr(fourBiggestSquaredMinus1+1.0)*0.5 mult:Float=0.25/biggestValue Select BiggestIndex Case 0 w#=BiggestValue x#=(grid[1,2]-grid[2,1])*mult y#=-(grid[2,0]-grid[0,2])*mult z#=-(grid[0,1]-grid[1,0])*mult Case 1 x#=-BiggestValue w#=-(grid[1,2]-grid[2,1])*mult y#=(grid[0,1]+grid(1,0))*mult z#=(grid[2,0]+grid[0,2])*mult Case 2 y#=BiggestValue w#=-(grid[2,0]-grid[0,2])*mult x#=-(grid[0,1]+grid(1,0))*mult z#=(grid[1,2]+grid[2,1])*mult Case 3 z#=-BiggestValue w#=(grid[0,1]-grid(1,0))*mult x#=(grid[2,0]+grid[0,2])*mult y#=-(grid[1,2]+grid[2,1])*mult EndSelect If w<-0.0 x=-x y=-y z=-z w=-w EndIf VECTOR_X=z VECTOR_Y=x VECTOR_Z=y VECTOR_W=w EndMethod |
| ||
Damn fine work, I'm fixing a drink in your honor. |
| ||
Scale is very hard to work into this. I might just let that go, since the only reason you would need it is if you are writing a mesh editor. If one of the main programmers of this wants to email me, I will give you as much code and info as I can. I don't really want to put together a patch, because there are a lot of extra entities and things in MiniB3D I don't want to mess with. One of the main changes I made was flipping the Z-axis, so positions and rotations can be stored with their true values, and the original triangle order is right. However, a lot of code was written on top of a faulty foundation, and it all needs to be fixed to work right. You vertex positions and normals will be reversed now, because they are being rendered the same as in Blitz3D. Anyone know how to extract the scale from a rotated matrix? I thought I could just get the magnitude of each row, but that doesn't account for rotation. |
| ||
Personally I wouldn't bother struggling with this. I'm not sure it's worth the effort - all you're gaining is a slightly more robust EntityParent and the potential for a better TurnEntity (if implemented). Otherwise, there are no benefits, as MinB3D works the same as Blitz3D in all other areas as far as I'm aware. Also, the aformentioned issues will be fixed at some point. |
| ||
I think it's a great idea using quaternions ! It permits lots of things like easy PointEntity, AlignToVector or Slerp functions... It also reduces operators from 45 for matrix rotations to 28 for quaternions Other : Try to make a TurnEntity local using matrix... using quaternions, it's easy as qf=q0*qd ( where qf is the final rotation, q0 is the initial one, and qd is the delta rotation ) I think MiniB3d has implemented matrix, but no support for quat, and that's a big problem. you can't optimise calculs anymore, and no ability to have better entity system. That's the reason why I finally attempt to do my own engine+wrapper. What i don't understand is : @SimonH => you released the bmax maths library, translated from mark's code... why don't you use it instead of matrix bases ? |
| ||
does it still work using fitmesh? |
| ||
strange the turnentity function I posted on the forum works with what im using it for and still allows all the commands to work perfectly (Even my testers have tested it fine). |