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

soxx

Frischling

  • »soxx« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Klagenfurt

  • Private Nachricht senden

1

12.05.2006, 11:01

Kollisionserkennung mit tbTriangleHitsTriangle

Hallo !

ich verwende eine leicht modifizierte Version dieser Funktion (d.h. ich verwende DirectX Strukturen wie D3DXVECTOR3 etc.)

Nun prüfe ich 2 Mesh-Modelle auf Kollision (beides .x Dateien).
Vorher extrahiere ich den Index und Vertexpuffer und erstelle jeweils eine Liste mit Dreiecken.
Diese Dreiecke lasse ich dann durch diese Funktion laufen. Leider bekomme ich immer ein TRUE für eine Kollision zurück, obwohl man keine Kollision auf dem Bildschirm wahrnimmt.
ich schätze mal, dass ich irgendetwas bei der Dreiecksberechnung durcheinander bringe - vielleicht sieht jemand von euch den Fehler:

KOLLISIONSABFRAGE:

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
bCollision = FALSE;
                    std::list<STriangle> listMesh1 = (*iteMeshes1)->getTriangleList();
                    std::list<STriangle> listMesh2 = (*iteMeshes2)->getTriangleList();

                    std::list<STriangle>::iterator iteTriangles1;
                    iteTriangles1 = listMesh1.begin();

                    std::list<STriangle>::iterator iteTriangles2;

                    // alle Dreiecke der 2 Modelle miteinander auf Kollision vergleichen !
                    while (iteTriangles1 != listMesh1.end())
                    {                       
                        iteTriangles2 = listMesh2.begin();
                        while (iteTriangles2 != listMesh2.end())
                        {
                            D3DXVECTOR3 pvHitStart;
                            ZeroMemory(&pvHitStart, sizeof(D3DXVECTOR3));
                            D3DXVECTOR3 pvHitEnd;
                            ZeroMemory(&pvHitStart, sizeof(D3DXVECTOR3));
                            bCollision = this->checkTriangleHitsTriangle(iteTriangles1->vPosX, 
                                iteTriangles1->vPosY,
                                iteTriangles1->vPosZ,
                                iteTriangles2->vPosX,
                                iteTriangles2->vPosY,
                                iteTriangles2->vPosZ,
                                &pvHitStart,
                                &pvHitEnd);

                            // nachdem kollision aufgetreten ist, muss ein dreieck herangezogen werden,
                            // mittels dem dann der normalvektor und somit der richtungsvektor berechnet wird.
                            if (bCollision)
                                return TRUE;

                            iteTriangles2++;
                        }
                        iteTriangles1++;
                    }


DREIECKSBERECHNUNG:

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
BOOL createTriangleList()
{
    int                             iLength = 0;
    iLength = sizeof(this->m_piAllIndizes) / sizeof(WORD);

    STriangle                       vTempTriangle;
    WORD                            wIndex0;
    WORD                            wIndex1;
    WORD                            wIndex2;

    // ein Dreieck besteht aus 3 Vertices !
    for (int i = 0; i < this->m_iIndizesSize; i = i+3)
    {
        wIndex0                     = this->m_piAllIndizes[i];
        wIndex1                     = this->m_piAllIndizes[i+1];
        wIndex2                     = this->m_piAllIndizes[i+2];
        memcpy(&vTempTriangle.vPosX, &this->m_psAllVertices[wIndex0].vPos, sizeof(D3DXVECTOR3));
        memcpy(&vTempTriangle.vPosY, &this->m_psAllVertices[wIndex1].vPos, sizeof(D3DXVECTOR3));
        memcpy(&vTempTriangle.vPosZ, &this->m_psAllVertices[wIndex2].vPos, sizeof(D3DXVECTOR3));
        m_listTriangle.push_back(vTempTriangle);        // aufnehmen aller Dreiecke in dieser Liste !
    }
    return TRUE;
}

std::list<STriangle> getTriangleList()
{
    STriangle                       sTempTriangle;
    D3DXVECTOR3                     vTempVector;
    this->m_listConvertedTriangles.clear();

    std::list<STriangle>::iterator  iteTriangles;
    iteTriangles = this->m_listTriangle.begin();
    while (iteTriangles != this->m_listTriangle.end())
    {
        memcpy(&vTempVector, &(*iteTriangles).vPosX, sizeof(D3DXVECTOR3));
        D3DXVec3TransformCoord(&sTempTriangle.vPosX, &vTempVector, &this->m_mMeshMatrix);
        
        ZeroMemory(&vTempVector, sizeof(D3DXVECTOR3));

        memcpy(&vTempVector, &(*iteTriangles).vPosY, sizeof(D3DXVECTOR3));
        D3DXVec3TransformCoord(&sTempTriangle.vPosY, &vTempVector, &this->m_mMeshMatrix);
        
        ZeroMemory(&vTempVector, sizeof(D3DXVECTOR3));

        memcpy(&vTempVector, &(*iteTriangles).vPosZ, sizeof(D3DXVECTOR3));
        D3DXVec3TransformCoord(&sTempTriangle.vPosZ, &vTempVector, &this->m_mMeshMatrix);
        
        ZeroMemory(&vTempVector, sizeof(D3DXVECTOR3));
        
        this->m_listConvertedTriangles.push_back(sTempTriangle);

        iteTriangles++;
    }
    
    return this->m_listConvertedTriangles;
}



KOPIEREN VON VERTEX- UND INDEXBUFFER:

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
void collectIndizesAndVerticesFromMesh()
{
    HRESULT                         hr;
topic_id=86467
    LPDIRECT3DVERTEXBUFFER9         pvb;
    LPDIRECT3DINDEXBUFFER9          pib;    
    
    this->m_pMesh->GetIndexBuffer(&pib);
    D3DINDEXBUFFER_DESC iDesc;
    pib->GetDesc(&iDesc);
    int iFaces                      = m_pMesh->GetNumFaces();
    this->m_iIndizesSize            = iFaces * 3;   // jedes Face besteht aus 3 Indizes, darum *3

    switch(iDesc.Format)
    {
        case D3DFMT_INDEX16:
        {
            this->m_piAllIndizes    = (WORD*)malloc(this->m_pMesh->GetNumFaces() * 3 * sizeof(WORD));
            WORD* pw16BitsData      = NULL;
            hr = pib->Lock(0, this->m_pMesh->GetNumFaces() * 3 * 2, (void**)(&pw16BitsData), D3DLOCK_READONLY);
            memcpy(this->m_piAllIndizes, pw16BitsData, this->m_pMesh->GetNumFaces() * 3 * sizeof(WORD));
            pw16BitsData            = NULL;
            hr = pib->Unlock();
            break;
        }
        case D3DFMT_INDEX32:
        {
            this->m_piAllIndizes    = (WORD*)malloc(this->m_pMesh->GetNumFaces() * 3 * sizeof(DWORD));
            WORD* pw32BitsData      = NULL;
            hr = pib->Lock(0, this->m_pMesh->GetNumFaces() * 3 * 4, (void**)(&pw32BitsData), D3DLOCK_READONLY);
            memcpy(this->m_piAllIndizes, pw32BitsData, this->m_pMesh->GetNumFaces() * 3 * sizeof(DWORD));
            pw32BitsData            = NULL;
            hr = pib->Unlock();
            break;
        }
    }
    
    WTL::CString strTMP = this->getIdentifier();
    this->m_pMesh->GetVertexBuffer(&pvb);
    D3DVERTEXBUFFER_DESC vDesc;
    pvb->GetDesc(&vDesc);
    m_uiVertexSize                  = m_pMesh->GetNumVertices();
    SVertexForMesh* pVertexData     = NULL;
    
    DWORD                   dwFVFMesh;
    dwFVFMesh               = this->m_pMesh->GetFVF();
    this->m_psAllVertices   = (SVertexForMesh*)malloc(m_pMesh->GetNumBytesPerVertex() * m_pMesh->GetNumVertices());
    
    if (dwFVFMesh != D3DFVF_MESHVERTEX) // es handelt sich um ein einfaches Modell (besteht nur aus Normalen und Vertizes)
    {
        if (dwFVFMesh == D3DFVF_MESHVERTEX_TEXTURE) // es handelt sich um ein "komplizierteres" Modell (Normale+Vertizes+Diffuse+Texturkoordinaten)
        {
            LPD3DXMESH          lpTmpMesh;
            // Das Objekt muss nun in ein einfaches Modell umkonvertiert werden, damit man später die Dreiecke berechnen kann
            hr = this->m_pMesh->CloneMeshFVF(0, D3DFVF_MESHVERTEX, 
                this->m_pDevice, 
                &lpTmpMesh);

            // Puffer sperren und auslesen
            hr = pvb->Lock(0, lpTmpMesh->GetNumBytesPerVertex() * lpTmpMesh->GetNumVertices(),
                (void**)(&pVertexData), 
                D3DLOCK_READONLY);
            memcpy(m_psAllVertices, pVertexData, lpTmpMesh->GetNumBytesPerVertex() * lpTmpMesh->GetNumVertices());
            SAFE_RELEASE(lpTmpMesh);
        }
        else
            return;
    }
    else
    {
        // Puffer sperren und auslesen
        hr = pvb->Lock(0, m_pMesh->GetNumBytesPerVertex() * m_pMesh->GetNumVertices(),
                (void**)(&pVertexData), 
                D3DLOCK_READONLY);
        memcpy(m_psAllVertices, 
            pVertexData, 
            m_pMesh->GetNumBytesPerVertex() * m_pMesh->GetNumVertices());
    }
    
    pVertexData                     = NULL;

    // Puffer entsperren
    hr = pib->Unlock();

    pvb                             = NULL;
    pib                             = NULL;
}


nach dem collectIndizesAndVerticesFromMesh() wird createTriangleList() aufgerufen.
Bei getTriangleList() werden alle Dreiecke mit der Matrix des Modells transformiert -> die Matrix ist richtig - es wird ja auch alles richtig gerendert.

Vielen Dank für jede Antwort!

mfg
soxx

2

12.05.2006, 16:13

Ich habe es mir nicht genau durchgelesen - ein bisschen viel Code, aber du wirst damit nicht glücklich werden. Du solltest je nach Fall entweder AABBs, OBBs oder BoundingSpheres verwenden.

soxx

Frischling

  • »soxx« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Klagenfurt

  • Private Nachricht senden

3

12.05.2006, 16:22

Hallo !

nun ja, wenn so einfach wäre - ich brauche eben eine ganz genaue Kollisionserkennung.
Habe diese gleich wie David in seinem Buch aufgebaut - mittels Octree´s.
Jetzt habe ich aber nur einmal die Dreieck vs Dreieck Methode aufgerufen - mit jeweils allen Dreiecken der 2 Modelle.
und eben diese Kollisionserkennung funktioniert nicht richtig. Leider weiß ich aber nicht wo der Fehler liegt... ich vermute, dass ich meine Dreiecke in das falsche Koordinatensystem umrechne... aber bei der Matrix die ich dazu verwende bin ich mir absolut sicher, dass das die richtige ist.

mfg
soxx

ext

Treue Seele

  • Private Nachricht senden

4

12.05.2006, 18:02

Wenn du mal die unnötige Komplexität rausnehmen würdest, dann hättest du a) die Chance, dass jemand sich die Mühe macht und den Quellcode anschaut
und
b) du den Fehler selber findest

z.B.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
   memcpy(&vTempVector, &(*iteTriangles).vPosX, sizeof(D3DXVECTOR3));
      D3DXVec3TransformCoord(&sTempTriangle.vPosX, &vTempVector, &this->m_mMeshMatrix);
      
      ZeroMemory(&vTempVector, sizeof(D3DXVECTOR3));

      memcpy(&vTempVector, &(*iteTriangles).vPosY, sizeof(D3DXVECTOR3));
      D3DXVec3TransformCoord(&sTempTriangle.vPosY, &vTempVector, &this->m_mMeshMatrix);
      
      ZeroMemory(&vTempVector, sizeof(D3DXVECTOR3));

      memcpy(&vTempVector, &(*iteTriangles).vPosZ, sizeof(D3DXVECTOR3));
      D3DXVec3TransformCoord(&sTempTriangle.vPosZ, &vTempVector, &this->m_mMeshMatrix);
      
      ZeroMemory(&vTempVector, sizeof(D3DXVECTOR3));


im Gegensatz zu

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
D3DXVec3TransformCoord(&sTempTriangle.vPosX, &iteTriangles->vPosX, &m_mMeshMatrix);
      
D3DXVec3TransformCoord(&sTempTriangle.vPosY, &iteTriangles->vPosY, &m_mMeshMatrix);

D3DXVec3TransformCoord(&sTempTriangle.vPosZ, &iteTriangles->vPosZ, &m_mMeshMatrix);

m_listConvertedTriangles.push_back(sTempTriangle);

 ++iteTriangles;



Nennst du die Vertizes deiner Dreiecke wirklich x,y,z?

soxx

Frischling

  • »soxx« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Klagenfurt

  • Private Nachricht senden

5

15.05.2006, 08:38

Hallo !

ja, da ich eine struktur, die ich für was anderes definiert habe, wieder verwende.
wegen der komplexität:

mir ist dies schon klar, nur wird meistens nachgefragt "wie dies und das implementiert ist"... da poste ich doch lieber gleich das gesamte.

mfg
soxx

soxx

Frischling

  • »soxx« ist der Autor dieses Themas

Beiträge: 53

Wohnort: Klagenfurt

  • Private Nachricht senden

6

15.05.2006, 11:07

nun ja...
wenn man sich david sein buch etwas genauer ansieht steht da:
"es ist also die transformation mit der matrix von modell B und anschließend mit der inversen matrix von Modell A nötig"

==> problem gelöst !

mfg
soxx

pip

Frischling

  • Private Nachricht senden

7

30.05.2006, 13:35

wie genau ist eigentlich die dreieck/dreieck kollisionsabfrage in der engine ?!?

lg pip

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

8

30.05.2006, 13:45

Das wird im Buch genauestens erläutert... Schau da nach!
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Werbeanzeige