3

I have created a bullet vehicle with a attached turret at the top like this:

    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);

This is how I render the vehicle:

   // 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);

Using the arrow keys I apply break or acceleration forces like this:

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

etc.

The camera is attached to the turret on top of the car, therefore attached to the car itself.

The issue is that when the car starts moving and as it gain speed, the wheels seem to fall behind and the chassis going forward. I would like make the wheels and the chassis more tight, but playing around with the car suspension settings did not help.

Here is a video demonstrating this behaviour: click

I have also noticed another strange behaviour related to the way the car pitches when moving, breaking and turning.

Increasing the gravity accentuates this behaviour. when I accelerate, the chassis pitches forward and when I brake it goes backwards. This is obviously wrong as it should be the other way around. Same happens when turning left, the car pitches left instead of right, and the other way around.

Here is another video demonstrating this behaviour: click

bogdan.css
  • 355
  • 6
  • 17

1 Answers1

0

i had this kind of problem. it turned out that wheels were rendered using transformation not from the same frame as chassis. i.e. from frame n-1 while chassis used frame n.

things werent apparent bcause wheel meshes were child nodes of chassis node, as it was how it was implemented by me in rendering engine, while in bullet physics, wheel coordinates are global, the same way chassis is. but that wasnt all, when converting wheel coords from global to local vehicle space, there was accuracy loss that, still caused problems. it was fixed by making wheel meshes as global nodes.

MaxLZ
  • 89
  • 1
  • 4