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

📄 interiorinstance.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:

      if (pDetail->mMinPixels < projRadius)
      {
         final = i;
         break;
      }
   }

   // Ok, that's it.
   return final;
}


//--------------------------------------------------------------------------
bool InteriorInstance::prepRenderImage(SceneState* state,   const U32 stateKey,
                                       const U32 startZone, const bool modifyBaseState)
{
   if (isLastState(state, stateKey))
      return false;

   PROFILE_START(InteriorPrepRenderImage);

   setLastState(state, stateKey);

   U32 realStartZone;
   if (startZone != 0xFFFFFFFF)
   {
      AssertFatal(startZone != 0, "Hm.  This really shouldn't happen.  Should only get inside zones here");
      AssertFatal(isManagingZones(), "Must be managing zones if we're here...");

      realStartZone = startZone - mZoneRangeStart + 1;
   }
   else
   {
      realStartZone = getPointZone(state->getCameraPosition());
      if (realStartZone != 0)
         realStartZone = realStartZone - mZoneRangeStart + 1;
   }

   bool render = true;
   if (modifyBaseState == false)
   {
      // Regular query.  We only return a render zone if our parent zone is rendered.
      //  Otherwise, we always render
      if (state->isObjectRendered(this) == false)
      {
         PROFILE_END();
         return false;
      }
   }
   else
   {
      if (mShowTerrainInside == true)
         state->enableTerrainOverride();
   }

   U32 detailLevel = 0;
   if (startZone == 0xFFFFFFFF)
      detailLevel = calcDetailLevel(state, state->getCameraPosition());

   if (!Interior::smUseVertexLighting)
   {
      // Since we're rendering: update the lights and the alarm state
      U32 msSinceLightsUpdated = Platform::getVirtualMilliseconds() - getLightUpdatedTime();
      if (msSinceLightsUpdated > smLightUpdatePeriod)
      {
         setLightUpdatedTime(Platform::getVirtualMilliseconds());
         updateAllLights(msSinceLightsUpdated);
      }
   }

   U32 baseZoneForPrep = getCurrZone(0);
   bool multipleZones = false;
   if (getNumCurrZones() > 1)
   {
      U32 numRenderedZones = 0;
      baseZoneForPrep = 0xFFFFFFFF;
      for (U32 i = 0; i < getNumCurrZones(); i++)
      {
         if (state->getZoneState(getCurrZone(i)).render == true)
         {
            numRenderedZones++;
            if (baseZoneForPrep == 0xFFFFFFFF)
               baseZoneForPrep = getCurrZone(i);
         }
      }

      if (numRenderedZones > 1)
         multipleZones = true;
   }

   bool continueOut = mInteriorRes->getDetailLevel(0)->prepRender(state,
                                                                  baseZoneForPrep,
                                                                  realStartZone, mZoneRangeStart,
                                                                  mRenderObjToWorld, mObjScale,
                                                                  modifyBaseState & !smDontRestrictOutside,
                                                                  smDontRestrictOutside | multipleZones,
                                                                  state->mFlipCull);
   if (smDontRestrictOutside)
      continueOut = true;

   InteriorRenderImage* image = new InteriorRenderImage;
   image->obj = this;
   image->mDetailLevel = detailLevel;
   image->mBaseZone    = realStartZone;
   image->textureSortKey = mInteriorFileHash;
   state->insertRenderImage(image);

   // Add renderimages for any sub-objects, first the independant subs, then the dependants
   //  for this detail...
   Point3F osPoint = state->getCameraPosition();
   mRenderWorldToObj.mulP(osPoint);
   osPoint.convolveInverse(mObjScale);

   U32 i;
   for (i = 0; i < mInteriorSubObjects[0].size(); i++)
   {
      InteriorSubObject* iso = (mInteriorSubObjects[0])[i];

      if (iso->renderDetailDependant() == false)
      {
         // We want to check the zone that this object is in.  If we are traversing upwards
         //  though, we have no information about our parent zone, and must return the
         //  render image regardless.
         if (modifyBaseState && iso->getZone() == 0)
         {
            // Must return
         }
         else
         {
            U32 realZone;
            if (iso->getZone() == 0)
               realZone = getCurrZone(0);
            else
               realZone = iso->getZone() + mZoneRangeStart - 1;

            if (state->getZoneState(realZone).render == false)
            {
               // Nuke it...
               continue;
            }
         }

         //  Register the render image, if any, for this ISO.
         SubObjectRenderImage* sri = iso->getRenderImage(state, osPoint);
         if (sri)
         {
            sri->mDetailLevel = 0;
            state->insertRenderImage(sri);
         }
      }
   }

   //  Condier any ISOs from the current LOD.
   for (i = 0; i < mInteriorSubObjects[detailLevel].size(); i++)
   {
      InteriorSubObject* iso = (mInteriorSubObjects[detailLevel])[i];

      if (iso->renderDetailDependant() == true)
      {
         // We want to check the zone that this object is in.  If we are traversing upwards
         //  though, we have no information about our parent zone, and must return the
         //  render image regardless.
         if (modifyBaseState && iso->getZone() == 0)
         {
            // Must return
         }
         else
         {
            U32 realZone;
            if (iso->getZone() == 0)
               realZone = getCurrZone(0);
            else
               realZone = iso->getZone() + mZoneRangeStart - 1;

            if (state->getZoneState(realZone).render == false)
            {
               // Nuke it...
               continue;
            }
         }

         SubObjectRenderImage* sri = iso->getRenderImage(state, osPoint);
         if (sri)
         {
            sri->mDetailLevel = detailLevel;
            state->insertRenderImage(sri);
         }
      }
   }

   PROFILE_END();
   return continueOut;
}


//--------------------------------------------------------------------------
bool InteriorInstance::castRay(const Point3F& s, const Point3F& e, RayInfo* info)
{
   info->object = this;
   return mInteriorRes->getDetailLevel(0)->castRay(s, e, info);
}


//------------------------------------------------------------------------------
void InteriorInstance::setTransform(const MatrixF & mat)
{
   Parent::setTransform(mat);

   // Since the interior is a static object, it's render transform changes 1 to 1
   //  with it's collision transform
   setRenderTransform(mat);

   // Notify subobjects that care about the transform change...
   if (bool(mInteriorRes))
   {
      for (U32 i = 0; i < mInteriorSubObjects.size(); i++)
      {
         for (U32 j = 0; j < mInteriorSubObjects[i].size(); j++)
            (mInteriorSubObjects[i])[j]->noteTransformChange();
      }
   }

   if (isServerObject())
      setMaskBits(TransformMask);
}


//------------------------------------------------------------------------------
bool InteriorInstance::buildPolyList(AbstractPolyList* list, const Box3F& wsBox, const SphereF&)
{
   if (bool(mInteriorRes) == false)
      return false;

   // Setup collision state data
   list->setTransform(&getTransform(), getScale());
   list->setObject(this);

   return mInteriorRes->getDetailLevel(0)->buildPolyList(list, wsBox, mWorldToObj, getScale());
}



void InteriorInstance::buildConvex(const Box3F& box, Convex* convex)
{
   if (bool(mInteriorRes) == false)
      return;

   mConvexList->collectGarbage();

   Box3F realBox = box;
   mWorldToObj.mul(realBox);
   realBox.min.convolveInverse(mObjScale);
   realBox.max.convolveInverse(mObjScale);

   if (realBox.isOverlapped(getObjBox()) == false)
      return;

   U32 waterMark = FrameAllocator::getWaterMark();

   if ((convex->getObject()->getType() & VehicleObjectType) &&
       mInteriorRes->getDetailLevel(0)->mVehicleConvexHulls.size() > 0)
   {
      // Can never have more hulls than there are hulls in the interior...
      U16* hulls = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mVehicleConvexHulls.size() * sizeof(U16));
      U32 numHulls = 0;

      Interior* pInterior = mInteriorRes->getDetailLevel(0);
      if (pInterior->getIntersectingVehicleHulls(realBox, hulls, &numHulls) == false)
      {
         FrameAllocator::setWaterMark(waterMark);
         return;
      }

      for (U32 i = 0; i < numHulls; i++)
      {
         // See if this hull exists in the working set already...
         Convex* cc = 0;
         CollisionWorkingList& wl = convex->getWorkingList();
         for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
         {
            if (itr->mConvex->getType() == InteriorConvexType &&
                (static_cast<InteriorConvex*>(itr->mConvex)->getObject() == this &&
                 static_cast<InteriorConvex*>(itr->mConvex)->hullId    == -S32(hulls[i] + 1)))
            {
               cc = itr->mConvex;
               break;
            }
         }
         if (cc)
            continue;

         // Create a new convex.
         InteriorConvex* cp = new InteriorConvex;
         mConvexList->registerObject(cp);
         convex->addToWorkingList(cp);
         cp->mObject   = this;
         cp->pInterior = pInterior;
         cp->hullId    = -S32(hulls[i] + 1);
         cp->box.min.x = pInterior->mVehicleConvexHulls[hulls[i]].minX;
         cp->box.min.y = pInterior->mVehicleConvexHulls[hulls[i]].minY;
         cp->box.min.z = pInterior->mVehicleConvexHulls[hulls[i]].minZ;
         cp->box.max.x = pInterior->mVehicleConvexHulls[hulls[i]].maxX;
         cp->box.max.y = pInterior->mVehicleConvexHulls[hulls[i]].maxY;
         cp->box.max.z = pInterior->mVehicleConvexHulls[hulls[i]].maxZ;
      }
   }
   else
   {
      // Can never have more hulls than there are hulls in the interior...
      U16* hulls = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mConvexHulls.size() * sizeof(U16));
      U32 numHulls = 0;

      Interior* pInterior = mInteriorRes->getDetailLevel(0);
      if (pInterior->getIntersectingHulls(realBox, hulls, &numHulls) == false)
      {
         FrameAllocator::setWaterMark(waterMark);
         return;
      }

      for (U32 i = 0; i < numHulls; i++)
      {
         // See if this hull exists in the working set already...
         Convex* cc = 0;
         CollisionWorkingList& wl = convex->getWorkingList();
         for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext)
         {
            if (itr->mConvex->getType() == InteriorConvexType &&
                (static_cast<InteriorConvex*>(itr->mConvex)->getObject() == this &&
                 static_cast<InteriorConvex*>(itr->mConvex)->hullId    == hulls[i]))
            {
               cc = itr->mConvex;
               break;
            }
         }

         if (cc)
            continue;

         // Create a new convex.
         InteriorConvex* cp = new InteriorConvex;
         mConvexList->registerObject(cp);
         convex->addToWorkingList(cp);
         cp->mObject   = this;
         cp->pInterior = pInterior;
         cp->hullId    = hulls[i];
         cp->box.min.x = pInterior->mConvexHulls[hulls[i]].minX;
         cp->box.min.y = pInterior->mConvexHulls[hulls[i]].minY;
         cp->box.min.z = pInterior->mConvexHulls[hulls[i]].minZ;
         cp->box.max.x = pInterior->mConvexHulls[hulls[i]].maxX;
         cp->box.max.y = pInterior->mConvexHulls[hulls[i]].maxY;
         cp->box.max.z = pInterior->mConvexHulls[hulls[i]].maxZ;
      }
   }
   FrameAllocator::setWaterMark(waterMark);
}


//------------------------------------------------------------------------------
U32 InteriorInstance::packUpdate(NetConnection* c, U32 mask, BitStream* stream)
{
   U32 retMask = Parent::packUpdate(c, mask, stream);

   if (stream->writeFlag((mask & InitMask) != 0))
   {
      // Initial update, write the whole kit and kaboodle
      stream->write(mCRC);

      stream->writeString(mInteriorFileName);
      stream->writeFlag(mShowTerrainInside);

      // Write the transform (do _not_ use writeAffineTransform.  Since this is a static
      //  object, the transform must be RIGHT THE *&)*$&^ ON or it will goof up the
      //  synchronization between the client and the server.
      mathWrite(*stream, mObjToWorld);
      mathWrite(*stream, mObjScale);

      // Write the alarm state
      stream->writeFlag(mAlarmState);

      // Write the skinbase
      stream->writeString(mSkinBase);

      // audio profile
      if(stream->writeFlag(mAudioProfile))
         stream->writeRangedU32(mAudioProfile->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);

      // audio environment:
      if(stream->writeFlag(mAudioEnvironment))
         stream->writeRangedU32(mAudioEnvironment->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);

      // Lighting behavior.
      stream->writeFlag(mUseGLLighting);
   }
   else
   {
      if (stream->writeFlag((mask & TransformMask) != 0))
      {
         mathWrite(*stream, mObjToWorld);

⌨️ 快捷键说明

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