[bb] Verlet water :-) by Nate the Great [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:39

Previous topic - Next topic

BlitzBot

Title : Verlet water :-)
Author : Nate the Great
Posted : 1+ years ago

Description : This is a modified verlet system for simulating a water level.  The water level variable sets the waterlevel on the y axis and all verlets are affected by the water level.. If an object is too heavy it will sink.  Use arrow keys to move.

Code :
Code (blitzbasic) Select
Graphics3D 640,480,0,2
SeedRnd(MilliSecs())

Global WATERLEVEL = 0
waterpln = CreatePlane()
EntityColor waterpln,0,0,255
EntityAlpha waterpln,.5
MoveEntity waterpln,0,waterlevel,0

cam = CreateCamera()
MoveEntity cam,0,2,-30
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()
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
rid = rigidbodynum
rent = ent
rx# = EntityX(rent)
ry# = EntityY(rent)
rz# = EntityZ(rent)
ryaw# = EntityYaw(rent)
rpitch# = EntityPitch(rent)
roll# = EntityRoll(rent)



rv1.verlet = New verlet
rv1id = rigidbodynum
rv1x# = rx#-MeshWidth(rent)/2
rv1y# = ry#-MeshHeight(rent)/2
rv1z# = rz#-MeshDepth(rent)/2
rv1ox# = rx#-MeshWidth(rent)/2-.9
rv1oy# = ry#-MeshHeight(rent)/2-.2
rv1oz# = rz#-MeshDepth(rent)/2-.1
rv1ent = rent
rv1mass# = mass#/8
rv1piv = CreateSphere()
EntityAlpha rv1piv,alph
PositionEntity rv1piv,rv1x#,rv1y#,rv1z#

rv2.verlet = New verlet
rv2id = rigidbodynum
rv2x# = rx#-MeshWidth(rent)/2
rv2y# = ry#+MeshHeight(rent)/2
rv2z# = rz#+MeshDepth(rent)/2
rv2ox# = rx#-MeshWidth(rent)/2-.3
rv2oy# = ry#+MeshHeight(rent)/2-.3
rv2oz# = rz#+MeshDepth(rent)/2-.1
rv2ent = rent
rv2mass# = mass#/8
rv2piv = CreateSphere()
EntityAlpha rv2piv,alph
PositionEntity rv2piv,rv2x#,rv2y#,rv2z#

rv3.verlet = New verlet
rv3id = rigidbodynum
rv3x# = rx#-MeshWidth(rent)/2
rv3y# = ry#-MeshHeight(rent)/2
rv3z# = rz#+MeshDepth(rent)/2
rv3ox# = rx#-MeshWidth(rent)/2-.5
rv3oy# = ry#-MeshHeight(rent)/2-.1
rv3oz# = rz#+MeshDepth(rent)/2-.5
rv3ent = rent
rv3mass# = mass#/8
rv3piv = CreateSphere()
EntityAlpha rv3piv,alph
PositionEntity rv3piv,rv3x#,rv3y#,rv3z#

rv4.verlet = New verlet
rv4id = rigidbodynum
rv4x# = rx#-MeshWidth(rent)/2
rv4y# = ry#+MeshHeight(rent)/2
rv4z# = rz#-MeshDepth(rent)/2
rv4ox# = rx#-MeshWidth(rent)/2
rv4oy# = ry#+MeshHeight(rent)/2-.1
rv4oz# = rz#-MeshDepth(rent)/2
rv4ent = rent
rv4mass# = mass#/8
rv4piv = CreateSphere()
EntityAlpha rv4piv,alph
PositionEntity rv4piv,rv4x#,rv4y#,rv4z#

rv5.verlet = New verlet
rv5id = rigidbodynum
rv5x# = rx#+MeshWidth(rent)/2
rv5y# = ry#+MeshHeight(rent)/2
rv5z# = rz#+MeshDepth(rent)/2
rv5ox# = rx#+MeshWidth(rent)/2
rv5oy# = ry#+MeshHeight(rent)/2-.2
rv5oz# = rz#+MeshDepth(rent)/2
rv5ent = rent
rv5mass# = mass#/8
rv5piv = CreateSphere()
EntityAlpha rv5piv,alph
PositionEntity rv5piv,rv5x#,rv5y#,rv5z#

rv6.verlet = New verlet
rv6id = rigidbodynum
rv6x# = rx#+MeshWidth(rent)/2
rv6y# = ry#+MeshHeight(rent)/2
rv6z# = rz#-MeshDepth(rent)/2
rv6ox# = rx#+MeshWidth(rent)/2
rv6oy# = ry#+MeshHeight(rent)/2-.15
rv6oz# = rz#-MeshDepth(rent)/2
rv6ent = rent
rv6mass# = mass#/8
rv6piv = CreateSphere()
EntityAlpha rv6piv,alph
PositionEntity rv6piv,rv6x#,rv6y#,rv6z#

rv7.verlet = New verlet
rv7id = rigidbodynum
rv7x# = rx#+MeshWidth(rent)/2
rv7y# = ry#-MeshHeight(rent)/2
rv7z# = rz#-MeshDepth(rent)/2
rv7ox# = rx#+MeshWidth(rent)/2
rv7oy# = ry#-MeshHeight(rent)/2-.15
rv7oz# = rz#-MeshDepth(rent)/2
rv7ent = rent
rv7mass# = mass#/8
rv7piv = CreateSphere()
EntityAlpha rv7piv,alph
PositionEntity rv7piv,rv7x#,rv7y#,rv7z#

rv8.verlet = New verlet
rv8id = rigidbodynum
rv8x# = rx#+MeshWidth(rent)/2
rv8y# = ry#-MeshHeight(rent)/2
rv8z# = rz#+MeshDepth(rent)/2
rv8ox# = rx#+MeshWidth(rent)/2
rv8oy# = ry#-MeshHeight(rent)/2-.15
rv8oz# = rz#+MeshDepth(rent)/2
rv8ent = rent
rv8mass# = mass#/8
rv8piv = CreateSphere()
EntityAlpha rv8piv,alph
PositionEntity rv8piv,rv8x#,rv8y#,rv8z#

rcpiv = CreatePivot()
PositionEntity rcpiv,rx#,ry#,rz#


For v.verlet = Each verlet
If vID = rigidbodynum Then
If idle = 0 Then
For vv.verlet = Each verlet
If vvid = rigidbodynum Then
If vvpiv <> vpiv
c.constraint = New constraint
cp1.verlet = v.verlet
cp2.verlet = vv.verlet
dx# = cp1x# - cp2x#
dy# = cp1y# - cp2y#
dz# = cp1z# - cp2z#
clength# = Sqr(dx#*dx# + dy#*dy# + dz#*dz#)
cent = cp1ent
EndIf
EndIf
Next
EndIf
EndIf
Next


For c.constraint = Each constraint
For cc.constraint = Each constraint
If cp1piv = ccp1piv And cp2piv = cp1piv Then
Delete cc.constraint
EndIf
Next
Next

End Function



Function updateverlets()


For v.verlet = Each verlet
vcollided = False
vvx# = (vx# - vox#)*.985 ; Get the velocities of the verlet,...add a bit of decay to simulate friction
vvy# = (vy# - voy#)*.985
vvz# = (vz# - voz#)*.985

vox# = vx# ; store position in "old"
voy# = vy#
voz# = vz#

vx# = vx# + vvx# ;store new postion based on velocity

vy# = vy# + vvy# - .007

vz# = vz# + vvz#

;check screen bounds
If vy# < -4 ;ground collision
vy# = -4
vcollided = True
vvy# = -vvy#
EndIf

If vy# < waterlevel Then
dtmp# = waterlevel-vy#
If dtmp# > 1 Then
voy# = voy# - .02
Else
voy# = voy# - .02*dtmp#
EndIf
EndIf
Next


End Function



Function drawstuff()
;For v.verlet = Each verlet
;VertexCoords vsurf,vindex,vx#,vy#,vz#
;Next

For r.rigidbody = Each rigidbody
cnt = 0
avgx# = 0
avgy# = 0
avgz# = 0
For v.verlet = Each verlet
If vent = rent
cnt = cnt + 1
avgx# = avgx# + vx#
avgy# = avgy# + vy#
avgz# = avgz# + vz#
PositionEntity vpiv,vx#,vy#,vz#
EndIf
Next
avgx# = avgx#/cnt
avgy# = avgy#/cnt
avgz# = avgz#/cnt

rx# = avgx#
ry# = avgy#
rz# = avgz#

RotateEntity rent,0,0,0
PositionEntity rent,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( rv5piv ) - EntityX( rv2piv ) + EntityX( rv6piv ) - EntityX( rv4piv )
y# = EntityY( rv5piv ) - EntityY( rv2piv ) + EntityY( rv6piv ) - EntityY( rv4piv )
z# = EntityZ( rv5piv ) - EntityZ( rv2piv ) + EntityZ( rv6piv ) - EntityZ( rv4piv )
AlignToVector rent, x#,y#,z#,1  
x# = EntityX( rv5piv ) - EntityX( rv6piv ) + EntityX( rv2piv ) - EntityX( rv4piv )
y# = EntityY( rv5piv ) - EntityY( rv6piv ) + EntityY( rv2piv ) - EntityY( rv4piv )
z# = EntityZ( rv5piv ) - EntityZ( rv6piv ) + EntityZ( rv2piv ) - EntityZ( rv4piv )
AlignToVector rent, x#,y#,z#, 3




Next
End Function


Function updateconstraints()

For a = 1 To 10
For c.constraint = Each constraint
dx#=cp2x# - cp1x#
dy#=cp2y# - cp1y#
dz#=cp2z# - cp1z#

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# - clength#) / length#  ; vector length minus constraint length
Else
diff# = 0
EndIf

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

If cp1collided = 0 Or a > 8 Then
cp1x# = cp1x# + diff# * dx#
cp1y# = cp1y# + diff# * dy#
cp1z# = cp1z# + diff# * dz#
EndIf
If cp2collided = 0 Or a > 8 Then
cp2x# = cp2x# - diff# * dx#
cp2y# = cp2y# - diff# * dy#
cp2z# = cp2z# - diff# * dz#
EndIf
Next  ;constraints
Next


End Function



Function equalizeverlets()

;For c.constraint = Each constraint
; If clength# = 0 Then
; dx#=cp2x# + cp1x#
; dy#=cp2y# + cp1y#
; dz#=cp2z# + cp1z#
;
; dx# = dx# * .5 ;find the midpoint
; dy# = dy# * .5
; dz# = dz# * .5
;
; cp2x# = dx#
; cp2y# = dy#
; cp2z# = dz#
;
; cp1x# = dx#
; cp1y# = dy#
; cp1z# = dz#
;
; EndIf
;Next

End Function



Function rotatephysicsentity(ent)

For r.rigidbody = Each rigidbody
If rent = ent Then
tmppiv = CreatePivot()
PositionEntity tmppiv,rx#,ry#,rz#
EndIf
Next

End Function


Comments :


GW(Posted 1+ years ago)

 Pretty Neat!if you turn off vsync, the program wont run. [div by 0]


Nate the Great(Posted 1+ years ago)

 oh oops im not sure why that happens?


Difference(Posted 1+ years ago)

 My guess is framecounter delta = 0


Nate the Great(Posted 1+ years ago)

 oh this doesnt use delta timing sorry :/it just goes as fast as it can