Ejemplo n.º 1
0
void TSStatic::_updatePhysics()
{
   SAFE_DELETE( mPhysicsRep );

   if ( !PHYSICSMGR || mCollisionType == None )
      return;

   PhysicsCollision *colShape = NULL;
   if ( mCollisionType == Bounds )
   {
      MatrixF offset( true );
      offset.setPosition( mShape->center );
      colShape = PHYSICSMGR->createCollision();
      colShape->addBox( getObjBox().getExtents() * 0.5f * mObjScale, offset );         
   }
   else
      colShape = mShape->buildColShape( mCollisionType == VisibleMesh, getScale() );

   if ( colShape )
   {
      PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
      mPhysicsRep = PHYSICSMGR->createBody();
      mPhysicsRep->init( colShape, 0, 0, this, world );
      mPhysicsRep->setTransform( getTransform() );
   }
}
Ejemplo n.º 2
0
PhysicsCollision* CollisionComponent::getCollisionData()
{
   if ((!PHYSICSMGR || mCollisionType == None) || mOwnerRenderInterface == NULL)
      return NULL;

   PhysicsCollision *colShape = NULL;
   if (mCollisionType == Bounds)
   {
      MatrixF offset(true);
      offset.setPosition(mOwnerRenderInterface->getShape()->center);
      colShape = PHYSICSMGR->createCollision();
      colShape->addBox(mOwner->getObjBox().getExtents() * 0.5f * mOwner->getScale(), offset);
   }
   else if (mCollisionType == CollisionMesh || (mCollisionType == VisibleMesh/* && !mOwner->getComponent<AnimatedMesh>()*/))
   {
      colShape = buildColShapes();
      //colShape = mOwnerShapeInstance->getShape()->buildColShape(mCollisionType == VisibleMesh, mOwner->getScale());
   }
   /*else if (mCollisionType == VisibleMesh && !mOwner->getComponent<AnimatedMesh>())
   {
   //We don't have support for visible mesh collisions with animated meshes currently in the physics abstraction layer
   //so we don't generate anything if we're set to use a visible mesh but have an animated mesh component.
   colShape = mOwnerShapeInstance->getShape()->buildColShape(mCollisionType == VisibleMesh, mOwner->getScale());
   }*/
   else if (mCollisionType == VisibleMesh/* && mOwner->getComponent<AnimatedMesh>()*/)
   {
      Con::printf("CollisionComponent::updatePhysics: Cannot use visible mesh collisions with an animated mesh!");
   }

   return colShape;
}
Ejemplo n.º 3
0
bool GroundPlane::onAdd()
{
   if( !Parent::onAdd() )
      return false;

   if( isClientObject() )
      _updateMaterial();
      
   if( mSquareSize < sMIN_SQUARE_SIZE )
   {
      Con::errorf( "GroundPlane - squareSize below threshold; re-setting to %.02f", sMIN_SQUARE_SIZE );
      mSquareSize = sMIN_SQUARE_SIZE;
   }

   Parent::setScale( VectorF( 1.0f, 1.0f, 1.0f ) );
   Parent::setTransform( MatrixF::Identity );
   setGlobalBounds();
   resetWorldBox();

   addToScene();

   if ( PHYSICSMGR )
   {
      PhysicsCollision *colShape = PHYSICSMGR->createCollision();
      colShape->addPlane( PlaneF( Point3F::Zero, Point3F( 0, 0, 1 ) ) ); 

      PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
      mPhysicsRep = PHYSICSMGR->createBody();
      mPhysicsRep->init( colShape, 0, 0, this, world );
   }

   return true;
}
Ejemplo n.º 4
0
//.logicking >>
void StaticShape::updatePhysics()
{
	SAFE_DELETE(mPhysicsRep);
	if ( PHYSICSMGR)
	{
		mShapeInstance->animate();

		// Get the interior collision geometry.
		ConcretePolyList polylist;
		if (buildPolyList(PLC_Collision, &polylist, getWorldBox(), getWorldSphere()))
		{
			polylist.triangulate();

			PhysicsCollision *colShape = PHYSICSMGR->createCollision();
			colShape->addTriangleMesh( polylist.mVertexList.address(), 
				polylist.mVertexList.size(),
				polylist.mIndexList.address(),
				polylist.mIndexList.size() / 3,
				MatrixF::Identity );

			PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
			mPhysicsRep = PHYSICSMGR->createBody();
			//.hack - set kinematic flag to prevent crash on deleting static shape in character sweep(deleting Doors)
			mPhysicsRep->init( colShape, 0, PhysicsBody::BF_KINEMATIC, this, world );
		}
		if (isServerObject())
			setMaskBits(PhysicsMask);
	}
}
Ejemplo n.º 5
0
void Trigger::setTriggerPolyhedron(const Polyhedron& rPolyhedron)
{
   mTriggerPolyhedron = rPolyhedron;

   if (mTriggerPolyhedron.pointList.size() != 0) {
      mObjBox.minExtents.set(1e10, 1e10, 1e10);
      mObjBox.maxExtents.set(-1e10, -1e10, -1e10);
      for (U32 i = 0; i < mTriggerPolyhedron.pointList.size(); i++) {
         mObjBox.minExtents.setMin(mTriggerPolyhedron.pointList[i]);
         mObjBox.maxExtents.setMax(mTriggerPolyhedron.pointList[i]);
      }
   } else {
      mObjBox.minExtents.set(-0.5, -0.5, -0.5);
      mObjBox.maxExtents.set( 0.5,  0.5,  0.5);
   }

   MatrixF xform = getTransform();
   setTransform(xform);

   mClippedList.clear();
   mClippedList.mPlaneList = mTriggerPolyhedron.planeList;
//   for (U32 i = 0; i < mClippedList.mPlaneList.size(); i++)
//      mClippedList.mPlaneList[i].neg();

   MatrixF base(true);
   base.scale(Point3F(1.0/mObjScale.x,
                      1.0/mObjScale.y,
                      1.0/mObjScale.z));
   base.mul(mWorldToObj);

   mClippedList.setBaseTransform(base);

   SAFE_DELETE( mPhysicsRep );

   if ( PHYSICSMGR )
   {
      PhysicsCollision *colShape = PHYSICSMGR->createCollision();

      MatrixF colMat( true );      
      colMat.displace( Point3F( 0, 0, mObjBox.getExtents().z * 0.5f * mObjScale.z ) );
      
      colShape->addBox( mObjBox.getExtents() * 0.5f * mObjScale, colMat );
      //MatrixF colMat( true );
      //colMat.scale( mObjScale );
      //colShape->addConvex( mTriggerPolyhedron.pointList.address(), mTriggerPolyhedron.pointList.size(), colMat );

      PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
      mPhysicsRep = PHYSICSMGR->createBody();
      mPhysicsRep->init( colShape, 0, PhysicsBody::BF_TRIGGER | PhysicsBody::BF_KINEMATIC, this, world );
      mPhysicsRep->setTransform( getTransform() );
   }
}
Ejemplo n.º 6
0
void CollisionComponent::prepCollision()
{
   if (!mOwner)
      return;

   // Let the client know that the collision was updated
   setMaskBits(ColliderMask);

   mOwner->disableCollision();

   if ((!PHYSICSMGR || mCollisionType == None) ||
      (mOwnerRenderInterface == NULL && (mCollisionType == CollisionMesh || mCollisionType == VisibleMesh)))
      return;

   PhysicsCollision *colShape = NULL;

   if (mCollisionType == Bounds)
   {
      MatrixF offset(true);

      if (mOwnerRenderInterface && mOwnerRenderInterface->getShape())
         offset.setPosition(mOwnerRenderInterface->getShape()->center);

      colShape = PHYSICSMGR->createCollision();
      colShape->addBox(mOwner->getObjBox().getExtents() * 0.5f * mOwner->getScale(), offset);
   }
   else if (mCollisionType == CollisionMesh || (mCollisionType == VisibleMesh /*&& !mOwner->getComponent<AnimatedMesh>()*/))
   {
      colShape = buildColShapes();
   }

   if (colShape)
   {
      mPhysicsWorld = PHYSICSMGR->getWorld(isServerObject() ? "server" : "client");

      if (mPhysicsRep)
      {
         if (mBlockColliding)
            mPhysicsRep->init(colShape, 0, 0, mOwner, mPhysicsWorld);
         else
            mPhysicsRep->init(colShape, 0, PhysicsBody::BF_TRIGGER, mOwner, mPhysicsWorld);

         mPhysicsRep->setTransform(mOwner->getTransform());
      }
   }

   mOwner->enableCollision();

   onCollisionChanged.trigger(colShape);
}
Ejemplo n.º 7
0
void Item::_updatePhysics()
{
   SAFE_DELETE( mPhysicsRep );

   if ( !PHYSICSMGR )
      return;

   if (mDataBlock->simpleServerCollision)
   {
      // We only need the trigger on the server.
      if ( isServerObject() )
      {
         PhysicsCollision *colShape = PHYSICSMGR->createCollision();
         colShape->addBox( mObjBox.getExtents() * 0.5f, MatrixF::Identity );

         PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
         mPhysicsRep = PHYSICSMGR->createBody();
         mPhysicsRep->init( colShape, 0, PhysicsBody::BF_TRIGGER | PhysicsBody::BF_KINEMATIC, this, world );
         mPhysicsRep->setTransform( getTransform() );
      }
   }
   else
   {
      if ( !mShapeInstance )
         return;

      PhysicsCollision* colShape = mShapeInstance->getShape()->buildColShape( false, getScale() );

      if ( colShape )
      {
         PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );
         mPhysicsRep = PHYSICSMGR->createBody();
         mPhysicsRep->init( colShape, 0, PhysicsBody::BF_KINEMATIC, this, world );
         mPhysicsRep->setTransform( getTransform() );
      }
   }
}
Ejemplo n.º 8
0
void ConvexShape::_updateCollision()
{
   SAFE_DELETE( mPhysicsRep );

   if ( !PHYSICSMGR )
      return;

   PhysicsCollision *colShape = PHYSICSMGR->createCollision();

   // We need the points untransformed!
   Vector<Point3F> rawPoints;
   MatrixF xfm( getWorldTransform() );
   xfm.setPosition( Point3F::Zero );
   for ( U32 i=0; i < mGeometry.points.size(); i++ )
   {
      Point3F p = mGeometry.points[i];
      xfm.mulP( p );
      rawPoints.push_back( p );
   }

   // The convex generation from a point cloud 
   // can fail at times... give up in that case.
   if ( !colShape->addConvex(    mGeometry.points.address(), 
                                 mGeometry.points.size(), 
                                 MatrixF::Identity ) )
   {
      delete colShape;
      return;
   }

   PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" );

   mPhysicsRep = PHYSICSMGR->createBody();
   mPhysicsRep->init( colShape, 0, 0, this, world );

   mPhysicsRep->setTransform( getTransform() );
}
Ejemplo n.º 9
0
void ForestCell::buildPhysicsRep( Forest *forest )
{   
   AssertFatal( isLeaf(), "ForestCell::buildPhysicsRep() - This shouldn't be called on non-leaf cells!" );

   bool isServer = forest->isServerObject();

   // Already has a PhysicsBody, if it needed to be rebuilt it would
   // already be null.
   if ( mPhysicsRep[ isServer ] )
      return;   

   if ( !PHYSICSMGR )
      return;

   PhysicsCollision *colShape = NULL;

   // If we can steal the collision shape from the server-side cell   
   // then do so as it saves us alot of cpu time and memory.
   if ( mPhysicsRep[ 1 ] )
   {      
      colShape = mPhysicsRep[ 1 ]->getColShape();
   }
   else
   {
      // We must pass a sphere to buildPolyList but it is not used.
      const static SphereF dummySphere( Point3F::Zero, 0 );       

      // Step thru them and build collision data.
      ForestItemVector::iterator itemItr = mItems.begin();
      ConcretePolyList polyList;
      for ( ; itemItr != mItems.end(); itemItr++ )
      {
         const ForestItem &item = *itemItr;
         const ForestItemData *itemData = item.getData();
         
         // If not collidable don't need to build anything.
         if ( !itemData->mCollidable )
            continue;

         // TODO: When we add breakable tree support this is where
         // we would need to store their collision data seperately.

         item.buildPolyList( &polyList, item.getWorldBox(), dummySphere );

         // TODO: Need to support multiple collision shapes
         // for really big forests at some point in the future.
      }

      if ( !polyList.isEmpty() )
      {
         colShape = PHYSICSMGR->createCollision();
         if ( !colShape->addTriangleMesh( polyList.mVertexList.address(),
                                          polyList.mVertexList.size(),
                                          polyList.mIndexList.address(),
                                          polyList.mIndexList.size() / 3,
                                          MatrixF::Identity ) )
         {
            SAFE_DELETE( colShape );
         }
      }
   }

   // We might not have any trees.
   if ( !colShape )
      return;

   PhysicsWorld *world = PHYSICSMGR->getWorld( isServer ? "server" : "client" );
   mPhysicsRep[ isServer ] = PHYSICSMGR->createBody();
   mPhysicsRep[ isServer ]->init( colShape, 0, 0, forest, world );
}
Ejemplo n.º 10
0
PhysicsCollision* CollisionComponent::buildColShapes()
{
   PROFILE_SCOPE(CollisionComponent_buildColShapes);

   PhysicsCollision *colShape = NULL;
   U32 surfaceKey = 0;

   TSShape* shape = mOwnerRenderInterface->getShape();

   if (mCollisionType == VisibleMesh)
   {
      // Here we build triangle collision meshes from the
      // visible detail levels.

      // A negative subshape on the detail means we don't have geometry.
      const TSShape::Detail &detail = shape->details[0];
      if (detail.subShapeNum < 0)
         return NULL;

      // We don't try to optimize the triangles we're given
      // and assume the art was created properly for collision.
      ConcretePolyList polyList;
      polyList.setTransform(&MatrixF::Identity, mOwner->getScale());

      // Create the collision meshes.
      S32 start = shape->subShapeFirstObject[detail.subShapeNum];
      S32 end = start + shape->subShapeNumObjects[detail.subShapeNum];
      for (S32 o = start; o < end; o++)
      {
         const TSShape::Object &object = shape->objects[o];
         if (detail.objectDetailNum >= object.numMeshes)
            continue;

         // No mesh or no verts.... nothing to do.
         TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum];
         if (!mesh || mesh->mNumVerts == 0)
            continue;

         // Gather the mesh triangles.
         polyList.clear();
         mesh->buildPolyList(0, &polyList, surfaceKey, NULL);

         // Create the collision shape if we haven't already.
         if (!colShape)
            colShape = PHYSICSMGR->createCollision();

         // Get the object space mesh transform.
         MatrixF localXfm;
         shape->getNodeWorldTransform(object.nodeIndex, &localXfm);

         colShape->addTriangleMesh(polyList.mVertexList.address(),
            polyList.mVertexList.size(),
            polyList.mIndexList.address(),
            polyList.mIndexList.size() / 3,
            localXfm);
      }

      // Return what we built... if anything.
      return colShape;
   }
   else if (mCollisionType == CollisionMesh)
   {

      // Scan out the collision hulls...
      //
      // TODO: We need to support LOS collision for physics.
      //
      for (U32 i = 0; i < shape->details.size(); i++)
      {
         const TSShape::Detail &detail = shape->details[i];
         const String &name = shape->names[detail.nameIndex];

         // Is this a valid collision detail.
         if (!dStrStartsWith(name, colisionMeshPrefix) || detail.subShapeNum < 0)
            continue;

         // Now go thru the meshes for this detail.
         S32 start = shape->subShapeFirstObject[detail.subShapeNum];
         S32 end = start + shape->subShapeNumObjects[detail.subShapeNum];
         if (start >= end)
            continue;

         for (S32 o = start; o < end; o++)
         {
            const TSShape::Object &object = shape->objects[o];
            const String &meshName = shape->names[object.nameIndex];

            if (object.numMeshes <= detail.objectDetailNum)
               continue;

            // No mesh, a flat bounds, or no verts.... nothing to do.
            TSMesh *mesh = shape->meshes[object.startMeshIndex + detail.objectDetailNum];
            if (!mesh || mesh->getBounds().isEmpty() || mesh->mNumVerts == 0)
               continue;

            // We need the default mesh transform.
            MatrixF localXfm;
            shape->getNodeWorldTransform(object.nodeIndex, &localXfm);

            // We have some sort of collision shape... so allocate it.
            if (!colShape)
               colShape = PHYSICSMGR->createCollision();

            // Any other mesh name we assume as a generic convex hull.
            //
            // Collect the verts using the vertex polylist which will 
            // filter out duplicates.  This is importaint as the convex
            // generators can sometimes fail with duplicate verts.
            //
            VertexPolyList polyList;
            MatrixF meshMat(localXfm);

            Point3F t = meshMat.getPosition();
            t.convolve(mOwner->getScale());
            meshMat.setPosition(t);

            polyList.setTransform(&MatrixF::Identity, mOwner->getScale());
            mesh->buildPolyList(0, &polyList, surfaceKey, NULL);
            colShape->addConvex(polyList.getVertexList().address(),
               polyList.getVertexList().size(),
               meshMat);
         } // objects
      } // details
   }

   return colShape;
}