子弹车轮落后,错误的底盘俯仰方向

时间:2013-11-25 10:04:19

标签: c++ opengl game-physics gravity bullet

我已经创建了一个带有附加炮塔的子弹车,如下所示:

    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;

摄像机安装在汽车顶部的炮塔上,因此安装在汽车上。

问题在于,当汽车开始移动并且速度加快时,车轮似乎落后并且底盘向前移动。我想让车轮和底盘更加紧凑,但玩车悬挂设置并没有帮助。

以下是展示此行为的视频:click

我还注意到另一种奇怪的行为,与汽车在移动,折断和转弯时的投球方式有关。

增加重力会突出这种行为。当我加速时,底盘向前倾斜,当我刹车时它向后倾斜。这显然是错误的,因为它应该是相反的方式。左转时也是如此,汽车向左而不是向右倾斜,反之亦然。

以下是另一个展示此行为的视频:click

1 个答案:

答案 0 :(得分:0)

我有这种问题。事实证明,车轮是使用转换而不是与底盘相同的框架来渲染的。即,从机架n-1开始,机箱使用帧n。

事情并不明显,因为轮网格是底盘节点的子节点,因为它是我在渲染引擎中实现的方式,而在子弹物理中,轮坐标是全局的,就像底盘一样。 但事实并非如此,当从全球到本地车辆空间转换车轮坐标时,精确度损失仍然会造成问题。它是通过将轮网格作为全局节点来修复的。