FIXED ROTATION/POSITIONING & ORIENTATION!!! :)
Well, my head hurts a lot but I've managed to pinpoint and correct the errors with the rotation/positioning and orientation issues. I've also managed to increase stability in the physics.
As I suspected the (Euler<>Quaternion) conversions were not at fault as far as I can tell.
The problems were in the following areas:
maxcontacts (changed internal integer for stability)
dBodySetRotation (corrected yaw)
dBodyGetYaw (corrected yaw)
dGeomSetRotation (corrected yaw)
dGeomGetYaw (corrected yaw)
dCreateBox (corrected orientation)
My main objective was to use the same orientation for ODE entity positioning/rotation as Blitz itself uses. So if you create a cube in Blitz, and then create another using the ODE wrapper they would have identical orientation properties. It's worth noting that Arkons wrapper does NOT have the same orientation as Blitz's entities, which leads to confusion when creating and positioning ODE/non-ODE objects.
The reason it was so confusing to figure out what was wrong with the wrapper, was due to the fact I was using a Blitz cube and an ODE box to figure out alignment issues. As soon as I realised the ODE box was being setup incorrectly, it was a simple process to correct everything.
With the fixed ODE.dll you can now create objects and expect them to be orientated as they would be using Blitz's own entities - and of course everything rotates/collides correctly now.
I've tested this on the (corrected) Car Demo and it works fine.
I'll send Jedive the new source with all of the corrections so that he can add it to the next update.
In the mean time, try this car demo code below, it contains all of the corrections (via blitz) so that you can test it with the current dll. The only thing it doesn't correct is the stability (which is internal to the dll).
The white rectangle is a standard Blitz entity and the blue one is an ODE entity, as you can see they are correctly orientated to each other.
Btw, the ODE box dimensions still need to be double that of the Blitz entity dimensions, this is easily fixed within the wrapper too. I'll check the dimensions of the ODE objects against Blitz entities next and see if I can correct those before I send Jedive the updated source.
Let me know if you find any problems.
Well, my head hurts a lot but I've managed to pinpoint and correct the errors with the rotation/positioning and orientation issues. I've also managed to increase stability in the physics.
As I suspected the (Euler<>Quaternion) conversions were not at fault as far as I can tell.
The problems were in the following areas:
maxcontacts (changed internal integer for stability)
dBodySetRotation (corrected yaw)
dBodyGetYaw (corrected yaw)
dGeomSetRotation (corrected yaw)
dGeomGetYaw (corrected yaw)
dCreateBox (corrected orientation)
My main objective was to use the same orientation for ODE entity positioning/rotation as Blitz itself uses. So if you create a cube in Blitz, and then create another using the ODE wrapper they would have identical orientation properties. It's worth noting that Arkons wrapper does NOT have the same orientation as Blitz's entities, which leads to confusion when creating and positioning ODE/non-ODE objects.
The reason it was so confusing to figure out what was wrong with the wrapper, was due to the fact I was using a Blitz cube and an ODE box to figure out alignment issues. As soon as I realised the ODE box was being setup incorrectly, it was a simple process to correct everything.
With the fixed ODE.dll you can now create objects and expect them to be orientated as they would be using Blitz's own entities - and of course everything rotates/collides correctly now.
I've tested this on the (corrected) Car Demo and it works fine.
I'll send Jedive the new source with all of the corrections so that he can add it to the next update.
In the mean time, try this car demo code below, it contains all of the corrections (via blitz) so that you can test it with the current dll. The only thing it doesn't correct is the stability (which is internal to the dll).
; ################################################################################################### ; # JediveODE Car Demo # ; # Code by Jim Williams (VIP3R) # # ; # Feel free to use this code, any credit appreciated # ; ################################################################################################### AppTitle "JediveODE Car Demo" Include "ODE.bb" Graphics3D 800,600,0,2 Global CMass#=200 ; ### Car Mass Global WMass#=8 ; ### Wheel Mass Global WorldERP#=1 ; ### World Error Correction Global WorldFriction#=64 ; ### World Friction Global HingeTorque#=24 ; ### Hinge Torque Global SuspensionHS#=0.01 ; ### Hinge Suspension Hardness/Softness (Higher=Softer - Lower=Harder) Global Speed#=0 Global Steer#=0 Global Car Global CGeom Global CMesh Const dParamVel2=258 Const dParamFMax2=259 Dim Wheel(4) Dim WGeom(4) Dim Joint(4) Type ODEGeom Field body Field geom Field mesh End Type ; ################################################################################################### ; ### Setup ODE Global World=dWorldCreate() Global Space=dHashSpaceCreate(0) Global ContactGroup=dJointGroupCreate(0) dWorldSetGravity(World,0,-1,0) dWorldSetERP(World,WorldERP) dContactSetMode(dContactSlip1) dContactSetMu(WorldFriction) ; ### Create car body g.ODEGeom=New ODEGeom g\body=dBodyCreate(World) Car=g\body FIXdBodySetRotation(g\body,0,0,0) dBodySetPosition(g\body,0,0,0) mass=dMassCreate() dMassSetBox(mass,1,3,1,4) dMassSetBoxTotal(mass,CMass,3,1,4) dMassTranslate(mass,0,-1,0) dBodySetMass(g\body,mass) dMassDestroy(mass) g\geom=FIXdCreateBox(Space,3,1,4) CGeom=g\geom dGeomSetBody(g\geom,g\body) g\mesh=CreateCube() CMesh=g\mesh ScaleMesh g\mesh,1.5,0.5,2 RotateMesh g\mesh,0,0,0 PositionMesh g\mesh,0,0,0 EntityColor g\mesh,40,80,255 EntityAlpha g\mesh,1 ; ### Create wheels For count=1 To 4 g.ODEGeom=New ODEGeom g\body=dBodyCreate(World) Wheel(count)=g\body FIXdBodySetRotation(g\body,0,0,0) dBodySetPosition(g\body,0,0,0) mass=dMassCreate() dMassSetSphere(mass,1,0.7) dMassSetSphereTotal(mass,WMass,0.7) dBodySetMass(g\body,mass) dMassDestroy(mass) g\geom=dCreateSphere(Space,0.7) WGeom(count)=g\geom dGeomSetBody(g\geom,g\body) g\mesh=CreateCylinder(8) ScaleMesh g\mesh,0.7,0.25,0.7 RotateMesh g\mesh,0,0,90 PositionMesh g\mesh,0,0,0 EntityColor g\mesh,255,255,255 Next ; ### Create some objects SeedRnd MilliSecs() For balls=1 To 20 g.ODEGeom=New ODEGeom g\body=dBodyCreate(World) FIXdBodySetRotation(g\body,0,0,0) dBodySetPosition(g\body,Rnd(-150,150),30,Rnd(-150,150)) g\geom=dCreateSphere(Space,4) dGeomSetBody(g\geom,g\body) g\mesh=CreateSphere() ScaleMesh g\mesh,4,4,4 RotateMesh g\mesh,0,0,0 PositionMesh g\mesh,0,0,0 EntityColor g\mesh,Rnd(255),Rnd(255),Rnd(255) EntityAlpha g\mesh,1 EntityShininess g\mesh,0.7 Next For cylinders=1 To 20 g.ODEGeom=New ODEGeom g\body=dBodyCreate(World) FIXdBodySetRotation(g\body,0,0,0) dBodySetPosition(g\body,Rnd(-50,50),30,Rnd(-50,50)) g\geom=dCreateCCylinder(Space,2,3) dGeomSetBody(g\geom,g\body) g\mesh=CreateCylinder(8) ScaleMesh g\mesh,2,3,2 RotateMesh g\mesh,0,0,0 PositionMesh g\mesh,0,0,0 EntityColor g\mesh,Rnd(255),Rnd(255),Rnd(255) EntityAlpha g\mesh,1 EntityShininess g\mesh,0.7 Next ; ### Create light Global Light=CreateLight() RotateEntity Light,45,-90,0 LightColor Light,255,255,255 AmbientLight 130,130,130 ; ### Create camera Global CameraPivot=CreatePivot(CMesh) PositionEntity CameraPivot,0,2,-7 Global Camera=CreateCamera() CameraClsColor Camera,0,0,0 CameraRange Camera,1,1000 ; ### Create plane dCreatePlane(Space,0,1,0,0) Plane=CreatePlane() EntityAlpha Plane,0.8 PlaneTexture=CreateTexture(128,128,9) ClsColor 0,200,80 Cls Color 255,255,255 Rect 0,0,64,64,1 Rect 64,64,64,64,1 CopyRect 0,0,128,128,0,0,BackBuffer(),TextureBuffer(PlaneTexture) ScaleTexture PlaneTexture,20,20 EntityTexture Plane,PlaneTexture,0,0 Mirror=CreateMirror() ; ################################################################################################### ; ### BLITZ TEST OBJECT (White) blitzobject=CreateCube() ScaleMesh blitzobject,1,4,20 RotateMesh blitzobject,-10,8,4 PositionMesh blitzobject,10,5,10 EntityColor blitzobject,255,255,255 EntityAlpha blitzobject,1 ; ### ODE STATIC TEST OBJECT (Blue) g.ODEGeom=New ODEGeom g\geom=FIXdCreateBox(Space,2,8,40) FIXdGeomSetRotation(g\geom,-10,8,4) dGeomSetPosition(g\geom,20,5,10) g\mesh=CreateCube() ScaleMesh g\mesh,1,4,20 RotateMesh g\mesh,0,0,0 PositionMesh g\mesh,0,0,0 EntityColor g\mesh,0,100,200 EntityAlpha g\mesh,1 ; ################################################################################################### SetupCar() While Not KeyHit(1) UpdateKeys() PTime=MilliSecs() UpdateCar() UpdateGeoms() dSpaceCollide(Space,World,ContactGroup) dWorldQuickStep(World,0.1) dJointGroupEmpty(ContactGroup) PhysicsTime#=MilliSecs()-PTime UpdateCam() UpdateWorld RenderWorld Text 0,0,"Physics Time:"+PhysicsTime Text 0,15,"Car Speed:"+Speed Text 640,0,"A - Accelerate" Text 640,15,"Z - Brake/Reverse" Text 640,30,"Arrows - Steering" Text 640,45,"Space - Reset Car" Flip Wend dJointGroupDestroy(ContactGroup) dSpaceDestroy(Space) dWorldDestroy(World) dCloseODE() End ; ################################################################################################### Function SetupCar() dBodySetPosition(Wheel(1),-2,-0.5,+2) dBodySetPosition(Wheel(2),+2,-0.5,+2) dBodySetPosition(Wheel(3),-2,-0.5,-2) dBodySetPosition(Wheel(4),+2,-0.5,-2) For count=1 To 4 Joint(count)=dJointCreateHinge2(World,0) dJointAttach(Joint(count),Car,Wheel(count)) dJointSetHinge2Anchor(Joint(count),dBodyGetPositionX(Wheel(count)),dBodyGetPositionY(Wheel(count)),dBodyGetPositionZ(Wheel(count))) dJointSetHinge2Axis1(Joint(count),0,1,0) dJointSetHinge2Axis2(Joint(count),1,0,0) dJointSetHinge2Param(Joint(count),dParamSuspensionERP,0.8) dJointSetHinge2Param(Joint(count),dParamSuspensionCFM,SuspensionHS) If count>2 dJointSetHinge2Param(Joint(count),dParamLoStop,0) dJointSetHinge2Param(Joint(count),dParamHiStop,0) End If Next Speed=0 End Function ; ################################################################################################### Function UpdateKeys() If KeyDown(30)=1 Speed=Speed+0.08 If Speed>30 Then Speed=30 End If If KeyDown(44)=1 Speed=Speed-0.1 If Speed<-10 Then Speed=-10 If Speed>0 Then Speed=Speed*0.97 End If If KeyDown(30)=0 And KeyDown(44)=0 Then Speed=Speed*0.99 If KeyDown(203)=1 Or KeyDown(205)=1 If KeyDown(203)=1 Steer=-0.5 Else Steer=0.5 End If Else Steer=0 End If If KeyHit(57)=1 Speed=0 FIXdBodySetRotation(Car,0,0,0) End If End Function ; ################################################################################################### Function UpdateCar() For count=1 To 4 dBodyEnable(Wheel(count)) Next dBodyEnable(Car) For count=1 To 4 dJointSetHinge2Param(Joint(count),dParamVel2,Speed) dJointSetHinge2Param(Joint(count),dParamFMax2,HingeTorque) Next For count=1 To 2 angle#=Steer-dJointGetHinge2Angle1(Joint(count)) dJointSetHinge2Param(Joint(count),dParamVel,angle) dJointSetHinge2Param(Joint(count),dParamFMax,400) Next End Function ; ################################################################################################### Function UpdateCam() PositionEntity CameraPivot,0,3,-12 camx#=EntityX(CameraPivot,1)-EntityX(Camera) camy#=EntityY(CameraPivot,1)-EntityY(Camera) camz#=EntityZ(CameraPivot,1)-EntityZ(Camera) TranslateEntity Camera,camx*0.5,camy*0.5,camz*0.5 PointEntity Camera,CMesh End Function ; ################################################################################################### Function FIXdBodySetRotation(body,rx,ry,rz) dBodySetRotation(body,rx,ry+90,rz) End Function ; ################################################################################################### Function FIXdGeomSetRotation(geom,rx,ry,rz) dGeomSetRotation(geom,rx,ry+90,rz) End Function ; ################################################################################################### Function FIXdCreateBox(sp,w,h,d) Return dCreateBox(sp,d,h,w) End Function ; ################################################################################################### Function UpdateGeoms() For g.ODEGeom=Each ODEGeom RotateEntity g\mesh,dGeomGetPitch#(g\geom),dGeomGetYaw#(g\geom)-90,dGeomGetRoll#(g\geom) PositionEntity g\mesh,dGeomGetPositionX#(g\geom),dGeomGetPositionY#(g\geom),dGeomGetPositionZ#(g\geom) Next End Function ; ###################################################################################################
The white rectangle is a standard Blitz entity and the blue one is an ODE entity, as you can see they are correctly orientated to each other.
Btw, the ODE box dimensions still need to be double that of the Blitz entity dimensions, this is easily fixed within the wrapper too. I'll check the dimensions of the ODE objects against Blitz entities next and see if I can correct those before I send Jedive the updated source.
Let me know if you find any problems.