Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

David Mehre

unregistriert

1

09.05.2009, 18:01

3DS-Loader

Hallo,
ich versuche gerade, einen Eigenen 3DS-Loader anhand des TriBase-Tools ModelConverter nachzubauen.

Da ich es unabhängig von er TriBase-Engine machen wollte, habe ich meine eigene Klasse CFile geschrieben, die allerdings genauso funktioniert wie tbVFile.

Ich poste mal den Code, den ich bisher geschrieben habe:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
enum RESULT { RES_OK = 0, RES_ERROR };

#define MAIN3DS       0x4D4D
#define EDIT3DS        0x3D3D

struct SChunkHeader
{
    WORD    wChunkID;
    DWORD   dwChunkSize;
};

/////////////////////////////////////////////////////////////////////////////////////
// Liest alle wichtigen Daten aus der 3DS-Datei aus
RESULT  Read3DSFile (char *pcFileName)
{
    CFile           file;           // Die Datei
    SChunkHeader    ChunkHeader;    // Der Chunk-Header
    
    // ---------------------------------------
    // Datei öffnen
    if (file.Init (pcFileName) == false)
    {   MessageBox (NULL, TEXT("file.Init  (pcFileName)"), TEXT("Error"), MB_ICONEXCLAMATION | MB_OK);
        return RES_ERROR;
    }

    // ---------------------------------------
    // Mit dem lesen beginnen
    while (TRUE)
    {
        // Am Ende der Datei angelangt
        if (file.IsEOF ())      break;

        // Chunk einlesen
        if (file.Read (sizeof (SChunkHeader), &ChunkHeader) == false)   break;
        if (ChunkHeader.dwChunkSize < sizeof(SChunkHeader))             return RES_ERROR;

        WCHAR mess [1024];
        wsprintf (mess, TEXT("ChunkHeader:\nwChunkID:\t%d\ndwChunkSize:\t%d\n\n"), ChunkHeader.wChunkID, ChunkHeader.dwChunkSize);
        MessageBox (NULL, mess, TEXT("Chunk gefunden"), MB_OK);

        // Alle Chunks durchgehen
        switch (ChunkHeader.wChunkID)
        {
        case MAIN3DS:   break;  // Hauptchunk
        case EDIT3DS:   break;  // Edit-Chunk
            
        default:
            // Unwichtiger Chunk. Wird übersprungen
            if (!file.Seek (CF_SEEK_CURSOR, (ChunkHeader.dwChunkSize - sizeof (SChunkHeader))))
                return RES_ERROR;
            break;
        }
    }

    return RES_OK;
}


Ich habe es mittlerweile bereits mit mehreren .3DS-Dateien ausprobiert:
Der erste Chunk, der eingelesen wird ist immer der Main-Chunk.
Der zweite hat jedoch ungültige Werte und fliegt durch die Abfrage "if (ChunkHeader.dwChunkSize < sizeof(SChunkHeader))".
Aber müsste es nicht eigneltich funktionieren, denn nach einer 3DS-Dokumentation befindet sich direkt hinter dem Main-Chunk ein weiterer Chunk...

Ich habe auch schon den 3DS-Ladecode des ModelConverters bis auf denselben Bereich gekürzt und eingesetzt, hatte dann jedoch immernoch dasselbe Problem. Wenn ich die Datei jedoch mit dem ModelConverter lade, werden alle Daten korrekt erkannt.


Weiß jemand, was da schief läuft?

Beste Grüße.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »David Mehre« (17.10.2011, 18:06)


2

09.05.2009, 21:30

So wie ich das sehe ist da nur ein Read drin, was so schonmal nicht gehen kann. Du musst erst den Chunk Header lesen, und aus diesem dann die Größe benutzen um die Chunkdaten zu lesen. Du brauchst also pro Chunk mindestens 2 Lesevorgänge.
Lieber dumm fragen, als dumm bleiben!

David Mehre

unregistriert

3

09.05.2009, 22:05

Zitat von »"Jonathan_Klein"«

So wie ich das sehe ist da nur ein Read drin, was so schonmal nicht gehen kann. Du musst erst den Chunk Header lesen, und aus diesem dann die Größe benutzen um die Chunkdaten zu lesen. Du brauchst also pro Chunk mindestens 2 Lesevorgänge.


Momentan will ich ja erstmal nur die Header auslesen, um den Inhalt kümmere ich mich noch gar nicht.


Ich habe die Methode etwas aufgedröselt, und nun erkennt er schon einige Chunks. Komisch ist nur, dass nach fast jedem Chunk ein "unwichtiger" Chunk mit einer Größe von 10 Bytes folgt.

Der neue Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    ofstream oInfo ("Info.txt");
    BYTE *pData = (BYTE*)(file.Get_Buffer());
    
    // ---------------------------------------

    // Mit dem lesen beginnen

    while (TRUE)
    {       
        if (pData - (BYTE*)(file.Get_Buffer()) >= file.Get_Size ()) break;
        memcpy (&ChunkHeader.wChunkID, pData, 2);
        memcpy (&ChunkHeader.dwChunkSize, pData + 2, 4);
        pData += 6;
                
        oInfo << endl;
        oInfo << "Chunk-ID:\t"   << ChunkHeader.wChunkID << endl;
        oInfo << "Chunk-Size:\t" << ChunkHeader.dwChunkSize << endl;

        // Alle Chunks durchgehen

        switch (ChunkHeader.wChunkID)
        {
        case MAIN3DS:   oInfo << "Main-Chunk gefunen!\n"; break;    // Hauptchunk

        case EDIT3DS:   oInfo << "Edit-Chunk gefunden!\n"; break;   // Edit-Chunk


        case EDIT_MATERIAL: oInfo << "Material-Chunk gefunden!\b";pData += ChunkHeader.dwChunkSize - 6; break; // Material-Chunk


        case EDIT_OBJECT: oInfo << "Object-Chunk gefunden!\n";  break;  // Object-Chunk

        case OBJ_TRIMESH: oInfo << "Mesh-Chunk gefunden!\n";    break;  // Mesh-Chunk

        case TRI_VERTEXL: oInfo << "Vertex-Chunk gefunden!\n";  pData += ChunkHeader.dwChunkSize - 6; break;    // Vertex-Chunk

        case TRI_SMOOTH:  oInfo << "Smooth-Chunk gefunden!\n";  pData += ChunkHeader.dwChunkSize - 6; break;    // Smooth-Chunk

            
        default:
            pData += ChunkHeader.dwChunkSize - 6;
            oInfo << "Unwichtiger Chunk.\n";
            break;
        }
    }
    
    oInfo.close();


Die Ausgabe:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Chunk-ID:   19789
Chunk-Size: 20235
Main-Chunk gefunen!

Chunk-ID:   2
Chunk-Size: 10
Unwichtiger Chunk.

Chunk-ID:   15677
Chunk-Size: 19995
Edit-Chunk gefunden!

Chunk-ID:   15678
Chunk-Size: 10
Unwichtiger Chunk.

Chunk-ID:   45055
Chunk-Size: 227
Material-Chunk gefunden!
Chunk-ID:   45055
Chunk-Size: 235
Material-Chunk gefunden!
Chunk-ID:   256
Chunk-Size: 10
Unwichtiger Chunk.

Chunk-ID:   16384
Chunk-Size: 19507
Object-Chunk gefunden!

Chunk-ID:   31043
Chunk-Size: 1684957548
Unwichtiger Chunk.


Da läuft immer noch irgendwas schief, oder?

Werbeanzeige