⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 item.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
      {
         // Need to clear out last updatePos or warp interpolation
         delta.posVec.set(0,0,0);
      }
   }
}

void Item::interpolateTick(F32 dt)
{
   // Client side interpolation
   Parent::interpolateTick(dt);
   Point3F pos = delta.pos + delta.posVec * dt;
   MatrixF mat = mObjToWorld;
   mat.setColumn(3,pos);
   Parent::setRenderTransform(mat);
   delta.dt = dt;
}


//----------------------------------------------------------------------------

void Item::setTransform(const MatrixF& mat)
{
   Point3F pos;
   mat.getColumn(3,&pos);
   MatrixF tmat;
   if (!mRotate) 
   {
      // Forces all rotation to be around the z axis
      VectorF vec;
      mat.getColumn(1,&vec);
      tmat.set(EulerF(0,0,-mAtan(-vec.x,vec.y)));
   }
   else
      tmat.identity();
   tmat.setColumn(3,pos);
   Parent::setTransform(tmat);
   if (!mStatic)
   {
      mAtRest = false;
      mAtRestCounter = 0;
   }
   setMaskBits(RotationMask | PositionMask | NoWarpMask);
}


//----------------------------------------------------------------------------
void Item::updateWorkingCollisionSet(const U32 mask, const F32 dt)
{
   // It is assumed that we will never accelerate more than 10 m/s for gravity...
   //
   Point3F scaledVelocity = mVelocity * dt;
   F32 len    = scaledVelocity.len();
   F32 newLen = len + (10 * dt);

   // Check to see if it is actually necessary to construct the new working list,
   //  or if we can use the cached version from the last query.  We use the x
   //  component of the min member of the mWorkingQueryBox, which is lame, but
   //  it works ok.
   bool updateSet = false;

   Box3F convexBox = mConvex.getBoundingBox(getTransform(), getScale());
   F32 l = (newLen * 1.1) + 0.1;  // from Convex::updateWorkingList
   convexBox.min -= Point3F(l, l, l);
   convexBox.max += Point3F(l, l, l);

   // Check containment
   {
      if (mWorkingQueryBox.min.x != -1e9)
      {
         if (mWorkingQueryBox.isContained(convexBox) == false)
         {
            // Needed region is outside the cached region.  Update it.
            updateSet = true;
         }
         else
         {
            // We can leave it alone, we're still inside the cached region
         }
      }
      else
      {
         // Must update
         updateSet = true;
      }
   }

   // Actually perform the query, if necessary
   if (updateSet == true)
   {
      mWorkingQueryBox = convexBox;
      mWorkingQueryBox.min -= Point3F(2 * l, 2 * l, 2 * l);
      mWorkingQueryBox.max += Point3F(2 * l, 2 * l, 2 * l);

      disableCollision();
      if (mCollisionObject)
         mCollisionObject->disableCollision();

      mConvex.updateWorkingList(mWorkingQueryBox, mask);

      if (mCollisionObject)
         mCollisionObject->enableCollision();
      enableCollision();
   }
}

void Item::updateVelocity(const F32 dt)
{
   // Acceleration due to gravity
   mVelocity.z += (mGravity * mDataBlock->gravityMod) * dt;
   F32 len;
   if (mDataBlock->maxVelocity > 0 && (len = mVelocity.len()) > (mDataBlock->maxVelocity * 1.05)) 
   {
      Point3F excess = mVelocity * (1.0 - (mDataBlock->maxVelocity / len ));
      excess *= 0.1;
      mVelocity -= excess;
   }

   // Container buoyancy & drag
   mVelocity.z -= mBuoyancy * (mGravity * mDataBlock->gravityMod * mGravityMod) * dt;
   mVelocity   -= mVelocity * mDrag * dt;
}


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.min.x + mObjBox.max.x) * 0.5,
                     (mObjBox.min.y + mObjBox.max.y) * 0.5,
                     mObjBox.max.z);
   Point3F endCast((mObjBox.min.x + mObjBox.max.x) * 0.5,
                   (mObjBox.min.y + mObjBox.max.y) * 0.5,
                   mObjBox.min.z);
   collisionMatrix.setColumn(3, pos);
   collisionMatrix.mulP(startCast);
   collisionMatrix.setColumn(3, end);
   collisionMatrix.mulP(endCast);
   RayInfo rinfo;
   bool doToughCollision = true;
   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->getType() & (InteriorObjectType|TerrainObjectType)) 
         {
            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());
            }
         }
      }
   }
   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.min;
         Point3F oldMax = testBox.max;
         testBox.min.setMin(oldMin + (mVelocity * time));
         testBox.max.setMin(oldMax + (mVelocity * time));

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

         CollisionWorkingList& eorList = mConvex.getWorkingList();
         CollisionWorkingList* eopList = eorList.wLink.mNext;
         while (eopList != &eorList) 
         {
            if ((eopList->mConvex->getObject()->getType() & 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);

         // 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()->getType() & mask) != 0)
            {
               Box3F convexBox = pList->mConvex->getBoundingBox();
               if (testBox.isOverlapped(convexBox))
               {
                  pList->mConvex->getPolyList(&sExtrudedPolyList);
               }
            }
            pList = pList->wLink.mNext;
         }

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

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

            if (collision && mDataBlock->sticky && 
               collision->object->getType() & (InteriorObjectType|TerrainObjectType)) 
            {
               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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -