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 Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

11

14.12.2003, 11:07

Zitat von »"chrissi"«

Einen Vektor darin nennt man doch Normalvektor.

Nein, ein Normalenvektor ist ein Vektor, der z.B. senkrecht auf einem Dreieck steht, oder senkrecht zur Oberfläche eines Objekts (Vertexnormalenvektor).

12

14.12.2003, 14:10

Oh, das wusste ich nicht...

Dann würde ich absoluten Poistionkoordinaten so herausfinden:

Quellcode

1
2
3
vA=&pOctree->m_pvVectors[pOctreeNode->pdwIndices[tb * 3]];; 
vB=&pOctree->m_pvVectors[pOctreeNode->pdwIndices[(tb * 3) + 1]]; 
vC=&pOctree->m_pvVectors[pOctreeNode->pdwIndices[(tb * 3) + 2]]; 


Danke nochmals,

Mfg, Chrissi

13

15.12.2003, 13:28

Also,

ich hab jetzt mal ein bisschen rumprobiert. Dabei herausgekommen ist das:

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
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// Kollision zwischen Octree und Quarder berechnen
BOOL CGame::BoxHitsOctree(const tbVector3& vBoxMin,
                                  const tbVector3& vBoxMax,
                                  const tbMatrix& mBoxTransformation,
                                  tbOctree* pOctree)
{
    // Parameter prüfen
    if(pOctree == NULL)
        TB_ERROR_NULL_POINTER("pOctree", TB_ERROR);
    if(!pOctree->ExtraData())
        TB_ERROR("Der Octree hat keine Extradaten!", TB_ERROR);

    BOOL bCollision = FALSE;

    // Rekursive Funktion aufrufen
    return BoxHitsOctreeRec(vBoxMin, vBoxMax, mBoxTransformation, pOctree, pOctree->GetRootNode(), &bCollision);
}

// Kollision zwischen Octree und Quarder berechnen
BOOL CGame::BoxHitsOctreeRec(const tbVector3& vBoxA,
                                    const tbVector3& vBoxB,
                                    const tbMatrix& mBoxTransformation,
                                    tbOctree* pOctree,
                                    const tbOctreeNode* pNode,
                                    BOOL* pbCollision)
{
    // Prüfen, ob der Quarder den Umgebungsquader des Knotens trifft.
    // Falls nicht, können wir sofort abbrechen
    if(!tbBoxHitsBox(vBoxA, vBoxB, mBoxTransformation,
                      pNode->vBoundingBoxMin,
                      pNode->vBoundingBoxMax,
                      tbMatrixIdentity(), 3))
    {
        // Abbruch!
        return FALSE;
    }

    // Ist dieser Knoten ein Endknoten? Falls ja, dann testen wir die
    // Kollision jetzt auf Dreiecksebene.
    if(pNode->bIsLeaf)
    {
        tbVector3   vTriA;
        tbVector3   vTriB;
        tbVector3   vTriC;

        // Nun jedes Dreieck dieses Knotens durchgehen und
        // nach der nächsten Kollisionen suchen
        for(DWORD t = 0; t < pNode->dwNumIndices / 3; t++)
        {
            // Ersten Vektor
            vTriA = pOctree->GetVectors()[pNode->pdwIndices[t * 3]];

            // Zweiten Vektor
            vTriB = pOctree->GetVectors()[pNode->pdwIndices[t * 3 + 1]];

            // Dritten Vektor
            vTriC = pOctree->GetVectors()[pNode->pdwIndices[t * 3 + 2]];
            
            // Kollidiert das Dreieck mit dem Quarder:
            // 1-3: Kollidieren die Drei "Ecklinien" mit dem Quarder?
            // 4-6: Kollidieren die Drei Seitenhalbierenden der "Ecklinien" des Dreiecks mit dem Quarder?
            if(tbLineHitsBox(vTriA, vTriB, vBoxA, vBoxB, mBoxTransformation) ||
                tbLineHitsBox(vTriB, vTriC, vBoxA, vBoxB, mBoxTransformation) ||
                tbLineHitsBox(vTriC, vTriA, vBoxA, vBoxB, mBoxTransformation)/* ||
                tbLineHitsBox(tbVector3(vTriA.x/2, vTriA.y, vTriA.z), tbVector3(vTriB.x/2, vTriB.y, vTriB.z), vBoxA, vBoxB, mBoxTransformation) ||
                tbLineHitsBox(tbVector3(vTriB.x/2, vTriB.y, vTriB.z), tbVector3(vTriC.x/2, vTriC.y, vTriC.z), vBoxA, vBoxB, mBoxTransformation) ||
                tbLineHitsBox(tbVector3(vTriC.x/2, vTriC.y, vTriC.z), tbVector3(vTriA.x/2, vTriA.y, vTriA.z), vBoxA, vBoxB, mBoxTransformation)*/)
            {
                // Kollision
                *pbCollision = TRUE;
                return TRUE;
            }

                    }
    }
    else
    {
        // Dieser Knoten ist kein Endknoten.
        // Wir gehen seine Unterknoten durch und testen diese.
        for(DWORD i = 0; i < 8; i++)
        {
            BoxHitsOctreeRec(vBoxA, vBoxB, mBoxTransformation, pOctree, pNode->apChild[i], pbCollision);
            
            if(*pbCollision)
                return TRUE;
        }
    }

    // Keine Kollision!
    return FALSE;
}


Das ganze funktioniert aber leider nicht. (Meine ich auf jeden Fall.) Die Framerate ist, wenn der Spieler nicht den Octree trifft (bzw, per Augenmaß nicht eine der BB-Boxen der Nodes trifft konstant 40. Wenn aber nicht, nur 20. Das liegt an dem Testen, ob die Dreiecke die Kiste treffen. Bis dahin ist ja noch alles OK. Nur, die Dreiecke sind gar nicht die des Octrees. Ich hab mal nen paar Screnshoots gemacht. Landschaft - Spieler - Dreiecke, die getestet werden. Das Ergebnis: Seht selbst!!!



(Link)


(Link)


Hoffe auf Hilfe,

Danke,

Chrissi

Werbeanzeige