Esempio n. 1
0
void csBulletPivotJoint::SetPosition (const csVector3& position)
{
  if (constraint)
  {
    constraint->setPivotB (CSToBullet (position, dynSys->internalScale));
    body->body->forceActivationState (ACTIVE_TAG);
  }
}
Esempio n. 2
0
void csBulletRigidBody::SetLinearVelocity (const csVector3& vel)
{
  linearVelocity = vel;
  if (!btBody)
    return;
  if (physicalState == CS::Physics::STATE_DYNAMIC)
  {
    btBody->setLinearVelocity (CSToBullet (vel, system->getInternalScale ()));
    btBody->activate ();
  }
}
Esempio n. 3
0
    HeightMapCollider::HeightMapCollider (csBulletDynamicsSystem* dynSys,
                                          iBody* csBody,
                                          csLockedHeightData gridData,
                                          int gridWidth, int gridHeight,
                                          csVector3 gridSize,
                                          csOrthoTransform transform,
                                          float minimumHeight, float maximumHeight)
        : dynSys (dynSys)
    {
        // Check if the min/max have to be computed
        bool needExtremum = minimumHeight == 0.0f && maximumHeight == 0.0f;
        if (needExtremum)
            minimumHeight = maximumHeight = gridData.data[0];

        // Initialize the terrain height data
        heightData = new float[gridHeight * gridWidth];
        for (int i = 0; i < gridWidth; i++)
            for (int j = 0; j < gridHeight; j++)
            {
                float height = heightData[(gridWidth - i - 1) * gridWidth + j]
                               = gridData.data[i * gridWidth + j];

                if (needExtremum)
                {
                    minimumHeight = MIN (minimumHeight, height);
                    maximumHeight = MAX (maximumHeight, height);
                }
            }

        // Create the terrain shape
        shape = new btHeightfieldTerrainShape (gridWidth, gridHeight,
                                               heightData, 1.0f, minimumHeight, maximumHeight,
                                               1, PHY_FLOAT, false);

        // Apply the local scaling on the shape
        btVector3 localScale (gridSize[0] * dynSys->internalScale / (gridWidth - 1),
                              dynSys->internalScale,
                              gridSize[2] * dynSys->internalScale / (gridHeight - 1));
        shape->setLocalScaling (localScale);

        // Set the origin to the middle of the heightfield
        csVector3 offset (gridSize[0] * 0.5f,
                          (maximumHeight - minimumHeight) * 0.5f + minimumHeight,
                          gridSize[2] * 0.5f);
        transform.SetOrigin (transform.GetOrigin () + transform.This2OtherRelative (offset));
        btTransform tr = CSToBullet (transform, dynSys->internalScale);

        // Create the rigid body and add it to the world
        body = new btRigidBody (0, 0, shape, btVector3 (0, 0, 0));
        body->setWorldTransform (tr);
        body->setUserPointer (csBody);
        dynSys->bulletWorld->addRigidBody (body);
    }
Esempio n. 4
0
void csBulletPivotJoint::Attach (::iRigidBody* body,
				 const csVector3& position)
{
  CS_ASSERT (body);
  this->body = static_cast<csBulletRigidBody*> ((csBulletRigidBody*) body);
  CS_ASSERT (this->body);

  btVector3 localPivot = this->body->body->getCenterOfMassTransform ().inverse ()
    * CSToBullet (position, dynSys->internalScale);

  constraint = new btPoint2PointConstraint
    (*this->body->body, localPivot);
  dynSys->bulletWorld->addConstraint (constraint);

  constraint->m_setting.m_tau = 0.1f;
}
Esempio n. 5
0
    bool csBulletCollider::CreateBoxGeometry (const csVector3& size)
    {
        delete shape;
        shape = 0;
        delete[] vertices;
        vertices = 0;
        delete[] indices;
        indices = 0;

        shape = new btBoxShape (CSToBullet (size * 0.5f, dynSys->internalScale));
        geomType = BOX_COLLIDER_GEOMETRY;

        if (isStaticBody)
        {
            body->compoundChanged = true;
            body->RebuildBody ();
        }

        return true;
    }
Esempio n. 6
0
bool csBulletJoint::RebuildJoint ()
{
  // TODO: use (or deprecate?) angular_constraints_axis
  // TODO: use btGeneric6DofSpringConstraint if there is some stiffness
  // TODO: use m_damping
  // TODO:: allow setting a motor with a target velocity of 0

  if (constraint)
  {
    dynSys->bulletWorld->removeConstraint (constraint);
    delete constraint;
    constraint = 0;
  }

  if (!bodies[0] || !bodies[1]) return false;
  if (!bodies[0]->body || !bodies[1]->body) return false;

  jointType = ComputeBestBulletJointType ();
  switch (jointType)
  {
    case BULLET_JOINT_6DOF:
      {
	// compute local transforms of the joint
	btTransform jointTransform =
	  CSToBullet (transform * bodies[1]->GetTransform (), dynSys->internalScale);

	btTransform frA;
	frA = bodies[0]->body->getCenterOfMassTransform().inverse() * jointTransform;
	// TODO: for some reason, the joint will be misplaced if some of the bodies are static

	btTransform frB;
	frB = bodies[1]->body->getCenterOfMassTransform().inverse() * jointTransform;

	// create joint
	btGeneric6DofConstraint* dof6 =
	  new btGeneric6DofConstraint (*bodies[0]->body, *bodies[1]->body,
				       frA, frB, true);

	// compute min/max values
	btVector3 minLinear(0.0f, 0.0f, 0.0f);
	btVector3 maxLinear(0.0f, 0.0f, 0.0f);

	if (!trans_constraint_x)
	{
	  minLinear.setX(min_dist[0]);
	  maxLinear.setX(max_dist[0]);
	}
	if (!trans_constraint_y)
	{
	  minLinear.setY(min_dist[1]);
	  maxLinear.setY(max_dist[1]);
	}
	if (!trans_constraint_z)
	{
	  minLinear.setZ(min_dist[2]);
	  maxLinear.setZ(max_dist[2]);
	}

	btVector3 minAngular(0.0f, 0.0f, 0.0f);
	btVector3 maxAngular(0.0f, 0.0f, 0.0f);

	if (!rot_constraint_x)
	{
	  minAngular.setX(min_angle[0]);
	  maxAngular.setX(max_angle[0]);
	}
	if (!rot_constraint_y)
	{
	  minAngular.setY(min_angle[1]);
	  maxAngular.setY(max_angle[1]);
	}
	if (!rot_constraint_z)
	{
	  minAngular.setZ(min_angle[2]);
	  maxAngular.setZ(max_angle[2]);
	}

	// apply min/max values
	dof6->setLinearLowerLimit (minLinear);
	dof6->setLinearUpperLimit (maxLinear);
	dof6->setAngularLowerLimit (minAngular);
	dof6->setAngularUpperLimit (maxAngular);

	// apply the parameters for the motor
	if (fabs (desired_velocity[0]) > EPSILON)
	{
	  btRotationalLimitMotor* motor = dof6->getRotationalLimitMotor (0);
	  motor->m_enableMotor = true;
	  motor->m_targetVelocity = desired_velocity[0];
	  motor->m_maxMotorForce = maxforce[0];
	}
	dof6->getRotationalLimitMotor (0)->m_bounce = bounce[0];

	if (fabs (desired_velocity[1]) > EPSILON)
	{
	  printf ("Setting motor\n");
	  btRotationalLimitMotor* motor = dof6->getRotationalLimitMotor (1);
	  motor->m_enableMotor = true;
	  motor->m_targetVelocity = desired_velocity[1];
	  motor->m_maxMotorForce = maxforce[1];
	  motor->m_damping = 0.1f;
	}
	dof6->getRotationalLimitMotor (1)->m_bounce = bounce[1];

	if (fabs (desired_velocity[2]) > EPSILON)
	{
	  btRotationalLimitMotor* motor = dof6->getRotationalLimitMotor (2);
	  motor->m_enableMotor = true;
	  motor->m_targetVelocity = desired_velocity[2];
	  motor->m_maxMotorForce = maxforce[2];
	  motor->m_damping = 0.1f;
	}
	dof6->getRotationalLimitMotor (2)->m_bounce = bounce[2];

	constraint = dof6;
      }
      break;

    case BULLET_JOINT_CONETWIST:
      {
	// compute local transforms of the joint
	btTransform frA;
	btTransform frB;

	btTransform jointTransform = CSToBullet (bodies[1]->GetTransform (),
						 dynSys->internalScale);

	bodies[0]->motionState->getWorldTransform (frA);
        frA = frA.inverse () * jointTransform;
	bodies[1]->motionState->getWorldTransform (frB);
        frB = frB.inverse () * jointTransform;

	// create joint
	btConeTwistConstraint* coneTwist = new btConeTwistConstraint (*bodies[0]->body, *bodies[1]->body,
								      frA, frB);

	// apply min/max values
	if (min_angle[0] < max_angle[0])
	  coneTwist->setLimit (3, (max_angle[0] - min_angle[0]) * 5.0f);
	if (min_angle[1] < max_angle[1])
	  coneTwist->setLimit (4, (max_angle[1] - min_angle[1]) * 5.0f);
	if (min_angle[2] < max_angle[2])
	  coneTwist->setLimit (5, (max_angle[2] - min_angle[2]) * 5.0f);

	constraint = coneTwist;
      }
      break;

    case BULLET_JOINT_POINT2POINT:
      {
	// TODO
      }
      break;

    default:
      // @@@ TODO
      break;
  }

  if (constraint)
  {
    dynSys->bulletWorld->addConstraint (constraint, true);
    return true;
  }

  return false;
}
Esempio n. 7
0
void csBulletJoint::SetMaximumDistance (const csVector3& max, bool force_update)
{
  max_dist = CSToBullet (max, dynSys->internalScale);
  if (force_update)
    RebuildJoint ();
}
Esempio n. 8
0
bool csBulletRigidBody::SetState (CS::Physics::RigidBodyState state)
{
  if (physicalState != state || !insideWorld)
  {
    CS::Physics::RigidBodyState previousState = physicalState;
    physicalState = state;

    if (!btBody)
      return false;

    if (haveStaticColliders > 0 && state != CS::Physics::STATE_STATIC)
      return false;

    if (insideWorld)
      sector->bulletWorld->removeRigidBody (btBody);

    btVector3 linearVelo = CSToBullet (linearVelocity, system->getInternalScale ());
    btVector3 angularVelo = btVector3 (angularVelocity.x, angularVelocity.y, angularVelocity.z);

    if (previousState == CS::Physics::STATE_KINEMATIC && insideWorld)
    {
      btBody->setCollisionFlags (btBody->getCollisionFlags()
        & ~btCollisionObject::CF_KINEMATIC_OBJECT);

      linearVelo = btBody->getInterpolationLinearVelocity ();
      angularVelo = btBody->getInterpolationAngularVelocity ();

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

    if (state == CS::Physics::STATE_DYNAMIC)
    {
      btBody->setCollisionFlags (btBody->getCollisionFlags()
        & ~btCollisionObject::CF_STATIC_OBJECT);

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

      if (compoundShape)
        compoundShape->calculateLocalInertia (mass, localInertia);
      else
        colliders[0]->shape->calculateLocalInertia (mass, localInertia);

      btBody->setMassProps (mass, localInertia);

      btBody->forceActivationState (ACTIVE_TAG);

      btBody->setLinearVelocity (linearVelo);
      btBody->setAngularVelocity (angularVelo);
      btBody->updateInertiaTensor ();
    }
    else if (state == CS::Physics::STATE_KINEMATIC)
    {
      if (!kinematicCb)
        kinematicCb.AttachNew (new csBulletDefaultKinematicCallback ());

      // create new motion state
      btTransform principalAxis = motionState->inversePrincipalAxis.inverse ();
      btTransform trans;
      motionState->getWorldTransform (trans);
      delete motionState;
      motionState = new csBulletKinematicMotionState
        (this, trans, principalAxis);
      btBody->setMotionState (motionState);

      // set body kinematic

      btBody->setMassProps (0.0f, btVector3 (0.0f, 0.0f, 0.0f));

      btBody->setCollisionFlags (btBody->getCollisionFlags()
        | btCollisionObject::CF_KINEMATIC_OBJECT
        & ~btCollisionObject::CF_STATIC_OBJECT);
      btBody->setActivationState (DISABLE_DEACTIVATION);    
      btBody->updateInertiaTensor ();
      btBody->setInterpolationWorldTransform (btBody->getWorldTransform ());
      btBody->setInterpolationLinearVelocity (btVector3(0.0f, 0.0f, 0.0f));
      btBody->setInterpolationAngularVelocity (btVector3(0.0f, 0.0f, 0.0f));
    }
    else if (state == CS::Physics::STATE_STATIC)
    {
      btBody->setCollisionFlags (btBody->getCollisionFlags()
        | btCollisionObject::CF_STATIC_OBJECT
        & ~btCollisionObject::CF_KINEMATIC_OBJECT);
      btBody->setActivationState (ISLAND_SLEEPING);    
      btBody->setMassProps (0.0f, btVector3 (0.0f, 0.0f, 0.0f));
      btBody->updateInertiaTensor ();
    }

    if (insideWorld)
      sector->bulletWorld->addRigidBody (btBody);
    return true;
  }
  else
    return false;
}
Esempio n. 9
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;
}