GetMeshData et dimension d'un Mesh.

Généralités sur la programmation 3D
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

GetMeshData et dimension d'un Mesh.

Message par falsam »

Actuellement il n'y a pas de fonctions natives pour trouver les dimensions d'un mesh. Par contre si j'ai bien compris le fonctionnement, GetsMeshData permet d'obtenir les données internes du mesh, comme les sommets, les faces mais aussi les coordonnées de chaque vertex.

On peut donc connaitre les points les plus à droite et à gauche de notre mesh sur chacun des axes x,y et z.

Partant de cette hypothèse, le code ci-dessous permet de connaitre les dimension de notre mesh.

Du moins c'est ce que je croyais !!!!

Touche Escape pour quitter le code - Touche O pour ouvrir un autre mesh - Touches de direction pour rotation et mouvement bas haut de la camera.

Code : Tout sélectionner

Global Event.l, Camera, Texture, Material, Mesh, Entity
Global Dim MeshData.PB_MeshVertex(0), XMin.f, XMax.f, Ymin.f, YMax.f, ZMin.f, ZMax.f

Procedure SelectMesh()
  Protected File.s, PathPart.s, FilePart.s, ExtensionPart.s
  
  XMin=0
  XMax=0
  Ymin=0
  YMax=0
  ZMin=0
  ZMax=0 
  
  ReDim MeshData.PB_MeshVertex(0)
  
  File = OpenFileRequester("","","",0)

  If File <> ""
    PathPart = GetPathPart(File)
    FilePart = GetFilePart(File)
    ExtensionPart = GetExtensionPart(File)
    
    Add3DArchive(PathPart, #PB_3DArchive_FileSystem)
    
    Mesh = LoadMesh(#PB_Any, FilePart)
    
    GetMeshData(Mesh, 0, MeshData(), #PB_Mesh_Vertex|#PB_Mesh_Color, 0, MeshVertexCount(Mesh)-1)
    
    For i = 0 To ArraySize(MeshData())
      If MeshData(i)\x < XMin
        Xmin = MeshData(i)\x
      EndIf
      
      If MeshData(i)\x > XMax
        XMax = MeshData(i)\x
      EndIf
      
      If MeshData(i)\y < YMin
        Ymin = MeshData(i)\Y
      EndIf
      
      If MeshData(i)\y > YMax
        YMax = MeshData(i)\y
      EndIf
      
      If MeshData(i)\z < ZMin
        Zmin = MeshData(i)\Z
      EndIf
      
      If MeshData(i)\z > ZMax
        ZMax = MeshData(i)\Z
      EndIf
      
    Next  
    
    Debug "Width = " + StrF(XMax-Xmin)
    Debug "Height = " + StrF(YMax-Ymin)
    Debug "Depth = " + StrF(ZMax-Zmin)
    
    Debug "Mesh Radius " + Str(MeshRadius(Mesh))
    
    Entity = CreateEntity(#PB_Any, MeshID(Mesh),  MaterialID(Material))
    MoveCamera(Camera, 0, EntityY(Entity), (Zmax-ZMin)+MeshRadius(Mesh)*2, #PB_Absolute)
    CameraLookAt(Camera, 0, 0, 0)

  EndIf
  
EndProcedure

Procedure Start()
  If Not (InitEngine3D() And InitKeyboard() And InitSprite())
    End
  EndIf
  
  Window = OpenWindow(#PB_Any,0, 0, 1024, 768, "Entity Size", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(Window),0, 0, 1024, 768)

  AmbientColor(RGB(127, 127, 127))
  CreateLight(#PB_Any,RGB(151, 251, 151), -50, 100, 200)
  WorldShadows(#PB_Shadow_Additive)
  
  Camera = CreateCamera(#PB_Any,0,0,100,100)
  CameraBackColor(Camera, RGB(145, 182, 201))
  
  Texture = CreateTexture(#PB_Any,256,256)
  StartDrawing(TextureOutput(Texture))
  Box(0, 0, 256, 256, RGB(255, 248, 220))
  StopDrawing()
  Material = CreateMaterial(#PB_Any, TextureID(Texture))
  MaterialFilteringMode(Material, #PB_Material_Anisotropic, 6)
    
  SelectMesh()
  
EndProcedure

Start()


Repeat 
  Repeat
    Event = WaitWindowEvent(10)
  Until Event = 0  
  
  ExamineKeyboard()  
  
  If Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
    Break
  EndIf    
  
  If KeyboardPushed(#PB_Key_Left)
    RotateEntity(Entity, 0, -0.7, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_Right)
    RotateEntity(Entity, 0, 0.7, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    MoveCamera(Camera, 0, 0.02, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_Down)
    MoveCamera(Camera, 0, -0.02, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_O)
    FreeEntity(Entity)
    FreeMesh(Mesh)
    SelectMesh()
  EndIf
  
  FlipBuffers()  
  ClearScreen(RGB(0, 0, 0))
  RenderWorld() 
  
ForEver
A l’exécution de ce code sélectionnez le fichier ninja.mesh ou AKM.mesh dans le dossier Examples\3D\Data\Models figurant dans le dossier d'installation de Pure Basic. Dans le débogueur vous constaterez que le tableau Meshdata est vide.

Par contre ça fonctionne si vous sélectionnez maintenant Robot.mesh ou si vous avez la derniere version (5.20 Rockstar release) sélectionnez purebasic.mesh :mrgreen: (Au passage merci à celui qui a crée ce mesh)

Et on obtient un magnifique Tilt Game over si vous sélectionnez facial.mesh.

Qu'est ce qui ne va pas dans mon code ? Est ce qu'il faut remettre en cause les mesh ?

PS : Impossible d'afficher une texture (materiel) sur AKM.mesh
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: GetMeshData et dimension d'un Mesh.

Message par comtois »

C'est Alexi qui a fourni le fichier PureBasic.mesh.

Sinon essaie comme ça (faut tester le nombre de submesh):

Code : Tout sélectionner

Global Event.l, Camera, Texture, Material, Mesh, Entity
Global Dim MeshData.PB_MeshVertex(0), XMin.f, XMax.f, Ymin.f, YMax.f, ZMin.f, ZMax.f

Procedure SelectMesh()
  Protected File.s, PathPart.s, FilePart.s, ExtensionPart.s
  
  XMin=0
  XMax=0
  Ymin=0
  YMax=0
  ZMin=0
  ZMax=0
  
  ReDim MeshData.PB_MeshVertex(0)
  
  File = OpenFileRequester("","","",0)
  
  If File <> ""
    PathPart = GetPathPart(File)
    FilePart = GetFilePart(File)
    ExtensionPart = GetExtensionPart(File)
    
    Add3DArchive(PathPart, #PB_3DArchive_FileSystem)
    
    Mesh = LoadMesh(#PB_Any, FilePart)
    
    For j=0 To SubMeshCount(Mesh)-1
      GetMeshData(Mesh, j, MeshData(), #PB_Mesh_Vertex|#PB_Mesh_Color, 0, MeshVertexCount(Mesh,j)-1)
      
      For i = 0 To ArraySize(MeshData())
        If MeshData(i)\x < XMin
          Xmin = MeshData(i)\x
        EndIf
        
        If MeshData(i)\x > XMax
          XMax = MeshData(i)\x
        EndIf
        
        If MeshData(i)\y < YMin
          Ymin = MeshData(i)\Y
        EndIf
        
        If MeshData(i)\y > YMax
          YMax = MeshData(i)\y
        EndIf
        
        If MeshData(i)\z < ZMin
          Zmin = MeshData(i)\Z
        EndIf
        
        If MeshData(i)\z > ZMax
          ZMax = MeshData(i)\Z
        EndIf
        
      Next 
    Next
    Debug "Width = " + StrF(XMax-Xmin)
    Debug "Height = " + StrF(YMax-Ymin)
    Debug "Depth = " + StrF(ZMax-Zmin)
    
    Debug "Mesh Radius " + Str(MeshRadius(Mesh))
    
    Entity = CreateEntity(#PB_Any, MeshID(Mesh),  MaterialID(Material))
    MoveCamera(Camera, 0, EntityY(Entity), (Zmax-ZMin)+MeshRadius(Mesh)*2, #PB_Absolute)
    CameraLookAt(Camera, 0, 0, 0)
    
  EndIf
  
EndProcedure

Procedure Start()
  If Not (InitEngine3D() And InitKeyboard() And InitSprite())
    End
  EndIf
  
  Window = OpenWindow(#PB_Any,0, 0, 1024, 768, "Entity Size", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(Window),0, 0, 1024, 768)
  
  AmbientColor(RGB(127, 127, 127))
  CreateLight(#PB_Any,RGB(151, 251, 151), -50, 100, 200)
  WorldShadows(#PB_Shadow_Additive)
  
  Camera = CreateCamera(#PB_Any,0,0,100,100)
  CameraBackColor(Camera, RGB(145, 182, 201))
  
  Texture = CreateTexture(#PB_Any,256,256)
  StartDrawing(TextureOutput(Texture))
  Box(0, 0, 256, 256, RGB(255, 248, 220))
  StopDrawing()
  Material = CreateMaterial(#PB_Any, TextureID(Texture))
  MaterialFilteringMode(Material, #PB_Material_Anisotropic, 6)
  
  SelectMesh()
  
EndProcedure

Start()


Repeat
  Repeat
    Event = WaitWindowEvent(10)
  Until Event = 0 
  
  ExamineKeyboard() 
  
  If Event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
    Break
  EndIf   
  
  If KeyboardPushed(#PB_Key_Left)
    RotateEntity(Entity, 0, -0.7, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_Right)
    RotateEntity(Entity, 0, 0.7, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_Up)
    MoveCamera(Camera, 0, 0.02, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_Down)
    MoveCamera(Camera, 0, -0.02, 0, #PB_Relative)
  EndIf
  
  If KeyboardPushed(#PB_Key_O)
    FreeEntity(Entity)
    FreeMesh(Mesh)
    SelectMesh()
  EndIf
  
  FlipBuffers() 
  ClearScreen(RGB(0, 0, 0))
  RenderWorld()
  
ForEver
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: GetMeshData et dimension d'un Mesh.

Message par falsam »

Merci Comtois. Effectivement je ne comptais pas le nombre de SubMesh et je n'y aurais jamais pensé.

Par contre le load de facial.mesh figurant dans les exemples provoque une erreur C++ Runtime Libray.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre