Verlet Help

Blitz3D Forums/Blitz3D Beginners Area/Verlet Help

Hey guys,

WHAT THE HECK IS A VERLET??????????

Verlets are simply a system of doing physics that work by linking several points with constraints. Each loop through the constraints are satisfied several times.

There is a good explanation of how things work here:
http://www.gamasutra.com/resource_guide/20030121/jacobson_01.shtml


Here is a simple b3d example

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
					vv\pos\z = vv\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




I still don't get it.

Verlet is actually the name for an integration method which can be used for position based particle physics. Some people call the particles verlets ( probably due to the integration method ) but really they are just particles / point masses.

There are loads of different integration methods which can be used for particle physics : Euler / Leapfrog / Runge Kutta 4 to name a few. Each has it's positives and negatives in terms of simulation accuracy, stability and ease of use. With Verlet, the velocity of particles are implied by old position / current position rather than defined explicitly which makes it extremely stable when compared to Euler which can suffer floating point inaccuracies / error buildup and eventually simulation explosion.

The truth is that is doesn't get any simpler than Jacobsens paper so if you can't understand that ..

Cool. I understand now, thanks :)