Simple pivot joint

Post Reply
holdnothing
Posts: 1
Joined: Sat Jun 23, 2012 2:33 am

Simple pivot joint

Post by holdnothing » Sat Jun 23, 2012 2:59 am

Ok, I've read the pdf manual, looked at the forklift and vehicle demos (both use raycast and doesn't seem right fit for me here), and tried every type of hinge I can come up with to get this working. None of my attempts work.

I'm trying to simulate a tank. I've got a basic box, then 6 cylinders as wheels, three for each side. I only want the wheels to rotate around the Z axis and but be fixed to the center box. To turn the object, all the wheels on one side will rotate +Z and the other side will use -Z.

Problem 1) Some versions appear to lock the center box from any rotation, others the center box works but the wheels don't follow center box rotation
Problem 2) For some reason I can only turn the wheels manually calling setAngularVelocity(), insead of applyTorque().

Here is an example of the shape I'm trying.
Image

And here is the code I've got, please tell me where I'm going wrong. Either my entire object doesn't rotate on Y axis, or the center box does but the wheels stay locked to Y axis.

Bullet version 2.80-rev2531

Code: Select all

    btCollisionShape *pShape = 0;
    btMotionState* pState = 0;
    btRigidBody*   pBody = 0;
    btScalar mass = 200;
 
    pShape = new btBoxShape(btVector3(50,10,32));
 
    btTransform localTrans;
    localTrans.setIdentity();
    localTrans.setOrigin( cvt(getPosition()) );
 
    pState = new btDefaultMotionState(localTrans);
 
    btVector3 inertia (0,0,0);
    // Important, do not remove this or object won't rotate!
    pShape->calculateLocalInertia(mass, inertia);
 
    //Create the rigid body
    pBody = new btRigidBody(mass, pState, pShape, inertia);
 
    // Don't deativate when movement done
    pBody->forceActivationState(DISABLE_DEACTIVATION);
 
    // add the body to the physics world
    mpBtWorld->addRigidBody(pBody);
    mpBodies[TANK_HULL] = pBody;
 
    //////// Wheels /////////////
    btScalar mass = 50;
    btVector3 interia(0,0,0);
    btVector3 startPos = cvt(getPosition() + Vector3(0,10,0));
    btVector3 endPos (0,0,0);
    btRigidBody* pBody = 0;
 
    int x,z;
    int xOffset = 36;  // spacing between wheels
 
    // create 6 wheels
    for (int i = 0; i < 6; i++)
    {
        if (i < 3)
            z = -38;
        else
            z = 38;
 
        if (i < 3)
            x = i * xOffset;
        else
            x = (i - 3) * xOffset;
        endPos = startPos + btVector3(x - xOffset, -20, z);
        localTrans.setIdentity();
        localTrans.setOrigin(endPos);
                                                         // width, radius, radius
        btCollisionShape* pShape = new btCylinderShapeZ(btVector3(12, 5, 5));
        mpShapes[TANK_WHEEL_1 + i] = pShape;
 
        pShape->calculateLocalInertia(mass, interia);
        btDefaultMotionState* state = new btDefaultMotionState(localTrans);
 
        pBody = new btRigidBody(mass, state, pShape);
        mpBodies[TANK_WHEEL_1 + i] = pBody;
 
        pBody->forceActivationState(DISABLE_DEACTIVATION);
 
       // add wheel to world
        mpBtWorld->addRigidBody(pBody);
 
        // add joint
/*
/////////// another attempt /////////////////////
        btGeneric6DofSpringConstraint* pJoint = 0;

        // this joint causes an explosion 
        pJoint = new btGeneric6DofSpringConstraint(*mpBodies[TANK_HULL],
                                       *pBody,
                                       hullTrans,
                                       localTrans,
                                       false);
      
////////////// another attempt ///////////////////
        btHingeConstraint* pJoint = 0;
 
        btVector3 axis1 (0,1,0); // Y
        btVector3 axis2;
 
        if (i < 3)
            axis2 = btVector3(0,0,1); // Z
        else
            axis2 = btVector3(0,0,-1); // Z
 
        pJoint = new btHingeConstraint(*mpBodies[TANK_HULL],
                                       *pBody,
                                       endPos,          // pivotInA
                                       endPos + axis2,  // pivotInB
                                       axis1,           // axisInA
                                       axis2,           // axisInB
                                       true);
*/ //////////// best match so far /////////////////////
        btHinge2Constraint* pJoint = 0;
 
        btVector3 axis1 (0,1,0); // Y
        btVector3 axis2;
 
        if (i < 3)
            axis2 = btVector3(0,0,1); // Z
        else
            axis2 = btVector3(0,0,-1); // Z
 
        pJoint = new btHinge2Constraint(*mpBodies[TANK_HULL],
                                       *pBody,
                                       endPos,
                                       axis1,
                                       axis2);
 
        pJoint->setAngularLowerLimit(btVector3(1,-1, 1));
        pJoint->setAngularUpperLimit(btVector3(0, 1, 0));
        pJoint->setDbgDrawSize(btScalar(25.0f));
 
        mpBtWorld->addConstraint(pJoint, true);
        mpJoints[TANK_WHEEL_1 + i] = pJoint;
 
    }
Days of trying different things is getting me nowhere. Hopefully someone can help. :)

Post Reply