experiments in Spherical Terrains

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

experiments in Spherical Terrains

Post by applePi »

1- Earth simulation, download these 2 files:
https://upload.wikimedia.org/wikipedia/ ... vation.jpg
http://eoimages.gsfc.nasa.gov/images/im ... 0x2700.jpg
Or from http://wikisend.com/download/543368/Elevation.rar for the 2 pictures
and save them to the same code folder
for a future project you may need https://commons.wikimedia.org/wiki/File ... nscale.JPG
i choose Elevation.jpg for its beauty and not its reality

i suggest to compile in OpenGL mode (compiler->compiler Options->Library subsystem) because the texture on the earth is stable and does not flicker like it is in default (dx9) in winxp32, may be good in win7++
Image
works only on PB 5.50 ... instructions on the title bar
save this as file sun.particle

Code: Select all

particle_system Space/Sun
 {
    material        Examples/Flare
    particle_width  30
    particle_height 30
    cull_each       false
    quota           1000
    billboard_type  point
 
    // Area emitter
    emitter Ellipsoid
    {
        angle           30
        emission_rate   20
        time_to_live_min 2
        time_to_live_max 10
        direction       0 0 1
        velocity       0.001
        colour 0.15 0.1 0.0
        width           5
        height          5
        depth           5
    }
 
    // Fader
    affector ColourFader
    {
        red -0.010
        green -0.025
        blue -0.025
    }
 }

Code: Select all

UsePNGImageDecoder()
UseJPEGImageDecoder()

Define texture.s = "Elevation.jpg"
Define heightMap.s = "world.topo.bathy.200410.3x5400x2700.jpg"

Enumeration
  #Camera
  #sphere
  #axis 
  #particle
  #particle_mat
EndEnumeration

Global Dim MeshData.PB_MeshVertex(0)

#CameraSpeed = 2

Declare Terrain()

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(".", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

If OpenWindow(0, 0, 0, DesktopW, DesktopH, "W wire/solid Frame ....mouse+arrow keys for the camera ")
  If OpenWindowedScreen(WindowID(0), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    Parse3DScripts()
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, 0, 120, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)
        
    CreateMaterial(1, LoadTexture(1, "Geebee2.bmp"))
    MaterialCullingMode(1, #PB_Material_NoCulling)
    
    CreateMaterial(0, LoadTexture(0, texture)) ;texturing the sphere (earth)
    MaterialCullingMode(0, #PB_Material_NoCulling)
    
    CreateLight(0, RGB(255, 255, 255), 100, 100, 100)
    AmbientColor(RGB(200, 200, 200))
  
  EndIf
EndIf

Global.l TileCountX = 200, TileCountZ = 100 ; number of squares acroos x, and acroos z
Global Dim TerrainData.l(TileCountX-1, TileCountZ-1)
LoadImage(0, heightMap)
ResizeImage(0, TileCountX, TileCountZ)
StartDrawing(ImageOutput(0))
 For z=0 To TileCountZ-1
   For x=0 To TileCountX-1
   colr=Point(x,z)
     TerrainData(x,z)=Red(colr)
   Next
 Next
 StopDrawing()
 
 ;*******************************************

CreateSphere(#sphere, 20, TileCountX-1,TileCountZ-1); TileSizeX, TileSizeZ) ;200 X 100
CreateEntity(#sphere,MeshID(#sphere),MaterialID(0), 0, 0, 0)

wireFrame = 1

Terrain()
CreateCylinder(#axis, 1,50)
CreateEntity(#axis, MeshID(#axis), MaterialID(1))
Global Earth = CreateEntity(#PB_Any,0,0) ; we want compound object from sphere and axis
AddSubEntity(Earth, #sphere, #PB_Entity_SphereBody) ;first component of compound
AddSubEntity(Earth, #axis, #PB_Entity_CylinderBody) ; sec component of compound
;CreateEntityBody(Earth, #PB_Entity_CompoundBody)
RotateEntity(Earth, 0,0, -23.4)

;the sun
LoadTexture(#particle_mat, "flare.png")
CreateMaterial(#particle_mat, TextureID(#particle_mat))
DisableMaterialLighting(#particle_mat, 1)
MaterialBlendingMode(#particle_mat, #PB_Material_Add)
	
GetScriptParticleEmitter(#particle, "Space/Sun")
MoveParticleEmitter(#particle, 0,0,0)
ParticleMaterial(#particle, MaterialID(#particle_mat))

angle.f = 1
Global earthX.f = 0, earthZ.f = 60
Global radius.f = Sqr(earthX*earthX+earthZ*earthZ) 
rot = 1
orbit = 1
a$ = "W wire/solid Frame ....mouse+arrows: camera .... Space/Z: rotations .... U/D/F: camera positions "
Repeat
  Repeat 
  Until WindowEvent()=0
          
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
                
      If ExamineKeyboard()
           
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
        
                
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
            MaterialShadingMode(0, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(0, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
      EndIf
      
      If KeyboardReleased(#PB_Key_D)
        MoveCamera(#Camera, 0, -200, 1, #PB_Absolute)
        CameraLookAt(#Camera,0,0,0)
      ElseIf KeyboardReleased(#PB_Key_U)
        MoveCamera(#Camera, 0, 200, 1, #PB_Absolute)
        CameraLookAt(#Camera,0,0,0)
      ElseIf KeyboardReleased(#PB_Key_F)
        MoveCamera(#Camera, 0, 0, 120, #PB_Absolute)
        CameraLookAt(#Camera,0,0,0)
      ElseIf KeyboardReleased(#PB_Key_Space)
        orbit ! 1
        ElseIf KeyboardReleased(#PB_Key_Z)
        rot ! 1
              
      EndIf
      

      
      If orbit
        ang.f + 0.2 ; determine the rotational speed
        earthX = radius * Sin(Radian(ang)) ; formula for the circular motion
        earthZ = radius * Cos(Radian(ang)) ; formula for the circular motion
      
        MoveEntity(Earth, earthX, 0, earthZ, #PB_Absolute)
        ;EntityLookAt(Earth, 0, 0, 0)
        EndIf
                  
      EndIf
                  
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
  
      RotateEntity(Earth, 0,rot/3,0, #PB_Relative)
      
      SetWindowTitle(0, "FPS = "+Str(Engine3DStatus(#PB_Engine3D_CurrentFPS ))+"  "+a$)
      
      RenderWorld()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End

  
 Procedure Terrain()

 GetMeshData(#sphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal  , 0, MeshVertexCount(#sphere)-1)
   
 c=0 
 For y = 0 To TileCountZ-1
       For x = 0 To TileCountX-1
         height.f = TerrainData(x,y)/200 ; reduce the height too much
         nx.f = MeshData(c)\NormalX
         ny.f = MeshData(c)\NormalY
         nz.f = MeshData(c)\NormalZ
         
         MeshData(c)\x + nx * height 
         MeshData(c)\y + ny * height 
         MeshData(c)\z + nz * height
         
         c+1
       Next
 Next 
     
   SetMeshData(#sphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(#sphere)-1)     
   NormalizeMesh(#sphere)
   UpdateMeshBoundingBox(#sphere)
    
 EndProcedure
2- i have found this funny shape ,
Image

by using this picture as a height map :save this picture (selectgradient.jpg) in the same folder as the code
Image
you can save the resulting mesh and use it any time, you can print it on a 3D printer
same code as above just changing dimensions and reposition the camera
PB 5.50

Code: Select all

UsePNGImageDecoder()
UseJPEGImageDecoder()

Enumeration
  #Camera
  #ball
  #sphere
         
EndEnumeration

Global Dim MeshData.PB_MeshVertex(0)

#CameraSpeed = 2

Declare Terrain()

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(".", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

If OpenWindow(0, 0, 0, DesktopW, DesktopH, "W wire/solid Frame ....mouse+arrow keys for the camera ")
  If OpenWindowedScreen(WindowID(0), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 0, -50, 100, #PB_Absolute)
    
    CameraLookAt(#Camera,0,45,0)
    CameraBackColor(#Camera, RGB(254,236,186))
    
    CreateMaterial(1, LoadTexture(1, "Geebee2.bmp"))
    MaterialCullingMode(1, #PB_Material_NoCulling)
    
    CreateMaterial(0, LoadTexture(0, "selectgradient.jpg"))
    MaterialCullingMode(0, #PB_Material_NoCulling)
    
    CreateLight(0, RGB(255, 255, 255), 100, 100, 0)
    AmbientColor(RGB(100, 100, 100))
  
  EndIf
EndIf

Global.l TileCountX = 100, TileCountZ = 100 ; number of squares acroos x, and acroos z
                                        ;Global Dim TerrainData.l(TileCountX, TileCountZ)
Global Dim TerrainData.l(TileCountX-1, TileCountZ-1)
LoadImage(0, "selectgradient.jpg");"earthmap1k.jpg")
ResizeImage(0, TileCountX, TileCountZ)
StartDrawing(ImageOutput(0))
 For z=0 To TileCountZ-1
   For x=0 To TileCountX-1
   colr=Point(x,z)
     TerrainData(x,z)=Red(colr)
   Next
 Next
 StopDrawing()
 
 ;*******************************************

CreateSphere(#sphere, 20, TileCountX-1,TileCountZ-1); TileSizeX, TileSizeZ) ;99 X99
CreateEntity(#sphere,MeshID(#sphere),MaterialID(0), 0, 0, 0)

MaterialShadingMode(0, #PB_Material_Wireframe)
wireFrame = 0

Terrain()
CreateEntityBody(#sphere, #PB_Entity_StaticBody ,1,1,1)
UpdateMeshBoundingBox(#sphere)

CreateSphere(#ball,3)
CreateEntity(#ball, MeshID(#ball  ), MaterialID(1), 0,100,0)
CreateEntityBody(#ball, #PB_Entity_ConvexHullBody  ,1,1,1)
WorldGravity(-20) ; the gravity here is twice the normal


Repeat
  Repeat 
  Until WindowEvent()=0
          
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
                
      If ExamineKeyboard()
           
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
        
                
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
            MaterialShadingMode(0, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(0, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
            
      EndIf
      DisableEntityBody(#sphere, #False)
                        
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      
      RotateEntity(#sphere, 0,0.1,0, #PB_Relative)
      RenderWorld()
           
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End

  
 Procedure Terrain()

 GetMeshData(#sphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal  , 0, MeshVertexCount(#sphere)-1)
   
 c=0 : dist.f : u.f: v.f
 For y = 0 To TileCountZ-1
       For x = 0 To TileCountX-1
         height.f = TerrainData(x,y)/1
         nx.f = MeshData(c)\NormalX
         ny.f = MeshData(c)\NormalY
         nz.f = MeshData(c)\NormalZ
         
         MeshData(c)\x + nx * height 
         MeshData(c)\y + ny * height 
         MeshData(c)\z + nz * height
         
         c+1
       Next
 Next 
     
   SetMeshData(#sphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(#sphere)-1)     
   NormalizeMesh(#sphere)
   UpdateMeshBoundingBox(#sphere)
   ;SaveMesh(#sphere, "BizzareSphere.mesh")     
 EndProcedure
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5353
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: experiments in Spherical Terrains

Post by Kwai chang caine »

The planet is splendid :shock:
The second code works like a charm two
Thanks, it's always a real discovery to test your splendids sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: experiments in Spherical Terrains

Post by DK_PETER »

Good examples, applePi.
Concerning first example:
The contours are a bit too high. Personally I would change the value from 200 to 450.
height.f = TerrainData(x,y)/200 ; Change to 450..Seems more real.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Post Reply