bounded box Kollisionserkennung in opengl
Ist hier die überlagerung des Programms. Ich arbeite in visual studio 10 , c++ mit opengl/glut. Ich bin versucht, ein Labyrinth erstellen, (die ich erzeugen aus einer Eingabe-Datei). Dann habe ich den import zwei Modelle aus 3dstudio max mit einer obj-loader(glm). Und eines der Modelle(mo) wird die Bewegung um das Labyrinth. Also fügte ich eine bounding box um ihn herum und auch um die Mauern des Labyrinths . Ich habe auch gezeichnet das Feld rund um mo und es scheint sich zu bewegen/drehen Sie zusammen mit dem Charakter. Aber aus irgendeinem Grund (vielleicht, ich mache das nicht an der richtigen Stelle) Kollisionsprüfung nie erkennt nichts. Ich lasse den code für sich sprechen , und wenn Sie Fragen haben, ich werde froh sein, Sie zu begradigen.Vorbereiten der code jetzt.
//bounding boxes
struct BoundingBox
{
Vector3D max;
Vector3D min;
};
BoundingBox *box_mo;
BoundingBox *static_box[400];
void initbox(BoundingBox *b){
b->min.x=100000;
b->min.y=100000;
b->min.z=100000;
b->max.x=-100000;
b->max.y=-100000;
b->max.z=-100000;
}
BoundingBox *CreateCollisionBox(GLMmodel *model,GLMgroup *object){
/* GLM doesn't store each vertex together with the object that owns it. It doesn't have that notion. In GLM object don't have vertex, they have triangles. And each triangle is actually an index in the triangle list of the object.*/
BoundingBox *boxx=(BoundingBox*)malloc(sizeof(BoundingBox));
initbox(boxx);
for(int i=0;i<object->numtriangles;i++){
//for each vertex of the triangle pmodel1->triangles[object->triangles[i]]
//calculate min and max
for(int j=0;j<3;j++){
GLuint index=model->triangles[object->triangles[i]].vindices[j];
GLfloat x = model->vertices[index*3 +0];
GLfloat y = model->vertices[index*3 +1];
GLfloat z = model->vertices[index*3 +2];
if(boxx->min.x>x) boxx->min.x =x;
if(boxx->min.y>y) boxx->min.y =y;
if(boxx->min.z>z) boxx->min.z =z;
if(boxx->max.x<x) boxx->max.x =x;
if(boxx->max.y<y) boxx->max.y =y;
if(boxx->max.z<z) boxx->max.z =z;
}
}
return boxx;
}
void AddCollisionBox(GLMmodel *model,GLMgroup *object){
//box[boxindex]=CreateCollisionBox(model,object);
box_mo=CreateCollisionBox(model,object);
//boxindex++;
}
//A GLMmodel has a chained list of groups, each group representing an object.
//Each object has a name (the name you gave it in 3D Studio Max or Gmax).
//Let's you have 10 walls in your scene a few other objects as well and you want to
//create collision boxes just for the walls and you do not want to make a collision box
//for one of your objects. You could name all your walls
//like this: Wall1, Wall2, ..., Wall10. If you wanted to add collision boxes just to them
//you could go through all objects in the scene and if their name contains "Wall" add them.
//with this one: strstr
//Basicly this function does just that: if you want to add boxes for the walls you would call it like this: DefineCollisionBoxes(model,"Wall");
void DefineCollisionBoxes(GLMmodel *model,char *name){
GLMgroup *group = model->groups;
while(group){
if(strstr(group->name,name))
AddCollisionBox(model,group);
group=group->next;
}
}
bool Collision(BoundingBox *b,GLfloat x,GLfloat y,GLfloat z){
return x <= b->max.x && x>= b->min.x && y<= b->max.y && y>= b->min.y && z<= b->max.z && z >= b->min.z;
}
bool CollisionTest(BoundingBox *a,BoundingBox *b){
/*bool collision=false;
for(int i=0;i<static_boxes;i++){
for(float x=static_box[i]->min.x, y=static_box[i]->min.y,z=static_box[i]->min.z ;x<=static_box[i]->max.x && y<=static_box[i]->max.y && z<=static_box[i]->max.z;x+=0.1,y+=0.1,z+=0.1){
if(Collision(a,x,y,z) == true)
collision=true;
}
}
return collision;*/
if(a->min.x <= b->max.x && a->max.x >= b->min.x && a->min.z <= b->max.z && a->max.z >= b->min.z && a->min.y <= b->max.y && a->max.y >= b->min.y)
return true;
return false;
}
void drawBox(BoundingBox *b){
glColor3f(1,1,1);
glBegin(GL_LINE_LOOP);
glVertex3f(b->max.x,b->max.y,b->min.z);
glVertex3f(b->min.x,b->max.y,b->min.z);
glVertex3f(b->min.x,b->min.y,b->min.z);
glVertex3f(b->max.x,b->min.y,b->min.z);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(b->max.x,b->min.y,b->max.z);
glVertex3f(b->max.x,b->max.y,b->max.z);
glVertex3f(b->min.x,b->max.y,b->max.z);
glVertex3f(b->min.x,b->min.y,b->max.z);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(b->max.x,b->max.y,b->min.z);
glVertex3f(b->max.x,b->max.y,b->max.z);
glVertex3f(b->min.x,b->max.y,b->max.z);
glVertex3f(b->min.x,b->max.y,b->min.z);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(b->max.x,b->min.y,b->max.z);
glVertex3f(b->min.x,b->min.y,b->max.z);
glVertex3f(b->min.x,b->min.y,b->min.z);
glVertex3f(b->max.x,b->min.y,b->min.z);
glEnd();
}
//display function
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//setup view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.render
//read from file, create walls and characters
//place model mo in front of the third person camera always
Vector3D positionn;
positionn = camera.position + camera.forward*5;
glPushMatrix();
glColor3f(0.88f,0.75f,0.49f);
//here i move my character and calculate bounding box at each frame for him
glTranslatef(positionn.x,-0.42f,positionn.z);
glScalef(0.7f,0.7f,0.7f);
glRotatef(angle,0,1,0);
drawMo();
DefineCollisionBoxes(pmodel1,"body"); //actual function call
drawBox(box_mo); //draw bounding box
glPopMatrix();
//test if the character collides with any of the walls - not working
for(int i=0;i<static_boxes;i++){
if(CollisionTest(box_mo,static_box[i]) == true){
printf("collision");
}
}
//swap buffers
glutSwapBuffers();
}
I will let the code do the talking
Dies ist nicht, wie Stack Overflow funktioniert, was ist die eigentliche praktische problem, das Sie erleben?Auch habe ich schon gesagt, das problem ist, dass CollisionTest nie true zurück, d.h. die Erkennung nicht funktioniert. Ich zeichne die Felder für jedes Objekt, und Sie scheinen alle zu sein, funktioniert ganz gut so, die wirklich Blättern Sie mir mit keine Ahnung, was stimmt. Wenn ich zeichne, einer der Kollisions-Boxen und es dreht sich und bewegt sich zusammen mit dem Charakter, heißt das nicht, daß die Struktur (das Prinzip) ist in Ordnung ? Warum also nicht Kollision-test ab ?
Könnte man den code verkürzen, so dass wir nicht haben, waten durch es alle und herauszufinden, welche Teile sind wichtig?
Ok, ich re-edited meinem post, hielt ich die Funktionen für die Erstellung von bounding-box, wenn Sie möchten, um Sie zu betrachten. Das Hauptanliegen ist die display-Funktion, wenn ich versuche zu sehen, ob die Objekte kollidieren, die printf () - Nachricht noch nie zeigt sich auch, wenn ich fliege herum durch alle Wände
Es Aussehen, als ob Sie die Prüfung, wenn ein Feld innerhalb einer box (Sie haben nur && Nein ||) scheint es mir so, dass, wenn die gesamte box enthalten ist, erhalten Sie immer den falschen
InformationsquelleAutor user1272703 | 2012-11-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich werde versuchen, geben einen überblick, wie löst man das collision-problem. Einfachheit halber mache ich die folgenden Annahmen:
Wenn wir diese Annahmen, die wir vertreten können jede Wand mit einem Rechteck in 3d. Und da sind wir davon ausgegangen das Labyrinth ist weder gedreht noch skaliert, können wir tun es einmal und speichern Sie in einem array oder ein B-Baum oder was auch immer. (Beachten Sie, dass die Wahl der richtigen Datenstruktur zum speichern Ihrer Welt, für Berechnungen kann die Leistungsfähigkeit deutlich steigern)
Den Charakter bewegt sich durch das Labyrinth und wir nahmen an, dass es sein kann gedreht und skaliert. Der einfachste Weg, um zu entscheiden, ob der Charakter kollidiert mit irgendetwas, ist die Berechnung der bounding-sphere des Objektes. Sobald Sie haben, Sie können zum Wohle der Kollisionserkennung store nur zwei Punkte. Der Mittelpunkt der Kugel und jedem beliebigen Punkt auf der Kugel.
Einmal die Zeichen an der richtigen position in das Labyrinth, die Sie anwenden, die genau die gleiche transformation auf die zwei genannten Punkte. Entweder Ihr macht dies mit der matrix-Bibliothek oder Sie können die Abfrage der MODELVIEW-matrix nach der Transformation des Charakters. Sie können dies tun, durch aufrufen von 'glGetFloatv` wie dieser:
Sobald Sie verwandelt die zwei Punkte, die Sie kann finden Sie die Entfernung zwischen Ihnen - dies wird die Entfernung zu einem Objekt zu werden, Weg von den transformierten Mittelpunkt, eine Kollision zu vermeiden.
Nun das Letzte, was zu tun ist, gehen über die einschlägigen Flugzeuge und überprüfen Sie Punkt-zu-Ebene Abstand mit den transformierten Mittelpunkt und die berechnete Entfernung. Sie müssen dann sicherstellen, dass die projizierte Zentrum zu, das Flugzeug fällt in den rectange.
Und hier ist eine Gliederung des Programms (Keine echten code hier nur Kommentare und Funktion Abstraktionen)
Ich hoffe, das bringt Sie auf den richtigen Weg
InformationsquelleAutor Sebastian Cabot