Physics engine

Blitz3D Forums/Blitz3D Beginners Area/Physics engine

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

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