;VividGL3D Lite.
;
;--[ Sim-Physics Module ]-[CORE]
;
;(c)Antony Wells 2004.
;
;Powered by Tokamak.
;Tokamak Wrapper originally by Sweenie, converted by Antony Wells.
;If the above is wrong, please inform me and i'll fix it.
;---

;--[ Sim Defaults ]

Global Sim_MaxActors=100
Global Sim_MaxSubActors=20
Global Sim_MaxParticles=20
Global Sim_MaxDirectors=0

Global Sim_DebugBatch=createBatch()

Type Sim_Obj ;Internal Type(All types are)
	Field body,aBody
	Field RealMesh
	Field Weight#
	Field LinearDrag#
	Field AngleDrag#
	Field Parent.ent
	;--[Debug Info/Visulization]
	Field Debug_Entity
End Type
Const Sim_On=1,Sim_Off=0

Function Sim_Init(GravityX#=0,GravityY#=-10,GravityZ#=0)
	;TOKSIM_SetRigidBodiesCount Sim_MaxActors
;	TOKSIM_SetAnimatedBodiesCount Sim_MaxActors
	;TOKSIM_SetRigidParticleCount Sim_MaxParticles
	;TOKSIM_SetControllersCount Sim_MaxDirector
	
	TOKSIM_CreateSimulator( GravityX,GravityY,GravityZ)
	
End Function

Function Sim_Update(Time#=1)
	TOKSIM_Advance 1.5/90,1
	For sim.sim_obj=Each sim_obj
		If sim\weight>0
			Entity_Position Handle(Sim\Parent),TOKRB_GetX(sim\body)-sim\parent\bound\x,TOKRB_GetY(sim\Body)-sim\parent\bound\y,TOKRB_GetZ(sim\body)-sim\parent\bound\z,True
			Entity_Rotate Handle(Sim\Parent),TOKRB_GetPitch(sim\body),TOKRB_GetYaw(sim\body),TOKRB_GetRoll(sim\body),True
		Else
			Entity_Position Handle(Sim\Parent),TOKAB_GetX(sim\body),TOKAB_GetY(sim\Body),TOKAB_GetZ(sim\body),True
			Entity_Rotate Handle(Sim\Parent),TOKAB_GetPitch(sim\body),TOKAB_GetYaw(sim\body),TOKAB_GetRoll(sim\body),True
		EndIf
	Next
	
End Function

;--[ Entity Module Extensions ]

;requires the adjency .exe to be included with your program.
Function Entity_UpdateConvex(Entity) ;Internally Generally..
Local m,in.ent,vcount
	in.ent=Object.ent(Entity)
	in\hull=Null Entity_UpdateHull(Entity)

	m=Handle(in\hull)
	For s=0 To Entity_CountSurfaces(m)-1
	surf=Entity_GetSurface(m,s)
	Surface_Lock(surf)
	For i=0 To Surface_CountVertices()-1
	vcount=vcount+1
	Next
	Next
	fil=WriteFile("TempConvex.txt")
		WriteLine fil,vcount
		For s=0 To Entity_CountSurfaces(m)-1
		surf=Entity_GetSurface(m,s)
		Surface_Lock(surf)
		For i=0 To Surface_CountVertices()-1
			WriteLine fil,Surface_VertexX(i)+" "+Surface_VertexY(i)+" "+Surface_VertexZ(i)
		Next
		Next
		CloseFile fil
		ExecFile "adjacency "+"TempConvex.txt "+"ConvexBin.Bin"
		out=CreateBank(FileSize("ConvexBin.Bin"))
		fi=ReadFile("Convexbin.bin")
		ReadBytes out,fi,0,BankSize(out)
		in\Convex=out
		CloseFile fi

End Function


Const Sim_Box=0,Sim_Ball=1,Sim_Hull=2,Sim_Static=3

Function Entity_SimMaterial(Entity,Material)
	in.ent=Object.ent(entity)
	in\sim_Mat=material
End Function

Function Entity_SimOn(Entity,Weight#=0.3,CollisionMode=0)
	In.ent=Object.ent(entity)
	Select CollisionMode
		Case Sim_Static
			Tok_AddMesh(Entity,in\Sim_Mat)
			Tok_SetMesh()
		Default
			Sim_GenericBody(In,Weight,CollisionMode)
	End Select
End Function
Function Entity_SimStatic(Entity)
;	in.ent=Object.ent(Entity)
	;Tok_AddMesh(Entity)
	
End Function

Function Entity_Push(Entity,XForce#,yForce#,zForce#,GlobalPush=True)
	in.ent=Object.ent(entity)
	If Not GlobalPush
			TForm_Point xforce,yforce,zforce,entity,0
			xForce=TFormedX()-in\x
			yForce=TFormedY()-in\y
			zForce=TFormedZ()-in\z
	EndIf
	TOKRB_ApplyImpulse in\sim\body,xForce,yForce,zForce
End Function

Function Entity_PushFrom(Entity,FromX#,FromY#,FromZ#,xForce#,yForce#,zForce#,GlobalFrom=True,GlobalForce=True)
	in.ent=Object.ent(Entity)
	If Not GlobalFrom
			TForm_Point formx,fromy,fromz,entity,0
			fromx=TFormedX()
			fromy=TFormedY()
			fromz=TFormedZ()
	EndIf
	If Not globalForce
		TForm_Point xforce,yforce,zforce,entity,0
			xForce=TFormedX()-in\x
			yForce=TFormedY()-in\y
			zForce=TFormedZ()-in\z
	EndIf
	TOKRB_ApplyImpulse2 in\sim\body,xForce,yForce,zForce,FromX#,FromY#,FromZ#
End Function
Function Entity_Twist(Entity,PitchForce#,YawForce#,RollForce#)
	in.ent=Object.ent(entity)
	TOKRB_ApplyTwist in\sim\body,PitchForce,YawForce,RollForce
End Function

Function Entity_Torque(Entity,PitchForce#,YawForce#,RollForce#)
	in.ent=Object.ent(entity)
	TOKRB_SetTorque in\sim\body,PitchForce,YawForce,RollForce
End Function


Function Entity_Velocity(Entity,xForce#,yForce#,zForce#,GlobalVelocity=False)
	in.ent=Object.ent(entity)
	If Not globalVelocity
		TForm_Point xforce,yforce,zforce,entity,0
		xForce=TFormedX()-in\x
		yForce=TFormedY()-in\y
		zForce=TFormedZ()-in\z
	EndIf
TOKRB_SetForce in\sim\body,xForce,yForce,zForce
End Function


Function Entity_Collider(Entity)

End Function

;Generic bodies automatically hug the entity. Don't worry about it!
Function Sim_GenericBody.Sim_Obj(Ent.Ent,Weight#=0,CollisionMode) ;Internal Function
	out.sim_obj=New sim_obj
	ent\sim=out
	Entity_UpdateBound(Handle(ent))
	out\parent=ent
	out\weight=weight
	
	If weight=0
		out\body=TOKAB_Create()
		aBody=TOKAB_AddBox(out\body,ent\bound\w,ent\bound\h+20,ent\bound\d)
		TOKAB_SetPosition out\body,ent\x,ent\y-25,ent\z
	Else
		out\body=TOKRB_Create()
		Select collisionMode
		Case Sim_Box
			aBody=TOKRB_AddBox(out\body,ent\bound\w,ent\bound\h,ent\bound\d)
			TOKRB_SetBoxInertiaTensor out\body,ent\bound\w,ent\bound\h,ent\bound\d,weight; weight+(0.01*(weight=0))
		Case Sim_Hull
			Entity_updateConvex(Handle(ent))
			aBody=TOKRB_AddConvex(out\body,ent\convex,BankSize(ent\convex))
			entity_updateBound(Handle(ent\hull))
			TOKRB_SetSphereInertiaTensor out\body,ent\hull\bound\size,weight
		End Select
			TOKRB_SetPosition out\body,ent\x,ent\y,ent\z
			TOKRB_SetMass out\body,weight;weight+(0.01*(Weight=0))
			TOKRB_SetPosition out\body,ent\x,ent\y,ent\z
			TOKRB_SetRotation out\body,ent\pt,ent\yw,ent\rl
		EndIf
	Out\aBody=aBody	
	Select CollisionMode
		Case Sim_Box
			temp=CreateCube() 
			FitMesh temp,-ent\bound\w/2,-ent\bound\h/2,-ent\bound\d/2,ent\bound\w,ent\bound\h,ent\bound\d
			temp=Entity_ConvB3D(temp)
		Case sim_Hull
			temp=Handle(ent\hull)
	End Select
	Entity_Paint temp,Rnd(128,255),Rnd(128,255),Rnd(128,255)
	Entity_CullMode temp,glDisableCull
	Entity_ColorMode temp,glColorMode
	Entity_Compile(Temp,Compile_Static)
	Entity_Position temp,ent\bound\x,ent\bound\y,ent\bound\z
	Batch_AddEntity(Sim_DebugBatch,Temp)
	Batch_AddEntity(SIM_debugBatch,TEMP)
	out\Debug_Entity=temp
	Return(out)
End Function

Global Sim_Index=0

Function Sim_NewMaterial(Friction#=0.1,Bounce#=0.7)
	Sim_Index=Sim_Index+1
	TOKSIM_SetMaterial Sim_Index,Friction,Bounce
	Return Sim_Index
End Function

Function Sim_UpdateDebug()
	For sim.sim_obj =Each sim_obj
		Entity_Position sim\debug_entity,sim\parent\x,sim\parent\y,sim\parent\z,True
		Entity_Rotate sim\debug_entity,sim\parent\pt,sim\parent\yw,sim\parent\rl,True
	Next
End Function

Function Sim_RenderDebug()
	glDisable(GL_LIGHTING)
;	glClsZ()
	Batch_Render(Sim_DebugBatch)
	glEnable(GL_LIGHTING)
End Function

;
;3rd party pd functions converted
;to vividgl by antony wells.

Global v_vertices=CreateBank(0),v_triangles=CreateBank(0)
Global v_offsett,v_offsetv,v_tric,ttlvert,v_ttltris,v_cvt
Dim v_tname$(20),v_tMindex(20)
Global v_cur=0
Function TOK_SetTextureMaterial(fil$,Mindex)
 v_tname$(cur)=fil$
 v_tMindex(cur)=Mindex
 cur=cur+1
End Function

Function TOK_AddMesh(mesh,mat=1)
 scount=Entity_CountSurfaces(mesh)
 For ind=0 To scount-1
  surface=Entity_GetSurface(mesh,ind)
  Surface_Lock(surface)
  v_ttltris=v_ttltris+Surface_CountTriangles()
  v_ttlvert=v_ttlvert+Surface_CountVertices()
 Next
 ResizeBank v_triangles,v_ttltris*24
 ResizeBank v_vertices,v_ttlvert*16
 For ind=0 To scount-1
 
  surface = Entity_GetSurface(mesh,ind)
  Surface_Lock(surface)
  ;bru=GetSurfaceBrush(surface)
  ;tex=GetBrushTexture(bru,textureindex)
	texIn=Surface_GetTexture(surface,texture_Index)
;  nam$=strippath$(Texture_GetName$(texIn))
 fo=0
 
 ; For a=0 To cur-1

 ;  If v_tname$(a)=nam$ Then mindex=v_tMindex(a):fo=1:Exit

;  Next

  If fo=0 Then mindex=0 

;  FreeBrush bru


 ; FreeTexture tex

  ctr=Surface_CountTriangles()
  v_cvt=Surface_CountVertices()


  ;add vertices to bank
;glLockSurface(surface)

  For v=0 To v_cvt-1 

   TForm_Point Surface_VertexX(v),Surface_VertexY(v),Surface_VertexZ(v),mesh,0
   PokeFloat v_vertices,v_offsetv,TFormedX()
   PokeFloat v_vertices,v_offsetv+4,TFormedY()
   PokeFloat v_vertices,v_offsetv+8,TFormedZ()
   PokeFloat v_vertices,v_offsetv+12,0.0
   v_offsetv=v_offsetv+16 
  Next

  ;fill bank with triangles 
  For v=0 To ctr-1 
   PokeInt v_triangles,v_offsett,v_tric+Surface_TriangleVertex(v,2)
   PokeInt v_triangles,v_offsett+4,v_tric+Surface_TriangleVertex(v,1)
   PokeInt v_triangles,v_offsett+8,v_tric+Surface_TriangleVertex(v,0)
  If mat=-1 Then PokeInt v_triangles,v_offsett+12,mindex Else PokeInt v_triangles,v_offsett+12,mat
   PokeInt v_triangles,v_offsett+16,0
   PokeInt v_triangles,v_offsett+20,0
   v_offsett=v_offsett+24
  Next
   v_tric=v_tric+ctr 
Surface_Unlock()
 Next
 .rec

 Return
 If recurse Then 
  ;children=glCountChildren(mesh)

  If children>0 Then

   For childcount = 1 To children

    child = GetChild(mesh,childcount)

    ;If EntityClass$(child)="Mesh" Then TOK_AddMesh child,recurse,mat Else TOK_recurse child,mat 

   Next 

  EndIf

 EndIf

End Function


Function TOK_recurse(mesh,mat)
Local child,children
 children=CountChildren(mesh)

 If children>0 Then

  For childcount = 1 To children

   child = GetChild(mesh,childcount)

;   If EntityClass$(child)="Mesh" Then TOK_AddMesh child,1,mat Else TOK_recurse child,mat  


  Next 

 EndIf

End Function


Function TOK_SetMesh()

 ;Hand over the terrain data to Tokamak

 TOKSIM_SetStaticMesh v_vertices,v_ttlvert,v_triangles,v_ttltris

 ; Now we can free the banks as Tokamak has copied all data

 ;FreeBank v_vertices
 ;FreeBank v_triangles
 

End Function


Function StripPath$(file$) 

 If Len(file$)>0 

  For i=Len(file$) To 1 Step -1 

   mi$=Mid$(file$,i,1) 

   If mi$="\" Or mi$="/" Then Return name$ Else name$=mi$+name$ 

  Next 

 EndIf 

 Return name$ 

End Function 


Function TOK_ReInitMap()

 v_vertices=CreateBank(0)

 v_triangles=CreateBank(0)

 v_offsett=0

 v_offsetv=0

 v_tric=0

 v_ttlvert=0

 v_ttltris=0


End Function


