How to get water height?
Posted: Fri Jun 20, 2025 12:41 pm
Is there any way to detect the height of the water created with 'CreateWater(' to simulate floating objects?
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
; ------------------------------------------------------------
;
; PureBasic - Water
;
; (c) Fantaisie Software
;
; ------------------------------------------------------------
; with rusty barrels added
;#################################################################################################################
#end_distance=1024*4
Procedure ColorBlend(color1.l, color2.l, blend.f)
Protected r.w,g.w,b.w,a.w
r= Red(color1) + (Red(color2) - Red(color1)) * blend
g=Green(color1) + (Green(color2) - Green(color1)) * blend
b= Blue(color1) + (Blue(color2) - Blue(color1)) * blend
a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
ProcedureReturn RGBA(r,g,b,a)
EndProcedure
InitEngine3D():InitSprite():InitKeyboard():InitMouse()
ExamineDesktops():dx=DesktopWidth(0)*0.9:dy=DesktopHeight(0)*0.9
OpenWindow(0, 0,0, DesktopUnscaledX(dx),DesktopUnscaledY(dy), " Water - [PageUp][PageDown] Sun height [F12] Wireframe [Esc] quit",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, dx, dy, 0, 0, 0)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
Parse3DScripts()
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0,0,5,0):CameraLookAt(0,2,5,10)
;sky
tx_sky=LoadTexture(#PB_Any,"sky.png")
SkyDome(TextureID(tx_sky),$cc6600,$0088ff,3,400,-0.5,0)
;ocean
tx_water=LoadTexture(#PB_Any,"waternormal.png")
tx_foam=LoadTexture(#PB_Any,"foam.png")
CreateWater(TextureID(tx_water),TextureID(tx_foam), $cc888800,$886666, #end_distance, 1.5,1.2,0.2,0.7)
;ground
tx_ground=LoadTexture(#PB_Any,"Dirt.jpg")
CreateMaterial(2,TextureID(tx_ground))
CreatePlane(2,#end_distance*2,#end_distance*2,16,16,#end_distance/64,#end_distance/64)
CreateEntity(2,MeshID(2),MaterialID(2),0,-50,0)
CreateEntityBody(2, #PB_Entity_StaticBody,100)
; barrel
tx_barrel=LoadTexture(#PB_Any,"RustyBarrel.png")
tx_rusty =LoadTexture(#PB_Any,"RustySteel.jpg")
CreateMaterial(3, TextureID(tx_barrel))
CreateMaterial(4, TextureID(tx_rusty))
LoadMesh(3,"Barrel.mesh")
For i.i = 1 To 100
CreateEntity(i+10, MeshID(3), MaterialID(3), Random(1000)-Random(1000),Random(1000,1),Random(1000)-Random(1000))
CreateEntityBody(i+10, #PB_Entity_CylinderBody, 1, 0.5, 0.5)
RotateEntity(i+10,Random(180)-Random(180),Random(180)-Random(180),Random(180)-Random(180))
Next
EnableWorldPhysics(1)
EnableWorldCollisions(1)
Procedure CameraUserControl(camera,speed.f=0.2,smooth.f=0.1,yfixed.f=1e10)
Static.f MouseX,Mousey,depx,depz,sdepx,sdepz
depx=-speed*(KeyboardPushed(#PB_Key_Left)-KeyboardPushed(#PB_Key_Right))
depz=-speed*(KeyboardPushed(#PB_Key_Down)-KeyboardPushed(#PB_Key_Up)-MouseWheel()*20)
MouseX = -MouseDeltaX() * 0.05
MouseY = -MouseDeltaY() * 0.05
RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
sdepx+(depx-sdepx)*smooth
sdepz+(depz-sdepz)*smooth
MoveCamera (camera, sdepX, 0, -sdepz)
If yfixed<>1e10:MoveCamera(camera,CameraX(camera),yfixed,CameraZ(camera),#PB_Absolute):EndIf
EndProcedure
WorldGravity(0)
Define.f r=1,rr
Repeat
While WindowEvent():Wend
ExamineKeyboard()
ExamineMouse()
If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
CameraUserControl(0,0.2,0.1)
; sun height
r+(KeyboardPushed(#PB_Key_PageUp)-KeyboardPushed(#PB_Key_PageDown))*0.004:If r<0:r=0:ElseIf r>1:r=1:EndIf:rr=Pow(r,0.25)
CreateLight(0,ColorBlend($0088ff,$ffffff,rr),20000, r*40000,20000)
AmbientColor($010101*Int(r*48+64))
Fog(ColorBlend($004488,$ffccaa,r),1,0,#end_distance)
For i=1 To 100
If EntityY(i+10)<0
EntityRenderMode(i+10,#PB_Entity_DisplaySkeleton)
EntityVelocity(i+10,0.99 * GetEntityAttribute(i+10, #PB_Entity_LinearVelocityX),0.99 * GetEntityAttribute(i+10, #PB_Entity_LinearVelocityY),0.99 * GetEntityAttribute(i+10, #PB_Entity_LinearVelocityZ))
ApplyEntityForce(i+10,0,5.4,0)
SetEntityMaterial(i+10,MaterialID(4))
Else
ApplyEntityForce(i+10,0,-9.8,0)
EntityRenderMode(i+10,#PB_Entity_CastShadow)
SetEntityMaterial(i+10,MaterialID(3))
EndIf
Next
RenderWorld()
FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or MouseButton(3)
Code: Select all
; WaterBarrels.pb
; Barrel boyancy example based on:
; ------------------------------------------------------------
;
; PureBasic - Water
;
; (c) Fantaisie Software
;
; ------------------------------------------------------------
;#################################################################################################################
#end_distance = 1024 * 4
Procedure ColorBlend(color1.l, color2.l, blend.f)
Protected r.w, g.w, b.w, a.w
r = Red(color1) + (Red(color2) - Red(color1)) * blend
g = Green(color1) + (Green(color2) - Green(color1)) * blend
b = Blue(color1) + (Blue(color2) - Blue(color1)) * blend
a = Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
ProcedureReturn RGBA(r, g, b, a)
EndProcedure
InitEngine3D():InitSprite():InitKeyboard():InitMouse()
ExamineDesktops():dx = DesktopWidth(0) * 1:dy = DesktopHeight(0) * 1
OpenWindow(0, 0, 0, DesktopUnscaledX(dx), DesktopUnscaledY(dy), " Water - [PageUp][PageDown] Sun height [F12] Wireframe [Esc] quit", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, dx, dy, 0, 0, 0)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
Parse3DScripts()
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0, 0, 150, 350):CameraLookAt(0, 2, 5, 10)
CreateCamera(1, 80, 0, 20, 20):MoveCamera(1, 0, -45, 150):CameraLookAt(1, 2, 0, 10)
;sky
tx_sky = LoadTexture(#PB_Any, "sky.png")
SkyDome(TextureID(tx_sky), $cc6600, $0088ff, 3, 400, -0.5, 0)
;ocean
tx_water = LoadTexture(#PB_Any, "waternormal.png")
tx_foam = LoadTexture(#PB_Any, "foam.png")
CreateWater(TextureID(tx_water), TextureID(tx_foam), $cc888800, $886666, #end_distance, 1.5, 1.2, 0.2, 0.7)
;ground
tx_ground = LoadTexture(#PB_Any, "Dirt.jpg")
CreateMaterial(2, TextureID(tx_ground))
CreatePlane(2, #end_distance * 2, #end_distance * 2, 16, 16, #end_distance / 64, #end_distance / 64)
CreateEntity(2, MeshID(2), MaterialID(2), 0, -50, 0)
CreateEntityBody(2, #PB_Entity_StaticBody, 100)
; barrel
tx_barrel = LoadTexture(#PB_Any, "RustyBarrel.png")
tx_rusty = LoadTexture(#PB_Any, "RustySteel.jpg")
CreateMaterial(3, TextureID(tx_barrel))
CreateMaterial(4, TextureID(tx_rusty))
;alternate material
mat_red = GetScriptMaterial( - 1, "Color/Red")
mat_green = GetScriptMaterial( - 1, "Color/Green")
mat_blue = GetScriptMaterial( - 1, "Color/Blue")
mat_yellow = GetScriptMaterial( - 1, "Color/Yellow")
LoadMesh(3, "Barrel.mesh")
Define BarrelVertices
BarrelVertices = MeshVertexCount(3)
;Debug "Barrel has "+FormatNumber(BarrelVertices,0)+" vertices, "+FormatNumber(BarrelVertices/3)+" faces???"
Dim BarrelVertex.MeshVertex(BarrelVertices + 1)
GetMeshData(3, 0, BarrelVertex(), #PB_Mesh_Vertex, 0, BarrelVertices - 1)
;WorldShadows(#PB_Shadow_Modulative,500) ; DOESNT WORK :(
#MAX_BARRELS = 250
For i.i = 1 To #MAX_BARRELS
CreateEntity(i + 10, MeshID(3), MaterialID(3), Random(200) - Random(200), Random(200, 1), Random(200) - Random(200), 1 << 7)
; ScaleEntity(i+10,0.334,0.334,0.334,#PB_Absolute)
CreateEntityBody(i + 10, #PB_Entity_CylinderBody, 1, 0.5, 0.5)
RotateEntity(i + 10, Random(180) - Random(180), Random(180) - Random(180), Random(180) - Random(180))
SetEntityAttribute(i + 10, #PB_Entity_Restitution, 0.5)
EntityRenderMode(i + 10, #PB_Entity_CastShadow)
Next
SetEntityMaterial(11, MaterialID(mat_red))
SetEntityMaterial(12, MaterialID(mat_blue))
SetEntityMaterial(13, MaterialID(mat_yellow))
SetEntityMaterial(14, MaterialID(mat_green))
EnableWorldPhysics(1)
EnableWorldCollisions(1)
Procedure CameraUserControl(camera, speed.f = 0.2, smooth.f = 0.1, yfixed.f = 1e10)
Static.f MouseX, Mousey, depx, depz, sdepx, sdepz
depx = - speed * (KeyboardPushed(#PB_Key_Left) - KeyboardPushed(#PB_Key_Right))
depz = - speed * (KeyboardPushed(#PB_Key_Down) - KeyboardPushed(#PB_Key_Up) - MouseWheel() * 20)
MouseX = - MouseDeltaX() * 0.05
MouseY = - MouseDeltaY() * 0.05
RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
sdepx + (depx - sdepx) * smooth
sdepz + (depz - sdepz) * smooth
MoveCamera (camera, sdepX, 0, - sdepz)
If yfixed <> 1e10:MoveCamera(camera, CameraX(camera), yfixed, CameraZ(camera), #PB_Absolute):EndIf
EndProcedure
Procedure ApplyBarrelWaterForces(Entity, Boyancy.f, Gravity.f)
Shared BarrelVertex()
Shared BarrelVertices
Protected i
Protected id = EntityID(Entity)
Protected wavesmall.f = GetWorldAttribute(#PB_Water_WaveHeight) + GetWorldAttribute(#PB_Water_WaveSmall)
Protected bellow_count
Protected friction_factor.f
Protected final_friction.f
Protected Boyancy2.f = Boyancy / BarrelVertices
Protected Gravity2.f = Gravity / BarrelVertices
Protected gx.f, gy.f, gz.f
Protected e2
; Check for every barrel vertex if it's bellow water surface (wavesmall) or above
While i < BarrelVertices
ConvertLocalToWorldPosition(id, BarrelVertex(i)\x, BarrelVertex(i)\y, BarrelVertex(i)\z)
gx = GetX()
gy = GetY()
gz = GetZ()
; e2 = RayPick(gx,wavesmall+2,gz,gx,gy,gz,1) ; Raypick doesn't work for now
If e2 = #PB_World_WaterPick Or gy <= wavesmall ; Bellow Water
bellow_count + 1
; apply boyancy on local entity vertex
ApplyEntityForce(Entity, 0, Boyancy2, 0, BarrelVertex(i)\x, BarrelVertex(i)\y, BarrelVertex(i)\z, #PB_World, #PB_Local)
Else
; apply gravitation on local entity vertex
ApplyEntityForce(Entity, 0, Gravity2, 0, BarrelVertex(i)\x, BarrelVertex(i)\y, BarrelVertex(i)\z, #PB_World, #PB_Local)
EndIf
i + 1
Wend
; ratio of vertices bellow water (for global water
friction_factor = bellow_count / BarrelVertices
final_friction = 1 - (friction_factor * 0.025) ; tweak here, seems ok
EntityVelocity(Entity, final_friction * GetEntityAttribute(Entity, #PB_Entity_LinearVelocityX), final_friction * GetEntityAttribute(Entity, #PB_Entity_LinearVelocityY), final_friction * GetEntityAttribute(Entity, #PB_Entity_LinearVelocityZ))
ApplyEntityTorque(Entity, - GetEntityAttribute(Entity, #PB_Entity_AngularVelocityX) * final_friction, - GetEntityAttribute(Entity, #PB_Entity_AngularVelocityY) * final_friction, - GetEntityAttribute(Entity, #PB_Entity_AngularVelocityZ) * final_friction)
EndProcedure
WorldGravity(0)
Define.f r = 1, rr
Repeat
While WindowEvent():Wend
ExamineKeyboard()
ExamineMouse()
If KeyboardReleased(#PB_Key_F12):fdf = 1 - fdf:If fdf:CameraRenderMode(0, #PB_Camera_Wireframe):Else:CameraRenderMode(0, #PB_Camera_Textured):EndIf:EndIf
CameraUserControl(0, 0.2, 0.1)
; sun height
r + (KeyboardPushed(#PB_Key_PageUp) - KeyboardPushed(#PB_Key_PageDown)) * 0.004:If r < 0:r = 0:ElseIf r > 1:r = 1:EndIf:rr = Pow(r, 0.25)
CreateLight(0, ColorBlend($0088ff, $ffffff, rr), 20000, r * 40000, 20000)
AmbientColor($010101*Int(r * 48 + 64))
Fog(ColorBlend($004488, $ffccaa, r), 1, 0, #end_distance)
; Reset barrel positions
If KeyboardReleased(#PB_Key_F1)
; immerge all entities
For i = 11 To #MAX_BARRELS + 10
MoveEntity(i, EntityX(i), Random(500, 50), EntityZ(i), #PB_Absolute)
ApplyEntityTorque(i, Random(3600) - Random(3600), Random(3600) - Random(3600), Random(3600) - Random(3600))
Next
ElseIf KeyboardReleased(#PB_Key_F2)
; submerge all entities
For i = 11 To #MAX_BARRELS + 10
MoveEntity(i, EntityX(i), -45 , EntityZ(i), #PB_Absolute)
ApplyEntityTorque(i, Random(3600) - Random(3600), Random(3600) - Random(3600), Random(3600) - Random(3600))
Next
ElseIf KeyboardReleased(#PB_Key_F3)
For i = 11 To #MAX_BARRELS + 10
MoveEntity(i, EntityX(i), 0, EntityZ(i), #PB_Absolute)
ApplyEntityTorque(i, Random(3600) - Random(3600), Random(3600) - Random(3600), Random(3600) - Random(3600))
Next
EndIf
; Apply forces
For i = 1 To #MAX_BARRELS
ApplyBarrelWaterForces(i + 10, 7.4, -9.8)
Next
RenderWorld()
FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or MouseButton(3) Or event = #PB_Event_CloseWindow