Physics again

Blitz3D Forums/Blitz3D Beginners Area/Physics again

Destroyer(Posted 2004) [#1]
Ok i found this link on BlitzCoder.

http://www.blitzcoder.com/cgi-bin/ubb-cgi/postdisplay.cgi?forum=Forum3&topic=001350
(scroll down for the code)

It has some 2D basic physics code of a 2d cube.

What would it take to convert this so i could move a 3D cube around using the createcube() command???

Thanks

DESTROYER :)


Destroyer(Posted 2004) [#2]
Ok ive played about with the code and this is wot ive come up with :(

(I think im getting there lol :) )

AppTitle "Verlet basics"

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Global cam = CreateCamera()

Global cube = CreateCube()

Global light = CreateLight()

PositionEntity cube,1,1,10
EntityType cube,1

plane=CreatePlane()
PositionEntity plane,0,-1,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Global PHY_GRAVITY# = 9.8 ; Gravity decides how much the particles are pulled towards the ground.
Global PHY_TIMESTEP# = 0.05 ; The timestep is how much the physics engine will progress per PHY_Update.
Global PHY_ITERATIONS% = 5 ; More iterations gives more accuracy while less iterations give more speed.

; Constraints are the lines between the particles that keep them in a certain length from eachother.
Type PHY_Constraint
Field p1.PHY_Particle
Field p2.PHY_Particle
Field length#
End Type

; Particles are points that move based on their old positions, gravity and mass.
Type PHY_Particle
Field x#,y#,z#
Field ox#,oy#,oz#
Field mass#
End Type

; Create all particles (Normally this should be done in a function to avoid so much creation code.)
p1.PHY_Particle = New PHY_Particle
p1\x = 368
p1\y = 268
p1\z = 168
p1\ox = 368
p1\oy = 268
p1\oz = 168
p1\mass = 1.0

p2.PHY_Particle = New PHY_Particle
p2\x = 432
p2\y = 268
p2\z = 68
p2\ox = 432
p2\oy = 268
p2\oz = 68
p2\mass = 1.0

p3.PHY_Particle = New PHY_Particle
p3\x = 368
p3\y = 332
p3\ox = 368
p3\oy = 332
p3\mass = 1.0

p4.PHY_Particle = New PHY_Particle
p4\x = 432
p4\y = 332
p4\ox = 432
p4\oy = 332
p4\mass = 1.0

; Create all constraints.
c.PHY_Constraint = New PHY_Constraint
c\p1 = p1
c\p2 = p2
c\length = 64

c.PHY_Constraint = New PHY_Constraint
c\p1 = p1
c\p2 = p3
c\length = 64

c.PHY_Constraint = New PHY_Constraint
c\p1 = p2
c\p2 = p4
c\length = 64

c.PHY_Constraint = New PHY_Constraint
c\p1 = p3
c\p2 = p4
c\length = 64

; Diagonal lengths are Sqr(64 * 64 + 64 * 64)
c.PHY_Constraint = New PHY_Constraint
c\p1 = p1
c\p2 = p4
c\length = 90.5097

c.PHY_Constraint = New PHY_Constraint
c\p1 = p2
c\p2 = p3
c\length = 90.5097

While Not KeyHit(1)
Cls

; Let the user control one of the particles with the arrow keys.
If KeyDown(57) Then p1\y = p1\y - 5 ;space
If KeyDown(200) Then p1\z = p1\z + 5 ;up
If KeyDown(208) Then p1\z = p1\z - 5 ;down
If KeyDown(203) Then p1\x = p1\x - 5 ;left
If KeyDown(205) Then p1\x = p1\x + 5 ;right


; Apply forces to all the particles.
PHY_Verlet

; Make sure no particle leaves the screen.
For p.PHY_Particle = Each PHY_Particle
If p\x < 10 Then p\x = 10 ElseIf p\x > 790 Then p\x = 790
If p\y < 10 Then p\y = 10 ElseIf p\y > 590 Then p\y = 590
Next

; Enforce lengths of constraints.
PHY_SatisfyConstraints

; Draw all the constraints.
For c.PHY_Constraint = Each PHY_Constraint
Line c\p1\x,c\p1\y,c\p2\x,c\p2\y
Next

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

AlignToVector cube,p1\x,p1\y,p1\z,1
PointEntity cam,cube
UpdateWorld()
RenderWorld()
UpdateNormals cube
Text 0,0,"P1\X = "+p1\x
Text 0,12,"P1\Y = "+p1\Y
Text 0,24,"P1\Z = "+p1\z
Text 300,0,"Use Spacebar + Cursor keys"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Flip
Wend
End

; This function will make sure that all constraints try to keep their length. It will be better the higher PHY_ITERATIONS is.
Function PHY_SatisfyConstraints()
Local c.PHY_Constraint,p1.PHY_Particle,p2.PHY_Particle
Local m1#,m2#,dx#,dy#,dz#,deltalength#,diff#
Local i%

; Do everything PHY_ITERATIONS times.
For i = 1 To PHY_ITERATIONS
For c = Each PHY_Constraint
p1 = c\p1
p2 = c\p2

; Get difference in distance between the two particles.
dx = p2\x - p1\x
dy = p2\y - p1\y
dz = p2\z - p1\z
; Get the masses of the particles.
m1 = -p1\mass
m2 = -p2\mass

; Get the length between the particles.
deltalength = Sqr(dx * dx + dy * dy + dz * dz)
If deltalength <> 0.0 ; Avoid division by 0
; Get a factor of how much to move the particles from eachother.
diff = (deltalength - c\length) / (deltalength * (m1 + m2))

; Move the particles.
p1\x = p1\x + dx * m1 * diff
p1\y = p1\y + dy * m1 * diff
p1\z = p1\z + dz * m1 * diff
p2\x = p2\x - dx * m2 * diff
p2\y = p2\y - dy * m2 * diff
p2\z = p2\z - dz * m2 * diff
EndIf
Next
Next
End Function

; This function will move the particles.
Function PHY_Verlet()
Local p.PHY_Particle
Local x#,y#,z#,dx#,dy#,dz#

For p = Each PHY_Particle
; Save current position.
x = p\x
y = p\y
z = p\z
; Get the difference between the old and new positions.
dx = x - p\ox
dy = y - p\oy
dz = z - p\oz
; Move the particle based on the difference.
p\x = p\x + dx
p\z = p\z + dz
If p\mass > 0.0 ; Avoid division by zero
p\y = p\y + dy + PHY_GRAVITY / p\mass * PHY_TIMESTEP * PHY_TIMESTEP
Else
p\y = p\y + dy
EndIf

; Keep the previous position.
p\ox = x
p\oy = y
p\oz = z
Next
End Function

Can any body help out on this i just want the physics attached to the cube so it acts properly.

Thanks

DESTROYER