void CylindricalBirefringentMaterial::rotationAxis( arma::vec &axis)
{
  // If there is some kind of cylindrical symmetry, two of the principal
  // inertia should be equal.
  double I12 = principalInertia(0)-principalInertia(1);
  double I13 = principalInertia(0)-principalInertia(2);
  double I23 = principalInertia(1)-principalInertia(2);

  if (( abs(I12) < abs(I13) ) && ( abs(I12) < abs(I23) ))
  {
    // 1 and 2 is most similar
    axis = principalAxes.col(2);
    princAxis = 2;
  }
  else if (( abs(I13) < abs(I12) ) && ( abs(I13) < abs(I23) ))
  {
    // 1 and 3 is most similar
    axis = principalAxes.col(1);
    princAxis = 1;
  }
  else
  {
    // 2 and 3 is most similar
    axis = principalAxes.col(0);
    princAxis = 0;
  }
}
Esempio n. 2
0
bool csBulletRigidBody::AddBulletObject ()
{
  // TODO: don't recompute everything if the internal scale hasn't changed

  if (insideWorld)
    RemoveBulletObject ();

  btVector3 localInertia (0.0f, 0.0f, 0.0f);
  float mass = GetMass ();

  btCollisionShape* shape;
  btTransform principalAxis;
  principalAxis.setIdentity ();
  btVector3 principalInertia(0,0,0);

  //Create btRigidBody
  if (compoundShape)
  {
    int shapeCount = compoundShape->getNumChildShapes ();
    CS_ALLOC_STACK_ARRAY(btScalar, masses, shapeCount); 
    for (int i = 0; i < shapeCount; i++)
      masses[i] = density * colliders[i]->GetVolume ();
    if (shapeChanged)
    {
      compoundShape->calculatePrincipalAxisTransform
        (masses, principalAxis, principalInertia);
      // apply principal axis
      // creation is faster using a new compound to store the shifted children
      btCompoundShape* newCompoundShape = new btCompoundShape();
      for (int i = 0; i < shapeCount; i++)
      {
        btTransform newChildTransform =
          principalAxis.inverse() * compoundShape->getChildTransform (i);
        newCompoundShape->addChildShape(newChildTransform,
          compoundShape->getChildShape (i));
        shapeChanged = false;
      }
      delete compoundShape;
      compoundShape = newCompoundShape;
    }

    shape = compoundShape;
  }
  else
  {
    shape = colliders[0]->shape;
    principalAxis = CSToBullet (relaTransforms[0], system->getInternalScale ());
  }

  // create new motion state
  btTransform trans;
  motionState->getWorldTransform (trans);
  trans = trans * motionState->inversePrincipalAxis;
  delete motionState;
  motionState = new csBulletMotionState (this, trans * principalAxis,
    principalAxis);

  //shape->calculateLocalInertia (mass, localInertia);

  btRigidBody::btRigidBodyConstructionInfo infos (mass, motionState,
    shape, localInertia);

  infos.m_friction = friction;
  infos.m_restitution = elasticity;
  infos.m_linearDamping = linearDampening;
  infos.m_angularDamping = angularDampening;

  // create new rigid body
  btBody = new btRigidBody (infos);
  btObject = btBody;

  if (haveStaticColliders > 0)
    physicalState = CS::Physics::STATE_STATIC;

  SetState (physicalState);

  sector->bulletWorld->addRigidBody (btBody, collGroup.value, collGroup.mask);
  btBody->setUserPointer (dynamic_cast<CS::Collisions::iCollisionObject*> (
    dynamic_cast<csBulletCollisionObject*>(this)));
 
  insideWorld = true;
  return true;
}