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

📄 item.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
   MatrixF mat = mObjToWorld;
   mat.setColumn(3,pos);
   Parent::setTransform(mat);
   enableCollision();
   if (mCollisionObject)
      mCollisionObject->enableCollision();
   updateContainer();

   //
   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.
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (!isGhost())
#endif
   {
      SimObjectPtr<Item> safePtr(this);
      if (stickyNotify)
      {
         notifyCollision();
         if(bool(safePtr))
            Con::executef(mDataBlock, 2, "onStickyCollision", scriptThis());
      }
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
      else
         notifyCollision();
#endif

      // water
      if(bool(safePtr))
      {
         if(!mInLiquid && mWaterCoverage != 0.0f)
         {
            Con::executef(mDataBlock,4,"onEnterLiquid",scriptThis(), Con::getFloatArg(mWaterCoverage), Con::getIntArg(mLiquidType));
            mInLiquid = true;
         }
         else if(mInLiquid && mWaterCoverage == 0.0f)
         {
            Con::executef(mDataBlock,3,"onLeaveLiquid",scriptThis(), Con::getIntArg(mLiquidType));
            mInLiquid = false;
         }
      }
   }
}


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

static MatrixF IMat(1);

bool Item::buildPolyList(AbstractPolyList* polyList, const Box3F&, const SphereF&)
{
   // Collision with the item is always against the item's object
   // space bounding box axis aligned in world space.
   Point3F pos;
   mObjToWorld.getColumn(3,&pos);
   IMat.setColumn(3,pos);
   polyList->setTransform(&IMat, mObjScale);
   polyList->setObject(this);
   polyList->addBox(mObjBox);
   return true;
}


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

U32 Item::packUpdate(NetConnection *connection, U32 mask, BitStream *stream)
{
   U32 retMask = Parent::packUpdate(connection,mask,stream);

   if (stream->writeFlag(mask & InitialUpdateMask)) 
   {
      stream->writeFlag(mRotate);
      stream->writeFlag(mStatic);
      stream->writeFlag(mCollidable);
      if (stream->writeFlag(getScale() != Point3F(1, 1, 1)))
         mathWrite(*stream, getScale());
   }

   if (mask & ThrowSrcMask && mCollisionObject) 
   {
      S32 gIndex = connection->getGhostIndex(mCollisionObject);
      if (stream->writeFlag(gIndex != -1))
         stream->writeInt(gIndex,GhostConnection::GhostIdBitSize);
   }
   else
      stream->writeFlag(false);

   if (stream->writeFlag(mask & RotationMask && !mRotate)) 
   {
      // Assumes rotation is about the Z axis
      AngAxisF aa(mObjToWorld);
      stream->writeFlag(aa.axis.z < 0);
      stream->write(aa.angle);
   }

   if (stream->writeFlag(mask & PositionMask)) 
   {
      Point3F pos;
      mObjToWorld.getColumn(3,&pos);
      mathWrite(*stream, pos);
      if (!stream->writeFlag(mAtRest))
         mathWrite(*stream, mVelocity);

      stream->writeFlag(!(mask & NoWarpMask));
   }

   return retMask;
}

void Item::unpackUpdate(NetConnection *connection, BitStream *stream)
{
   Parent::unpackUpdate(connection,stream);

   if (stream->readFlag())
   {
      mRotate = stream->readFlag();
      mStatic = stream->readFlag();
      mCollidable = stream->readFlag();
      if (stream->readFlag())
         mathRead(*stream, &mObjScale);
      else
         mObjScale.set(1, 1, 1);
   }

   if (stream->readFlag())
   {
      S32 gIndex = stream->readInt(GhostConnection::GhostIdBitSize);
      setCollisionTimeout(static_cast<ShapeBase*>(connection->resolveGhost(gIndex)));
   }

   MatrixF mat = mObjToWorld;
   if (stream->readFlag())
   {
      // Assumes rotation is about the Z axis
      AngAxisF aa;
      aa.axis.set(0,0,stream->readFlag()? -1: 1);
      stream->read(&aa.angle);
      aa.setMatrix(&mat);

      Point3F pos;
      mObjToWorld.getColumn(3,&pos);
      mat.setColumn(3,pos);
   }

   if (stream->readFlag())
   {
      Point3F pos;
      mathRead(*stream, &pos);
      F32 speed = mVelocity.len();
      if ((mAtRest = stream->readFlag()) == true)
         mVelocity.set(0,0,0);
      else
         mathRead(*stream, &mVelocity);

      if (stream->readFlag() && isProperlyAdded())
      {
         // Determine number of ticks to warp based on the average
         // of the client and server velocities.
         delta.warpOffset = pos - delta.pos;
         F32 as = (speed + mVelocity.len()) * 0.5 * TickSec;
         F32 dt = (as > 0.00001f) ? delta.warpOffset.len() / as: sMaxWarpTicks;
         delta.warpTicks = (S32)((dt > sMinWarpTicks)? getMax(mFloor(dt + 0.5), 1.0f): 0.0f);

         if (delta.warpTicks)
         {
            // Setup the warp to start on the next tick, only the
            // object's position is warped.
            if (delta.warpTicks > sMaxWarpTicks)
               delta.warpTicks = sMaxWarpTicks;
            delta.warpOffset /= delta.warpTicks;
         }
         else
         {
            // Going to skip the warp, server and client are real close.
            // Adjust the frame interpolation to move smoothly to the
            // new position within the current tick.
            Point3F cp = delta.pos + delta.posVec * delta.dt;
            VectorF vec = delta.pos - cp;
            F32 vl = vec.len();
            if (vl)
            {
               F32 s = delta.posVec.len() / vl;
               delta.posVec = (cp - pos) * s;
            }
            delta.pos = pos;
            mat.setColumn(3,pos);
         }
      }
      else
      {
         // Set the item to the server position
         delta.warpTicks = 0;
         delta.posVec.set(0,0,0);
         delta.pos = pos;
         delta.dt = 0;
         mat.setColumn(3,pos);
      }
   }

   Parent::setTransform(mat);
}

ConsoleMethod(Item, isStatic, bool, 2, 2, "()"
              "Is the object static (ie, non-movable)?")
{
   return object->isStatic();
}

ConsoleMethod(Item, isRotating, bool, 2, 2, "()"
              "Is the object still rotating?")
{
   return object->isRotating();
}

ConsoleMethod(Item, setCollisionTimeout, bool, 3, 3, "(ShapeBase obj)"
              "Temporarily disable collisions against obj.")
{
   ShapeBase* source;
   if (Sim::findObject(dAtoi(argv[2]),source))
   {
      object->setCollisionTimeout(source);
      return true;
   }

   return false;
}

ConsoleMethod( Item, getLastStickyPos, const char *, 2, 2, "()"
              "Get the position on the surface on which the object is stuck.")
{
   char* ret = Con::getReturnBuffer(256);
   if (object->isServerObject())
      dSprintf(ret, 255, "%g %g %g",
               object->mStickyCollisionPos.x,
               object->mStickyCollisionPos.y,
               object->mStickyCollisionPos.z);
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsServerObject
   else
      dStrcpy(ret, "0 0 0");
#endif

   return ret;
}

ConsoleMethod( Item, getLastStickyNormal, const char *, 2, 2, "()"
              "Get the normal of the surface on which the object is stuck.")
{
   char* ret = Con::getReturnBuffer(256);
   if (object->isServerObject())
      dSprintf(ret, 255, "%g %g %g",
               object->mStickyCollisionNormal.x,
               object->mStickyCollisionNormal.y,
               object->mStickyCollisionNormal.z);
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsServerObject
   else
      dStrcpy(ret, "0 0 0");
#endif

   return ret;
}

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

void Item::initPersistFields()
{
   Parent::initPersistFields();

   addGroup("Misc");
   addDepricatedField("collideable");
   addField("collidable",  TypeBool, Offset(mCollidable, Item));
   addField("static",      TypeBool, Offset(mStatic, Item));
   addField("rotate",      TypeBool, Offset(mRotate, Item));
   endGroup("Misc");
}

void Item::consoleInit()
{
   Con::addVariable("Item::minWarpTicks",TypeF32,&sMinWarpTicks);
   Con::addVariable("Item::maxWarpTicks",TypeS32,&sMaxWarpTicks);
}

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

bool Item::prepRenderImage(SceneState* state,
                           const U32   stateKey,
                           const U32   startZone,
                           const bool  modifyBaseState)
{
   // Items do NOT render if destroyed
   if (getDamageState() == Destroyed)
      return false;

   return Parent::prepRenderImage(state, stateKey, startZone, modifyBaseState);
}


void Item::renderImage(SceneState* state, SceneRenderImage* image)
{
   // Client side rotation
   if (mRotate)
   {
      F32 t = Sim::getCurrentTime() * F32(1)/1000;
      F32 r = (t / sRotationSpeed) * M_2PI;
      Point3F pos;
      mRenderObjToWorld.getColumn(3,&pos);
      MatrixF mat = mRenderObjToWorld;
      mat.set(Point3F(0,0,r));
      mat.setColumn(3,pos);
      Parent::setRenderTransform(mat);
   }

   Parent::renderImage(state, image);

   if (mShadow)
   {
      mShadow->setMoving(!mAtRest);
      mShadow->setAnimating(!mAtRest && !mRotate);
   }
}


void Item::buildConvex(const Box3F& box, Convex* convex)
{
   if (mShapeInstance == NULL)
      return;

   // These should really come out of a pool
   mConvexList->collectGarbage();

   if (box.isOverlapped(getWorldBox()) == false)
      return;

   // Just return a box convex for the entire shape...
   Convex* cc = 0;
   CollisionWorkingList& wl = convex->getWorkingList();
   for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
   {
      if (itr->mConvex->getType() == BoxConvexType &&
          itr->mConvex->getObject() == this)
      {
         cc = itr->mConvex;
         break;
      }
   }
   if (cc)
      return;

   // Create a new convex.
   BoxConvex* cp = new BoxConvex;
   mConvexList->registerObject(cp);
   convex->addToWorkingList(cp);
   cp->init(this);

   mObjBox.getCenter(&cp->mCenter);
   cp->mSize.x = mObjBox.len_x() / 2.0f;
   cp->mSize.y = mObjBox.len_y() / 2.0f;
   cp->mSize.z = mObjBox.len_z() / 2.0f;
}

⌨️ 快捷键说明

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