У моего объекта моделирования Box2D с использованием openGL есть странное движение - PullRequest
0 голосов
/ 08 октября 2019

Я делаю простой проект, который визуализирует движение объекта 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, но я не могу получить общую картину их и какое ключевое слово дляпоиск.

...