Calculate force and torque to interpolate between 2 mat4s

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Leadwerks » Tue Jan 13, 2009 10:41 pm

Using the ACos() code, I run into the problem of the object taking the longer route to reach the desired angle, at certain angles. Using the code I posted, here is the behavior. This is using a large dt value to make the rotation smoothed:
http://www.leadwerks.com/post/omega3.wmv

With a higher smoothing value, here you can see the body always takes the closest approach to reach the desired orientation:
http://www.leadwerks.com/post/omega4.wmv

I believe you, but I shouldn't have to write out a bunch of formulas on paper just to figure out how to rotate an object. I think that would be more useful as a basic command in the library. How many of your users even know what a quaternion is?
User avatar
Leadwerks
 
Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

Re: Calculate force and torque to interpolate between 2 mat4s

Postby JernejL » Wed Jan 14, 2009 5:47 am

Leadwerks wrote:How many of your users even know what a quaternion is?


This does make a good point, i personally don't know what a quarternion is in math-sense, all i know is it has 4 values, it fixes gimbal lock and sometimes it's useful, when it works i think of it as "magic" or something - i never study how underlyning formulas work as i'm not good with it, i was never that good with math and physics, i'm better at rendering graphics and making game logic.. :oops:
Help improving the Newton Game Dynamics WIKI
User avatar
JernejL
 
Posts: 1531
Joined: Mon Dec 06, 2004 2:00 pm
Location: Slovenia

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Dave Gravel » Wed Jan 14, 2009 10:53 am

I have already make some test in 3d with quarternion and I have get problem with the gimbal look limitation.
I know it is possible to over pass this but I don't know how and I think it cost more too.
I never have success to make a continuous rotation with quarternion, I have all times back with matrix rotation.

Maybe this link can help you.
http://www.euclideanspace.com/physics/k ... /index.htm
http://www.koders.com/cpp/fid38F83F165A ... %3Acompute
ReturnMatrix Omega(const Quaternion & q, const Quaternion & q_dot)
You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://www.facebook.com/dave.gravel1
http://orionx3d.googlepages.com/
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 725
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Julio Jerez » Wed Jan 14, 2009 5:41 pm

the thing is that the function In teh SDK is what to do what you need to do exatly what you want.

are you expectiong the diferent in rotation to be larger than 180 dregree?
the funtion tah you want is ginet tow 4 x 4 matrices calutale teh angule velocity the will rotate matrix one on ot matrix tow?
and you wan this value to be laregt that 180 gregree

Code: Select all
void CalculateToOmegaFromMatrix (vector omegaOut, matrix A, marix B, float time)
{
...
...
}

I will post the code in the FAQ tonight?
Julio Jerez
Moderator
Moderator
 
Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Leadwerks » Wed Jan 14, 2009 6:04 pm

the thing is that the function In teh SDK is what to do what you need to do exatly what you want.

That is not completely true. I already demonstrated your code has an error, in that it sometimes chooses the longer route (>180 degrees) to rotate around. I did, however, find a fix that uses your ACos() recommendation. If the m_q0 ("w" for my quaternions) term is greater than zero, the other terms of the quaternion need to be flipped. Here is my final code:
Code: Select all
   Method CalcAverageOmega:TVec3( QB:TQuat, dt:Double=1.0 )
      
      Const REALLYSMALLNUMBER:Double=0.00001
      Local dirMag:Double
      Local dirMag2:Double
      Local omegaMag:Double
      Local dirMagInv:Double
      Local dq:TQuat
      Local omegaDir:TVec4
      Local dq2:TQuat
      Local scale:Float
      
      dq=Inverse().Times(QB)      
      omegaDir=vec4(dq.x,dq.y,dq.z,dq.w)
      dirMag2=omegaDir.dot(omegaDir);
      If dirMag2<REALLYSMALLNUMBER*REALLYSMALLNUMBER Return vec3(0)
      dirMagInv=1.0/Sqr(dirMag2)
      omegaMag=2.0*ACos(dq.w)/dt
      If omegaDir.w>0.0
         omegaDir.x:*-1.0
         omegaDir.y:*-1.0
         omegaDir.z:*-1.0
      EndIf
      omegaDir.x=Degrees(omegaDir.x)
      omegaDir.y=Degrees(omegaDir.y)
      omegaDir.z=Degrees(omegaDir.z)
      scale=Degrees(dirMagInv*omegaMag)
      Return (omegaDir.xyz()).Scale(scale)
   EndMethod


Does that look right to you?
User avatar
Leadwerks
 
Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Julio Jerez » Wed Jan 14, 2009 7:05 pm

I whish My english was good enought to explain.
My guess is that you are converting your matrices to quartenions and calling the funtion,
fliping the values based of heuritic or gusses will only hide the bug until it shows up somewhere else.
tell me if this is correct, are you dount this:

you start with two matrices; M0 and M1 and you are convertion then to quaternions,

q0 = Quat (m0)
q1 = Quat (m1)

the you are call the function

if that is correct then the problems is this
if q0 is the quaternion reprentation of matrix M0, then -q0 is also a represetaion of matrix0.
whith the Lema, it is possible the the above convertion give you

q0 = -Quat (m0)
q1 = Quat(m1)

and it will be arithmetically correct, but it will intepoiste in teh wornd diorection.
that is because dot product (q0, q1) will alway generates the shortest arch of rotation.
if whatI am saying is wjhat you are doing, then this is teh solution.
Code: Select all
void GetOmega (vector omega, matrix  m0, matrix ma1, time dt)
{
    q0 = quat (m0);
    q1= quat(m1)
   
    dot = dotpropduct (q0, q1)
    if (dot < 0) {
      q1 = q1 * -1;
    }

  GetOmega (omega, q0, q1, dt)
}


This will alway guarates the shortest arch of rotation from m0 to m1
Julio Jerez
Moderator
Moderator
 
Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Leadwerks » Wed Jan 14, 2009 7:59 pm

Okay, I seem to be getting correct results with that:
Code: Select all
   Method CalcAverageOmega:TVec3( QB:TQuat, dt:Double=1.0 )
      
      Const REALLYSMALLNUMBER:Double=0.00001
      Local dirMag:Double
      Local dirMag2:Double
      Local omegaMag:Double
      Local dirMagInv:Double
      Local dq:TQuat
      Local omegaDir:TVec4
      Local dq2:TQuat
      Local scale:Float
      
      If dot(QB)>0.0
         QB.w:*-1.0
         QB.x:*-1.0
         QB.y:*-1.0
         QB.z:*-1.0
         Return CalcAverageOmega(QB,dt)
      EndIf
      dq=Inverse().Times(QB)      
      omegaDir=vec4(dq.x,dq.y,dq.z,dq.w)
      dirMag2=omegaDir.dot(omegaDir);
      If dirMag2<REALLYSMALLNUMBER*REALLYSMALLNUMBER Return vec3(0)
      dirMagInv=1.0/Sqr(dirMag2)
      omegaMag=2.0*ACos(dq.w)/dt
      Return (omegaDir.xyz()).Scale(dirMagInv*omegaMag)
   EndMethod
User avatar
Leadwerks
 
Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Leadwerks » Fri Jan 16, 2009 6:32 pm

So I guess this is all correct now? Thanks. Hopefully this thread will make it easier for people who want to do this in the future.
User avatar
Leadwerks
 
Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Leadwerks » Sun Jan 18, 2009 4:08 pm

Hre is my test prog, just to get this off my desktop:
Code: Select all
'   ====================================================================
'   This file was generated by Leadwerks C++/LEO/BlitzMax Project Wizard
'   Written by Rimfrost Software
'   http://www.rimfrost.com
'   ====================================================================

SuperStrict

Framework leadwerks.engine

Local world:TWorld
Local gbuffer:TBuffer
Local camera:TCamera
Local mesh:TMesh
Local light:TLight
Local ground:TMesh
Local material:TMaterial

RegisterAbstractPath( "C:/Program Files/Leadwerks Engine SDK" )

Graphics(800,600)

world=CreateWorld()
If Not world RuntimeError "Failed to create world."

gbuffer=CreateBuffer(GraphicsWidth(),GraphicsHeight(),BUFFER_COLOR|BUFFER_DEPTH|BUFFER_NORMAL)

camera=CreateCamera()
PositionEntity camera,[0.0,0.0,-2.0]

material=LoadMaterial("abstract::cobblestones.mat")

mesh=CreateCube()
PaintEntity mesh,material

ground=CreateCube()
ScaleEntity ground,[10.0,1.0,10.0]
PositionEntity ground,[0.0,-2.0,0.0]
PaintEntity ground,material

Local gb:TBody=CreateBodyBox(10,1,10)
PositionEntity gb,[0.0,-2.0,0.0]
gb.setcollisiontype 1

light=CreateDirectionalLight()

Local body:TBody=CreateBodyBox()
SetBodyMass body,1
SetBodyGravityMode body,0
body.setcollisiontype 1

DebugPhysics True

RotateEntity light,[45.0,45.0,45.0]

SetBodyDamping body,0,0


Function QuatToNewtonQuat:TQuat(q:TQuat)
   Local result:TQuat=New TQuat
   result.x=q.w
   result.y=-q.x
   result.z=-q.y
   result.w=-q.z
   Return result
EndFunction

Function NewtonQuatToQuat:TQuat(q:TQuat)
   Local result:TQuat=New TQuat
   result.w=q.x
   result.x=-q.y
   result.y=-q.z
   result.z=-q.w
   Return result
EndFunction

'RotateEntity body,[0.0,0.0,0.0]
'RotateEntity mesh,[0.0,0.0,10.0]

Global mx:Float=MouseX()

collisions 1,1,1


Repeat

   'RotateEntity cube,[0.0,0.0,45.0]
   'HideEntity cube
   
   Local a#=MouseX()-mx
   
   RotateEntity mesh,vec3(0,0,a)
   
   'TurnEntity mesh,vec3(0.3,1.0,-0.5)
   
   'If MouseHit(1)
   '   Local b:TBody=CreateBodyBox(0.1,0.1,0.1)
   '   b.setmass 1
   '   b.setposition([0.0,4.0,0.0])
   '   b.setcollisiontype 1
   'EndIf
   
   
   Local q:TQuat=New TQuat
   Local q2:TQuat=New TQuat
   Local omega:TVec3
   Local mat:TMat4=New TMat4

   omega=body.CalcOmega(mesh.rotation,1)
   'If MouseHit(1)
      body.setomega omega
   'Else
   '   body.setomega vec3(0)
   'EndIf

   If KeyHit(KEY_ESCAPE) Exit
   If AppTerminate() Exit
   
   UpdateAppTime()
   UpdateWorld(1)'AppSpeed())

   SetBuffer(gbuffer)
   RenderWorld()
   SetBuffer(BackBuffer())
   RenderLights(gbuffer)
   
   DrawText a,0,0
   
   Flip(1)

Forever

gbuffer=Null
FreeEntity light
GCCollect()
End
User avatar
Leadwerks
 
Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Julio Jerez » Sun Jan 18, 2009 5:59 pm

is this a bug?
Julio Jerez
Moderator
Moderator
 
Posts: 11155
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Calculate force and torque to interpolate between 2 mat4s

Postby agi_shi » Sun Jan 18, 2009 6:09 pm

Julio Jerez wrote:is this a bug?

No, I believe he posted that as a working example for others who may want to do the same thing.
agi_shi
 
Posts: 263
Joined: Fri Aug 17, 2007 6:54 pm

Re: Calculate force and torque to interpolate between 2 mat4s

Postby Leadwerks » Mon Jan 19, 2009 11:30 pm

Just some code I used for testing that I wanted to delete, but still have a copy of somewhere, just in case.
User avatar
Leadwerks
 
Posts: 539
Joined: Fri Oct 27, 2006 2:54 pm

Previous

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 6 guests