Verlet Physics engine 2

Blitz3D Forums/Blitz3D Beginners Area/Verlet Physics engine 2

Hi this is a continuation of my previous physics thread because it was too long and took forever to load.

Here is my most recent code you still need heightmap1.bmp posted at the bottom

Graphics3D 640,480,0,2
SeedRnd(MilliSecs())




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Temporary camera stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cam = CreateCamera()
;CameraRange cam,.01,50
CameraZoom cam,2
TurnEntity cam,0,90,0
TurnEntity cam,20,0,0
MoveEntity cam,16,0,-35
MoveEntity cam,0,0,-85

lit = CreateLight()
TurnEntity lit,90,0,0

;plane = CreatePlane()
;EntityColor plane,32,32,64
;EntityAlpha plane,.9

;EntityType plane,3

;mir = CreateMirror()

Map = LoadTerrain("Heightmap1.bmp")
TerrainDetail map,10000
ScaleEntity map,4,50,4
MoveEntity map,-128,-50,-128



grass = LoadTexture("Grass.png")
EntityTexture map,grass
ScaleTexture grass,20,20
EntityColor map,0,100,0

EntityType map,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




Global VerletType = 1					;Collision Types
Global RBodyType = 2
Global RigidBodyNum = 0
Global groundtype = 3

;Collisions VerletType,RBodyType,2,2  	;Sets Collision Types
;Collisions VerletType,VerletType,1,2
Collisions verletType,GroundType,2,2

Type Verlet								;Verlet type Contains:
	Field Active						;Determines if the verlet is an active verlet or a verlet used for orientation
	Field Mass#							;Gives the verlet a mass
	Field x#,y#,z#						;Gives the verlet an x,y,z cooridnate
	Field vx#,vy#,vz#					;Gives the verlet a velocity in 3d
	Field ox#,oy#,oz#					;Stores the old x,y,z coordinates to figure out the velocity of the verlet
	Field piv,ent						;Gives the verlet a pivot point and names the verlet's entity
	Field Col,ID						;Col tells if the verlet has collided yet and ID tells what entity and verlet group the verlet belongs to
End Type	

Type Constraint							;Constraints constrain the verlets to certain distances from eachother
	Field v1.verlet						;First verlet in constraint
	Field v2.verlet						;Second verlet in constraint
	Field length#						;Length of the constraint
End Type

Type Rigidbody										;Rigidbody is used as a reference for all of the verlets that belong to a mesh
	Field Ent										;Ent is the entity that is acting as the rigid body
	Field ID										;ID is the ID that all of the verlets in this mesh are attatched to
	Field x#,y#,z#									;X,Y,Z coordinates of the mesh
	Field Yaw#,pitch#,Roll#							;Yaw,Pitch,Roll coordinates of the mesh
	Field lf.verlet,lb.verlet,rf.verlet,rb.verlet	;The verlets that are inactive and are used to orient the mesh
	Field lfd.verlet,lbd.verlet,rfd.verlet,rbd.verlet;The verlets that are inactive and are used to orient the mesh	
	Field c.verlet,idl								;The central Verlet
End Type





SetBuffer BackBuffer()

;cube = CreateCube()
;EntityAlpha cube,0
;MoveEntity cube,0,3,0
;applyphysics(cube,10,False)

;cube1 = CreateCube()
;EntityAlpha cube,0
;MoveEntity cube1,10,8,70
;applyphysics(cube1,10,False)

Dim cube2(50)
tmp = 1

timer = MilliSecs()
cnter = 0
While Not KeyDown(1)
Cls




If KeyHit(57) Then
	cube2(tmp) = CreateSphere(4)
	;ScaleEntity cube2(tmp),3,3,3
	MoveEntity cube2(tmp),Rnd(-100,100),2,Rnd(-100,100)
	;MoveEntity cube2(tmp),10,8,70+Rnd(-1,1)
	applyphysics(cube2(tmp),10,False)
	tmp = tmp + 1
EndIf
If KeyDown(200) Then MoveEntity cam,0,0,.5
If KeyDown(208) Then MoveEntity cam,0,0,-.5
If KeyDown(203) Then MoveEntity cam,-.5,0,0
If KeyDown(205) Then MoveEntity cam,.5,0,0
If KeyDown(30) Then MoveEntity cam,0,.5,0
If KeyDown(44) Then MoveEntity cam,0,-.5,0

If KeyDown(21) Then applyforce(cube2(1),-.05,0,0)
If KeyDown(35) Then applyforce(cube2(1),.05,0,0)
If KeyDown(34) Then applyforce(cube2(1),0,0,-.05)
If KeyDown(36) Then applyforce(cube2(1),0,0,.05)

UpdateVerlets()

UpdateConstraints()

DrawVerlets()

UpdateWorld()
detectcollisions()

drawverlets()

positionPhysicsEntity()

RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next

Text 1,1,cnt

cnter = cnter + 1
Text 1,20,"FPS: "+1000/((MilliSecs()-timer)/cnter)

Flip
Wend
End




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet bounding box & creates verlets;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function ApplyPhysics(ent,mass#,stationary)

rigidbodynum = rigidbodynum + 1


;Creates the Rigidbody that all of the verlets are linked to

r.rigidbody = New rigidbody
r\id = rigidbodynum
r\ent = ent
r\x# = EntityX(r\ent)
r\y# = EntityY(r\ent)
r\z# = EntityZ(r\ent)
r\yaw# = EntityYaw(r\ent)
r\pitch# = EntityPitch(r\ent)
r\roll# = EntityRoll(r\ent)
EntityType r\ent,RBodyType
r\idl = stationary

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;






;Loops through all surfaces and verticies
For k = 1 To CountSurfaces(ent)
	surf = GetSurface(ent,k)
	For index = 0 To CountVertices(surf)-1
		TFormPoint VertexX(surf,index), VertexY(surf, index),VertexZ(surf, index), ent, 0
		CreateVerlet(TFormedX(),TFormedY(),TFormedZ(),mass#,ent,r\ID,True)   ;Creates a verlet for every vertice  Later it deletes duplicate verlets for the sake of stability.
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;Creates the bounding box verlets that don't react with anything but are used to orient the mesh

r\lf.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\lb.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\rf.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\rb.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\lfd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\lbd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\rfd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\rbd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\c.verlet = CreateVerlet(r\x# , r\y# , r\z#, 1 , ent , r\ID , False)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;Deletes Duplicate verlets so that the meshes are more stable

For v.verlet = Each verlet
	For vv.verlet = Each verlet
		If vv\ID = v\ID Then
			If vv\piv <> v\piv Then
				If v\x# = vv\x# And v\y# = vv\y# And v\z# = vv\z# And vv\mass <> 0 And v\mass <> 0 Then
					FreeEntity vv\piv
					Delete vv.verlet
				EndIf
			EndIf
		EndIf
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;







;This code makes constraints which it links every inside verlet to all eight of the outside verlets but no others

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If r\idl = False Then
			If v\active = True Then
				Createconstraint(v.verlet,r\rf.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rb.verlet)
				Createconstraint(v.verlet,r\lf.verlet)
				Createconstraint(v.verlet,r\lb.verlet)
				Createconstraint(v.verlet,r\rfd.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rbd.verlet)
				Createconstraint(v.verlet,r\lfd.verlet)
				Createconstraint(v.verlet,r\lbd.verlet)
				Createconstraint(v.verlet,r\c.verlet)
				
			EndIf
		EndIf
	EndIf
Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




createconstraint(r\rf.verlet,r\c.verlet)
createconstraint(r\rb.verlet,r\c.verlet)
createconstraint(r\lf.verlet,r\c.verlet)
createconstraint(r\lb.verlet,r\c.verlet)
createconstraint(r\rfd.verlet,r\c.verlet)
createconstraint(r\rbd.verlet,r\c.verlet)
createconstraint(r\lfd.verlet,r\c.verlet)
createconstraint(r\lbd.verlet,r\c.verlet)

createconstraint(r\rf.verlet,r\rb.verlet)
createconstraint(r\rf.verlet,r\lf.verlet)
createconstraint(r\rf.verlet,r\lb.verlet)

createconstraint(r\rb.verlet,r\lb.verlet)
createconstraint(r\rb.verlet,r\lf.verlet)

createconstraint(r\lf.verlet,r\lb.verlet)


createconstraint(r\rfd.verlet,r\rbd.verlet)
createconstraint(r\rfd.verlet,r\lfd.verlet)
createconstraint(r\rfd.verlet,r\lbd.verlet)

createconstraint(r\rbd.verlet,r\lbd.verlet)
createconstraint(r\rbd.verlet,r\lfd.verlet)

createconstraint(r\lfd.verlet,r\lbd.verlet)


createconstraint(r\rf.verlet,r\rfd.verlet)
createconstraint(r\lf.verlet,r\lfd.verlet)
createconstraint(r\rb.verlet,r\rbd.verlet)
createconstraint(r\lb.verlet,r\lbd.verlet)

;Deletes duplicate Or reversed constraints  This speeds up the constraint loops very much

For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\v1\piv = cc\v1\piv And c\v2\piv = c\v1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





End Function














;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet at the given x,y,z coordinate;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function createverlet.verlet(x#,y#,z#,mass#,ent,ID,Active)

	v.Verlet = New Verlet
	v\x# = x#
	v\y# = y#
	v\z# = z#
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	v\vx# = 0
	v\vy# = 0
	v\vz# = 0
	v\ent = ent
	v\ID = ID
	v\active = Active
	v\mass# = mass#
	
	v\piv = CreatePivot()
	ScaleEntity v\piv,.2,.2,.2
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
	If active = True Then
		EntityType v\piv,VerletType
		EntityRadius v\piv,.1
	EndIf
	
	Return v
End Function

















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Constrains two verlets together;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function CreateConstraint(v1.verlet,v2.verlet)

	c.constraint = New constraint
	c\v1.verlet = v1.verlet
	c\v2.verlet = v2.verlet
	c\length# = Sqr((c\v1\x#-c\v2\x#)^2 + (c\v1\y#-c\v2\y#)^2 + (c\v1\z#-c\v2\z#)^2)

End Function
























;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every verlet and updates it;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Updateverlets()

For v.verlet = Each verlet
	
	If v\col = True Then
		v\col = False
		fric# = .5
	Else
		fric# = 1
	EndIf
	
	v\vx# = (v\x# - v\ox#)*fric#
	v\vy# = (v\y# - v\oy#)*fric#
	v\vz# = (v\z# - v\oz#)*fric#
	
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	
	v\x# = v\x# + v\vx#
	v\y# = v\y# + v\vy# - .004
	v\z# = v\z# + v\vz#
	
	
	For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx# = v\x# - vv\x#
				dy# = v\y# - vv\y#
				dz# = v\z# - vv\z#
				dist# = Sqr ( dx#*dx# + dy#*dy# + dz#*dz# )		
				If dist# < .6 Then
				
					
					Diffx# = ( dist# - .6 ) * ( dx# / dist# )
					Diffy# = ( dist# - .6 ) * ( dy# / dist# )
					Diffz# = ( dist# - .6 ) * ( dz# / dist# )

					v\x# = v\x# - Diffx# ;* .5
					v\y# = v\y# - Diffy# ;* .5
					v\z# = v\z# - Diffz# ;* .5

					vv\x# = vv\x# + Diffx# ;* .5
					vv\y# = vv\y# + Diffy# ;* .5
					vv\z# = vv\z# + Diffz# ;* .5
				EndIf 				
			EndIf
		Next 

;	If v\y# < 0 Then
;		v\y# = 0
;		v\col = True
;	EndIf
	
Next

End Function






















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every constraint and updates it;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function UpdateConstraints()

For i = 1 To 10

	For c.constraint = Each constraint
		mx# = ( c\v1\x# - c\v2\x# )
		my# = ( c\v1\y# - c\v2\y# )
		mz# = ( c\v1\z# - c\v2\z# )
		
		dist# = Sqr( (mx)^2 + (my)^2 + (mz)^2 )
		
		mx# = mx# / 2
		my# = my# / 2
		mz# = mz# / 2
		
		If dist# <> 0  Then
			dif# = (dist# - c\length#) / dist#
		EndIf
		
	;	If c\v1\col = False Or i > 5 Then
			c\v1\x# = c\v1\x# - dif# * mx#
			c\v1\y# = c\v1\y# - dif# * my#
			c\v1\z# = c\v1\z# - dif# * mz#
	;	EndIf
	;	If c\v2\col = False Or i > 5 Then
			c\v2\x# = c\v2\x# + dif# * mx#
			c\v2\y# = c\v2\y# + dif# * my#
			c\v2\z# = c\v2\z# + dif# * mz#
	;	EndIf
	Next

Next

End Function



















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all verlets;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Drawverlets()

For v.verlet = Each verlet
	
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
Next

End Function


















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all meshes;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function PositionPhysicsEntity()

For r.rigidbody = Each rigidbody
	PositionEntity r\ent,EntityX(r\c\piv),EntityY(r\c\piv),EntityZ(r\c\piv)
	
	;align mesh to verlet cage
	x# = EntityX( r\rf\piv ) - EntityX( r\lf\piv ) + EntityX( r\rb\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\lf\piv ) + EntityY( r\rb\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\lf\piv ) + EntityZ( r\rb\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#,1  
	x# = EntityX( r\rf\piv ) - EntityX( r\rb\piv ) + EntityX( r\lf\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\rb\piv ) + EntityY( r\lf\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\rb\piv ) + EntityZ( r\lf\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#, 3
Next

End Function





















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;tests all verlets for collisions;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Detectcollisions()

For v.verlet = Each verlet
	If EntityX(v\piv) <> v\x# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\x# = EntityX(v\piv)
	EndIf
	If EntityY(v\piv) <> v\y# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\y# = EntityY(v\piv)
	EndIf
	If EntityZ(v\piv) <> v\z# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\z# = EntityZ(v\piv)
	EndIf
Next

End Function






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;applies a force to given object;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function applyForce(ent,x#,y#,z#)

For v.verlet = Each verlet
	If v\ent = ent Then
		v\ox# = v\ox# - x#
		v\oy# = v\oy# - y#
		v\oz# = v\oz# - z#
	EndIf
Next

End Function




Here is the link to heightmap1.bmp
http://files.filefront.com/heightmap1bmp/;11773113;/fileinfo.html

I tried that with the second UpdateWorld() taken out and it works the same, I don't see why you would need two. I get a tiny bit faster FPS too. But if you need it then don't mind me XD.

But anyways.. I like how it's going. It may be slow but at least it works. Hopefully you can get it to go faster and be as great as Half-Life 2 physics (or better).

Oh Thanks for pointing that out I just forgot to take it out. When I finish it, I will make an updatePhysics function that also updates the world and all of the physics.

I am having a problem with applying rotational velocity to things here is the code. The function that doesn't work is the last one.

Graphics3D 640,480,0,2
SeedRnd(MilliSecs())




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Temporary camera stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cam = CreateCamera()
;CameraRange cam,.01,50
CameraZoom cam,2
TurnEntity cam,0,90,0
TurnEntity cam,20,0,0
MoveEntity cam,16,0,-35
MoveEntity cam,0,0,-85

lit = CreateLight()
TurnEntity lit,90,0,0

;plane = CreatePlane()
;EntityColor plane,32,32,64
;EntityAlpha plane,.9

;EntityType plane,3

;mir = CreateMirror()

Map = LoadTerrain("Heightmap1.bmp")
TerrainDetail map,10000
ScaleEntity map,4,50,4
MoveEntity map,-128,-50,-128



grass = LoadTexture("Grass.png")
EntityTexture map,grass
ScaleTexture grass,20,20
EntityColor map,0,100,0

EntityType map,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




Global VerletType = 1					;Collision Types
Global RBodyType = 2
Global RigidBodyNum = 0
Global groundtype = 3

;Collisions VerletType,RBodyType,2,2  	;Sets Collision Types
;Collisions VerletType,VerletType,1,2
Collisions verletType,GroundType,2,2

Type Verlet								;Verlet type Contains:
	Field Active						;Determines if the verlet is an active verlet or a verlet used for orientation
	Field Mass#							;Gives the verlet a mass
	Field x#,y#,z#						;Gives the verlet an x,y,z cooridnate
	Field vx#,vy#,vz#					;Gives the verlet a velocity in 3d
	Field ox#,oy#,oz#					;Stores the old x,y,z coordinates to figure out the velocity of the verlet
	Field piv,ent						;Gives the verlet a pivot point and names the verlet's entity
	Field Col,ID,piv2					;Col tells if the verlet has collided yet and ID tells what entity and verlet group the verlet belongs to
End Type	

Type Constraint							;Constraints constrain the verlets to certain distances from eachother
	Field v1.verlet						;First verlet in constraint
	Field v2.verlet						;Second verlet in constraint
	Field length#						;Length of the constraint
End Type

Type Rigidbody										;Rigidbody is used as a reference for all of the verlets that belong to a mesh
	Field Ent										;Ent is the entity that is acting as the rigid body
	Field ID										;ID is the ID that all of the verlets in this mesh are attatched to
	Field x#,y#,z#									;X,Y,Z coordinates of the mesh
	Field Yaw#,pitch#,Roll#							;Yaw,Pitch,Roll coordinates of the mesh
	Field lf.verlet,lb.verlet,rf.verlet,rb.verlet	;The verlets that are inactive and are used to orient the mesh
	Field lfd.verlet,lbd.verlet,rfd.verlet,rbd.verlet;The verlets that are inactive and are used to orient the mesh	
	Field c.verlet,idl								;The central Verlet
End Type





SetBuffer BackBuffer()

axel = CreateCube()
ScaleEntity axel,.1,1.3,.1

wheel = CreateCylinder(8)

EntityParent Axel,Wheel

ApplyPhysics(wheel,10,False)

EntityColor axel,255,0,0
EntityColor wheel,0,0,255

timer = MilliSecs()
cnter = 0
While Not KeyDown(1)
Cls

;papplyrotationalvelocity(Wheel,axel,0,5,0)

If KeyDown(200) Then MoveEntity cam,0,0,.5
If KeyDown(208) Then MoveEntity cam,0,0,-.5
If KeyDown(203) Then MoveEntity cam,-.5,0,0
If KeyDown(205) Then MoveEntity cam,.5,0,0
If KeyDown(30) Then MoveEntity cam,0,.5,0
If KeyDown(44) Then MoveEntity cam,0,-.5,0

If KeyDown(21) Then End
If KeyDown(35) Then End
If KeyDown(34) Then End
If KeyDown(36) Then End

UpdateVerlets()

UpdateConstraints()

DrawVerlets()

UpdateWorld()
detectcollisions()

drawverlets()

positionPhysicsEntity()

RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next

Text 1,1,cnt

cnter = cnter + 1
Text 1,20,"FPS: "+1000/((MilliSecs()-timer)/cnter)

Flip
Wend
End




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet bounding box & creates verlets;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function ApplyPhysics(ent,mass#,stationary)

rigidbodynum = rigidbodynum + 1


;Creates the Rigidbody that all of the verlets are linked to

r.rigidbody = New rigidbody
r\id = rigidbodynum
r\ent = ent
r\x# = EntityX(r\ent)
r\y# = EntityY(r\ent)
r\z# = EntityZ(r\ent)
r\yaw# = EntityYaw(r\ent)
r\pitch# = EntityPitch(r\ent)
r\roll# = EntityRoll(r\ent)
EntityType r\ent,RBodyType
r\idl = stationary

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;






;Loops through all surfaces and verticies
For k = 1 To CountSurfaces(ent)
	surf = GetSurface(ent,k)
	For index = 0 To CountVertices(surf)-1
		TFormPoint VertexX(surf,index), VertexY(surf, index),VertexZ(surf, index), ent, 0
		CreateVerlet(TFormedX(),TFormedY(),TFormedZ(),mass#,ent,r\ID,True)   ;Creates a verlet for every vertice  Later it deletes duplicate verlets for the sake of stability.
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;Creates the bounding box verlets that don't react with anything but are used to orient the mesh

r\lf.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\lb.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\rf.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\rb.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\lfd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\lbd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\rfd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\rbd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\c.verlet = CreateVerlet(r\x# , r\y# , r\z#, 1 , ent , r\ID , False)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;Deletes Duplicate verlets so that the meshes are more stable

For v.verlet = Each verlet
	For vv.verlet = Each verlet
		If vv\ID = v\ID Then
			If vv\piv <> v\piv Then
				If v\x# = vv\x# And v\y# = vv\y# And v\z# = vv\z# And vv\mass <> 0 And v\mass <> 0 Then
					FreeEntity vv\piv
					Delete vv.verlet
				EndIf
			EndIf
		EndIf
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;







;This code makes constraints which it links every inside verlet to all eight of the outside verlets but no others

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If r\idl = False Then
			If v\active = True Then
				Createconstraint(v.verlet,r\rf.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rb.verlet)
				Createconstraint(v.verlet,r\lf.verlet)
				Createconstraint(v.verlet,r\lb.verlet)
				Createconstraint(v.verlet,r\rfd.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rbd.verlet)
				Createconstraint(v.verlet,r\lfd.verlet)
				Createconstraint(v.verlet,r\lbd.verlet)
				Createconstraint(v.verlet,r\c.verlet)
				
			EndIf
		EndIf
	EndIf
Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




createconstraint(r\rf.verlet,r\c.verlet)
createconstraint(r\rb.verlet,r\c.verlet)
createconstraint(r\lf.verlet,r\c.verlet)
createconstraint(r\lb.verlet,r\c.verlet)
createconstraint(r\rfd.verlet,r\c.verlet)
createconstraint(r\rbd.verlet,r\c.verlet)
createconstraint(r\lfd.verlet,r\c.verlet)
createconstraint(r\lbd.verlet,r\c.verlet)

createconstraint(r\rf.verlet,r\rb.verlet)
createconstraint(r\rf.verlet,r\lf.verlet)
createconstraint(r\rf.verlet,r\lb.verlet)

createconstraint(r\rb.verlet,r\lb.verlet)
createconstraint(r\rb.verlet,r\lf.verlet)

createconstraint(r\lf.verlet,r\lb.verlet)


createconstraint(r\rfd.verlet,r\rbd.verlet)
createconstraint(r\rfd.verlet,r\lfd.verlet)
createconstraint(r\rfd.verlet,r\lbd.verlet)

createconstraint(r\rbd.verlet,r\lbd.verlet)
createconstraint(r\rbd.verlet,r\lfd.verlet)

createconstraint(r\lfd.verlet,r\lbd.verlet)


createconstraint(r\rf.verlet,r\rfd.verlet)
createconstraint(r\lf.verlet,r\lfd.verlet)
createconstraint(r\rb.verlet,r\rbd.verlet)
createconstraint(r\lb.verlet,r\lbd.verlet)

;Deletes duplicate Or reversed constraints  This speeds up the constraint loops very much

For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\v1\piv = cc\v1\piv And c\v2\piv = c\v1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





End Function














;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet at the given x,y,z coordinate;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function createverlet.verlet(x#,y#,z#,mass#,ent,ID,Active)

	v.Verlet = New Verlet
	v\x# = x#
	v\y# = y#
	v\z# = z#
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	v\vx# = 0
	v\vy# = 0
	v\vz# = 0
	v\ent = ent
	v\ID = ID
	v\active = Active
	v\mass# = mass#
	
	v\piv = CreatePivot()
	v\piv2 = CreatePivot()
	ScaleEntity v\piv,.2,.2,.2
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
	If active = True Then
		EntityType v\piv,VerletType
		EntityRadius v\piv,.1
	EndIf
	
	Return v
End Function

















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Constrains two verlets together;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function CreateConstraint(v1.verlet,v2.verlet)

	c.constraint = New constraint
	c\v1.verlet = v1.verlet
	c\v2.verlet = v2.verlet
	c\length# = Sqr((c\v1\x#-c\v2\x#)^2 + (c\v1\y#-c\v2\y#)^2 + (c\v1\z#-c\v2\z#)^2)

End Function
























;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every verlet and updates it;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Updateverlets()

For v.verlet = Each verlet
	
	If v\col = True Then
		v\col = False
		fric# = .5
	Else
		fric# = 1
	EndIf
	
	v\vx# = (v\x# - v\ox#)*fric#
	v\vy# = (v\y# - v\oy#)*fric#
	v\vz# = (v\z# - v\oz#)*fric#
	
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	
	v\x# = v\x# + v\vx#
	v\y# = v\y# + v\vy# - .004
	v\z# = v\z# + v\vz#
	
	
	For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx# = v\x# - vv\x#
				dy# = v\y# - vv\y#
				dz# = v\z# - vv\z#
				dist# = Sqr ( dx#*dx# + dy#*dy# + dz#*dz# )		
				If dist# < .6 Then
				
					
					Diffx# = ( dist# - .6 ) * ( dx# / dist# )
					Diffy# = ( dist# - .6 ) * ( dy# / dist# )
					Diffz# = ( dist# - .6 ) * ( dz# / dist# )

					v\x# = v\x# - Diffx# ;* .5
					v\y# = v\y# - Diffy# ;* .5
					v\z# = v\z# - Diffz# ;* .5

					vv\x# = vv\x# + Diffx# ;* .5
					vv\y# = vv\y# + Diffy# ;* .5
					vv\z# = vv\z# + Diffz# ;* .5
				EndIf 				
			EndIf
		Next 

;	If v\y# < 0 Then
;		v\y# = 0
;		v\col = True
;	EndIf
	
Next

End Function






















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every constraint and updates it;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function UpdateConstraints()

For i = 1 To 10

	For c.constraint = Each constraint
		mx# = ( c\v1\x# - c\v2\x# )
		my# = ( c\v1\y# - c\v2\y# )
		mz# = ( c\v1\z# - c\v2\z# )
		
		dist# = Sqr( (mx)^2 + (my)^2 + (mz)^2 )
		
		mx# = mx# / 2
		my# = my# / 2
		mz# = mz# / 2
		
		If dist# <> 0  Then
			dif# = (dist# - c\length#) / dist#
		EndIf
		
	;	If c\v1\col = False Or i > 5 Then
			c\v1\x# = c\v1\x# - dif# * mx#
			c\v1\y# = c\v1\y# - dif# * my#
			c\v1\z# = c\v1\z# - dif# * mz#
	;	EndIf
	;	If c\v2\col = False Or i > 5 Then
			c\v2\x# = c\v2\x# + dif# * mx#
			c\v2\y# = c\v2\y# + dif# * my#
			c\v2\z# = c\v2\z# + dif# * mz#
	;	EndIf
	Next

Next

End Function



















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all verlets;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Drawverlets()

For v.verlet = Each verlet
	
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
Next

End Function


















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all meshes;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function PositionPhysicsEntity()

For r.rigidbody = Each rigidbody
	PositionEntity r\ent,EntityX(r\c\piv),EntityY(r\c\piv),EntityZ(r\c\piv)
	
	;align mesh to verlet cage
	x# = EntityX( r\rf\piv ) - EntityX( r\lf\piv ) + EntityX( r\rb\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\lf\piv ) + EntityY( r\rb\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\lf\piv ) + EntityZ( r\rb\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#,1  
	x# = EntityX( r\rf\piv ) - EntityX( r\rb\piv ) + EntityX( r\lf\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\rb\piv ) + EntityY( r\lf\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\rb\piv ) + EntityZ( r\lf\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#, 3
Next

End Function





















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;tests all verlets for collisions;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Detectcollisions()

For v.verlet = Each verlet
	If EntityX(v\piv) <> v\x# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\x# = EntityX(v\piv)
	EndIf
	If EntityY(v\piv) <> v\y# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\y# = EntityY(v\piv)
	EndIf
	If EntityZ(v\piv) <> v\z# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\z# = EntityZ(v\piv)
	EndIf
Next

End Function






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;applies a force to given object;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function PApplyForce(ent,x#,y#,z#)

For v.verlet = Each verlet
	If v\ent = ent Then
		v\ox# = v\ox# - x#
		v\oy# = v\oy# - y#
		v\oz# = v\oz# - z#
	EndIf
Next

End Function



Function PMoveEntity(ent,x#,y#,z#)

For v.verlet = Each verlet
	If v\ent = ent Then
		v\ox# = v\ox# + x#
		v\oy# = v\oy# + y#
		v\oz# = v\oz# + z#
		v\x# = v\x# + x#
		v\y# = v\y# + y#
		v\z# = v\z# + z#
	EndIf
Next

End Function



Function PPositionEntity(ent,x#,y#,z#)

For v.verlet = Each verlet
	If v\ent = ent Then
		v\ox# = x#
		v\oy# = y#
		v\oz# = z#
		v\x# = x#
		v\y# = y#
		v\z# = z#
	EndIf
Next

End Function


Function PApplyRotationalVelocity(Ent,axel,Yaw#,pitch#,roll#)

tmpPiv = CreatePivot()

PositionEntity tmppiv,EntityX(axel),EntityY(axel),EntityZ(axel)

TurnEntity tmppiv,EntityYaw(axel),EntityPitch(axel),EntityRoll(axel)

For V.verlet = Each verlet
	If V\ent = ent Then
		EntityParent v\piv2,tmppiv
		PositionEntity v\piv,v\x#,v\y#,v\z#
	EndIf
Next

TurnEntity tmppiv,-Yaw#,-Pitch#,-Roll#

For V.verlet = Each verlet
	If v\ent = ent Then
		V\ox# = V\ox# + (v\x# - EntityX#(v\piv2))
		V\oy# = V\oy# + (v\y# - EntityY#(v\piv2))
		V\oz# = V\oz# + (v\z# - EntityZ#(v\piv2))
	EndIf
Next

TurnEntity tmppiv,Yaw#,Pitch,Roll#

For V.verlet = Each verlet
	If v\ent = ent Then
		
		;EntityParent v\piv2,0
		FreeEntity v\piv2
		v\piv2 = CreatePivot()
		;RotateEntity v\piv2,0,0,0
		;PositionEntity v\piv2,V\x#,v\y#,v\z#
	EndIf
Next

FreeEntity tmppiv
End Function



Here is the function I am having trouble with

Function PApplyRotationalVelocity(Ent,axel,Yaw#,pitch#,roll#)

tmpPiv = CreatePivot()

PositionEntity tmppiv,EntityX(axel),EntityY(axel),EntityZ(axel)

TurnEntity tmppiv,EntityYaw(axel),EntityPitch(axel),EntityRoll(axel)

For V.verlet = Each verlet
	If V\ent = ent Then
		EntityParent v\piv2,tmppiv
		PositionEntity v\piv,v\x#,v\y#,v\z#
	EndIf
Next

TurnEntity tmppiv,-Yaw#,-Pitch#,-Roll#

For V.verlet = Each verlet
	If v\ent = ent Then
		V\ox# = V\ox# + (v\x# - EntityX#(v\piv2))
		V\oy# = V\oy# + (v\y# - EntityY#(v\piv2))
		V\oz# = V\oz# + (v\z# - EntityZ#(v\piv2))
	EndIf
Next

TurnEntity tmppiv,Yaw#,Pitch,Roll#

For V.verlet = Each verlet
	If v\ent = ent Then
		
		;EntityParent v\piv2,0
		FreeEntity v\piv2
		v\piv2 = CreatePivot()
		;RotateEntity v\piv2,0,0,0
		;PositionEntity v\piv2,V\x#,v\y#,v\z#
	EndIf
Next

FreeEntity tmppiv
End Function




Does anyone know how I could apply rotational velocity correctly? This doesn't seem to work.

Rotation for verlet is best done by applying forces/acceleration to the pointmasses / verlets. Your system does not do this it only uses implied velocities. You are therefore missing acceleration and a timestep constant in your code.

ImpliedVelocityX# = ( CurrentXPos - OldXPos ) * Damping + AccelerationX * TIMESTEP ^ 2

ImpliedVelocityY# = ( CurrentYPos - OldYPos ) * Damping + AccelerationY * TIMESTEP ^ 2

I'm not sure what you are trying to do in your function above but it is not very efficient to iterated through every verlet just to find the ones you want. Either use a linked list of verlets or create a blitz array to hold your verlets within the rigidbody type. I've already mentioned this. Also, don't keep freeing and creating pivots. Create one GLOBAL helper pivot and re-use it.

If you look at this paper then it explains the best way of setting things up correctly.


accumulate forces -----> update verlets -----> reset forces ------> update constraints ( including collisions )



http://www.gamasutra.com/resource_guide/20030121/jacobson_01.shtml

Taking a 2d example :

Imagine this simple object

p1-----------p2


Where p1 & p2 are pointmasses ( verlets ) with the line being a constraint connecting them.

To rotate this object clockwise you apply an upwards force to p1 and a downwards force to p2. Both forces should be equal but opposite for s mooth turn. Note that getting the object to rotate to a specific angle isn't so easy but can be simulated by reducing the force applied the closer it gets to the target and also applying friction forces perpendicular to the movement.

                    |
                    V
p1-----------p2
^
|


I'd recommend you get the basics right in 2d before moving to 3d. Note that this doesn't stop you from using 2d in 3d to make use of blitz collisions. You simply have to ignore the z axis.

Hope this helps you.

Stevie

As always You have been a lot of help stevie thanks

I realize that it is inefficient however I don't know what you mean by create a list of verlets or how to make a blitz array that is different for each rigidbody. I am not sure how to do these things exactly.

I am also confused about exactly what a timestep is.

Sorry if the answers to my questions seem obvious but I don't know everything about B3d yet.

Within a type, a blitz array must be set to a maximum per rigid body, it's doubtful you should get past 50 pointmasses with such a simple system. For linked lists use the search function - it's been asked many times before.

Read the article - the timestep is just a constant which tells the system how many times to update accelerations per second. I tend to use 0.05 in conjunction with high gravity of 40ms-2

This might sound harsh but if you are a beginner with the language then starting with a physics engine is probably not a good idea.

I'm not a real beginner. I have programmed for 5 years. I just now started getting on the blog though and have started learning a lot of things that I could not find in the help section of b3d. I will try out the array thing for now. Thanks :)

Also I found a fun little bug in polymaniacs after a few hours of playing. If you are using a tank on keys 2 after the game over thingy starts to come in you can press self destruct over and over an you will fly in the air like a helicopter. sorry I couldn't post a video but it is really funny seeing a tank fly in a game.


Also I found a fun little bug in polymaniacs after a few hours of playing. If you are using a tank on keys 2 after the game over thingy starts to come in you can press self destruct over and over an you will fly in the air like a helicopter. sorry I couldn't post a video but it is really funny seeing a tank fly in a game.



Which mini-game? I knew this happened in Timetrial as you're indestructable there. This is all fixed now though - you can't shoot or self-destruct when the game is over and in timetrial it resets you to the start position.

You can self destruct at the end of deathmatch when the game over thing still hasn't grown to its full size.

Just wanted to mention. Someone saw me playing polymaniacs over my shoulder at school and wanted to play so now almost every guy at my school has it on their laptop. I think you would make a ton of money off of this game considering it is so populare at my school.

P.S. How many different worlds are you planning to have in your final game. 3 worlds is fun but more worlds would mean more fun. :)


P.S. How many different worlds are you planning to have in your final game. 3 worlds is fun but more worlds would mean more fun. :)



Just wait until you see the..... nahhh, I'll let Stevie tell you! :)

What are you talking about pongo???

P.S. How is the physics coming?


P.S. How many different worlds are you planning to have in your final game. 3 worlds is fun but more worlds would mean more fun. :)



There will be loads of levels with alot more variation. Here's a quick preview of a prototype stunt level Pongo has been kindly building for me .. fantastic fun :)




Just wanted to mention. Someone saw me playing polymaniacs over my shoulder at school and wanted to play so now almost every guy at my school has it on their laptop. I think you would make a ton of money off of this game considering it is so populare at my school.



Thanks - that's good to know. I'm not convinced yet about making much money - we'll see though.

[quote]There will be loads of levels with alot more variation. Here's a quick preview of a prototype stunt level Pongo has been kindly building for me .. fantastic fun :)[\quote]

Is there a level builder or something?

That level looks fun :)

There is a level builder but it isn't very user friendly at the moment. I hope to integrate it into the game but we'll see how that goes.

ok Feel free to email it to me if you want me to make a level :) I don't mind if it isn't user friendly

I think it would be a nice effect to make the water like ice when it was snowing. :)


I think it would be a nice effect to make the water like ice when it was snowing. :)



This is easily done so I will add it at some point.

Anyway, I've hogged this thread enough ...

I think after I tweak some things and make them more efficient I will leave my physics engine simple and pretty close to how it is so I can adopt it to almost any game I want to make and make it efficient for that game.

this has been a very fun project... so far :)

BTW How do you use seperating axis theory? I don't get how to use it?

Here is my code so far. I'm not sure that I will take this any furthur until I figure out what kind of game I will need it for. :)

Graphics3D 640,480,0,2
SeedRnd(MilliSecs())




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Temporary camera stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

cam = CreateCamera()
;CameraRange cam,.01,50
CameraZoom cam,2
TurnEntity cam,0,90,0
TurnEntity cam,20,0,0
MoveEntity cam,16,0,-35
MoveEntity cam,0,0,-85

lit = CreateLight()
TurnEntity lit,90,0,0

;plane = CreatePlane()
;EntityColor plane,32,32,64
;EntityAlpha plane,.9

;EntityType plane,3

;mir = CreateMirror()

Map = LoadTerrain("Heightmap1.bmp")
TerrainDetail map,10000
ScaleEntity map,4,50,4
MoveEntity map,-128,-50,-128



grass = LoadTexture("Grass.png")
EntityTexture map,grass
ScaleTexture grass,20,20
EntityColor map,0,100,0

EntityType map,3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




Global VerletType = 1					;Collision Types
Global RBodyType = 2
Global RigidBodyNum = 0
Global groundtype = 3

;Collisions VerletType,RBodyType,2,2  	;Sets Collision Types
;Collisions VerletType,VerletType,1,2
Collisions verletType,GroundType,2,2

Type Verlet								;Verlet type Contains:
	Field Active						;Determines if the verlet is an active verlet or a verlet used for orientation
	Field Mass#							;Gives the verlet a mass
	Field x#,y#,z#						;Gives the verlet an x,y,z cooridnate
	Field vx#,vy#,vz#					;Gives the verlet a velocity in 3d
	Field ox#,oy#,oz#					;Stores the old x,y,z coordinates to figure out the velocity of the verlet
	Field piv,ent						;Gives the verlet a pivot point and names the verlet's entity
	Field Col,ID,piv2					;Col tells if the verlet has collided yet and ID tells what entity and verlet group the verlet belongs to
End Type	

Type Constraint							;Constraints constrain the verlets to certain distances from eachother
	Field v1.verlet						;First verlet in constraint
	Field v2.verlet						;Second verlet in constraint
	Field length#						;Length of the constraint
End Type

Type Rigidbody										;Rigidbody is used as a reference for all of the verlets that belong to a mesh
	Field Ent										;Ent is the entity that is acting as the rigid body
	Field ID										;ID is the ID that all of the verlets in this mesh are attatched to
	Field x#,y#,z#									;X,Y,Z coordinates of the mesh
	Field Yaw#,pitch#,Roll#							;Yaw,Pitch,Roll coordinates of the mesh
	Field lf.verlet,lb.verlet,rf.verlet,rb.verlet	;The verlets that are inactive and are used to orient the mesh
	Field lfd.verlet,lbd.verlet,rfd.verlet,rbd.verlet;The verlets that are inactive and are used to orient the mesh	
	Field c.verlet,idl								;The central Verlet
	Field Verl.verlet[50],verlnum
End Type





SetBuffer BackBuffer()

axel = CreateCube()
ScaleEntity axel,.1,1.3,.1

wheel = CreateCylinder(8)

EntityParent Axel,Wheel

ApplyPhysics(wheel,10,False)

EntityColor axel,255,0,0
EntityColor wheel,0,0,255

papplyforce(wheel,0,.5,0)

timer = MilliSecs()

cnter = 0
While Not KeyDown(1)
Cls


If KeyDown(200) Then MoveEntity cam,0,0,.5
If KeyDown(208) Then MoveEntity cam,0,0,-.5
If KeyDown(203) Then MoveEntity cam,-.5,0,0
If KeyDown(205) Then MoveEntity cam,.5,0,0
If KeyDown(30) Then MoveEntity cam,0,.5,0
If KeyDown(44) Then MoveEntity cam,0,-.5,0

If KeyDown(21) Then End
If KeyDown(35) Then End
If KeyDown(34) Then End
If KeyDown(36) Then End

UpdateVerlets()

UpdateConstraints()

DrawVerlets()

UpdateWorld()
detectcollisions()

drawverlets()

positionPhysicsEntity()

RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next

Text 1,1,cnt

cnter = cnter + 1
Text 1,20,"FPS: "+1000/((MilliSecs()-timer)/cnter)

Flip
Wend
End




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet bounding box & creates verlets;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function ApplyPhysics(ent,mass#,stationary)

rigidbodynum = rigidbodynum + 1


;Creates the Rigidbody that all of the verlets are linked to

r.rigidbody = New rigidbody
r\id = rigidbodynum
r\ent = ent
r\x# = EntityX(r\ent)
r\y# = EntityY(r\ent)
r\z# = EntityZ(r\ent)
r\yaw# = EntityYaw(r\ent)
r\pitch# = EntityPitch(r\ent)
r\roll# = EntityRoll(r\ent)
EntityType r\ent,RBodyType
r\idl = stationary

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;






;Loops through all surfaces and verticies
For k = 1 To CountSurfaces(ent)
	surf = GetSurface(ent,k)
	For index = 0 To CountVertices(surf)-1
		TFormPoint VertexX(surf,index), VertexY(surf, index),VertexZ(surf, index), ent, 0
		CreateVerlet(TFormedX(),TFormedY(),TFormedZ(),mass#,ent,r\ID,True)   ;Creates a verlet for every vertice  Later it deletes duplicate verlets for the sake of stability.
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;Creates the bounding box verlets that don't react with anything but are used to orient the mesh

r\lf.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\lb.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\rf.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\rb.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\lfd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\lbd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\rfd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\rbd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\c.verlet = CreateVerlet(r\x# , r\y# , r\z#, 1 , ent , r\ID , False)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;Deletes Duplicate verlets so that the meshes are more stable

For v.verlet = Each verlet
	For vv.verlet = Each verlet
		If vv\ID = v\ID Then
			If vv\piv <> v\piv Then
				If v\x# = vv\x# And v\y# = vv\y# And v\z# = vv\z# And vv\mass <> 0 And v\mass <> 0 Then
					FreeEntity vv\piv
					Delete vv.verlet
				EndIf
			EndIf
		EndIf
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




cnt = 0
For v.verlet = Each verlet
	If V\ent = ent And V\Active = True Then
		R\Verl.verlet[cnt] = v.verlet
		cnt = cnt + 1
	EndIf
Next

r\Verlnum = cnt - 1


;This code makes constraints which it links every inside verlet to all eight of the outside verlets but no others

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If r\idl = False Then
			If v\active = True Then
				Createconstraint(v.verlet,r\rf.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rb.verlet)
				Createconstraint(v.verlet,r\lf.verlet)
				Createconstraint(v.verlet,r\lb.verlet)
				Createconstraint(v.verlet,r\rfd.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rbd.verlet)
				Createconstraint(v.verlet,r\lfd.verlet)
				Createconstraint(v.verlet,r\lbd.verlet)
				Createconstraint(v.verlet,r\c.verlet)
				
			EndIf
		EndIf
	EndIf
Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




createconstraint(r\rf.verlet,r\c.verlet)
createconstraint(r\rb.verlet,r\c.verlet)
createconstraint(r\lf.verlet,r\c.verlet)
createconstraint(r\lb.verlet,r\c.verlet)
createconstraint(r\rfd.verlet,r\c.verlet)
createconstraint(r\rbd.verlet,r\c.verlet)
createconstraint(r\lfd.verlet,r\c.verlet)
createconstraint(r\lbd.verlet,r\c.verlet)

createconstraint(r\rf.verlet,r\rb.verlet)
createconstraint(r\rf.verlet,r\lf.verlet)
createconstraint(r\rf.verlet,r\lb.verlet)

createconstraint(r\rb.verlet,r\lb.verlet)
createconstraint(r\rb.verlet,r\lf.verlet)

createconstraint(r\lf.verlet,r\lb.verlet)


createconstraint(r\rfd.verlet,r\rbd.verlet)
createconstraint(r\rfd.verlet,r\lfd.verlet)
createconstraint(r\rfd.verlet,r\lbd.verlet)

createconstraint(r\rbd.verlet,r\lbd.verlet)
createconstraint(r\rbd.verlet,r\lfd.verlet)

createconstraint(r\lfd.verlet,r\lbd.verlet)


createconstraint(r\rf.verlet,r\rfd.verlet)
createconstraint(r\lf.verlet,r\lfd.verlet)
createconstraint(r\rb.verlet,r\rbd.verlet)
createconstraint(r\lb.verlet,r\lbd.verlet)

;Deletes duplicate Or reversed constraints  This speeds up the constraint loops very much

For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\v1\piv = cc\v1\piv And c\v2\piv = c\v1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





End Function














;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet at the given x,y,z coordinate;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function createverlet.verlet(x#,y#,z#,mass#,ent,ID,Active)

	v.Verlet = New Verlet
	v\x# = x#
	v\y# = y#
	v\z# = z#
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	v\vx# = 0
	v\vy# = 0
	v\vz# = 0
	v\ent = ent
	v\ID = ID
	v\active = Active
	v\mass# = mass#
	
	v\piv = CreatePivot()
	v\piv2 = CreatePivot()
	ScaleEntity v\piv,.2,.2,.2
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
	If active = True Then
		EntityType v\piv,VerletType
		EntityRadius v\piv,.1
	EndIf
	
	Return v
End Function

















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Constrains two verlets together;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function CreateConstraint(v1.verlet,v2.verlet)

	c.constraint = New constraint
	c\v1.verlet = v1.verlet
	c\v2.verlet = v2.verlet
	c\length# = Sqr((c\v1\x#-c\v2\x#)^2 + (c\v1\y#-c\v2\y#)^2 + (c\v1\z#-c\v2\z#)^2)

End Function
























;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every verlet and updates it;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Updateverlets()

For v.verlet = Each verlet
	
	If v\col = True Then
		v\col = False
		fric# = .5
	Else
		fric# = 1
	EndIf
	
	v\vx# = (v\x# - v\ox#)*fric#
	v\vy# = (v\y# - v\oy#)*fric#
	v\vz# = (v\z# - v\oz#)*fric#
	
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	
	v\x# = v\x# + v\vx#
	v\y# = v\y# + v\vy# - .004
	v\z# = v\z# + v\vz#
	
	
	For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx# = v\x# - vv\x#
				dy# = v\y# - vv\y#
				dz# = v\z# - vv\z#
				dist# = Sqr ( dx#*dx# + dy#*dy# + dz#*dz# )		
				If dist# < .6 Then
				
					
					Diffx# = ( dist# - .6 ) * ( dx# / dist# )
					Diffy# = ( dist# - .6 ) * ( dy# / dist# )
					Diffz# = ( dist# - .6 ) * ( dz# / dist# )

					v\x# = v\x# - Diffx# ;* .5
					v\y# = v\y# - Diffy# ;* .5
					v\z# = v\z# - Diffz# ;* .5

					vv\x# = vv\x# + Diffx# ;* .5
					vv\y# = vv\y# + Diffy# ;* .5
					vv\z# = vv\z# + Diffz# ;* .5
				EndIf 				
			EndIf
		Next 

;	If v\y# < 0 Then
;		v\y# = 0
;		v\col = True
;	EndIf
	
Next

End Function






















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every constraint and updates it;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function UpdateConstraints()

For i = 1 To 3

	For c.constraint = Each constraint
		mx# = ( c\v1\x# - c\v2\x# )
		my# = ( c\v1\y# - c\v2\y# )
		mz# = ( c\v1\z# - c\v2\z# )
		
		dist# = Sqr( (mx)^2 + (my)^2 + (mz)^2 )
		
		mx# = mx# / 2
		my# = my# / 2
		mz# = mz# / 2
		
		If dist# <> 0  Then
			dif# = (dist# - c\length#) / dist#
		EndIf
		
	;	If c\v1\col = False Or i > 5 Then
			c\v1\x# = c\v1\x# - dif# * mx#
			c\v1\y# = c\v1\y# - dif# * my#
			c\v1\z# = c\v1\z# - dif# * mz#
	;	EndIf
	;	If c\v2\col = False Or i > 5 Then
			c\v2\x# = c\v2\x# + dif# * mx#
			c\v2\y# = c\v2\y# + dif# * my#
			c\v2\z# = c\v2\z# + dif# * mz#
	;	EndIf
	Next

Next

End Function



















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all verlets;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Drawverlets()

For v.verlet = Each verlet
	
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
Next

End Function


















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all meshes;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function PositionPhysicsEntity()

For r.rigidbody = Each rigidbody
	PositionEntity r\ent,EntityX(r\c\piv),EntityY(r\c\piv),EntityZ(r\c\piv)
	
	;align mesh to verlet cage
	x# = EntityX( r\rf\piv ) - EntityX( r\lf\piv ) + EntityX( r\rb\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\lf\piv ) + EntityY( r\rb\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\lf\piv ) + EntityZ( r\rb\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#,1  
	x# = EntityX( r\rf\piv ) - EntityX( r\rb\piv ) + EntityX( r\lf\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\rb\piv ) + EntityY( r\lf\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\rb\piv ) + EntityZ( r\lf\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#, 3
Next

End Function





















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;tests all verlets for collisions;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Detectcollisions()

For v.verlet = Each verlet
	If EntityX(v\piv) <> v\x# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\x# = EntityX(v\piv)
	EndIf
	If EntityY(v\piv) <> v\y# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\y# = EntityY(v\piv)
	EndIf
	If EntityZ(v\piv) <> v\z# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\z# = EntityZ(v\piv)
	EndIf
Next

End Function






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;applies a force to given object;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function PApplyForce(ent,x#,y#,z#)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		For i = 0 To r\Verlnum
			r\verl[i]\ox# = r\verl[i]\ox# - x#
			r\verl[i]\oy# = r\verl[i]\oy# - y#
			r\verl[i]\oz# = r\verl[i]\oz# - z#
		Next
	EndIf
Next

End Function



Function PMoveEntity(ent,x#,y#,z#)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		For i = 0 To r\verlnum
			r\verl[cnt]\ox# = r\verl[cnt]\ox# + x#
			r\verl[cnt]\oy# = r\verl[cnt]\oy# + y#
			r\verl[cnt]\oz# = r\verl[cnt]\oz# + z#
			r\verl[cnt]\x# = r\verl[cnt]\x# + x#
			r\verl[cnt]\y# = r\verl[cnt]\y# + y#
			r\verl[cnt]\z# = r\verl[cnt]\z# + z#
		Next
	EndIf
Next

End Function



Function PPositionEntity(ent,x#,y#,z#)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		For i = 0 To r\verlnum
			r\verl[cnt]\ox# = x#
			r\verl[cnt]\oy# = y#
			r\verl[cnt]\oz# = z#
			r\verl[cnt]\x# = x#
			r\verl[cnt]\y# = y#
			r\verl[cnt]\z# = z#
		Next
	EndIf
Next

End Function



I was surprised that it is still very stable if you set the number of times in the constraint loop to 3

Here is a fun little demonstration of my physics engine

No terrain map required for this one. :)

Graphics3D 640,480,0,2
SeedRnd(MilliSecs())




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Temporary camera stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

piv = CreatePivot()
cam = CreateCamera(piv)
;CameraRange cam,.01,50
CameraZoom cam,2
MoveEntity cam,0,3,-30
lit = CreateLight()
TurnEntity lit,90,0,0

TurnEntity piv,20,0,0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




Global VerletType = 1					;Collision Types
Global RBodyType = 2
Global RigidBodyNum = 0
Global groundtype = 3

;Collisions VerletType,RBodyType,2,2  	;Sets Collision Types
;Collisions VerletType,VerletType,1,2
Collisions verletType,GroundType,2,2

Type Verlet								;Verlet type Contains:
	Field Active						;Determines if the verlet is an active verlet or a verlet used for orientation
	Field Mass#							;Gives the verlet a mass
	Field x#,y#,z#						;Gives the verlet an x,y,z cooridnate
	Field vx#,vy#,vz#					;Gives the verlet a velocity in 3d
	Field ox#,oy#,oz#					;Stores the old x,y,z coordinates to figure out the velocity of the verlet
	Field piv,ent						;Gives the verlet a pivot point and names the verlet's entity
	Field Col,ID,piv2,radius#			;Col tells if the verlet has collided yet and ID tells what entity and verlet group the verlet belongs to
End Type	

Type Constraint							;Constraints constrain the verlets to certain distances from eachother
	Field v1.verlet						;First verlet in constraint
	Field v2.verlet						;Second verlet in constraint
	Field length#						;Length of the constraint
End Type

Type Rigidbody										;Rigidbody is used as a reference for all of the verlets that belong to a mesh
	Field Ent										;Ent is the entity that is acting as the rigid body
	Field ID										;ID is the ID that all of the verlets in this mesh are attatched to
	Field x#,y#,z#									;X,Y,Z coordinates of the mesh
	Field Yaw#,pitch#,Roll#							;Yaw,Pitch,Roll coordinates of the mesh
	Field lf.verlet,lb.verlet,rf.verlet,rb.verlet	;The verlets that are inactive and are used to orient the mesh
	Field lfd.verlet,lbd.verlet,rfd.verlet,rbd.verlet;The verlets that are inactive and are used to orient the mesh	
	Field c.verlet,idl								;The central Verlet
	Field Verl.verlet[50],verlnum
End Type





SetBuffer BackBuffer()

ground = CreatePlane()
EntityColor ground,32,32,64
EntityAlpha ground,.9
EntityType ground,GroundType



rwall = CreateCube()
ScaleEntity rwall,.1,.8,10
MoveEntity rwall,5,.1,0

EntityType rwall,GroundType

lwall = CreateCube()
ScaleEntity lwall,.1,.8,10
MoveEntity lwall,-5,.1,0

EntityType lwall,GroundType

bwall = CreateCube()
ScaleEntity bwall,5,.8,.1
MoveEntity bwall,0,.1,-10

EntityType bwall,GroundType

fwall = CreateCube()
ScaleEntity fwall,5,.8,.1
MoveEntity fwall,0,.1,10

EntityType fwall,GroundType


obstacle = CreateCylinder(10)
MoveEntity obstacle,0,0,5

EntityType obstacle,GroundType


puck = CreateCylinder(8)
MoveEntity puck,0,.8,0
ScaleEntity puck,.3,.1,.3

applyphysics(puck,10,False,.2)



pl1 = CreateCylinder(10)
MoveEntity pl1,0,.8,-4
ScaleEntity pl1,.5,.2,.5
EntityColor pl1,255,0,0

applyphysics(pl1,10,False,.2)

CreateMirror()





timer = MilliSecs()

cnter = 0
While Not KeyDown(1)
Cls


If KeyDown(205) Then PApplyForce(pl1,.015,0,0)
If KeyDown(203) Then PApplyForce(pl1,-.015,0,0)
If KeyDown(200) Then PApplyForce(pl1,0,0,.015)
If KeyDown(208) Then PApplyForce(pl1,0,0,-.015)



UpdateVerlets()

UpdateConstraints()

DrawVerlets()

UpdateWorld()
detectcollisions()

drawverlets()

positionPhysicsEntity()

RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next

Text 1,1,cnt

cnter = cnter + 1
Text 1,20,"FPS: "+1000/((MilliSecs()-timer)/cnter)

Flip
Wend
End




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet bounding box & creates verlets;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function ApplyPhysics(ent,mass#,stationary,verlsize# = .3)

rigidbodynum = rigidbodynum + 1


;Creates the Rigidbody that all of the verlets are linked to

r.rigidbody = New rigidbody
r\id = rigidbodynum
r\ent = ent
r\x# = EntityX(r\ent)
r\y# = EntityY(r\ent)
r\z# = EntityZ(r\ent)
r\yaw# = EntityYaw(r\ent)
r\pitch# = EntityPitch(r\ent)
r\roll# = EntityRoll(r\ent)
EntityType r\ent,RBodyType
r\idl = stationary

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;






;Loops through all surfaces and verticies
For k = 1 To CountSurfaces(ent)
	surf = GetSurface(ent,k)
	For index = 0 To CountVertices(surf)-1
		TFormPoint VertexX(surf,index), VertexY(surf, index),VertexZ(surf, index), ent, 0
		CreateVerlet(TFormedX(),TFormedY(),TFormedZ(),mass#,ent,r\ID,True,verlsize#)   ;Creates a verlet for every vertice  Later it deletes duplicate verlets for the sake of stability.
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;Creates the bounding box verlets that don't react with anything but are used to orient the mesh

r\lf.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\lb.verlet = CreateVerlet(r\x# - .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\rf.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# + .5, 1 , ent , r\ID , False)

r\rb.verlet = CreateVerlet(r\x# + .5 , r\y# - .5, r\z# - .5, 1 , ent , r\ID , False)

r\lfd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\lbd.verlet = CreateVerlet(r\x# - .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\rfd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# + .5, 1 , ent , r\ID , False)

r\rbd.verlet = CreateVerlet(r\x# + .5 , r\y# + .5, r\z# - .5, 1 , ent , r\ID , False)

r\c.verlet = CreateVerlet(r\x# , r\y# , r\z#, 1 , ent , r\ID , False)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



;Deletes Duplicate verlets so that the meshes are more stable

For v.verlet = Each verlet
	For vv.verlet = Each verlet
		If vv\ID = v\ID Then
			If vv\piv <> v\piv Then
				If v\x# = vv\x# And v\y# = vv\y# And v\z# = vv\z# And vv\mass <> 0 And v\mass <> 0 Then
					FreeEntity vv\piv
					Delete vv.verlet
				EndIf
			EndIf
		EndIf
	Next
Next

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




cnt = 0
For v.verlet = Each verlet
	If V\ent = ent And V\Active = True Then
		R\Verl.verlet[cnt] = v.verlet
		cnt = cnt + 1
	EndIf
Next

r\Verlnum = cnt - 1


;This code makes constraints which it links every inside verlet to all eight of the outside verlets but no others

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If r\idl = False Then
			If v\active = True Then
				Createconstraint(v.verlet,r\rf.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rb.verlet)
				Createconstraint(v.verlet,r\lf.verlet)
				Createconstraint(v.verlet,r\lb.verlet)
				Createconstraint(v.verlet,r\rfd.verlet)              ;Creates constraint
				Createconstraint(v.verlet,r\rbd.verlet)
				Createconstraint(v.verlet,r\lfd.verlet)
				Createconstraint(v.verlet,r\lbd.verlet)
				Createconstraint(v.verlet,r\c.verlet)
				
			EndIf
		EndIf
	EndIf
Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




createconstraint(r\rf.verlet,r\c.verlet)
createconstraint(r\rb.verlet,r\c.verlet)
createconstraint(r\lf.verlet,r\c.verlet)
createconstraint(r\lb.verlet,r\c.verlet)
createconstraint(r\rfd.verlet,r\c.verlet)
createconstraint(r\rbd.verlet,r\c.verlet)
createconstraint(r\lfd.verlet,r\c.verlet)
createconstraint(r\lbd.verlet,r\c.verlet)

createconstraint(r\rf.verlet,r\rb.verlet)
createconstraint(r\rf.verlet,r\lf.verlet)
createconstraint(r\rf.verlet,r\lb.verlet)

createconstraint(r\rb.verlet,r\lb.verlet)
createconstraint(r\rb.verlet,r\lf.verlet)

createconstraint(r\lf.verlet,r\lb.verlet)


createconstraint(r\rfd.verlet,r\rbd.verlet)
createconstraint(r\rfd.verlet,r\lfd.verlet)
createconstraint(r\rfd.verlet,r\lbd.verlet)

createconstraint(r\rbd.verlet,r\lbd.verlet)
createconstraint(r\rbd.verlet,r\lfd.verlet)

createconstraint(r\lfd.verlet,r\lbd.verlet)


createconstraint(r\rf.verlet,r\rfd.verlet)
createconstraint(r\lf.verlet,r\lfd.verlet)
createconstraint(r\rb.verlet,r\rbd.verlet)
createconstraint(r\lb.verlet,r\lbd.verlet)

;Deletes duplicate Or reversed constraints  This speeds up the constraint loops very much

For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\v1\piv = cc\v1\piv And c\v2\piv = c\v1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





End Function














;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Creates a verlet at the given x,y,z coordinate;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function createverlet.verlet(x#,y#,z#,mass#,ent,ID,Active,radius# = .1)

	v.Verlet = New Verlet
	v\x# = x#
	v\y# = y#
	v\z# = z#
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	v\vx# = 0
	v\vy# = 0
	v\vz# = 0
	v\ent = ent
	v\ID = ID
	v\active = Active
	v\mass# = mass#
	v\radius# = radius#
	
	v\piv = CreatePivot()
	v\piv2 = CreatePivot()
	ScaleEntity v\piv,.2,.2,.2
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
	If active = True Then
		EntityType v\piv,VerletType
		EntityRadius v\piv,radius#
	EndIf
	
	Return v
End Function

















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;Constrains two verlets together;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function CreateConstraint(v1.verlet,v2.verlet)

	c.constraint = New constraint
	c\v1.verlet = v1.verlet
	c\v2.verlet = v2.verlet
	c\length# = Sqr((c\v1\x#-c\v2\x#)^2 + (c\v1\y#-c\v2\y#)^2 + (c\v1\z#-c\v2\z#)^2)

End Function
























;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every verlet and updates it;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Updateverlets()

For v.verlet = Each verlet
	
	If v\col = True Then
		v\col = False
		fric# = .95
	Else
		fric# = 1
	EndIf
	
	v\vx# = (v\x# - v\ox#)*fric#
	v\vy# = (v\y# - v\oy#)*fric#
	v\vz# = (v\z# - v\oz#)*fric#
	
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	
	v\x# = v\x# + v\vx#
	v\y# = v\y# + v\vy# - .004
	v\z# = v\z# + v\vz#
	
	
	For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx# = v\x# - vv\x#
				dy# = v\y# - vv\y#
				dz# = v\z# - vv\z#
				dist# = Sqr ( dx#*dx# + dy#*dy# + dz#*dz# )		
				totalr# = v\radius# + vv\radius#
				If dist# < totalr# Then
				
					
					Diffx# = ( dist# - totalr# ) * ( dx# / dist# )
					Diffy# = ( dist# - totalr# ) * ( dy# / dist# )
					Diffz# = ( dist# - totalr# ) * ( dz# / dist# )

					v\x# = v\x# - Diffx# ;* .5
					v\y# = v\y# - Diffy# ;* .5
					v\z# = v\z# - Diffz# ;* .5

					vv\x# = vv\x# + Diffx# ;* .5
					vv\y# = vv\y# + Diffy# ;* .5
					vv\z# = vv\z# + Diffz# ;* .5
				EndIf 				
			EndIf
		Next 

;	If v\y# < 0 Then
;		v\y# = 0
;		v\col = True
;	EndIf
	
Next

End Function






















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;goes through every constraint and updates it;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function UpdateConstraints()

For i = 1 To 3

	For c.constraint = Each constraint
		mx# = ( c\v1\x# - c\v2\x# )
		my# = ( c\v1\y# - c\v2\y# )
		mz# = ( c\v1\z# - c\v2\z# )
		
		dist# = Sqr( (mx)^2 + (my)^2 + (mz)^2 )
		
		mx# = mx# / 2
		my# = my# / 2
		mz# = mz# / 2
		
		If dist# <> 0  Then
			dif# = (dist# - c\length#) / dist# * .7
		EndIf
		
	;	If c\v1\col = False Or i > 5 Then
			c\v1\x# = c\v1\x# - dif# * mx#
			c\v1\y# = c\v1\y# - dif# * my#
			c\v1\z# = c\v1\z# - dif# * mz#
	;	EndIf
	;	If c\v2\col = False Or i > 5 Then
			c\v2\x# = c\v2\x# + dif# * mx#
			c\v2\y# = c\v2\y# + dif# * my#
			c\v2\z# = c\v2\z# + dif# * mz#
	;	EndIf
	Next

Next

End Function



















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all verlets;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Drawverlets()

For v.verlet = Each verlet
	
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
Next

End Function


















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;positions all meshes;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function PositionPhysicsEntity()

For r.rigidbody = Each rigidbody
	PositionEntity r\ent,EntityX(r\c\piv),EntityY(r\c\piv),EntityZ(r\c\piv)
	
	;align mesh to verlet cage
	x# = EntityX( r\rf\piv ) - EntityX( r\lf\piv ) + EntityX( r\rb\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\lf\piv ) + EntityY( r\rb\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\lf\piv ) + EntityZ( r\rb\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#,1  
	x# = EntityX( r\rf\piv ) - EntityX( r\rb\piv ) + EntityX( r\lf\piv ) - EntityX( r\lb\piv )
	y# = EntityY( r\rf\piv ) - EntityY( r\rb\piv ) + EntityY( r\lf\piv ) - EntityY( r\lb\piv )
	z# = EntityZ( r\rf\piv ) - EntityZ( r\rb\piv ) + EntityZ( r\lf\piv ) - EntityZ( r\lb\piv )
	AlignToVector r\ent, x#,y#,z#, 3
Next

End Function





















;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;tests all verlets for collisions;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function Detectcollisions()

For v.verlet = Each verlet
	If EntityX(v\piv) <> v\x# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\x# = EntityX(v\piv)
	EndIf
	If EntityY(v\piv) <> v\y# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\y# = EntityY(v\piv)
	EndIf
	If EntityZ(v\piv) <> v\z# Then
		If EntityCollided(v\piv,3) Then
			v\col = True
		EndIf
		v\z# = EntityZ(v\piv)
	EndIf
Next

End Function






;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;applies a force to given object;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Function PApplyForce(ent,x#,y#,z#)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		For i = 0 To r\Verlnum
			r\verl[i]\ox# = r\verl[i]\ox# - x#
			r\verl[i]\oy# = r\verl[i]\oy# - y#
			r\verl[i]\oz# = r\verl[i]\oz# - z#
		Next
	EndIf
Next

End Function



Function PMoveEntity(ent,x#,y#,z#)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		For i = 0 To r\verlnum
			r\verl[cnt]\ox# = r\verl[cnt]\ox# + x#
			r\verl[cnt]\oy# = r\verl[cnt]\oy# + y#
			r\verl[cnt]\oz# = r\verl[cnt]\oz# + z#
			r\verl[cnt]\x# = r\verl[cnt]\x# + x#
			r\verl[cnt]\y# = r\verl[cnt]\y# + y#
			r\verl[cnt]\z# = r\verl[cnt]\z# + z#
		Next
	EndIf
Next

End Function



Function PPositionEntity(ent,x#,y#,z#)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		For i = 0 To r\verlnum
			r\verl[cnt]\ox# = x#
			r\verl[cnt]\oy# = y#
			r\verl[cnt]\oz# = z#
			r\verl[cnt]\x# = x#
			r\verl[cnt]\y# = y#
			r\verl[cnt]\z# = z#
		Next
	EndIf
Next

End Function


hmm...

I probably should have put this in the blitz3d programming section rather than the b3d begginers area because it isn't really a beginner's topic but it is too late now. :(

yay it's awesome!

How would I make constraints to constrain the wheels to the car? This is very confusing.

Stevie on average how many verlets do you have per vehicle? I can't see each vehicle having a verlet for every vertex. Do you have 4 big verlets for each wheel or what?

P.S. I put my code in the code archives and gave you and pongo credit. :)

This is nice. I was pleasantly surprised considering you haven't been working on it all that long. I eventually managed to get the puck out of the constraining box too. ( I don't mean an error, it didn't go through the wall. I managed to get it moving fast enough that it bounced up and over. )

It is fun to play around with. If you change the createpivot to create sphere in the funciton create verlet, then you can see the verlets reacting with each other.

I plan to start making a game using it soon although it might be a few years before I get a demo out :)

P.S. This has been a very good learning experience for me. Thanks pongo and Stevie G!!! Good luck with polymaniacs can't wait to buy it :)