JV-ODE Physics Thread 3

Blitz3D Forums/Blitz3D Userlibs/JV-ODE Physics Thread 3

I think I found it!
I don't necessarly agree with shifty's numbers but I think he's onto something.
8)

After playing with shifty code I believe JV/ODE function: dMassSetSphereTotal is accidentially calling dMassSetSphere but should be calling ode function dMassSetSphereTotal. The following code would seem to show this.

* No fool like and old fool, so I hope I'm right ! *

Include "JV-ODE.bb"

Graphics3D 800,600,0,2

Global WorldERP#=0.8			; ### World Error Correction
Global WorldFriction#=0			; ### World Friction

Global SpaceInfo=0

Global Pointer
Global PlaneGeom

Type ODEGeom
	Field body
	Field geom
	Field mesh
End Type

; ###################################################################################################

; ### Setup ODE

Global World=dWorldCreate()
Global Space=dHashSpaceCreate(0)

Global GroundSpace=dHashSpaceCreate(Space)
Global ObjSpace=dHashSpaceCreate(Space)
Global ContactGroup=dJointGroupCreate(0)

dWorldSetAutoDisableFlag(World,1)
dWorldSetGravity(World,0,-0.98,0)
dWorldSetERP(World,WorldERP)

dContactSetMode(dContactSlip1)
dContactSetMu(WorldFriction)

; ### Create light
Light=CreateLight()
RotateEntity Light,45,-90,0
LightColor Light,255,255,255
AmbientLight 130,130,130

; ### Create camera
Camera=CreateCamera()
PositionEntity Camera,-10,10,-10
RotateEntity Camera,20,0,0
CameraClsColor Camera,0,0,0
CameraRange Camera,1,1000

; ### Create plane
PlaneGeom=dCreatePlane(GroundSpace,0,1,0,0)
Plane=CreatePlane()
EntityAlpha Plane,0.8
PlaneTexture=CreateTexture(128,128,9)
ClsColor 0,200,80
Cls
Color 255,255,255
Rect 0,0,64,64,1
Rect 64,64,64,64,1
CopyRect 0,0,128,128,0,0,BackBuffer(),TextureBuffer(PlaneTexture)
ScaleTexture PlaneTexture,20,20
EntityTexture Plane,PlaneTexture,0,0

; ### Create some objects
	GRAVITY_ENABLED=True
	SIZE#=2.0
	CYLINDER_RADIUS#=1.7319
	DENSITY#=1.0
	SPHERE_VOL#=4.0 / 3.0 * Pi * SIZE# * SIZE# * SIZE#
	OBJECT_MASS#=4.0 / 3.0 * Pi * SIZE# * SIZE# * SIZE# * DENSITY#
	FRICTION#=100.0
	gamma#=0.5

; Ode1 = Sphere with density based mass
ode1.ODEGeom=New ODEGeom
	ode1\body=dBodyCreate(World)
	dBodySetRotation(ode1\body,0,0,0)
	dBodySetPosition(ode1\body,-25,10,10)
	ode1\geom=dCreateSphere(Space,SIZE)
	dGeomSetBody(ode1\geom,ode1\body)
	dGeomContactSetMu(ode1\geom,0.0)
	mass=dMassCreate()

		;dMassSetSphereTotal(mass,OBJECT_MASS,SIZE)
		dMassSetSphere(mass,DENSITY,SIZE)
		
		dBodySetMass(ode1\body,mass)
		dMassDestroy(mass)
		
	ode1\mesh=CreateSphere()
	ScaleMesh ode1\mesh,SIZE,SIZE,SIZE

; Ode2 = Sphere with total mass
; Mass of sphere = 4/3 x Pi x r^3 x density
ode2.ODEGeom=New ODEGeom
	ode2\body=dBodyCreate(World)
	dBodySetRotation(ode2\body,0,0,0)
	dBodySetPosition(ode2\body,-20,10,10)
	ode2\geom=dCreateSphere(Space,SIZE)
	dGeomSetBody(ode2\geom,ode2\body)
	dGeomContactSetMu(ode2\geom,0.0)
	mass=dMassCreate()
	
		;dMassSetSphere(mass,DENSITY,SIZE)
		;dMassSetSphereTotal(mass,OBJECT_MASS#,SIZE#)
		dMassSetSphereTotal(mass,1,2) ;33.52, 2
	
		dBodySetMass(ode2\body,mass)
		dMassDestroy(mass)
		
	ode2\mesh=CreateSphere()
	ScaleMesh ode2\mesh,SIZE,SIZE,SIZE

; Change Cube size to match Sphere's volume
SIZE#=3.223983

; Ode3 = Cube with density based mass
ode3.ODEGeom=New ODEGeom
	ode3\body=dBodyCreate(World)
	dBodySetRotation(ode3\body,0,0,0)
	dBodySetPosition(ode3\body,-15,10,10)
	ode3\geom=dCreateBox(Space,SIZE,SIZE,SIZE)
	dGeomSetBody(ode3\geom,ode3\body)
	dGeomContactSetMu(ode3\geom,0.0)
	mass=dMassCreate()
	
		;dMassSetBoxTotal(mass,CUBE_MASS,SIZE,SIZE,SIZE)
		dMassSetBox(mass,DENSITY#,SIZE#,SIZE#,SIZE#)
		
		dBodySetMass(ode3\body,mass)
		dMassDestroy(mass)
	ode3\mesh=CreateCube()
	ScaleMesh ode3\mesh,SIZE/2,SIZE/2,SIZE/2

; Ode4 = Cube with total mass
; Mass = Density x Volume
; mass=x*y*z*density
;CUBE_MASS#=SIZE*SIZE*SIZE*DENSITY
ode4.ODEGeom=New ODEGeom
	ode4\body=dBodyCreate(World)
	dBodySetRotation(ode4\body,0,0,0)
	dBodySetPosition(ode4\body,-10,10,10)
	ode4\geom=dCreateBox(Space,SIZE,SIZE,SIZE)
	dGeomSetBody(ode4\geom,ode4\body)
	dGeomContactSetMu(ode4\geom,0.0)
	mass=dMassCreate()
		;dMassSetBox(mass,DENSITY,SIZE,SIZE,SIZE)
		dMassSetBoxTotal(mass,OBJECT_MASS#,SIZE#,SIZE#,SIZE#)
		dBodySetMass(ode4\body,mass)
		dMassDestroy(mass)
	ode4\mesh=CreateCube()
	ScaleMesh ode4\mesh,SIZE/2,SIZE/2,SIZE/2

; Change Cylinder size to match Sphere's volume
SIZE=2
ode5.ODEGeom=New ODEGeom
	ode5\body=dBodyCreate(World)
	dBodySetRotation(ode5\body,90,0,0)
	dBodySetPosition(ode5\body,-5,10,10)
	ode5\geom=dCreateCylinder(Space,CYLINDER_RADIUS,SIZE)
	dGeomSetBody(ode5\geom,ode5\body)
	dGeomContactSetMu(ode5\geom,0.0)
	mass=dMassCreate()
		dMassSetCappedCylinder(mass,DENSITY,2,CYLINDER_RADIUS,SIZE)
		dMassSetCappedCylinderTotal(mass,OBJECT_MASS,2,CYLINDER_RADIUS,SIZE)
		dBodySetMass(ode5\body,mass)
		dMassDestroy(mass)ode5\mesh=CreateCylinder(8)
	ScaleMesh ode5\mesh,CYLINDER_RADIUS/2,SIZE/2,CYLINDER_RADIUS/2

ode6.ODEGeom=New ODEGeom
	ode6\body=dBodyCreate(World)
	dBodySetRotation(ode6\body,90,0,0)
	dBodySetPosition(ode6\body,0,10,10)
	ode6\geom=dCreateCylinder(Space,CYLINDER_RADIUS,SIZE)
	dGeomSetBody(ode6\geom,ode6\body)
	dGeomContactSetMu(ode6\geom,0.0)
	mass=dMassCreate()
		dMassSetCappedCylinderTotal(mass,OBJECT_MASS,2,CYLINDER_RADIUS,SIZE)
		dMassSetCappedCylinder(mass,DENSITY,2,CYLINDER_RADIUS,SIZE)
		dBodySetMass(ode6\body,mass)
		dMassDestroy(mass)ode6\mesh=CreateCylinder(8)
	ScaleMesh ode6\mesh,CYLINDER_RADIUS/2,SIZE/2,CYLINDER_RADIUS/2

While Not KeyHit(1)
	If KeyHit(210)	; Hit insert key
		dBodyEnable (ode1\body)
		dBodyEnable (ode2\body)
		dBodyEnable (ode3\body)
		dBodyEnable (ode4\body)
		dBodyEnable (ode5\body)
		dBodyEnable (ode6\body)
		dBodyAddForce(ode1\body,0,0,100)
		dBodyAddForce(ode2\body,0,0,100)
		dBodyAddForce(ode3\body,0,0,100)
		dBodyAddForce(ode4\body,0,0,100)
		dBodyAddForce(ode5\body,0,0,100)
		dBodyAddForce(ode6\body,0,0,100)
	EndIf
	
	For ode.ODEGeom=Each ODEGeom
		RotateEntity ode\mesh,dGeomGetPitch#(ode\geom),dGeomGetYaw#(ode\geom),dGeomGetRoll#(ode\geom)
		PositionEntity ode\mesh,dGeomGetPositionX#(ode\geom),dGeomGetPositionY#(ode\geom),dGeomGetPositionZ#(ode\geom)
	Next

	dSpaceCollide(Space,World,ContactGroup)
	dWorldQuickStep(World,0.1)
	dJointGroupEmpty(ContactGroup)

	UpdateWorld
	RenderWorld
	
	y=15
	Text 20,y,OBJECT_MASS : y=y+15

	Flip

Wend

dJointGroupDestroy(ContactGroup)
dSpaceDestroy(Space)
dWorldDestroy(World)
dCloseODE()

End