Пример #1
0
int main(int argc, char **argv){
  int peid, numpes;
  MPI_Comm newComm;

  //basic MPI initilization
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &peid);
  MPI_Comm_size(MPI_COMM_WORLD, &numpes);


  //initialize Charm for each set
  CharmLibInit(MPI_COMM_WORLD, argc, argv);
  MPI_Barrier(MPI_COMM_WORLD);
  CollisionList *colls;
  CkVector3d o(-6.8,7.9,8.0), x(4.0,0,0), y(0,0.3,0);
  CkVector3d boxSize(0.2,0.2,0.2);
  int nBoxes=1000;
  bbox3d *box=new bbox3d[nBoxes];
  for (int i=0;i<nBoxes;i++) {
	  CkVector3d c(o+x*peid+y*i);
	  CkVector3d c2(c+boxSize);
	  box[i].empty();
	  box[i].add(c); box[i].add(c2);
  }
  // first box stretches over into next object:
  box[0].add(o+x*(peid+1.5)+y*2);
  detectCollision(colls,nBoxes, box, NULL);
  int numColls=colls->length();
  for (int c=0;c<numColls;c++) {
	  printf("%d:%d hits %d:%d\n",
			  (*colls)[c].A.chunk,(*colls)[c].A.number,
			  (*colls)[c].B.chunk,(*colls)[c].B.number);
  }

  delete box;
  MPI_Barrier(MPI_COMM_WORLD);
  CharmLibExit();

  //final synchronization
  MPI_Barrier(MPI_COMM_WORLD);

  MPI_Finalize();
  return 0;  
}
Пример #2
0
bool PhysicsEntity::findPlaneCollisions(const glm::vec4& plane, CollisionList& collisions) {
    bool collided = false;
    PlaneShape planeShape(plane);
    for (int i = 0; i < _shapes.size(); i++) {
        if (_shapes.at(i) && ShapeCollider::collideShapes(&planeShape, _shapes.at(i), collisions)) {
            CollisionInfo* collision = collisions.getLastCollision();
            collision->_data = (void*)(this);
            collision->_intData = i;
            collided = true;
        }
    }
    return collided;
}
Пример #3
0
bool PhysicsEntity::findSphereCollisions(const glm::vec3& sphereCenter, float sphereRadius, CollisionList& collisions) {
    bool collided = false;
    SphereShape sphere(sphereRadius, sphereCenter);
    for (int i = 0; i < _shapes.size(); i++) {
        Shape* shape = _shapes[i];
        if (!shape) {
            continue;
        }
        if (ShapeCollider::collideShapes(&sphere, shape, collisions)) {
            CollisionInfo* collision = collisions.getLastCollision();
            collision->_data = (void*)(this);
            collision->_intData = i;
            collided = true;
        }
    }
    return collided;
}
Пример #4
0
bool collideShapesCoarse(const QVector<const Shape*>& shapesA, const QVector<const Shape*>& shapesB, CollisionInfo& collision) {
    tempCollisions.clear();
    foreach (const Shape* shapeA, shapesA) {
        foreach (const Shape* shapeB, shapesB) {
            ShapeCollider::collideShapes(shapeA, shapeB, tempCollisions);
        }
Пример #5
0
void Item::updatePos(const U32 /*mask*/, const F32 dt)
{
   // Try and move
   Point3F pos;
   mObjToWorld.getColumn(3,&pos);
   delta.posVec = pos;

   bool contact = false;
   bool nonStatic = false;
   bool stickyNotify = false;
   CollisionList collisionList;
   F32 time = dt;

   static Polyhedron sBoxPolyhedron;
   static ExtrudedPolyList sExtrudedPolyList;
   static EarlyOutPolyList sEarlyOutPolyList;
   MatrixF collisionMatrix(true);
   Point3F end = pos + mVelocity * time;
   U32 mask = isServerObject() ? sServerCollisionMask : sClientCollisionMask;

   // Part of our speed problem here is that we don't track contact surfaces, like we do
   //  with the player.  In order to handle the most common and performance impacting
   //  instance of this problem, we'll use a ray cast to detect any contact surfaces below
   //  us.  This won't be perfect, but it only needs to catch a few of these to make a
   //  big difference.  We'll cast from the top center of the bounding box at the tick's
   //  beginning to the bottom center of the box at the end.
   Point3F startCast((mObjBox.minExtents.x + mObjBox.maxExtents.x) * 0.5,
                     (mObjBox.minExtents.y + mObjBox.maxExtents.y) * 0.5,
                     mObjBox.maxExtents.z);
   Point3F endCast((mObjBox.minExtents.x + mObjBox.maxExtents.x) * 0.5,
                   (mObjBox.minExtents.y + mObjBox.maxExtents.y) * 0.5,
                   mObjBox.minExtents.z);
   collisionMatrix.setColumn(3, pos);
   collisionMatrix.mulP(startCast);
   collisionMatrix.setColumn(3, end);
   collisionMatrix.mulP(endCast);
   RayInfo rinfo;
   bool doToughCollision = true;
   disableCollision();
   if (mCollisionObject)
      mCollisionObject->disableCollision();
   if (getContainer()->castRay(startCast, endCast, mask, &rinfo))
   {
      F32 bd = -mDot(mVelocity, rinfo.normal);

      if (bd >= 0.0)
      {
         // Contact!
         if (mDataBlock->sticky && rinfo.object->getTypeMask() & (STATIC_COLLISION_TYPEMASK)) {
            mVelocity.set(0, 0, 0);
            mAtRest = true;
            mAtRestCounter = 0;
            stickyNotify = true;
            mStickyCollisionPos    = rinfo.point;
            mStickyCollisionNormal = rinfo.normal;
            doToughCollision = false;;
         } else {
            // Subtract out velocity into surface and friction
            VectorF fv = mVelocity + rinfo.normal * bd;
            F32 fvl = fv.len();
            if (fvl) {
               F32 ff = bd * mDataBlock->friction;
               if (ff < fvl) {
                  fv *= ff / fvl;
                  fvl = ff;
               }
            }
            bd *= 1 + mDataBlock->elasticity;
            VectorF dv = rinfo.normal * (bd + 0.002);
            mVelocity += dv;
            mVelocity -= fv;

            // Keep track of what we hit
            contact = true;
            U32 typeMask = rinfo.object->getTypeMask();
            if (!(typeMask & StaticObjectType))
               nonStatic = true;
            if (isServerObject() && (typeMask & ShapeBaseObjectType)) {
               ShapeBase* col = static_cast<ShapeBase*>(rinfo.object);
               queueCollision(col,mVelocity - col->getVelocity());
            }
         }
      }
   }
   enableCollision();
   if (mCollisionObject)
      mCollisionObject->enableCollision();

   if (doToughCollision)
   {
      U32 count;
      for (count = 0; count < 3; count++)
      {
         // Build list from convex states here...
         end = pos + mVelocity * time;


         collisionMatrix.setColumn(3, end);
         Box3F wBox = getObjBox();
         collisionMatrix.mul(wBox);
         Box3F testBox = wBox;
         Point3F oldMin = testBox.minExtents;
         Point3F oldMax = testBox.maxExtents;
         testBox.minExtents.setMin(oldMin + (mVelocity * time));
         testBox.maxExtents.setMin(oldMax + (mVelocity * time));

         sEarlyOutPolyList.clear();
         sEarlyOutPolyList.mNormal.set(0,0,0);
         sEarlyOutPolyList.mPlaneList.setSize(6);
         sEarlyOutPolyList.mPlaneList[0].set(wBox.minExtents,VectorF(-1,0,0));
         sEarlyOutPolyList.mPlaneList[1].set(wBox.maxExtents,VectorF(0,1,0));
         sEarlyOutPolyList.mPlaneList[2].set(wBox.maxExtents,VectorF(1,0,0));
         sEarlyOutPolyList.mPlaneList[3].set(wBox.minExtents,VectorF(0,-1,0));
         sEarlyOutPolyList.mPlaneList[4].set(wBox.minExtents,VectorF(0,0,-1));
         sEarlyOutPolyList.mPlaneList[5].set(wBox.maxExtents,VectorF(0,0,1));

         CollisionWorkingList& eorList = mConvex.getWorkingList();
         CollisionWorkingList* eopList = eorList.wLink.mNext;
         while (eopList != &eorList) {
            if ((eopList->mConvex->getObject()->getTypeMask() & mask) != 0)
            {
               Box3F convexBox = eopList->mConvex->getBoundingBox();
               if (testBox.isOverlapped(convexBox))
               {
                  eopList->mConvex->getPolyList(&sEarlyOutPolyList);
                  if (sEarlyOutPolyList.isEmpty() == false)
                     break;
               }
            }
            eopList = eopList->wLink.mNext;
         }
         if (sEarlyOutPolyList.isEmpty())
         {
            pos = end;
            break;
         }

         collisionMatrix.setColumn(3, pos);
         sBoxPolyhedron.buildBox(collisionMatrix, mObjBox, true);

         // Build extruded polyList...
         VectorF vector = end - pos;
         sExtrudedPolyList.extrude(sBoxPolyhedron, vector);
         sExtrudedPolyList.setVelocity(mVelocity);
         sExtrudedPolyList.setCollisionList(&collisionList);

         CollisionWorkingList& rList = mConvex.getWorkingList();
         CollisionWorkingList* pList = rList.wLink.mNext;
         while (pList != &rList) {
            if ((pList->mConvex->getObject()->getTypeMask() & mask) != 0)
            {
               Box3F convexBox = pList->mConvex->getBoundingBox();
               if (testBox.isOverlapped(convexBox))
               {
                  pList->mConvex->getPolyList(&sExtrudedPolyList);
               }
            }
            pList = pList->wLink.mNext;
         }

         if (collisionList.getTime() < 1.0)
         {
            // Set to collision point
            F32 dt = time * collisionList.getTime();
            pos += mVelocity * dt;
            time -= dt;

            // Pick the most resistant surface
            F32 bd = 0;
            const Collision* collision = 0;
            for (int c = 0; c < collisionList.getCount(); c++) {
               const Collision &cp = collisionList[c];
               F32 dot = -mDot(mVelocity,cp.normal);
               if (dot > bd) {
                  bd = dot;
                  collision = &cp;
               }
            }

            if (collision && mDataBlock->sticky && collision->object->getTypeMask() & (STATIC_COLLISION_TYPEMASK)) {
               mVelocity.set(0, 0, 0);
               mAtRest = true;
               mAtRestCounter = 0;
               stickyNotify = true;
               mStickyCollisionPos    = collision->point;
               mStickyCollisionNormal = collision->normal;
               break;
            } else {
               // Subtract out velocity into surface and friction
               if (collision) {
                  VectorF fv = mVelocity + collision->normal * bd;
                  F32 fvl = fv.len();
                  if (fvl) {
                     F32 ff = bd * mDataBlock->friction;
                     if (ff < fvl) {
                        fv *= ff / fvl;
                        fvl = ff;
                     }
                  }
                  bd *= 1 + mDataBlock->elasticity;
                  VectorF dv = collision->normal * (bd + 0.002);
                  mVelocity += dv;
                  mVelocity -= fv;

                  // Keep track of what we hit
                  contact = true;
                  U32 typeMask = collision->object->getTypeMask();
                  if (!(typeMask & StaticObjectType))
                     nonStatic = true;
                  if (isServerObject() && (typeMask & ShapeBaseObjectType)) {
                     ShapeBase* col = static_cast<ShapeBase*>(collision->object);
                     queueCollision(col,mVelocity - col->getVelocity());
                  }
               }
            }
         }
         else
         {
            pos = end;
            break;
         }
      }
      if (count == 3)
      {
         // Couldn't move...
         mVelocity.set(0, 0, 0);
      }
   }

   // If on the client, calculate delta for backstepping
   if (isGhost()) {
      delta.pos     = pos;
      delta.posVec -= pos;
      delta.dt = 1;
   }

   // Update transform
   MatrixF mat = mObjToWorld;
   mat.setColumn(3,pos);
   Parent::setTransform(mat);
   enableCollision();
   if (mCollisionObject)
      mCollisionObject->enableCollision();
   updateContainer();

   if ( mPhysicsRep )
      mPhysicsRep->setTransform( mat );

   //
   if (contact) {
      // Check for rest condition
      if (!nonStatic && mVelocity.len() < sAtRestVelocity) {
         mVelocity.x = mVelocity.y = mVelocity.z = 0;
         mAtRest = true;
         mAtRestCounter = 0;
      }

      // Only update the client if we hit a non-static shape or
      // if this is our final rest pos.
      if (nonStatic || mAtRest)
         setMaskBits(PositionMask);
   }

   // Collision callbacks. These need to be processed whether we hit
   // anything or not.
   if (!isGhost())
   {
      SimObjectPtr<Item> safePtr(this);
      if (stickyNotify)
      {
         notifyCollision();
         if(bool(safePtr))
			 onStickyCollision_callback( getIdString() );
      }
      else
         notifyCollision();

      // water
      if(bool(safePtr))
      {
         if(!mInLiquid && mWaterCoverage != 0.0f)
         {
            mInLiquid = true;
            if ( !isGhost() )
             mDataBlock->onEnterLiquid_callback( this, mWaterCoverage, mLiquidType.c_str() );
         }

         else if(mInLiquid && mWaterCoverage == 0.0f)
         {
            mInLiquid = false;
            if ( !isGhost() )
             mDataBlock->onLeaveLiquid_callback( this, mLiquidType.c_str() );
         }
      }
   }
}
Пример #6
0
//-----------------------------------------------------------------------------
//
// VActorPhysicsController::findGroundContact( pContactObject, pContactPoint, pContactNormal );
//
// ...
//
//-----------------------------------------------------------------------------
bool VActorPhysicsController::findGroundContact( SceneObject *&pContactObject, Point3F &pContactPoint, VectorF &pContactNormal )
{
    // Setup Collision List.
    static CollisionList sCollisionList;
    sCollisionList.clear();

    static Polyhedron       sBoxPolyhedron;
    static ExtrudedPolyList sExtrudedPolyList;

    // Fetch Max Step Height.
    const F32 stepHeight = mObject->getDataBlock()->getMaxStepHeight();

    // Determine Positions.
    const Point3F preTickPosition  = getPosition() + Point3F( 0.f, 0.f, stepHeight );
    const VectorF preTickVelocity  = getVelocity() + mGravity - VectorF( 0.f, 0.f, stepHeight / TickSec );
    const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec );
    const VectorF postTickVector   = postTickPosition - preTickPosition;

    // Construct Scaled Box.
    Box3F scaledBox = mObject->getObjBox();
    scaledBox.minExtents.convolve( mObject->getScale() );
    scaledBox.maxExtents.convolve( mObject->getScale() );

    // Setup Polyherdron.
    MatrixF collisionMatrix( true );
    collisionMatrix.setPosition( preTickPosition );
    sBoxPolyhedron.buildBox( collisionMatrix, scaledBox, true );

    // Setup Extruded Poly List.
    sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector );
    sExtrudedPolyList.setVelocity( preTickVelocity );
    sExtrudedPolyList.setCollisionList( &sCollisionList );

    // Construct World Convex Box & Adjust for Sweep.
    Box3F convexBox = scaledBox;
    getTransform().mul( convexBox );
    convexBox.minExtents += postTickVector;
    convexBox.maxExtents += postTickVector;

    // Build List of Contacts.
    CollisionWorkingList &rList = mConvex.getWorkingList();
    for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext )
    {
        Convex *convexShape = pList->mConvex;

        // Ground Object?
        if ( !( convexShape->getObject()->getTypeMask() & sGroundCollisionMask ) )
        {
            // No, Continue.
            continue;
        }

        // Overlap?
        const Box3F &collisionConvexBox = convexShape->getBoundingBox();
        if ( convexBox.isOverlapped( collisionConvexBox ) )
        {
            // Build Contact Information.
            convexShape->getPolyList( &sExtrudedPolyList );
        }
    }

    // Valid Collision?
    if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() < 0.f || sCollisionList.getTime() > 1.f )
    {
        // No, Quit Now.
        return false;
    }

    // Use First Collision.
    Collision *collision = &sCollisionList[0];

    // More Collisions?
    if ( sCollisionList.getCount() > 1 )
    {
        // Check for Better Contacts.
        for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ )
        {
            if ( cp->faceDot > collision->faceDot )
            {
                // Use this One.
                collision = cp;
            }
        }
    }

    // Set Properties.
    pContactObject = collision->object;
    //pContactPoint  = collision->point;
    pContactPoint  = ( preTickPosition + ( preTickVelocity * TickSec * sCollisionList.getTime() ) );
    pContactNormal = collision->normal;

    // Valid Contact.
    return true;
}
Пример #7
0
//-----------------------------------------------------------------------------
//
// VActorPhysicsController::findCollision( pCollision );
//
// ...
//
//-----------------------------------------------------------------------------
bool VActorPhysicsController::findCollision( Collision *&pCollision )
{
    // Setup Collision List.
    static CollisionList sCollisionList;
    sCollisionList.clear();

    static Polyhedron       sBoxPolyhedron;
    static ExtrudedPolyList sExtrudedPolyList;

    // Determine Positions.
    const Point3F preTickPosition  = getPosition();
    const VectorF preTickVelocity  = getVelocity();
    const Point3F postTickPosition = preTickPosition + ( preTickVelocity * TickSec );
    const VectorF postTickVector   = postTickPosition - preTickPosition;

    // Construct Scaled Box.
    Box3F scaledBox = mObject->getObjBox();
    scaledBox.minExtents.convolve( mObject->getScale() );
    scaledBox.maxExtents.convolve( mObject->getScale() );

    // Setup Polyherdron.
    MatrixF collisionMatrix( true );
    collisionMatrix.setPosition( preTickPosition );
    sBoxPolyhedron.buildBox( collisionMatrix, scaledBox );

    // Setup Extruded Poly List.
    sExtrudedPolyList.extrude( sBoxPolyhedron, postTickVector );
    sExtrudedPolyList.setVelocity( preTickVelocity );
    sExtrudedPolyList.setCollisionList( &sCollisionList );

    // Construct World Convex Box & Adjust for Sweep.
    Box3F convexBox = scaledBox;
    getTransform().mul( convexBox );
    convexBox.minExtents += postTickVector;
    convexBox.maxExtents += postTickVector;

    // Determine the Collision Mask.
    const U32 collisionMask = ( isInWater() ) ? ( sGroundCollisionMask | sMoveCollisionMask ) : sMoveCollisionMask;

    // Build List of Contacts.
    CollisionWorkingList &rList = mConvex.getWorkingList();
    for ( CollisionWorkingList *pList = rList.wLink.mNext; pList != &rList; pList = pList->wLink.mNext )
    {
        Convex *convexShape = pList->mConvex;

        // Valid Collision Target?
        if ( !( convexShape->getObject()->getTypeMask() & collisionMask ) )
        {
            // No, Continue.
            continue;
        }

        // Overlap?
        const Box3F &collisionConvexBox = convexShape->getBoundingBox();
        if ( convexBox.isOverlapped( collisionConvexBox ) )
        {
            // Build Contact Information.
            convexShape->getPolyList( &sExtrudedPolyList );
        }
    }

    // Valid Collision?
    if ( sCollisionList.getCount() == 0 || sCollisionList.getTime() > 1.f )
    {
        // No, Quit Now.
        return false;
    }

    // Use First Collision.
    Collision *collision = &sCollisionList[0];

    // More Collisions?
    if ( sCollisionList.getCount() > 1 )
    {
        // Check for Better Contacts.
        for ( Collision *cp = ( collision + 1 ); cp != ( collision + sCollisionList.getCount() ); cp++ )
        {
            if ( cp->faceDot > collision->faceDot )
            {
                // Use this One.
                collision = cp;
            }
        }
    }

    // Store Reference.
    pCollision = collision;

    // Valid Collision.
    return true;
}
Пример #8
0
bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) {
    if (_collisionFlags & COLLISION_GROUP_PARTICLES) {
        return false;
    }
    bool collided = false;
    // first do the hand collisions
    const HandData* handData = getHandData();
    if (handData) {
        for (int i = 0; i < NUM_HANDS; i++) {
            const PalmData* palm = handData->getPalm(i);
            if (palm && palm->hasPaddle()) {
                // create a disk collision proxy where the hand is
                glm::vec3 fingerAxis(0.f);
                for (size_t f = 0; f < palm->getNumFingers(); ++f) {
                    const FingerData& finger = (palm->getFingers())[f];
                    if (finger.isActive()) {
                        // compute finger axis
                        glm::vec3 fingerTip = finger.getTipPosition();
                        glm::vec3 fingerRoot = finger.getRootPosition();
                        fingerAxis = glm::normalize(fingerTip - fingerRoot);
                        break;
                    }
                }

                int jointIndex = -1;
                glm::vec3 handPosition;
                if (i == 0) {
                    _skeletonModel.getLeftHandPosition(handPosition);
                    jointIndex = _skeletonModel.getLeftHandJointIndex();
                }
                else {
                    _skeletonModel.getRightHandPosition(handPosition);
                    jointIndex = _skeletonModel.getRightHandJointIndex();
                }
                glm::vec3 diskCenter = handPosition + HAND_PADDLE_OFFSET * fingerAxis;
                glm::vec3 diskNormal = palm->getNormal();
                const float DISK_THICKNESS = 0.08f;

                // collide against the disk
                glm::vec3 penetration;
                if (findSphereDiskPenetration(particleCenter, particleRadius, 
                            diskCenter, HAND_PADDLE_RADIUS, DISK_THICKNESS, diskNormal,
                            penetration)) {
                    CollisionInfo* collision = collisions.getNewCollision();
                    if (collision) {
                        collision->_type = PADDLE_HAND_COLLISION;
                        collision->_flags = jointIndex;
                        collision->_penetration = penetration;
                        collision->_addedVelocity = palm->getVelocity();
                        collided = true;
                    } else {
                        // collisions are full, so we might as well bail now
                        return collided;
                    }
                }
            }
        }
    }
    // then collide against the models
    int preNumCollisions = collisions.size();
    if (_skeletonModel.findSphereCollisions(particleCenter, particleRadius, collisions)) {
        // the Model doesn't have velocity info, so we have to set it for each new collision
        int postNumCollisions = collisions.size();
        for (int i = preNumCollisions; i < postNumCollisions; ++i) {
            CollisionInfo* collision = collisions.getCollision(i);
            collision->_penetration /= (float)(TREE_SCALE);
            collision->_addedVelocity = getVelocity();
        }
        collided = true;
    }
    return collided;
}
Пример #9
0
Point3F Etherform::_move( const F32 travelTime, Collision *outCol )
{
   // Try and move to new pos
   F32 totalMotion  = 0.0f;
   
   // TODO: not used?
   //F32 initialSpeed = mVelocity.len();

   Point3F start;
   Point3F initialPosition;
   getTransform().getColumn(3,&start);
   initialPosition = start;

   static CollisionList collisionList;
   static CollisionList physZoneCollisionList;

   collisionList.clear();
   physZoneCollisionList.clear();

   MatrixF collisionMatrix(true);
   collisionMatrix.setColumn(3, start);

   VectorF firstNormal(0.0f, 0.0f, 0.0f);
   F32 time = travelTime;
   U32 count = 0;

   static Polyhedron sBoxPolyhedron;
   static ExtrudedPolyList sExtrudedPolyList;
   static ExtrudedPolyList sPhysZonePolyList;

   for (; count < sMoveRetryCount; count++) {
      F32 speed = mVelocity.len();
      if(!speed)
         break;

      Point3F end = start + mVelocity * time;
      Point3F distance = end - start;

      if (mFabs(distance.x) < mObjBox.len_x() &&
          mFabs(distance.y) < mObjBox.len_y() &&
          mFabs(distance.z) < mObjBox.len_z())
      {
         // We can potentially early out of this.  If there are no polys in the clipped polylist at our
         //  end position, then we can bail, and just set start = end;
         Box3F wBox = mScaledBox;
         wBox.minExtents += end;
         wBox.maxExtents += end;

         static EarlyOutPolyList eaPolyList;
         eaPolyList.clear();
         eaPolyList.mNormal.set(0.0f, 0.0f, 0.0f);
         eaPolyList.mPlaneList.clear();
         eaPolyList.mPlaneList.setSize(6);
         eaPolyList.mPlaneList[0].set(wBox.minExtents,VectorF(-1.0f, 0.0f, 0.0f));
         eaPolyList.mPlaneList[1].set(wBox.maxExtents,VectorF(0.0f, 1.0f, 0.0f));
         eaPolyList.mPlaneList[2].set(wBox.maxExtents,VectorF(1.0f, 0.0f, 0.0f));
         eaPolyList.mPlaneList[3].set(wBox.minExtents,VectorF(0.0f, -1.0f, 0.0f));
         eaPolyList.mPlaneList[4].set(wBox.minExtents,VectorF(0.0f, 0.0f, -1.0f));
         eaPolyList.mPlaneList[5].set(wBox.maxExtents,VectorF(0.0f, 0.0f, 1.0f));

         // Build list from convex states here...
         CollisionWorkingList& rList = mConvex.getWorkingList();
         CollisionWorkingList* pList = rList.wLink.mNext;
         while (pList != &rList) {
            Convex* pConvex = pList->mConvex;
            if (pConvex->getObject()->getTypeMask() & sCollisionMoveMask) {
               Box3F convexBox = pConvex->getBoundingBox();
               if (wBox.isOverlapped(convexBox))
               {
                  // No need to separate out the physical zones here, we want those
                  //  to cause a fallthrough as well...
                  pConvex->getPolyList(&eaPolyList);
               }
            }
            pList = pList->wLink.mNext;
         }

         if (eaPolyList.isEmpty())
         {
            totalMotion += (end - start).len();
            start = end;
            break;
         }
      }

      collisionMatrix.setColumn(3, start);
      sBoxPolyhedron.buildBox(collisionMatrix, mScaledBox, true);

      // Setup the bounding box for the extrudedPolyList
      Box3F plistBox = mScaledBox;
      collisionMatrix.mul(plistBox);
      Point3F oldMin = plistBox.minExtents;
      Point3F oldMax = plistBox.maxExtents;
      plistBox.minExtents.setMin(oldMin + (mVelocity * time) - Point3F(0.1f, 0.1f, 0.1f));
      plistBox.maxExtents.setMax(oldMax + (mVelocity * time) + Point3F(0.1f, 0.1f, 0.1f));

      // Build extruded polyList...
      VectorF vector = end - start;
      sExtrudedPolyList.extrude(sBoxPolyhedron,vector);
      sExtrudedPolyList.setVelocity(mVelocity);
      sExtrudedPolyList.setCollisionList(&collisionList);

      sPhysZonePolyList.extrude(sBoxPolyhedron,vector);
      sPhysZonePolyList.setVelocity(mVelocity);
      sPhysZonePolyList.setCollisionList(&physZoneCollisionList);

      // Build list from convex states here...
      CollisionWorkingList& rList = mConvex.getWorkingList();
      CollisionWorkingList* pList = rList.wLink.mNext;
      while (pList != &rList) {
         Convex* pConvex = pList->mConvex;
         if (pConvex->getObject()->getTypeMask() & sCollisionMoveMask) {
            Box3F convexBox = pConvex->getBoundingBox();
            if (plistBox.isOverlapped(convexBox))
            {
               if (pConvex->getObject()->getTypeMask() & PhysicalZoneObjectType)
                  pConvex->getPolyList(&sPhysZonePolyList);
               else
                  pConvex->getPolyList(&sExtrudedPolyList);
            }
         }
         pList = pList->wLink.mNext;
      }

      // Take into account any physical zones...
      for (U32 j = 0; j < physZoneCollisionList.getCount(); j++) 
      {
         AssertFatal(dynamic_cast<PhysicalZone*>(physZoneCollisionList[j].object), "Bad phys zone!");
         const PhysicalZone* pZone = (PhysicalZone*)physZoneCollisionList[j].object;
         if (pZone->isActive())
            mVelocity *= pZone->getVelocityMod();
      }

      if (collisionList.getCount() != 0 && collisionList.getTime() < 1.0f) 
      {
         // Set to collision point
         F32 velLen = mVelocity.len();

         F32 dt = time * getMin(collisionList.getTime(), 1.0f);
         start += mVelocity * dt;
         time -= dt;

         totalMotion += velLen * dt;

         // Back off...
         if ( velLen > 0.f ) {
            F32 newT = getMin(0.01f / velLen, dt);
            start -= mVelocity * newT;
            totalMotion -= velLen * newT;
         }

         // Pick the surface most parallel to the face that was hit.
         const Collision *collision = &collisionList[0];
         const Collision *cp = collision + 1;
         const Collision *ep = collision + collisionList.getCount();
         for (; cp != ep; cp++)
         {
            if (cp->faceDot > collision->faceDot)
               collision = cp;
         }

         F32 bd = -mDot(mVelocity, collision->normal);

         // Copy this collision out so
         // we can use it to do impacts
         // and query collision.
         *outCol = *collision;

         // Subtract out velocity
         VectorF dv = collision->normal * (bd + sNormalElasticity);
         mVelocity += dv;
         if (count == 0)
         {
            firstNormal = collision->normal;
         }
         else
         {
            if (count == 1)
            {
               // Re-orient velocity along the crease.
               if (mDot(dv,firstNormal) < 0.0f &&
                   mDot(collision->normal,firstNormal) < 0.0f)
               {
                  VectorF nv;
                  mCross(collision->normal,firstNormal,&nv);
                  F32 nvl = nv.len();
                  if (nvl)
                  {
                     if (mDot(nv,mVelocity) < 0.0f)
                        nvl = -nvl;
                     nv *= mVelocity.len() / nvl;
                     mVelocity = nv;
                  }
               }
            }
         }
      }
      else
      {
         totalMotion += (end - start).len();
         start = end;
         break;
      }
   }

   if (count == sMoveRetryCount)
   {
      // Failed to move
      start = initialPosition;
      mVelocity.set(0.0f, 0.0f, 0.0f);
   }

   return start;
}