我创建了一辆子弹车,其顶部装有一个炮塔,如下所示:

    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

最佳答案

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

因为车轮网格是底盘节点的子节点,所以并不是很明显,因为这是我在渲染引擎中实现的,而在子弹物理学中,车轮坐标是全局的,底盘也是如此。
但这还不是全部,当将车轮坐标从全局空间转换为本地车辆空间时,仍然存在精度损失,这仍然会引起问题。它通过将车轮网格作为全局节点来修复。

07-24 14:31