
Mesh I/O (oder einfach Meshio) soll als Vorlage zum importieren von Modell-Formaten dienen. Hinzugefügt habe ich XML Import, falls Interesse besteht führe ich das noch fort. Solange Bones etc. nicht unterstützt sind, ist ein direkter Import animierter Meshes nicht möglich, aber als zentraler Punkt zur Umkonvertierung hilfreich. Mit dem Ogre Converter könnte auch einfach fix eine XML Version durchgejagt werden.
Meshio.pbi
Code: Alles auswählen
EnableExplicit
;- Formats
XIncludeFile "XML.pbi"
DeclareModule Meshio
Structure FACE
*Vertex.PB_MeshVertex[3]
EndStructure
Structure VERTEXBUFFER
Map Attribute.s(8)
List Vertex.PB_MeshVertex()
EndStructure
Structure SUBMESH
Count.i
List Face.FACE()
List VertexBuffer.VERTEXBUFFER()
Map *Vertex.PB_MeshVertex()
Map Attribute.s(8)
EndStructure
Structure MESHIO
Map *Submesh.SUBMESH()
List Mesh.SUBMESH()
EndStructure
Declare I(*h.MESHIO, File.s, ShowError.b = #False)
Declare O(*h.MESHIO, File.s, ShowError.b = #False)
EndDeclareModule
Module Meshio
Procedure I(*h.MESHIO, File.s, ShowError.b = #False)
With *h
Select LCase(GetExtensionPart(File))
Case "xml"
MeshXML::I(*h, File, ShowError)
EndSelect
EndWith
EndProcedure
Procedure O(*h.MESHIO, File.s, ShowError.b = #False)
With *h
Select LCase(GetExtensionPart(File))
Case "xml"
EndSelect
EndWith
EndProcedure
EndModule
UseModule Meshio
CompilerIf #PB_Compiler_IsMainFile
Define MyMesh.MESHIO
Define File.s = OpenFileRequester("Mesh", "", "Mesh (*.xml)|*.xml|All files (*.*)|*.*", 0)
If File
Meshio::I(MyMesh, File, #True)
ForEach MyMesh\Submesh()
Debug MyMesh\Submesh()\Count
Debug MapKey(MyMesh\Submesh())
; Access triangle-list
ForEach MyMesh\Submesh()\Face()
Debug StrF(MyMesh\Submesh()\Face()\Vertex[0]\x, 2)+", "+StrF(MyMesh\Submesh()\Face()\Vertex[1]\x, 2)+", "+StrF(MyMesh\Submesh()\Face()\Vertex[2]\x, 2)
Next
Next
EndIf
CompilerEndIF
XML.pbi
Code: Alles auswählen
EnableExplicit
DeclareModule MeshXML
Structure FACE
*Vertex.PB_MeshVertex[3]
EndStructure
Structure VERTEXBUFFER
Map Attribute.s(8)
List Vertex.PB_MeshVertex()
EndStructure
Structure SUBMESH
Count.i
List Face.FACE()
List VertexBuffer.VERTEXBUFFER()
Map *Vertex.PB_MeshVertex()
Map Attribute.s(8)
EndStructure
Structure MESHIO
Map *Submesh.SUBMESH()
List Mesh.SUBMESH()
EndStructure
Declare VertexBuffer(*h.MESHIO, *Submesh.SUBMESH, *Node)
Declare Face(*h.MESHIO, *Submesh.SUBMESH, *Node)
Declare Submesh(*h.MESHIO, *Node)
Declare SubmeshIndex(*h.MESHIO, *Node)
Declare Examine(*h.MESHIO, *Node)
Declare I(*h.MESHIO, File.s, ShowError.b)
EndDeclareModule
Module MeshXML
Procedure VertexBuffer(*h.MESHIO, *Submesh.SUBMESH, *Node)
Protected *Child, *VertexBuffer, *Current.PB_MeshVertex, Index
With *Submesh
*VertexBuffer = ChildXMLNode(*Node)
If *VertexBuffer
While *VertexBuffer <> 0
AddElement(\VertexBuffer())
; VertexBuffer-Attributes
If ExamineXMLAttributes(*VertexBuffer)
While NextXMLAttribute(*VertexBuffer)
\VertexBuffer()\Attribute(XMLAttributeName(*VertexBuffer)) = XMLAttributeValue(*VertexBuffer)
Wend
EndIf
;[ Vertices
Index = 0
*Vertex = ChildXMLNode(*VertexBuffer)
While *Vertex <> 0
Select GetXMLNodeName(*Vertex)
Case "vertex"
; Vertex-Attribute Nodes
*VertexAttribute = ChildXMLNode(*Vertex)
If *VertexAttribute ;[
; Buffer Vertex
AddElement(\VertexBuffer()\Vertex())
*Current = @\VertexBuffer()\Vertex()
; Map Vertex
\Vertex(Str(Index)) = *Current
While *VertexAttribute <> 0
Select GetXMLNodeName(*VertexAttribute)
Case "position"
;[/ Position
If ExamineXMLAttributes(*VertexAttribute)
While NextXMLAttribute(*VertexAttribute)
Select XMLAttributeName(*VertexAttribute)
Case "x"
*Current\x = ValF(XMLAttributeValue(*VertexAttribute))
Case "y"
*Current\y = ValF(XMLAttributeValue(*VertexAttribute))
Case "z"
*Current\z = ValF(XMLAttributeValue(*VertexAttribute))
EndSelect
Wend
EndIf
;]/
Case "normal"
;[/ Normal
If ExamineXMLAttributes(*VertexAttribute)
While NextXMLAttribute(*VertexAttribute)
Select XMLAttributeName(*VertexAttribute)
Case "x"
*Current\NormalX = ValF(XMLAttributeValue(*VertexAttribute))
Case "y"
*Current\NormalY = ValF(XMLAttributeValue(*VertexAttribute))
Case "z"
*Current\NormalZ = ValF(XMLAttributeValue(*VertexAttribute))
EndSelect
Wend
EndIf
;]/
Case "texcoord"
;[/ UV
If ExamineXMLAttributes(*VertexAttribute)
While NextXMLAttribute(*VertexAttribute)
Select XMLAttributeName(*VertexAttribute)
Case "u"
*Current\u = ValF(XMLAttributeValue(*VertexAttribute))
Case "v"
*Current\v = ValF(XMLAttributeValue(*VertexAttribute))
EndSelect
Wend
EndIf
;]/
EndSelect
*VertexAttribute = NextXMLNode(*VertexAttribute)
Wend
;]
EndIf
EndSelect
Index + 1
*Vertex = NextXMLNode(*Vertex)
Wend
;]
*VertexBuffer = NextXMLNode(*VertexBuffer)
Wend
EndIf
EndWith
EndProcedure
Procedure Face(*h.MESHIO, *Submesh.SUBMESH, *Node)
With *Submesh
If ExamineXMLAttributes(*Node)
While NextXMLAttribute(*Node)
Select XMLAttributeName(*Node)
Case "count"
\Count = Val(XMLAttributeValue(*Node))
EndSelect
Wend
Else
ProcedureReturn #False
EndIf
*Face = ChildXMLNode(*Node)
If *Face
While *Face <> 0
AddElement(\Face())
If ExamineXMLAttributes(*Face)
While NextXMLAttribute(*Face)
Select XMLAttributeName(*Face)
Case "v1"
\Face()\Vertex[0] = \Vertex(XMLAttributeValue(*Face))
Case "v2"
\Face()\Vertex[1] = \Vertex(XMLAttributeValue(*Face))
Case "v3"
\Face()\Vertex[2] = \Vertex(XMLAttributeValue(*Face))
EndSelect
Wend
EndIf
*Face = NextXMLNode(*Face)
Wend
EndIf
ProcedureReturn #True
EndWith
EndProcedure
Procedure Submesh(*h.MESHIO, *Node)
Protected *Child, *Submesh, NewMap *Node()
With *h
*Submesh = ChildXMLNode(*Node)
If *Submesh
While *Submesh <> 0
AddElement(\Mesh())
; Submesh-Attributes
If ExamineXMLAttributes(*Submesh)
While NextXMLAttribute(*Submesh)
\Mesh()\Attribute(XMLAttributeName(*Submesh)) = XMLAttributeValue(*Submesh)
Wend
EndIf
*Child = ChildXMLNode(*Submesh)
While *Child <> 0
Select GetXMLNodeName(*Child)
Case "faces"
*Node("faces") = *Child
Case "geometry"
*Node("geometry") = *Child
EndSelect
*Child = NextXMLNode(*Child)
Wend
VertexBuffer(*h, @\Mesh(), *Node("geometry"))
Face(*h, @\Mesh(), *Node("faces"))
*Submesh = NextXMLNode(*Submesh)
Wend
EndIf
EndWith
EndProcedure
Procedure SubmeshIndex(*h.MESHIO, *Node)
Protected *Submesh, Name.s, Index
With *h
*Submesh = ChildXMLNode(*Node)
If *Submesh
While *Submesh <> 0
; Submesh-Association
If ExamineXMLAttributes(*Submesh)
While NextXMLAttribute(*Submesh)
Select XMLAttributeName(*Submesh)
Case "name"
Name = XMLAttributeValue(*Submesh)
Case "index"
Index = Val(XMLAttributeValue(*Submesh))
EndSelect
Wend
EndIf
ForEach \Mesh()
If ListIndex(\Mesh()) = Index
\Submesh(Name) = @\Mesh()
Break
EndIf
Next
*Submesh = NextXMLNode(*Submesh)
Wend
EndIf
EndWith
EndProcedure
Procedure Examine(*h.MESHIO, *Node)
Protected *Child, *SubmeshIndex
With *h
If XMLNodeType(*Node) = #PB_XML_Normal
While *Node <> 0
Select GetXMLNodeName(*Node)
Case "submeshes"
Submesh(*h, *Node)
Case "submeshnames"
*SubmeshIndex = *Node
Default
*Child = ChildXMLNode(*Node)
If *Child
Examine(*h, *Child)
EndIf
EndSelect
*Node = NextXMLNode(*Node)
Wend
If *SubmeshIndex
SubmeshIndex(*h, *SubmeshIndex)
EndIf
EndIf
EndWith
EndProcedure
Procedure I(*h.MESHIO, File.s, ShowError.b)
Protected XML, Output.s, *Root
With *h
XML = LoadXML(-1, File)
If XMLStatus(XML) <> #PB_XML_Success
If ShowError
Output = "Error in the XML file:" + Chr(13)
Output + "Message: " + XMLError(XML) + Chr(13)
Output + "Line: " + Str(XMLErrorLine(XML)) + " Character: " + Str(XMLErrorPosition(XML))
MessageRequester("Error", Output)
EndIf
ProcedureReturn #False
EndIf
*Root = MainXMLNode(XML)
If *Root
Examine(*h, *Root)
EndIf
EndWith
EndProcedure
EndModule