flattening a sphere to make a circular flat plane

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

flattening a sphere to make a circular flat plane

Post by applePi »

to continue this thread: http://purebasic.fr/english/viewtopic.p ... 2&start=60 so the project can be seen.
to flatten a sphere we copy only its vertices x,z coordinates
xa.f=MeshData(c)\x
zb.f=MeshData(c)\z
set the MeshData(c)\y to some formula not what is necessary for making the sphere so we get the 2D surface with the waves represented by MeshData(c)\y
if setting MeshData(c)\y=0 then we get perfect disk, press 'V' to save disk02.mesh .
uncomment line 125
TransformMesh(0, 0, 0, 0, 1, 0, 1, 0, 0, 0)
;SaveMesh(0,"disk01.mesh")
to save a flat disk before entering the repeat loop. check it with the Bananenfreak model viewer attached below for its convenience (not perfect but usable: may needs some fine tunning)
i have used the DK_PETER suggestion for the waves formula suitable to trap the balls and cubes:
MeshData(c)\y=yy+Cos(dtime + (Sqr(Pow(0.7*xa,2)+Pow(0.4*zb,2))))*50
but primarily giving the object a static geometry so the ball can go between its bumps. and if you want uncomment line EntityPhysicBody(0, #PB_Entity_ConvexHullBody , 1, 1, 1) so it will fall down and can be raised up if we press 'space' for make the bridge lift it

there are still several questions to answer and investigate.

Edit: i forgot to say that since this example use the Bridge.pb demo from the PureBasic\Example\3D for its convenience you need only to look at this subject related code from line 113: ;the flatten sphere + procedure UpdateMatrix. very short and simple code.
to show the wireframe press 'W', for solidframe press 'S'

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - PointJoint (Bridge)
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 1
#NbPlanks = 30
#NbX=30
#NbZ=30

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Global flag=0

Declare UpdateMatrix()

Define.f KeyX, KeyY, MouseX, MouseY
Dim Plank(#NbPlanks)

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;Materials
    ;
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    
    ; Ground
    ;
    CreatePlane(3, 500, 500, 5, 5, 5, 5)
    CreateEntity(3,MeshID(3),MaterialID(3), 0, -50, 0)
    EntityRenderMode(3, 0) 
    EntityPhysicBody(3, #PB_Entity_BoxBody, 0, 1, 1)
    
    ; Bridge
    CreateCube(1, 1.0)
    For i = 1 To #NbPlanks
      Plank(i)=CreateEntity(#PB_Any, MeshID(1), MaterialID(0))
      ScaleEntity(Plank(i), 2.8, 0.8, 20)
      MoveEntity(Plank(i), i * 3, 0, 0, #PB_Absolute)
      EntityPhysicBody(Plank(i), #PB_Entity_BoxBody, 1.0)
    Next i
    
    Pas.f = 1.5
    PointJoint(#PB_Any, EntityID(Plank(1)), -Pas, 0, -5)
    For i= 1 To #NbPlanks-2
      Joint=PointJoint(#PB_Any, EntityID(Plank(i+1)), -Pas, 0, -5, EntityID(Plank(i)), Pas, 0, -5)
    Next i
    PointJoint(#PB_Any, EntityID(Plank(#NbPlanks)),  Pas, 0, -5)
    PointJoint(#PB_Any, EntityID(Plank(#NbPlanks-1)),  Pas, 0, -5, EntityID(Plank(#NbPlanks)), -Pas, 0, -5)
    
    PointJoint(#PB_Any, EntityID(Plank(1)), -Pas, 0, 5)
    For i= 1 To #NbPlanks-2
      Joint=PointJoint(#PB_Any, EntityID(Plank(i+1)),  -Pas, 0, 5, EntityID(Plank(i)), Pas, 0, 5)
    Next i
    PointJoint(#PB_Any, EntityID(Plank(#NbPlanks)),  Pas, 0, 5)
    toto=PointJoint(#PB_Any, EntityID(Plank(#NbPlanks-1)),  Pas, 0, 5, EntityID(Plank(#NbPlanks)), -Pas, 0, 5)
    
    ; Objects
    ;
    CreateSphere(2, 3, 30, 30)
    
    C = Plank(1)
    For i = 1 To #NbPlanks/2
      Perso = CreateEntity(#PB_Any, MeshID(2), MaterialID(1), EntityX(C) +i * 5, EntityY(C)+ i * 4, EntityZ(C))
      EntityPhysicBody(Perso, #PB_Entity_SphereBody, 1.0, 0.3, 0.5)
    Next i
    
    For i = 1 To #NbPlanks/2
      Perso = CreateEntity(#PB_Any, MeshID(1), MaterialID(2), EntityX(C) +i * 5, EntityY(C)+ i * 6, EntityZ(C))
      ScaleEntity(Perso, 3, 3, 3)
      EntityPhysicBody(Perso, #PB_Entity_BoxBody, 1.0)
    Next i
    
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, -20, 60, -140, #PB_Absolute)
    CameraLookAt(0, EntityX(C) + 45, EntityY(C) + 10,  EntityZ(C))
    
    ; Skybox
    ;
    SkyBox("desert07.jpg")
    
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(255, 255, 255))
    
    Plank = 1
    
  ;the flatten sphere  
  CreateMaterial(4, LoadTexture(4, "MRAMOR6X6.jpg"))
  ;MaterialShadingMode(4, #PB_Material_Wireframe)  
  CreateSphere(0,20,30,30)
  CreateEntity(0, MeshID(0), MaterialID(4), 70,10,0)
    
  ScaleEntity(0, 3, 0.1, 3)
  ;EntityPhysicBody(0, #PB_Entity_ConvexHullBody , 1, 1, 1)
  EntityPhysicBody(0, #PB_Entity_StaticBody , 1, 1, 1)
  
  ;TransformMesh(#Mesh, x, y, z, ScaleX, ScaleY, ScaleZ, RotateX, RotateY, RotateZ [, SubMesh])
  TransformMesh(0, 0, 0, 0, 1, 0, 1, 0, 0, 0)
  ;SaveMesh(0,"disk01.mesh") ; will save a flattened sphere (disk)
  
  GetMeshData(0,0, MeshData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0, 0)-1)
  ;GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
    
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      
      If ExamineKeyboard()
        If KeyboardReleased(#PB_Key_W)
          MaterialShadingMode(4, #PB_Material_Wireframe)
        ElseIf KeyboardReleased(#PB_Key_S)
          MaterialShadingMode(4, #PB_Material_Solid)
        EndIf
        
        If KeyboardReleased(#PB_Key_V)
          SaveMesh(0, "disk02.mesh")
        EndIf
        
        
        If KeyboardPushed(#PB_Key_Space)
          ApplyEntityImpulse(Plank(#NbPlanks/2), 0, 9, 0)
        EndIf
        If KeyboardReleased(#PB_Key_Return)
          
          If Plank <= #NbPlanks
            DisableEntityBody(Plank(Plank), 0)
            FreeEntityJoints(Plank(Plank))
            Plank + 1  
          EndIf  
          
        EndIf      
        
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      RotateEntity(0, 0,0.2,0, #PB_Relative)
      ; Waves
      
      UpdateMatrix()
      
      
      
      RenderWorld()
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End


Procedure UpdateMatrix()
 
  dtime.f=ElapsedMilliseconds()/600 ; reduce 600 to get speedier animation
  
  For b=0 To #Nbz
    For a=0 To #NbX
      xa.f=MeshData(c)\x
      zb.f=MeshData(c)\z
      ;yy.f= MeshData(c)\y
      ;new y vertex coordinates
      ;MeshData(c)\y=yy+Cos(dtime + (Sqr(Pow(0.5*xa,2)+Pow(0.5*zb,2))))*20
      MeshData(c)\y=yy+Cos(dtime + (Sqr(Pow(0.7*xa,2)+Pow(0.4*zb,2))))*50
      ;MeshData(c)\y=0 ; uncomment to flatten the sphere completely
      c + 1 ; vertex number

    Next a
  Next b
  
  SetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(0, 0)-1)
  ;EntityPhysicBody(0, #PB_Entity_ConvexHullBody , 1, 1, 1)
  EntityPhysicBody(0, #PB_Entity_StaticBody , 1, 1, 1)
EndProcedure
Bananenfreak model viewer (easy to use for viewing the .mesh files but needs fine tunning, used without his permission)

Code: Select all

EnableExplicit


Define.f KeyX, KeyY, MouseX, MouseY
Define nx.f, nz.f, Boost.f = 1, Yaw.f, Pitch.f
Define.i Quit, boden, mesh
Define.s path
Define meshsize.f
#kam_0 = 0
#window = 0
#plane = 0
#planent = 1

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts", #PB_3DArchive_FileSystem)
  ;Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  ExamineDesktops()
  OpenWindow(#window, 0, 0, DesktopWidth(0), DesktopHeight(0), "3D-Template", #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(#window), 10, 10, DesktopWidth(0), DesktopHeight(0), 0, 10, 10, #PB_Screen_SmartSynchronization)
  
  
  Parse3DScripts()
  WorldShadows(#PB_Shadow_TextureAdditive, 200, RGB(255 * 0.2, 255 * 0.2, 255 * 0.2), 4096)
  
  CreateLight(33,RGB(255,255,255),-100,40,30)
  AmbientColor(RGB(255,255,255))
  ;AmbientColor(RGB(255 * 0.2, 255 * 0.2, 255 * 0.2))
  
  ;- Ground
    ;
    CreateMaterial(0, LoadTexture(0, "snow_1024.jpg"))
    CreatePlane(#plane, 500, 500, 40, 40, 15, 15)
    CreateEntity(#plane,MeshID(#plane),MaterialID(0))
    EntityRenderMode(#plane, 0)
  
  ;-Camera
  CreateCamera(#kam_0, 0, 0, 100, 100)
  MoveCamera(#kam_0, 0, 25, -10, #PB_Absolute)
  CameraLookAt(#kam_0, 0, 0, 20)
  CameraRange (#kam_0, 2, 5000)
  CameraFOV   (#kam_0, 90)
  ;CameraBackColor(#kam_0, RGB(0, 0, 0))
  
  
  path = OpenFileRequester("Choose file to load", "", "OGRE-Mesh (*.mesh)|*.mesh", 0, 0)
  
  If Not Add3DArchive(GetPathPart(path), #PB_3DArchive_FileSystem)
    MessageRequester("Error", "Path can´t be solved!" + Chr(10) + GetPathPart(path))
  EndIf
  
  CreateMaterial(1, LoadTexture(1, "wood.jpg"))
  MaterialCullingMode(1, #PB_Material_NoCulling)
  MaterialShadingMode(1, #PB_Material_Wireframe)
  
  mesh = LoadMesh(#PB_Any, GetFilePart(path))
  meshsize.f = MeshRadius(mesh)
  ;Debug "MeshRadius = " + Str(meshsize)
  CreateEntity(23,MeshID(mesh), MaterialID(1),0,15,0) 
  ScaleEntity(23,4/meshsize,4/meshsize,4/meshsize)
  
  If Not mesh
    MessageRequester("Error", "This file isn't a mesh!" + Chr(10) + GetFilePart(path))
  EndIf
  
  
  Repeat
    If ExamineMouse()
      Yaw   = -MouseDeltaX() * 0.05
      Pitch = -MouseDeltaY() * 0.05
    EndIf
    
    If ExamineKeyboard()
      
      If KeyboardPushed(#PB_Key_Up)    
        MoveCamera(0,  0, 0, -0.3 * Boost)
      ElseIf KeyboardPushed(#PB_Key_Down)
        MoveCamera(0,  0, 0,  0.3 * Boost)
      EndIf 
      
      If KeyboardPushed(#PB_Key_Left)  
        MoveCamera(0, -0.3 * Boost, 0, 0) 
      ElseIf KeyboardPushed(#PB_Key_Right)
        MoveCamera(0,  0.3 * Boost, 0, 0)
      EndIf 
      
    EndIf

    RotateCamera(0, Pitch, Yaw, 0, #PB_Relative)
    RotateEntity(23,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
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: flattening a sphere to make a circular flat plane

Post by applePi »

Tea Cup from the flattened sphere
this is the practical man method to make a tea cup or any concave pot, since the sphere are ready implemented with many triangles connected mysteriously to make a sphere.
1- we first flatten the sphere, look post 1 above
2-determine the vertexes at the disk circumference from the circle equation x^2+y^2=r^2 , approximately, look line 147 : if pow(....
3-reposition the vertex y up : MeshData(c)\y + 300
4- if we do this only we will get a vertical cup, but we want the cup walls to be tilted slightly like a cone, so we must reposition the x,z on a wider circle slightly

there is a problem when we specify the material as MaterialCullingMode(4, #PB_Material_NoCulling )
Edit: TransformMesh have transformed the y < 0 to 0 so the other side of the sphere are still available even it is flat . so we should delete that piece and then the lighting will be normal, and the MaterialCullingMode(4, #PB_Material_NoCulling ) will work. will try later

Image

Code: Select all

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 2

#Nb = 50 ; number of sphere Segments and Rings
#Radius = 4


Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

Declare UpdateMatrix()

Define.f KeyX, KeyY, MouseX, MouseY

InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  ExamineDesktops()
  OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press W for wire frame, press S for Solid ,____ move by keyboard and mouse", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)   
  
      
    ;WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;Materials
    ;
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    
    ; Ground
    ;
    CreatePlane(3, 500, 500, 5, 5, 5, 5)
    CreateEntity(3,MeshID(3),MaterialID(3), 0, 0, 0)
    EntityRenderMode(3, 0) 
    EntityPhysicBody(3, #PB_Entity_BoxBody, 0, 1, 1)
    
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 20, -25, #PB_Absolute)
    CameraLookAt(0, 0,7,0)
    
    ; Skybox
    ;
    SkyBox("desert07.jpg")
    
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(255, 255, 255))
  
    CreateMaterial(4, LoadTexture(4, "ValetCoeur.jpg"))
    ;MaterialCullingMode(4, #PB_Material_NoCulling )
 
  ; the main sphere we want to deform it
  CreateSphere(0,#Radius,#Nb,#Nb)
  CreateEntity(0, MeshID(0), MaterialID(4), 0,1,0)
  
  ;TransformMesh(#Mesh, x, y, z, ScaleX, ScaleY, ScaleZ, RotateX, RotateY, RotateZ [, SubMesh])
  TransformMesh(0, 0, 0, 0, 1, 0, 1, 0, 0, 0) ; note scaleY = 0
    
  GetMeshData(0,0, MeshData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0, 0)-1)
  ;GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
  UpdateMatrix() ; build the tea cup from the flatten sphere
  UpdateMeshBoundingBox(0)
  
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      
      If ExamineKeyboard()
        If KeyboardReleased(#PB_Key_W)
          MaterialShadingMode(4, #PB_Material_Wireframe)
        ElseIf KeyboardReleased(#PB_Key_S)
          MaterialShadingMode(4, #PB_Material_Solid)
        EndIf
        
        If KeyboardReleased(#PB_Key_V)
          SaveMesh(0, "disk02.mesh")
        EndIf
     
        
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      RotateEntity(0, 0,0.2,0, #PB_Relative)
           
      RenderWorld()
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1


End


Procedure UpdateMatrix()
 
    
  For b=0 To #Nb ; number of sphere Segments , Rings
    
    For a=0 To #Nb
     
      xx.f=MeshData(c)\x
      zz.f=MeshData(c)\z
      ;checking if the vertex position on the circle Circumference
      If Pow((MeshData(c)\x),2) + Pow((MeshData(c)\z),2) >= (#Radius*#Radius)-1 ;circle equation x^2+y^2=r^2
        angle.f= ATan2(xx,zz)
        ;Debug StrF(xx)+"  "+StrF(zz)
        ;Debug StrF((#Radius)*Cos(angle)) +"   " +StrF((#Radius)*Sin(angle))
        MeshData(c)\y + 12
        MeshData(c)\x = (#Radius+1)*Cos(angle) ; the upper cup position is on a wider circle Radius by +1 
        MeshData(c)\z = (#Radius+1)*Sin(angle)
      EndIf
      
      c + 1 ; vertex number

    Next a
  Next b
  
  SetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(0, 0)-1)
  ;EntityPhysicBody(0, #PB_Entity_ConvexHullBody , 1, 1, 1)
  EntityPhysicBody(0, #PB_Entity_StaticBody , 1, 1, 2)
EndProcedure
Edit: added UpdateMeshBoundingBox(0)
Last edited by applePi on Fri Jun 12, 2015 2:15 pm, edited 1 time in total.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: flattening a sphere to make a circular flat plane

Post by applePi »

stretch the vertexes from place between center and circumference will produce a coffee cub, note that if you need other Radius then choose values from the output of debug line 143
Image

Code: Select all

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
Procedure.d Truncate (number.d, places.l) ; code from Little John , Aug 03, 2008
   Protected f.l

   f = Pow(10, places)
   ProcedureReturn Int(number*f) / f
 EndProcedure
#CameraSpeed = 1

#Nb = 50 ; number of sphere Segments and Rings
#Radius = 4


Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

Declare MakeCup()

Define.f KeyX, KeyY, MouseX, MouseY

InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  ExamineDesktops()
  OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press W toggle wireframe/ solidFrame ,____ move by keyboard and mouse", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)   
  
      
    ;WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;Materials
    ;
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    
    ; Ground
    ;
    CreatePlane(3, 500, 500, 5, 5, 5, 5)
    CreateEntity(3,MeshID(3),MaterialID(3), 0, 0, 0)
    EntityRenderMode(3, 0) 
    EntityPhysicBody(3, #PB_Entity_BoxBody, 0, 1, 1)
    
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 20, -25, #PB_Absolute)
    CameraLookAt(0, 0,7,0)
    
    ; Skybox
    ;
    SkyBox("desert07.jpg")
    
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(255, 255, 255))
  
    CreateMaterial(4, LoadTexture(4, "dirt.jpg"))
    ;MaterialCullingMode(4, #PB_Material_NoCulling )
 
  ; the main sphere we want to deform it
  CreateSphere(0,#Radius,#Nb,#Nb)
  CreateEntity(0, MeshID(0), MaterialID(4), 0,1,0)
  
  ;TransformMesh(#Mesh, x, y, z, ScaleX, ScaleY, ScaleZ, RotateX, RotateY, RotateZ [, SubMesh])
  TransformMesh(0, 0, 0, 0, 1, 0, 1, 0, 0, 0) ; note scaleY = 0

  MakeCup()
  
  wireFrame = 1
  Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      
      If ExamineKeyboard()
        
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
           MaterialShadingMode(4, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
          MaterialShadingMode(4, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
        
        If KeyboardReleased(#PB_Key_V)
          SaveMesh(0, "disk02.mesh")
        EndIf
     
        
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      RotateEntity(0, 0,0.2,0, #PB_Relative)
           
      RenderWorld()
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1


End

Procedure MakeCup()
   GetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(0)-1)
  ;GetMeshData(#TempSphere,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#TempSphere, 0)-1)
  
  For c=0 To MeshVertexCount(0,0)-1
    xx.f=MeshData(c)\x
    zz.f=MeshData(c)\z 
    Debug Sqr(Pow((MeshData(c)\x),2) + Pow((MeshData(c)\z),2))
    
    r.f = Sqr(Pow((xx),2) + Pow((zz),2)) ;circle equation x^2+y^2=r^2 . "-1" is the uncertainty in position
    r.f = Truncate (r, 6)
    If r = 1.927014 ; the radius from which we want to stretch vertexes up
    ;If r = 3.999999 Or r = 4.000000  ; the vertexes on the remote edge
        angle.f= ATan2(xx,zz) 
        
        MeshData(c)\y + 6
        MeshData(c)\x = (#Radius+0)*Cos(angle) ; the upper cup position is on a wider circle Radius by +... 
        MeshData(c)\z = (#Radius+0)*Sin(angle)
    EndIf
  Next
  SetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(0, 0)-1)
  ;EntityPhysicBody(0, #PB_Entity_StaticBody, 1, 0.2, 1)  
  EndProcedure
all the above code are dealing with a flatten complete sphere, so the disk are still have 2 sides , suitable for physics collisions.
but now we make a half sphere by dropping all vertexes with Y < 0, then we flatten it to disk with one face only, then we stretch it from the desired points
we have 3 procedures
HalfSphere()
FlattenHalfSphere()
MakeCup()

comment the FlattenHalfSphere() and the MakeCup and we will get a good half sphere
Note: all objects suffer from shadow problems, the last example can't have physics on its walls at all. so if you want physics use the double faces disk flatten from a full sphere

Code: Select all

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
Procedure.d Truncate (number.d, places.l) ; code from Little John , Aug 03, 2008
   Protected f.l

   f = Pow(10, places)
   ProcedureReturn Int(number*f) / f
 EndProcedure
 
#CameraSpeed = 0.1

#Nb = 50 ; number of sphere Segments and Rings
#Radius = 4
#TempSphere = 30

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

Global flag=0

Declare HalfSphere()
Declare FlattenHalfSphere()
Declare MakeCup()

Define.f KeyX, KeyY, MouseX, MouseY

InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  ExamineDesktops()
  OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press W for wireframe/ SolidFrame ,____ move by keyboard and mouse", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)   
      
    ;Materials
    CreateMaterial(0, LoadTexture(0, "ground_diffuse.png"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    CreateMaterial(5, LoadTexture(5, "snow_1024.jpg"))
    MaterialCullingMode(5, #PB_Material_NoCulling )
        
    ; Ground
    CreatePlane(3, 200, 200, 5, 5, 5, 5)
    CreateEntity(3,MeshID(3),MaterialID(5), 0, 0, 0)
    EntityPhysicBody(3, #PB_Entity_BoxBody, 0, 1, 1)
    
    ; Camera
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 20, -20, #PB_Absolute)
    CameraLookAt(0, 0,7,0)
    CameraBackColor(0, RGB(224,225,241))
    
    CreateLight(0, RGB(255, 255, 255), 200, 300, 0)
    
    AmbientColor(RGB(255, 255, 255))
    
    ;WorldShadows(#PB_Shadow_Modulative  , -1, RGB(100, 100, 100))
    ;WorldShadows(#PB_Shadow_Additive)
    ;WorldShadows(#PB_Shadow_TextureAdditive)
    
    CreateMaterial(4, LoadTexture(4, "ValetCoeur.jpg"))
    MaterialCullingMode(4, #PB_Material_NoCulling )
    MaterialShadingMode(4, #PB_Material_Wireframe)
  
    HalfSphere()

    FinishMesh(1)
  
  CreateEntity(7, MeshID(7), MaterialID(4), 0,3,0)
  
  FlattenHalfSphere() ; build the tea cup from the flatten sphere
 
  MakeCup()
wireFrame = 0
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.3
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.3
      EndIf
      
      If ExamineKeyboard()
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
           MaterialShadingMode(4, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
          MaterialShadingMode(4, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
      
        
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      RotateEntity(7, 0,0.2,0, #PB_Relative)
           
      RenderWorld()
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

End
Procedure HalfSphere()
CreateMesh(7, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)

  CreateSphere(#TempSphere,#Radius, #Nb, #Nb)
  GetMeshData(#TempSphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(#TempSphere)-1)
  GetMeshData(#TempSphere,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#TempSphere, 0)-1)
  ArrSize = ArraySize(MeshData())
 
   For c=0 To ArrSize
      
      x.f = MeshData(c)\x 
      y.f = MeshData(c)\y
      z.f = MeshData(c)\z
      
      If y >= 0 ; to discard the sphere bottom in which the MeshData(c)\y < 0
         MeshVertexPosition(x,y,z)
         MeshVertexTextureCoordinate(MeshData(c)\u, MeshData(c)\v) 
         MeshVertexNormal(MeshData(c)\NormalX, MeshData(c)\NormalY, MeshData(c)\NormalZ)
         
      EndIf   
   Next   
   
   ArrSizeInd = ArraySize(MeshDataInd())/2-((#Nb*6)+6) ; every square = 2 triangles = 6 vertexes
   
   For i=0 To ArrSizeInd Step 3 
     MeshFace(MeshDataInd(i)\Index, MeshDataInd(i+1)\Index,MeshDataInd(i+2)\Index)
   Next  
 EndProcedure

Procedure FlattenHalfSphere()
 
  c=0 
  GetMeshData(7,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(7, 0)-1)
  GetMeshData(7,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(7, 0)-1)
  
  For c=0 To MeshVertexCount(7,0)-1
     MeshData(c)\y = 0
  
  Next
      
      
  SetMeshData(7,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(7, 0)-1)
    
  ;EntityPhysicBody(7, #PB_Entity_ConvexHullBody , 1, 0.1, 1)
  ;EntityPhysicBody(7, #PB_Entity_StaticBody , 1, 1, 2)
EndProcedure
 
 Procedure MakeCup()
  
   For c=0 To MeshVertexCount(7,0)-1
    xx.f=MeshData(c)\x
    zz.f=MeshData(c)\z 
    Debug Sqr(Pow((MeshData(c)\x),2) + Pow((MeshData(c)\z),2))
    
    r.f = Sqr(Pow((xx),2) + Pow((zz),2)) ;circle equation x^2+y^2=r^2 . "-1" is the uncertainty in position
    
    r.f = Truncate (r, 6)
    ;If r = 1.927014 ; the radius from which we want to stretch vertexes up
    If r > 3.9   ; the vertexes on the remote edge
        angle.f= ATan2(xx,zz)
        
        MeshData(c)\y + 6
        MeshData(c)\x = (#Radius+0)*Cos(angle) ; the upper cup position is on a wider circle Radius by +... 
        MeshData(c)\z = (#Radius+0)*Sin(angle)
    EndIf
  Next
  SetMeshData(7,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(7, 0)-1)
    
  EndProcedure
    
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: flattening a sphere to make a circular flat plane

Post by DK_PETER »

Good examples applePi. We/I appreciate your work.
I have one question, though.
For some reason, your cup examples disappears way too soon, when you
align the camera horizontally with the cup and tilt
the camera slowly upwards.
Do you any idea why this happens?

Here I've added a normal sphere entity instead.
The entity doesn't disappear anymore when tilting the camera.

Code: Select all

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 0.1

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

Global flag=0

Declare HalfSphere()
Declare FlattenHalfSphere()
Declare MakeCup()

Define.f KeyX, KeyY, MouseX, MouseY

InitEngine3D()
 
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
  ExamineDesktops()
  OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press W for wireframe/ SolidFrame ,____ move by keyboard and mouse", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)   
     
    ;Materials
    CreateMaterial(0, LoadTexture(0, "ground_diffuse.png"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    CreateMaterial(5, LoadTexture(5, "snow_1024.jpg"))
    MaterialCullingMode(5, #PB_Material_NoCulling )
       
    ; Ground
    CreatePlane(3, 200, 200, 5, 5, 5, 5)
    CreateEntity(3,MeshID(3),MaterialID(5), 0, 0, 0)
    EntityPhysicBody(3, #PB_Entity_BoxBody, 0, 1, 1)
   
    ; Camera
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 20, -20, #PB_Absolute)
    CameraLookAt(0, 0,7,0)
    CameraBackColor(0, RGB(224,225,241))
   
    CreateLight(0, RGB(255, 255, 255), 200, 300, 0)
   
    AmbientColor(RGB(255, 255, 255))
   
    ;WorldShadows(#PB_Shadow_Modulative  , -1, RGB(100, 100, 100))
    ;WorldShadows(#PB_Shadow_Additive)
    ;WorldShadows(#PB_Shadow_TextureAdditive)
   
    CreateMaterial(4, LoadTexture(4, "ValetCoeur.jpg"))
    MaterialCullingMode(4, #PB_Material_NoCulling )
    MaterialShadingMode(4, #PB_Material_Wireframe)
    CreateSphere(3, 3, 20, 20)
    CreateEntity(7, MeshID(3), MaterialID(4), 0,3,0)
 

wireFrame = 0
    Repeat
      Screen3DEvents()
     
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.3
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.3
      EndIf
     
      If ExamineKeyboard()
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
           MaterialShadingMode(4, #PB_Material_Wireframe)
          wireFrame ! 1
        Else
          MaterialShadingMode(4, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
     
       
        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
       
      EndIf
     
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      RotateEntity(7, 0,0.2,0, #PB_Relative)
           
      RenderWorld()
      
      FlipBuffers()
     
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

End
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.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: flattening a sphere to make a circular flat plane

Post by applePi »

Thank you DK_PETER , yes i have noticed this phenomena while testing the examples. especially the tea cup with color over the coffee cup but can't solve it, may be it is related to normal or tangents, also the problems with the shadow, the tea cup with color is in reality a full sphere but its up and down faces sticky to each other, then from this flatten disk we stretched the vertices which is near the outer side of the disk. it has the same number of vertices and triangles like the original sphere. i will test more.
but what annoys me is the lack of physics on the walls of the last example wich made from half sphere , not its bottom but its walls, as a test make the cup like a cone (#Radius+4):

Code: Select all

MeshData(c)\y + 6
 MeshData(c)\x = (#Radius+4)*Cos(angle) ; the upper cup position is on a wider circle Radius by +... 
 MeshData(c)\z = (#Radius+4)*Sin(angle)
and add sphere to fall on the walls, it will penetrate it,

Code: Select all

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
Procedure.d Truncate (number.d, places.l) ; code from Little John , Aug 03, 2008
   Protected f.l

   f = Pow(10, places)
   ProcedureReturn Int(number*f) / f
 EndProcedure
 
#CameraSpeed = 0.1

#Nb = 50 ; number of sphere Segments and Rings
#Radius = 4
#TempSphere = 30

Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)

Global flag=0

Declare HalfSphere()
Declare FlattenHalfSphere()
Declare MakeCup()

Define.f KeyX, KeyY, MouseX, MouseY

InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  ExamineDesktops()
  OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "press W for wireframe/ SolidFrame ,____ move by keyboard and mouse", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-10, 0, 0, 0)   
      
    ;Materials
    CreateMaterial(0, LoadTexture(0, "ground_diffuse.png"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    CreateMaterial(5, LoadTexture(5, "snow_1024.jpg"))
    MaterialCullingMode(5, #PB_Material_NoCulling )
        
    ; Ground
    CreatePlane(3, 200, 200, 5, 5, 5, 5)
    CreateEntity(3,MeshID(3),MaterialID(5), 0, 0, 0)
    EntityPhysicBody(3, #PB_Entity_BoxBody, 0, 1, 1)
    
    ; Camera
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 20, -20, #PB_Absolute)
    CameraLookAt(0, 0,7,0)
    CameraBackColor(0, RGB(224,225,241))
    
    CreateLight(0, RGB(255, 255, 255), 200, 300, 0)
    
    AmbientColor(RGB(255, 255, 255))
    
    ;WorldShadows(#PB_Shadow_Modulative  , -1, RGB(100, 100, 100))
    ;WorldShadows(#PB_Shadow_Additive)
    ;WorldShadows(#PB_Shadow_TextureAdditive)
    
    CreateMaterial(4, LoadTexture(4, "ValetCoeur.jpg"))
    MaterialCullingMode(4, #PB_Material_NoCulling )
    ;MaterialShadingMode(4, #PB_Material_Wireframe)
  
    HalfSphere()

    FinishMesh(1)
  
  CreateEntity(7, MeshID(7), MaterialID(4), 0,3,0)
  
  FlattenHalfSphere() ; build the tea cup from the flatten sphere
 
  MakeCup()
  
  CreateSphere(3, 1, 20, 20)
  CreateEntity(3, MeshID(3), MaterialID(5), 5,15,0)
  EntityPhysicBody(3, #PB_Entity_ConvexHullBody , 1, 0.5, 1)
  
wireFrame = 1
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.3
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.3
      EndIf
      
      If ExamineKeyboard()
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
           MaterialShadingMode(4, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
          MaterialShadingMode(4, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
      
        
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      RotateEntity(7, 0,0.2,0, #PB_Relative)
           
      RenderWorld()
      Screen3DStats()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

End
Procedure HalfSphere()
CreateMesh(7, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)

  CreateSphere(#TempSphere,#Radius, #Nb, #Nb)
  GetMeshData(#TempSphere,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(#TempSphere)-1)
  GetMeshData(#TempSphere,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(#TempSphere, 0)-1)
  ArrSize = ArraySize(MeshData())
 
   For c=0 To ArrSize
      
      x.f = MeshData(c)\x 
      y.f = MeshData(c)\y
      z.f = MeshData(c)\z
      
      If y >= 0 ; to discard the sphere bottom in which the MeshData(c)\y < 0
         MeshVertexPosition(x,y,z)
         MeshVertexTextureCoordinate(MeshData(c)\u, MeshData(c)\v) 
         MeshVertexNormal(MeshData(c)\NormalX, MeshData(c)\NormalY, MeshData(c)\NormalZ)
         
      EndIf   
   Next   
   
   ArrSizeInd = ArraySize(MeshDataInd())/2-((#Nb*6)+6) ; every square = 2 triangles = 6 vertexes
   
   For i=0 To ArrSizeInd Step 3 
     MeshFace(MeshDataInd(i)\Index, MeshDataInd(i+1)\Index,MeshDataInd(i+2)\Index)
   Next  
 EndProcedure

Procedure FlattenHalfSphere()
 
  c=0 
  GetMeshData(7,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(7, 0)-1)
  GetMeshData(7,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(7, 0)-1)
  
  For c=0 To MeshVertexCount(7,0)-1
     MeshData(c)\y = 0
  
  Next
      
      
  SetMeshData(7,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(7, 0)-1)
    
  ;EntityPhysicBody(7, #PB_Entity_ConvexHullBody , 1, 0.1, 1)
  EntityPhysicBody(7, #PB_Entity_StaticBody , 1, 1, 2)
EndProcedure
 
 Procedure MakeCup()
  
   For c=0 To MeshVertexCount(7,0)-1
    xx.f=MeshData(c)\x
    zz.f=MeshData(c)\z 
    ;Debug Sqr(Pow((MeshData(c)\x),2) + Pow((MeshData(c)\z),2))
    
    r.f = Sqr(Pow((xx),2) + Pow((zz),2)) ;circle equation x^2+y^2=r^2 . "-1" is the uncertainty in position
    
    r.f = Truncate (r, 6)
    ;If r = 1.927014 ; the radius from which we want to stretch vertexes up
    If r > 3.9   ; the vertexes on the remote edge
        angle.f= ATan2(xx,zz)
        
        MeshData(c)\y + 6
        MeshData(c)\x = (#Radius+4)*Cos(angle) ; the upper cup position is on a wider circle Radius by +... 
        MeshData(c)\z = (#Radius+4)*Sin(angle)
    EndIf
  Next
  SetMeshData(7,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(7, 0)-1)
    
  EndProcedure
    
this will not happened with the tea cup with color above, its wall have normal physics (remember it has 2 faces up and down sticky to each other).
a possible research and solutions :
making a cup not by stretching a thin vertexes around a circle, but let the triangles go up gradually and not condensed on the cup base only, so to get a cup walls made from several triangles, in concise distribute the triangles fairly over the whole object. this procedure will make the object more natural. but may be harder to work.
Post Reply