Колеса бронетранспортера отстают, а направление тангажа шасси неправильное.

Я создал бронетранспортер с прикрепленной к нему башней вот так:

    gEngineForce = 0.f;
    gBreakingFrontForce = 0.f;
    gBreakingBackForce = 0.f;

    maxEngineForce = 20000.f;
    minEngineForce = -2000.f;
    maxBreakingFrontForce = 4000.f;
    maxBreakingBackForce = 600.f;

    gVehicleSteering = 0.f;
    steeringIncrement = 0.002f;
    steeringClamp = 0.6f;
    wheelRadius = 0.5f;
    wheelWidth = 0.4f;
    wheelFriction = 50;
    suspensionStiffness = 10.f;
    suspensionDamping = 1.3f;
    suspensionCompression = 4.4f;
    rollInfluence = 0.1f;//1.0f

    btScalar suspensionRestLength(0.6);
    btVector3 wheelDirectionCS0(0, -1, 0);
    btVector3 wheelAxleCS(-1, 0, 0);




    btTransform tr;
    tr.setIdentity();

    chassisShape = new btBoxShape(btVector3(1.f, 0.5f, 2.f));
    bulletCollisionShapes.push_back(chassisShape);

    compound = new btCompoundShape();
    bulletCollisionShapes.push_back(compound);

    btTransform chassisTrans;
    chassisTrans.setIdentity();
    //localTrans effectively shifts the center of mass with respect to the chassis
    chassisTrans.setOrigin(btVector3(0, 1.3, 0));
    compound->addChildShape(chassisTrans, chassisShape);

    tr.setOrigin(btVector3(0, 0.f, 0));
    //m_carChassis = CreateRigidBody(2000, tr, compound);
    //m_carChassis->setDamping(0.2,0.2);
    m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth, wheelRadius, wheelRadius));

    m_carChassis = CreateRigidBody(2000, tr, compound);


    // create turret
    turretShape = new btBoxShape(btVector3(0.4f, 0.2f, 0.8f));
    bulletCollisionShapes.push_back(turretShape);
    btTransform turretTrans;
    turretTrans.setIdentity();
    turretTrans.setOrigin(btVector3(0.0f, 0.7f, 0.0f));
    turretBody = CreateRigidBody(1, turretTrans, turretShape);

    // add some data to build constraint frames
    btVector3 axisA(0.f, 1.f, 0.f);
    btVector3 axisB(0.f, 0.f, 0.f);
    btVector3 pivotA(0.f, 1.f, 0.f);
    btVector3 pivotB(0.f, 0.f, 0.f);
    hinge = new btHingeConstraint(*m_carChassis, *turretBody, pivotA, pivotB, axisA, axisB);
    //hinge->setLimit(-SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
    hinge->enableAngularMotor(true, 0, 1);

    // add constraint to world
    bt_dynamicsWorld->addConstraint(hinge, true);

    {
        btTransform something;
        something.setIdentity();
        something.setOrigin(btVector3(0, 10, 0));
        m_carChassis->setWorldTransform(something);

        m_vehicleRayCaster = new btDefaultVehicleRaycaster(bt_dynamicsWorld);
        m_vehicle = new btRaycastVehicle(m_tuning, m_carChassis, m_vehicleRayCaster);

        m_carChassis->setActivationState(DISABLE_DEACTIVATION);

        bt_dynamicsWorld->addVehicle(m_vehicle);

        float connectionHeight = 1.2f;


        //choose coordinate system
        m_vehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex);

        bool isFrontWheel = true;
        btVector3 connectionPointCS0(1 - (-0.8*wheelWidth), connectionHeight, 3 * 1 - wheelRadius);
        m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);

        connectionPointCS0 = btVector3(-1 + (-0.8*wheelWidth), connectionHeight, 3 * 1 - wheelRadius);
        m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);

        isFrontWheel = false;
        connectionPointCS0 = btVector3(-1 + (-0.8*wheelWidth), connectionHeight, -3 * 1 + wheelRadius);
        m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);

        connectionPointCS0 = btVector3(1 - (-0.8*wheelWidth), connectionHeight, -3 * 1 + wheelRadius);
        m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);

        for (int i = 0; i < m_vehicle->getNumWheels(); i++)
        {
            btWheelInfo& wheel = m_vehicle->getWheelInfo(i);
            wheel.m_suspensionStiffness = suspensionStiffness;
            wheel.m_wheelsDampingRelaxation = suspensionDamping;
            wheel.m_wheelsDampingCompression = suspensionCompression;
            wheel.m_frictionSlip = wheelFriction;
            wheel.m_rollInfluence = rollInfluence;
        }
    }

    int wheelIndex = 2;
    m_vehicle->applyEngineForce(gEngineForce, wheelIndex);
    m_vehicle->setBrake(gBreakingBackForce, wheelIndex);
    wheelIndex = 3;
    m_vehicle->applyEngineForce(gEngineForce, wheelIndex);
    m_vehicle->setBrake(gBreakingBackForce, wheelIndex);

    wheelIndex = 0;
    m_vehicle->setSteeringValue(gVehicleSteering, wheelIndex);
    m_vehicle->setBrake(gBreakingFrontForce, wheelIndex);
    wheelIndex = 1;
    m_vehicle->setSteeringValue(gVehicleSteering, wheelIndex);
    m_vehicle->setBrake(gBreakingFrontForce, wheelIndex);

Вот как я визуализирую автомобиль:

   // render wheels
   btScalar mwheel[16];
   for (int i = 0; i<m_vehicle->getNumWheels(); i++){
      //synchronize the wheels with the (interpolated) chassis worldtransform
      m_vehicle->updateWheelTransform(i, true);
      //draw wheels
      m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(mwheel);
      RenderWheel(m_wheelShape, mwheel);
   }


   // render car chassis
   btScalar mchassis[16];
   m_vehicle->getChassisWorldTransform().getOpenGLMatrix(mchassis);
   RenderBox(chassisShape, mchassis);


   // render turret
   btScalar mturret[16];
   // get chassis and turret transforms
   btTransform chassisTransform = m_vehicle->getChassisWorldTransform();
   //btTransform turretTransform = compound->getChildTransform(1);
   btTransform turretTransform = turretBody->getWorldTransform();
   // multiply transforms to get updated turret transform
   //turretTransform *= chassisTransform;
   turretTransform.getOpenGLMatrix(mturret);
   RenderBox(turretShape, mturret);

С помощью клавиш со стрелками я применяю силы торможения или ускорения следующим образом:

  bullet.gEngineForce = bullet.maxEngineForce;
  bullet.gBreakingFrontForce = 0.f;
  bullet.gBreakingBackForce = 0.f;

и т.п.

Камера прикреплена к башне сверху машины, поэтому прикреплена к самой машине.

Проблема в том, что когда машина начинает двигаться и набирает скорость, кажется, что колеса отстают, а шасси уходит вперед. Хотелось сделать колеса и шасси пожестче, но игра с настройками подвески не помогла.

Вот видео, демонстрирующее такое поведение: нажмите

Я также заметил еще одно странное поведение, связанное с тем, как автомобиль качается при движении, торможении и повороте.

Увеличение гравитации усиливает это поведение. при разгоне шасси кренится вперед, при торможении назад. Это явно неправильно, так как должно быть наоборот. То же самое происходит при повороте налево, машину кидает влево, а не вправо, и наоборот.

Вот еще одно видео, демонстрирующее такое поведение: нажмите


person bogdan.css    schedule 25.11.2013    source источник
comment
Вам удалось решить проблему?   -  person Gediminas    schedule 07.12.2019


Ответы (1)


у меня была такая проблема. оказалось, что колеса были отрендерены с помощью трансформации не из той же рамы, что и шасси. т. е. от рамы n-1, в то время как шасси использовало раму n.

вещи не были очевидны, потому что сетки колес были дочерними узлами узла шасси, как это было реализовано мной в движке рендеринга, в то время как в физике пули координаты колес глобальны, как и шасси. но это еще не все, при преобразовании координат колеса из глобального в локальное пространство транспортного средства произошла потеря точности, которая по-прежнему вызывала проблемы. это было исправлено путем создания сетки колес в качестве глобальных узлов.

person MaxLZ    schedule 01.05.2014