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

📄 interiorinstance.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
         mathWrite(*stream, mObjScale);
      }

      stream->writeFlag(mAlarmState);

      // Check the lights to see if we need to update any of their states
      LightUpdateGrouper::BitIterator itr;
      for (itr = mUpdateGrouper->begin(); itr.valid() && itr.getNumKeys(); itr++)
      {
         if (stream->writeFlag((mask & itr.getMask()) != 0))
         {
            LightUpdateGrouper::BitIterator::iterator kItr;
            for (kItr = itr.begin(); kItr != itr.end(); kItr++)
            {
               U32 key = *kItr;
               U32 detail = detailFromUpdateKey(key);
               U32 index  = indexFromUpdateKey(key);

               stream->writeFlag(mLightInfo[detail].mLights[index].active);
            }
         }
      }

      if (stream->writeFlag(mask & SkinBaseMask))
         stream->writeString(mSkinBase);

      // audio update:
      if(stream->writeFlag(mask & AudioMask))
      {
         // profile:
         if(stream->writeFlag(mAudioProfile))
            stream->writeRangedU32(mAudioProfile->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast);

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

   return retMask;
}


//------------------------------------------------------------------------------
void InteriorInstance::unpackUpdate(NetConnection* c, BitStream* stream)
{
   Parent::unpackUpdate(c, stream);

   MatrixF temp;
   Point3F tempScale;

   if (stream->readFlag())
   {
      // Initial Update
      // CRC
      stream->read(&mCRC);

      // File
      mInteriorFileName = stream->readSTString();

      // Terrain flag
      mShowTerrainInside = stream->readFlag();

      // Transform
      mathRead(*stream, &temp);
      mathRead(*stream, &tempScale);
      setScale(tempScale);
      setTransform(temp);

      // Alarm state: Note that we handle this ourselves on the initial update
      //  so that the state is always full on or full off...
      mAlarmState = stream->readFlag();

      mSkinBase = stream->readSTString();

      // audio profile:
      if(stream->readFlag())
      {
         U32 profileId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
         mAudioProfile = dynamic_cast<AudioProfile*>(Sim::findObject(profileId));
      }
      else
         mAudioProfile = 0;

      // audio environment:
      if(stream->readFlag())
      {
         U32 profileId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
         mAudioEnvironment = dynamic_cast<AudioEnvironment*>(Sim::findObject(profileId));
      }
      else
         mAudioEnvironment = 0;

      // Lighting behavior.
      mDoSimpleDynamicRender = mUseGLLighting = stream->readFlag();
   }
   else
   {
      // Normal update
      if (stream->readFlag())
      {
         mathRead(*stream, &temp);
         mathRead(*stream, &tempScale);
         setScale(tempScale);
         setTransform(temp);
      }

      setAlarmMode(stream->readFlag());

      LightUpdateGrouper::BitIterator itr;
      for (itr = mUpdateGrouper->begin(); itr.valid() && itr.getNumKeys(); itr++)
      {
         if (stream->readFlag())
         {
            LightUpdateGrouper::BitIterator::iterator kItr;
            for (kItr = itr.begin(); kItr != itr.end(); kItr++)
            {
               U32 key = *kItr;
               U32 detail = detailFromUpdateKey(key);
               U32 index  = indexFromUpdateKey(key);

               if (stream->readFlag())
                  activateLight(detail, index);
               else
                  deactivateLight(detail, index);
            }
         }
      }

      if (stream->readFlag())
      {
         mSkinBase = stream->readSTString();
         renewOverlays();
      }

      // audio update:
      if(stream->readFlag())
      {
         // profile:
         if(stream->readFlag())
         {
            U32 profileId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
            mAudioProfile = dynamic_cast<AudioProfile*>(Sim::findObject(profileId));
         }
         else
            mAudioProfile = 0;

         // environment:
         if(stream->readFlag())
         {
            U32 profileId = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);
            mAudioEnvironment = dynamic_cast<AudioEnvironment*>(Sim::findObject(profileId));
         }
         else
            mAudioEnvironment = 0;
      }
   }
}


//------------------------------------------------------------------------------
Interior* InteriorInstance::getDetailLevel(const U32 level)
{
   return mInteriorRes->getDetailLevel(level);
}

U32 InteriorInstance::getNumDetailLevels()
{
   return mInteriorRes->getNumDetailLevels();
}

//--------------------------------------------------------------------------
//-------------------------------------- Alarm functionality
//
void InteriorInstance::setAlarmMode(const bool alarm)
{
   if (mInteriorRes->getDetailLevel(0)->mHasAlarmState == false)
      return;

   if (mAlarmState == alarm)
      return;

   mAlarmState = alarm;
   if (isServerObject())
   {
      setMaskBits(AlarmMask);
   }
   else
   {
      // DMMTODO: Invalidate current light state
   }
}


//--------------------------------------------------------------------------
void InteriorInstance::rebuildVertexColors()
{
   U32 i;
   for (i = 0; i < mVertexColorsNormal.size(); i++)
   {
      delete mVertexColorsNormal[i];
      mVertexColorsNormal[i] = NULL;
   }
   for (i = 0; i < mVertexColorsAlarm.size(); i++)
   {
      delete mVertexColorsAlarm[i];
      mVertexColorsAlarm[i] = NULL;
   }

   if (bool(mInteriorRes) == false)
      return;

   mVertexColorsNormal.setSize(mInteriorRes->getNumDetailLevels());
   mVertexColorsAlarm.setSize(mInteriorRes->getNumDetailLevels());

   for (i = 0; i < mInteriorRes->getNumDetailLevels(); i++)
   {
      mVertexColorsNormal[i] = new Vector<ColorI>;
      mVertexColorsAlarm[i]  = new Vector<ColorI>;
      VECTOR_SET_ASSOCIATION((*mVertexColorsNormal[i]));
      VECTOR_SET_ASSOCIATION((*mVertexColorsAlarm[i]));
   }

   for (i = 0; i < mInteriorRes->getNumDetailLevels(); i++)
   {
      Interior* pInterior = mInteriorRes->getDetailLevel(i);
      pInterior->rebuildVertexColors(mLMHandle,
                                     mVertexColorsNormal[i],
                                     mVertexColorsAlarm[i]);
   }
}


//--------------------------------------------------------------------------
void InteriorInstance::updateLightMap(Interior* pInterior, LightInfo& rLightInfo, const U32 surfaceIndex)
{
   AssertFatal(surfaceIndex < pInterior->mSurfaces.size(), "Error, out of range surface index");
   static U8 _newLightMapBuffer[256*256*3];

   const Interior::Surface& rSurface = pInterior->mSurfaces[surfaceIndex];
   if (rSurface.lightCount == 0)
      return;

   // Get the surface's original bitmap
   TextureHandle* originalLMapHandle = ((mAlarmState == false) ?
                                        gInteriorLMManager.getHandle(pInterior->getLMHandle(), mLMHandle,
                                                                     pInterior->mNormalLMapIndices[surfaceIndex]) :
                                        gInteriorLMManager.getHandle(pInterior->getLMHandle(), mLMHandle,
                                                                     pInterior->mAlarmLMapIndices[surfaceIndex]));

   const GBitmap* pOriginalLMap = originalLMapHandle->getBitmap();
   AssertFatal(pOriginalLMap != NULL, "error, no lightmap on the handle!");
   AssertFatal(pOriginalLMap->getFormat() == GBitmap::RGB, "error, bad lightmap format!");

   // First, we need to create a buffer that will receive the new lightmap
   U32 dimX = rSurface.mapSizeX;
   U32 dimY = rSurface.mapSizeY;
   U8* pNewLightmap = _newLightMapBuffer;

   // copy the original lightmap
   const U8 * src = pOriginalLMap->getAddress(rSurface.mapOffsetX, rSurface.mapOffsetY);
   U8 * dest = pNewLightmap;

   U32 runSize = rSurface.mapSizeX * 3;
   U32 srcStep = pOriginalLMap->getWidth() * 3;

   for(U32 y = 0; y < rSurface.mapSizeY; y++)
   {
      dMemcpy(dest, src, runSize);
      dest += runSize;
      src += srcStep;
   }

   // ...now we have the original lightmap, add in the animateds...
   for (U32 i = 0; i < rSurface.lightCount; i++)
   {
      const LightInfo::StateDataInfo& rInfo = rLightInfo.mStateDataInfo[rSurface.lightStateInfoStart + i];

      // Only add in states that affect this surface...duh.
      if (rInfo.curMap != NULL && rInfo.alarm == (mAlarmState != Normal))
      {
         intensityMapMerge(pNewLightmap, dimX, dimY,
                           rInfo.curMap, rInfo.curColor);
      }
   }

   // OK, now we have the final, current lightmap.  subimage it in...
   glBindTexture(GL_TEXTURE_2D, originalLMapHandle->getGLName());

   if (Con::getBoolVariable("$pref::OpenGL::disableSubImage", false))
   {
      const U8 *src = pNewLightmap;
      U8 *dest = (U8 *) pOriginalLMap->getAddress(rSurface.mapOffsetX, rSurface.mapOffsetY);
      U32 destStep = pOriginalLMap->getWidth() * 3;

      // copy back into the original lightmap
      for (U32 y = 0; y < rSurface.mapSizeY; y++)
      {
         dMemcpy(dest, src, runSize);
         src += runSize;
         dest += destStep;
      }

      glTexImage2D(GL_TEXTURE_2D,
                   0,
                   GL_RGB,
                   pOriginalLMap->getWidth(), pOriginalLMap->getHeight(),
                   0,
                   GL_RGB, GL_UNSIGNED_BYTE,
                   pOriginalLMap->getBits(0));
   }
   else
   {
      glTexSubImage2D(GL_TEXTURE_2D,
                      0,
                      rSurface.mapOffsetX, rSurface.mapOffsetY,
                      rSurface.mapSizeX,   rSurface.mapSizeY,
                      GL_RGB, GL_UNSIGNED_BYTE,
                      pNewLightmap);
   }
}


//--------------------------------------------------------------------------
void InteriorInstance::downloadLightmaps(SceneState* /*state*/,
                                         Interior*   pInterior,
                                         LightInfo&  rLightInfo)
{
   extern U16* sgActivePolyList;
   extern U32  sgActivePolyListSize;

   for (U32 i = 0; i < sgActivePolyListSize; i++)
   {
      if (rLightInfo.mSurfaceInvalid.test(sgActivePolyList[i]) == true)
      {
         updateLightMap(pInterior, rLightInfo, sgActivePolyList[i]);
         rLightInfo.mSurfaceInvalid.clear(sgActivePolyList[i]);
      }
   }
}


//--------------------------------------------------------------------------
void InteriorInstance::addChildren()
{
   if (bool(mInteriorRes) == false)
      return;

   char nameBuffer[256];
   U32 i;

   // First thing to do, add a group with our name
   SimGroup* myGroup = getGroup();

   // Load all the interior game objects...
   for(i = 0; i < mInteriorRes->getNumGameEntities(); i++)
   {
      ItrGameEntity *ent = mInteriorRes->getGameEntity(i);
      ConsoleObject *obj = ConsoleObject::create(ent->mGameClass);
      GameBase *gb = dynamic_cast<GameBase*>(obj);
      if(!gb)
      {
         Con::errorf("Invalid game class for entity: %s", ent->mGameClass);
         delete obj;
         continue;
      }
      gb->setField("dataBlock", ent->mDataBlock);
      gb->setModStaticFields(true);
      for(U32 j = 0; j < ent->mDictionary.size(); j++)
         gb->setDataField(StringTable->insert(ent->mDictionary[j].name), NULL, ent->mDictionary[j].value);
      gb->setModStaticFields(false);
      Point3F origin = ent->mPos;
      origin.convolve(mObjScale);
      getTransform().mulP(origin);
      MatrixF xform(true);
      xform.setColumn(3, origin);
      gb->setTransform(xform);
      if(!gb->registerObject())
      {
         Con::errorf("Failed to register entity: %s: %s", ent->mGameClass, ent->mDataBlock);
         delete gb;
         continue;
      }
      myGroup->addObject(gb);
   }

   // Next, for each door in our resource, we'll be creating a group
   for (i = 0; i < mInteriorRes->getNumInteriorPathFollowers(); i++)
   {
      InteriorPathFollower* pSource = mInteriorRes->getInteriorPathFollower(i);

      StringTableEntry name = StringTable->insert(pSource->mName);
      PathedInterior* child = new PathedInterior;
      child->mName             = name;
      child->mInteriorResIndex = pSource->mInteriorResIndex;
      child->mPathIndex        = pSource->mPathI

⌨️ 快捷键说明

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