Ich erstelle liebend gern 3D-Objekte mit dem Programm Cinema 4D. Leider ist es nur äußerst umständlich und über viele Umwege möglich diese Objekte in .mesh-Dateien umzuwandeln, um sie in PB-Projekten nutzen zu können.
Deshalb habe ich mal einen kleinen Konverter gebastelt, welcher .obj-Dateien in .mesh-Dateien umwandelt.
Ich hab erst überlegt, ob ich ihn in der Kategorie "Code, Tipps und Tricks" Poste aber das habe ich aufgrund der Kategorie-Beschreibung dann doch lieber sein lassen.
("Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.")
Da mein Code allerdings alles andere als effizient, elegant und beispielhaft ist, sondern einfach nur mal so für mich sein sollte, stelle ich ihn einfach mal hier rein.
Vieleicht dient die Idee ja anderen als kleine Anregung für eigene Projekte.
Bevor ich den Code Poste allerdings noch ein paar kleine Hinweise.
-Das Programm wurde bis jetzt nur mit .obj-Dateien angetestet, die mittels Cinema 4D exportiert wurden.
-Die Faces (/Flächen/Polygone) müssen trianguliert sein (sie dürfen nur aus Dreiecken bestehen).
-Der ungefähre Mittelpunkt des erstellten Objekts sollte sich ca. auf den Koordinaten X = 0, Y = 0 und Z = 0 befinden (das ist allerdings nur für eine saubere Vorschau von bedeutung).
-Wie schon erwähnt ist der Quellcode ziemlich unsauber, weil ich ihn anfangs nur mal schnell für mich selbst gecoded hab (also bitte nich meckern ^^).
-Da ich noch keine ausführlichen Tests gemacht habe kann ich nichts genauers über irgendwelche Bugs sagen.
So... hier jetzt mal der Code:
Code: Alles auswählen
If InitEngine3D() = 0
End
EndIf
If InitSprite() = 0
End
EndIf
Structure vtx
x.f
y.f
z.f
EndStructure
Structure fce
a.i
b.i
c.i
EndStructure
Structure obj
name.s
level.i
List vertex.vtx()
List face.fce()
EndStructure
NewList object.obj()
NewList tosort.f()
Procedure ReadObject(ObjFile.s, List object.obj())
Protected.s Row, Type, Pointer
Protected.i Counter
If OpenFile(0, ObjFile)
While Eof(0) = 0
Row = ReadString(0)
Type = StringField(Row, 1, " ")
If Type = "g"
AddElement(object())
object()\name = StringField(Row, CountString(Row, " ") + 1, " ")
object()\level = CountString(Row, " ") - 1
ElseIf Type = "v"
AddElement(object()\vertex())
object()\vertex()\x = ValF(StringField(Row, 2, " "))
object()\vertex()\y = ValF(StringField(Row, 3, " "))
object()\vertex()\z = ValF(StringField(Row, 4, " "))
ElseIf Type = "f"
AddElement(object()\face())
Pointer = StringField(Row, 2, " ")
object()\face()\a = Val(StringField(Pointer, 1, "/"))
Pointer = StringField(Row, 3, " ")
object()\face()\b = Val(StringField(Pointer, 1, "/"))
Pointer = StringField(Row, 4, " ")
object()\face()\c = Val(StringField(Pointer, 1, "/"))
EndIf
Wend
CloseFile(0)
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 400, 448, "2 Mesh", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If OpenWindowedScreen(WindowID(0), 0, 24, 400, 400, 0, 0, 0)
ButtonGadget(0, 0, 0, 400, 24, ".obj-Datei öffnen")
ButtonGadget(1, 0, 424, 400, 24, ".obj zu .mesh konvertieren")
CreateCamera(0, 0, 0, 100, 100)
CreateLight(0, RGB(0, 0, 200), 1.5, 1.5, -2)
CreateLight(1, RGB(255, 200, 80), -3, -1, -2)
CreateTexture(0, 256, 256)
StartDrawing(TextureOutput(0))
Box(0, 0, 256, 256, RGB(200, 200, 200))
StopDrawing()
CreateMaterial(0, TextureID(0))
Repeat
event = WaitWindowEvent(20)
If event = #PB_Event_Gadget
If EventGadget() = 0
file$ = OpenFileRequester("Datei öffnen...", "C:\", "Wavefront (*.obj)|*.obj", 0)
If file$
ClearList(object())
ReadObject(file$, object())
ClearList(tosort())
CreateMesh(0)
Xall.f = 0
Yall.f = 0
Zall.f = 0
All = 0
ForEach object()\vertex()
AddMeshVertex(object()\vertex()\x, object()\vertex()\y, object()\vertex()\z)
Xall.f + object()\vertex()\x
Yall.f + object()\vertex()\y
Zall.f + object()\vertex()\z
All + 1
AddElement(tosort())
tosort() = object()\vertex()\x
AddElement(tosort())
tosort() = object()\vertex()\y
AddElement(tosort())
tosort() = object()\vertex()\z
Next
ForEach object()\face()
AddMeshFace(object()\face()\a - 1, object()\face()\b - 1, object()\face()\c - 1)
Next
FinishMesh()
SortList(tosort(), #PB_Sort_Ascending)
SelectElement(tosort(), 0)
smallest.f = tosort()
SelectElement(tosort(), ListSize(tosort()) - 1)
biggest.f = tosort()
NormalizeMesh(0)
CreateEntity(0, MeshID(0), MaterialID(0))
CameraLocate(0, 0, (smallest - biggest) * -1 * 2, (smallest - biggest) * 3)
CameraLookAt(0, Xall / All, Yall / All, Zall / All)
LightLocate(0, (smallest - biggest) * -1 * 1.5, (smallest - biggest) * -1 * 1.5, (smallest - biggest) * -1 * -2)
LightLocate(1, (smallest - biggest) * -1 * -3, (smallest - biggest) * -1 * -1, (smallest - biggest) * -1 * -2)
MeshCreate = 1
EndIf
ElseIf EventGadget() = 1
savefile$ = SaveFileRequester("Datei speichern...", "C:\Unbenannt.mesh", "Alle Dateien (*.*)|*.*", 0)
If savefile$
If Right(savefile$, 5) <> ".mesh"
savefile$ + ".mesh"
EndIf
SaveMesh(0, savefile$)
EndIf
EndIf
EndIf
If MeshCreate = 1
RotateEntity(0, 1, 2, 0, #PB_Relative)
EndIf
ClearScreen(RGB(0,0,0))
RenderWorld()
FlipBuffers()
Until event = #PB_Event_CloseWindow
End
EndIf
EndIf