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

📄 interiorinstance.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "interior/interiorInstance.h"
#include "interior/lightUpdateGrouper.h"
#include "interior/interior.h"
#include "interior/interiorSubObject.h"
#include "interior/pathedInterior.h"
#include "console/consoleTypes.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sceneState.h"
#include "core/bitStream.h"
#include "dgl/dgl.h"
#include "dgl/gBitmap.h"
#include "math/mathIO.h"
#include "dgl/materialList.h"
#include "editor/editor.h"
#include "interior/interiorResObjects.h"
#include "game/trigger.h"
#include "sim/simPath.h"
#include "interior/forceField.h"
#include "dgl/materialList.h"
#include "sceneGraph/lightManager.h"
#include "collision/convex.h"
#include "audio/audioDataBlock.h"
#include "core/frameAllocator.h"

#include "sim/netConnection.h"
#include "platform/profiler.h"

//--------------------------------------------------------------------------
//-------------------------------------- Local classes, data, and functions
//
const U32 csgMaxZoneSize = 256;
bool sgScopeBoolArray[256];

class InteriorRenderImage : public SceneRenderImage
{
  public:
   InteriorRenderImage() : mDetailLevel(0) { }

   U32   mDetailLevel;
   U32   mBaseZone;
};

ConsoleFunctionGroupBegin(Interiors, "");

#if defined(TORQUE_DEBUG) || defined (INTERNAL_RELEASE)
ConsoleFunction( setInteriorRenderMode, void, 2, 2, "(int modeNum)")
{
   S32 mode = dAtoi(argv[1]);
   if (mode < 0 || mode > Interior::ShowDetailLevel)
      mode = 0;

   Interior::smRenderMode = mode;
}

ConsoleFunction( setInteriorFocusedDebug, void, 2, 2, "(bool enable)")
{
   if (dAtob(argv[1])) {
      Interior::smFocusedDebug = true;
   } else {
      Interior::smFocusedDebug = false;
   }
}

#endif

ConsoleFunction( isPointInside, bool, 2, 4, "(Point3F pos) or (float x, float y, float z)")
{
   static bool lastValue = false;

   if(!(argc == 2 || argc == 4))
   {
      Con::errorf(ConsoleLogEntry::General, "cIsPointInside: invalid parameters");
      return(lastValue);
   }

   Point3F pos;
   if(argc == 2)
      dSscanf(argv[1], "%g %g %g", &pos.x, &pos.y, &pos.z);
   else
   {
      pos.x = dAtof(argv[1]);
      pos.y = dAtof(argv[2]);
      pos.z = dAtof(argv[3]);
   }

   RayInfo collision;
   if(gClientContainer.castRay(pos, Point3F(pos.x, pos.y, pos.z - 2000.f), InteriorObjectType, &collision))
   {
      if(collision.face == -1)
         Con::errorf(ConsoleLogEntry::General, "cIsPointInside: failed to find hit face on interior");
      else
      {
         InteriorInstance * interior = dynamic_cast<InteriorInstance *>(collision.object);
         if(interior)
            lastValue = !interior->getDetailLevel(0)->isSurfaceOutsideVisible(collision.face);
         else
            Con::errorf(ConsoleLogEntry::General, "cIsPointInside: invalid interior on collision");
      }
   }

   return(lastValue);
}


ConsoleFunctionGroupEnd(Interiors);

ConsoleMethod( InteriorInstance, setAlarmMode, void, 3, 3, "(string mode) Mode is 'On' or 'Off'")
{
   bool alarm;
   if (dStricmp(argv[2], "On") == 0)
      alarm = true;
   else
      alarm = false;

#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (object->isClientObject()) {
      Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands.  Ignored");
      return;
   }
#endif

   object->setAlarmMode(alarm);
}

ConsoleMethod( InteriorInstance, activateLight, void, 3, 3, "(string lightName)")
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (object->isClientObject()) {
      Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands.  Ignored");
      return;
   }
#endif

   const char* pLightName = argv[2];
   object->activateLight(pLightName);
}

ConsoleMethod( InteriorInstance, deactivateLight, void, 3, 3, "(string lightName)")
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (object->isClientObject()) {
      Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands.  Ignored");
      return;
   }
#endif

   const char* pLightName = argv[2];
   object->deactivateLight(pLightName);
}

ConsoleMethod( InteriorInstance, echoTriggerableLights, void, 2, 2, "List lights usable with activateLight()/deactivateLight().")
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (object->isClientObject()) {
      Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands.  Ignored");
      return;
   }
#endif

   object->echoTriggerableLights();
}

ConsoleMethod( InteriorInstance, magicButton, void, 2, 2, "@deprecated unimplemented")
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (object->isClientObject()) {
      Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands.  Ignored");
      return;
   }
#endif

   object->addChildren();
}

ConsoleMethod( InteriorInstance, setSkinBase, void, 3, 3, "(string basename)")
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (object->isClientObject()) {
      Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands.  Ignored");
      return;
   }
#endif

   object->setSkinBase(argv[2]);
}

ConsoleMethod( InteriorInstance, getNumDetailLevels, S32, 2, 2, "")
{
   return(object->getNumDetailLevels());
}

ConsoleMethod( InteriorInstance, setDetailLevel, void, 3, 3, "(int level)")
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsServerObject
   if(object->isServerObject())
   {
      NetConnection * toServer = NetConnection::getConnectionToServer();
      NetConnection * toClient = NetConnection::getLocalClientConnection();
      if(!toClient || !toServer)
         return;

      S32 index = toClient->getGhostIndex(object);
      if(index == -1)
         return;

      InteriorInstance * clientInstance = dynamic_cast<InteriorInstance*>(toServer->resolveGhost(index));
      if(clientInstance)
         clientInstance->setDetailLevel(dAtoi(argv[2]));
   }
   else
#endif
      object->setDetailLevel(dAtoi(argv[2]));
}

//--------------------------------------------------------------------------
//-------------------------------------- Static functions
//
IMPLEMENT_CO_NETOBJECT_V1(InteriorInstance);

//------------------------------------------------------------------------------
//-------------------------------------- InteriorInstance
//
bool InteriorInstance::smDontRestrictOutside = false;
bool InteriorInstance::smRenderDynamicLights = true;
U32  InteriorInstance::smLightUpdatePeriod = 66;  // 66 ms between updates
F32  InteriorInstance::smDetailModification = 1.0f;


InteriorInstance::InteriorInstance()
{
   mAlarmState             = false;
   mDoSimpleDynamicRender  = false;
   mUseGLLighting          = false;

   mInteriorFileName = NULL;
   mTypeMask = InteriorObjectType | StaticObjectType | StaticRenderedObjectType;
   mNetFlags.set(Ghostable | ScopeAlways);

   mUpdateGrouper = NULL;

   mShowTerrainInside = false;

   mSkinBase = StringTable->insert("base");
   mAudioProfile = 0;
   mAudioEnvironment = 0;
   mForcedDetailLevel = -1;

   mConvexList = new Convex;
#ifdef TGE_RPGCLIENT2//TGE_RPGClient2
   mCRC = 1;
#else
   mCRC = 0;
#endif
}

InteriorInstance::~InteriorInstance()
{
   U32 i;

   for (i = 0; i < mLightInfo.size(); i++)
      destructInPlace(&mLightInfo[i]);

   for (i = 0; i < mInteriorSubObjects.size(); i++)
   {
      // DMM: Fix for first-class objects...
      for (U32 j = 0; j < mInteriorSubObjects[i].size(); j++)
         delete (mInteriorSubObjects[i])[j];

      destructInPlace(&mInteriorSubObjects[i]);
   }
   delete mUpdateGrouper;

   delete mConvexList;
   mConvexList = NULL;

   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;
   }

   for (i = 0; i < mMaterialMaps.size(); i++)
   {
      delete mMaterialMaps[i];
      mMaterialMaps[i] = NULL;
   }
}


void InteriorInstance::init()
{
   // Does nothing for the moment
}


void InteriorInstance::destroy()
{
   // Also does nothing for the moment
}


//--------------------------------------------------------------------------
// Inspection
static AudioProfile * saveAudioProfile = 0;
static AudioEnvironment * saveAudioEnvironment = 0;
void InteriorInstance::inspectPreApply()
{
   saveAudioProfile = mAudioProfile;
   saveAudioEnvironment = mAudioEnvironment;
}

void InteriorInstance::inspectPostApply()
{
   if((mAudioProfile != saveAudioProfile) || (mAudioEnvironment != saveAudioEnvironment))
      setMaskBits(AudioMask);

   // Update the Transform on Editor Apply.
   setMaskBits(TransformMask);
}

void InteriorInstance::onStaticModified( const char* slotName )
{
   if( (!dStricmp( slotName, "position") || !dStricmp( slotName, "rotation") || !dStricmp( slotName, "scale")) && !mUseGLLighting )
      Con::executef( 1, "onNeedRelight" );

   if( !dStricmp( slotName, "useGLLighting" ))
      setMaskBits(InitMask);
}

//--------------------------------------------------------------------------
//-------------------------------------- Console functionality
//
void InteriorInstance::initPersistFields()
{
   Parent::initPersistFields();

   addGroup("Media");
   addField("interiorFile",      TypeFilename,              Offset(mInteriorFileName, InteriorInstance));
   endGroup("Media");

   addGroup("Audio");
   addField("audioProfile",      TypeAudioProfilePtr,       Offset(mAudioProfile, InteriorInstance));
   addField("audioEnvironment",  TypeAudioEnvironmentPtr,   Offset(mAudioEnvironment, InteriorInstance));
   endGroup("Audio");

   addGroup("Misc");
   addField("useGLLighting",     TypeBool,                  Offset(mUseGLLighting, InteriorInstance));
   addField("showTerrainInside", TypeBool,                  Offset(mShowTerrainInside, InteriorInstance));
   endGroup("Misc");

}

void InteriorInstance::consoleInit()
{
   Con::addVariable("pref::Interior::LightUpdatePeriod",    TypeS32,  &smLightUpdatePeriod);
   Con::addVariable("pref::Interior::ShowEnvironmentMaps",  TypeBool, &Interior::smRenderEnvironmentMaps);
   Con::addVariable("pref::Interior::DynamicLights",        TypeBool, &smRenderDynamicLights);
   Con::addVariable("pref::Interior::VertexLighting",       TypeBool, &Interior::smUseVertexLighting);
   Con::addVariable("pref::Interior::TexturedFog",          TypeBool, &Interior::smUseTexturedFog);
   Con::addVariable("pref::Interior::lockArrays",           TypeBool, &Interior::smLockArrays);

   Con::addVariable("pref::Interior::detailAdjust", TypeF32, &InteriorInstance::smDetailModification);

   // DEBUG ONLY!!!
#ifdef TORQUE_DEBUG
   Con::addVariable("Interior::DontRestrictOutside", TypeBool, &smDontRestrictOutside);
#endif
}

//--------------------------------------------------------------------------
void InteriorInstance::renewOverlays()
{
   StringTableEntry baseName = dStricmp(mSkinBase, "base") == 0 ? "blnd" : mSkinBase;

   for (U32 i = 0; i < mMaterialMaps.size(); i++)
   {
      MaterialList* pMatList = mMaterialMaps[i];

      for (U32 j = 0; j < pMatList->mMaterialNames.size(); j++)
      {
         const char* pName     = pMatList->mMaterialNames[j];
         const U32 len = dStrlen(pName);
         if (len < 6)
            continue;

         const char* possible = pName + (len - 5);
         if (dStricmp(".blnd", possible) == 0)
         {

⌨️ 快捷键说明

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