Page 1 of 1

MeshCentering suggested function

Posted: Sun Mar 08, 2015 4:34 pm
by applePi
in the following demo look at this part of the sphere , it will rotate around x axis in a circular orbit and not around itself, and this is natural since it (was) part of a sphere

now uncomment line 56 ChangeMesh() , and see the sphere part rotate around itself in x axis correctly. the procedure ChangeMesh() are from Comtois here: http://purebasic.fr/english/viewtopic.p ... 15#p417666 so i suggest to add it or an advanced version of it to purebasic functions
someone may say: why not using this procedure yourself ? because:
1- not every one know it, and several questions are asked in the forum about the models which rotate incorrectly around itself
2- it complements the RotateEntity function
3- it change the behavior of the model in an enjoyable way
4- using an explicit procedure will make the code more mysterious and longer.

Code: Select all

Enumeration
   
   #LIGHT
   #CAMERA
   #WorkSphereMesh = 555
   
EndEnumeration

#CameraSpeed = 0.5
Define.f KeyX, KeyY, MouseX, MouseY

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

Global mesh
ExamineDesktops()
If OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), " ... W.... to WireFrame/ SolidFrame ......use mouse + Arrows to rotate + move Camera ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

Define.f KeyX, KeyY

Declare CreateSpherePlus(mesh, radius.f, Segments, Rings, start.f, sphereParts.f)
Declare ChangeMesh()

If InitEngine3D()
  
  Add3DArchive(".", #PB_3DArchive_FileSystem)
  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()
  OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
                
    CreateCamera(#camera, 0, 0, 100, 100)
    MoveCamera(#camera, 0, 0, 12, #PB_Absolute)
    CameraFOV(#camera, 70)
    CameraBackColor(#camera, RGB(255,200,200))
    CameraLookAt(#camera,0,0,0)
        
    CreateLight(0, RGB(255,255,255), 20, 100, 0)
    AmbientColor(RGB(200, 200, 200))
 
    CreateMaterial(5, LoadTexture(5, "fw12b.jpg"))
    MaterialCullingMode(5, #PB_Material_NoCulling)
    MaterialShadingMode(5, #PB_Material_Wireframe)
    
    ;CreateSpherePlus(mesh, radius.f, Segments, Rings, start, sphereParts)
    CreateSpherePlus(1, 5, 32,32, 1,8) ; several rings from the sphere
    CreateEntity(0, MeshID(0), MaterialID(5) , 0,0,0)
    
    wireFrame = 0
    
    ;ChangeMesh()
        
    
    Repeat
      Event = WindowEvent()
        
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
                
      If ExamineKeyboard()
        
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
          MaterialShadingMode(5, #PB_Material_Wireframe)
          wireFrame ! 1
            Else 
          MaterialShadingMode(5, #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
        
     
        RotateEntity(0,1,0,0, #PB_Relative)
        
        RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End


Procedure CreateSpherePlus(mesh, radius.f, Segments, Rings, start.f, sphereParts.f)
  CreateMesh(0, #PB_Mesh_TriangleList, #True)
  
  CreateSphere(mesh,radius,Segments, Rings)

  ;TransformMesh(mesh,0,0,0, 1,1,1,0,0,0)
  GetMeshData(mesh,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate , 0, MeshVertexCount(mesh)-1)
  GetMeshData(mesh,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(mesh, 0)-1)
  ArrSize = ArraySize(MeshData())
  ;Debug ArrSize
  
  For c=0 To 200
      
      x.f = MeshData(c)\x 
      y.f = MeshData(c)\y
      z.f = MeshData(c)\z
      MeshVertexPosition(x,y,z)
      MeshVertexTextureCoordinate(MeshData(c)\u, MeshData(c)\v) 
      
  Next 
  
  ArrSizeInd = ArraySize(MeshDataInd()) 
  ;Debug ArrSizeInd
  ArrSizeInd = ArrSizeInd / sphereParts ; sphereParts is the number of sphere divisions we want
    
  For i=start To ArrSizeInd Step 3
     indx = i-1
     MeshFace(MeshDataInd(indx)\Index, MeshDataInd(indx+1)\Index,MeshDataInd(indx+2)\Index)
   Next
   
  FinishMesh(#True)
  
  GetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_UVCoordinate, 0, MeshVertexCount(0)-1)
  GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
  ;ArrSize = ArraySize(MeshData())
  ;Debug ArrSize
  
EndProcedure

Procedure ChangeMesh()
  Protected.f minx, miny, minz, maxx, maxy, maxz
  Protected.f corx, cory, corz
  minx =  999999
  miny =  999999
  minz =  999999
  maxx = -999999
  maxy = -999999
  maxz = -999999
  
  For i=0 To ArraySize(MeshData())
    If MeshData(i)\x > maxx
      maxx = MeshData(i)\x
    EndIf
    If MeshData(i)\x < minx
      minx = MeshData(i)\x
    EndIf    
    If MeshData(i)\y > maxy
      maxy = MeshData(i)\y
    EndIf
    If MeshData(i)\y < miny
      miny = MeshData(i)\y
    EndIf   
    If MeshData(i)\z > maxz
      maxz = MeshData(i)\z
    EndIf
    If MeshData(i)\z < minz
      minz = MeshData(i)\z
    EndIf       
  Next  
  corx = (-maxx - minx) /2.0
  cory = (-maxy - miny) /2.0
  corz = (-maxz - minz) /2.0
  
  MessageRequester("", "minx = " + StrF(minx,2) + Chr(10) +
                       "miny = " + StrF(miny,2) + Chr(10) +
                       "minz = " + StrF(minz,2) + Chr(10) +
                       "maxx = " + StrF(maxx,2) + Chr(10) +
                       "maxy = " + StrF(maxy,2) + Chr(10) +
                       "maxz = " + StrF(maxz,2) + Chr(10) +
                       "Correction x = " + StrF(corx,2) + Chr(10) +
                       "Correction y = " + StrF(cory,2) + Chr(10) +
                       "Correction z = " + StrF(corz,2), #PB_MessageRequester_Ok )
  For i=0 To ArraySize(MeshData())
    MeshData(i)\x + corx
    MeshData(i)\y + cory
    MeshData(i)\z + corz     
  Next  
  SetMeshData(0,0, MeshData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0)-1)
EndProcedure