Я делаю простой проект, который визуализирует движение объекта Box2D с помощью OpenGL. (Я новичок в обоих из них.)
Мое намерение состоит в том, чтобы переместить шар со значением восстановления 1 (он подпрыгивает повторно и им можно управлять с клавиатуры), в мире статических объектов, который состоит изребер и ящиков.
Я создал класс Box, Edge, Circle, чтобы мне было проще определять и управлять ими.
Например, это мой класс Circle:
class Circle {
private:
b2Body* body;
b2BodyDef body_def;
b2CircleShape shape;
b2FixtureDef fixture;
public:
Circle() {
body_def.type = b2_staticBody;
body = nullptr;
shape.m_p.Set(0, 0);
shape.m_radius = 0;
fixture.shape = &shape;
fixture.density = 0.0f;
fixture.friction = 0.2f;
fixture.restitution = 0.0f;
}
Circle(b2World* WORLD, float32 positionX, float32 positionY, float32 centerX, float32 centerY, float32 radius, float32 density, float32 friction, float32 restitution, int mode) {
// Initialize type
switch (mode) {
case 0:
body_def.type = b2_staticBody;
break;
case 1:
body_def.type = b2_dynamicBody;
break;
case 2:
body_def.type = b2_kinematicBody;
break;
default:
body_def.type = b2_staticBody;
}
// Initialize positionXY
body_def.position.Set(positionX, positionY);
// Creating Body
body = WORLD->CreateBody(&body_def);
// Initializing Shape
shape.m_p.Set(centerX, centerY);
shape.m_radius = radius;
// Initializing Fixture
fixture.shape = &shape;
fixture.density = density;
fixture.friction = friction;
fixture.restitution = restitution;
body->CreateFixture(&fixture);
}
void setPosition(float32 positionX, float32 positionY) {
body_def.position.Set(positionX, positionY);
}
void setType(int mode) {
switch (mode) {
case 0:
body_def.type = b2_staticBody;
break;
case 1:
body_def.type = b2_dynamicBody;
break;
case 2:
body_def.type = b2_kinematicBody;
break;
default:
body_def.type = b2_staticBody;
}
}
void setSize(float32 radius) {
shape.m_radius = radius;
}
void setDensity(float32 density) {
fixture.density = density;
body->CreateFixture(&fixture);
}
void setFriction(float32 friction) {
fixture.friction = friction;
body->CreateFixture(&fixture);
}
void setRestitution(float32 restitution) {
fixture.restitution = restitution;
body->CreateFixture(&fixture);
}
b2Body* getInf() {
return body;
}
b2CircleShape getShape() {
return shape;
}
};
И мой drawCircle(Circle* circle, float32 red, float32 blue, float32 green)
ниже:
void drawCircle(Circle* circle, float32 red, float32 blue, float32 green) {
b2Vec2 pos = circle->getInf()->GetPosition();
float32 ang_rad = circle->getInf()->GetAngle();
glPushMatrix();
glTranslatef(pos.x, pos.y, 0.0f);
glRotatef(ang_rad * RADTODEG, 0.0f, 0.0f, 1.0f);
glColor3f(red, blue, green);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(pos.x, pos.y);
float x2, y2;
for (float angle = 1.0f; angle < 361; angle += 0.1f) {
x2 = pos.x + cos(angle * 3.1416 / 180) * circle->getShape().m_radius;
y2 = pos.y + sin(angle * 3.1416 / 180) * circle->getShape().m_radius;
glVertex2f(x2, y2);
}
glEnd();
glPopMatrix();
}
Я тоже сделал drawBox
, drawEdge
, но скелет такой же, как у drawCircle
.
И мойRender()
Функция как ниже: (Извините, я так плохо знаком с OpenGL, и мой код выглядит как мусор ... Но я потратил почти 20 часов, чтобы достичь этой точки ..)
void Render() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawEdge(FRAME_BOTTOM, 10.0f, 1.0, 0.5, 0.0);
glLoadIdentity();
drawEdge(FRAME_TOP, 10.0f, 1.0, 0.5, 0.0);
glLoadIdentity();
drawEdge(FRAME_LEFT, 10.0f, 1.0, 0.5, 0.0);
glLoadIdentity();
drawEdge(FRAME_RIGHT, 10.0f, 1.0, 0.5, 0.0);
glLoadIdentity();
drawEdge(VLINE1, 1.0f, 1.0, 0.0, 0.0);
glLoadIdentity();
drawEdge(VLINE2, 1.0f, 1.0, 0.0, 0.0);
glLoadIdentity();
drawEdge(VLINE3, 1.0f, 1.0, 0.0, 0.0);
glLoadIdentity();
drawEdge(VLINE4, 1.0f, 1.0, 0.0, 0.0);
glLoadIdentity();
drawBox(MAP01_A, 1.0f, 0.5f, 0.0f);
glLoadIdentity();
drawBox(MAP01_B, 1.0f, 0.5f, 0.0f);
glLoadIdentity();
drawBox(MAP01_C, 1.0f, 0.5f, 0.0f);
glLoadIdentity();
drawBox(MAP01_D, 1.0f, 0.5f, 0.0f);
glLoadIdentity();
drawCircle(CIRCLE, 1.0f, 1.0f, 1.0f);
glutSwapBuffers();
}
В результате, если я перемещаю свой шар в направлении x или -x с помощью метода ApplyForce
, он перемещается, но его движение искажается и не сталкивается с моими ребрами и прямоугольниками. А несколько раз спустя его искаженное движение становится еще хуже, когда мяч пролетает через края и коробки, как будто он имеет свободную волю ...
Это проблема
Мне кажется, что проблема, возможно, из-за разницы в единицах между openGL и Box2d, или из-за какого-то материала glTranslationf
, glRotatef
, но я не могу получить общую картину их и какое ключевое слово дляпоиск.