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!