*.b3d-Datei auslesen
Übersicht

![]() |
TheProgrammerBetreff: *.b3d-Datei auslesen |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
ich verzweifel schon eine Weile daran, aus dem *.b3d-Format einen richtigen mesh zu bauen. Das Auslesen ist ja eigentlich kein Problem, aber dann die Vertizes den Surfaces zuzuordnen und Triangles drauszumachen funktioniert irgendwie noch nicht. Das Problem ist, dass im Format die Vertizes keinem Surface zugeordnet werden und die Triangles in jedem Surface die selben Vertizes nehmen wollen (0,1,2,...). Hier mal der Code: Code: [AUSKLAPPEN] Graphics3D 800,600,0,1 SetBuffer BackBuffer() AppTitle "Static Mesh" Include "b3dfile.bb" camera = CreateCamera() light = CreateLight() RotateEntity light,0,90,0 ConvertStaticMesh("helicopter.b3d","house.sme") MoveMouse 400,300 FlushMouse() While Not KeyHit(1) RenderWorld RotateEntity camera,pitch#,yaw#,0 pitch# = pitch# + MouseYSpeed()*0.1 yaw# = yaw# - MouseXSpeed()*0.1 MoveMouse 400,300 If KeyDown(17) Then MoveEntity camera,0,0,0.5 If KeyDown(31) Then MoveEntity camera,0,0,-0.5 If KeyDown(30) Then MoveEntity camera,-0.5,0,0 If KeyDown(32) Then MoveEntity camera,0.5,0,0 Flip Wend End ClearWorld() End Function ConvertStaticMesh(in$, name$) file = ReadFile(in$) If file Then CloseFile file mesh = LoadMesh(in$) If mesh Then FreeEntity mesh b3d_file=ReadFile( in$ ) b3dSetFile( b3d_file ) If b3dReadChunk$()<>"BB3D" RuntimeError "Invalid b3d file" If b3dReadInt()/100>0 RuntimeError "Invalid b3d file version" SaveB3DInTypes() b3dexitchunk() CloseFile b3d_file mesh = CreateMesh() brush_id = 0 For brus.TBrus = Each TBrus surf = CreateSurface(mesh) brush = CreateBrush() For tris.TTris = Each TTris If brush_id = tris\brush_id If brush_id = 0 Then ; Erstmal nur die Vertices vom ersten Surface erstellen ... und hier beginnt das tolle Problem. vert_id = 0 For vrts.TVrts = Each TVrts If vert_id = tris\v0 Then v0 = AddVertex(surf,vrts\x,vrts\z,vrts\y) EndIf If vert_id = tris\v1 Then v1 = AddVertex(surf,vrts\x,vrts\z,vrts\y) EndIf If vert_id = tris\v2 Then v2 = AddVertex(surf,vrts\x,vrts\z,vrts\y) EndIf vert_id = vert_id + 1 Next AddTriangle surf,v0,v1,v2 EndIf EndIf Next PaintSurface surf,brush FreeBrush brush brush_id = brush_id + 1 Next UpdateNormals(mesh) ClearB3DTypes() Else RuntimeError "Mesh does not exist" EndIf Else RuntimeError "Mesh does not exist" EndIf End Function ; *********************** ; ; Helper Functions ; ; *********************** Function ClearB3DTypes() For texs.TTexs = Each TTexs Delete texs Next For brus.TBrus = Each TBrus Delete brus Next For vrts.TVrts = Each TVrts Delete vrts Next For tris.TTris = Each TTris Delete tris Next End Function Function SaveB3DInTypes() While b3dChunkSize() chunk$=b3dReadChunk$() Select chunk$ Case "ANIM" flags=b3dReadInt() n_frames=b3dReadInt() fps=b3dReadFloat() Case "KEYS" flags=b3dReadInt() sz=4 If flags And 1 sz=sz+12 If flags And 2 sz=sz+12 If flags And 4 sz=sz+16 n_keys=b3dChunkSize()/sz If n_keys*sz=b3dChunkSize() While b3dChunkSize() frame=b3dReadInt() If flags And 1 key_px#=b3dReadFloat() key_py#=b3dReadFloat() key_pz#=b3dReadFloat() EndIf If flags And 2 key_sx#=b3dReadFloat() key_sy#=b3dReadFloat() key_sz#=b3dReadFloat() EndIf If flags And 4 key_rw#=b3dReadFloat() key_rx#=b3dReadFloat() key_ry#=b3dReadFloat() key_rz#=b3dReadFloat() EndIf Wend EndIf Case "TEXS" While b3dChunkSize() texs.TTexs = New TTexs texs\name$=b3dReadString$() texs\flags=b3dReadInt() texs\blend=b3dReadInt() texs\x_pos#=b3dReadFloat() texs\y_pos#=b3dReadFloat() texs\x_scl#=b3dReadFloat() texs\y_scl#=b3dReadFloat() texs\rot#=b3dReadFloat() Wend Case "BRUS" n_texs=b3dReadInt() If n_texs > 8 Then RuntimeError "Wrong Texture-Set" While b3dChunkSize() brus.TBrus = New TBrus name$=b3dReadString$() brus\red#=b3dReadFloat() brus\grn#=b3dReadFloat() brus\blu#=b3dReadFloat() brus\alp#=b3dReadFloat() brus\shi#=b3dReadFloat() brus\blend=b3dReadInt() brus\fx=b3dReadInt() For k=0 To 7 brus\tex_id[k] = -1 Next For k=0 To n_texs-1 brus\tex_id[k]=b3dReadInt() Next Wend Case "VRTS" flags=b3dReadInt() tc_sets=b3dReadInt() tc_size=b3dReadInt() If tc_sets > 2 Then RuntimeError "Wrong UV-Set size" If tc_size > 3 Then RuntimeError "Wrong UVW's" sz=12+tc_sets*tc_size*4 If flags And 1 Then sz=sz+12 If flags And 2 Then sz=sz+16 n_verts=b3dChunkSize()/sz If n_verts*sz=b3dChunkSize() While b3dChunkSize() vrts.TVrts = New TVrts vrts\x#=b3dReadFloat() vrts\y#=b3dReadFloat() vrts\z#=b3dReadFloat() If flags And 1 nx#=b3dReadFloat() ny#=b3dReadFloat() nz#=b3dReadFloat() EndIf If flags And 2 red#=b3dReadFloat() grn#=b3dReadFloat() blu#=b3dReadFloat() lfa#=b3dReadFloat() EndIf For j=1 To 6 vrts\coords[j]=-1 Next For j=1 To tc_sets*tc_size vrts\coords[j]=b3dReadFloat() Next Wend EndIf Case "TRIS" brush_id=b3dReadInt() sz=12 n_tris=b3dChunkSize()/sz If n_tris*sz=b3dChunkSize() While b3dChunkSize() tris.TTris = New TTris tris\brush_id=brush_id tris\v0=b3dReadInt() tris\v1=b3dReadInt() tris\v2=b3dReadInt() Wend EndIf Case "MESH" brush_id=b3dReadInt() Case "BONE" sz=8 n_weights=b3dChunkSize()/sz If n_weights*sz=b3dChunkSize() While b3dChunkSize() vertex_id=b3dReadInt() weight#=b3dReadFloat() Wend EndIf Case "NODE" name$=b3dReadString$() x_pos#=b3dReadFloat() y_pos#=b3dReadFloat() z_pos#=b3dReadFloat() x_scl#=b3dReadFloat() y_scl#=b3dReadFloat() z_scl#=b3dReadFloat() w_rot#=b3dReadFloat() x_rot#=b3dReadFloat() y_rot#=b3dReadFloat() z_rot#=b3dReadFloat() End Select SaveB3DInTypes() b3dExitChunk() Wend End Function Function FileName$(name$) While Instr(name$,"\") name$ = Mid(name$,Instr(name$,"\")+1,Len(name$)) Wend Return name$ End Function ; ******************** ; ; Types ; ; ******************** Type TTexs Field name$ Field flags Field blend Field x_pos# Field y_pos# Field x_scl# Field y_scl# Field rot# End Type Type TBrus Field red# Field grn# Field blu# Field alp# Field shi# Field blend Field fx Field tex_id[7] End Type Type TVrts Field x# Field y# Field z# Field coords#[6] End Type Type TTris Field brush_id Field v0 Field v1 Field v2 End Type Hier die b3dfile.bb Code: [AUSKLAPPEN] ; ;b3d file utils to be included ; Dim b3d_stack(100) Global b3d_file,b3d_tos Function b3dSetFile( file ) b3d_tos=0 b3d_file=file End Function ;***** functions for reading from B3D files ***** Function b3dReadByte() Return ReadByte( b3d_file ) End Function Function b3dReadInt() Return ReadInt( b3d_file ) End Function Function b3dReadFloat#() Return ReadFloat( b3d_file ) End Function Function b3dReadString$() Repeat ch=b3dReadByte() If ch=0 Return t$ t$=t$+Chr$(ch) Forever End Function Function b3dReadChunk$() For k=1 To 4 tag$=tag$+Chr$(b3dReadByte()) Next sz=ReadInt( b3d_file ) b3d_tos=b3d_tos+1 b3d_stack(b3d_tos)=FilePos( b3d_file )+sz Return tag$ End Function Function b3dExitChunk() SeekFile b3d_file,b3d_stack(b3d_tos) b3d_tos=b3d_tos-1 End Function Function b3dChunkSize() Return b3d_stack(b3d_tos)-FilePos( b3d_file ) End Function ;***** Functions for writing to B3D files ***** Function b3dWriteByte( n ) WriteByte( b3d_file,n ) End Function Function b3dWriteInt( n ) WriteInt( b3d_file,n ) End Function Function b3dWriteFloat( n# ) WriteFloat( b3d_file,n ) End Function Function b3dWriteString( t$ ) For k=1 To Len( t$ ) ch=Asc(Mid$(t$,k,1)) b3dWriteByte(ch) If ch=0 Return Next b3dWriteByte( 0 ) End Function Function b3dBeginChunk( tag$ ) b3d_tos=b3d_tos+1 For k=1 To 4 b3dWriteByte(Asc(Mid$( tag$,k,1 ))) Next b3dWriteInt( 0 ) b3d_stack(b3d_tos)=FilePos( b3d_file ) End Function Function b3dEndChunk() n=FilePos( b3d_file ) SeekFile b3d_file,b3d_stack(b3d_tos)-4 b3dWriteInt( n-b3d_stack(b3d_tos) ) SeekFile b3d_file,n b3d_tos=b3d_tos-1 End Function Wer die Datei helicopter.b3d brauch: helicopter.rar Und hier nochmal die Dokumentation über das Format: http://www.blitzbasic.com/sdkspecs/sdkspecs.php Ein weiteres problem liegt darin, die richtigen UV-Koordinaten zuzuordnen. Ich hoffe, ihr könnt mir bei dem problem helfen, ich komme da einfach nicht mehr weiter. Mfg TheProgrammer |
||
aktuelles Projekt: The last day of human being |
![]() |
Jan_Ehemaliger Admin |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hm,
worin liegt der sinn das per hand zu laden? |
||
between angels and insects |
![]() |
5k41 |
![]() Antworten mit Zitat ![]() |
---|---|---|
vielleicht verständniss, vorbereitung auf C++?! kA genug!
MfG |
||
Projekte:
For a better World - Gesellschaftsspiel ( 100%) User posted image |
![]() |
TheProgrammer |
![]() Antworten mit Zitat ![]() |
---|---|---|
LoadMesh lädt die Surfaces manchmal in einer unterschiedlichen Reihenfolge, was zu schweren Bugs bei Lightmaps führen würde (kann jeder ganz einfach mal ausprobieren, indem er sich den ersten Vertex jedes Surfaces in der Reihenfolge, in der es geladen wird, ausgibt und dann nochmal ne .exe kompiliert und nochmal ausgibt.)
Auf jeden Fall möchte ich das Model in mein eigenes Format convertieren (Texture ist dort mit inbegriffen ![]() Mfg TheProgrammer |
||
aktuelles Projekt: The last day of human being |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wenn du für lightmaps verschiedene Surfaces hast, hast du schon einen schwerwiegenden Bug im Model. Das geschieht normalerweise durch Multitexturing und die zweite UV Koordinate für die Lightmap. | ||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
antome!!! gesperrt !!! |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Jeder Brush stellt ein Surface dar.
Der TRIS - Chunk hat eine Brush-ID, diese ist praktisch dann das Surface und der TRIS Chunk hat des weiteren 3 Vertex Einträge, also du liest erstmal alle Vertexe in deine Variablen ein, später weisst du die Vertexe dann den Triangles zu. Du kannst deinem Vertex-Type einen neuen Eintrag geben Vertex\Surface diesen füllt du dann beim erstellen des Triangles aus, indem du den 3 Vertexen die Brush-ID des TRIS-Chunks gibst. Damit kannst du dann bei CreateSurface(mesh,brush) die brush-id für das Surface aus deinem Type holen. |
||
antome |
![]() |
Mr.Keks |
![]() Antworten mit Zitat ![]() |
---|---|---|
also, soweit ich das sehe, stellt jeder tris-chunk ein eigenes surface dar, oder? denn so ein brush kann ja über verschiedene nodes verteilt sein | ||
MrKeks.net |
![]() |
TheProgrammer |
![]() Antworten mit Zitat ![]() |
---|---|---|
@antome: Das dachte ich mir eigentlich auch so. Das Problem ist nur, dass die Tris unterschiedlicher Surfaces immer die selben Vertizes nehmen. | ||
aktuelles Projekt: The last day of human being |
antome!!! gesperrt !!! |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Vertexe (vertize oder Vertice...) wrden immer doppelt belegt, wenn man Schattierung haben will muss das so sein.
Milkshape macht dies z.B. nicht , jedenfall bei älteren Versionen siehe Psionics Animationen, diese bekommen dann keinen Schatten spendiert bei der Beleuchtung mit CreateLight() Nehmen wir mal ein Flaches Quadrat aus 2 Tris v1, v2, v3, v4 Dann bekommt Triangle1 z.B. v1,v2 und v3 zugewiesen Triangle2 v2,v3 und v4 also v2 und v3 sind doppelt belegt. |
||
antome |
antome!!! gesperrt !!! |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@inarie
ja, der TRIS Chunk ist sozusagen ein Surface, zu Beginn steht die BrushID und dann kommen immer im 3er Block die Vertexnummern für jedes Triangle. Man kann theoretisch auch mehrere Surfaces mit der selben Brush-ID haben. Habe das oben etwas ungenau erklärt, aber das Problem bei TheProgrammer sind wohl die Tris und die doppelten Vertexnummern, aber das ist eigentlich normal und sollte auch so sein. |
||
antome |
![]() |
Mr.Keks |
![]() Antworten mit Zitat ![]() |
---|---|---|
wie genau die id-zählung funktioniert wird leider auf bb.com, soweit ich sehe, nicht wirklich erklärt. ich denke, die zählung beginnt bei jedem mesh-tag von neuem, was theprogrammer nicht beachtet. (überhaupt müssen auch die nodes geparst werden... ein node entspricht in b3ddenke einem entity, soweit ich sehe.) | ||
MrKeks.net |
antome!!! gesperrt !!! |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hab grad mal kurz getestet, wenn man mit Wings3D ein .3ds File importiert und dupliziert
dann wieder als .3ds speichert und mit Decorator in ein .B3D umwandelt entsteht kein Multiple-Mesh File, d.h. ein B3D File mit 2 Mesh-Chunks, ich kenne bisher nur ein Programm welches solche multiple-Mesh Files überhaupt erstellt und das ist GLET alias XWorld3D --> http://www.freewebs.com/kefir/ Aber falls es doch mehrere Programme gibt welche Multi-Mesh-Chunk Files erstellen kann man sagen das pro Mesh-Chunk die nummerierung wieder von vorne beginnt, also Vertex1 dort andere Koordinaten besitz als im Mesh Chunk zuvor. Man kann das leicht testen, einfach in XWorld 2 Meshes importieren, am besten 2 ganz einfache diese dann als B3D exportieren und dann entweder im HEX-Editor ansehen oder ein kleines Prg. schreiben welches die ID-Nummern ausgibt. |
||
antome |
BIG BUG |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Du hast für jedes Triangle die IDs der 3 Vertexpunkte(Diese werden mit jedem MESH neu nummeriert, innerhalb sind diese aber eindeutig(auch bei mehreren Surfaces)). Damit kommst Du an die Koordinaten.
D.h. Du musst innerhalb eines Surfaces ja nicht alle Vertices belegt haben.(Ob BB3D unbenutzte Vertices innerhalb eines Surfaces wohl einfach löscht?) |
||
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final) |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nein, warum sollte sie. Wenn du Vertices nicht mehr brauchst kannst du die Surface clearen und nur mit den Daten befüllen, die noch gebraucht werden. | ||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Das Problem ist, Mark hat das Format ziemlich beschissen designed. Die Vertices liegen nicht für jedes Surface einzeln vor sondern fürs komplette Mesh. Das Exportieren ist damit kein Problem aber das Importieren jedoch schon.
Die Chunks sind zwar schön und gut, aber sie müssen in einer vorgeschriebenen Reihenfolge existieren, was sie wieder überflüssig macht. Über das B3D Format könnte ich mich pausenlos aufregen! mfg olli |
||
vertex.dreamfall.at | GitHub |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group