Я пытаюсь сделать танковую игру. Я успешно загрузил модель OBJ и вычислил ее ограничивающую рамку для модели в начале координат.
Сейчас я пытаюсь применить преобразования, сделанные к моей модели в игровой логике, к исходным координатам ограничительной рамки. Для этого я беру матрицу вида модели прямо перед рисованием моей модели, а затем умножаю эту матрицу на два вектора, которые определяют BBox.
Вот код, который рисует мой танк:
void drawTank()
{
bBox = calcBBox(modelo, 1);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texTank);
glScalef(0.2, 0.2, 0.2);
glTranslatef(posTank.x,posTank.y,posTank.z);
glRotatef(anguloTanque, 0, 1, 0); // rotate around Y (horizontal)glRotatef(90, 0, 1, 0);
glRotatef(-90, 1, 0, 0);
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glmDraw(modelo, GLM_TEXTURE | GLM_MATERIAL);glColor3f(1,0,0);
drawBBox(bBox);
glPopMatrix();}
С помощью этого фрагмента мой bbox правильно рисуется поверх модели танка (преобразования выполняются при рендеринге glTranslate & функции glRotate). Как вы можете видеть, я также взял свою матрицу ModelView.
Затем я применяю эту матрицу следующим образом (это вся моя функция отображения):
void Display(void) {// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();glPushMatrix();
camera();
glEnable(GL_TEXTURE_2D);
//glTranslatef(0,-40,150);
//PLANE
glBindTexture(GL_TEXTURE_2D, texArena);
glBegin(GL_POLYGON);
glTexCoord2f( 0.0f, 0.0f );
glVertex3f(-500, 0, -500);
glTexCoord2f( 5.0f, 5.0f );
glVertex3f(500, 0, -500);
glTexCoord2f(5.0f, 0.0f );
glVertex3f(500, 0, 500);
glTexCoord2f( 0.0f, 5.0f );
glVertex3f(-500, 0, 500);
glEnd();drawTank();
glPopMatrix();point3D max = bBox.max;
point3D min = bBox.min;
point3D resultMax;
point3D resultMin;
//Transformacion
multVectorByMatrix(matrix, max, resultMax);
multVectorByMatrix(matrix, min, resultMin);
bBox.max.x = resultMax.x; bBox.max.y = resultMax.y; bBox.max.z = resultMax.z;
bBox.min.x = resultMin.x; bBox.min.y = resultMin.y; bBox.min.z = resultMin.z;
glPushMatrix();
glColor3f(1,1,1);
drawBBox(bBox);
glPopMatrix();glFlush();
glutSwapBuffers();
}
Функция, которая умножает вектор на матрицу:
void multVectorByMatrix(float* matrix, point3D vector, point3D &result)
{
result.x = (matrix[0] * vector.x) +
(matrix[4] * vector.y) +
(matrix[8] * vector.z) +
matrix[12];
result.y = (matrix[1] * vector.x) +
(matrix[5] * vector.y) +
(matrix[9] * vector.z) +
matrix[13];
result.z = (matrix[2] * vector.x) +
(matrix[6] * vector.y) +
(matrix[10] * vector.z) +
matrix[14];
}
Если я рисую ограничивающий прямоугольник с помощью этого цикла рендеринга, то мой ограничивающий прямоугольник рисуется, но преобразования не применяются должным образом. Я вижу, как ограничивающая рамка перемещается правильно с переводами, но вращения не выполняются правильно.
В чем может быть проблема здесь?
редактировать: некоторые скриншоты
Ваша проблема в этом коде.
point3D max = bBox.max;
point3D min = bBox.min;
point3D resultMax;
point3D resultMin;
//Transformacion
multVectorByMatrix(matrix, max, resultMax);
multVectorByMatrix(matrix, min, resultMin);
bBox.max.x = resultMax.x; bBox.max.y = resultMax.y; bBox.max.z = resultMax.z;
bBox.min.x = resultMin.x; bBox.min.y = resultMin.y; bBox.min.z = resultMin.z;
glPushMatrix();
glColor3f(1,1,1);
drawBBox(bBox);
glPopMatrix();
Вы берете две вершины из своего блока и затем применяете к ним преобразования, а затем используете эти преобразованные вершины, чтобы отобразить блок, который, конечно, будет выровнен по оси, потому что это единственный блок, который вы можете получить только из двух противоположных вершин. И вы можете видеть на своем скриншоте, что у вашего bbox и правильного bbox есть общие вершины — это именно те вершины, к которым вы применили свои преобразования. Таким образом, чтобы получить правильный bbox, вам нужно получить все вершины bbox и применить эти преобразования ко всем из них. Тогда вы получите именно то, что вы хотите.
Других решений пока нет …