*.b3d-Datei auslesen

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

TheProgrammer

Betreff: *.b3d-Datei auslesen

BeitragSa, Jun 24, 2006 16:06
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jun 26, 2006 7:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Hm,

worin liegt der sinn das per hand zu laden?
between angels and insects

5k41

BeitragMo, Jun 26, 2006 8:11
Antworten mit Zitat
Benutzer-Profile anzeigen
vielleicht verständniss, vorbereitung auf C++?! kA genug!

MfG
Projekte:
For a better World - Gesellschaftsspiel ( 100%)

User posted image

TheProgrammer

BeitragMo, Jun 26, 2006 8:27
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Wink ), damit ich die Surfaces immer in der selben Reihenfolge laden kann. Ich habe ja schon die Variante, das Model einfach zu laden und dann die Surfaces etc. auszulesen, dort gelange ich dann aber leider nicht an die Brush-Informationen, da ich nicht weiß, welcher Brush aus dem .b3d-Format zu welchem Surface des Meshs gehört.

Mfg
TheProgrammer
aktuelles Projekt: The last day of human being
 

Dreamora

BeitragMo, Jun 26, 2006 8:29
Antworten mit Zitat
Benutzer-Profile anzeigen
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 !!!

BeitragMo, Jun 26, 2006 10:50
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jun 26, 2006 15:07
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jun 26, 2006 15:56
Antworten mit Zitat
Benutzer-Profile anzeigen
@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 !!!

BeitragMo, Jun 26, 2006 16:23
Antworten mit Zitat
Benutzer-Profile anzeigen
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 !!!

BeitragMo, Jun 26, 2006 16:35
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

BeitragMo, Jun 26, 2006 16:41
Antworten mit Zitat
Benutzer-Profile anzeigen
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 !!!

BeitragMo, Jun 26, 2006 16:58
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jun 26, 2006 21:25
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Jun 26, 2006 22:44
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Jun 29, 2006 10:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group