Bounding box of non centered meshes

All bugs related to the 3D engine
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Bounding box of non centered meshes

Post by miso »

If I create or load a mesh, that is not centered around the origo, the bounding box of the physics body and the center of mass does not translate.
This applies to box, sphere, cylinder and capsule body. (I can manually rearrange the vertices though around 0,0,0)
Here's an example:

Code: Select all

Structure maincamerastructure :ID.i:x.f:y.f:z.f:ax.f:ay.f:az.f:tax.f:tay.f:taz.f:speed.f:EndStructure
#Vectorlength=25 :#castlength=100000 :#maxcamspeed = 5 :#mincamspeed = 0
Global maincamera.maincamerastructure
Global distance.f,vvectrornormalid.i,castvectorid.i,mousesensitivity.f=0.05,mdy.f,mdx.f

Procedure.f smooth(x.f,targetx.f)
  ProcedureReturn((0.9*x.f)+(0.1*targetx.f))
EndProcedure  

Procedure init()
  InitEngine3D()
  OpenWindow(0,10,10,800,600,"")
  InitSprite()
  OpenWindowedScreen(WindowID(0),0,0,800,600)
  InitMouse()
  InitKeyboard()
  EnableWorldPhysics(#True)
EndProcedure

Procedure checkevents()
  Repeat
  Until WindowEvent()=0
EndProcedure

Procedure setupcamera()
  maincamera\ID = CreateCamera(#PB_Any,0,0,100,100)
  MoveCamera(maincamera\ID,1,1,1,#PB_Absolute)
EndProcedure

Procedure updatecamera()
  maincamera\tax = maincamera\tax+mdy
  maincamera\tay = maincamera\tay-mdx
  maincamera\ax = smooth(maincamera\ax,maincamera\tax)
  maincamera\ay = smooth(maincamera\ay,maincamera\tay)
  maincamera\az = (maincamera\tay-maincamera\ay)/4 
  RotateCamera(maincamera\id,maincamera\ax,maincamera\ay,maincamera\az,#PB_Absolute)
  MoveCamera(maincamera\id,CameraX(maincamera\id)+(CameraDirectionX(maincamera\id)*maincamera\speed),CameraY(maincamera\id)+(CameraDirectionY(maincamera\id)*maincamera\speed),CameraZ(maincamera\id)+(CameraDirectionZ(maincamera\id)*maincamera\speed),#PB_Absolute)
EndProcedure

;// Centered around 0 works
Procedure.i createboxmesh_centered_around_0(x,y,z)
  Define returnvalue.i
  returnvalue = CreateMesh(#PB_Any,#PB_Mesh_TriangleList)
    MeshVertexPosition(-x/2,-y/2,z/2):MeshVertexPosition(x/2,-y/2,z/2):MeshVertexPosition(-x/2,-y/2,-z/2):MeshVertexPosition(x/2,-y/2,-z/2) 
    MeshVertexPosition(-x/2,y/2,z/2):MeshVertexPosition(x/2,y/2,z/2):MeshVertexPosition(-x/2,y/2,-z/2):MeshVertexPosition(x/2,y/2,-z/2)  
    MeshFace(2,1,0):MeshFace(3,1,2):MeshFace(4,5,6):MeshFace(6,5,7)
    MeshFace(2,6,7):MeshFace(2,7,3):MeshFace(3,7,5):MeshFace(3,5,1) 
    MeshFace(5,4,0):MeshFace(1,5,0):MeshFace(4,6,2):MeshFace(0,4,2)
    FinishMesh(returnvalue)
    UpdateMeshBoundingBox(returnvalue)
  ProcedureReturn returnvalue
  EndProcedure
  
;// It bugs with the physics
  Procedure.i createboxmesh_ON_Top_0(x,y,z)
  Define returnvalue.i
  returnvalue = CreateMesh(#PB_Any,#PB_Mesh_TriangleList)
    MeshVertexPosition(-x/2,0,z/2):MeshVertexPosition(x/2,0,z/2):MeshVertexPosition(-x/2,0,-z/2):MeshVertexPosition(x/2,0,-z/2)
    MeshVertexPosition(-x/2,y,z/2):MeshVertexPosition(x/2,y,z/2):MeshVertexPosition(-x/2,y,-z/2):MeshVertexPosition(x/2,y,-z/2)
    MeshFace(2,1,0):MeshFace(3,1,2):MeshFace(4,5,6):MeshFace(6,5,7)
    MeshFace(2,6,7):MeshFace(2,7,3):MeshFace(3,7,5):MeshFace(3,5,1)
    MeshFace(5,4,0):MeshFace(1,5,0):MeshFace(4,6,2):MeshFace(0,4,2)
    FinishMesh(returnvalue)
    UpdateMeshBoundingBox(returnvalue)
  ProcedureReturn returnvalue
  EndProcedure
  
Procedure createenvironment()
  mesh_A=CreatePlane(#PB_Any,10000,10000,1,1,1,1)
  surface = CreateEntity(#PB_Any,MeshID(mesh_A),#PB_Material_None,0,0,0)
  RotateEntity(surface,0,180,0)
  CreateEntityBody(surface,#PB_Entity_StaticBody)
  ;myboxmesh = createboxmesh_around_0(15,15,50) ;that is a workaround
  myboxmesh = createboxmesh_ON_Top_0(15,50,15)
  Dim cubes(100)
  For i=1 To 100
    ;cubes(i)=CreateEntity(#PB_Any,MeshID(mesh_B),MaterialID(material_B),-1000+Random(2000),55,-1000+Random(2000))
    cubes(i)=CreateEntity(#PB_Any,MeshID(myboxmesh),#PB_Material_None,-1000+Random(2000),55,-1000+Random(2000))
    RotateEntity(cubes(i),0,Random(360),0)
    CreateEntityBody(cubes(i),#PB_Entity_BoxBody)
  Next i
  setupcamera()
EndProcedure

Procedure rc()
  tx.f=CameraX(maincamera\id)+(CameraDirectionX(maincamera\id)*#castlength)
  ty.f=CameraY(maincamera\id)+(CameraDirectionY(maincamera\id)*#castlength)
  tz.f=CameraZ(maincamera\id)+(CameraDirectionZ(maincamera\id)*#castlength)
  rayhitbool = RayCast(CameraX(mainCamera\ID), CameraY(mainCamera\ID), CameraZ(maincamera\id), tX, ty, tz,-1)
  If rayhitbool
    CreateLine3D(vvectornormalid, PickX(), PickY(), PickZ(), RGB(255,0,0), PickX() + NormalX()*#vectorlength, PickY() + NormalY()*#vectorlength, PickZ() + NormalZ()*#vectorlength, RGB(255,255,127))
  EndIf
EndProcedure

Procedure checkinput()
  ExamineKeyboard()
  ExamineMouse()
  mdx=MouseDeltaX()*mousesensitivity
  mdy=-MouseDeltaY()*mousesensitivity
  If MouseButton(#PB_MouseButton_Right)
    maincamera\speed=smooth(maincamera\speed,#maxcamspeed)
  Else
    maincamera\speed=smooth(maincamera\speed,#mincamspeed)
  EndIf
  
  If KeyboardPushed(#PB_Key_Escape)
    CloseScreen()
    CloseWindow(0)
    End
  EndIf
EndProcedure

Procedure render()
  rc()
  RenderWorld()
  FlipBuffers()
EndProcedure

Procedure Run()
  init()
  createenvironment()
  WorldDebug(#PB_World_DebugBody)
  Repeat  
    checkevents()
    checkinput()
    updatecamera()
    render()
  ForEver
EndProcedure

run()
Edit: With convexhullbody seems OK, but the center of mass does not translate, is at 0,0,0.

Code: Select all

Structure maincamerastructure :ID.i:x.f:y.f:z.f:ax.f:ay.f:az.f:tax.f:tay.f:taz.f:speed.f:EndStructure
#Vectorlength=25 :#castlength=100000 :#maxcamspeed = 5 :#mincamspeed = 0
Global maincamera.maincamerastructure
Global distance.f,vvectrornormalid.i,castvectorid.i,mousesensitivity.f=0.05,mdy.f,mdx.f

Procedure.f smooth(x.f,targetx.f)
  ProcedureReturn((0.9*x.f)+(0.1*targetx.f))
EndProcedure  

Procedure init()
  InitEngine3D()
  OpenWindow(0,10,10,800,600,"")
  InitSprite()
  OpenWindowedScreen(WindowID(0),0,0,800,600)
  InitMouse()
  InitKeyboard()
  EnableWorldPhysics(#True)
EndProcedure

Procedure checkevents()
  Repeat
  Until WindowEvent()=0
EndProcedure

Procedure setupcamera()
  maincamera\ID = CreateCamera(#PB_Any,0,0,100,100)
  MoveCamera(maincamera\ID,1,1,1,#PB_Absolute)
EndProcedure

Procedure updatecamera()
  maincamera\tax = maincamera\tax+mdy
  maincamera\tay = maincamera\tay-mdx
  maincamera\ax = smooth(maincamera\ax,maincamera\tax)
  maincamera\ay = smooth(maincamera\ay,maincamera\tay)
  maincamera\az = (maincamera\tay-maincamera\ay)/4 
  RotateCamera(maincamera\id,maincamera\ax,maincamera\ay,maincamera\az,#PB_Absolute)
  MoveCamera(maincamera\id,CameraX(maincamera\id)+(CameraDirectionX(maincamera\id)*maincamera\speed),CameraY(maincamera\id)+(CameraDirectionY(maincamera\id)*maincamera\speed),CameraZ(maincamera\id)+(CameraDirectionZ(maincamera\id)*maincamera\speed),#PB_Absolute)
EndProcedure

;// Centered around 0 works
Procedure.i createboxmesh_centered_around_0(x,y,z)
  Define returnvalue.i
  returnvalue = CreateMesh(#PB_Any,#PB_Mesh_TriangleList)
    MeshVertexPosition(-x/2,-y/2,z/2):MeshVertexPosition(x/2,-y/2,z/2):MeshVertexPosition(-x/2,-y/2,-z/2):MeshVertexPosition(x/2,-y/2,-z/2) 
    MeshVertexPosition(-x/2,y/2,z/2):MeshVertexPosition(x/2,y/2,z/2):MeshVertexPosition(-x/2,y/2,-z/2):MeshVertexPosition(x/2,y/2,-z/2)  
    MeshFace(2,1,0):MeshFace(3,1,2):MeshFace(4,5,6):MeshFace(6,5,7)
    MeshFace(2,6,7):MeshFace(2,7,3):MeshFace(3,7,5):MeshFace(3,5,1) 
    MeshFace(5,4,0):MeshFace(1,5,0):MeshFace(4,6,2):MeshFace(0,4,2)
    FinishMesh(returnvalue)
    UpdateMeshBoundingBox(returnvalue)
  ProcedureReturn returnvalue
  EndProcedure
  
;// It bugs with the physics
  Procedure.i createboxmesh_ON_Top_0(x,y,z)
  Define returnvalue.i
  returnvalue = CreateMesh(#PB_Any,#PB_Mesh_TriangleList)
    MeshVertexPosition(-x/2,0,z/2):MeshVertexPosition(x/2,0,z/2):MeshVertexPosition(-x/2,0,-z/2):MeshVertexPosition(x/2,0,-z/2)
    MeshVertexPosition(-x/2,y,z/2):MeshVertexPosition(x/2,y,z/2):MeshVertexPosition(-x/2,y,-z/2):MeshVertexPosition(x/2,y,-z/2)
    MeshFace(2,1,0):MeshFace(3,1,2):MeshFace(4,5,6):MeshFace(6,5,7)
    MeshFace(2,6,7):MeshFace(2,7,3):MeshFace(3,7,5):MeshFace(3,5,1)
    MeshFace(5,4,0):MeshFace(1,5,0):MeshFace(4,6,2):MeshFace(0,4,2)
    FinishMesh(returnvalue)
    UpdateMeshBoundingBox(returnvalue)
  ProcedureReturn returnvalue
  EndProcedure
  
Procedure createenvironment()
  mesh_A=CreatePlane(#PB_Any,10000,10000,1,1,1,1)
  surface = CreateEntity(#PB_Any,MeshID(mesh_A),#PB_Material_None,0,0,0)
  RotateEntity(surface,0,180,0)
  CreateEntityBody(surface,#PB_Entity_StaticBody)
  ;myboxmesh = createboxmesh_around_0(15,15,50) ;that is a workaround
  myboxmesh = createboxmesh_ON_Top_0(15,50,15)
  Dim cubes(100)
  For i=1 To 100
    ;cubes(i)=CreateEntity(#PB_Any,MeshID(mesh_B),MaterialID(material_B),-1000+Random(2000),55,-1000+Random(2000))
    cubes(i)=CreateEntity(#PB_Any,MeshID(myboxmesh),#PB_Material_None,-1000+Random(2000),55,-1000+Random(2000))
    RotateEntity(cubes(i),Random(360),Random(360),Random(360))
    CreateEntityBody(cubes(i),#PB_Entity_ConvexHullBody)
  Next i
  setupcamera()
EndProcedure

Procedure rc()
  tx.f=CameraX(maincamera\id)+(CameraDirectionX(maincamera\id)*#castlength)
  ty.f=CameraY(maincamera\id)+(CameraDirectionY(maincamera\id)*#castlength)
  tz.f=CameraZ(maincamera\id)+(CameraDirectionZ(maincamera\id)*#castlength)
  rayhitbool = RayCast(CameraX(mainCamera\ID), CameraY(mainCamera\ID), CameraZ(maincamera\id), tX, ty, tz,-1)
  If rayhitbool
    CreateLine3D(vvectornormalid, PickX(), PickY(), PickZ(), RGB(255,0,0), PickX() + NormalX()*#vectorlength, PickY() + NormalY()*#vectorlength, PickZ() + NormalZ()*#vectorlength, RGB(255,255,127))
  EndIf
EndProcedure

Procedure checkinput()
  ExamineKeyboard()
  ExamineMouse()
  mdx=MouseDeltaX()*mousesensitivity
  mdy=-MouseDeltaY()*mousesensitivity
  If MouseButton(#PB_MouseButton_Right)
    maincamera\speed=smooth(maincamera\speed,#maxcamspeed)
  Else
    maincamera\speed=smooth(maincamera\speed,#mincamspeed)
  EndIf
  
  If KeyboardPushed(#PB_Key_Escape)
    CloseScreen()
    CloseWindow(0)
    End
  EndIf
EndProcedure

Procedure render()
  rc()
  RenderWorld()
  FlipBuffers()
EndProcedure

Procedure Run()
  init()
  createenvironment()
  WorldDebug(#PB_World_DebugBody)
  Repeat  
    checkevents()
    checkinput()
    updatecamera()
    render()
  ForEver
EndProcedure

run()