Try these physics.

Blitz3D Forums/Blitz3D Programming/Try these physics.

This is a wonderful collision and velocity routine that is easy to plug into an existing program. All you do is create a physics type for your entity, then call UpdatePhysics every loop instead of UpdateWorld.

The collision uses Blitz's collision, but manages to overcome a few of the weaknesses. Sliding, bouncing collisions will occur, depending on the elasticity you give the physics type.

This should be very useful as a base for more advanced physics.

Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam=CreateCamera()
MoveEntity cam,0,15,-20
TurnEntity cam,35,0,0

g=CreateCube()
ScaleMesh g,10,10,10
FlipMesh g

EntityType g,2

r=2
m=CreateSphere()
EntityShininess m,1
EntityType m,1
EntityRadius m,r
ScaleEntity m,r,r,r
EntityColor m,255,0,0

Collisions 1,2,2,2
Collisions 1,1,2,2

RotateEntity CreateLight(),25,45,0

Type physics
Field mesh
Field velocity#[5]
Field position#[5]
Field elasticity#
End Type

balls=3

For n=1 To balls
	ph.physics=New physics
	ph\mesh=CopyEntity(m)
	ph\velocity[0]=Rnd(-.5,.5)
	ph\velocity[1]=Rnd(-1,1)
	ph\velocity[2]=Rnd(-.5,.5)	
	;PositionEntity ph\mesh,Rnd(-8,8),8,Rnd(-8,8)
	ResetEntity ph\mesh
	ph\elasticity#=0.95
	EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
	Next

HideEntity m

period=1000/60
time=MilliSecs()-period

While Not KeyHit(1)
	
	Repeat
		elapsed=MilliSecs()-time
		Until elapsed
	
	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)
	
	For k=1 To ticks
		time=time+period
		
		If KeyHit(28)
			ph.physics=New physics
			ph\mesh=CopyEntity(m)
			ph\velocity[0]=Rnd(-.5,.5)
			ph\velocity[1]=Rnd(-1,1)
			ph\velocity[2]=Rnd(-.5,.5)	
			;PositionEntity ph\mesh,Rnd(-8,8),8,Rnd(-8,8)
			ScaleEntity ph\mesh,r,r,r
			EntityRadius ph\mesh,r
			ResetEntity ph\mesh
			ph\elasticity#=0.95
			EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
			balls=balls+1
			EndIf
			
		If KeyHit(57)
			For ph.physics=Each physics
				ph\velocity[0]=Rnd(-.5,.5)
				ph\velocity[1]=Rnd(-2,2)
				ph\velocity[2]=Rnd(-.5,.5)
				Next
			EndIf
		
		UpdatePhysics
		
		Next
		
	RenderWorld
	Text 0,0,fps()
	Text 0,20,"Press space to reset balls."
	Text 0,40,"Press enter to add a ball."
	Text 0,60,balls+" balls exist."
	Flip
	
	Wend
	
Function UpdatePhysics()

friction#=0.99;sliding friction
staticfriction#=0.0001;minimum velocity before an objects starts sticking

For ph.physics=Each physics
		
	ph\position[0]=EntityX(ph\mesh,1)
	ph\position[1]=EntityY(ph\mesh,1)
	ph\position[2]=EntityZ(ph\mesh,1)
	
	;gravity	
	ph\velocity[1]=ph\velocity[1]-0.03
	
	;carry out velocity
	TranslateEntity ph\mesh,ph\velocity[0],ph\velocity[1],ph\velocity[2],1	

	ph\position[3]=EntityX(ph\mesh,1)
	ph\position[4]=EntityY(ph\mesh,1)
	ph\position[5]=EntityZ(ph\mesh,1)

	Next

UpdateWorld

;correct velocity
For ph.physics=Each physics

	ax#=(EntityX(ph\mesh,1)-ph\position[3])
	ay#=(EntityY(ph\mesh,1)-ph\position[4])
	az#=(EntityZ(ph\mesh,1)-ph\position[5])
	
	PositionEntity ph\mesh,ph\position[3],ph\position[4],ph\position[5],1

	ph\velocity[0]=(EntityX(ph\mesh,1)-ph\position[0]+ax*ph\elasticity)
	ph\velocity[1]=(EntityY(ph\mesh,1)-ph\position[1]+ay*ph\elasticity)
	ph\velocity[2]=(EntityZ(ph\mesh,1)-ph\position[2]+az*ph\elasticity)

	TranslateEntity ph\mesh,ax*(1.0-ph\elasticity),ay*(1.0-ph\elasticity),az*(1.0-ph\elasticity)
				
	Next

;transfer inertia
For ph.physics=Each physics
	For c=1 To CountCollisions(ph\mesh)
		If GetEntityType(CollisionEntity(ph\mesh,c))=1

			;lose some energy as heat for each collision
			ph\velocity[0]=ph\velocity[0]*.98
			ph\velocity[1]=ph\velocity[1]*.98
			ph\velocity[2]=ph\velocity[2]*.98

			;hmmm...should the collision normals be absolute value or not?
			nx#=Abs(CollisionNX(ph\mesh,c))
			ny#=Abs(CollisionNY(ph\mesh,c))
			nz#=Abs(CollisionNZ(ph\mesh,c))
			ph2.physics=findphysics(CollisionEntity(ph\mesh,c))
			ph2\velocity[0]=ph2\velocity[0]+(nx)*ph\velocity[0]/2.0
			ph2\velocity[1]=ph2\velocity[1]+(ny)*ph\velocity[1]/2.0
			ph2\velocity[2]=ph2\velocity[2]+(nz)*ph\velocity[2]/2.0
			ph\velocity[0]=ph\velocity[0]-(nx)*ph\velocity[0]/2.0
			ph\velocity[1]=ph\velocity[1]-(ny)*ph\velocity[1]/2.0
			ph\velocity[2]=ph\velocity[2]-(nz)*ph\velocity[2]/2.0
			EndIf
		Next
	Next	

;add friction
For ph.physics=Each physics
	If EntityCollided(ph\mesh,2)
		;sliding friction
		ph\velocity[0]=ph\velocity[0]*friction
		ph\velocity[1]=ph\velocity[1]*friction
		ph\velocity[2]=ph\velocity[2]*friction
		;static friction
		If Abs(ph\velocity[0])<staticfriction# ph\velocity[0]=0.0
		If Abs(ph\velocity[1])<staticfriction# ph\velocity[1]=0.0
		If Abs(ph\velocity[2])<staticfriction# ph\velocity[2]=0.0
		EndIf
	Next

End Function

Function FindPhysics.physics(e)
For ph.physics=Each physics
	If ph\mesh=e Return ph
	Next
Return Null
End Function

Global FPS_fpstime

Function FPS()
oldtime=FPS_fpstime
FPS_fpstime=MilliSecs()
elapsed=FPS_fpstime-oldtime
If Not elapsed elapsed=1
FPS_fps=1000/elapsed
Return FPS_FPS
End Function


Interesting! Nice work.

I had the same problem with my phyics routine and what I ended up doing was stuffing the handle of the type into the name of the mesh.

Function FindPhysics.physics(e)
For ph.physics=Each physics
	If ph\mesh=e Return ph
	Next
Return Null
End Function


   NameEntity someMesh, str(handle(SomeType))


then I retrieve it by
 object.SomeType EntityName(someMesh)


Handle and Object are unsupported but it does save the search.

I also added an active flag so that object that were resting on the floor and had no velocity would not need to be updated each tic.

I used my code to add pushable object to a 3d platform game but still have issues with the player being able to sometime push his way into objects. It works correct almost 99% percent of the time but it's still not acceptable. I may try to drop in your routines and see what I can do.

I have used names before to attach properties, but I suspect that converting a string to a number would be slow.

I updated the program. This is MUCH BETTER. I can now handle 200 balls. The collisions are perfect, and it is written in such a way that adding inertia and mass would be easy. As of now, all balls just have the same mass.

Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam=CreateCamera()
;MoveEntity cam,0,-8,-20
MoveEntity cam,0,15,-20
TurnEntity cam,35,0,0

g=CreateCube()
ScaleMesh g,10,10,10
FlipMesh g
EntityType g,2

r=1
m=CreateSphere()
EntityShininess m,1
EntityType m,1
EntityRadius m,r
ScaleEntity m,r,r,r
EntityColor m,255,0,0

Collisions 1,2,2,2
Collisions 1,1,1,2

RotateEntity CreateLight(),25,45,0

Global gravity=True

Type physics
Field mesh
Field velocity#[5]
Field elasticity#
Field mass#
End Type

balls=5
e#=0.9

For n=1 To balls
	ph.physics=New physics
	ph\mesh=CopyEntity(m)
	ph\velocity[0]=Rnd(-.5,.5)
	ph\velocity[1]=Rnd(-1,1)
	ph\velocity[2]=Rnd(-.5,.5)	
	PositionEntity ph\mesh,Rnd(-8,8),-8,Rnd(-8,8)
	ResetEntity ph\mesh
	ph\elasticity#=e#
	EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
	Next

HideEntity m

period=1000/60
time=MilliSecs()-period

While Not KeyHit(1)
	
	Repeat
		elapsed=MilliSecs()-time
		Until elapsed
	
	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)
	
	For k=1 To ticks
		time=time+period
		
		If KeyDown(28)
			ph.physics=New physics
			ph\mesh=CopyEntity(m)
			ph\velocity[0]=Rnd(-.5,.5)
			ph\velocity[1]=Rnd(-1,1)
			ph\velocity[2]=Rnd(-.5,.5)	
			ScaleEntity ph\mesh,r,r,r
			EntityRadius ph\mesh,r
			ResetEntity ph\mesh
			ph\elasticity#=e
			EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
			balls=balls+1
			EndIf
			
		If KeyHit(57)
			For ph.physics=Each physics
				PositionEntity ph\mesh,Rnd(-8,8),8,Rnd(-8,8)
				ph\velocity[0]=Rnd(-.5,.5)
				ph\velocity[1]=Rnd(-2,2)
				ph\velocity[2]=Rnd(-.5,.5)
				Next
			EndIf
		
		If KeyHit(34) gravity=1-gravity
		
		UpdatePhysics
		
		Next
		
	RenderWorld
	Text 0,0,fps()
	Text 0,20,"Press space to reset balls."
	Text 0,40,"Press enter to add more balls."
	Text 0,60,"Press g to toggle gravity."
	Text 0,80,balls+" balls exist."
	Flip
	
	Wend
	
Function UpdatePhysics()

friction#=0.99;sliding friction
staticfriction#=0.0001;static friction = minimum velocity before an objects starts sticking

For ph.physics=Each physics
	;gravity	
	If gravity ph\velocity[1]=ph\velocity[1]-0.03
	;carry out velocity
	TranslateEntity ph\mesh,ph\velocity[0],ph\velocity[1],ph\velocity[2],1	
	Next

UpdateWorld

;transfer inertia
For ph.physics=Each physics
	
	vx#=ph\velocity[0]
	vy#=ph\velocity[1]
	vz#=ph\velocity[2]
	
	For c=1 To CountCollisions(ph\mesh)
	
		dx#=ph\velocity[0]*Abs(CollisionNX(ph\mesh,c))
		dy#=ph\velocity[1]*Abs(CollisionNY(ph\mesh,c))
		dz#=ph\velocity[2]*Abs(CollisionNZ(ph\mesh,c))
	
		If GetEntityType(CollisionEntity(ph\mesh,c))=2
			ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))-dx*ph\elasticity
			ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))-dy*ph\elasticity
			ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))-dz*ph\elasticity
			EndIf
				
		If GetEntityType(CollisionEntity(ph\mesh,c))=1
		
			ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))
			ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))
			ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))
	
			ph2.physics=findphysics(CollisionEntity(ph\mesh,c))
			ph2\velocity[0]=ph2\velocity[0]+dx
			ph2\velocity[1]=ph2\velocity[1]+dy
			ph2\velocity[2]=ph2\velocity[2]+dz

			EndIf
		
		Next
	Next	

;add friction
For ph.physics=Each physics
	If EntityCollided(ph\mesh,2)
		;sliding friction
		ph\velocity[0]=ph\velocity[0]*friction
		ph\velocity[1]=ph\velocity[1]*friction
		ph\velocity[2]=ph\velocity[2]*friction
		;static friction
		If Abs(ph\velocity[0])<staticfriction# ph\velocity[0]=0.0
		If Abs(ph\velocity[1])<staticfriction# ph\velocity[1]=0.0
		If Abs(ph\velocity[2])<staticfriction# ph\velocity[2]=0.0
		EndIf
	Next

End Function

Function FindPhysics.physics(e)
For ph.physics=Each physics
	If ph\mesh=e Return ph
	Next
Return Null
End Function

Global FPS_fpstime

Function FPS()
oldtime=FPS_fpstime
FPS_fpstime=MilliSecs()
elapsed=FPS_fpstime-oldtime
If Not elapsed elapsed=1
FPS_fps=1000/elapsed
Return FPS_FPS
End Function


Without gravity I can have over 300 balls without the fps dropping at all..

Amd XP 1800+, gf4-4200

Impressive! :)

I stuffed the handle to the type into the name and I don't see the speed increase I expected but I don't have a profiler handy. Oh well, interesting stuff all the same. Thanks for sharing. Love to see inertia and mass!

Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam=CreateCamera()
;MoveEntity cam,0,-8,-20
MoveEntity cam,0,15,-20
TurnEntity cam,35,0,0

g=CreateCube()
ScaleMesh g,10,10,10
FlipMesh g
EntityType g,2

r=1
m=CreateSphere()
EntityShininess m,1
EntityType m,1
EntityRadius m,r
ScaleEntity m,r,r,r
EntityColor m,255,0,0

Collisions 1,2,2,2
Collisions 1,1,1,2

RotateEntity CreateLight(),25,45,0

Global gravity=True

Type physics
Field mesh
Field velocity#[5]
Field elasticity#
Field mass#
End Type

balls=100
e#=0.9

For n=1 To balls
	ph.physics=New physics
	ph\mesh=CopyEntity(m)
	ph\velocity[0]=Rnd(-.5,.5)
	ph\velocity[1]=Rnd(-1,1)
	ph\velocity[2]=Rnd(-.5,.5)	
	PositionEntity ph\mesh,Rnd(-8,8),-8,Rnd(-8,8)
	ResetEntity ph\mesh
	ph\elasticity#=e#
	EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
	NameEntity ph\mesh, Str(Handle(ph))
	Next

HideEntity m

period=1000/60
time=MilliSecs()-period

While Not KeyHit(1)
	
	Repeat
		elapsed=MilliSecs()-time
		Until elapsed
	
	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)
	
	For k=1 To ticks
		time=time+period
		
		If KeyDown(28)
			ph.physics=New physics
			ph\mesh=CopyEntity(m)
			ph\velocity[0]=Rnd(-.5,.5)
			ph\velocity[1]=Rnd(-1,1)
			ph\velocity[2]=Rnd(-.5,.5)	
			ScaleEntity ph\mesh,r,r,r
			EntityRadius ph\mesh,r
			ResetEntity ph\mesh
			ph\elasticity#=e
			EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
			balls=balls+1
			NameEntity ph\mesh, Str(Handle(ph))
			EndIf
			
		If KeyHit(57)
			For ph.physics=Each physics
				PositionEntity ph\mesh,Rnd(-8,8),8,Rnd(-8,8)
				ph\velocity[0]=Rnd(-.5,.5)
				ph\velocity[1]=Rnd(-2,2)
				ph\velocity[2]=Rnd(-.5,.5)
				Next
			EndIf
		
		If KeyHit(34) gravity=1-gravity
		
		UpdatePhysics
		
		Next
		
	RenderWorld
	Text 0,0,fps()
	Text 0,20,"Press space to reset balls."
	Text 0,40,"Press enter to add more balls."
	Text 0,60,"Press g to toggle gravity."
	Text 0,80,balls+" balls exist."
	Flip
	
	Wend
	
Function UpdatePhysics()

friction#=0.99;sliding friction
staticfriction#=0.0001;static friction = minimum velocity before an objects starts sticking

For ph.physics=Each physics
	;gravity	
	If gravity ph\velocity[1]=ph\velocity[1]-0.03
	;carry out velocity
	TranslateEntity ph\mesh,ph\velocity[0],ph\velocity[1],ph\velocity[2],1	
	Next

UpdateWorld

;transfer inertia
For ph.physics=Each physics
	
	vx#=ph\velocity[0]
	vy#=ph\velocity[1]
	vz#=ph\velocity[2]
	
	For c=1 To CountCollisions(ph\mesh)
	
		dx#=ph\velocity[0]*Abs(CollisionNX(ph\mesh,c))
		dy#=ph\velocity[1]*Abs(CollisionNY(ph\mesh,c))
		dz#=ph\velocity[2]*Abs(CollisionNZ(ph\mesh,c))
	
		If GetEntityType(CollisionEntity(ph\mesh,c))=2
			ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))-dx*ph\elasticity
			ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))-dy*ph\elasticity
			ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))-dz*ph\elasticity
			EndIf
				
		If GetEntityType(CollisionEntity(ph\mesh,c))=1
		
			ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))
			ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))
			ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))
	
			ph2.physics=findphysics(CollisionEntity(ph\mesh,c))
			ph2\velocity[0]=ph2\velocity[0]+dx
			ph2\velocity[1]=ph2\velocity[1]+dy
			ph2\velocity[2]=ph2\velocity[2]+dz

			EndIf
		
		Next
	Next	

;add friction
For ph.physics=Each physics
	If EntityCollided(ph\mesh,2)
		;sliding friction
		ph\velocity[0]=ph\velocity[0]*friction
		ph\velocity[1]=ph\velocity[1]*friction
		ph\velocity[2]=ph\velocity[2]*friction
		;static friction
		If Abs(ph\velocity[0])<staticfriction# ph\velocity[0]=0.0
		If Abs(ph\velocity[1])<staticfriction# ph\velocity[1]=0.0
		If Abs(ph\velocity[2])<staticfriction# ph\velocity[2]=0.0
		EndIf
	Next

End Function

Function FindPhysics.physics(e)
;For ph.physics=Each physics
;	If ph\mesh=e Return ph
;	Next
;Return Null
	Return Object.physics EntityName(e)
End Function

Global FPS_fpstime

Function FPS()
oldtime=FPS_fpstime
FPS_fpstime=MilliSecs()
elapsed=FPS_fpstime-oldtime
If Not elapsed elapsed=1
FPS_fps=1000/elapsed
Return FPS_FPS
End Function




What is the advantage of using your FindPhysics() function?

Oh, I guess it could speed things up if you had thousands of a type, but here you don't.

this only seems to work good if the cube is not rotated.

Try this one. If anyone can get the bonds to keep the balls the right distance from each other, please do:

Graphics3D 800,600,16,2
SetBuffer BackBuffer()

cam=CreateCamera()
MoveEntity cam,0,15,-20
TurnEntity cam,35,0,0

g=CreateCube()
ScaleMesh g,10,10,10
FlipMesh g
EntityType g,2
EntityColor g,100,100,100

r=1
m=CreateSphere()
EntityShininess m,1
EntityType m,1
EntityRadius m,r
ScaleEntity m,r,r,r

Collisions 1,2,2,2
Collisions 1,1,1,2
Collisions 1,3,2,2

Collisions 3,2,2,2
;Collisions 3,1,1,2
;Collisions 3,3,1,2

;cubes=5

;For n=1 To cubes
;	cube=CreateCube()
;	EntityRadius cube,r
;	ScaleEntity cube,r,r,r
;	cubeph.physics=New physics
;	cubeph\mesh=cube
;	cubeph\elasticity=0.2
;	ScaleEntity cube,3,1,1
;	EntityType cube,3
;	EntityColor cube,255,0,0
;	MoveEntity cube,Rnd(-8,8),-8,Rnd(-8,8)
;	Next

RotateEntity CreateLight(),25,45,0

Global gravity=True

Type bond
Field mesh
Field a.physics, b.physics
End Type

Type physics
Field mesh
Field velocity#[5]
Field elasticity#
Field mass#
End Type

balls=5
e#=0.9

b.bond=New bond
b\mesh=CreateCube()

For n=1 To balls
	ph.physics=New physics
	If n=1 b\a=ph
	If n=2 b\b=ph
	ph\mesh=CopyEntity(m)
	ph\velocity[0]=Rnd(-.5,.5)
	ph\velocity[1]=Rnd(-1,1)
	ph\velocity[2]=Rnd(-.5,.5)	
	PositionEntity ph\mesh,Rnd(-8,8),-8,Rnd(-8,8)
	ResetEntity ph\mesh
	ph\elasticity#=e#
	EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
	Next

HideEntity m

period=1000/60
time=MilliSecs()-period

While Not KeyHit(1)
	
	Repeat
		elapsed=MilliSecs()-time
		Until elapsed
	
	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)
	
	For k=1 To ticks
		time=time+period
		
		If KeyDown(28)
			ph.physics=New physics
			ph\mesh=CopyEntity(m)
			ph\velocity[0]=Rnd(-.5,.5)
			ph\velocity[1]=Rnd(-1,1)
			ph\velocity[2]=Rnd(-.5,.5)	
			ScaleEntity ph\mesh,r,r,r
			EntityRadius ph\mesh,r
			ResetEntity ph\mesh
			ph\elasticity#=e
			EntityColor ph\mesh,Rand(255),Rand(255),Rand(255)
			balls=balls+1
			EndIf
			
		If KeyHit(57)
			For ph.physics=Each physics
				ph\velocity[0]=Rnd(-.5,.5)
				ph\velocity[1]=Rnd(-2,2)
				ph\velocity[2]=Rnd(-.5,.5)
				ph\velocity[4]=0
				Next
			EndIf
		
		If KeyHit(34) gravity=1-gravity
		
		UpdatePhysics
	
		Next
		
	RenderWorld
	
	Text 0,0,fps()
	Text 0,20,"Press space to reset balls."
	Text 0,40,"Press enter to add more balls."
	Text 0,60,"Press g to toggle gravity."
	Text 0,80,balls+" balls exist."
	Flip
	
	Wend
Function UpdatePhysics()

friction#=1;0.99;sliding friction
staticfriction#=0.0000;static friction = minimum velocity before an objects starts sticking

For ph.physics=Each physics
	;gravity	
	If gravity ph\velocity[1]=ph\velocity[1]-0.03
	;ph\velocity[1]=0
	;execute translational velocity
	TranslateEntity ph\mesh,ph\velocity[0],ph\velocity[1],ph\velocity[2],1
	;execute rotational velocity
	TurnEntity ph\mesh,ph\velocity[3],ph\velocity[4],ph\velocity[5],1	
	Next
	
UpdateWorld

;transfer inertia
For ph.physics=Each physics
	
	vx#=ph\velocity[0]
	vy#=ph\velocity[1]
	vz#=ph\velocity[2]
	
	For c=1 To CountCollisions(ph\mesh)
	
		collider=CollisionEntity(ph\mesh,c)
	
		dx#=ph\velocity[0]*Abs(CollisionNX(ph\mesh,c))
		dy#=ph\velocity[1]*Abs(CollisionNY(ph\mesh,c))
		dz#=ph\velocity[2]*Abs(CollisionNZ(ph\mesh,c))
	
		Select GetEntityType(collider)
	
			;Spheres
			Case 1
				ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))
				ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))
				ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))			
				ph\velocity[0]=ph\velocity[0];-dx*.5
				ph\velocity[1]=ph\velocity[1];-dy*.5
				ph\velocity[2]=ph\velocity[2];-dz*.5	
				ph2.physics=findphysics(collider)
				ph2\velocity[0]=ph2\velocity[0]+dx;*.5
				ph2\velocity[1]=ph2\velocity[1]+dy;*.5
				ph2\velocity[2]=ph2\velocity[2]+dz;*.5

			;Polygons with infinite mass
			Case 2
				ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))-dx*ph\elasticity
				ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))-dy*ph\elasticity
				ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))-dz*ph\elasticity

			;Polygons
			;Case 3
			;	ph\velocity[0]=ph\velocity[0]*(1.0-Abs(CollisionNX(ph\mesh,c)))
			;	ph\velocity[1]=ph\velocity[1]*(1.0-Abs(CollisionNY(ph\mesh,c)))
			;	ph\velocity[2]=ph\velocity[2]*(1.0-Abs(CollisionNZ(ph\mesh,c)))
			;	ph2.physics=findphysics(collider)
			;	temp=CreatePivot()
			;	PositionEntity temp,CollisionX(ph\mesh,c),CollisionY(ph\mesh,c),CollisionZ(ph\mesh,c);PickedX(),PickedY(),PickedZ()
			;	AlignToVector temp,-CollisionNX(ph\mesh,c),-CollisionNY(ph\mesh,c),-CollisionNZ(ph\mesh,c),3
			;	TFormPoint EntityX(ph2\mesh,1),EntityY(ph2\mesh,1),EntityZ(ph2\mesh,1),0,temp
			;	ph2\velocity[4]=ph2\velocity[4]-TFormedX()*Sqr(dx^2.0+dz^2.0)
			;	TFormPoint 0,0,TFormedZ(),temp,0
			;	ph2\velocity[0]=ph2\velocity[0]-dx*CollisionNX(ph\mesh,c)
			;	ph2\velocity[1]=ph2\velocity[1]-dy*CollisionNY(ph\mesh,c)
			;	ph2\velocity[2]=ph2\velocity[2]-dz*CollisionNZ(ph\mesh,c)
			;	FreeEntity temp
		
			End Select
		
		Next
	Next	

;add friction
For ph.physics=Each physics
	If EntityCollided(ph\mesh,2)
		For n=0 To 5
			;sliding friction
			ph\velocity[n]=ph\velocity[n]*friction
			;static friction
			If Abs(ph\velocity[n])<staticfriction# ph\velocity[n]=0.0
			Next
		EndIf
	Next

For b.bond=Each bond
	PositionEntity b\mesh,(EntityX(b\a\mesh,1)+EntityX(b\b\mesh,1))/2.0,(EntityY(b\a\mesh,1)+EntityY(b\b\mesh,1))/2.0,(EntityZ(b\a\mesh,1)+EntityZ(b\b\mesh,1))/2.0
	AlignToVector b\mesh,EntityX(b\a\mesh,1)-EntityX(b\b\mesh,1),EntityY(b\a\mesh,1)-EntityY(b\b\mesh,1),EntityZ(b\a\mesh,1)-EntityZ(b\b\mesh,1),3
	RotateEntity b\mesh,EntityPitch(b\mesh,1),EntityYaw(b\mesh,1),0,1
	ScaleEntity b\mesh,.25,.25,0.5*pointdistance(EntityX(b\b\mesh,1),EntityY(b\b\mesh,1),EntityZ(b\b\mesh,1),EntityX(b\a\mesh,1),EntityY(b\a\mesh,1),EntityZ(b\a\mesh,1))	
	ax#=b\a\velocity[0]
	ay#=b\a\velocity[1]
	az#=b\a\velocity[2]
	bx#=b\b\velocity[0]
	by#=b\b\velocity[1]
	bz#=b\b\velocity[2]

	;TFormPoint EntityX(b\a\mesh),EntityY(b\a\mesh),EntityZ(b\a\mesh),0,b\mesh
	;TFormPoint 0,0,TFormedZ()+2,b\mesh,0
	;b\a\velocity[0]=b\a\velocity[0]+TFormedX()
	;b\a\velocity[1]=b\a\velocity[1]+TFormedY()
	;b\a\velocity[2]=b\a\velocity[2]+TFormedZ()

	;TFormPoint EntityX(b\b\mesh),EntityY(b\b\mesh),EntityZ(b\b\mesh),0,b\mesh	
	;TFormPoint 0,0,TFormedZ()-2,b\mesh,0
	;b\b\velocity[0]=b\b\velocity[0]+TFormedX()
	;b\b\velocity[1]=b\b\velocity[1]+TFormedY()
	;b\b\velocity[2]=b\b\velocity[2]+TFormedZ()
	;b\a\velocity[0]=-bx;(EntityX(b\a\mesh)-TFormedX())
	;b\a\velocity[1]=-by;(EntityY(b\a\mesh)-TFormedY())
	;b\a\velocity[2]=-bz;(EntityZ(b\a\mesh)-TFormedZ())
	;PositionEntity b\a\mesh,TFormedX(),TFormedY(),TFormedZ(),1	
	;TranslateEntity b\a\mesh,bx,by,bz,1
	;TFormPoint 0,0,2,b\mesh,0
	;b\b\velocity[0]=-ax;(EntityX(b\b\mesh)-TFormedX())
	;b\b\velocity[1]=-ay;(EntityY(b\b\mesh)-TFormedY())
	;b\b\velocity[2]=-az;(EntityZ(b\b\mesh)-TFormedZ())	
	;TranslateEntity b\b\mesh,ax,ay,az,1;TFormedX(),TFormedY(),TFormedZ(),1	
	Next

End Function

Function FindPhysics.physics(e)
For ph.physics=Each physics
	If ph\mesh=e Return ph
	Next
Return Null
End Function

Function PointDistance#( x1#,y1#,z1#,x2#,y2#,z2# )
Return Sqr#((x1-x2)^2+(y1-y2)^2+(z1-z2)^2)
End Function

Global FPS_fpstime

Function FPS()
oldtime=FPS_fpstime
FPS_fpstime=MilliSecs()
elapsed=FPS_fpstime-oldtime
If Not elapsed elapsed=1
FPS_fps=1000/elapsed
Return FPS_FPS
End Function


dont utilise mass#

if mass#<>

thanks

What is this doing in Advanced 3d forum?

sswift, check one of the many versions of the verlet engine code for some good rigid constraints.

sniff..

basicaly this actually is a real good physic engine! you only need to do a few things: at first, make the spheres rotate, too. this will look better. at second, you need cubes/cylinders/cones and as many primitives as possible to do a real nice physic engine :)

i wanna hear from you when you got that right :)

..and thats 4 years old thread :)

oh, i didnt see.
but "tin-cat" posted here first after 5 years BEFORE i did...
also i would like to know how to do cube to cube verlets!!