Exemplo n.º 1
0
bool PxBody::init(   PhysicsCollision *shape, 
                     F32 mass,
                     U32 bodyFlags,
                     SceneObject *obj, 
                     PhysicsWorld *world )
{
   AssertFatal( obj, "PxBody::init - Got a null scene object!" );
   AssertFatal( world, "PxBody::init - Got a null world!" );
   AssertFatal( dynamic_cast<PxWorld*>( world ), "PxBody::init - The world is the wrong type!" );
   AssertFatal( shape, "PxBody::init - Got a null collision shape!" );
   AssertFatal( dynamic_cast<PxCollision*>( shape ), "PxBody::init - The collision shape is the wrong type!" );
   AssertFatal( !((PxCollision*)shape)->getShapes().empty(), "PxBody::init - Got empty collision shape!" );
	 
   // Cleanup any previous actor.
   _releaseActor();

   mWorld = (PxWorld*)world;
   mColShape = (PxCollision*)shape;
   mBodyFlags = bodyFlags;

   NxActorDesc actorDesc;
   NxBodyDesc bodyDesc;

   const bool isKinematic = mBodyFlags & BF_KINEMATIC;
   const bool isTrigger = mBodyFlags & BF_TRIGGER;
   const bool isDebris = mBodyFlags & BF_DEBRIS;

   if ( isKinematic )
   {
      // Kinematics are dynamics... so they need
      // a body description.
      actorDesc.body = &bodyDesc;
      bodyDesc.mass = getMax( mass, 1.0f );
	   bodyDesc.flags	|= NX_BF_KINEMATIC;
   }
   else if ( mass > 0.0f )
   {
      // We have mass so its a dynamic.
      actorDesc.body = &bodyDesc;
      bodyDesc.mass = mass;
   }

   if ( isTrigger )
      actorDesc.flags |= NX_AF_DISABLE_RESPONSE;

   // Add all the shapes.
   const Vector<NxShapeDesc*> &shapes = mColShape->getShapes();
   for ( U32 i=0; i < shapes.size(); i++ )
   {
      NxShapeDesc *desc = shapes[i];

      // If this hits then something is broken with 
      // this descrption... check all the fields to be
      // sure their values are correctly filled out.
      AssertFatal( desc->isValid(), "PxBody::init - Got invalid shape description!" );

      if ( isTrigger )
         desc->group = 31;

      if ( isDebris )
         desc->group = 30;

      actorDesc.shapes.push_back( desc );
   }

   // This sucks, but it has to happen if we want
   // to avoid write lock errors from PhysX right now.
   mWorld->releaseWriteLock();

   mActor = mWorld->getScene()->createActor( actorDesc );
   mIsEnabled = true;

   if ( isDebris )
      mActor->setDominanceGroup( 31 );

   mUserData.setObject( obj );
   mUserData.setBody( this );
   mActor->userData = &mUserData;

   return true;
}
Exemplo n.º 2
0
PxBody::~PxBody()
{
   _releaseActor();
}
Exemplo n.º 3
0
BtBody::~BtBody()
{
   _releaseActor();
}
Exemplo n.º 4
0
bool BtBody::init(   PhysicsCollision *shape, 
                        F32 mass,
                        U32 bodyFlags,
                        SceneObject *obj, 
                        PhysicsWorld *world )
{
   AssertFatal( obj, "BtBody::init - Got a null scene object!" );
   AssertFatal( world, "BtBody::init - Got a null world!" );
   AssertFatal( dynamic_cast<BtWorld*>( world ), "BtBody::init - The world is the wrong type!" );
   AssertFatal( shape, "BtBody::init - Got a null collision shape!" );
   AssertFatal( dynamic_cast<BtCollision*>( shape ), "BtBody::init - The collision shape is the wrong type!" );
   AssertFatal( ((BtCollision*)shape)->getShape(), "BtBody::init - Got empty collision shape!" );
	 
   // Cleanup any previous actor.
   _releaseActor();

   mWorld = (BtWorld*)world;

   mColShape = (BtCollision*)shape;
   btCollisionShape *btColShape = mColShape->getShape();
   MatrixF localXfm = mColShape->getLocalTransform();
   btVector3 localInertia( 0, 0, 0 );   

   // If we have a mass then we're dynamic.
   mIsDynamic = mass > 0.0f;
   if ( mIsDynamic )
   {
      if ( btColShape->isCompound() )
      {
         btCompoundShape *btCompound = (btCompoundShape*)btColShape;

         btScalar *masses = new btScalar[ btCompound->getNumChildShapes() ];
         for ( U32 j=0; j < btCompound->getNumChildShapes(); j++ )
	         masses[j] = mass / btCompound->getNumChildShapes();

         btVector3 principalInertia;
         btTransform principal;
         btCompound->calculatePrincipalAxisTransform( masses, principal, principalInertia );
         delete [] masses;

	      // Create a new compound with the shifted children.
	      btColShape = mCompound = new btCompoundShape();
	      for ( U32 i=0; i < btCompound->getNumChildShapes(); i++ )
	      {
		      btTransform newChildTransform = principal.inverse() * btCompound->getChildTransform(i);
		      mCompound->addChildShape( newChildTransform, btCompound->getChildShape(i) );
	      }

         localXfm = btCast<MatrixF>( principal );
      }

      // Note... this looks like we're changing the shape, but 
      // we're not.  All this does is ask the shape to calculate the
      // local inertia vector from the mass... the shape doesn't change.
      btColShape->calculateLocalInertia( mass, localInertia );
   }

   // If we have a local transform then we need to
   // store it and the inverse to offset the center
   // of mass from the graphics origin.
   if ( !localXfm.isIdentity() )
   {
      mCenterOfMass = new MatrixF( localXfm );
      mInvCenterOfMass = new MatrixF( *mCenterOfMass );
      mInvCenterOfMass->inverse();
   }

   mMass = mass;
   mActor = new btRigidBody( mass, NULL, btColShape, localInertia );
   
   int btFlags = mActor->getCollisionFlags();

   if ( bodyFlags & BF_TRIGGER )
      btFlags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
   if ( bodyFlags & BF_KINEMATIC )
   {
      btFlags &= ~btCollisionObject::CF_STATIC_OBJECT;
      btFlags |= btCollisionObject::CF_KINEMATIC_OBJECT;
   }

   mActor->setCollisionFlags( btFlags );

   mWorld->getDynamicsWorld()->addRigidBody( mActor );
   mIsEnabled = true;

   mUserData.setObject( obj );
   mUserData.setBody( this );
   mActor->setUserPointer( &mUserData );

   return true;
}
Exemplo n.º 5
0
bool Px3Body::init(   PhysicsCollision *shape, 
                     F32 mass,
                     U32 bodyFlags,
                     SceneObject *obj, 
                     PhysicsWorld *world )
{
   AssertFatal( obj, "Px3Body::init - Got a null scene object!" );
   AssertFatal( world, "Px3Body::init - Got a null world!" );
   AssertFatal( dynamic_cast<Px3World*>( world ), "Px3Body::init - The world is the wrong type!" );
   AssertFatal( shape, "Px3Body::init - Got a null collision shape!" );
   AssertFatal( dynamic_cast<Px3Collision*>( shape ), "Px3Body::init - The collision shape is the wrong type!" );
   AssertFatal( !((Px3Collision*)shape)->getShapes().empty(), "Px3Body::init - Got empty collision shape!" );
	 
   // Cleanup any previous actor.
   _releaseActor();

   mWorld = (Px3World*)world;
   mColShape = (Px3Collision*)shape;
   mBodyFlags = bodyFlags;

   const bool isKinematic = mBodyFlags & BF_KINEMATIC;
   const bool isTrigger = mBodyFlags & BF_TRIGGER;
   const bool isDebris = mBodyFlags & BF_DEBRIS;

   if ( isKinematic )
   {
		mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
		physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
		actor->setRigidDynamicFlag(physx::PxRigidDynamicFlag::eKINEMATIC, true);
		actor->setMass(getMax( mass, 1.0f ));
   }
   else if ( mass > 0.0f )
   {
      mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
   }
   else
   {
      mActor = gPhysics3SDK->createRigidStatic(physx::PxTransform(physx::PxIDENTITY()));
      mIsStatic = true;
	}

   mMaterial = gPhysics3SDK->createMaterial(0.6f,0.4f,0.1f);
  
   // Add all the shapes.
   const Vector<Px3CollisionDesc*> &shapes = mColShape->getShapes();
   for ( U32 i=0; i < shapes.size(); i++ )
   {
	   Px3CollisionDesc* desc = shapes[i];
	   if( mass > 0.0f )
	   {
			if(desc->pGeometry->getType() == physx::PxGeometryType::eTRIANGLEMESH)
			{
				Con::errorf("PhysX3 Dynamic Triangle Mesh is not supported.");
			}
	   }
	   physx::PxShape * pShape = mActor->createShape(*desc->pGeometry,*mMaterial);
	   physx::PxFilterData colData;
	   if(isDebris)
			colData.word0 = PX3_DEBRIS;
	   else if(isTrigger)
        colData.word0 = PX3_TRIGGER;
	   else
		   colData.word0 = PX3_DEFAULT;

      //set local pose - actor->createShape with a local pose is deprecated in physx 3.3
      pShape->setLocalPose(desc->pose);
      //set the skin width
      pShape->setContactOffset(0.01f);
      pShape->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE, !isTrigger);
      pShape->setFlag(physx::PxShapeFlag::eSCENE_QUERY_SHAPE,true);
      pShape->setSimulationFilterData(colData);
      pShape->setQueryFilterData(colData);
   }

   //mass & intertia has to be set after creating the shape
   if ( mass > 0.0f )
   {
		physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
		physx::PxRigidBodyExt::setMassAndUpdateInertia(*actor,mass);
   }

    // This sucks, but it has to happen if we want
   // to avoid write lock errors from PhysX right now.
   mWorld->releaseWriteLock();

   mWorld->getScene()->addActor(*mActor);
   mIsEnabled = true;

   if ( isDebris )
     mActor->setDominanceGroup( 31 );

   mUserData.setObject( obj );
   mUserData.setBody( this );
   mActor->userData = &mUserData;

   return true;
}