newton physics time

BlitzMax Modules Forums/MiniB3D/newton physics time

It is my (possibly mis)understanding that the line 382 ( Physic.Update(TGLobal.GetDelta()) ) in the Physic.bmx sample included with minib3dext is supposed to control physics simulation speed?

In my observation, it doesn't. Regardless of its use The simulation speed is tied to the loop update speed. I have tried using delta time, or just other random variables. it doesn't seem to have an effect.


Is this not working, or am I doing something wrong? (as usual)

it is a bit buggy

try this instead:

        Field accumulator:Float
	Field lastupdate:Int = MilliSecs()
	Field updates:Int

        Method Update(UpTime:Float = - 1.0) 
		
		Local Time:Int = MilliSecs()

		If  Uptime < 0 Then
			NewtonUpdate(World , GetDelta() ) 
		Else
			NewtonUpdate(World , Uptime ) 
		EndIf
	End Method
	
	Method AccuUpdate()
		GCSuspend()
		accumulator:+ Min(MilliSecs() - lastupdate,60)/1000.0
		lastupdate = MilliSecs() 
		
		updates:Int = 0
		While accumulator >= dt
			Update(dt) 
			accumulator:- dt
			updates:+1
		Wend
		GCResume()
	End Method


Thanks for the prompt response.


I tried your code, and there was no difference.

As the frame rate drops, so does the physics speed.

Am I supposed to call AccuUpdate() somewhere?


This is what the modified TPhysik.bmx looks like (I had to change one or two things in your code above) I am using the sample physic.bmx to see the results.




Type TPhysic
	Global World:Byte Ptr
	Global Debug:Byte = False
	Global ActiveBodies:Int
	Global UnActiveBodies:Int = 0
	Global CurrentContact:TContactinfo
	Global ContactEnd(Contact:TContactinfo)
	Global ContactProcess(Contact:TContactInfo)
	Global BallUserCallBack(Ball:TBallConstrait)
	Global MainBall_Callback(ball:Byte Ptr)
	
	Field PhysicObjects:TList = New TList
	Field Standard_Transform_Callback(body:Byte Ptr)
	Field Standard_ForceAndTorque_Callback(body:Byte Ptr)
	Field Standard_Activation_Callback(body:Byte Ptr)
	Field Contact_Begin_CallBack:Int(material:Byte Ptr,body0:Byte Ptr, body1:Byte Ptr)
	Field Contact_Process_CallBack:Int(material:Byte Ptr,body0:Byte Ptr, body1:Byte Ptr,contact:Byte Ptr)
	Field Contact_End_Callback(material:Byte Ptr)
	
	Field Materials:TMap = CreateMap()
	Field Standard_Material:Int
	


		
	
	
	Function init:TPhysic()
		'?win32
		'StartNewton()
		'?
		Local P:TPhysic = New TPhysic
		World = NewtonCreate(Null , Null)
		NewtonSetPlatformArchitecture (World, 0)
		P.Standard_Transform_Callback = TransformCallback
		P.Standard_ForceAndTorque_Callback = ForceCallBack
		P.Standard_Activation_Callback = ActivationCallback
		P.Contact_Begin_CallBack = Contact_Begin_CallBack
		P.Contact_Process_CallBack = Contact_Process_CallBack
		P.Contact_End_CallBack = Contact_End_CallBack
		P.Standard_Material = NewtonMaterialGetDefaultGroupID(World)
		MainBall_CallBack = Ball_Callback
		Return P
	End Function
	
	Method SetWorldSize(V1:TVector,V2:TVector)
		NewtonSetWorldSize(World,V1,V2)
	End Method
	
	Method SetPhysicModel(SolverModel:Int,FrictionModel:Int)
		NewtonSetSolverModel(TPhysic.World,SolverModel)
		NewtonSetFrictionModel(TPhysic.World,FrictionModel)
	End Method
	
	
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
'!!!!!!!!!!!!!!!!   Klepto's Fix is here:   !!!!!!!!!!!!!!!!!!
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	Global dt

     Field accumulator:Float
	Field lastupdate:Int = MilliSecs()
	Field updates:Int
	Global dt

        Method Update(UpTime:Float = - 1.0) 
		
		Local Time:Int = MilliSecs()

		If  Uptime < 0 Then
			NewtonUpdate(World , TGlobal.GetDelta() ) 
		Else
			NewtonUpdate(World , Uptime ) 
		EndIf
	End Method
	
	Method AccuUpdate()
		GCSuspend()
		accumulator:+ Min(MilliSecs() - lastupdate,60)/1000.0
		lastupdate = MilliSecs() 
		
		updates:Int = 0
		While accumulator >= dt
			Update(dt) 
			accumulator:- dt
			updates:+1
		Wend
		GCResume()
	End Method


	
'What it looked like before Klepto's Fix	
	
'	Method Update(UpTime:Float = - 1.0)
'		If  Uptime < 0 Then
'			NewtonUpdate(World , TGlobal.GetDelta() ) 
'		Else
'			NewtonUpdate(World , Uptime ) 
'		EndIf
'		TPhysic.ActiveBodies = PhysicObjects.Count()-TPhysic.UnActiveBodies
'	End Method
	
	
	
	
	
	
	
	Method AddMaterial(Material:TPhysicMaterial)
		If Material <> Null
			MapInsert(Materials,Material.Name,Material)
		EndIf
	End Method
	
	Method BuildMaterialLibraries(BuildOption:Int = PHYS_MATERIAL_AVERAGE)
		Local KFriction:Float
		Local SFriction:Float
		Local Softness:Float
		Local Elasticity:Float
		For Local M1:TPhysicMaterial = EachIn Materials.Values()
			For Local M2:TPhysicMaterial = EachIn Materials.Values()
				Select BuildOption
					Case PHYS_MATERIAL_AVERAGE
						SFriction = (M1.DefaultFriction[0] + M2.DefaultFriction[0]) / 2
						KFriction = (M1.DefaultFriction[1] + M2.DefaultFriction[1]) / 2
						Softness = (M1.DefaultSoftness + M2.DefaultSoftness) / 2
						Elasticity = (M1.DefaultElasticity + M2.DefaultElasticity) / 2
						
						NewtonMaterialSetDefaultFriction(TPhysic.World,M1.GroupID,M2.GroupID,SFriction,KFriction)
						NewtonMaterialSetDefaultSoftness(TPhysic.World,M1.GroupID,M2.GroupID,Softness)
						NewtonMaterialSetDefaultElasticity(TPhysic.World,M1.GroupID,M2.GroupID,Elasticity)
				End Select
				
				NewtonMaterialSetCollisionCallback(TPhysic.World,M1.GroupID,M2.GroupID,Null,Contact_Begin_CallBack,Contact_Process_CallBack,Contact_End_CallBack)
			Next
		Next
		
		For Local M:String = EachIn MapKeys(Materials)
			Print "Material : " + String(M)
		Next
	End Method
	
	Method SetMaterialCollision(M1:Object,M2:Object,state:Int = 1)
		If TPhysicMaterial(M1)<>Null And TPhysicMaterial(M2) <> Null Then
			NewtonMaterialSetDefaultCollidable(TPhysic.World,TPhysicMaterial(M1).GroupID,TPhysicMaterial(M2).GroupID,state)
		Else
			Local MT1:TPhysicMaterial = TPhysicMaterial(MapValueForKey(Materials,String(M1)))
			Local MT2:TPhysicMaterial = TPhysicMaterial(MapValueForKey(Materials,String(M2)))
			
			If MT1 <> Null And MT2 <> Null Then 
				NewtonMaterialSetDefaultCollidable(TPhysic.World,MT1.GroupID,MT2.GroupID,state)
			EndIf
		EndIf
	End Method

	
	Method AddObject(NO:TNewtonObject)
		NewtonBodySetTransformCallback(NO.Node,Standard_Transform_Callback)
		NewtonBodySetForceAndTorqueCallback(NO.Node,Standard_ForceAndTorque_Callback)
		?Debug
		NewtonBodySetAutoActiveCallback(NO.Node,Standard_Activation_Callback)
		?
		PhysicObjects.Addlast(NO)

	End Method
	
	Method GetNode:Byte Ptr(mesh:TEntity)
		For Local T:TNewtonObject = EachIn PhysicObjects
			If T.Mesh = mesh Then Return T.node
		Next
		Return Null
	End Method
	
	Method GetPhysicTime:Float()
		Return NewtonGetTimeStep(World)
	End Method
	
	Method GetActiveBodyCount:Int()
		Return TPhysic.ActiveBodies
	End Method
	
	Method GetUnActiveBodyCount:Int()
		Return TPhysic.UnActiveBodies
	End Method
	
	Method ApplyImpulse(mesh:TEntity,impactX:Float,ImpactY:Float,ImpactZ:Float,ForceX:Float,ForceY:Float,ForceZ:Float)
		NewtonAddBodyImpulse(GetNode(mesh),[ForceX,ForceY,ForceZ],[impactX,impactY,impactZ])
	End Method
	
	Method SetDefaultElasticity(Value:Float)
		NewtonMaterialSetDefaultElasticity(TPhysic.World,Standard_Material,Standard_Material,Value)
	End Method
	
	Method SetDefaultFriction(staticFriction:Float,kineticfriction:Float)
		NewtonMaterialSetDefaultFriction(TPhysic.World,Standard_Material,Standard_Material,staticFriction,kineticFriction)
	End Method
	
	Method SetDefaultSoftiness(Value:Float)
		NewtonMaterialSetDefaultSoftness(TPhysic.World,Standard_Material,Standard_Material,Value)
	End Method
	
	Method SetBodyMaterial(NObject:TNewtonObject,MAterial:Object)
		'Print "Material : " + TPhysicMaterial(Material).Name
		If TPhysicMaterial(Material)<>Null 
			Print TPhysicMaterial(Material).Name + "applied"
			NewtonBodySetMaterialGroupID(NObject.node,TPhysicMaterial(Material).GroupID)
			NObject.Material = TPhysicMaterial(Material)
		Else
			Local MT1:TPhysicMaterial = TPhysicMaterial(MapValueForKey(Materials,String(Material)))
			If MT1 <> Null
				Print mt1.Name + "applied" 
				 NewtonBodySetMaterialGroupID(NObject.node,Mt1.GroupID)
				 NObject.Material = MT1
			EndIf
		EndIf
	
	End Method
	
	Method SetCollisionMode(Material1:Object,Material2:Object,Mode:Int = PHYS_NORMAL_COLLISION)
		Local Mat1:TPhysicMaterial
		Local Mat2:TPhysicMaterial
		If TPhysicMaterial(Material1)<>Null 
			Mat1 = TPhysicMaterial(Material1)
		Else
			Local MT1:TPhysicMaterial = TPhysicMaterial(MapValueForKey(Materials,String(Material1)))
			If MT1 <> Null
				Mat1 = MT1
			EndIf
		EndIf
		If TPhysicMaterial(Material2)<>Null 
			Mat1 = TPhysicMaterial(Material2)
		Else
			Local MT1:TPhysicMaterial = TPhysicMaterial(MapValueForKey(Materials,String(Material2)))
			If MT1 <> Null
				Mat2 = MT1
			EndIf
		EndIf
		
		If Mat1 = Null Or Mat2 = Null Then Return
		
		NewtonMaterialSetContinuousCollisionMode(TPhysic.World,Mat1.GroupID,Mat2.GroupID,Mode)
	End Method
	
	Method DestroyBody(mesh:TMesh)
		Local NO:Byte Ptr = GetNode(mesh)
		If NO <> Null Then
			NewtonDestroyBody(TPhysic.World,NO)
			'PhysicObjects.Remove(NO)
		EndIf
	End Method
	
		
End Type

Type TConstrait
	Field Constrait:Byte Ptr
	
	Method SetCollisionState(state:Int = 0)
		NewtonJointSetCollisionState(Constrait,state)
	End Method
	
	Method SetStiffness(stiffiness:Float)
		Print "Stiff: " + Int(Constrait)
		NewtonJointSetStiffness(Constrait,stiffiness)
	End Method
	
	Method GetStiffiness:Float()
		Return NewtonJointGetStiffness(Constrait)
	End Method
	
	Method Destroy()
		NewtonDestroyJoint(TPhysic.World,Constrait)
	End Method
	
End Type

Type TBallConstrait Extends TConstrait
	Function Create:TBallConstrait(WorldPosition:TVector,body0:TNewtonObject,body1:TNewtonObject)
		Local Ball:TBallConstrait = New TBallConstrait
		If body1 = Null Then
			Ball.Constrait = NewtonConstraintCreateBall(Tphysic.World,WorldPosition,body0.node,Null)
		Else
			Ball.Constrait = NewtonConstraintCreateBall(Tphysic.World,WorldPosition,body0.node,body1.node)
		EndIf
		
		NewtonJointSetUserData(Ball.Constrait,Byte Ptr(bbHandleFromObject(Ball)))
		NewtonBallSetUserCallback(Ball.Constrait,TPhysic.MainBall_CallBack)
		Return Ball
	End Function
	
	Method SetConeLimits(Vector:TVector,maxConeAngle:Float,MaxTwistAngle:Float)
		NewtonBallSetConeLimits(Constrait,Vector,maxConeAngle,MaxTwistAngle)
	End Method
	
	Method GetForce:TVector()
		Local V:TVector = New TVector
		NewtonBallGetJointForce(Constrait,V)
		Return V
	End Method
End Type
 

Type TContactInfo
	Field ContactPoints:Byte Ptr
	Field body1:TNewtonObject
	Field body2:TNewtonObject
	Field Material:Byte Ptr
	Field ContactNormalSpeed:Float
	Field ContactTangentSpeed1:Float
	Field ContactTangentSpeed2:Float
	Field ContactForce:TVector = New TVector
	Field ContactPosition:TVector = New TVector
	Field ContactNormalPosition:TVector = New TVector
	Field TimeStep:Float
	Field ContactTangentDirection1:TVector = New TVector
	Field ContactTangentDirection2:TVector = New TVector
	
	
	
	Method Info()
		DebugLog "Materials      : " + body1.Material.Name + " : " + body2.Material.Name
		DebugLog "NormalSpeed    : " + ContactNormalSpeed
		DebugLog "TangentSpeed 1 : " + ContactTangentSpeed1
		DebugLog "TangentSpeed 2 : " + ContactTangentSpeed2
		DebugLog "Force          : " + ContactForce.x + "," + ContactForce.y + "," + ContactForce.z
		DebugLog "Position       : " + ContactPosition.x + "," + ContactPosition.y + "," + ContactPosition.z
		DebugLog "NormalPosition : " + ContactNormalPosition.x + "," + ContactNormalPosition.y + "," + ContactNormalPosition.z
		DebugLog "TimeStep       : " + TimeStep
		DebugLog "-------------------------------------------------------"
	End Method
	
	Method OverrideElasticity(value:Float)
		NewtonMaterialSetContactElasticity(Material , Value)
	End Method
	
	Method OverrideFrictionState(state:Int , id:Int = 0)
		NewtonMaterialSetContactFrictionState(Material , State , id)
	End Method
	
	Method OverrideSoftness(Value:Float)
		NewtonMaterialSetContactSoftness(Material,Max(0.0,Value))
	End Method
	
	Method OverrideStaticFriction(Value:Float,id:Int=0)
		NewtonMaterialSetContactStaticFrictionCoef(Material,Value,id)
	End Method
	
	Method OverrideKineticFriction(Value:Float,id:Int = 0)
		NewtonMaterialSetContactKineticFrictionCoef(Material,Value,id)
	End Method
	
	Method OverrideNormalAcceleration(value:Float)
		NewtonMaterialSetContactNormalAcceleration(Material,value)
	End Method
	
	Method OverrideNormalDirection(Value:TVector)
		NewtonMaterialSetContactNormalDirection(Material,Value)
	End Method
	
	Method OverrideTangentAcceleration(Value:Float,id:Int = 0)
		NewtonMaterialSetContactTangentAcceleration(Material,Value,id)
	End Method
			
End Type

Const PHYS_SPHERE_HULL:Int =1
Const PHYS_BOX_HULL:Int = 2
Const PHYS_CONE_HULL:Int = 3
Const PHYS_CYLINDER_HULL:Int = 4
Const PHYS_MESHCONVEX_HULL:Int = 5
Const PHYS_MESHCOMPLEX_HULL:Int = 6
Const PHYS_MESHCOMPLEXUNOPTOMIZED_HULL:Int = 7


Const PHYS_MATERIAL_MIN:Int = 0
Const PHYS_MATERIAL_MAX:Int = 1
Const PHYS_MATERIAL_ORDER:Int = 2
Const PHYS_MATERIAL_AVERAGE:Int = 3
Const PHYS_MATERIAL_AVERAGE_WITH_REFERENCE:Int = 4

Const PHYS_NORMAL_COLLISION:Int = 0
Const PHYS_CONTINUES_COLLISION:Int = 1


Type TNewtonObject
	Field Mesh:TMesh
	
	Field Mat:Float[16]
	Field rotX:Float,rotY:Float,rotZ:Float
	Field posX:Float,posY:Float,PosZ:Float
	
	Field LCX:Float,LCY:Float,LCZ:Float
	
	Field Body:Byte Ptr
	Field Node:Byte Ptr
	
	Field Velocity:Float[3]
	Field Omega:Float[3]
	Field Active:Byte = False
	Field Material:TPhysicMaterial
	Field Volume:Float
	Field AABB:TVector[2]

	Field UpdateForce:Float[3]
	Field Extra:Object
	Field UpPos:Byte = False
	
	Field UserForceCallback(Body:TNewtonObject)
	Field tp:Int

	
	Function Create:TNewtonObject(Mesh:TMesh,T:Int = 0)
		Local NO:TNewtonObject = New TNewtonObject
			Local nx:Float
			Local ny:Float
			Local nz:Float
			nx = Mesh.sx * Mesh.msx
			ny = Mesh.sy * Mesh.msy
			nz = Mesh.sz * Mesh.msz
			NO.tp=T

		Select T		
			Case 1
				NO.Body =  NewtonCreateSphere(TPhysic.World,nx,ny,nz,Null)
			Case 2
				NO.Body = NewtonCreateBox(TPhysic.World,-nx*2,ny*2,-nz*2,Null)
			Case 5
				Local surf:TSurface = Mesh.GetSurface(1)
				If Surf <> Null Then
					'Print "Creating Convex Hull"
					NO.Body = NewtonCreateConvexHull(TPhysic.World,surf.no_verts,surf.vert_coords,12,Null)
				EndIf
			Case 3
				NO.Body = NewtonCreateCone(TPhysic.World,nx,ny*2,Null)
			Case 4
				NO.Body = NewtonCreateCylinder(TPhysic.World,nx,ny*2,Null)
			Case 6
				NO.BODY = NewtonCreateTreeCollision(TPhysic.World,Null) 
				NewtonTreeCollisionBeginBuild(NO.Body)
				Local Vector:Float[9]
				For	Local Surf:TSurface = EachIn Mesh.surf_List
						For Local I:Int = 0 To surf.no_tris-1
							Local v0=surf.TriangleVertex(i,0)
							Local v1=surf.TriangleVertex(i,1)
							Local v2=surf.TriangleVertex(i,2)
							
							Vector[0] = surf.VertexX(v0)
							Vector[1] = surf.VertexY(v0)
							Vector[2] = surf.VertexZ(v0)
							
							Vector[3] = surf.VertexX(v1)
							Vector[4] = surf.VertexY(v1)
							Vector[5] = surf.VertexZ(v1)
							
							Vector[6] = surf.VertexX(v2)
							Vector[7] = surf.VertexY(v2)
							Vector[8] = surf.VertexZ(v2)
							
							NewtonTreeCollisionAddFace(NO.Body,3,Vector,12,0)
						Next
				Next		
				NewtonTreeCollisionEndBuild(NO.Body , 1)
				
			Case 7
				NO.BODY = NewtonCreateTreeCollision(TPhysic.World,Null) 
				NewtonTreeCollisionBeginBuild(NO.Body)
				Local Vector:Float[9]
				For	Local Surf:TSurface = EachIn Mesh.surf_List
						For Local I:Int = 0 To surf.no_tris-1
							Local v0=surf.TriangleVertex(i,0)
							Local v1=surf.TriangleVertex(i,1)
							Local v2=surf.TriangleVertex(i,2)
							
							Vector[0] = surf.VertexX(v0)
							Vector[1] = surf.VertexY(v0)
							Vector[2] = surf.VertexZ(v0)
							
							Vector[3] = surf.VertexX(v1)
							Vector[4] = surf.VertexY(v1)
							Vector[5] = surf.VertexZ(v1)
							
							Vector[6] = surf.VertexX(v2)
							Vector[7] = surf.VertexY(v2)
							Vector[8] = surf.VertexZ(v2)
							
							NewtonTreeCollisionAddFace(NO.Body,3,Vector,12,0)
						Next
				Next		
				NewtonTreeCollisionEndBuild(NO.Body,0)

							
		End Select
		
		NO.PosX = EntityX(mesh)
		NO.PosY = EntityY(mesh)
		NO.PosZ = EntityZ(mesh)
		NO.Mesh = mesh

		
			
		
		NO.Node =  newtonCreateBody(TPhysic.World , NO.Body)
		
		'Max3DGetMatrix(NO , Varptr NO.Mat[0])
						
		Local tempmat:Float[16]
		Local mmp:Float Ptr=Mesh.Mat.grid
		tempmat[0]=mmp[0]
		tempmat[1]=mmp[1]
		tempmat[2]=-mmp[2]
		tempmat[4]=mmp[4]
		tempmat[5]=mmp[5]
		tempmat[6]=-mmp[6]
		tempmat[8]=mmp[8]
		tempmat[9]=mmp[9]
		tempmat[10]=-mmp[10]
		tempmat[12]=mmp[12]'posx
		tempmat[13]=mmp[13]'posy
		tempmat[14]=-mmp[14]'-posz
		'Mesh.Mat.Scale(-mesh.sx,-mesh.sy,-mesh.sz)
		
				
	
		newtonBodySetMatrix(NO.Node , tempmat)
		newtonBodySetUserData(NO.node ,Byte Ptr bbhandlefromobject(NO))
		
		NO.Volume = NewtonConvexCollisionCalculateVolume(No.Body)
		NO.AABB[0] = New TVector
		NO.AABB[1] = New TVector
		NewtonBodyGetAABB(NO.Node,No.AABB[0],NO.AABB[1])
		
		No.UpdateForce = [0.0 , 9.81 , 0.0]
				
		Mesh.PhysicObject = NO
						
		Return NO
	End Function
		
	Method OmegaToString:String()
		Return "Omega : " + Omega[0] + " : " + (Omega[1]* 180.0 / Pi) + " : " + Omega[2]
	End Method
	
	Method VelocityToString:String()
		Return "Velocity : " + Velocity[0] + " : " + Velocity[1] + " : " + Velocity[2]
	End Method
	
	Method GetVelocity:TVector()
		Local V:TVector = New TVector
		V.X = Velocity[0]
		V.Y = Velocity[1]
		V.Z = Velocity[2]
		Return V
	End Method
		
	Method GetPosition:TVector()
		Local V:TVector = New TVector
		V.X = PosX
		V.Y = PosY
		V.Z = PosZ
		Return V
	End Method
	
	Method SetRotation(Pitch# , Roll# , Yaw#)
		RotX = Pitch 
		RotY = Roll
		RotZ = Yaw
		Local Euler:Float[3]
		Euler[0] = rotX * Pi / 180.0
		Euler[1] = rotY * Pi / 180.0
		Euler[2] = rotZ * Pi / 180.0
		NewtonSetEulerAngle(Varptr Euler[0] , Varptr Mat[0])
		
		Max3DSetMatrix(Self,Mat)

	End Method
		
	
	Method Update()
		If UpPos = True Then
			UpdatePos()
			Return
		EndIf
		newtonBodyGetMatrix(Node , Mat)
		NewtonBodyGetVelocity(Node,Velocity)
		NewtonBodyGetOmega(Node,Omega)
		Max3DSetMatrix(Self,Mat)
		Local mmp:Float Ptr=Mesh.Mat.grid
		mmp[0]=mat[0]
		mmp[1]=mat[1]
		mmp[2]=-mat[2]
		mmp[4]=mat[4]
		mmp[5]=mat[5]
		mmp[6]=-mat[6]
		mmp[8]=mat[8]
		mmp[9]=mat[9]
		mmp[10]=-mat[10]
		mmp[12]=mat[12]'posx
		mmp[13]=mat[13]'posy
		mmp[14] = - mat[14]'-posz
		
		posx = mat[12]
		posy = mat[13]
		posz = - mat[14]
		
		Mesh.Mat.Scale(-mesh.sx,-mesh.sy,-mesh.sz)
	End Method
	
	Method UpdatePos()
		newtonBodyGetMatrix(Node , Mat)
		NewtonBodyGetVelocity(Node,Velocity)
		NewtonBodyGetOmega(Node,Omega)
		Max3DSetMatrix(Self,Mat)
		Local mmp:Float Ptr=Mesh.Mat.grid
		mmp[12]=mat[12]'posx
		mmp[13]=mat[13]'posy
		mmp[14] = - mat[14]'-posz
		
		posx = mat[12]
		posy = mat[13]
		posz = - mat[14]
		
		Mesh.Mat.Scale(-mesh.sx,-mesh.sy,-mesh.sz)
	End Method
		
		
	Method SetMass(Mass:Float)
		Local Massp:Float[3]
		Local Inertia:Float[3]
		newtonBodySetMassMatrix(Node , Mass , inertia[0] , inertia[1], inertia[2])
		NewtonConvexCollisionCalculateInertialMatrix(body,Inertia,Massp)
		NewtonBodySetCentreOfMass(Node,Massp)
		'Print "Inertia: " + inertia[0] +","+inertia[1]+","+inertia[2]
		'Print "Mass: " + Massp[0] +","+Massp[1]+","+Massp[2]
		
		newtonBodySetMassMatrix(Node , Mass , inertia[0] , inertia[1], inertia[2])
	End Method
	
	Method SetCollisionMode(Mode:Int = PHYS_NORMAL_COLLISION)
		NewtonBodySetContinuousCollisionMode(Node,Mode)
	End Method
	
	Method SetAutoSleep(State:Int = 1)
		NewtonBodySetAutoFreeze(node , State)
	End Method
	
	Method SetSleepTreshold(speedmag:Float,omegamag:Float,frames:Int)
		NewtonBodySetFreezetreshold(node , speedmag , omegamag , frames)
	End Method
	
	Method SetUserForceCallback(Callback(NewtonObject:TNewtonObject))
		UserForceCallBack = CallBack
	End Method
	
	Method GetRotation:String()
		Local Euler:Float[3]
		NewtonGetEulerAngle(Varptr Mat[0] , Varptr Euler[0])
		rotX  = Euler[0] * 180.0 / Pi
		rotY  = Euler[1] * 180.0 / Pi
		rotZ = Euler[2] * 180.0 / Pi
		Return "Rotation : " + rotX   + " : " + rotY + " : " + rotZ

	End Method
	
	
	
End Type

Type TPhysicMaterial
	Field Name:String = ""
	Field GroupID:Int
	Field UseContactCallback:Byte = False
	
	Field DefaultFriction:Float[2]
	Field DefaultSoftness:Float
	Field DefaultElasticity:Float
	
	Field StaticFriction:Float
	Field KineticFriction:Float
	Field Softness:Float
	Field Elasticity:Float
	Field FrictionState:Int
	Field TangantACC:Float
	Field TangantDirs:Float
	Field NormalAcc:Float
	Field NormalDir:Float
	
	Function Create:TPhysicMaterial(Name:String)
		Local Mat:TPhysicMaterial = New TPhysicMaterial
		Mat.Name = Name
		Mat.GroupID = NewtonMaterialCreateGroupID(TPhysic.World)
		Return Mat
	End Function
	
	Method SetFriction(staticFriction:Float,KineticFriction:Float)
		DefaultFriction = [staticFriction,KineticFriction]
	End Method
	
	Method SetSoftness(Softness:Float)
		DefaultSoftness = Softness
	End Method
	
	Method SetElasticity(Elasticity:Float)
		DefaultElasticity = Elasticity
	End Method
End Type
	

Function Max3DGetMatrix(Node:TNewtonObject , NewtonMat:Float Ptr)
	Local Euler:Float[3]
	Euler[0] = Node.rotX * Pi / 180.0
	Euler[1] = Node.rotY * Pi / 180.0
	Euler[2] = Node.rotZ * Pi / 180.0
	NewtonSetEulerAngle(Varptr Euler[0] , Varptr newtonMat[0])
	Newtonmat[12] = Node.PosX
	newtonMat[13] = Node.PosY
	NewtonMat[14] = Node.PosZ	
End Function

Function Max3DSetMatrix(Node:TNewtonObject , NewtonMat:Float Ptr)
	Local Euler:Float[3]
	NewtonGetEulerAngle(Varptr NewtonMat[0] , Varptr Euler[0])
	Node.Posx = NewtonMat[12]
	Node.Posy = NewtonMat[13]
	Node.Posz = NewtonMat[14]
	Node.rotX  = Euler[0] * 180.0 / Pi
	Node.rotY  = Euler[1] * 180.0 / Pi
	Node.rotZ  = Euler[2] * 180.0 / Pi
End Function


Function ForceCallback(body:Byte Ptr)
	
	Local T:Byte Ptr = newtonBodyGetUserData(body)
	Local T2:TNewtonObject = TNewtonObject(bbhandletoobject(Int(T) ) )
	
	If T2.UserForceCallBack <> Null Then
		T2.UserForceCallBack(T2)
	EndIf
	
	Local Ixx:Float[1]
	Local Iyy:Float[1]
	Local Izz:Float[1]
	Local mass:Float[1]

	NewtonBodyGetMassMatrix (body, mass, Ixx, Iyy, Izz);
	Local force:Float[] = [T2.UpdateForce[0], -mass[0]* T2.UpdateForce[1], T2.UpdateForce[2]]
	NewtonBodySetForce (body, force)
End Function

Function TransformCallback(body:Byte Ptr)
	Local T:Byte Ptr = newtonBodyGetUserData(body)
	Local T2:TNewtonObject = TNewtonObject(bbhandletoobject(Int(T)))
	T2.Update()
End Function

Function ActivationCallback(body:Byte Ptr)
	Local T:Byte Ptr = newtonBodyGetUserData(body)
	Local T2:TNewtonObject = TNewtonObject(bbhandletoobject(Int(T)))
	
	
	If T2.Active = True Then
		T2.Active = False
		TPhysic.UnActiveBodies:+1
	Else
		T2.Active = True
		TPhysic.UnActiveBodies:-1
	EndIf
	
	If TPhysic.UnActiveBodies < 0 Then TPhysic.UnActiveBodies = 0
	
End Function

Function Contact_Begin_CallBack:Int(material:Byte Ptr,body0:Byte Ptr, body1:Byte Ptr)
	TPhysic.CurrentContact = New TContactInfo
	Local T:Byte Ptr = newtonBodyGetUserData(body0)
	Local TT:TNewtonObject = TNewtonObject(bbhandletoobject(Int(T)))
	
	Local T1:Byte Ptr = newtonBodyGetUserData(body1)
	Local TT1:TNewtonObject = TNewtonObject(bbhandletoobject(Int(T1)))
	

	TPhysic.CurrentContact.Body1 = TT
	TPhysic.CurrentContact.Body2 = TT1
	TPhysic.CurrentContact.Material = material
	Return 1
End Function

Function Contact_Process_CallBack:Int(material:Byte Ptr,body0:Byte Ptr, body1:Byte Ptr,contact:Byte Ptr)
	TPhysic.CurrentContact.Contactpoints = contact
	?win32
	TPhysic.CurrentContact.ContactNormalSpeed = NewtonMaterialGetContactNormalSpeed(Varptr material,Varptr contact)
	?	
	NewtonMaterialGetContactPositionAndNormal(material,TPhysic.CurrentContact.ContactPosition,TPhysic.CurrentContact.ContactNormalPosition)
	NewtonMaterialGetContactForce(material,TPhysic.CurrentContact.ContactForce)
	NewtonMaterialGetContactTangentDirections(material,TPhysic.CurrentContact.ContactTangentDirection1,TPhysic.CurrentContact.ContactTangentDirection2)
	TPhysic.CurrentContact.TimeStep = NewtonMaterialGetCurrentTimeStep(material)
	?win32
	TPhysic.CurrentContact.ContactTangentSpeed1 = NewtonMaterialGetContactTangentSpeed(Varptr material,Varptr contact,0)
	TPhysic.CurrentContact.ContactTangentSpeed1 = NewtonMaterialGetContactTangentSpeed(Varptr material,Varptr contact,1)
	?
	If TPhysic.ContactProcess
		TPhysic.ContactProcess(TPhysic.CurrentContact)
	EndIf
	Return 1
End Function

Function Contact_End_CallBack(material:Byte Ptr)
	If TPhysic.ContactEnd Then
		TPhysic.ContactEnd(TPhysic.CurrentContact)
	EndIf
End Function

Function Ball_CallBack(ball:Byte Ptr)
	Local h:Byte Ptr = NewtonJointGetUserData(Ball)
	Local B:TBallConstrait = TBallConstrait(bbHandletoObject(Int(h)))
	
	If TPhysic.BallUserCallBack Then
		TPhysic.BallUserCallBack(B)
	EndIf
End Function


Function RenderDebugCollision(body:Byte Ptr,vertexCount:Int,faceVertec:Float Ptr,id:Byte Ptr)
	Local i:Int
	Local p0:TVector
	Local p1:TVector
	
	'glDisable(GL_LIGHTING)
	'glDisable(GL_TEXTURE_2D)
	
	'glMaterialfv(GL_FRONT,GL_DIFFUSE,[1.0,0.0,0.0,1.0])
	'glDrawElements(GL_LINES ,vertexCount/2, GL_UNSIGNED_INT , faceVertec)

	'glBegin(GL_LINES)
	'glColor3f(1.0, 1.0, 0.0)
	
	
	i = vertexcount - 1
	p0=  New TVector
	p0.x = faceVertec[i * 3 + 0]
	p0.y = faceVertec[i * 3 + 1]
	p0.z = faceVertec[i * 3 + 2]
	For i = 0 To vertexcount-1
		p1 = New TVector
		p1.x = faceVertec[i * 3 + 0]
		p1.y = faceVertec[i * 3 + 1]
		p1.z = faceVertec[i * 3 + 2]

		glVertex3f (p0.x, p0.y, -p0.z)
		glVertex3f (p1.x, p1.y, -p1.z)
 		p0 = p1
	Next
	'glEND()
	
End Function

Function RenderBodyCollision(body:Byte Ptr)
	NewtonBodyForEachPolygonDo (body, RenderDebugCollision)
End Function
	
Extern
Function bbHandleToObject:Object( handle )
Function bbHandleFromObject:Int( obj:Object )
End Extern

' Leadwerks function
Function EulerToQuat:TQuaternion(pitch#,yaw#,roll#)
	Local cr#=Cos(-roll#/2.0)
	Local cp#=Cos(pitch#/2.0)
	Local cy#=Cos(yaw#/2.0)
	Local sr#=Sin(-roll#/2.0)
	Local sp#=Sin(pitch#/2.0)
	Local sy#=Sin(yaw#/2.0)
	Local cpcy#=cp#*cy#
	Local spsy#=sp#*sy#
	Local spcy#=sp#*cy#
	Local cpsy#=cp#*sy#
	Local q:TQuaternion=New TQuaternion
	q.w#=cr#*cpcy#+sr#*spsy#
	q.x#=sr#*cpcy#-cr#*spsy#
	q.y#=cr#*spcy#+sr#*cpsy#
	q.z#=cr#*cpsy#-sr#*spcy#
	Return q
End Function

Function MultiplyQuats:TQuaternion(q1:TQuaternion,q2:TQuaternion)

	Local q:TQuaternion=New TQuaternion
	
	q.w = q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z
	q.x = q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y
	q.y = q1.w*q2.y + q1.y*q2.w + q1.z*q2.x - q1.x*q2.z
	q.z = q1.w*q2.z + q1.z*q2.w + q1.x*q2.y - q1.y*q2.x

	Return q

End Function

Function NormalizeQuat:TQuaternion(q:TQuaternion)

	Local uv#=Sqr(q.w*q.w+q.x*q.x+q.y*q.y+q.z*q.z)

	q.w=q.w/uv
	q.x=q.x/uv
	q.y=q.y/uv
	q.z=q.z/uv

	Return q

End Function

Type TCameraController
	Field Cam:TCamera
	Field Bounding:TMesh
	Field NewtonObject:TNewtonObject
	Field Upvector:Float[] = [0.0 , 1.0 , 0.0]
	Field Dummies:TPivot[3] 'Left = 0,Front = 1,Right = 2
	Field System:TPhysic
	
	Function Create:TCameraController(Cam:TCamera,System:TPhysic,RadiusX:Int = 5,RadiusY:Int = 10,RadiusZ:Int = 5)
		Local CC:TCameraController = New TCameraController
		CC.Cam = Cam
		
		'temporaly saving orientation of the cam
		Local X:Float = EntityX(Cam)
		Local Y:Float = EntityY(Cam)
		Local Z:Float = EntityZ(Cam)
		Local Pitch:Float = EntityPitch(Cam)
		Local Roll:Float = EntityRoll(Cam)
		Local Yaw:Float = EntityYaw(Cam)
		
		'Setting all cam coords to 0 (for propper dummy align)
		
		PositionEntity(Cam , 0 , 0 , 0) 
		RotateEntity(Cam , 0 , 0 , 0)
		
		'Creating Pivots
		
		CC.Dummies[0] = CreatePivot(Cam)
		CC.Dummies[1] = CreatePivot(Cam)
		CC.Dummies[2] = CreatePivot(Cam)
		
		TranslateEntity(CC.Dummies[0] , 5 , 0 , 0)
		TranslateEntity(CC.Dummies[1] , 0 , 0 , 5)
		TranslateEntity(CC.Dummies[2] , -5 , 0 , 0)
		
		'Reseting Cam
		
		PositionEntity(Cam , X , Y , Z)
		RotateEntity(Cam , Pitch , Yaw , Roll)
		
		CC.Bounding = CreateSphere(8) 
		ScaleEntity(CC.Bounding , RadiusX , RadiusY , RadiusZ)
		PositionEntity(CC.Bounding, X , Y , Z)
		RotateEntity(CC.Bounding , Pitch , Yaw , Roll)
		HideEntity(CC.Bounding)

		
		'EntityParent(Cam,CC.Bounding)
		
		CC.NewtonObject = TNewtonObject.Create(CC.Bounding , PHYS_SPHERE_HULL)		
		CC.NewtonObject.SetMass(1.0) ' Set it solid
		CC.System = system
		CC.NewtonObject.extra = cc
		CC.NewtonObject.SetUserForceCallback(Control_Callback)
		System.AddObject(CC.NewtonObject) 
		NewtonConstraintCreateUpVector(TPhysic.World,[0.0,1.0,0.0],CC.NewtonObject.Node)

		
		
		Return CC
		
	End Function
	
	Method Move(Speed:Float)
		Local V1:TVector = TVector.Create(EntityX(Dummies[1],True),EntityY(Dummies[1],True),EntityZ(Dummies[1],True))
		Local V2:TVector = TVector.Create(EntityX(Cam) , EntityY(Cam) , EntityZ(Cam) )
		
		Local V3:TVector = V1.Subtract(V2).Multiply(Speed/20.0)
					
		System.ApplyImpulse(Bounding,EntityX(Cam),EntityY(cam),EntityZ(cam),V3.X,V3.Y,V3.Z)
	End Method
	
	Method MoveVector(V:TVector)
		
		'V = Cam.mat.MulV(V)
		NewtonObject.SetRotation(EntityPitch(Cam) , EntityRoll(Cam) , EntityYaw(Cam) )
		NewtonObject.Update()

		System.ApplyImpulse(Bounding,EntityX(Cam),EntityY(cam),EntityZ(cam),V.Y,V.X,V.Z)
	End Method
		
	
End Type

Function Control_Callback(body:TNewtonObject)
	Local CC:TCameraController = TCameraController(body.extra)
	If CC = Null Then Return
	PositionEntity(CC.Cam,body.posx,body.posy,-body.posz)
End Function	


Any other help would be greatly appreciated!

sry, I had forgotten to mention that in the new Version you don't have to manage the update ad it is managed in UpdateWorld.

So with your version you have to replace the PhysicWorld.Update() in the sample with PhysicWorld.AccuUpdate()

Then it should work much better.