Bounding Algorithmus von mir scheint nicht der beste zu sein, wie macht ihr das?
-
Hallo!
Wie ich hier bestimmt schon 30 mal gesagt habe teile ich mein Model und mein Level in BoundinBoxes auf. Bis zu einer bestimmten Tiefe in Octrees..jedes kann in weitere Octrees unterteilt sein. Dann überprüfe ich die OberOctrees miteinander und gehe dann immer weiter runter bis ich beim Level an den untersten bin überprüfe ich die Polygone des Levels in der untersten Box nur mit der ModelBox, wenn diese kollidieren gibt es eine Kollision
So nun gebe ich hier mal preis wie ich das implementieren wollte.Wenn ich ein Modellade kann man angeben in wie viele Verschachtelungen von Octrees es unterteilt werden soll. Dann beim Aufteilen überprüfe ich alle Polygone des Models mit der momentanen Box und schaue ob eine Ecke des Polygons in dieser Unterbox vorhanden ist. Wenn ja schreibe ich die Nummer im IndexArray (wo das Polygon anfängt) in ein Array der Box.
Wenn ich die Tasten vor/zurück/rechts/links betätige verändere ich die Position der BoundingBoxes je nachdem wie ich mich bewege (nicht jedes Polygon, sondern nur die BoundingBoxes für die Berechnung).
Dann überprüfe ich ob eine Kollision vorhanden ist, ich schreibe euch jetzt mal den Code in Worten:
bool LevelModelKollision( level, Model) { if KugelVonModel die äußerste BoundingBox von level berührt weiter, sonst return false if AußenBox von Level kollidiert mit AußenBox von Model weiter, sonst return false BOOL BoxesLevel und BoxesModel[8] wenn GetKollision(level->Bound, model->Bound, BL, BM) => kollision } bool GetKollision(levelBound, modelBound, BOOL * BoxesLevel, BOOL * BoxesModel) { bool b1, b2 b1 = Ist Die Verschachtelung der momentanten Box kleiner als die tiefste Verschachtelung bei model? b2 = das selbe nur beim level If b1 und b2 sind FALSE, d.h. die momentane Box ist bei beiden die tiefste { Nehme alle Polygone des Levels der tiefsten Box im moment und schaue ob sie mit der Box des Models kollidiert, wenn ja return false } Wenn bei einem der beiden noch nicht die tiefste erreicht wurde Überprüfe welche Boxen der tieferen Verschachtelung sich schneiden und schreibe sie in BoxesLevel und BoxesModel je nachdem ob sie eine andere schneiden oder nicht (TRUE/FALSE) for(int i = 0; i < 8; i++) { for(int j = 0; j < 8; j++) { Wenn BoxesLevel[i] Und BoxesModel[j], d.h. wenn beide mit der anderen Überbox kollidieren { if(GetKollision(levelBound->next[i], levelBound[j], BoxesLevel, BoxesModel) ) return true; } return false; }
Sooo das nenn ich mal ne Schreibarbeit
Wie all meine Algorithmen nehme ich an ist er sehr kompliziert. Kennt ihr eine einfachere Lösung?Danke euch
Kevin
edit: falls meine Worte unverständlich waren hier der Code:
BOOL bModelKollision(DX_Object * dd_obj, CModelFormat * m_level, CModelFormat * m_player) { BOOL HitsFirst[8]; BOOL HitsSecond[8]; if(!BoxHitsSphere(dd_obj, m_level->m_Bound, m_player->dCenter, m_player->dRadius)) { return false; } //MessageBox(0, "passt", 0, 0); if(!BoundHitsBound(m_level->m_Bound, m_player->m_Bound, HitsFirst, HitsSecond)) { return false; } //MessageBox(0, "passt", 0, 0); SetWindowText(dd_obj->hwnd, "Sodala mach amal"); if(GetKollisionBoxes(m_level, m_player, m_level->m_Bound, m_player->m_Bound, HitsFirst, HitsSecond)) MessageBox(0, "kollision", 0, 0); return FALSE; } BOOL GetKollisionBoxes(CModelFormat* level, CModelFormat * player, CBoundingBox *m_level, CBoundingBox *m_player, BOOL *BoxesOfLevel, BOOL *BoxesOfPlayer) { BOOL b1, b2; b1 = b2 = FALSE; if(m_level->dOwnNumber < m_level->dContainers) b1 = TRUE; if(m_player->dOwnNumber < m_player->dContainers) b2 = TRUE; if(!b1 && !b2) { if(m_level->dVMembersCount > 0 && m_player->dVMembersCount > 0) { //MessageBox(0, "bla", 0, 0); for(int i = 0; i < (signed)m_level->dVMembersCount; i++) { v11 = level->v[level->dwIndicies[m_level->dVMembers[i]]].position; v12 = level->v[level->dwIndicies[m_level->dVMembers[i] + 1]].position; v13 = level->v[level->dwIndicies[m_level->dVMembers[i] + 2]].position; for(int j = 0; j < (signed)m_player->dVMembersCount; j++) { v21 = player->m_vertizes[player->dwIndicies[m_player->dVMembers[j]]].v.position; v22 = player->m_vertizes[player->dwIndicies[m_player->dVMembers[j] + 1]].v.position; v23 = player->m_vertizes[player->dwIndicies[m_player->dVMembers[j] + 2]].v.position; if(bTriangleHitsTriangle(v11, v12, v13, v21, v22, v23)) return true; } } //MessageBox(0, "mh", 0, 0); } } else { if(m_level->dOwnNumber < m_level->dContainers || m_player->dOwnNumber < m_player->dContainers) { if(!BoundHitsBound(m_level, m_player, BoxesOfLevel, BoxesOfPlayer)) return false; } for(int i = 0; i < 8; i++) { for(int j = 0; j < 8; j++) { //if(Hits if(BoxesOfLevel[i] && BoxesOfPlayer[j]) { if(GetKollisionBoxes(level, player, b1 ? &m_level->next[i] : m_level, b2 ? &m_player->next[j] : m_player, BoxesOfLevel, BoxesOfPlayer)) return true; } } } } return false; }