New ODE 0.5 wrapper for Blitz3D

Blitz3D Forums/Blitz3D Programming/New ODE 0.5 wrapper for Blitz3D

It is possible to scan all child in a loadanimmesh for automatic
add box around object ? i ha ve try this code but seem don't work well

; ----------------------------
; Global ODE space
; ----------------------------
Global ODE_Space

; --------------------------
; ODE Object Type
; --------------------------
Type ODE_Object
	Field ObjectBody
	Field ObjectMesh
	Field ObjectGeom

	Field ObjectFake ; Pour les cylindres
	
	Field ObjectSound
	Field ObjectChannel

	Field ObjectMass#

	Field ObjectRotX#
	Field ObjectRotY#
	Field ObjectRotZ#
	
	Field ObjectPx#
	Field ObjectPy#
	Field ObjectPz#

	Field ObjectScaleX#
	Field ObjectScaleY#
	Field ObjectScaleZ#
End Type

; ------------------------------------
; On setup le monde ODE
; ------------------------------------
Function ODE_InitWorld(Gravity#=-1.5,Bounce#=0.1)
	ODE_Space = ODE_dWorldCreate()
;	ODE_dWorldSetGravity(0, Gravity#, 0)

;	ODE_dSetContactMode(dContactBounce+ dContactSoftERP )  ; dContactBounce+ dContactSoftERP + dContactSoftCFM
	
;	ODE_dSetBOUNCE(Bounce#)
;	ODE_dSetSOFT_ERP(0.4)
;	ODE_dSetSOFT_CFM(0.8)
	
	ODE_dSetContactMode(dContactBounce + dContactSoftERP + dContactSoftCFM + dSlip1 + dSlip2)
ODE_dSetBOUNCE(0.5)
ODE_dSetSOFT_ERP(0.3)
ODE_dSetSOFT_CFM(0.00000001);0.3)

End Function

; -------------------------------------------------------------------------
; Permet de créer un cube ODE a partie d'une mesh
; -------------------------------------------------------------------------
Function ODE_CreateCubeMesh(Mesh$,Px#,Py#,Pz#,RotX#,RotY#,RotZ#,Mass#=1,Sound$="")
	G.ODE_Object = New ODE_Object

	G\ObjectMass#=Mass#
	G\ObjectMesh = LoadMesh(Mesh$)
	ScaleEntity G\ObjectMesh,1,1,1
	
	G\ObjectRotX#=RotX#
	G\ObjectRotY#=RotY#
	G\ObjectRotZ#=RotZ#
	
	G\ObjectPx#=Px#
	G\ObjectPy#=Py#
	G\ObjectPz#=Pz#

	RotateEntity G\ObjectMesh,G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#
	PositionEntity G\ObjectMesh,G\ObjectPx#,G\ObjectPy#,G\ObjectPz#

	G\ObjectScaleX#=MeshWidth(G\ObjectMesh) 
	G\ObjectScaleY#=MeshHeight(G\ObjectMesh) 
	G\ObjectScaleZ#=MeshDepth(G\ObjectMesh) 
	
	G\ObjectBody = ODE_dBodyCreate()
	G\ObjectGeom = ODE_dCreateBox(ODE_Space, G\ObjectScaleX#,G\ObjectScaleY#,G\ObjectScaleZ#, G\ObjectMass#)
	
	ODE_dGeomSetBody G\ObjectGeom, G\ObjectBody
	ODE_dBodySetPosition(G\ObjectBody, G\ObjectPx#,G\ObjectPy#,G\ObjectPz#)
	ODE_dBodySetRotation(G\ObjectBody, G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#)

	If Sound$<>"" Then 
		G\ObjectSound=LoadSound(Sound$)
	Else
		G\ObjectSound=0
	EndIf 
End Function

; ------------------------------------------------------------------------------
; Permet de créer une sphere ODE a partie d'une mesh
; ------------------------------------------------------------------------------
Function ODE_CreateSphereMesh(Mesh$,Px#,Py#,Pz#,RotX#,RotY#,RotZ#,Mass#=1,Sound$="")
	G.ODE_Object = New ODE_Object

	G\ObjectMass#=Mass#
	G\ObjectMesh = LoadMesh(Mesh$)

	G\ObjectRotX#=RotX#
	G\ObjectRotY#=RotY#
	G\ObjectRotZ#=RotZ#
	
	G\ObjectPx#=Px#
	G\ObjectPy#=Py#
	G\ObjectPz#=Pz#

	RotateEntity G\ObjectMesh,G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#
	PositionEntity G\ObjectMesh,G\ObjectPx#,G\ObjectPy#,G\ObjectPz#

	G\ObjectScaleX#=MeshHeight(G\ObjectMesh) 
	G\ObjectScaleY#=MeshHeight(G\ObjectMesh) 
	G\ObjectScaleZ#=MeshHeight(G\ObjectMesh) 
	
	G\ObjectBody = ODE_dBodyCreate()
	G\ObjectGeom = ODE_dCreateSphere(ODE_Space, G\ObjectScaleX#,G\ObjectMass#)
	
	ODE_dGeomSetBody G\ObjectGeom, G\ObjectBody
	ODE_dBodySetPosition(G\ObjectBody, G\ObjectPx#,G\ObjectPy#,G\ObjectPz#)
	ODE_dBodySetRotation(G\ObjectBody, G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#)

	If Sound$<>"" Then 
		G\ObjectSound=LoadSound(Sound$)
	Else
		G\ObjectSound=0
	EndIf 
End Function

; ------------------------------------
; Permet de créer un cube
; ------------------------------------
Function ODE_CreateCube(Px#,Py#,Pz#,RotX#,RotY#,RotZ#,ScaleX#,ScaleY#,ScaleZ#,Mass#=1,Sound$="",Red=255,Green=255,Blue=255,View%=1)
	G.ODE_Object = New ODE_Object

	G\ObjectMass#=Mass#
	
	G\ObjectScaleX#=ScaleX#
	G\ObjectScaleY#=ScaleY#
	G\ObjectScaleZ#=ScaleZ#

	G\ObjectBody = ODE_dBodyCreate()
	G\ObjectGeom = ODE_dCreateBox(ODE_Space, G\ObjectScaleX#*2,G\ObjectScaleY#*2,G\ObjectScaleZ#*2, G\ObjectMass#)
	ODE_dGeomSetBody G\ObjectGeom, G\ObjectBody

	G\ObjectRotX#=RotX#
	G\ObjectRotY#=RotY#
	G\ObjectRotZ#=RotZ#
	
	G\ObjectPx#=Px#
	G\ObjectPy#=Py#
	G\ObjectPz#=Pz#

	ODE_dBodySetPosition(G\ObjectBody, G\ObjectPx#,G\ObjectPy#,G\ObjectPz#)
	ODE_dBodySetRotation(G\ObjectBody, G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#)

	G\ObjectMesh = CreateCube()
	RotateEntity G\ObjectMesh,G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#
	PositionEntity G\ObjectMesh,G\ObjectPx#,G\ObjectPy#,G\ObjectPz#
	ScaleEntity G\ObjectMesh,G\ObjectScaleX#,G\ObjectScaleY#,G\ObjectScaleZ#
	EntityColor G\ObjectMesh, Red,Green,Blue

	If View%=0 Then
		HideEntity G\ObjectMesh
	EndIf
	
	If Sound$<>"" Then 
		G\ObjectSound=LoadSound(Sound$)
	Else
		G\ObjectSound=0
	EndIf

	Return G\ObjectBody
End Function

; ----------------------------------------
; Permet de créer une sphere
; ----------------------------------------
Function ODE_CreateSphere(Px#,Py#,Pz#,Scale#,Mass#=1,Sound$="",Red=255,Green=255,Blue=255,View%=1)
	G.ODE_Object = New ODE_Object

	G\ObjectMass#=Mass#

	G\ObjectScaleX#=Scale#
	G\ObjectScaleY#=Scale#
	G\ObjectScaleZ#=Scale#

	G\ObjectBody = ODE_dBodyCreate()
	G\ObjectGeom = ODE_dCreateSphere(ODE_Space,G\ObjectScaleX#, G\ObjectMass#)
	ODE_dGeomSetBody G\ObjectGeom, G\ObjectBody
	
	G\ObjectPx#=Px#
	G\ObjectPy#=Py#
	G\ObjectPz#=Pz#
	
	ODE_dBodySetPosition(G\ObjectBody, G\ObjectPx#,G\ObjectPy#,G\ObjectPz#)

	G\ObjectMesh = CreateSphere()

	PositionEntity G\ObjectMesh,G\ObjectPx#,G\ObjectPy#,G\ObjectPz#
	ScaleEntity G\ObjectMesh,G\ObjectScaleX#,G\ObjectScaleY#,G\ObjectScaleZ#
	EntityColor G\ObjectMesh, Red,Green,Blue

	If View%=0 Then
		HideEntity G\ObjectMesh
	EndIf
	
	If Sound$<>"" Then 
		G\ObjectSound=LoadSound(Sound$)
	Else
		G\ObjectSound=0
	EndIf

	Return G\ObjectBody
End Function

; ----------------------------------------
; Permet de créer un cylindre
; ---------------------------------------
Function ODE_CreateCylinder(Px#,Py#,Pz#,RotX#,RotY#,RotZ#,Radius#,Height#,Mass#=1,Sound$="",Red=255,Green=255,Blue=255,View%=1)
	G.ODE_Object = New ODE_Object

	G\ObjectMass#=Mass#

	G\ObjectScaleX#=Radius#
	G\ObjectScaleY#=Height#
	G\ObjectScaleZ#=Radius#

	G\ObjectBody = ODE_dBodyCreate()
	G\ObjectGeom = ODE_dCreateCCylinder(ODE_Space,G\ObjectScaleX#, G\ObjectScaleY#*2,G\ObjectMass#)
	ODE_dGeomSetBody G\ObjectGeom, G\ObjectBody
	
	G\ObjectPx#=Px#
	G\ObjectPy#=Py#
	G\ObjectPz#=Pz#

	G\ObjectRotX#=RotX#
	G\ObjectRotY#=RotY#
	G\ObjectRotZ#=RotZ#

	ODE_dBodySetPosition(G\ObjectBody, G\ObjectPx#,G\ObjectPy#,G\ObjectPz#)
	ODE_dBodySetRotation(G\ObjectBody, G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#)
	
	G\ObjectMesh = CreatePivot()
	G\ObjectFake=CreateCylinder(8,1,G\ObjectMesh)
	RotateEntity G\ObjectFake, 90, 0, 0
	
	PositionEntity G\ObjectMesh,G\ObjectPx#,G\ObjectPy#,G\ObjectPz#
	ScaleEntity G\ObjectFake,G\ObjectScaleX#,G\ObjectScaleY#,G\ObjectScaleZ#
	RotateEntity G\ObjectMesh,G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#
	EntityColor G\ObjectFake, Red,Green,Blue

	If View%=0 Then
		HideEntity G\ObjectMesh
	EndIf
	
	If Sound$<>"" Then 
		G\ObjectSound=LoadSound(Sound$)
	Else
		G\ObjectSound=0
	EndIf

	Return G\ObjectBody
End Function

; ------------------------------------------------
; On update la physique des objets
; ------------------------------------------------
Function ODE_UpdatePhysic(Time#=0.1)
	For G.ODE_Object = Each ODE_Object
		; --------------------------------------------------------------
		; On update la position et rotation des objets
		; --------------------------------------------------------------
		PositionEntity G\ObjectMesh, ODE_dGeomGetPositionX(G\ObjectGeom), ODE_dGeomGetPositionY(G\ObjectGeom), ODE_dGeomGetPositionZ(G\ObjectGeom)
		RotateEntity G\ObjectMesh, ODE_dGeomGetPitch(G\ObjectGeom), ODE_dGeomGetYaw(G\ObjectGeom), ODE_dGeomGetRoll(G\ObjectGeom), 1

		; ------------------------------------------------------------
		; Gestion du son en fonction des collisions
		; ------------------------------------------------------------
		If G\ObjectSound<>0
			ODE_CollisionCount% = ODE_dBodyGetCollisionsCount%(G\ObjectBody)

			For i = 0 To ODE_CollisionCount% - 1
				ODE_CollisionDepth# =ODE_dBodyGetCollisionDepth(G\ObjectBody, i)
				DebugLog ODE_CollisionDepth#
					
				If ODE_CollisionDepth# >=0.05 And ODE_CollisionDepth# <=0.3
					If ChannelPlaying(G\ObjectChannel)=0
						G\ObjectChannel = PlaySound(G\ObjectSound)
						ChannelVolume G\ObjectChannel, ODE_CollisionDepth * 3
					EndIf
				EndIf
			Next
		EndIf
	Next
End Function









Global TOKP_taillex
Global TOKP_tailley
Global TOKP_taillez

Global TOKP_centrex#
Global TOKP_centrey#
Global TOKP_centrez#


Function ODE_AnimMeshPhysic(Parent%)
 	Children%=CountChildren(Parent%)

	;je scanne que les premiers enfants pour pas créer une box au pivot	

	For Loop = 1 To Children%
		Child%=GetChild (Parent%,Loop)
		ODE_CreateCubeChild(Child%,10,"")
		;ODE_AnimMeshPhysic(Child%)
	Next
End Function


; -------------------------------------------------------------------------
; Permet de créer un cube ODE a partie d'une mesh
; -------------------------------------------------------------------------
Function ODE_CreateCubeChild(Mesh,Mass#=1,Sound$="")
	G.ODE_Object = New ODE_Object
	
	G\ObjectMass#=Mass#
	G\ObjectMesh = Mesh
	
	;If mesh<>0 Then EntityParent Mesh,0;PivotDeMeurde
	G\ObjectRotX#=EntityPitch(Mesh,True)
	G\ObjectRotY#=EntityYaw(Mesh,True)
	G\ObjectRotZ#=EntityRoll(Mesh,True)



	;RotateEntity G\ObjectMesh,G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#
	;PositionEntity G\ObjectMesh,G\ObjectPx#,G\ObjectPy#,G\ObjectPz#

	;tu gères pas le scale de 3dsmax là, ca va te faire des irrégularités
	TOKP_CalculeTailleCentreEntity(G\ObjectMesh)

	G\ObjectPx#=EntityX(mesh)
	G\ObjectPy#=EntityY(mesh)
	G\ObjectPz#=EntityZ(mesh)

	
	G\ObjectScaleX#=TOKP_taillex*0.5
	G\ObjectScaleY#=TOKP_tailley*0.5
	G\ObjectScaleZ#=TOKP_taillez*0.5
	
	G\ObjectBody = ODE_dBodyCreate()
	G\ObjectGeom = ODE_dCreateBox(ODE_Space, G\ObjectScaleX#,G\ObjectScaleY#,G\ObjectScaleZ#, G\ObjectMass#)
	
	ODE_dGeomSetBody G\ObjectGeom, G\ObjectBody
	ODE_dBodySetPosition(G\ObjectBody, G\ObjectPx#,G\ObjectPy#,G\ObjectPz#)
	ODE_dBodySetRotation(G\ObjectBody, G\ObjectRotX#,G\ObjectRotY#,G\ObjectRotZ#)

	If Sound$<>"" Then 
		G\ObjectSound=LoadSound(Sound$)
	Else
		G\ObjectSound=0
	EndIf 
End Function

Function TOKP_CalculeTailleCentreEntity(e);
	xmin#=99999999999
	xmax#=-99999999999
	ymin#=99999999999
	ymax#=-99999999999
	zmin#=99999999999
	zmax#=-99999999999
	
	For k=1 To CountSurfaces(e)
		For l=0 To CountVertices(GetSurface(e,k))-1
			If VertexX(GetSurface(e,k),l)<=xmin# Then xmin#=VertexX(GetSurface(e,k),l)
			If VertexX(GetSurface(e,k),l)>=xmax# Then xmax#=VertexX(GetSurface(e,k),l)
			If VertexY(GetSurface(e,k),l)<=ymin# Then ymin#=VertexY(GetSurface(e,k),l)
			If VertexY(GetSurface(e,k),l)>=ymax# Then ymax#=VertexY(GetSurface(e,k),l)
			If VertexZ(GetSurface(e,k),l)<=zmin# Then zmin#=VertexZ(GetSurface(e,k),l)
			If VertexZ(GetSurface(e,k),l)>=zmax# Then zmax#=VertexZ(GetSurface(e,k),l)
		Next
	Next

	TOKP_centrex#=xmin*0.5+xmax*0.5
	TOKP_centrey#=ymin*0.5+ymax*0.5
	TOKP_centrez#=zmin*0.5+zmax*0.5

	;Calcule les valeurs de scale
	x#=EntityPitch(e,True)
	y#=EntityYaw(e,True)
	z#=EntityRoll(e,True)
	
	RotateEntity e,0,0,0,True
	scalex#=GetMatElement(e,0,0)
	scaley#=GetMatElement(e,1,1)
	scalez#=GetMatElement(e,2,2)
	
	RotateEntity e,x,y,z,True

	TOKP_centrex=scalex*TOKP_centrex
	TOKP_centrey=scaley*TOKP_centrey
	TOKP_centrez=scalez*TOKP_centrez

	TOKP_taillex=(xmax-xmin)*scalex
	TOKP_tailley=(ymax-ymin)*scaley
	TOKP_taillez=(zmax-zmin)*scalez
End Function



Example code



; ------------------------
; Freelook cam var
; ------------------------
Global Mouse_X_Speed#
Global Mouse_Y_Speed#
Global Camera_VelX#
Global Camera_VelZ#
Global Camera_Pitch
Global Camera_Yaw

Include "BlitzODE.bb"
Include "Inc_ODEStuff.bb"

;------ Initialize Graphics --------
Graphics3D 800, 600,16,2
SetBuffer BackBuffer()	

lh = CreateLight(2)
PositionEntity lh,50,50,50
LightRange lh,100
LightColor lh,255,200,150

plane = CreatePlane()
;mirror = CreateMirror(plane)
EntityColor plane, 0, 0, 150
;EntityAlpha plane, .8
PositionEntity plane,0,-0.3,0

SeedRnd MilliSecs()
;--------- Initialize ODE ----------
ODE_InitWorld()


;------- Create siple cube ---------
;For i=0 To 5
;Mass#=30
;Area=30
;ODE_CreateCube(Rnd(-5,5),i,Rnd(-5,5),0,0,0,1,1,1,Mass#,"Bounce.wav",Rnd(255),Rnd(255),Rnd(255))
;ODE_CreateSphere(Rnd(-5,5),i,Rnd(-5,5),1,Mass#,"Bounce.wav",Rnd(255),Rnd(255),Rnd(255))
;ODE_CreateCylinder(Rnd(-Area,Area),5,Rnd(-Area,Area),90,0,0,1,3,Mass#,"chimes.wav",Rnd(255),Rnd(255),Rnd(255))
;
;ODE_CreateCubeMesh("teapot.b3d",Rnd(-20,20),i,Rnd(-20,20),0,0,0,Mass#,"Bounce.wav")
;ODE_CreateSphereMesh("chamber.b3d",Rnd(-20,20),i,Rnd(-20,20),0,0,0,Mass#,"Bounce.wav")
;Next

mesh=LoadAnimMesh("002.b3d")
PositionEntity mesh,0,10,0
ODE_AnimMeshPhysic(mesh)


;-----------------------------------

ODE_UpdatePhysic()

cam = CreateCamera()
PositionEntity cam, 0, 10, -25
cambody = ODE_CreateSphere(0, 10, -25,6,0,"",0,0,0,0)

;-----------------------------------

gameFPS = 50.0
framePeriod = 1000 / gameFPS
frameTime = MilliSecs () - framePeriod

MoveMouse GraphicsWidth()/2,GraphicsHeight()/2

While Not KeyHit(1)
	Repeat
		frameElapsed = MilliSecs () - frameTime
	Until frameElapsed
	
	frameTicks = frameElapsed / framePeriod
	frameTween# = Float(frameElapsed Mod framePeriod) / Float(framePeriod)
	For frameLimit = 1 To frameTicks
		If frameLimit = frameTicks Then CaptureWorld
		frameTime = frameTime + framePeriod

            ;------------ Update physics world ----------		

		
	ODE_dWorldQuickStep 0.1
            ;--------------------------------------------


	Next

		If KeyHit(57)
			For G.ODE_Object = Each ODE_Object
				ODE_dBodyEnable G\ObjectBody
				ODE_dBodyAddForce G\ObjectBody, 0, Rnd(20, 50), 0
				ODE_dBodyAddTorque G\ObjectBody, Rnd(-30, 10), Rnd(-10, 10), Rnd(-10, 10)
			Next
		EndIf

		
		
	;---- Set geometry position and rotation ----

	ODE_UpdatePhysic()

Proc_Freelook(Cam,1.05,0.05)
ODE_dBodySetPosition(cambody,EntityX(Cam),EntityY(Cam), EntityZ(Cam))

	;--------------------------------------------

	RenderWorld frameTween#
	
	Flip 0
Wend

ODE_dCloseODE()
End

Function Proc_Freelook(CamEntity,Velocity#,Speed#)
 Mouse_X_Speed#=MouseXSpeed()*0.5
 Mouse_Y_Speed#=MouseYSpeed()*0.5

 MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
 Camera_Pitch=Camera_Pitch+Mouse_Y_Speed#
 Camera_Yaw=Camera_Yaw+Mouse_X_Speed#


 RotateEntity CamEntity,Camera_Pitch,-Camera_Yaw,0

 If KeyDown(203) Then
   Camera_VelX=Camera_VelX-Speed#
 ElseIf  KeyDown(205)
   Camera_VelX=Camera_VelX+Speed#
 EndIf
 If KeyDown(208) Then
   Camera_VelZ=Camera_VelZ-Speed#
 ElseIf  KeyDown(200)
   Camera_VelZ=Camera_VelZ+Speed#
 EndIf
 
 Camera_VelX=Camera_VelX/velocity#
 Camera_VelZ=Camera_VelZ/velocity#
 MoveEntity CamEntity,Camera_VelX,0,Camera_VelZ

 If KeyDown(200) Then
   MoveEntity CamEntity,0,0,Speed#
 EndIf

 If KeyDown(208) Then
   MoveEntity CamEntity,0,0,-Speed#
 EndIf

 If KeyDown(205) Then
   MoveEntity CamEntity,Speed#,0,0
 EndIf

 If KeyDown(203) Then
   MoveEntity CamEntity,-Speed#,0,0
 EndIf
End Function


But my object become "crazy" !!! i think that my code for calculate
mesh child scale is bugged, but i don't find where.

Anybody have an example code for test child mesh scale ?