OK, I have gathered code from multiple sources here and there and I am trying to wrap my head around Newton. I have it up and running but for some reason my registered physics callback functions only get called once. From reading the Newton docs that may be due to the fact that (from the engine's) perspective my objects do not need to be updated.
Anyway, I spent all day on this yesterday so if anyone has any ideas / help I'd appreciate it. I'm especially interested in any info folks might have on making sure I am doing 2D properly (assuming I can get my object moving around the screen!)
Here is my code:
Anyway, I spent all day on this yesterday so if anyone has any ideas / help I'd appreciate it. I'm especially interested in any info folks might have on making sure I am doing 2D properly (assuming I can get my object moving around the screen!)
Here is my code:
SuperStrict Import misc.Newton ' Module from LeadWerks Type ImageNode Field Image:TImage Field x:Int , y:Int , z:Int = 0 Field rotX:Float , rotY:Float , rotZ:Float = 0.0 Field mass:Float Function Create:ImageNode(ImgStr:String , tmpX:Int , tmpY:Int , tmpRot:Int) Local tmpN:ImageNode = New ImageNode tmpN.Image = LoadImage(ImgStr) tmpN.x = tmpX tmpN.y = tmpY tmpN.rotZ = tmpRot MidHandleImage tmpN.Image Return tmpN End Function Method draw() SetRotation rotZ DrawImage image , x , y SetRotation 0 End Method End Type Rem Max2DGetMatrix is the function to get the matrix from the Max2D Image And pass it to an array to be used by Newton. Max2DSetMatrix is the function to pass the Matrix from Newton to the Max2D Image EndRem Function Max2DGetMatrix(NImageNode:ImageNode , NewtonMat:Float Ptr) Local Euler:Float[3] Euler[0] = NImageNode.rotX * (Pi / 180.0) Euler[1] = NImageNode.rotY * (Pi / 180.0) Euler[2] = NImageNode.rotZ * (Pi / 180.0) NewtonSetEulerAngle(Varptr Euler[0] , Varptr newtonMat[0]) Newtonmat[12] = NImageNode.X newtonMat[13] = NImageNode.Y NewtonMat[14] = NImageNode.Z End Function Function Max2DSetMatrix(NImageNode:ImageNode , NewtonMat:Float Ptr) Local Euler:Float[3] NewtonGetEulerAngle(Varptr NewtonMat[0] , Varptr Euler[0]) NImageNode.x = NewtonMat[12] NImageNode.y = NewtonMat[13] NImageNode.z = NewtonMat[14] NImageNode.rotX = Euler[0] * (180 / Pi) NImageNode.rotY = Euler[1] * (180 / Pi) NImageNode.rotZ = Euler[2] * (180 / Pi) End Function Graphics 1024, 768, 0, 60 If StartNewton() Then Local Test:ImageNode = ImageNode.create("water.png" , 400 , 400 , 10) Local newtonWorld:Byte Ptr = newtonCreate(MemAllocate, MemRelease) Local collision:Byte Ptr = Null collision = newtonCreateBox(newtonWorld, ImageWidth(Test.Image) , ImageHeight(Test.Image) , 1 , Null) Local myBox:Byte Ptr = NewtonCreateBody(newtonWorld, collision) NewtonReleaseCollision newtonWorld, collision newtonBodySetMassMatrix myBox, 5.0 , 1.0 , 1.0 , 1.0 Local Mat:Float[16] Max2DGetMatrix Test, Varptr Mat[0] newtonBodySetMatrix(myBox, Varptr Mat[0]) Local force:Float[3] force[0] = 1.0# force[1] = 1.0# force[2] = 1.0# newtonBodySetForce(myBox, Varptr force[0]) Local Omega:Float[] = [50.0 , 10.0 , 10.0] newtonBodySetOmega(myBox , Varptr omega[0]) Local testHandle:Int = HandleFromObject(Test) Local testHandlePtr:Int Ptr = Varptr(testHandle) newtonBodySetUserData(myBox, testHandlePtr) newtonBodySetTransformCallBack(myBox, PhysicsSetTransform) newtonBodySetForceandTorqueCallback(myBox, PhysicsApplyForceAndTorque) NewtonBodySetDestructorCallback (myBox, PhysicsBodyDestructor); newtonWorldUnFreezeBody newtonWorld, myBox Local iTicks:Int = 0 Local iStart:Int = 0 Repeat iStart = MilliSecs() 'newtonUpdate(newtonWorld , FPS.Calc()) newtonUpdate(newtonWorld , .01#) Cls DrawText String(iTicks), 1, 1 newtonBodyGetMatrix(myBox, Varptr Mat[0]) For Local i2:Int = 0 To 15 DrawText mat[i2] , 10 , (i2 * 10) + 64 Next 'DrawText Test.rotZ , 10 , 200 'NewtonWorldForEachBodyDo newtonWorld, iterator Test.draw Flip iTicks = MilliSecs() - iStart Until KeyHit(KEY_ESCAPE) Or AppTerminate() StopNewton End If Rem Function iterator (newtonBody:Byte Ptr) Local bp:Byte Ptr = newtonBodyGetUserData(newtonBody) Local iHandle:Int = bp[0] Local tmpNode:ImageNode = ImageNode(HandleToObject(iHandle)) ' Get latest newton stuff for our object newtonBodyGetMatrix(tmpNNode , Varptr tmpMat[0]) Local Euler:Float[] = [0.0 , 0.0 , tmpImageNode.rotZ] Max2DSetMatrix(tmpImageNode , Varptr tmpMat[0]) newtonBodyGetMatrix 'newtonBodyGetMatrix(tmpNode , Varptr tmpMat[0]) 'Local Euler:Float[] = [0.0 , 0.0 , tmpImageNode.rotZ] 'Max2DSetMatrix(tmpImageNode , Varptr tmpMat[0]) End Function End Rem 'These override Newton's local memory functions with native function wrappers. Function MemAllocate:Byte Ptr(sizeInBytes:Int) Return MemAlloc(sizeInBytes) End Function Function MemRelease(memptr:Byte Ptr,sizeInBytes:Int) 'sizeInBytes:Int is a placeholder. MemFree(memptr) GCCollect End Function Function PhysicsSetTransform(newtonBody:Byte Ptr , tmpMat:Float Ptr) ' This never even gets called! Local bp:Byte Ptr = newtonBodyGetUserData(newtonBody) Local iHandle:Int = bp[0] Local tmpNode:ImageNode = ImageNode(HandleToObject(iHandle)) newtonBodyGetMatrix(newtonBody, Varptr tmpMat[0]) 'Local Euler:Float[] = [0.0 , 0.0 , tmpImageNode.rotZ] Max2DSetMatrix(tmpNode, Varptsr tmpMat[0]) End Function Function PhysicsApplyForceAndTorque(tmpNNode:Byte Ptr) ' This only gets called once 'DebugStop Local Mass:Float Local Ixx:Float Local Iyy:Float Local Izz:Float newtonBodyGetMassMatrix(tmpNNode , Varptr Mass , Varptr Ixx , Varptr Iyy , Varptr Izz) Local force:Float[] = [0.0 , mass * 9.8 , 0.0] newtonBodySetForce(tmpNNode , Varptr force[0]) End Function Function PhysicsBodyDestructor(tmpNNode:Byte Ptr) DebugStop End Function Type FPS ' FPS_Counter <> Runs and displays the FPS Global Counter:Int, Time:Int, TFPS:Int Function Calc%() Counter:+1 If Time < MilliSecs() TFPS = Counter' <- Frames/Sec Time = MilliSecs() + 1000'Update Counter = 0 EndIf Return TFPS EndFunction Function Display() DrawText "FPS: "+FPS.Calc(),10,220 End Function EndType