Trying to dive into Newton (2D)

BlitzMax Forums/BlitzMax Programming/Trying to dive into Newton (2D)

Shaun Sullivan(Posted 2007) [#1]
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:

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





René(Posted 2007) [#2]
Hi, there. I'm also veryinterested in using Newton for 2D. It seems you are using a Newton wrapper from Leadwerks, but I can't find a link to it. Do you have a download link so I can use the same mod as you and test you code?


Shaun Sullivan(Posted 2007) [#3]
He posted the source on a thread here, a search for Leadwerks and Newton should turn it up.


René(Posted 2007) [#4]
Sorry, I cannot find any working links to a Newton wrapper for BMax neither by Leadwerks nor by any other author.


René(Posted 2007) [#5]
Ok found something here:
http://www.blitzmax.com/Community/posts.php?topic=51140