JV-ODE Physics Thread 3

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

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Hey VIP3R. Big problematic problem I have encountered, which makes a bit of a mockery of all my friction investigations to date! I've been applying forces to spheres and boxes and getting different results. I've looked more closely and found the dMassSetSphere() and dMassSetSphereTotal() give different results, while setting a sphere's mass seems to set it differently to a box's mass. Look at the following...
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
	DENSITY#=1.0
	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()
		dMassSetSphere(mass,DENSITY,SIZE)
		dBodySetMass(ode1\body,mass)
		dMassDestroy(mass)
	ode1\mesh=CreateSphere()
	ScaleMesh ode1\mesh,SIZE,SIZE,SIZE
	RotateMesh ode1\mesh,0,0,0
	PositionMesh ode1\mesh,0,0,0
	EntityColor ode1\mesh,255,255,255
	EntityAlpha ode1\mesh,1
	dBodySetGravityMode(ode1\body,GRAVITY_ENABLED)

; Ode2 = Sphere with total mass
; Mass of sphere = 3/4 Pi.r^3
SPHERE_MASS#=(3.141*(SIZE*SIZE*SIZE)*3)/4
ode2.ODEGeom=New ODEGeom
	ode2\body=dBodyCreate(World)
	dBodySetRotation(ode2\body,0,0,0)
	dBodySetPosition(ode2\body,-15,10,10)
	ode2\geom=dCreateSphere(Space,SIZE)
	dGeomSetBody(ode2\geom,ode2\body)
	dGeomContactSetMu(ode2\geom,0.0)
	mass=dMassCreate()
		dMassSetSphereTotal(mass,SPHERE_MASS,SIZE)
		dBodySetMass(ode2\body,mass)
		dMassDestroy(mass)
	ode2\mesh=CreateSphere()
	ScaleMesh ode2\mesh,SIZE,SIZE,SIZE
	RotateMesh ode2\mesh,0,0,0
	PositionMesh ode2\mesh,0,0,0
	EntityColor ode2\mesh,255,255,255
	EntityAlpha ode2\mesh,1
	dBodySetGravityMode(ode2\body,GRAVITY_ENABLED)

; Change Cube size to match Sphere's volume
SIZE=2.661175
; Ode3 = Cube with density based mass
ode3.ODEGeom=New ODEGeom
	ode3\body=dBodyCreate(World)
	dBodySetRotation(ode3\body,0,0,0)
	dBodySetPosition(ode3\body,-5,10,10)
	ode3\geom=dCreateBox(Space,SIZE,SIZE,SIZE)
	dGeomSetBody(ode3\geom,ode3\body)
	dGeomContactSetMu(ode3\geom,0.0)
	mass=dMassCreate()
		dMassSetBox(mass,DENSITY,SIZE,SIZE,SIZE)
		dBodySetMass(ode3\body,mass)
		dMassDestroy(mass)
	ode3\mesh=CreateCube()
	ScaleMesh ode3\mesh,SIZE/2,SIZE/2,SIZE/2
	RotateMesh ode3\mesh,0,0,0
	PositionMesh ode3\mesh,0,0,0
	EntityColor ode3\mesh,255,255,255
	EntityAlpha ode3\mesh,1
	dBodySetGravityMode(ode3\body,GRAVITY_ENABLED)

; Ode4 = Cube with total mass
; 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,5,10,10)
	ode4\geom=dCreateBox(Space,SIZE,SIZE,SIZE)
	dGeomSetBody(ode4\geom,ode4\body)
	dGeomContactSetMu(ode4\geom,0.0)
	mass=dMassCreate()
		dMassSetBoxTotal(mass,CUBE_MASS,SIZE,SIZE,SIZE)
		dBodySetMass(ode4\body,mass)
		dMassDestroy(mass)
	ode4\mesh=CreateCube()
	ScaleMesh ode4\mesh,SIZE/2,SIZE/2,SIZE/2
	RotateMesh ode4\mesh,0,0,0
	PositionMesh ode4\mesh,0,0,0
	EntityColor ode4\mesh,255,255,255
	EntityAlpha ode4\mesh,1
	dBodySetGravityMode(ode4\body,GRAVITY_ENABLED)
	
While Not KeyHit(1)
	If KeyHit(210)	; Hit insert key
		dBodyEnable (ode1\body)
		dBodyEnable (ode2\body)
		dBodyEnable (ode3\body)
		dBodyEnable (ode4\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)
	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,SPHERE_MASS : y=y+15
	Text 20,y,CUBE_MASS : y=y+15

	Flip

Wend

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

End

Press the insert key to apply a force of (0,0,100) to all four objects. There's no friction and they're all the same volume and the same mass in theory, so they should all move at the same speed.

Taking the boxes, they both work. They travel at the same speed though one has mass set with Total and the other by density. Looking at the first sphere, who's mass is set by density, it moves slower than the cubes. Thus it appears heavier. Looking at the second sphere who's mass is set by the Total method, it hardly moves at all. Assuming my maths isn't up the swanny and I'm calculating the total mass right

; Mass of sphere = 3/4 Pi.r^3
SPHERE_MASS#=(3.141*(SIZE*SIZE*SIZE)*3)/4

It should act exactly the same way as the first sphere. And given there's no friction, and all objects are supposed to have the same mass, and they all receive the same force, they should all move at a uniform speed, which means the sphere's should move the same as the cubes.

To me it looks like the sphere mass calculations are wrong. The SphereMassTotal set's the sphere's mass about 30x greater than it should be.