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