Physics engine

Blitz3D Forums/Blitz3D Beginners Area/Physics engine

Has anyone here ever made a simple physics engine before in B3d. I decided to make one just for a fun little project. If you have some simple code or helpful tips that would help please post them.

I know it wouldn't be very fast or efficient and it would take a while to program, but I have too much free time and it would help me to get more familliar with b3d. ;)

I'm working on one, but i'm stuck on vertex commands.

Yeah that's where it gets complicated. Can you post your code so far? I don't mind if it is incomplete.

[edit] Never mind

I have started on a new verlet physics engine myself,... I'm about to move things into 3d right now, but here is my 2d verlets for dummies code. Note: This is based on some code from the code archives, so some things may look similar to those. When I am trying to learn something new I strip it down to the very bare essentials and start building up to where I need it. This is about as basic as I can get it.

The next phase will involve getting collisions working between different objects. There are a few extra lines of code in here dealing with the collision code I have already started on.

Edit: see my following posts for a version with collisions, and a full 3d version as well.

Global screen_w = 640
Global screen_h = 480
Global gravity# = .25

Graphics screen_w,screen_h,0,2
SetBuffer BackBuffer()

;SeedRnd MilliSecs()
timer = CreateTimer (60) ; lock game fps to this

Type vector2
	Field x#
	Field y#
End Type

Type Verlet
	Field pos.vector2	; verlet position
	Field vel.vector2	; verlet velocity
	Field old.vector2 ; store the previous pos here
	Field radius ; size of verlet
	Field id ;use to identify groups
	Field collide ; is this colliding?
End Type

Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#
End Type 

Global circle=CreateImage (40,40)
Global circlehit=CreateImage (40,40)
initCircleGFX() ;create circle graphics

;For loop = 1 To 10
	definebox() ;create verlet box
;Next

;CreateVerlet.verlet (xpos,ypos,size,id)
Global v1.verlet = CreateVerlet (400,100,20,1)
Global v2.verlet = CreateVerlet(400,150,20,1)
Global v3.verlet = CreateVerlet (500,100,20,1)
Global v4.verlet = CreateVerlet(500,150,20,1)
ConstrainVerlet (v1,v2)
ConstrainVerlet(v2,v3)
ConstrainVerlet(v1,v3)
ConstrainVerlet(v1,v4)
ConstrainVerlet(v2,v4)
ConstrainVerlet(v3,v4)

While Not KeyHit(1)
	WaitTimer(Timer) ; Pause until the timer reaches 60 (caps the game framerate on faster systems)

	UpdateVerlets()
	UpdateConstraints()

	; move verlet 1 based on arrow keys
	v1\pos\y =	v1\pos\y + (KeyDown(208) - KeyDown(200) )*2
	v1\pos\x =	v1\pos\x + (KeyDown(205) - KeyDown(203) )*2

	If KeyHit(57)
		For v.verlet = Each verlet
			v\pos\y = v\pos\y - Rnd(1,20)
			v\pos\x = v\pos\x + Rnd(-5,5)
		Next
	EndIf 

	drawscreen()


	Flip()
	Cls()
Wend

End 

Function initCircleGFX()
	SetBuffer ImageBuffer(circle)
	Color 128,128,128
	Oval 0,0,40,40
	Color 0,255,0
	Oval 0,0,40,40,0
	MidHandle circle
	
	SetBuffer ImageBuffer(circlehit)
	Color 255,0,0
	Oval 0,0,40,40
	MidHandle circlehit
	SetBuffer BackBuffer()

	Color 255,255,255
End Function 

Function definebox()
	; define the shape and constraints
	;CreateVerlet.verlet (xpos,ypos,size,id)
	v1.verlet = CreateVerlet.verlet (100,100,20,num)
	v2.verlet = CreateVerlet.verlet (150,100,20,num)
	v3.verlet = CreateVerlet.verlet (100,150,20,num)
	v4.verlet = CreateVerlet.verlet (150,150,20,num)
	v5.verlet = CreateVerlet.verlet (100,200,20,num)
	v6.verlet = CreateVerlet.verlet (150,200,20,num)

	c.constraint = 	ConstrainVerlet	(v1,v2)
	c.constraint = 	ConstrainVerlet	(v2,v4)
	c.constraint = 	ConstrainVerlet	(v3,v4)
	c.constraint = 	ConstrainVerlet	(v3,v1)
	c.constraint = 	ConstrainVerlet	(v6,v1)
	c.constraint = 	ConstrainVerlet	(v2,v5)
	c.constraint = 	ConstrainVerlet	(v4,v6)
	c.constraint = 	ConstrainVerlet	(v5,v6)
	c.constraint = 	ConstrainVerlet	(v3,v5)
	c.constraint = 	ConstrainVerlet	(v3,v6)
	c.constraint = 	ConstrainVerlet	(v4,v1)

End Function

Function CreateVerlet.verlet (xpos,ypos,size,id)
	v.verlet=New verlet
	v\pos = New vector2
	v\pos\x = xpos
	v\pos\y = ypos
	v\vel = New vector2
	v\vel\x = 0
	v\vel\y = 0
	v\old = New vector2
	v\old\x = xpos
	v\old\y = ypos
	v\radius = size
	v\id = num

	Return v
End Function 

Function ConstrainVerlet.constraint (head.verlet,	tail.verlet)
	Local dx#,dy#

	;this creates a new constraint and sets the length equal to the current distance between the verlets
	c.constraint = New constraint
	c\p1.verlet = head.verlet
	c\p2.verlet = tail.verlet

	dx = c\p1\pos\x - c\p2\pos\x
	dy = c\p1\pos\y - c\p2\pos\y
	c\length = Sqr ( dx*dx + dy*dy )

	;DebugLog c\length
	Return c
End Function

Function UpdateVerlets()
	Local tx#,ty#
	For v.verlet = Each verlet
		v\collide = False
		v\vel\x = (v\pos\x - v\old\x)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vel\y = (v\pos\y - v\old\y)*.985

		v\old\x = v\pos\x ; store position in "old"
		v\old\y = v\pos\y

		v\pos\x = v\pos\x + v\vel\x ;store new postion based on velocity
		v\pos\y = v\pos\y + v\vel\y + gravity

		;check screen bounds
		If v\pos\x	>	screen_w - v\radius
			v\pos\x=screen_w - v\radius
			v\collide = True
		ElseIf v\pos\x	<	v\radius
			v\pos\x	=	v\radius
			v\collide = True
		EndIf
		If v\pos\y	>	screen_h - v\radius
			v\pos\y=screen_h - v\radius
			v\collide = True
		ElseIf v\pos\y	<	v\radius
			v\pos\y=	v\radius
			v\collide = True
		EndIf
	Next
End Function

Function UpdateConstraints()
	Local dx#,dy#,length#,diff#;,nx#,ny#,tx#,ty#

	For loop = 1 To 5 ;iterations
		For c.constraint = Each constraint
			dx=c\p2\pos\x	-	c\p1\pos\x
			dy=c\p2\pos\y	-	c\p1\pos\y
					
			length=Sqr(dx*dx+dy*dy) ; distance between p1 and p2
	
			If length<>0 ;avoid divide by 0, then normalize the vector
				diff = (length - c\length) / length ; vector length minus constraint length
			EndIf
	
			dx = dx * .5 ;find the midpoint
			dy = dy * .5
	
			c\p1\pos\x = c\p1\pos\x + diff * dx 
			c\p1\pos\y = c\p1\pos\y + diff * dy
	
			c\p2\pos\x = c\p2\pos\x - diff * dx
			c\p2\pos\y = c\p2\pos\y - diff * dy

		Next  ;constraints
	Next ;iterations
End Function 

Function DrawScreen()
	For v.verlet=Each verlet
		If v\collide = False
			DrawImage circle,v\pos\x,v\pos\y	; draw circle
			;Oval v\pos\x-v\radius,v\pos\y-v\radius,v\radius*2,v\radius*2,0 ;draw the actual radius (slow)
		Else
			DrawImage circlehit,v\pos\x,v\pos\y	; draw red circle if colliding
		EndIf		
	Next

	For c.constraint = Each constraint
		Line c\p1\pos\x,c\p1\pos\y,c\p2\pos\x,c\p2\pos\y
	Next 

	Text 10,10,"Use arrow keys to move V1, space bar for earthquake"
	Text v1\pos\x,v1\pos\y,"V1"
End Function


Another example ...

http://www.blitzbasic.com/codearcs/codearcs.php?code=2105

Thanks for the examples those will help. I will post my code when I get cubes working. :) Might be a few days.

Ok I Have a problem.

Here are my types

Type vertex
     Field mass
     Field x#,y#,z#
     Field vx#,vy#,vz#
End Type

Type rigidbody
     Field entity,x#,y#,z#
     Field xv#,yv#,zv#
     Field xrv#,yrv#,zrv#
     Field xr#,yr#,zr#
     Field mass#,cx#,cy#,cz#
     Field ID,IDL
     Field v1.vertex
End Type


How would I make some rigid bodies have 6 vertexes and others have 20 vertexes.

I guess you'll have to either roll your own linked list of vertices in the type or have an array of vertices in the type.

Here is my substitute for the slow meshesintersect function

Function NMeshesIntersect(e1,e2)

EntityPickMode e1,0
EntityPickMode e2,2

Surfaces=CountSurfaces(e1)
For s=1 To Surfaces
Surf = GetSurface(e1,s)

	Triangles=CountTriangles(Surf)-1
	For t=0 To Triangles
		
		v1 = TriangleVertex(surf,t,0)
		v2 = TriangleVertex(surf,t,1)
		v3 = TriangleVertex(surf,t,2)
		
		v1x# = VertexX(surf,v1)
		v1y# = VertexY(surf,v1)
		v1z# = VertexZ(surf,v1)
		
		v2x# = VertexX(surf,v2)
		v2y# = VertexY(surf,v2)
		v2z# = VertexZ(surf,v2)
		
		v3x# = VertexX(surf,v3)
		v3y# = VertexY(surf,v3)
		v3z# = VertexZ(surf,v3)
		
		tent = LinePick(v1x#,v1y#,v1z#,v2x#-v1x#,v2y#-v1y#,v2z#-v1z#)
		;If tent <> Null Then
			If tent = e2 Then
				Return True
			Else
				tent = LinePick(v2x#,v2y#,v2z#,v3x#-v2x#,v3y#-v2y#,v3z#-v2z#)
				;If tent <> Null Then
					If tent = e2 Then
						Return True
					Else
						tent = LinePick(v3x#,v3y#,v3z#,v1x#-v3x#,v1y#-v3y#,v1z#-v3z#)
						;If tent <> Null Then
							If tent = e2 Then
								Return True
							EndIf
						;EndIf
					EndIf
				;EndIf
			EndIf	
		;EndIf
	Next
Next

Return False

End Function


It works faster than meshesintersect on my computer. I can also use pickedx and pickedy and pickedz to determine where the collision was. I am currently trying to get it to figure out which vertex was hit.

You may already be on top of this, but you should also do a basic bounding box or radius check first, to see if you even need to calculate further.

Yes That's a good Idea I'll update it when I have that built in.

I just realized that you have to use positionmesh and rotatemesh rather than positionentity and rotateentity. Can someone fix this please?

How about a bit of code to look at? It would help to see what you are doing.

I've started adding collisions into the code I posted above, but things are not quite right yet. Collisions are working great, but the response is incorrect, so things tend to stick together. When I get this bit worked out I will post the updated code.

[EDIT]

As you just realised ..

Your intersection function will not work. Vertex info is in local space coords so you'd need to transform these into world space before doing the linepicks.

e.g.

This :

v1x# = VertexX(surf,v1)
v1y# = VertexY(surf,v1)
v1z# = VertexZ(surf,v1)

Should be :

tformpoint vertexx(surf,v1), vertexy(surf, v1),vertexz(surf,v1), e1, 0
v1x# = tformedx()
v1y# = tformedy()
v1z# = tformedz()

That said, it will be faaaaaaar too slow to use in game even using a broadphase bounding box or sphere checks. You'll need to rethink your collision detection as this method is not practical as you'll soon find out.

Stevie

Here is all of the code I have put together. Sorry nothing works yet. I just started doing this yesterday.

Graphics3D 640,480,0,2

cam = CreateCamera()
TurnEntity cam,45,0,0
MoveEntity cam,0,0,-5

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

Type vertex
	Field mass
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ID
End Type

Type rigidbody
	Field entity,x#,y#,z#
	Field xv#,yv#,zv#
	Field xrv#,yrv#,zrv#
	Field xr#,yr#,zr#
	Field mass#,cx#,cy#,cz#
	Field ID,IDL
End Type

Global Rigidbodycnt = 0

SetBuffer BackBuffer()

cube = NCreateCube()

While Not KeyDown(1)
Cls

NUpdateWorld()
RenderWorld()

Flip
Wend

Function NCreateCube(mass = 1,idl = 0)
	r.rigidbody = New rigidbody
	r\x# = 0
	r\y# = 0
	r\z# = 0
	r\xv# = 0
	r\yv# = 0
	r\zv# = 0
	r\xrv# = 0
	r\yrv# = 0
	r\zrv# = 0
	r\xr# = 0
	r\yr# = 0
	r\zr# = 0
	r\mass# = mass
	r\cx# = 0
	r\cy# = 0
	r\cz# = 0
	r\ID = rigidbodycnt
	rigidbodycnt = rigidbodycnt + 1
	r\entity = CreateCube()
	r\idl = idl
	
	Surfaces=CountSurfaces(r\entity)
	For s=1 To Surfaces
	Surf = GetSurface(r\entity,s)
	
		Triangles=CountTriangles(Surf)-1
		For t=0 To Triangles
		
		v1 = TriangleVertex(surf,t,0)
		v2 = TriangleVertex(surf,t,1)
		v3 = TriangleVertex(surf,t,2)
		
		v.vertex = New vertex
		v\x# = VertexX(surf,v1)
		v\y# = VertexY(surf,v1)
		v\z# = VertexZ(surf,v1)
		v\id = r\id
		v\mass# = r\mass#/(triangles*3)
		
		v11.vertex = New vertex
		v11\x# = VertexX(surf,v2)
		v11\y# = VertexY(surf,v2)
		v11\z# = VertexZ(surf,v2)
		v11\id = r\id
		v11\mass# = v\mass#
		
		v12.vertex = New vertex
		v12\x# = VertexX(surf,v3)
		v12\y# = VertexY(surf,v3)
		v12\z# = VertexZ(surf,v3)
		v12\mass# = v\mass#
		v12\id = r\id
		
		Next
	Next

	
	Return r\entity
End Function





Function NUpdateWorld()

For r.rigidbody = Each rigidbody
	For r1.rigidbody = Each rigidbody
		If r\ID <> r1\ID Then
			If NMeshesIntersect(r1\entity,r\entity)
				EntityColor r\entity,255,0,0         ;This is where it will do all of the physics for the entitys
													 ;I plan To use PickedTriangle To determine the force each vertex
													 ;has applied to it which I will use To determine speed And rotation.
			EndIf
		EndIf
	Next
Next

For r.rigidbody = Each rigidbody
PositionEntity r\entity,r\x#,r\y#,r\z#
r\x# = r\x# + r\xv#
r\y# = r\y# + r\yv#
r\z# = r\z# + r\zv#
Next

UpdateWorld()

End Function




Function NMeshesIntersect(e1,e2,radius# = 0)

EntityPickMode e1,0
EntityPickMode e2,2

If radius <> 0 Then
	If radius# > EntityDistance(e1,e2) Then


		Surfaces=CountSurfaces(e1)
		For s=1 To Surfaces
			Surf = GetSurface(e1,s)
		
			Triangles=CountTriangles(Surf)-1
			For t=0 To Triangles
				
				v1 = TriangleVertex(surf,t,0)
				v2 = TriangleVertex(surf,t,1)
				v3 = TriangleVertex(surf,t,2)
				
				TFormPoint VertexX(surf,v1), VertexY(surf, v1),VertexZ(surf,v1), e1, 0
				v1x# = TFormedX()
				v1y# = TFormedY()
				v1z# = TFormedZ()
				
				TFormPoint VertexX(surf,v2), VertexY(surf, v2),VertexZ(surf,v2), e1, 0
				v2x# = TFormedX()
				v2y# = TFormedY()
				v2z# = TFormedZ()
				
				TFormPoint VertexX(surf,v3), VertexY(surf, v3),VertexZ(surf,v3), e1, 0
				v3x# = TFormedX()
				v3y# = TFormedY()
				v3z# = TFormedZ()
				
				tent = LinePick(v1x#,v1y#,v1z#,v2x#-v1x#,v2y#-v1y#,v2z#-v1z#)
				;If tent <> Null Then
					If tent = e2 Then
						Return True
					Else
						tent = LinePick(v2x#,v2y#,v2z#,v3x#-v2x#,v3y#-v2y#,v3z#-v2z#)
						;If tent <> Null Then
							If tent = e2 Then
								Return True
							Else
								tent = LinePick(v3x#,v3y#,v3z#,v1x#-v3x#,v1y#-v3y#,v1z#-v3z#)
								;If tent <> Null Then
									If tent = e2 Then
										Return True
									EndIf
								;EndIf
							EndIf
						;EndIf
					EndIf	
				;EndIf
			Next
		Next
	EndIf
Else

	Surfaces=CountSurfaces(e1)
	For s=1 To Surfaces
		Surf = GetSurface(e1,s)
	
		Triangles=CountTriangles(Surf)-1
		For t=0 To Triangles
			
			v1 = TriangleVertex(surf,t,0)
			v2 = TriangleVertex(surf,t,1)
			v3 = TriangleVertex(surf,t,2)
			
			TFormPoint VertexX(surf,v1), VertexY(surf, v1),VertexZ(surf,v1), e1, 0
			v1x# = TFormedX()
			v1y# = TFormedY()
			v1z# = TFormedZ()
			
			TFormPoint VertexX(surf,v2), VertexY(surf, v2),VertexZ(surf,v2), e1, 0
			v2x# = TFormedX()
			v2y# = TFormedY()
			v2z# = TFormedZ()
			
			TFormPoint VertexX(surf,v3), VertexY(surf, v3),VertexZ(surf,v3), e1, 0
			v3x# = TFormedX()
			v3y# = TFormedY()
			v3z# = TFormedZ()
			
			tent = LinePick(v1x#,v1y#,v1z#,v2x#-v1x#,v2y#-v1y#,v2z#-v1z#)
			;If tent <> Null Then
				If tent = e2 Then
					Return True
				Else
					tent = LinePick(v2x#,v2y#,v2z#,v3x#-v2x#,v3y#-v2y#,v3z#-v2z#)
					;If tent <> Null Then
						If tent = e2 Then
							Return True
						Else
							tent = LinePick(v3x#,v3y#,v3z#,v1x#-v3x#,v1y#-v3y#,v1z#-v3z#)
							;If tent <> Null Then
								If tent = e2 Then
									Return True
								EndIf
							;EndIf
						EndIf
					;EndIf
				EndIf	
			;EndIf
		Next
	Next
EndIf

Return False

End Function


feel free to add to it please post your improvements.


stevie G, As I said in my first post, I know it will be slow, however I am just doing this for fun and for the experience. also it is pretty fast for now. 3 spheres colliding but not bouncing off of each other = 60-80fps

here is a version with working collisions between verlet objects.

Edit: updated code with Stevie's modification,... Thanks!

Global screen_w = 1024
Global screen_h = 768
Global gravity# = .25

Graphics screen_w,screen_h,0,2
SetBuffer BackBuffer()

;SeedRnd MilliSecs()
timer = CreateTimer (60) ; lock game fps to this

Type vector2
	Field x#
	Field y#
End Type

Type Verlet
	Field pos.vector2	; verlet position
	Field vel.vector2	; verlet velocity
	Field old.vector2 ; store the previous pos here
	Field radius ; size of verlet
	Field id ;use to identify groups
	Field collide ; is this colliding?
End Type

Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#
End Type 

Global circle=CreateImage (40,40)
Global circlehit=CreateImage (40,40)
initCircleGFX() ;create circle graphics

definebox(1) ;create verlet box

;CreateVerlet.verlet (xpos,ypos,size,id)
Global v1.verlet = CreateVerlet (400,100,20,10)
Global v2.verlet = CreateVerlet(400,150,20,10)
Global v3.verlet = CreateVerlet (500,100,20,10)
Global v4.verlet = CreateVerlet(500,150,20,10)

ConstrainVerlet (v1,v2)
ConstrainVerlet(v2,v3)
ConstrainVerlet(v1,v3)
ConstrainVerlet(v1,v4)
ConstrainVerlet(v2,v4)
ConstrainVerlet(v3,v4)

Global v5.verlet = CreateVerlet (600,100,20,20)
Global v6.verlet = CreateVerlet(650,150,20,20)
Global v7.verlet = CreateVerlet (700,200,20,20)
Global v8.verlet = CreateVerlet(750,250,20,20)

;ConstrainVerlet(v4,v5)
ConstrainVerlet(v5,v6)
ConstrainVerlet(v6,v7)
ConstrainVerlet(v7,v8)

While Not KeyHit(1)
	WaitTimer(Timer) ; Pause until the timer reaches 60 (caps the game framerate on faster systems)

	UpdateVerlets()
	UpdateConstraints()

	; move verlet 1 based on arrow keys
	v1\pos\y =	v1\pos\y + (KeyDown(208) - KeyDown(200) )*2
	v1\pos\x =	v1\pos\x + (KeyDown(205) - KeyDown(203) )*2

	If KeyHit(57)
		For v.verlet = Each verlet
			v\pos\y = v\pos\y - Rnd(1,20)
			v\pos\x = v\pos\x + Rnd(-5,5)
		Next
	EndIf 

	drawscreen()

	Flip()
	Cls()
Wend

End 

Function initCircleGFX()
	SetBuffer ImageBuffer(circle)
	Color 128,128,128
	Oval 0,0,40,40
	Color 0,255,0
	Oval 0,0,40,40,0
	MidHandle circle
	
	SetBuffer ImageBuffer(circlehit)
	Color 255,0,0
	Oval 0,0,40,40
	MidHandle circlehit
	SetBuffer BackBuffer()

	Color 255,255,255
End Function 

Function definebox(id=1)
	; define the shape and constraints
	;CreateVerlet.verlet (xpos,ypos,size,id)
	v1.verlet = CreateVerlet.verlet (100,100,20,id)
	v2.verlet = CreateVerlet.verlet (150,100,20,id)
	v3.verlet = CreateVerlet.verlet (100,150,20,id)
	v4.verlet = CreateVerlet.verlet (150,150,20,id)
	v5.verlet = CreateVerlet.verlet (100,200,20,id)
	v6.verlet = CreateVerlet.verlet (150,200,20,id)

	c.constraint = 	ConstrainVerlet	(v1,v2)
	c.constraint = 	ConstrainVerlet	(v2,v4)
	c.constraint = 	ConstrainVerlet	(v3,v4)
	c.constraint = 	ConstrainVerlet	(v3,v1)
	c.constraint = 	ConstrainVerlet	(v6,v1)
	c.constraint = 	ConstrainVerlet	(v2,v5)
	c.constraint = 	ConstrainVerlet	(v4,v6)
	c.constraint = 	ConstrainVerlet	(v5,v6)
	c.constraint = 	ConstrainVerlet	(v3,v5)
	c.constraint = 	ConstrainVerlet	(v3,v6)
	c.constraint = 	ConstrainVerlet	(v4,v1)

End Function

Function CreateVerlet.verlet (xpos,ypos,size,id)
	v.verlet=New verlet
	v\pos = New vector2
	v\pos\x = xpos
	v\pos\y = ypos
	v\vel = New vector2
	v\vel\x = 0
	v\vel\y = 0
	v\old = New vector2
	v\old\x = xpos
	v\old\y = ypos
	v\radius = size
	v\id = id

	Return v
End Function 

Function ConstrainVerlet.constraint (head.verlet,	tail.verlet)
	Local dx#,dy#

	;this creates a new constraint and sets the length equal to the current distance between the verlets
	c.constraint = New constraint
	c\p1.verlet = head.verlet
	c\p2.verlet = tail.verlet

	dx = c\p1\pos\x - c\p2\pos\x
	dy = c\p1\pos\y - c\p2\pos\y
	c\length = Sqr ( dx*dx + dy*dy )

	;DebugLog c\length
	Return c
End Function

Function UpdateVerlets()
	Local dx#,dy#,dist#
	For v.verlet = Each verlet
		v\collide = False
		v\vel\x = (v\pos\x - v\old\x)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vel\y = (v\pos\y - v\old\y)*.985

		v\old\x = v\pos\x ; store position in "old"
		v\old\y = v\pos\y

		v\pos\x = v\pos\x + v\vel\x ;store new postion based on velocity
		v\pos\y = v\pos\y + v\vel\y + gravity



For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx = v\pos\x - vv\pos\x
				dy = v\pos\y - vv\pos\y
				dist = Sqr ( dx*dx + dy*dy )
				TotalRadius# = v\radius + vv\radius		
				If dist < Totalradius
				
					
					Diffx# = ( dist - TotalRadius ) * ( dx / dist )
					Diffy# = ( dist - TotalRadius ) * ( dy / dist )
				
					;to do list
					;get the velocities of v And vv
					;use them to find the new vectors for v and vv 
					
					v\pos\x = v\pos\x - Diffx ;* .5
					v\pos\y = v\pos\y - Diffy ;* .5
					vv\pos\x = vv\pos\x + Diffx ;* .5
					vv\pos\y = vv\pos\y + Diffy ;* .5

					v\collide = True
				EndIf 				
			EndIf
		Next 


		;check screen bounds
		If v\pos\x	>	screen_w - v\radius
			v\pos\x=screen_w - v\radius
			v\collide = True
		ElseIf v\pos\x	<	v\radius
			v\pos\x	=	v\radius
			v\collide = True
		EndIf
		If v\pos\y	>	screen_h - v\radius
			v\pos\y=screen_h - v\radius
			v\collide = True
		ElseIf v\pos\y	<	v\radius
			v\pos\y=	v\radius
			v\collide = True
		EndIf
	Next
End Function

Function UpdateConstraints()
	Local dx#,dy#,length#,diff#

	For loop = 1 To 5 ;iterations
		For c.constraint = Each constraint
			dx=c\p2\pos\x	-	c\p1\pos\x
			dy=c\p2\pos\y	-	c\p1\pos\y
					
			length=Sqr(dx*dx+dy*dy) ; distance between p1 and p2
	
			If length<>0 ;avoid divide by 0, then normalize the vector
				diff = (length - c\length) / length ; vector length minus constraint length
			EndIf
	
			dx = dx * .5 ;find the midpoint
			dy = dy * .5
	
			c\p1\pos\x = c\p1\pos\x + diff * dx 
			c\p1\pos\y = c\p1\pos\y + diff * dy
	
			c\p2\pos\x = c\p2\pos\x - diff * dx
			c\p2\pos\y = c\p2\pos\y - diff * dy

		Next  ;constraints
	Next ;iterations
End Function 

Function DrawScreen()
	For v.verlet=Each verlet
		If v\collide = False
			DrawImage circle,v\pos\x,v\pos\y	; draw circle
			;Oval v\pos\x-v\radius,v\pos\y-v\radius,v\radius*2,v\radius*2,0 ;draw the actual radius (slow)
		Else
			DrawImage circlehit,v\pos\x,v\pos\y	; draw red circle if colliding
		EndIf		
	Next

	For c.constraint = Each constraint
		Line c\p1\pos\x,c\p1\pos\y,c\p2\pos\x,c\p2\pos\y
	Next 

	Text 10,10,"Use arrow keys to move V1, space bar for earthquake"
	Text v1\pos\x,v1\pos\y,"V1"
End Function



How can I calculate the rotation velocities of an object after it is hit.

Here is how I calculated the x y and z velocities for the mesh as a whole.

I averaged all of the vertex's x, y, and z velocities to get the final x, y, and z velocity. This makes the movement of the rigid body's look natural however I can't figure out how to make them spin naturally.

Here is the code I figured out the velocities with.

avgx# = 0
avgy# = 0
avgz# = 0
cnt = 0
For v.vertex = Each vertex
	If v\id = r\id Then
		cnt = cnt + 1
		avgx# = avgx# + v\vx
		avgy# = avgy# + v\vy
		avgz# = avgz# + v\vz
	EndIf
Next
r\xv# = avgx#/cnt
r\yv# = avgy#/cnt
r\zv# = avgz#/cnt
r\x# = r\x# + r\xv#
r\y# = r\y# + r\yv#
r\z# = r\z# + r\zv#


Sorry Troy, couldn't resist ..

For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx = v\pos\x - vv\pos\x
				dy = v\pos\y - vv\pos\y
				dist = Sqr ( dx*dx + dy*dy )
				TotalRadius# = v\radius + vv\radius		
				If dist < Totalradius
				
					
					Diffx# = ( dist - TotalRadius ) * ( dx / dist )
					Diffy# = ( dist - TotalRadius ) * ( dy / dist )
				
					;to do list
					;get the velocities of v And vv
					;use them to find the new vectors for v and vv 

					;for now just do a quick cheat
					
					v\pos\x = v\pos\x - Diffx * .5
					v\pos\y = v\pos\y - Diffy * .5
					vv\pos\x = vv\pos\x + Diffx * .5
					vv\pos\y = vv\pos\y + Diffy * .5
					
					
			;		v\pos\x = v\old\x - v\vel\x
			;		v\pos\y = v\old\y - v\vel\y
			;		vv\pos\x = vv\old\x + v\vel\x
			;		vv\pos\y = vv\old\y + v\vel\y

					v\collide = True
				EndIf 				
			EndIf



I am assuming that figuring out the yaw pitch and roll velocities will require calculus which is a bit above my head considering I am in 9th grade. (taking pre calculus next year) :)

Stevie,... that's what I was looking for,... thanks. Can't believe how close I was several times. I have updated the code above to include this, and it's working nice now.

Nate,...you really won't need to figure out any of that if you use a verlet system like the one I have posted, or the link that Stevie gave earlier. Knowledge of how vectors work will help.

Verlets are a very good physics solution that do not require heavy cpu, and can also be easily adjusted for softbodies as well. Here is my quick explanation of how they work.

With a verlet system, you work with the physics at the point level, rather than calculating out all the rotations. At the core of a verlet system is just a system that allows individual verlets (particles) to move with physics like velocity, mass, gravity,...etc. None of these have rotation, and are simply points in space. Next is where the magic happens,... the constraint system. This simply links verlets together at a certain distance. You can make these more elastic, but for simplicity now lets just call them fixed distance. The constraint system cycles through each link, and moves each appropriate verlet towards or away from it's linked verlet. This is done several times per loop, and the result is that the other verlets get pulled around by the overall mass.

Let's walk through a simple example of a square.
1. first, the lower right verlet has a force applied to it, and it moves to the right. This is the verlet update phase, and none of the other verlets move.
2. now the square no longer looks like a square, because the verlet is out of position.
3. now we run the constraint system. This will adjust all of the edges to the correct length again. By doing this, each time you adjust one side, another will be off a bit, but this is ok. What ends up happening is like an averaging of the mass, and moving a single point will pull around the entire mass with a rotational force. This is why we run the constraint system several times per loop. (If you only had 2 points, it would be perfect after one loop, but more points are going to squish around a bit more.) Usually a number between 5 and 10 is sufficient.

Hope this helps and doesn't confuse more. I would try to diagram this, but don't have a way of posting images right now.

Thanks pongo. I will try your method of verlets but the only flaw I can see is that if you make the sides long enough the verlets just pass through the lines inbetween verlets. I am inexperienced in this field but I like your explanation.

I think mabey to move it into 3d and eliminate the flaw with the verlets going through the linesegments, you could do a linepick between the verlet's old xyz and its new xyz to see if it went through something.

maybe this could be a community project so people that just started learning blitz3d could see how a physics engine might work. Please post your code if you convert it to 3d It would be neet to see how it works out.

Wow. Programming a 3d verlet system is very easy compared to the way I did it. Thanks pongo!!!

P.S. I will post the code when I get basic physics and constraints.(may be a few days)

Here's the 3d version. I'm really happy with this so far, but I still have a long way to go.

If you plan your verlets, you should not have to worry about the line intersections. You can increase the radius of the verlets to close the gaps. Try changing my code so that the verlets are a size 10 instead of size 3 and you will see what I mean.

for example,...change this
Global v1.verlet = CreateVerlet (10,0,10,3,1)

to this
Global v1.verlet = CreateVerlet (10,0,10,10,1)

Remember that these would be invisible in the final code, and would drive the rotation of a mesh object. I have made the verlets and constraints visible just for the sake of seeing things work. Also, the verlets only need to represent to basic shape of the more complex object and things will work well.


Global screen_w = 1024
Global screen_h = 768
Global gravity# = .25

Graphics3D screen_w,screen_h,0,2
SetBuffer BackBuffer()

SeedRnd MilliSecs()
timer = CreateTimer (60) ; lock game fps to this

Type vector3
	Field x#
	Field y#
	Field z#
End Type

Type Verlet
	Field pos.vector3	; verlet position
	Field vel.vector3	; verlet velocity
	Field old.vector3 ; store the previous pos here
	Field radius ; size of verlet
	Field id ;use to identify groups
	Field collide ; is this colliding?
	Field pivot ; pivot for operations
End Type

Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#
	Field mesh ; display line
End Type 

campivot = CreatePivot()
cam = CreateCamera(campivot)
CameraZoom cam,2
MoveEntity cam,0,200,500
PointEntity cam,campivot

light = CreateLight()
;PositionEntity light,0,100,-50
RotateEntity light,90,0,0

Global arenabounds = 200

wall1 = CreateCube()
PositionEntity wall1,-arenabounds,0,0
ScaleEntity wall1,1,1,arenabounds
wall2 = CreateCube()
PositionEntity wall2,arenabounds,0,0
ScaleEntity wall2,1,1,arenabounds
wall3 = CreateCube()
PositionEntity wall3,0,0,arenabounds
ScaleEntity wall3,arenabounds,1,1
wall4 = CreateCube()
PositionEntity wall4,0,0,-arenabounds
ScaleEntity wall4,arenabounds,1,1

ground = CreatePlane()
EntityColor ground,32,32,64
EntityAlpha ground, .9
mirror = CreateMirror()

definePyramid()

;CreateVerlet.verlet (xpos,ypos,size,id)
Global v1.verlet = CreateVerlet (10,0,10,8,1)
Global v2.verlet = CreateVerlet(10,0,-10,8,1)
Global v3.verlet = CreateVerlet (-10,0,10,8,1)
Global v4.verlet = CreateVerlet(-10,0,-10,8,1)
Global v5.verlet = CreateVerlet(0,20,0,8,1)

ConstrainVerlet (v1,v2)
ConstrainVerlet(v2,v3)
ConstrainVerlet(v1,v3)
ConstrainVerlet(v1,v4)
ConstrainVerlet(v2,v4)
ConstrainVerlet(v3,v4)
ConstrainVerlet(v1,v5)
ConstrainVerlet(v2,v5)
ConstrainVerlet(v3,v5)
ConstrainVerlet(v4,v5)

EntityColor v1\pivot,160,32,32

While Not KeyHit(1)
	WaitTimer(Timer) ; Pause until the timer reaches 60 (caps the game framerate on faster systems)

	; move verlet 1 based on arrow keys
	v1\pos\z =	v1\pos\z + (KeyDown(208) - KeyDown(200) ) * .8
	v1\pos\x =	v1\pos\x + (KeyDown(203) - KeyDown(205) ) * .8
	v1\pos\y =  	v1\pos\y + KeyDown(57) * 2

	UpdateVerlets()
	UpdateConstraints()
	positionstuff()

	UpdateWorld()
	RenderWorld()

	Text 20,20,"use arrow keys and space bar to move verlet cage"

	Flip()
	Cls()
Wend

End 


Function definePyramid()
;CreateVerlet.verlet (xpos,ypos,size,id)
v11.verlet = CreateVerlet (10,20,10,8,2)
v12.verlet = CreateVerlet(10,20,-10,8,2)
v13.verlet = CreateVerlet (-10,20,10,8,2)
v14.verlet = CreateVerlet(-10,20,-10,8,2)
v15.verlet = CreateVerlet(0,40,0,8,2)

ConstrainVerlet (v11,v12)
ConstrainVerlet(v12,v13)
ConstrainVerlet(v11,v13)
ConstrainVerlet(v11,v14)
ConstrainVerlet(v12,v14)
ConstrainVerlet(v13,v14)
ConstrainVerlet(v11,v15)
ConstrainVerlet(v12,v15)
ConstrainVerlet(v13,v15)
ConstrainVerlet(v14,v15)
End Function

Function CreateVerlet.verlet (xpos,ypos,zpos,size,id)
	v.verlet=New verlet
	v\pos = New vector3
	v\pos\x = xpos
	v\pos\y = ypos
	v\pos\z = zpos
	v\vel = New vector3
	v\vel\x = 0
	v\vel\y = 0
	v\vel\z = 0
	v\old = New vector3
	v\old\x = xpos
	v\old\y = ypos
	v\old\z = zpos
	v\radius = size
	v\id = id

	v\pivot = CreateSphere()
	ScaleEntity v\pivot,size,size,size
	Return v
End Function 

Function ConstrainVerlet.constraint (head.verlet,	tail.verlet)
	Local dx#,dy#,dz#

	;this creates a new constraint and sets the length equal to the current distance between the verlets
	c.constraint = New constraint
	c\p1.verlet = head.verlet
	c\p2.verlet = tail.verlet

	dx = c\p1\pos\x - c\p2\pos\x
	dy = c\p1\pos\y - c\p2\pos\y
	dz = c\p1\pos\z - c\p2\pos\z
	c\length = Sqr ( dx*dx + dy*dy + dz*dz )
	
	c\mesh = CreateCube()
	ScaleEntity c\mesh,.2,.2,c\length * .5
	PositionMesh c\mesh,0,0,1
	;DebugLog c\length
	Return c
End Function

Function UpdateVerlets()
	Local dx#,dy#,dz#,dist#
	For v.verlet = Each verlet
		v\collide = False
		v\vel\x = (v\pos\x - v\old\x)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vel\y = (v\pos\y - v\old\y)*.985
		v\vel\z = (v\pos\z - v\old\z)*.985

		v\old\x = v\pos\x ; store position in "old"
		v\old\y = v\pos\y
		v\old\z = v\pos\z
		
		v\pos\x = v\pos\x + v\vel\x ;store new postion based on velocity
		v\pos\y = v\pos\y + v\vel\y - gravity
		v\pos\z = v\pos\z + v\vel\z


For vv.verlet = Each verlet
			If v <> vv And v\id <> vv\id; if not the same verlet or group
				dx = v\pos\x - vv\pos\x
				dy = v\pos\y - vv\pos\y
				dz = v\pos\z - vv\pos\z
				dist = Sqr ( dx*dx + dy*dy + dz*dz)
				TotalRadius# = v\radius + vv\radius		
				If dist < Totalradius
				
					
					Diffx# = ( dist - TotalRadius ) * ( dx / dist )
					Diffy# = ( dist - TotalRadius ) * ( dy / dist )
					Diffz# = ( dist - TotalRadius ) * ( dz / dist )

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

					vv\pos\x = vv\pos\x + Diffx ;* .5
					vv\pos\y = vv\pos\y + Diffy ;* .5
					v\pos\z = v\pos\z - Diffz ;* .5

					v\collide = True
				EndIf 				
			EndIf
		Next 


		;check screen bounds
		If v\pos\y	<	v\radius ;ground collision
			v\pos\y=	v\radius
			v\collide = True
		EndIf

		If v\pos\x >arenabounds Then v\pos\x = arenabounds
		If v\pos\x < -arenabounds Then v\pos\x = -arenabounds
		If v\pos\z >arenabounds Then v\pos\z = arenabounds
		If v\pos\z < -arenabounds Then v\pos\z = -arenabounds
		
	Next
End Function

Function UpdateConstraints()
	Local dx#,dy#,dz#,length#,diff#

	For loop = 1 To 5 ;iterations
		For c.constraint = Each constraint
			dx=c\p2\pos\x	-	c\p1\pos\x
			dy=c\p2\pos\y	-	c\p1\pos\y
			dz=c\p2\pos\z	-	c\p1\pos\z
					
			length=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2
	
			If length<>0 ;avoid divide by 0, then normalize the vector
				diff = (length - c\length) / length ; vector length minus constraint length
			EndIf
	
			dx = dx * .5 ;find the midpoint
			dy = dy * .5
			dz = dz * .5
	
			c\p1\pos\x = c\p1\pos\x + diff * dx 
			c\p1\pos\y = c\p1\pos\y + diff * dy
			c\p1\pos\z = c\p1\pos\z + diff * dz

			c\p2\pos\x = c\p2\pos\x - diff * dx
			c\p2\pos\y = c\p2\pos\y - diff * dy
			c\p2\pos\z = c\p2\pos\z - diff * dz

		Next  ;constraints
	Next ;iterations
End Function 

Function positionstuff()
		For v.verlet = Each verlet
			EntityColor v\pivot,255,255,255
			If v\collide = True Then	EntityColor v\pivot,128,0,0
			PositionEntity v\pivot, v\pos\x, v\pos\y, v\pos\z
		Next

		For c.constraint = Each constraint
			PositionEntity c\mesh, c\p1\pos\x, c\p1\pos\y, c\p1\pos\z
			PointEntity c\mesh ,c\p2\pivot
		Next
End Function


Ok I have a bad bug!!!

Here is the code. You should see the bug if you run it.

P.S. I borrowed some code from you, pongo. Thanks!

Graphics3D 640,480,0,2

cam = CreateCamera()
MoveEntity cam,0,5,-20
CameraZoom cam,1.6

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,surf,index
	Field collided,ID,mass#
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#,flex
	Field rnglow#
	Field rnghig#
End Type

Global rigidbodynum = 0

cube = CreateCube()

Applyphysics(cube,10)

SetBuffer BackBuffer()

While Not KeyDown(1)
Cls

updateconstraints()
updateverlets()

UpdateWorld()
RenderWorld()
Flip
Wend
WaitKey

Function Applyphysics(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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
		v.verlet = New verlet
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\vy# = -.03
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				c.constraint = New constraint
				c\p1.verlet = v.verlet
				c\p2.verlet = vv.verlet
				dx# = c\p1\x# - c\p2\x#
				dy# = c\p1\y# - c\p2\y#
				dz# = c\p1\z# - c\p2\z#
				c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
			Next
		EndIf
	EndIf
Next

End Function



Function updateverlets()

For v.verlet = Each verlet
	VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	v\x# = v\x# + v\vx#
	v\y# = v\y# + v\vy#
	v\z# = v\z# + v\vz#
Next

End Function



Function updateconstraints()

For a = 1 To 20
For c.constraint = Each constraint
	dx# = c\p1\x# - c\p2\x#
	dy# = c\p1\y# - c\p2\y#
	dz# = c\p1\z# - c\p2\z#
	dist# = Sqr(dx#^2 + dy#^2 + dz#^2)
	If dist# <> c\length# Then
		mx# = c\p1\x# + c\p2\x#
		my# = c\p1\y# + c\p2\y#
		mz# = c\p1\z# + c\p2\z#
		
		mx# = mx# / 2
		my# = my# / 2
		mz# = mz# / 2
		
		If c\length# <> 0 Then
			scl# = (c\length#-dist#)/c\length# + 1
			dx# = c\p1\x#-mx#
			dy# = c\p1\y#-my#
			dz# = c\p1\z#-mz#
			c\p1\x# = c\p1\x# + dx#*scl#
			c\p1\y# = c\p1\y# + dy#*scl#
			c\p1\z# = c\p1\z# + dz#*scl#
			c\p2\x# = c\p2\x# - dx#*scl#
			c\p2\y# = c\p2\y# - dy#*scl#
			c\p2\z# = c\p2\z# - dz#*scl#
		Else
			c\p1\x# = mx#
			c\p1\y# = my#
			c\p1\z# = mz#
			c\p2\x# = mx#
			c\p2\y# = my#
			c\p2\z# = mz#
		EndIf
		
	EndIf
Next
Next

End Function


Hurray I solved the problem by combining our code!!!

to do list:

1. get collisions working (might have to use more of your code) :)
2. make it so there are never any dark lines down the edges of the mesh (small bug)
3. get mass to affect collisions

Graphics3D 640,480,0,2

cam = CreateCamera()
MoveEntity cam,0,5,-20
CameraZoom cam,1.6

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,surf,index
	Field collided,ID,mass#
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#,flex
	Field rnglow#
	Field rnghig#
End Type

Global rigidbodynum = 0

cube = CreateCube()

Applyphysics(cube,10)

SetBuffer BackBuffer()

While Not KeyDown(1)
Cls

updateconstraints()
updateverlets()

UpdateWorld()
RenderWorld()
Flip
Wend
WaitKey

Function Applyphysics(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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
		v.verlet = New verlet
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\vy# = -.03
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				c.constraint = New constraint
				c\p1.verlet = v.verlet
				c\p2.verlet = vv.verlet
				dx# = c\p1\x# - c\p2\x#
				dy# = c\p1\y# - c\p2\y#
				dz# = c\p1\z# - c\p2\z#
				c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
			Next
		EndIf
	EndIf
Next

End Function



Function updateverlets()

For v.verlet = Each verlet
	VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	v\ox# = v\x#
	v\oy# = v\y#
	v\oz# = v\z#
	v\x# = v\x# + v\vx#
	v\y# = v\y# + v\vy#
	v\z# = v\z# + v\vz#
Next

End Function



Function updateconstraints()

For a = 1 To 20
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5

		c\p1\x# = c\p1\x# + diff# * dx# 
		c\p1\y# = c\p1\y# + diff# * dy#
		c\p1\z# = c\p1\z# + diff# * dz#
		c\p2\x# = c\p2\x# - diff# * dx#
		c\p2\y# = c\p2\y# - diff# * dy#
		c\p2\z# = c\p2\z# - diff# * dz#
	Next  ;constraints
Next

End Function


Feel free to use as much of it as you need, that's why I posted it.

This is my first verlet engine. I started writing it just a few days ago, but I've been kicking ideas around in my head for quite a while. I found that developing things in 2d first helped me out quite a bit. It was a very simple matter to move into 3d once things were working.

Here are a few suggestions I have.
-Consider building primitive cages of verlets instead of using the whole mesh. It may work ok for cubes, but will struggle with more complex geometry.

-you don't need to connect every verlet to every other verlet. Too many constraints will hurt performance, however you will need enough to make sure the structure does not collapse on itself. This is a bit of trial and error as well as drawing things out on paper.

-Mass can be done on the verlet level. This lets you do things like have a heavy verlet in the base to keep things right side up. You can also do a light verlet that has the opposite effect.

pongo Thanks for all of the advice. I was working on building a program that figured out the most efficient constraints to use. Also you do need quite a lot of constraints to keep blacklines from forming on the seems of your mesh. This is why I connected every verlet to every other verlet on the cube.

here is the most recent version. The only problem is that the cube deforms as it hits.

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


cam = CreateCamera()
MoveEntity cam,0,0,-12
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent piv,cam

plane = CreatePlane()
tex = CreateTexture(200,200)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,100,100,1
Rect 100,100,100,100
Color 0,225,0
Rect 0,100,100,100
Rect 100,0,100,100
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,surf,index
	Field collided,ID,mass#
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#,flex
	Field rnglow#
	Field rnghig#
End Type

Global rigidbodynum = 0

cube = CreateCube()
RotateMesh cube,Rnd(90),Rnd(90),Rnd(90)
Applyphysics(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()

While Not KeyDown(1)
Cls

updateverlets()

updateconstraints()

drawstuff()

UpdateWorld()
RenderWorld()

Text 1,1,1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysics(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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
		v.verlet = New verlet
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\vy = .1
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				c.constraint = New constraint
				c\p1.verlet = v.verlet
				c\p2.verlet = vv.verlet
				dx# = c\p1\x# - c\p2\x#
				dy# = c\p1\y# - c\p2\y#
				dz# = c\p1\z# - c\p2\z#
				c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
			Next
		EndIf
	EndIf
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
	
	Next


End Function



Function drawstuff()
	For v.verlet = Each verlet
		VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	Next
End Function


Function updateconstraints()

For a = 1 To 20
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

End Function


Here is the version that automatically takes away the black lines and some of the squashing. :)

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


cam = CreateCamera()
MoveEntity cam,0,0,-12
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent piv,cam

plane = CreatePlane()
tex = CreateTexture(200,200)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,100,100,1
Rect 100,100,100,100
Color 0,225,0
Rect 0,100,100,100
Rect 100,0,100,100
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,surf,index
	Field collided,ID,mass#
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field length#,flex
	Field rnglow#
	Field rnghig#
End Type

Global rigidbodynum = 0

cube = CreateCube()
RotateMesh cube,Rnd(90),Rnd(90),Rnd(90)
Applyphysics(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()

While Not KeyDown(1)
Cls

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

Text 1,1,1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysics(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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
		v.verlet = New verlet
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\vy = .1
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				c.constraint = New constraint
				c\p1.verlet = v.verlet
				c\p2.verlet = vv.verlet
				dx# = c\p1\x# - c\p2\x#
				dy# = c\p1\y# - c\p2\y#
				dz# = c\p1\z# - c\p2\z#
				c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
			Next
		EndIf
	EndIf
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
	
	Next


End Function



Function drawstuff()
	For v.verlet = Each verlet
		VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	Next
End Function


Function updateconstraints()

For a = 1 To 20
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

End Function



Function equalizeverlets()

For c.constraint = Each constraint
	If c\length# = 0 Then
		dx#=c\p2\x#	+	c\p1\x#
		dy#=c\p2\y#	+	c\p1\y#
		dz#=c\p2\z#	+	c\p1\z#
		
		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		c\p2\x# = dx#
		c\p2\y# = dy#
		c\p2\z# = dz#
		
		c\p1\x# = dx#
		c\p1\y# = dy#
		c\p1\z# = dz#
		
	EndIf
Next

End Function


I think you still need to change how you are doing things. Right now you are manipulating the individual vertices of the mesh which is going to be slowing you down. That is also why the black lines are appearing, because you are pulling the faces apart a bit. You are also using a very high number of iterations, which will slow things down as well. Higher iterations are more accurate, but can be time expensive.

Here is how I would suggest to change things.
- Don't manipulate the vertices of your mesh.

- instead, build a verlet cage that is not rendered, and attach the mesh to it. By doing this you do not need to edit your mesh on the vertex level, since it is merely along for the ride, and the verlets are doing all the work. This way, the verlet cage may flex a bit, but your object will not. Verlets will naturally flex a bit, but the beauty of the system is that it will correct itself over time.

Hope this is making sense.

Makes perfect sense thanks.

How would I build a verlet cage and attatch the mesh to it? That is a good idea considering that if you change the Createcube() to Createcylinder(32), it is not only slow but makes the cylinder look liquidy the only problem is that I have no idea of how to attach a mesh to the verlet cage.

also if you haven't noticed manipulating the vertices makes the lighting of the mesh mess up

p.s. On your verlet program, are you going to take out the verlet radius thing because it seems like that might cause things to start looking funny in 3d for example, a cube might look like it was floating in mid air just above the ground.

This is very interesting. I have created a 2d physics engine that is totally different from this verlet thingy. It uses vectors that create the outline of the object and uses line intersects to detect collisions. No 3d commands are used, so it is not tied to meshes. Objects have mass points, that sum up to total mass and they are used to calculate inertia also.

I'm not sure what this verlet thing is ideal for. Do I understand correctly, that it isn't good for fully rigid objects? For bouncy objects this is kinda nice idea, like a variation of the rubber band force.

I use a verlet hybrid for both of the below. As you can see, with a bit of effort - it works just fine with rigid bodies. I only use 4 iterations of the contraint relaxation routines and it's very stable.

http://www.blitzbasic.co.nz/Community/posts.php?topic=80032

http://www.blitzbasic.co.nz/Community/posts.php?topic=71891#804067

Thanks for this thread guys, and pongo for your code. I've always been interested in verlet physics, as it seems pretty customisable. You have explained it quite well :o)

The reason I started to make my own physics engine is because I was inspired to by polymaniacs. Can you post some of the code for the physics in polymaniacs or tell me how it works exactly.

P.S. still working on the physics engine :)

Can you post some of the code for the physics in polymaniacs or tell me how it works exactly.


I can't post any code at this point - I've spend a looong time getting to this point and until I finish my game I'll need to keep my secrets. Besides, without seeing how it all hangs together in it's entirety, specific functions wouldn't make much sense to you.

That said, it isn't a million miles away from what Pongo is doing although I am correctly applying external forces ( friction / drag / gravity / thrust / lift / buoyancy etc.. ) and have a load of functions to prevent verlet cages braking, body/body collisions, turning physics off on static objects and self-righting vehicles.

Keep in there with Troy - he knows what he's doing and you will understand it better having built it from the ground up.

Stevie

can't post any code at this point - I've spend a looong time getting to this point and until I finish my game I'll need to keep my secrets.


I can understand that. It's nice to know that someone has already done what I am trying to do so I know it is possible.

P.S. I really like your physics in your game and wanted to compliment you on how realistic it looks. I am having trouble aligning the meshes to their verlet cages though. I might have to rethink how I am doing this

Hey,... I've got some things to add, but unfortunately not enough time to write them up right now. (at work)


Keep in there with Troy - he knows what he's doing and you will understand it better having built it from the ground up.


Thanks for the support! You are the inspiration for most everyone in here.


I'm still in the process of building things here, so I want to get it right before I go adding things. Right now I'm going to be changing things a bit so that verlets will be children of another type,... that will be where I will store the group ID and the mesh that will be attached to the cage.

I am actively working on this, but the next few days might be a bit crazy for me (Wife and I are expecting our 3rd child any day now)

Jasu- any examples you can post? I'm interested in seeing how it works.

Ok I don't have a lot of time for the next few days (math and english tests)

Off topic -is it a Boy or Girl?

It's a,.... surprise! We have a boy and a girl already, so we wanted to have the surprise this time.

Depending on how things go, I'm either going to have a lot of free time, or very little free time. You can probably judge by how far I get with this over the next week or so.

Yeah From my experience babies can be quite time consuming. Good luck! :)

P.S. Got hit by a hurricane Ahhhhh! I love getting hit by hurricanes because the wind is so fast and there is no damage where we live because as it hit us, it turned into a tropical storm! You may call me crazy but I love going outside when the wind is blowing really fast yet nothing gets hurt.

P.S.S. big Umbrellas + Hurricane = pull you off the ground. This really happens! Learned the hard way

I can't even imagine what a hurricane must be like, but we lost our roof and garage due to a tornado 2 years ago. One of the scariest things I've been through, and we had about 30 seconds of warning.

Anyways, to get back on topic,... I'm building a new verlet cage the uses a cube instead of the pyramid that is in the code above. Those will be my main cages that physics are applied to, since they will fit most objects in some fashion.

For the linking the mesh, you can use the verlet positions. There is an example of this in the blitz samples,... the driver.bb file in the mak directory specifically. In that example, a mesh body is aligned to four wheels. It is the same process to link a mesh body to a verlet cage.

Here is the code section that does the aligning

	;align car to wheels
	zx#=(EntityX( wheels[2],True )+EntityX( wheels[4],True ))/2
	zx=zx-(EntityX( wheels[1],True )+EntityX( wheels[3],True ))/2
	zy#=(EntityY( wheels[2],True )+EntityY( wheels[4],True ))/2
	zy=zy-(EntityY( wheels[1],True )+EntityY( wheels[3],True ))/2
	zz#=(EntityZ( wheels[2],True )+EntityZ( wheels[4],True ))/2
	zz=zz-(EntityZ( wheels[1],True )+EntityZ( wheels[3],True ))/2
	AlignToVector car,zx,zy,zz,1
	
	zx#=(EntityX( wheels[1],True )+EntityX( wheels[2],True ))/2
	zx=zx-(EntityX( wheels[3],True )+EntityX( wheels[4],True ))/2
	zy#=(EntityY( wheels[1],True )+EntityY( wheels[2],True ))/2
	zy=zy-(EntityY( wheels[3],True )+EntityY( wheels[4],True ))/2
	zz#=(EntityZ( wheels[1],True )+EntityZ( wheels[2],True ))/2
	zz=zz-(EntityZ( wheels[3],True )+EntityZ( wheels[4],True ))/2
	AlignToVector car,zx,zy,zz,3


What is happening here is that you need to get a vector along the x axis, align the mesh, and then get a z vector and align it again.

There is something terribly wrong with my program. It is something about the atan2 math. If you can't figure it out then I guess I'll use your method which I don't quite get.

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


cam = CreateCamera()
MoveEntity cam,0,0,-12
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent cam,piv

plane = CreatePlane()
tex = CreateTexture(200,200)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,100,100,1
Rect 100,100,100,100
Color 0,225,0
Rect 0,100,100,100
Rect 100,0,100,100
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,surf,index
	Field collided,ID,mass#
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#,flex
	Field rnglow#
	Field rnghig#
	Field yaw#,pitch#,roll#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
RotateMesh cube,0,0,44;Rnd(90),Rnd(90),Rnd(90)
Applyphysics(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

TurnEntity piv,0,1,0


updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysics(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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
		v.verlet = New verlet
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next

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)



For v.verlet = Each verlet
	For vv.verlet = Each verlet
		If vv\id = rigidbodynum And v\id = vv\id And v\index <> vv\index Then
			If vv\x# = v\x# And vv\y# = v\y# And vv\z# = v\z# Then
				Delete vv.verlet
			EndIf
		EndIf
	Next
Next

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\index <> v\index
						c.constraint = New constraint
						c\p1.verlet = v.verlet
						c\p2.verlet = vv.verlet
						dx# = c\p1\x# - c\p2\x#
						dy# = c\p1\y# - c\p2\y#
						dz# = c\p1\z# - c\p2\z#
						c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
						c\roll# = ATan2(c\p1\y#-c\p2\y#,c\p1\x#-c\p2\x#)
						c\pitch# = ATan2(c\p1\z#-c\p2\z#,c\p1\x#-c\p2\x#)
						c\roll# = ATan2(c\p1\y#-c\p2\y#,c\p1\x#-c\p2\x#)
						c\ent = c\p1\ent
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
Next


End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw# =0
		avgpitch# = 0
		avgroll# = 0
		For c.constraint = Each constraint
			If c\p1\ent = r\ent
				cnt = cnt + 1
				tmpang# = ATan2(c\p1\y#-c\p2\y#,c\p1\x#-c\p2\x#)
				avgroll# = avgroll# + (tmpang# - c\roll#)
				tmpang# = ATan2(c\p1\z#-c\p2\z#,c\p1\x#-c\p2\x#)
				avgpitch# = avgpitch# + (tmpang# - c\pitch#)
				tmpang# = ATan2(c\p1\y#-c\p2\y#,c\p1\x#-c\p2\x#)
				avgyaw# = avgyaw# + (tmpyaw# - c\yaw#)
			EndIf
		Next
		avgroll# = avgroll# / cnt
		avgpitch# = avgpitch# / cnt
		avgyaw# = avgyaw# / cnt
		RotateEntity r\ent,avgyaw#,avgpitch#,avgroll#
	Next
End Function


Function updateconstraints()

For a = 1 To 2
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



p.s. Hurricanes last forever... well mabe 12 hours of rain and wind isn't forever but it is pretty long

How would I use the aligntovector command? I don't get how I could put it in my code. You might be buisy but could you(pongo) or anyone else put it in my code or your code so I can understand it better? Also If someone knows what is wrong with the math in my program could you change it so it is right. I don't know exactly how to use atan2 Thanks

P.S. How did you solve this problem stevie? Are we going about it the right way?

Ok I got the physics rotation working, it just has one flaw :(

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


cam = CreateCamera()
MoveEntity cam,0,0,-12
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent cam,piv

plane = CreatePlane()
tex = CreateTexture(200,200)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,100,100,1
Rect 100,100,100,100
Color 0,225,0
Rect 0,100,100,100
Rect 100,0,100,100
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,surf,index
	Field collided,ID,mass#
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#,flex
	Field rnglow#
	Field rnghig#
	Field yaw#,pitch#,roll#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
RotateMesh cube,0,0,44;Rnd(90),Rnd(90),Rnd(90)
Applyphysics(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

TurnEntity piv,0,1,0


updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysics(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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
		v.verlet = New verlet
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next

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)



For v.verlet = Each verlet
	For vv.verlet = Each verlet
		If vv\id = rigidbodynum And v\id = vv\id And v\index <> vv\index Then
			If vv\x# = v\x# And vv\y# = v\y# And vv\z# = v\z# Then
				Delete vv.verlet
			EndIf
		EndIf
	Next
Next

For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\index <> v\index
						c.constraint = New constraint
						c\p1.verlet = v.verlet
						c\p2.verlet = vv.verlet
						dx# = c\p1\x# - c\p2\x#
						dy# = c\p1\y# - c\p2\y#
						dz# = c\p1\z# - c\p2\z#
						c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
						c\ent = c\p1\ent
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\p1\index = cc\p1\index And c\p2\index = c\p1\index Then
			Delete cc.constraint
		EndIf
	Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
Next


End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		For c.constraint = Each constraint
			If c\p1\ent = r\ent
				If cnt = 0 Then
					dx# = c\p1\x#-c\p2\x#
					dy# = c\p1\y#-c\p2\y#
					dz# = c\p1\z#-c\p2\z#
					AlignToVector c\p1\ent,dx#,dy#,dz#,1,1
				EndIf
				If cnt = 1 Then
					dx# = c\p1\x#-c\p2\x#
					dy# = c\p1\y#-c\p2\y#
					dz# = c\p1\z#-c\p2\z#
					AlignToVector c\p1\ent,dx#,dy#,dz#,3,1
				EndIf
			
	;			If cnt = 2 Then
	;				yaw# = EntityYaw(c\p1\ent)
	;				pitch# = EntityPitch(c\p1\ent)
	;				roll# = EntityRoll(c\p1\ent)
	;				yaw# = yaw# + c\yaw#
	;				pitch# = pitch# + c\pitch
	;			EndIf
					cnt = cnt + 1
			EndIf
		Next
		
	Next
End Function


Function updateconstraints()

For a = 1 To 2
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function


Yes, this is how I also do it.

0 = center
5 = top front left
6 = top front right
7 = top rear right
8 = top rear left


;align mesh to verlet cage
			PositionEntity b\Align , EntityX( b\p[0]\pivot ) , EntityY( b\p[0]\pivot ) , EntityZ( b\p[0]\pivot )
			x# = EntityX( b\p[6]\pivot ) - EntityX( b\p[5]\pivot ) + EntityX( b\p[7]\pivot ) - EntityX( b\p[8]\pivot )
			y# = EntityY( b\p[6]\pivot ) - EntityY( b\p[5]\pivot ) + EntityY( b\p[7]\pivot ) - EntityY( b\p[8]\pivot )
			z# = EntityZ( b\p[6]\pivot ) - EntityZ( b\p[5]\pivot ) + EntityZ( b\p[7]\pivot ) - EntityZ( b\p[8]\pivot )
			AlignToVector b\Align, x,y,z,1  
			x# = EntityX( b\p[6]\pivot ) - EntityX( b\p[7]\pivot ) + EntityX( b\p[5]\pivot ) - EntityX( b\p[8]\pivot )
			y# = EntityY( b\p[6]\pivot ) - EntityY( b\p[7]\pivot ) + EntityY( b\p[5]\pivot ) - EntityY( b\p[8]\pivot )
			z# = EntityZ( b\p[6]\pivot ) - EntityZ( b\p[7]\pivot ) + EntityZ( b\p[5]\pivot ) - EntityZ( b\p[8]\pivot )
			AlignToVector b\Align, x,y,z, 3


Thanks Stevie G!! Just what I was looking for but haven't gotten a chance to try it yet. Will modify my code to fit yours thanks! :)

P.S. Has rained constantly for 48 hours(predicted 24 more hours) and I only have electricity for a little while until another car crashes into a telephone pole Has happened 3 times already and lost electricity each time Hurricane season :(

You need to lose adding a verlet at each mesh vertex as it's too impractical. For example, a standard create consists of 24 unwelded vertices, so has 3 verlets for each corner and none in the center so isn't stable. You only need 9 and this will fit most shapes.

@Pongo

What sort of examples you want? I have my physics engine implemented in a game I'm working on and it's currently in a status that I don't want to share it around. In a few weeks maybe.

Also there are so much physics code there, that it isn't good idea to put it all here. I'm not even sure do I want to reveal the inner workings of the game just yet. In code level that is.

Here are the basics on how it is built:
- All objects are built of vectors creating the outlines, and points of mass which are used to calculate total mass, center of mass and inertia
- Collisions are detected by checking line intersects between outlines of two objects
- When a collision is detected, object positions are back tracked to a moment when objects barely touched each other. Then I calculate collision normal (very hard thing to do) and use collision response math to get new directional and rotational velocities for both objects.
- There's also functions to calculate forces on objects. As my game takes place in space, I'm talking about thrusters on space ships. Basically it calculates effects on directional and rotational velocities when a certain amount of directional force is applied on a point on the object. The same code is used to apply directional thrusters (ahead, reverse, strafe) and rotational thrusters (turn left, turn right). It's just a matter of placement and alignment of the thruster to determine the outcome (effect on speed and rotation).

The engine is simple (compared to physics libs out there) and fast. I can have 20 AI players and 200 asteroids floating around and colliding with each other, still having game logic calculation in around 4-7 ms. And about half of that is used by AI...

@ Jasu, I assume you use SAT to calculate the collision stuff.

The shapes the vectors create are not convex hulls. So projection cannot be used. I had to go with the intersections.

Sounds good - when are we going to see it in action - can you post a video?

Collision demo, no sound, captured with fraps (a little less than 2MB download)

If you want to see action, here's some: Scish gameplay

Sorry about poor quality of picture and sound.

Not bad. I can't really see the need for complex collision detection though. Maybe I'm missing something but most of the objects there look like they could be handled as sphere / sphere or sphere / capsule and still be accurate enough in the heat of battle.

Here is my verlet code that allows the object to align itself to the verlets. Has some serious flaws

Edit: I think it is something to do with aligning the cube using stevie's method

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


cam = CreateCamera()
MoveEntity cam,0,0,-12
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
tex = CreateTexture(200,200)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,100,100,1
Rect 100,100,100,100
Color 0,225,0
Rect 0,100,100,100
Rect 100,0,100,100
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

;TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

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)

r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#-MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2
r\v1\oy# = r\y#-MeshHeight(r\ent)/2-.9
r\v1\oz# = r\z#-MeshDepth(r\ent)/2
r\v1\ent = r\ent
r\v1\mass# = mass#/8
r\v1\piv = CreatePivot()
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#-MeshWidth(r\ent)/2
r\v2\y# = r\y#+MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#-MeshWidth(r\ent)/2
r\v2\oy# = r\y#+MeshHeight(r\ent)/2-.3
r\v2\oz# = r\z#+MeshDepth(r\ent)/2
r\v2\ent = r\ent
r\v2\mass# = mass#/8
r\v2\piv = CreatePivot()
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#-MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#+MeshDepth(r\ent)/2
r\v3\ox# = r\x#-MeshWidth(r\ent)/2
r\v3\oy# = r\y#-MeshHeight(r\ent)/2-.5
r\v3\oz# = r\z#+MeshDepth(r\ent)/2
r\v3\ent = r\ent
r\v3\mass# = mass#/8
r\v3\piv = CreatePivot()
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#+MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#+MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = mass#/8
r\v4\piv = CreatePivot()
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#+MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#+MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2
r\v5\ent = r\ent
r\v5\mass# = mass#/8
r\v5\piv = CreatePivot()
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#-MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#-MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = mass#/8
r\v6\piv = CreatePivot()
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#-MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#-MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = mass#/8
r\v7\piv = CreatePivot()
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#+MeshWidth(r\ent)/2
r\v8\y# = r\y#-MeshHeight(r\ent)/2
r\v8\z# = r\z#+MeshDepth(r\ent)/2
r\v8\ox# = r\x#+MeshWidth(r\ent)/2
r\v8\oy# = r\y#-MeshHeight(r\ent)/2
r\v8\oz# = r\z#+MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = mass#/8
r\v8\piv = CreatePivot()
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						c.constraint = New constraint
						c\p1.verlet = v.verlet
						c\p2.verlet = vv.verlet
						dx# = c\p1\x# - c\p2\x#
						dy# = c\p1\y# - c\p2\y#
						dz# = c\p1\z# - c\p2\z#
						c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
						c\ent = c\p1\ent
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


;For c.constraint = Each constraint
;	For cc.constraint = Each constraint
;		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
;			Delete cc.constraint
;		EndIf
;	Next
;Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
Next


End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v4\piv ) - EntityX( r\v3\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v4\piv ) - EntityY( r\v3\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v4\piv ) - EntityZ( r\v3\piv )
			AlignToVector r\ent, x#,y#,z#,1  
		;	x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v4\piv ) - EntityX( r\v3\piv )
		;	y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v4\piv ) - EntityY( r\v3\piv )
		;	z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v4\piv ) - EntityZ( r\v3\piv )
			AlignToVector r\ent, x#,y#,z#, 3

			
		
	Next
End Function


Function updateconstraints()

For a = 1 To 5
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function


Jasu- Nice!

I wasn't particularly interested in anything specific, just the overall technique. It sounds a lot like something I had looked into a while back. Right now I'm pretty focused on the verlet technique, but I like to spread my knowledge when I can.

I haven't gotten anything done the last few nights,... trying to wrap up all the loose ends at work before I'm gone for a bit.

Jasu-I can't get the avi to work!!!??? I'm not sure what is wrong. I am trying to open it in Vista

The avi is XVid, so you need a codec that can play it. Like ffdshow. I didn't want to put this on youtube because of the poor quality and fraps logo.

I know the collision detection is a bit of an overkill for this game type, but this is not a commercial project, so the purpose is not to do things easy/quick way. It's for learning stuff and a personal playground. It has my own physics engine, my own particle system, bitmap font system, data archiving system, AI code, pathfinding... well, all of it.

@ Nate - why have you commented out the second part of the alignment process? This is probably why it doesn't work.

It was just the same as the other part. wasn't it?

No - it's not the same - what on earth would be the point in that?! Have a closer look at what I posted.

Stevie.

Ohhhhh...

thanks stevie will change my code later buisy right now bye

Solved the problem sorry stevie g I got the vertex's mixed up now it works!!! :)

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


cam = CreateCamera()
MoveEntity cam,0,0,-12
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

;TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 0

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)

r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#-MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2
r\v1\oy# = r\y#-MeshHeight(r\ent)/2-.9
r\v1\oz# = r\z#-MeshDepth(r\ent)/2
r\v1\ent = r\ent
r\v1\mass# = mass#/8
r\v1\piv = CreateSphere()
EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#-MeshWidth(r\ent)/2
r\v2\y# = r\y#+MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#-MeshWidth(r\ent)/2
r\v2\oy# = r\y#+MeshHeight(r\ent)/2-.3
r\v2\oz# = r\z#+MeshDepth(r\ent)/2
r\v2\ent = r\ent
r\v2\mass# = mass#/8
r\v2\piv = CreateSphere()
EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#-MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#+MeshDepth(r\ent)/2
r\v3\ox# = r\x#-MeshWidth(r\ent)/2
r\v3\oy# = r\y#-MeshHeight(r\ent)/2-.5
r\v3\oz# = r\z#+MeshDepth(r\ent)/2
r\v3\ent = r\ent
r\v3\mass# = mass#/8
r\v3\piv = CreateSphere()
EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#+MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#+MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = mass#/8
r\v4\piv = CreateSphere()
EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#+MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#+MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2
r\v5\ent = r\ent
r\v5\mass# = mass#/8
r\v5\piv = CreateSphere()
EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#-MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#-MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = mass#/8
r\v6\piv = CreateSphere()
EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#-MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#-MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = mass#/8
r\v7\piv = CreateSphere()
EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#+MeshWidth(r\ent)/2
r\v8\y# = r\y#-MeshHeight(r\ent)/2
r\v8\z# = r\z#+MeshDepth(r\ent)/2
r\v8\ox# = r\x#+MeshWidth(r\ent)/2
r\v8\oy# = r\y#-MeshHeight(r\ent)/2
r\v8\oz# = r\z#+MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = mass#/8
r\v8\piv = CreateSphere()
EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						c.constraint = New constraint
						c\p1.verlet = v.verlet
						c\p2.verlet = vv.verlet
						dx# = c\p1\x# - c\p2\x#
						dy# = c\p1\y# - c\p2\y#
						dz# = c\p1\z# - c\p2\z#
						c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
						c\ent = c\p1\ent
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


;For c.constraint = Each constraint
;	For cc.constraint = Each constraint
;		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
;			Delete cc.constraint
;		EndIf
;	Next
;Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
Next


End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			x# = EntityX( r\v5\piv ) - EntityX( r\v2\piv ) + EntityX( r\v6\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v2\piv ) + EntityY( r\v6\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v2\piv ) + EntityZ( r\v6\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v2\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v2\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v2\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#, 3
			

			
		
	Next
End Function


Function updateconstraints()

For a = 1 To 5
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# / 2 ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

For a = 1 To 3
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length# ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function


Here is improved code with camera movement and the verlets are spheres they are unstable for some reason. so it messes up the physics :(

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


cam = CreateCamera()
MoveEntity cam,0,0,-30
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1
If KeyDown(203) Then MoveEntity cam,-.1,0,0
If KeyDown(205) Then MoveEntity cam,.1,0,0

;TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 1

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)

r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#-MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2-.9
r\v1\oy# = r\y#-MeshHeight(r\ent)/2-.2
r\v1\oz# = r\z#-MeshDepth(r\ent)/2-.1
r\v1\ent = r\ent
r\v1\mass# = mass#/8
r\v1\piv = CreateSphere()
EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#-MeshWidth(r\ent)/2
r\v2\y# = r\y#+MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#-MeshWidth(r\ent)/2-.3
r\v2\oy# = r\y#+MeshHeight(r\ent)/2-.5
r\v2\oz# = r\z#+MeshDepth(r\ent)/2-.1
r\v2\ent = r\ent
r\v2\mass# = mass#/8
r\v2\piv = CreateSphere()
EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#-MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#+MeshDepth(r\ent)/2
r\v3\ox# = r\x#-MeshWidth(r\ent)/2-.5
r\v3\oy# = r\y#-MeshHeight(r\ent)/2-.1
r\v3\oz# = r\z#+MeshDepth(r\ent)/2-.5
r\v3\ent = r\ent
r\v3\mass# = mass#/8
r\v3\piv = CreateSphere()
EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#+MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#+MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = mass#/8
r\v4\piv = CreateSphere()
EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#+MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#+MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2
r\v5\ent = r\ent
r\v5\mass# = mass#/8
r\v5\piv = CreateSphere()
EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#-MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#-MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = mass#/8
r\v6\piv = CreateSphere()
EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#-MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#-MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = mass#/8
r\v7\piv = CreateSphere()
EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#+MeshWidth(r\ent)/2
r\v8\y# = r\y#-MeshHeight(r\ent)/2
r\v8\z# = r\z#+MeshDepth(r\ent)/2
r\v8\ox# = r\x#+MeshWidth(r\ent)/2
r\v8\oy# = r\y#-MeshHeight(r\ent)/2
r\v8\oz# = r\z#+MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = mass#/8
r\v8\piv = CreateSphere()
EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						c.constraint = New constraint
						c\p1.verlet = v.verlet
						c\p2.verlet = vv.verlet
						dx# = c\p1\x# - c\p2\x#
						dy# = c\p1\y# - c\p2\y#
						dz# = c\p1\z# - c\p2\z#
						c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
						c\ent = c\p1\ent
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
Next


End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			x# = EntityX( r\v5\piv ) - EntityX( r\v2\piv ) + EntityX( r\v6\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v2\piv ) + EntityY( r\v6\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v2\piv ) + EntityZ( r\v6\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v2\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v2\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v2\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#, 3
			

			
		
	Next
End Function


Function updateconstraints()

For a = 1 To 10
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length#  ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function



Just change alph to 0 in the function applyphysicscube if you want to make the spheres go away.

Tired,... so very tired. Big news though,...

Gabriella Rose,... born 8:08 am this morning. Started around 1:00 last night. Off to sleep now,...hope to rejoin the living soon!

Nate,...I'll take a look at what's going on when I am better able to think.

So its a girl :)

Ok I think there is a slight flaw in the code that allows the verticies that are touching the ground to slip a little because it only updates their position if they are not touching the ground Good luck with the baby! :)

I seem to have fixed the problem by allowing transformation after a certain loop.

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


cam = CreateCamera()
MoveEntity cam,0,0,-30
CameraZoom cam,1.6

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1
If KeyDown(203) Then MoveEntity cam,-.1,0,0
If KeyDown(205) Then MoveEntity cam,.1,0,0

;TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 0

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)

r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#-MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2-.9
r\v1\oy# = r\y#-MeshHeight(r\ent)/2-.2
r\v1\oz# = r\z#-MeshDepth(r\ent)/2-.1
r\v1\ent = r\ent
r\v1\mass# = mass#/8
r\v1\piv = CreateSphere()
EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#-MeshWidth(r\ent)/2
r\v2\y# = r\y#+MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#-MeshWidth(r\ent)/2-.3
r\v2\oy# = r\y#+MeshHeight(r\ent)/2-.5
r\v2\oz# = r\z#+MeshDepth(r\ent)/2-.1
r\v2\ent = r\ent
r\v2\mass# = mass#/8
r\v2\piv = CreateSphere()
EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#-MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#+MeshDepth(r\ent)/2
r\v3\ox# = r\x#-MeshWidth(r\ent)/2-.5
r\v3\oy# = r\y#-MeshHeight(r\ent)/2-.1
r\v3\oz# = r\z#+MeshDepth(r\ent)/2-.5
r\v3\ent = r\ent
r\v3\mass# = mass#/8
r\v3\piv = CreateSphere()
EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#+MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#+MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = mass#/8
r\v4\piv = CreateSphere()
EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#+MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#+MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2
r\v5\ent = r\ent
r\v5\mass# = mass#/8
r\v5\piv = CreateSphere()
EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#-MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#-MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = mass#/8
r\v6\piv = CreateSphere()
EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#-MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#-MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = mass#/8
r\v7\piv = CreateSphere()
EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#+MeshWidth(r\ent)/2
r\v8\y# = r\y#-MeshHeight(r\ent)/2
r\v8\z# = r\z#+MeshDepth(r\ent)/2
r\v8\ox# = r\x#+MeshWidth(r\ent)/2
r\v8\oy# = r\y#-MeshHeight(r\ent)/2
r\v8\oz# = r\z#+MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = mass#/8
r\v8\piv = CreateSphere()
EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						c.constraint = New constraint
						c\p1.verlet = v.verlet
						c\p2.verlet = vv.verlet
						dx# = c\p1\x# - c\p2\x#
						dy# = c\p1\y# - c\p2\y#
						dz# = c\p1\z# - c\p2\z#
						c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
						c\ent = c\p1\ent
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.985
		v\vz# = (v\z# - v\oz#)*.985

		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
		v\x# = v\x# + v\vx# ;store new postion based on velocity
		
		v\y# = v\y# + v\vy# - .007
		
		v\z# = v\z# + v\vz#
		
		;check screen bounds
		If v\y#	< -4 ;ground collision
			v\y# = -4
			v\collided = True
			v\vy# = -v\vy#
		EndIf
Next


End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			x# = EntityX( r\v5\piv ) - EntityX( r\v2\piv ) + EntityX( r\v6\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v2\piv ) + EntityY( r\v6\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v2\piv ) + EntityZ( r\v6\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v2\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v2\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v2\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#, 3
			

			
		
	Next
End Function


Function updateconstraints()

For a = 1 To 10
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length#  ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Or a = 10 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Or a = 10 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next


There is still a flaw with stevieg's code and the rotating thing but here is my attempt to make two cubes collide using the physics engine and a line picking method.

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


cam = CreateCamera()
MoveEntity cam,0,0,-20
CameraZoom cam,2
CameraFogMode cam,1
CameraFogRange cam,20,100
CameraRange cam,.001,100
;CameraClsColor cam,100,100,100
;CameraFogColor cam,100,100,100

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
EntityPickMode plane,0
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
	Field surf,index
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

Global cube2 = CreateCube()
MoveEntity cube2,0,3,0
applyphysicscube(cube2,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1
If KeyDown(203) Then MoveEntity cam,-.1,0,0
If KeyDown(205) Then MoveEntity cam,.1,0,0

;TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 0

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)

EntityPickMode r\ent,2

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
		v.verlet = New verlet
		v\piv = CreatePivot()
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		PositionEntity v\piv,v\x#,v\y#,v\z#
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next


r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#-MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2
r\v1\oy# = r\y#-MeshHeight(r\ent)/2
r\v1\oz# = r\z#-MeshDepth(r\ent)/2
r\v1\ent = r\ent
r\v1\mass# = 0
r\v1\piv = CreateSphere()
EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#-MeshWidth(r\ent)/2
r\v2\y# = r\y#+MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#-MeshWidth(r\ent)/2
r\v2\oy# = r\y#+MeshHeight(r\ent)/2
r\v2\oz# = r\z#+MeshDepth(r\ent)/2-.5
r\v2\ent = r\ent
r\v2\mass# = 0
r\v2\piv = CreateSphere()
EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#-MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#+MeshDepth(r\ent)/2
r\v3\ox# = r\x#-MeshWidth(r\ent)/2
r\v3\oy# = r\y#-MeshHeight(r\ent)/2
r\v3\oz# = r\z#+MeshDepth(r\ent)/2
r\v3\ent = r\ent
r\v3\mass# = 0
r\v3\piv = CreateSphere()
EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#+MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#+MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = 0
r\v4\piv = CreateSphere()
EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#+MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#+MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2
r\v5\ent = r\ent
r\v5\mass# = 0
r\v5\piv = CreateSphere()
EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#-MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#-MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = 0
r\v6\piv = CreateSphere()
EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#-MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#-MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = 0
r\v7\piv = CreateSphere()
EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#+MeshWidth(r\ent)/2
r\v8\y# = r\y#-MeshHeight(r\ent)/2
r\v8\z# = r\z#+MeshDepth(r\ent)/2
r\v8\ox# = r\x#+MeshWidth(r\ent)/2
r\v8\oy# = r\y#-MeshHeight(r\ent)/2
r\v8\oz# = r\z#+MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = 0
r\v8\piv = CreateSphere()
EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	For vv.verlet = Each verlet
		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
				Delete vv.verlet
			EndIf
		EndIf
	Next
Next



For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						If vv\mass# = 0 Then
							c.constraint = New constraint
							c\p1.verlet = v.verlet
							c\p2.verlet = vv.verlet
							dx# = c\p1\x# - c\p2\x#
							dy# = c\p1\y# - c\p2\y#
							dz# = c\p1\z# - c\p2\z#
							c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
							c\ent = c\p1\ent
						EndIf
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.98 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.98
		v\vz# = (v\z# - v\oz#)*.98
		
		If v\vx# > -.001 And v\vx# < .001 Then
			If v\vy# > -.001 And v\vy# < .001 Then
				If v\vz# > -.001 And v\vz# < .001 Then
					v\vx# = 0
					v\vy# = 0
					v\vz# = 0
				EndIf
			EndIf
		EndIf
		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
	;	If v\collided = False Then
			v\x# = v\x# + v\vx# ;store new postion based on velocity
		
			v\y# = v\y# + v\vy# - .007
		
			v\z# = v\z# + v\vz#
	;	EndIf
		
		If v\mass > 0 Then
			;check screen bounds
			If v\y#	< -4 ;ground collision
				v\y# = -4
				v\collided = True
				v\vy# = -v\vy#
			EndIf
		EndIf
		
Next

For v.verlet = Each verlet
	If v\mass# > 0 Then
		ent = LinePick(v\ox# , v\oy# , v\oz# , v\x#-v\ox# , v\y#-v\oy# , v\z#-voz#)
		If ent <> 0 And ent <> v\ent Then
			v\collided = True
			v\x# = PickedX()
			v\y# = PickedY()
			v\z# = PickedZ()
			v\ox# = v\x# + v\vx#*13
			v\oy# = v\y# + v\vy#*13
			v\oz# = v\z# + v\vz#*13
		EndIf
	EndIf
Next

End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			x# = EntityX( r\v5\piv ) - EntityX( r\v2\piv ) + EntityX( r\v6\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v2\piv ) + EntityY( r\v6\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v2\piv ) + EntityZ( r\v6\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v2\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v2\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v2\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#, 3
			

			
		
	Next
End Function


Function updateconstraints()

For a = 1 To 10
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length#  ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Or a > 8 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Or a > 8 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function


ok now stevies code is giving me a headache I can't get it to align right.

Here is code that shows the flaws in stevie's code.

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


cam = CreateCamera()
MoveEntity cam,0,0,-20
CameraZoom cam,2
CameraFogMode cam,1
CameraFogRange cam,20,100
CameraRange cam,.001,100
;CameraClsColor cam,100,100,100
;CameraFogColor cam,100,100,100

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
EntityPickMode plane,0
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
	Field surf,index
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

Global cube2 = CreateCube()
MoveEntity cube2,0,3,0
applyphysicscube(cube2,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1
If KeyDown(203) Then MoveEntity cam,-.1,0,0
If KeyDown(205) Then MoveEntity cam,.1,0,0

;TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 0

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)

EntityPickMode r\ent,2

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
		v.verlet = New verlet
		v\piv = CreatePivot()
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		PositionEntity v\piv,v\x#,v\y#,v\z#
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
	Next
Next


r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#-MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2
r\v1\oy# = r\y#-MeshHeight(r\ent)/2
r\v1\oz# = r\z#-MeshDepth(r\ent)/2
r\v1\ent = r\ent
r\v1\mass# = 0
r\v1\piv = CreateSphere()
EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#-MeshWidth(r\ent)/2
r\v2\y# = r\y#+MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#-MeshWidth(r\ent)/2
r\v2\oy# = r\y#+MeshHeight(r\ent)/2
r\v2\oz# = r\z#+MeshDepth(r\ent)/2-.5
r\v2\ent = r\ent
r\v2\mass# = 0
r\v2\piv = CreateSphere()
EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#-MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#+MeshDepth(r\ent)/2
r\v3\ox# = r\x#-MeshWidth(r\ent)/2
r\v3\oy# = r\y#-MeshHeight(r\ent)/2
r\v3\oz# = r\z#+MeshDepth(r\ent)/2
r\v3\ent = r\ent
r\v3\mass# = 0
r\v3\piv = CreateSphere()
EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#+MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#+MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = 0
r\v4\piv = CreateSphere()
EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#+MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#+MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2
r\v5\ent = r\ent
r\v5\mass# = 0
r\v5\piv = CreateSphere()
EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#-MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#-MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = 0
r\v6\piv = CreateSphere()
EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#-MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#-MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = 0
r\v7\piv = CreateSphere()
EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#+MeshWidth(r\ent)/2
r\v8\y# = r\y#-MeshHeight(r\ent)/2
r\v8\z# = r\z#+MeshDepth(r\ent)/2
r\v8\ox# = r\x#+MeshWidth(r\ent)/2
r\v8\oy# = r\y#-MeshHeight(r\ent)/2
r\v8\oz# = r\z#+MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = 0
r\v8\piv = CreateSphere()
EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	For vv.verlet = Each verlet
		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
				Delete vv.verlet
			EndIf
		EndIf
	Next
Next



For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						If vv\mass# = 0 Then
							c.constraint = New constraint
							c\p1.verlet = v.verlet
							c\p2.verlet = vv.verlet
							dx# = c\p1\x# - c\p2\x#
							dy# = c\p1\y# - c\p2\y#
							dz# = c\p1\z# - c\p2\z#
							c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
							c\ent = c\p1\ent
						EndIf
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.98 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.98
		v\vz# = (v\z# - v\oz#)*.98
		
		If v\vx# > -.001 And v\vx# < .001 Then
			If v\vy# > -.001 And v\vy# < .001 Then
				If v\vz# > -.001 And v\vz# < .001 Then
					v\vx# = 0
					v\vy# = 0
					v\vz# = 0
				EndIf
			EndIf
		EndIf
		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
	;	If v\collided = False Then
			v\x# = v\x# + v\vx# ;store new postion based on velocity
		
			v\y# = v\y# + v\vy# - .007
		
			v\z# = v\z# + v\vz#
	;	EndIf
		
		If v\mass > 0 Then
			;check screen bounds
			If v\y#	< -4 ;ground collision
				v\y# = -4
				v\collided = True
				v\vy# = -v\vy#
			EndIf
		EndIf
		
Next

For v.verlet = Each verlet
	If v\mass# > 0 Then
		ent = LinePick(v\ox# , v\oy# , v\oz# , v\x#-v\ox# , v\y#-v\oy# , v\z#-voz#)
		If ent <> 0 And ent <> v\ent Then
			v\collided = True
			v\x# = PickedX()
			v\y# = PickedY()
			v\z# = PickedZ()
			v\ox# = v\x# + v\vx#*14
			v\oy# = v\y# + v\vy#*14
			v\oz# = v\z# + v\vz#*14
		EndIf
	EndIf
Next

End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			
			x# = EntityX( r\v5\piv ) - EntityX( r\v2\piv ) + EntityX( r\v6\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v2\piv ) + EntityY( r\v6\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v2\piv ) + EntityZ( r\v6\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v5\piv ) - EntityX( r\v6\piv ) + EntityX( r\v2\piv ) - EntityX( r\v4\piv )
			y# = EntityY( r\v5\piv ) - EntityY( r\v6\piv ) + EntityY( r\v2\piv ) - EntityY( r\v4\piv )
			z# = EntityZ( r\v5\piv ) - EntityZ( r\v6\piv ) + EntityZ( r\v2\piv ) - EntityZ( r\v4\piv )
			AlignToVector r\ent, x#,y#,z#, 3
		;	x# = EntityX( r\v4\piv ) - EntityX( r\v1\piv )   ;align to a third vector
		;	y# = EntityY( r\v4\piv ) - EntityY( r\v1\piv )
		;	z# = EntityZ( r\v4\piv ) - EntityZ( r\v1\piv )
		;	AlignToVector r\ent, X#,y#,z#, 2
	Next
End Function


Function updateconstraints()

For a = 1 To 10
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length#  ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Or a > 8 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Or a > 8 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function




stevie any ideas as to why your code doesn't work? It seems like it should work

My code works just fine. It is your implementation of this code which is flawed. Look again at what I posted - your code is not the same.

First thing I notice is that I refer to pivot 5 as front/top/left. You create it as front/top/right. I'd imagine that some of the others do not match either. Also, you are creating verlets at each vertex in the surface - you are already creating 9 verlets so you shouldn't be doing this. You are also aligning the visable mesh to a combination of top and bottom verlets. Pick the top or the bottom - not both.

You collision stuff is seriously flawed. There are examples of collisions in the archives.


Stevie

Congrats on the baby! Still an interesting thread guys, cheers!

sorry I am new to this so I may be a bit slow to catch on to what you are saying sorry I if I don't understand

Ok I will search the blitz website to see how other people did collision stuff...

I found that most people used the blitz built in collisions and their physics engines worked well Would this be a good Idea?

@Stevie G

Did you use the blitz collisions to make polymaniacs?


[edit] Maybe I could make the pivots a collision type and the actual meshes another collision type but then the pivots would react to their own meshes so I would have to make a different collision type for each mesh and its pivots

[edit] Stevie, is your helicopter an animated mesh? If so, How did you do the collisions on it It seems that you can't get the vertex coords for animated meshes.


I found that most people used the blitz built in collisions and their physics engines worked well Would this be a good Idea?



Yes. I think you've answered your own question there.

I only use one collision type for the pivots which make up the rigid body. I do use blitz collisions for body / level collisions but for body/body I use something similar to SAT( separating axis theory ) with mass weighting.

The helicopter is an animated mesh in that the rotors are separate entities which I turn independently. Collision volumes are built at runtime, I do not need to know the vertex coordinates for collisions. The collisions for the helicopter are the same as the other body / body collisions. It has a very specific mass structure with lift and thust forces being applied in a specific way to keep it stable in the air.

I have applied the blitz collisions here is the code sorry it has some major flaws

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


cam = CreateCamera()
MoveEntity cam,0,0,-20
CameraZoom cam,2
CameraFogMode cam,1
CameraFogRange cam,20,100
CameraRange cam,.001,100
;CameraClsColor cam,100,100,100
;CameraFogColor cam,100,100,100

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
EntityPickMode plane,0
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
	Field surf,index
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)

Global cube2 = CreateCube()
MoveEntity cube2,0,3,0
applyphysicscube(cube2,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1
If KeyDown(203) Then MoveEntity cam,-.1,0,0
If KeyDown(205) Then MoveEntity cam,.1,0,0

TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey

Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 0

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,1000-r\ID
EntityPickMode r\ent,2

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
		v.verlet = New verlet
		v\piv = CreatePivot()
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		PositionEntity v\piv,v\x#,v\y#,v\z#
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
		EntityType v\piv,v\ID
	
		EntityRadius v\piv,.5
	Next
Next


For i = 1 To rigidbodynum
	If i <> rigidbodynum Then
		Collisions rigidbodynum,1000-i,2,1
	EndIf
Next

For i = 1 To rigidbodynum
	If i <> rigidbodynum Then
		Collisions i,1000-rigidbodynum,2,1
	EndIf
Next

r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#+MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2
r\v1\oy# = r\y#-MeshHeight(r\ent)/2
r\v1\oz# = r\z#+MeshDepth(r\ent)/2
r\v1\ent = r\ent
r\v1\mass# = 0
r\v1\piv = CreatePivot()
;EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#+MeshWidth(r\ent)/2
r\v2\y# = r\y#-MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#+MeshWidth(r\ent)/2
r\v2\oy# = r\y#-MeshHeight(r\ent)/2
r\v2\oz# = r\z#+MeshDepth(r\ent)/2
r\v2\ent = r\ent
r\v2\mass# = 0
r\v2\piv = CreatePivot()
;EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#+MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#-MeshDepth(r\ent)/2
r\v3\ox# = r\x#+MeshWidth(r\ent)/2
r\v3\oy# = r\y#-MeshHeight(r\ent)/2
r\v3\oz# = r\z#-MeshDepth(r\ent)/2
r\v3\ent = r\ent
r\v3\mass# = 0
r\v3\piv = CreatePivot()
;EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#-MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#-MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = 0
r\v4\piv = CreatePivot()
;EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#-MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#-MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2-.5
r\v5\ent = r\ent
r\v5\mass# = 0
r\v5\piv = CreatePivot()
;EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#+MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#+MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = 0
r\v6\piv = CreatePivot()
;EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#+MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#+MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = 0
r\v7\piv = CreatePivot()
;EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#-MeshWidth(r\ent)/2
r\v8\y# = r\y#+MeshHeight(r\ent)/2
r\v8\z# = r\z#-MeshDepth(r\ent)/2
r\v8\ox# = r\x#-MeshWidth(r\ent)/2
r\v8\oy# = r\y#+MeshHeight(r\ent)/2
r\v8\oz# = r\z#-MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = 0
r\v8\piv = CreatePivot()
;EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#


For v.verlet = Each verlet
	For vv.verlet = Each verlet
		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
				Delete vv.verlet
			EndIf
		EndIf
	Next
Next



For v.verlet = Each verlet
	If v\ID = rigidbodynum Then
		If idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						If vv\mass# = 0 Then
							c.constraint = New constraint
							c\p1.verlet = v.verlet
							c\p2.verlet = vv.verlet
							dx# = c\p1\x# - c\p2\x#
							dy# = c\p1\y# - c\p2\y#
							dz# = c\p1\z# - c\p2\z#
							c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
							c\ent = c\p1\ent
						EndIf
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next


For c.constraint = Each constraint
	For cc.constraint = Each constraint
		If c\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.98 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.98
		v\vz# = (v\z# - v\oz#)*.98
		
		If v\vx# > -.001 And v\vx# < .001 Then
			If v\vy# > -.001 And v\vy# < .001 Then
				If v\vz# > -.001 And v\vz# < .001 Then
					v\vx# = 0
					v\vy# = 0
					v\vz# = 0
				EndIf
			EndIf
		EndIf
		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
	;	If v\collided = False Then
			v\x# = v\x# + v\vx# ;store new postion based on velocity
		
			v\y# = v\y# + v\vy# - .007
		
			v\z# = v\z# + v\vz#
	;	EndIf
		
		If v\mass > 0 Then
			;check screen bounds
			If v\y#	< -4 ;ground collision
				v\y# = -4
				v\collided = True
				v\vy# = -v\vy#
			EndIf
		EndIf
Next

End Function



Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			
			x# = EntityX( r\v6\piv ) - EntityX( r\v5\piv ) + EntityX( r\v7\piv ) - EntityX( r\v8\piv )
			y# = EntityY( r\v6\piv ) - EntityY( r\v5\piv ) + EntityY( r\v7\piv ) - EntityY( r\v8\piv )
			z# = EntityZ( r\v6\piv ) - EntityZ( r\v5\piv ) + EntityZ( r\v7\piv ) - EntityZ( r\v8\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v6\piv ) - EntityX( r\v7\piv ) + EntityX( r\v5\piv ) - EntityX( r\v8\piv )
			y# = EntityY( r\v6\piv ) - EntityY( r\v7\piv ) + EntityY( r\v5\piv ) - EntityY( r\v8\piv )
			z# = EntityZ( r\v6\piv ) - EntityZ( r\v7\piv ) + EntityZ( r\v5\piv ) - EntityZ( r\v8\piv )
			AlignToVector r\ent, x#,y#,z#, 3
		;	x# = EntityX( r\v4\piv ) - EntityX( r\v1\piv )   ;align to a third vector
		;	y# = EntityY( r\v4\piv ) - EntityY( r\v1\piv )
		;	z# = EntityZ( r\v4\piv ) - EntityZ( r\v1\piv )
		;	AlignToVector r\ent, X#,y#,z#, 2
	Next
	UpdateWorld()
	For v.verlet = Each verlet
		If v\mass# > 0 Then
			If EntityX(v\piv) <> v\x# Or EntityY(v\piv) <> v\y# Or EntityZ(v\piv) <> v\z# Then
				v\collided = True
				v\x# = EntityX(v\piv)
				v\y# = EntityY(v\piv)
				v\z# = EntityZ(v\piv)
			EndIf
		EndIf
	Next

End Function


Function updateconstraints()

For a = 1 To 10
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length#  ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Or a > 8 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Or a > 8 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next

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


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function


Just took a quick skim through your code,... are you accounting for a size at the points at all?

I didn't see anything, and since the collision only happens at the points, then things will fall through easily.

Hi pongo Long time no see
I set the entityradius to 1 just to make sure it worked but unfortunately it doesn't work right

how is your verlet engine coming along

@ Nate, rather than adding to seriously flawed code I think you should take a step back and look at the entries in the code archives better and get the basic single object against a plane collisions working correctly.

You really need to have more structure to your code so that if you need help in the future people will be able to follow it. At the moment you have unused variables and alot of what your doing can be simplified a great deal. You should do this for your own benefit.

For example,

You create 8 verlets - one after the other - a repeat process. Write a function which creates the verlet ... something like this ..

Function VERLETcreate.verlet( r.rigidbody, x#, y#, z# , Radius# = 1 , Mass# = 1 )

	v.verlet = New verlet
	
	TFormPoint x, y, z, r\Ent, 0
	v\x = TFormedX()
	v\y = TFormedY()
	v\z = TFormedZ()
	v\ox = x
	v\oy = y
	v\oz = z
	v\Mass = Mass
	v\Piv = CreatePivot()
	PositionEntity v\Piv, v\x, v\y, v\z
	v\Ent = r\Ent
	EntityType v\Piv , C_VERLET
        entityradius v\Piv, Radius
	
	Return v
	
End Function


Then you can set up all your verlet like so ...

Type rigidbody
   field v.verlet[8]
   field etc...
end type

r\v[0] = VERLETcreate( ... )
r\v[1] = VERLETcreate( ... )


As I've pointed out a few times. You are not creating a central verlet - this will lead to collapse with heavy collisions.

If you need to constrain every verlet to all others ( which is overkill for a cube btw ) then do something like this ..

For l = 0 To 7
		For m = l+1 To 8
			CONSTRAINTcreate( r, r\v[l] , r\v[m] )
		Next
	Next


Again, use a function to create the CONSTRAINT as you are going to be creating alot of them.

Function CONSTRAINTcreate( r.rigidbody, v1.verlet , v2.verlet )

	c.constraint = New contraint
	c\p1 = v1
	c\p2 = v2
	c\Length = EntityDistance( v1\piv, v2\piv )
	c\Ent = r\Ent

End Function


I realise that everyone has their own coding style so if you're happy with what you have then just ignore me.

I can say this from experience that while the physics in Polymaniacs may look simple it took me a loooong time to get things working the way I wanted. Don't expect everything to fall into place overnight.

Stevie

I prefer to have fewer and longer functions. I guess that's just how I program.

One quality I wanted to have in my physics engine was for it to work flawlessly for any purpose I needed it for in the future.

P.S. When will polymaniacs be released I will certainly like to buy it!!! :)

I prefer to have fewer and longer functions. I guess that's just how I program.



Fair enough. I can't work with or follow messy bloated code myself ( probably a form of OCD - see function list image below ) so I'll probably be no help from here on in I'm afraid. Good luck to you though.

It'll be a while before I'm done with Polymaniacs - alot still to do.


One quality I wanted to have in my physics engine was for it to work flawlessly for any purpose I needed it for in the future.



I think it would really help if you would step back a bit and try to get a more simple example working. Right now you are adding in a bunch of extra code without getting the underlying collisions working.

If you look at my last example again, I have everything working that is in there. The next steps will add quite a bit of complexity to the code, but I know that everything works at this stage. If I screw things up, I know what portion of code is messed up, and I can return to the last known working version.

If you looks at my examples, I have done this entire project with that method. Here have been my major steps:
1. Individual verlets can moved around and can collide with each other.
2. Build a constraint system so that 2 verlets can be tied together
3. Expand the constraint system to any number of constraints.
4. Groups of verlets can be moved as a single mass
5. Collisions between groups of verlets
6. Now do it all in 3d
and so on...

At several of these steps I re-wrote code so that it was cleaner and more efficient. Through this refinement things have gotten very light code-wise, yet do everything I want, and is very stable.

Look at Stevie's example,... about the 6th post down here. It's an awesome structure to use, and I have learned tremendously by ripping it apart to figure out how it works.

I added a lot of comments and added some functions and gave the plane a collision type to test if it worked.

I think it would really help if you would step back a bit and try to get a more simple example working.


Just did that! :)

you will notice that it is kind of bouncy but I like it like that. It makes it look more homemade and that is good

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


cam = CreateCamera()
MoveEntity cam,0,0,-20
CameraZoom cam,2
CameraFogMode cam,1
CameraFogRange cam,20,100
CameraRange cam,.001,100
;CameraClsColor cam,100,100,100
;CameraFogColor cam,100,100,100

piv = CreatePivot()
EntityParent cam,piv
;TurnEntity piv,0,180,0
plane = CreatePlane()
EntityType plane,2
EntityPickMode plane,0
tex = CreateTexture(256,256)
SetBuffer TextureBuffer(tex)
Color 255,255,255
Rect 0,0,128,128,1
Rect 128,128,128,128
Color 0,225,0
Rect 0,128,128,128
Rect 128,0,128,128
Color 255,255,255

mir = CreateMirror()
MoveEntity mir,0,-4,0

SetBuffer BackBuffer()
EntityTexture plane,tex
MoveEntity plane,0,-4,0
ScaleTexture tex,10,10
EntityAlpha plane,.5

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



;Types

Type verlet
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field ox#,oy#,oz#
	Field ent,piv
	Field collided,ID,mass#
	Field surf,index
End Type


Type rigidbody
	Field x#,y#,z#,ent
	Field yaw#,pitch#,roll#
	Field v1.verlet,v2.verlet,v3.verlet,v4.verlet,v5.verlet,v6.verlet,v7.verlet,v8.verlet,cpiv
	Field ID
End Type


Type constraint
	Field p1.verlet
	Field p2.verlet
	Field ent
	Field length#
End Type

Global rigidbodynum = 0

Global cube = CreateCube()
EntityAlpha cube,1
Applyphysicscube(cube,10)


Collisions 1,2,2,1

;Global cube2 = CreateCube()
;MoveEntity cube2,0,3,0
;applyphysicscube(cube2,10)

SetBuffer BackBuffer()

tim = MilliSecs()


While Not KeyDown(1)
Cls

If KeyDown(200) Then MoveEntity cam,0,0,.1
If KeyDown(208) Then MoveEntity cam,0,0,-.1
If KeyDown(203) Then MoveEntity cam,-.1,0,0
If KeyDown(205) Then MoveEntity cam,.1,0,0

TurnEntity piv,0,1,0

updateverlets()

updateconstraints()

equalizeverlets()

drawstuff()

UpdateWorld()
RenderWorld()

cnt = 0
For v.verlet = Each verlet
	cnt = cnt + 1
Next
Text 1,20,"Verticies: "+cnt
Text 1,1,"FPS: "+1000/(MilliSecs()-tim)
tim = MilliSecs()

Flip

Wend

WaitKey()

End



Function Applyphysicscube(ent,mass#,idle = 0,siz# = 5)

rigidbodynum = rigidbodynum + 1

alph = 0


;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,1000-r\ID
EntityPickMode r\ent,2

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






;Loops through all surfaces and verticies
For k = 1 To CountSurfaces(ent)
	surf = GetSurface(ent,k)
	For index = 0 To CountVertices(surf)-1
		CreateVerlet(ent,surf,index,mass#)   ;Creates a verlet for every vertice  Later it deletes duplicate verlets for the sake of stability.
	Next
Next

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






;The following code creates collisions for the rigidbodies and their verlets
;For i = 1 To rigidbodynum
;	If i <> rigidbodynum Then
;		Collisions rigidbodynum,1000-i,2,1
;	EndIf
;Next

;For i = 1 To rigidbodynum
;	If i <> rigidbodynum Then
;		Collisions i,1000-rigidbodynum,2,1
;	EndIf
;Next
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




;This code makes the bounding box vertices which are used to orient the object when it is given rotational velocity
r\v1.verlet = New verlet
r\v1\id = rigidbodynum
r\v1\x# = r\x#-MeshWidth(r\ent)/2
r\v1\y# = r\y#-MeshHeight(r\ent)/2
r\v1\z# = r\z#+MeshDepth(r\ent)/2
r\v1\ox# = r\x#-MeshWidth(r\ent)/2
r\v1\oy# = r\y#-MeshHeight(r\ent)/2
r\v1\oz# = r\z#+MeshDepth(r\ent)/2
r\v1\ent = r\ent
r\v1\mass# = 0
r\v1\piv = CreatePivot()
;EntityAlpha r\v1\piv,alph
PositionEntity r\v1\piv,r\v1\x#,r\v1\y#,r\v1\z#

r\v2.verlet = New verlet
r\v2\id = rigidbodynum
r\v2\x# = r\x#+MeshWidth(r\ent)/2
r\v2\y# = r\y#-MeshHeight(r\ent)/2
r\v2\z# = r\z#+MeshDepth(r\ent)/2
r\v2\ox# = r\x#+MeshWidth(r\ent)/2
r\v2\oy# = r\y#-MeshHeight(r\ent)/2
r\v2\oz# = r\z#+MeshDepth(r\ent)/2
r\v2\ent = r\ent
r\v2\mass# = 0
r\v2\piv = CreatePivot()
;EntityAlpha r\v2\piv,alph
PositionEntity r\v2\piv,r\v2\x#,r\v2\y#,r\v2\z#

r\v3.verlet = New verlet
r\v3\id = rigidbodynum
r\v3\x# = r\x#+MeshWidth(r\ent)/2
r\v3\y# = r\y#-MeshHeight(r\ent)/2
r\v3\z# = r\z#-MeshDepth(r\ent)/2
r\v3\ox# = r\x#+MeshWidth(r\ent)/2
r\v3\oy# = r\y#-MeshHeight(r\ent)/2
r\v3\oz# = r\z#-MeshDepth(r\ent)/2
r\v3\ent = r\ent
r\v3\mass# = 0
r\v3\piv = CreatePivot()
;EntityAlpha r\v3\piv,alph
PositionEntity r\v3\piv,r\v3\x#,r\v3\y#,r\v3\z#

r\v4.verlet = New verlet
r\v4\id = rigidbodynum
r\v4\x# = r\x#-MeshWidth(r\ent)/2
r\v4\y# = r\y#-MeshHeight(r\ent)/2
r\v4\z# = r\z#-MeshDepth(r\ent)/2
r\v4\ox# = r\x#-MeshWidth(r\ent)/2
r\v4\oy# = r\y#-MeshHeight(r\ent)/2
r\v4\oz# = r\z#-MeshDepth(r\ent)/2
r\v4\ent = r\ent
r\v4\mass# = 0
r\v4\piv = CreatePivot()
;EntityAlpha r\v4\piv,alph
PositionEntity r\v4\piv,r\v4\x#,r\v4\y#,r\v4\z#

r\v5.verlet = New verlet
r\v5\id = rigidbodynum
r\v5\x# = r\x#-MeshWidth(r\ent)/2
r\v5\y# = r\y#+MeshHeight(r\ent)/2
r\v5\z# = r\z#+MeshDepth(r\ent)/2
r\v5\ox# = r\x#-MeshWidth(r\ent)/2
r\v5\oy# = r\y#+MeshHeight(r\ent)/2
r\v5\oz# = r\z#+MeshDepth(r\ent)/2-.5
r\v5\ent = r\ent
r\v5\mass# = 0
r\v5\piv = CreatePivot()
;EntityAlpha r\v5\piv,alph
PositionEntity r\v5\piv,r\v5\x#,r\v5\y#,r\v5\z#

r\v6.verlet = New verlet
r\v6\id = rigidbodynum
r\v6\x# = r\x#+MeshWidth(r\ent)/2
r\v6\y# = r\y#+MeshHeight(r\ent)/2
r\v6\z# = r\z#+MeshDepth(r\ent)/2
r\v6\ox# = r\x#+MeshWidth(r\ent)/2
r\v6\oy# = r\y#+MeshHeight(r\ent)/2
r\v6\oz# = r\z#+MeshDepth(r\ent)/2
r\v6\ent = r\ent
r\v6\mass# = 0
r\v6\piv = CreatePivot()
;EntityAlpha r\v6\piv,alph
PositionEntity r\v6\piv,r\v6\x#,r\v6\y#,r\v6\z#

r\v7.verlet = New verlet
r\v7\id = rigidbodynum
r\v7\x# = r\x#+MeshWidth(r\ent)/2
r\v7\y# = r\y#+MeshHeight(r\ent)/2
r\v7\z# = r\z#-MeshDepth(r\ent)/2
r\v7\ox# = r\x#+MeshWidth(r\ent)/2
r\v7\oy# = r\y#+MeshHeight(r\ent)/2
r\v7\oz# = r\z#-MeshDepth(r\ent)/2
r\v7\ent = r\ent
r\v7\mass# = 0
r\v7\piv = CreatePivot()
;EntityAlpha r\v7\piv,alph
PositionEntity r\v7\piv,r\v7\x#,r\v7\y#,r\v7\z#

r\v8.verlet = New verlet
r\v8\id = rigidbodynum
r\v8\x# = r\x#-MeshWidth(r\ent)/2
r\v8\y# = r\y#+MeshHeight(r\ent)/2
r\v8\z# = r\z#-MeshDepth(r\ent)/2
r\v8\ox# = r\x#-MeshWidth(r\ent)/2
r\v8\oy# = r\y#+MeshHeight(r\ent)/2
r\v8\oz# = r\z#-MeshDepth(r\ent)/2
r\v8\ent = r\ent
r\v8\mass# = 0
r\v8\piv = CreatePivot()
;EntityAlpha r\v8\piv,alph
PositionEntity r\v8\piv,r\v8\x#,r\v8\y#,r\v8\z#

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






r\cpiv = CreatePivot()
PositionEntity r\cpiv,r\x#,r\y#,r\z#





;Deletes Duplicate verlets so that the meshes are more stable

For v.verlet = Each verlet
	For vv.verlet = Each verlet
		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
				Delete vv.verlet
			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 idle = 0 Then
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						If vv\mass# = 0 And v\mass > 0 Then
							c.constraint = New constraint
							c\p1.verlet = v.verlet
							c\p2.verlet = vv.verlet
							dx# = c\p1\x# - c\p2\x#
							dy# = c\p1\y# - c\p2\y#
							dz# = c\p1\z# - c\p2\z#
							c\length# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
							c\ent = c\p1\ent
						EndIf
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;








;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\p1\piv = cc\p1\piv And c\p2\piv = c\p1\piv Then
			Delete cc.constraint
		EndIf
	Next
Next


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





End Function





















Function updateverlets()


For v.verlet = Each verlet
		v\collided = False
		v\vx# = (v\x# - v\ox#)*.98 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
		v\vy# = (v\y# - v\oy#)*.98
		v\vz# = (v\z# - v\oz#)*.98
		
		If v\vx# > -.001 And v\vx# < .001 Then
			If v\vy# > -.001 And v\vy# < .001 Then
				If v\vz# > -.001 And v\vz# < .001 Then
					v\vx# = 0
					v\vy# = 0
					v\vz# = 0
				EndIf
			EndIf
		EndIf
		v\ox# = v\x# ; store position in "old"
		v\oy# = v\y#
		v\oz# = v\z#
		
	;	If v\collided = False Then
			v\x# = v\x# + v\vx# ;store new postion based on velocity
		
			v\y# = v\y# + v\vy# - .007
		
			v\z# = v\z# + v\vz#
	;	EndIf
		
	;	If v\mass > 0 Then
	;		;check screen bounds
	;		If v\y#	< -4 ;ground collision
	;			v\y# = -4
	;			v\collided = True
	;			v\vy# = -v\vy#
	;		EndIf
	;	EndIf
Next

End Function
























Function drawstuff()
	;For v.verlet = Each verlet
		;VertexCoords v\surf,v\index,v\x#,v\y#,v\z#
	;Next
	
	For r.rigidbody = Each rigidbody
		cnt = 0
		avgx# = 0
		avgy# = 0
		avgz# = 0
		For v.verlet = Each verlet
			If v\ent = r\ent
				cnt = cnt + 1
				avgx# = avgx# + v\x#
				avgy# = avgy# + v\y#
				avgz# = avgz# + v\z#
				PositionEntity v\piv,v\x#,v\y#,v\z#
			EndIf
		Next
		avgx# = avgx#/cnt
		avgy# = avgy#/cnt
		avgz# = avgz#/cnt
		
		r\x# = avgx#
		r\y# = avgy#
		r\z# = avgz#
		
		RotateEntity r\ent,0,0,0
		PositionEntity r\ent,avgx#,avgy#,avgz#
		
		cnt = 0
		avgyaw =0
		avgpitch = 0
		avgroll = 0
		
		
		;this computes the orientation of the verticies using stevie g's code  Thnx Stevie G!!!
			
			;align mesh to verlet cage
			
			x# = EntityX( r\v6\piv ) - EntityX( r\v5\piv ) + EntityX( r\v7\piv ) - EntityX( r\v8\piv )
			y# = EntityY( r\v6\piv ) - EntityY( r\v5\piv ) + EntityY( r\v7\piv ) - EntityY( r\v8\piv )
			z# = EntityZ( r\v6\piv ) - EntityZ( r\v5\piv ) + EntityZ( r\v7\piv ) - EntityZ( r\v8\piv )
			AlignToVector r\ent, x#,y#,z#,1  
			x# = EntityX( r\v6\piv ) - EntityX( r\v7\piv ) + EntityX( r\v5\piv ) - EntityX( r\v8\piv )
			y# = EntityY( r\v6\piv ) - EntityY( r\v7\piv ) + EntityY( r\v5\piv ) - EntityY( r\v8\piv )
			z# = EntityZ( r\v6\piv ) - EntityZ( r\v7\piv ) + EntityZ( r\v5\piv ) - EntityZ( r\v8\piv )
			AlignToVector r\ent, x#,y#,z#, 3
		;	x# = EntityX( r\v4\piv ) - EntityX( r\v1\piv )   ;align to a third vector
		;	y# = EntityY( r\v4\piv ) - EntityY( r\v1\piv )
		;	z# = EntityZ( r\v4\piv ) - EntityZ( r\v1\piv )
		;	AlignToVector r\ent, X#,y#,z#, 2
	Next
	UpdateWorld()
	For v.verlet = Each verlet
		If v\mass# > 0 Then
			If EntityX(v\piv) <> v\x# Or EntityY(v\piv) <> v\y# Or EntityZ(v\piv) <> v\z# Then
				v\collided = True
				v\x# = EntityX(v\piv)
				v\y# = EntityY(v\piv)
				v\z# = EntityZ(v\piv)
			EndIf
		EndIf
	Next

End Function


















;Updates the constraints and deals a little with collisions


Function updateconstraints()

For a = 1 To 10
	For c.constraint = Each constraint
		dx#=c\p2\x#	-	c\p1\x#
		dy#=c\p2\y#	-	c\p1\y#
		dz#=c\p2\z#	-	c\p1\z#
				
		length#=Sqr(dx*dx + dy*dy + dz*dz) ; distance between p1 and p2

		If length#<>0 ;avoid divide by 0, then normalize the vector
			diff# = (length# - c\length#) / length#  ; vector length minus constraint length
		Else
			diff# = 0
		EndIf

		dx# = dx# * .5 ;find the midpoint
		dy# = dy# * .5
		dz# = dz# * .5
		
		If c\p1\collided = 0 Or a > 8 Then
			c\p1\x# = c\p1\x# + diff# * dx# 
			c\p1\y# = c\p1\y# + diff# * dy#
			c\p1\z# = c\p1\z# + diff# * dz#
		EndIf
		If c\p2\collided = 0 Or a > 8 Then
			c\p2\x# = c\p2\x# - diff# * dx#
			c\p2\y# = c\p2\y# - diff# * dy#
			c\p2\z# = c\p2\z# - diff# * dz#
		EndIf
	Next  ;constraints
Next


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


End Function





















Function equalizeverlets()

;For c.constraint = Each constraint
;	If c\length# = 0 Then
;		dx#=c\p2\x#	+	c\p1\x#
;		dy#=c\p2\y#	+	c\p1\y#
;		dz#=c\p2\z#	+	c\p1\z#
;		
;		dx# = dx# * .5 ;find the midpoint                ;This function, I have found could be useful for other projects but not for this one so I saved the code
;		dy# = dy# * .5
;		dz# = dz# * .5
;		
;		c\p2\x# = dx#
;		c\p2\y# = dy#
;		c\p2\z# = dz#
;		
;		c\p1\x# = dx#
;		c\p1\y# = dy#
;		c\p1\z# = dz#
;		
;	EndIf
;Next

End Function

























;Soon to be code that rotates the verlets of a rigidbody as well as the entity.
Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
	If r\ent = ent Then
		tmppiv = CreatePivot()
		PositionEntity tmppiv,r\x#,r\y#,r\z#
	EndIf
Next

End Function


























;Creates a Verlet  Duh  :)
Function CreateVerlet(ent,surf,index,mass#)

		TFormPoint VertexX(surf,index), VertexY(surf, index),VertexZ(surf, index), ent, 0
		v.verlet = New verlet
		v\piv = CreatePivot()
		v\x# = TFormedX()
		v\y# = TFormedY()
		v\z# = TFormedZ()
		PositionEntity v\piv,v\x#,v\y#,v\z#
		v\ox# = v\x#
		v\oy# = v\y#
		v\oz# = v\z#
		v\ent = ent
		v\surf = surf
		v\index = index
		v\collided =0
		v\ID = rigidbodynum
		v\mass# = mass#/(CountSurfaces(ent)*CountVertices(surf))
		EntityType v\piv,v\ID
	
		EntityRadius v\piv,.1


End Function



Pongo, how is your code? have you changed it recently or gotten 3d meshes to align themselves to you verlet cage? I would like to see how far you have gotten

@Stevie G. and Pongo
You have both been a great help so far thanks for all of the great advice and advising me on how to create a physics engine. I would have given up a long time ago if it wasn't for you

@ Nate,

Your welcome. However, it's clear from your latest version that you are not listening to either of us and seem insistant on doing things the hard way.

Wrapping re-used code into a function is a basic principle of programming and it's a good habbit to get into.

sorry but I don't understand how far you want me to step back or what you want me to do

I am having a hard time understanding you. Do you want me to re-write my whole physics engine or just modify the one I have.

Wrapping re-used code into a function is a basic principle of programming and it's a good habbit to get into.


I am currently working on that but I only have time on the weekend.

Please explain what you mean by I am doing it the hard way. What way should I be doing it. Sorry if I am slow to understand what you are saying.

Nate, you need to be the one to determine haw far back to go.

I personally like to start with extremely simple examples, and get each of the small examples working perfect before I put things together. I have an entire folder of this type of code, usually 50-100 lines of code max. Then when I need to refresh my brain I can load up one of these and see things very clearly without going through pages of code. That is how I work, but everyone works a bit different, so you need to figure out what works for you.

I would suggest forgetting about the aligned mesh for now,... get the underlying physics working first. I do not consider myself much of a programmer (I'm an artist), but I'm not even thinking about attaching meshes to things until I get the basics working exactly how I want. Right now I'm expanding my code to allow for new things, and I have restructured things a bit. I'm also trying to optimize verlet positions and constraints to get structures that are both efficient and do not collapse.

Ok I have made a desicion to go back to the drawing board (I am really using a white board) unless I accidentally fix my old code. It will most likely be finished in a few days. I will base it on the verlet system which is the only system I know how to make.

If I encounter any problems and post on this blog, it will probably be completely different code than my old code. Wish me luck. I will post it when I am at least half-way finished. Thanks for the help.

@Pongo Have you added to your verlet system yet? It would be interesting to see how it is coming along.

P.S. I found some neat code in the archives that uses car.x from the driver sample file. here it is. :)

; 3D Verlet Functions

; from Thomas Jakobsen's "Advanced Character Physics"
; www.gamasutra.com/resource_guide/20030121/jacobson_01.shtml
; Adapted for Blitz3D by Chris "Miracle" Casey, May 6 2003
;
; Added polymesh "cage" around verlet group and made constraint distance auto-calculating - Dave Cornish
; Need to make polymesh cage a collideable entity. I have had some minor success with this but its very complicated
; so it is left OUT of this version.
; Added player mesh and orient that mesh to the collision mesh

Graphics3D height,width,0,2

Const height=640
Const width=480
Const ACTIVE=1
Const radius#=.33333
Const size#=1.5
Const ITERATIONS = 5				; How many loops through the "relaxation" routine, Lower = speed up / lose accuracy
Global fTimeStep#
Global vGrav.Vector = Vector(0.0,4,0.0)	; Gravity	
Global Temp.Vector=Vector()									
Global vTemp1.Vector = Vector(0,0,0)	; Some temporary vectors for calculations
Global vTemp2.Vector = Vector(0,0,0)
Global tol# = 0.001

Type Vector
	Field x#
	Field y#
	Field z#
End Type

Type VerletPack							; Contains everything we need for basic physics
	Field m.Vector							; Current position
	Field old.Vector						; Last position
	Field a.Vector							; Accumulated forces
	Field radius#							; Collision radius from center
	Field mass#							; Arbitrary mass unit
	Field entity							; Placeholder for the 3D sphere
	Field obj								; Which construct is this verlet a part of?
	Field vertex							; vertex assigned to verlet
	Field surface							; surface id from cube type
	Field mesh							; mesh id from cube type
End Type

Type Constraint							; Two verlets connected by a mutual spring
	Field v1.VerletPack
	Field v2.VerletPack
	Field d#								; Distance between verlets
End Type

Type cube
	Field v.VerletPack[8]
	Field player							; Player mesh
	Field center.VerletPack					; Used to pisition player mesh
	Field x1.VerletPack						; Used to orient player mesh to collision mesh/verlets
	Field x2.VerletPack
	Field z1.VerletPack
	Field z2.VerletPack
	Field X_vec#							; Junk for calculations
	Field Y_vec#
	Field Z_vec#
End Type

ClearTextureFilters
SetBuffer BackBuffer()
Collisions ACTIVE,ACTIVE,2,1
MoveMouse width/2,height/2

lgt = CreateLight()
cam = CreateCamera()
flr = CreateCube()

ScaleEntity flr,20,20,20
PositionEntity flr,0,10,0
EntityType flr,ACTIVE
grid_tex=CreateTexture( 256,256,1+4+8)
SetBuffer TextureBuffer( grid_tex )
ScaleTexture grid_tex,.2,.2
Color 255,255,255:Rect 0,0,256,256,False
grid_tex2=CreateTexture( 32,32,1)
SetBuffer TextureBuffer( grid_tex2 )
ScaleTexture grid_tex2,100,100
Color 0,0,60:Rect 0,0,32,32,False
EntityTexture flr,grid_tex,0,1
EntityTexture flr,grid_tex2,0,0
TextureBlend grid_tex,3
EntityFX flr,1
FlipMesh flr
SetBuffer BackBuffer()

For m = 1 To 10			; Let's make some cubes!
	xa# = 0
	xb# = m*5 +5
	xc# = 0
	cc.cube = New cube
	mesh=CreateMesh()
	surface=CreateSurface(mesh)
	cc\player=CreateCube();LoadMesh( "car.x" ) ; this can be loaded in the "Samples\Blitz 3D Samples\mak\driver"
	FitMesh cc\player,-size,-size,-size,size*2,size*2,size*2
	
	; Yes, all the below is necessary to create a stable 9-verlet "cube" ...
	a.VerletPack = Verlet(xa - size, xb - size, xc - size, radius, 1.0, m, 0, 0, 0,surface,mesh,True)
	b.VerletPack = Verlet(xa + size, xb - size, xc - size, radius, 1.0, m, 0, 0, 0,surface,mesh,True)
	c.VerletPack = Verlet(xa + size, xb + size, xc - size, radius, 1.0, m, 255, 0, 0,surface,mesh,True)
	d.VerletPack = Verlet(xa - size, xb + size, xc - size, radius, 1.0, m, 0, 255, 0,surface,mesh,True)
	e.VerletPack = Verlet(xa - size, xb - size, xc + size, radius, 1.0, m, 0, 0, 0,surface,mesh,True)
	f.VerletPack = Verlet(xa + size, xb - size, xc + size, radius, 1.0, m, 0, 0, 0,surface,mesh,True)
	g.VerletPack = Verlet(xa + size, xb + size, xc + size, radius, 1.0, m, 0, 0, 255,surface,mesh,True)
	h.VerletPack = Verlet(xa - size, xb + size, xc + size, radius, 1.0, m, 0, 0, 0,surface,mesh,True)
	i.VerletPack = Verlet(xa, xb, xc,size, 1.0, m, 255, 255, 255,surface,mesh,True)
	
	AddTriangle(surface,0,2,1)
	AddTriangle(surface,0,3,2)
	AddTriangle(surface,0,1,5)
	AddTriangle(surface,0,5,4)
	AddTriangle(surface,0,4,7)
	AddTriangle(surface,0,7,3)
	
	AddTriangle(surface,6,1,2)
	AddTriangle(surface,6,2,3)
	AddTriangle(surface,6,5,1)
	AddTriangle(surface,6,4,5)
	AddTriangle(surface,6,7,4)
	AddTriangle(surface,6,3,7)
	
	UpdateNormals mesh
	EntityType mesh,0
	EntityColor mesh,255,0,0	
	EntityAlpha mesh,0
	
	; Edges - distance 1.0
	Constraint2(a,b)
	Constraint2(b,c)
	Constraint2(a,d)
	Constraint2(c,d)
	Constraint2(e,f)	
	Constraint2(f,g)
	Constraint2(e,h)
	Constraint2(g,h)
	Constraint2(a,e)
	Constraint2(b,f)
	Constraint2(c,g)
	Constraint2(d,h)

	; Cross-faces - distance ~Sqr(2.0)
	Constraint2(a,c)
	Constraint2(b,d)
	Constraint2(e,g)
	Constraint2(f,h)
	Constraint2(a,f)
	Constraint2(a,h)
	Constraint2(b,e)
	Constraint2(b,g)
	Constraint2(c,f)
	Constraint2(c,h)
	Constraint2(d,e)
	Constraint2(d,g)

	; Diagonals - distance ~Sqr(3.0)
	Constraint2(a,g)
	Constraint2(b,h)
	Constraint2(c,e)
	Constraint2(d,f)
	
	; Constraining the center sphere - distance ~0.5 * Sqr(3.0)
	Constraint2(a,i)
	Constraint2(b,i)
	Constraint2(c,i)
	Constraint2(d,i)
	Constraint2(e,i)
	Constraint2(f,i)
	Constraint2(g,i)
	Constraint2(h,i)
	
	cc\v[0] = i
	cc\v[1] = a
	cc\v[2] = b
	cc\v[3] = c
	cc\v[4] = d
	cc\v[5] = e
	cc\v[6] = f
	cc\v[7] = g
	cc\v[8] = h
	
	; Set up variables used for player mesh
	cc\center=i
	cc\x1=c
	cc\x2=d
	cc\z1=g
	cc\z2=c
Next

;********* functions defined ********************************************
Function TimeStep()							; The main loop
	AccumulateForces()
	DoVerlet()
	SatisfyConstraints2()
End Function

Function AccumulateForces()					; As of right now, we only accumulate gravity
	For v.VerletPack = Each VerletPack
		CloneVector(v\a,vGrav)
	Next
End Function

Function DoVerlet()
	For v.VerletPack = Each VerletPack
		CloneVector(vTemp1,v\m)
		MulVecScalar(vTemp2,v\a,fTimeStep * fTimeStep)		; a * timestep * timestep
		AddVector2(v\old,vTemp2)							; old = old + a * ts * ts
		SubVector2(v\m,v\old)								; m = m - old + a * ts * ts
		AddVector2(v\m,vTemp1)								; m += m - old + a * ts * ts
		CloneVector(v\old,vTemp1)
	Next
End Function

Function SatisfyConstraints2()
	For n = 1 To ITERATIONS
		For c.Constraint = Each Constraint
			SetDistance(c\v1,c\v2,c\d)
		Next
		
		For cc.cube = Each cube
			bing = 0
			q.cube = cc
			While bing = 0
				If q <> Last cube
					q = After q
					dp# = ((cc\v[0]\m\x - q\v[0]\m\x) * (cc\v[0]\m\x - q\v[0]\m\x)) + ((cc\v[0]\m\y - q\v[0]\m\y) * (cc\v[0]\m\y - q\v[0]\m\y)) + ((cc\v[0]\m\z - q\v[0]\m\z) * (cc\v[0]\m\z - q\v[0]\m\z))
					If dp < 6.0
						For aa = 0 To 8
							For bb = 0 To 8
								l# = cc\v[aa]\radius + q\v[bb]\radius
								dp2# = ((cc\v[aa]\m\x - q\v[bb]\m\x) * (cc\v[aa]\m\x - q\v[bb]\m\x)) + ((cc\v[aa]\m\y - q\v[bb]\m\y) * (cc\v[aa]\m\y - q\v[bb]\m\y)) + ((cc\v[aa]\m\z - q\v[bb]\m\z) * (cc\v[aa]\m\z - q\v[bb]\m\z))
								If dp2 < (l * l) 
									SetDistance(cc\v[aa],q\v[bb],l)
									SubVector(vTemp1,cc\v[aa]\m,cc\v[aa]\old)
									MulVecScalar2(vTemp1,.4 * fTimeStep)
									AddVector2(cc\v[aa]\old,vTemp1)
								EndIf
							Next
						Next
					EndIf
				Else
					bing = 1
				EndIf
			Wend
		Next
	Next
End Function

	
Function SetDistance(v1.VerletPack,v2.VerletPack,dist#)	
		SubVector(vTemp1,v1\m,v2\m)
		deltalength# = Sqr((vTemp1\x * vTemp1\x) + (vTemp1\y * vTemp1\y) + (vTemp1\z * vTemp1\z))
		If deltalength <= 0.0 deltalength = 0.0001
		diff# = (deltalength - dist) / deltalength
		tmass# = v1\mass + v2\mass
		MulVecScalar(vTemp2,vTemp1,diff * (v2\mass / tmass))
		SubVector2(v1\m,vTemp2)
		MulVecScalar(vTemp2,vTemp1,diff * (v1\mass / tmass))
		AddVector2(v2\m,vTemp2)
End Function

Function CageVerlet2(v.VerletPack)				; Collision code
	col = False
	If v\m\x <> EntityX(v\entity)
		v\m\x=EntityX(v\entity)
		col = True
	EndIf
	If v\m\y <> EntityY(v\entity)
		v\m\y=EntityY(v\entity)
		col = True
	EndIf
	If v\m\z <> EntityZ(v\entity)
		v\m\z=EntityZ(v\entity)
		col = True
	EndIf
	If col
		SubVector(vTemp1,v\m,v\old)
		MulVecScalar2(vTemp1,0.4 * fTimeStep)
		AddVector2(v\old,vTemp1)
	EndIf
End Function

Function Verlet.VerletPack(x#,y#,z#,radius#, mass# = 1.0, obj%, red,green,blue,surface,mesh,state)
	v.VerletPack = New VerletPack
	v\surface=surface
	v\mesh=mesh
	v\vertex=AddVertex(v\surface,x,y,z)
	v\m = Vector(x,y,z)
	v\entity = CreatePivot()
	PositionEntity v\entity,x,y,z
	EntityType v\entity, ACTIVE
	EntityRadius v\entity,radius#
	v\old = Vector(x,y,z)
	v\a = Vector(0.0,0.0,0.0)
	If radius <= 0.0 radius = 0.01
	v\radius = radius
	If mass <= 0.0 mass = 0.01
	v\mass = mass
	v\obj = obj
	Return v
End Function

Function Constraint2.Constraint(v1.VerletPack,v2.VerletPack)
	c.Constraint = New Constraint
	c\v1 = v1
	c\v2 = v2
	c\d = Sqr((v2\m\x - v1\m\x)^2 + (v2\m\y - v1\m\y)^2 + (v2\m\z - v1\m\z)^2)
	;Return c	; You may need this someday ... we don't for what we have here
End Function

;// Create a Vector
Function Vector.Vector(x#=0.0,y#=0.0,z#=0.0)
	v.Vector = New Vector
	v\x=x
	v\y=y
	v\z=z
	Return v
End Function 

;// Vector 1 is set to Vector 2
Function CloneVector(v1.Vector,v2.Vector)
	v1\x = v2\x
	v1\y = v2\y
	v1\z = v2\z
End Function

;// Vector Scalar Multiplication
;// Form of Vector1 = Vector2 * Scalar
Function MulVecScalar(v1.Vector,v2.Vector,s#)
	v1\x = v2\x * s
	v1\y = v2\y * s
	v1\z = v2\z * s
End Function

;// Form of Vector1 = Vector1 + Vector2
Function AddVector2(v1.Vector,v2.Vector)
	v1\x = v1\x + v2\x
	v1\y = v1\y + v2\y
	v1\z = v1\z + v2\z
End Function

;// Form of Vector1 = Vector1 - Vector2
Function SubVector2(v1.Vector,v2.Vector)
	v1\x = v1\x - v2\x
	v1\y = v1\y - v2\y
	v1\z = v1\z - v2\z
End Function

;// Vector Subtraction
;// Form of Vector1 = Vector2 - Vector3
Function SubVector(v1.Vector,v2.Vector,v3.Vector)
	v1\x = v2\x - v3\x
	v1\y = v2\y - v3\y
	v1\z = v2\z - v3\z
End Function

;// Form of Vector1 = Vector1 * Scalar
Function MulVecScalar2(v1.Vector,s#)
	v1\x = v1\x * s
	v1\y = v1\y * s
	v1\z = v1\z * s
End Function

;************* deltatime function ******************
Global new_time=MilliSecs(), old_time=MilliSecs()
Function delta_time#(new_time)
	delta_t#=(new_time - old_time) * .001
	old_time=new_time
Return delta_t#
End Function

;**************** main loop ***************************************	
While Not KeyHit(1)
	fTimeStep#=delta_time(MilliSecs())
	TimeStep()
				
	For v.VerletPack = Each VerletPack
		VertexCoords v\surface,v\vertex,v\m\x,v\m\y,v\m\z
		UpdateNormals v\mesh
		PositionEntity v\entity,v\m\x,v\m\y,v\m\z
	Next
	
	For temp_cube.cube = Each cube
		PositionEntity temp_cube\player,EntityX(temp_cube\center\entity),EntityY(temp_cube\center\entity),EntityZ(temp_cube\center\entity)
		temp_cube\X_vec=EntityX(temp_cube\x1\entity)-EntityX(temp_cube\x2\entity)
		temp_cube\Y_vec=EntityY(temp_cube\x1\entity)-EntityY(temp_cube\x2\entity)
		temp_cube\Z_vec=EntityZ(temp_cube\x1\entity)-EntityZ(temp_cube\x2\entity)
		AlignToVector temp_cube\player, temp_cube\X_vec, temp_cube\Y_vec, temp_cube\Z_vec, 1		
		temp_cube\X_vec=EntityX(temp_cube\z1\entity)-EntityX(temp_cube\z2\entity)
		temp_cube\Y_vec=EntityY(temp_cube\z1\entity)-EntityY(temp_cube\z2\entity)
		temp_cube\Z_vec=EntityZ(temp_cube\z1\entity)-EntityZ(temp_cube\z2\entity)
		AlignToVector temp_cube\player, temp_cube\X_vec, temp_cube\Y_vec, temp_cube\Z_vec, 3
		
	Next
	
	UpdateWorld
	For v.VerletPack = Each VerletPack
		CageVerlet2(v)
	Next
		
	PositionEntity cam,0,0,0
	RotateEntity cam,MouseY()-height*.5 ,(-MouseX())-width*.5+50,0
	MoveEntity cam,0,0,-15
	
	RenderWorld
	Flip False
	
Wend

End


Oh Great another hurricane is going to hit!!!

I may not be able to post over the weekend depending on how bad the hurricane is.

Here is my code rewritten and revised to have a lot more friction when things collide :) This is only part of it so far. Stepping back really helps!!!

Graphics3D 640,480,0,2



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

cam = CreateCamera()
CameraRange cam,.01,18
TurnEntity cam,45,0,0
MoveEntity cam,0,0,-10

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

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

EntityType plane,2

mir = CreateMirror()


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




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

Collisions VerletType,RBodyType,2,2  	;Sets Collision Types
Collisions VerletType,VerletType,1,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 c.verlet,idl								;The central Verlet
End Type





SetBuffer BackBuffer()

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



While Not KeyDown(1)
Cls

UpdateVerlets()

UpdateConstraints()

DrawVerlets()

detectcollisions()

positionPhysicsEntity()

UpdateWorld()
RenderWorld()

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

Text 1,1,cnt

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# - .3 , r\y# + .5 , r\z# + .3, 1 , ent , r\ID , False)

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

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

r\rb.verlet = CreateVerlet(r\x# + .3 , r\y# + .5 , r\z# - .3, 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
			For vv.verlet = Each verlet
				If vv\id = rigidbodynum Then
					If vv\piv <> v\piv
						If vv\active# = False And v\mass > 0 Then
							Createconstraint(v.verlet,vv.verlet)              ;Creates constraint
						EndIf
					EndIf
				EndIf
			Next
		EndIf
	EndIf
Next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;








;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#-Rnd(.1,.3)
	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 = CreateSphere()
	ScaleEntity v\piv,.2,.2,.2
	PositionEntity v\piv,v\x#,v\y#,v\z#
	
	EntityType v\piv,VerletType
	EntityRadius v\piv,.1
	
	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((v1\x#-v2\x#)^2 + (v1\y#-v2\y#)^2 + (v1\z#-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# = .8
	Else
		fric# = .985
	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#
	
	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)
Next

End Function





















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

Function Detectcollisions()

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

End Function



I figured out what I believe is the most efficient way of making very stable verlet structures.

this is way cool, much better than i could do right now :) but i wanted to know what entity i need to apply transformations to to make it move. if i try "cube" or "r\ent" or r\c\ent it fails, why?? what am i missing?

Thanks but it still has a long way to go

As for the problem. I am working on a MovePhysicsEntity function soon but with the code above, You will have to stick with transforming it before you use the Applyphysics function sorry I am working on adding some terrain collisions at the moment. :)

check in tommorrow maybe I will have it fixed up a bit.

ok thanks!

@Nate the Great
Me likes.. but just to let you know if you don't already, if you change the CreateCube to CreateSphere it goes wonky.

Oh yeah sorrry about that glitch but too many vertcies too close together makes it act funny. try createsphere(4)

Is there a limit of 100 posts per topic? If there is then I should move this to a new topic because it is getting close

Here is the code that deals with terrain collisions!!!

you need a bmp file called heightmap1.bmp you can find it here

[a http://files.filefront.com/heightmap1bmp/;11773113;/fileinfo.html]Heightmap1.bmp[/a]

Here is the source code

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
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

UpdateVerlets()

UpdateConstraints()

DrawVerlets()

UpdateWorld()
detectcollisions()

positionPhysicsEntity()

UpdateWorld()
RenderWorld()

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

Text 1,1,cnt

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#
	
;	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


press space bar to add a sphere

use arrowkeys and a and z to navigate.

If you can figure out how to improve it or make it faster please tell me.

Enjoy

Stevie G,

How do you use SAT for your collisions I attempted this but could not figure out how to do it.

Ok I have basic verlet sphere-sphere collisions working proporly using the concepts from some of pongo's code.

it still needs heightmap.bmp

you press the space bar for more balls to appear over the terrain

you can use yhgj for the controls of the first ball that you put on the map

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
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()

UpdateWorld()
RenderWorld()

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

Text 1,1,cnt

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




P.S. It is much faster now I haven't gotten to measure the fps recently though :)

This thread is so long and is taking to long to load so I will move it to another thread called verlet Physics 2