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

big_muff

Alter Hase

  • »big_muff« ist der Autor dieses Themas

Beiträge: 460

Wohnort: Schweiz

Beruf: Informatikstudent (4. Semester)

  • Private Nachricht senden

1

31.05.2006, 19:12

MilkShape3D Exporter

Ich versuche seit einigen Tagen einen Exporter für MilkShape3D zu schreiben. Das klappte auch schnell sehr gut, doch bei grösseren Objekten traten Probleme beim Darstellen in der Engine auf (es wurden nur Teile des Objektes gerendert).
Daraufhin habe ich ein kleine Programm geschrieben, das alle Wert ausliest und per MessageBox ausgibt und habe festgestellt das die Indices ab einem bestimmten (von Modell zu Modell unterschiedlichen) Punkt -12851 betragen.
Danach habe ich beim Exporter eine MessageBox eingefügt, die die Indices unmittelbar vor dem Speichern ausgibt und da sind alle noch in Ordnung.
Der Fehler passiert aber irgendo zwischen Speichern und Lesen was ich mir nicht so recht erklären kann.

Ich weiss jetzt nicht welcher Teil des Codes für den Fehler verantwortlich ist, also poste ich hier den kompletten Kern des Exports (so lange ist er aber gar nicht):

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
57
58
59
60
61
62
63
64
65
66
67
68
69
    for (i = 0; i < msModel_GetMeshCount (pModel); i++)
    {
        msMesh *pMesh = msModel_GetMeshAt (pModel, i);

        HFListElement<HFVertex> *VertexElement;
        HFList<HFVertex>        VertexList;
        HFList<SHORT>           IndexList;

        //Daten sammeln

        for (j = 0; j < msMesh_GetTriangleCount (pMesh); j++)
        {
            msTriangle *pTriangle = msMesh_GetTriangleAt (pMesh, j);
            
            word nIndices[3];
            word nNormalIndices[3];
            msTriangle_GetVertexIndices (pTriangle, nIndices);
            msTriangle_GetNormalIndices (pTriangle, nNormalIndices);

            for(v=0; v<3; v++)
            {
                msVertex *pVertex = msMesh_GetVertexAt(pMesh, nIndices[v]);
                msVec3 Position;
                msVec3 Normal;
                msVec2 Texture;
                SHORT  Index;

                msVertex_GetVertex(pVertex, Position);
                msVertex_GetTexCoords(pVertex, Texture);
                msMesh_GetVertexNormalAt(pMesh, nNormalIndices[v], Normal);

                HFVertex SVertex;
                SVertex.Position[0] = Position[0];
                SVertex.Position[1] = Position[1];
                SVertex.Position[2] = Position[2];
                SVertex.Texture[0]  = Texture[0];
                SVertex.Texture[1]  = Texture[1];
                SVertex.Normal[0]   = Normal[0];
                SVertex.Normal[1]   = Normal[1];
                SVertex.Normal[2]   = Normal[2];

                VertexElement = VertexList.Search(VertexSearchFunc, &SVertex);
                if(VertexElement==NULL)
                {
                    Index = VertexList.GetElementCount();
                    VertexList.AddElement(&SVertex);
                }
                else
                    Index = VertexList.GetElementNumByPointer(VertexElement);

                IndexList.AddElement(&Index);
            }
        }

        //Daten schreiben

        UINT VertexCount = VertexList.GetElementCount();
        UINT IndexCount  = IndexList.GetElementCount();
        
        fwrite(&VertexCount, 4, 1, file);
        for(j=0; j<VertexList.GetElementCount(); j++)
            fwrite(VertexList.GetElementDataByInt(j), 32, 1, file);
        
        fwrite(&IndexCount, 4, 1, file);
        for(j=0; j<IndexList.GetElementCount(); j++)
            fwrite(IndexList.GetElementDataByInt(j), 2, 1, file);

        //Listen löschen

        VertexList.Clear();
        IndexList.Clear();
    }


Der Code wurde teilweise aus den Beispiel-Exportern des MilkShape-SDKs geholt. (Das habe ich jetzt gesagt um alle Nöregleien am Codestyle, wie "Alle Variablen werden am Anfang der Funktion definiert", von mir weisen zu können ;))

Einige Erklärungen zur Funktionsweise:
-Bei MilkShape liegen die Normalenvektoren pro Index vor und nicht pro Vertex. Deshalb die ganzen Umformungen über Listen. Mein Format ist schlussendlich so aufgebaut, dass man in der Engine nichts mehr umrechnen muss, sondern dass die Daten alle schon in der passenden Form vorliegen.
-HFList ist meine eigene Listenklasse und die hat bisher immer funktioniert
-VectorSearchFunc ist eine Funktion die TRUE zurückliefert wenn die 2 Vertices identisch sind

Ich hoffe das reicht, damit hier jemand den Fehler findet :?
Nur Idioten halten Ordnung, ein Genie beherrscht das Chaos.[size=7]

[/size]HardFate - Ein Start, Ein Ziel, Viele Wege[size=7]

[/size]Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.

big_muff

Alter Hase

  • »big_muff« ist der Autor dieses Themas

Beiträge: 460

Wohnort: Schweiz

Beruf: Informatikstudent (4. Semester)

  • Private Nachricht senden

2

01.06.2006, 11:30

Ich habe mir gedacht, da der Fehler beim Speichern und Laden der SHORT-Werte geschieht, schreibe ich mal ein Testprogramm, dass 100 SHORT-Werte schreibt und sie anschliessend wieder ausliesst:

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
FILE *File;
SHORT Value, i;
char buffer[20];

fopen_s(&File, "Test2.hfm", "w");
for(i=0; i<100; i++)
{
    if(fwrite(&i, 2, 1, File)!=1)
        MessageBoxA(NULL, "Schreib-Fehler", "Test2.hfm", MB_OK);
}
fclose(File);

fopen_s(&File, "Test2.hfm", "r");
for(i=0; i<100; i++)
{
    Value=0;
    if(fread(&Value, 2, 1, File)!=1)
        MessageBoxA(NULL, "Lese-Fehler", "Test2.hfm", MB_OK);
    sprintf_s(buffer, 20, "%d\n\nWeiter?", Value);
    if(MessageBoxA(NULL, buffer, "Test2.hfm", MB_YESNO)!=IDYES)
        i=100;
}
fclose(File);


Dabei sollten ja alle Werte von 0 bis 99 ausgegeben werden, aber nach dem Wert 25 tritt jedesmal ein Lesefehler auf (Schreibfehler kamen nie vor) und es wird nur noch 0 ausgegeben. Wenn mir das jemand erkläre kann, wäre mein Problem sicher auch gelöst. (Der Debug-Modus hat übrigens auch nicht interessantes geliefert)
Nur Idioten halten Ordnung, ein Genie beherrscht das Chaos.[size=7]

[/size]HardFate - Ein Start, Ein Ziel, Viele Wege[size=7]

[/size]Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

01.06.2006, 13:47

hi!

genau den fehler hatte ich auch mal (hab mir die zähne dran ausgebissen^^)

C-/C++-Quelltext

1
fopen_s(&File, "Test2.hfm", "w");


so richtig:

C-/C++-Quelltext

1
fopen_s(&File, "Test2.hfm", "wb"); 


:D

big_muff

Alter Hase

  • »big_muff« ist der Autor dieses Themas

Beiträge: 460

Wohnort: Schweiz

Beruf: Informatikstudent (4. Semester)

  • Private Nachricht senden

4

01.06.2006, 13:59

Endlich funktioniert es perfekt. VIELEN DANK!!!!! Da habe ich mir auch die Zähne dran ausgebissen...

Falls jemand mal das gleiche Problem haben sollte, natürlich muss das Öffnen zum Lesen auch das "b" enthalten:

C-/C++-Quelltext

1
fopen_s(&File, "Test2.hfm", "rb");
Nur Idioten halten Ordnung, ein Genie beherrscht das Chaos.[size=7]

[/size]HardFate - Ein Start, Ein Ziel, Viele Wege[size=7]

[/size]Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.

john

Alter Hase

Beiträge: 786

Beruf: Schüler

  • Private Nachricht senden

5

01.06.2006, 14:30

Wobei das "b" für "Binärmodus" steht, nur um die Aussage zu komplettieren. :)
mfg
john

Werbeanzeige