我装了直升机.obj文件,它可以用键(wasd)和(o-up)(l-down)移动。现在我想在移动时旋转螺旋桨,但不能这样做。 This is the link to .obj file.
感谢任何回答。
这是我的代码:
#include <stdlib.h>
#include <windows.h>
#include <GL/glut.h>
#include <stdio.h>
#include <cmath>
#include <GL/glut.h>
#include <GL/GL.H>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
float v[27982][3];
int f[25130][3];
int mX, mY;
int trX, trY, trZ;
GLfloat amblight[] = { 1.0, 0.0, 0.0, 0.0 };
GLfloat diflight[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat speclight[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat position[] = { 1.0, 0.0, 1.0 };
GLfloat difposition[] = { 1.0, 0.0, 1.0, 0.0 };
GLfloat shinines[] = { 120.0 };
GLfloat ambmatherial[] = { 1.0, 0.0, 0.0, 0.0 };
GLfloat difmatherial[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat specmatherial[] = { 1.0, 1.0, 1.0, 0.0 };
GLfloat angle = 0.0;
void init() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, difposition);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diflight);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, difmatherial);
glLightfv(GL_LIGHT0, GL_SPECULAR, speclight);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specmatherial);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shinines);
}
void idle() {
glutPostRedisplay();
}
class Coord
{
public:
float x;
float y;
float z;
} a3d, b3d, c3d, original;
Coord norm(Coord a3d, Coord b3d, Coord c3d)
{
Coord d3D_1, d3D_2, cross;
d3D_1.x = b3d.x - a3d.x;
d3D_1.y = b3d.y - a3d.y;
d3D_1.z = b3d.z - a3d.z;
d3D_2.x = c3d.x - b3d.x;
d3D_2.y = c3d.y - b3d.y;
d3D_2.z = c3d.z - b3d.z;
cross.x = d3D_1.y * d3D_2.z - d3D_1.z * d3D_2.y;
cross.y = d3D_1.z * d3D_2.x - d3D_1.x * d3D_2.z;
cross.z = d3D_1.x * d3D_2.y - d3D_1.y * d3D_2.x;
double l;
l = sqrt(cross.x * cross.x + cross.y * cross.y + cross.z * cross.z);
cross.x /= l;
cross.y /= l;
cross.z /= l;
return cross;
}
void drawHelicopter(){
glPushMatrix();
for (int i = 0; i<25130; i++){
glBegin(GL_TRIANGLES);
a3d.x = v[f[i][0]][0];
a3d.y = v[f[i][0]][1];
a3d.z = v[f[i][0]][2];
b3d.x = v[f[i][1]][0];
b3d.y = v[f[i][1]][1];
b3d.z = v[f[i][1]][2];
c3d.x = v[f[i][2]][0];
c3d.y = v[f[i][2]][1];
c3d.z = v[f[i][2]][2];
glVertex3f(a3d.x, a3d.y, a3d.z);
glVertex3f(b3d.x, b3d.y, b3d.z);
glVertex3f(c3d.x, c3d.y, c3d.z);
Coord response = norm(a3d, b3d, c3d);
glNormal3f(response.x, response.y, response.z);
glEnd();
}
glPopMatrix();
}
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 0);
glLoadIdentity();
glTranslatef(0, 0, -1500);
glRotatef(180.0, 0, 1, 0);
glTranslatef(trX, trY, trZ);
glRotatef(mX, 0, 1, 0);
glRotatef(mY, 1, 0, 0);
glScalef(1.0f, 1.0f, 1.0f);
drawHelicopter();
glutSwapBuffers();
}
void reshape(int w, int h){
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLdouble)w / (GLdouble)h, 1.0, 8000.0);
glMatrixMode(GL_MODELVIEW);
}
void keyPressed(unsigned char key, int x, int y) {
if (key == 'a'){ trX += 20; }
else if (key == 'd'){ trX -= 20; }
else if (key == 'w'){ trZ += 20; }
else if (key == 's'){ trZ -= 20; }
else if (key == 'o'){ trY += 20; }
else if (key == 'l'){ trY -= 20; }
glutPostRedisplay();
}
void mouse(int x, int y){
mX = x;
mY = y;
glutPostRedisplay();
}
int main(){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(0, 0);
glutInitWindowSize(1200, 640);
glutCreateWindow("Helicopter");
glClearColor(0.0, 0.0, 0.0, 0.0);
int k = 0, m = 0;
char ch;
float aa, bb, cc;
ifstream in("havoc.obj", ios::in);
string line;
while (getline(in, line))
{
//check v for vertices
if (line.substr(0, 2) == "v ")
{
istringstream vert(line.substr(2));
vert >> aa;
vert >> bb;
vert >> cc;
v[k][0] = (float)aa;
v[k][1] = (float)bb;
v[k][2] = (float)cc;
k++;
}
else if (line.substr(0, 2) == "f ")
{
int a, b, c, d; //to store mesh index
int A, B, C, D; //to store texture index
int a1, b1, c1;
const char* chh = line.c_str();
sscanf(chh, "f %i/%i/%i %i/%i/%i %i/%i/%i", &a, &A, &a1, &b, &B, &b1, &c, &C, &c1); //here it read the line start with f and store the corresponding values in the variables
f[m][0] = a - 1;
f[m][1] = b - 1;
f[m][2] = c - 1;
m++;
}
}
printf("Use 'w'/'s' keys to move forward/downward\n");
printf("Use 'a'/'d' keys to move to the left/right\n");
printf("Use 'o'/'l' keys to move up/down\n");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyPressed);
glutMotionFunc(mouse);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
答案 0 :(得分:2)
所以你遇到的问题是一个常见的问题,我确信许多人在某些时候都会看到3D图形和动画。您有一个模型,您正在使用您的obj文件加载,但您只想旋转直升机的螺旋桨。因此,只要我读到这一点,我就会想到一些东西,分别加载几何体,并将几何体放入树形结构中。
因此,想象一下您的直升机的不同组件作为树的不同节点,例如,我们就说我们有一个人。躯干将是根节点,孩子将是手臂,腿和颈部,并且每个节点儿童将逐渐向下移动直到所有点都被存储。
现在一架直升机要简单得多,因为这时只有一架螺旋桨和直升机的架子。您可以实现这样的树结构,因为如果您想要移动到更复杂的动画和更复杂的对象,它将会很方便。
每个树节点都将包含该节点的当前属性,这也有助于解决其他一些问题,但我们很快就会解决这个问题。因此,对于每个节点,您将在节点模型空间中存储旋转和平移。然后,您将在树中传播这些值。因此,如果您的整个模型旋转,您的根节点将旋转并沿树向下传播其旋转,以便螺旋桨与直升机的主体一起旋转,并且还执行属于其节点的自己的旋转。同样的原则适用于翻译,只记得正确的订购,否则你会发现你的轮换问题不正确。
最后,问题的最终解决方案是将您的实际模型几何体分成3D建模程序中的不同对象,并将它们作为代码中的不同对象加载,它们仍将被编译到同一个obj文件中。然后,您可以使用此信息来构建对象树。
我真的希望这有助于你提供某种方向。 =)