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

📄 explosion.cc

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

#include "game/fx/explosion.h"

#include "console/consoleTypes.h"
#include "console/typeValidators.h"
#include "dgl/dgl.h"
#include "platform/platformAudio.h"
#include "audio/audioDataBlock.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sceneState.h"
#include "core/bitStream.h"
#include "sim/netConnection.h"
#include "ts/tsShape.h"
#include "ts/tsShapeInstance.h"
#include "math/mRandom.h"
#include "math/mathIO.h"
#include "math/mathUtils.h"
#include "game/debris.h"
#include "game/gameConnection.h"
#include "game/fx/particleEngine.h"
#include "game/fx/cameraFXMgr.h"
#include "util/safeDelete.h"

IMPLEMENT_CONOBJECT(Explosion);

#define MaxLightRadius 20

MRandomLCG sgRandom(0xdeadbeef);

ConsoleFunction( calcExplosionCoverage, F32, 4, 4, "(Point3F source, SceneObject originator, bitset coverageMask)")
{
   Point3F pos, center;

   dSscanf(argv[1], "%g %g %g", &pos.x, &pos.y, &pos.z);
   S32 id      = dAtoi(argv[2]);
   U32 covMask = (U32)dAtoi(argv[3]);

   SceneObject* sceneObject = NULL;
   if (Sim::findObject(id, sceneObject) == false)
   {
      Con::warnf(ConsoleLogEntry::General, "calcExplosionCoverage: couldn't find object: %s", argv[2]);
      return 1.0;
   }

#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if ( sceneObject->getContainer() == NULL)
#else
   if (sceneObject->isClientObject() || sceneObject->getContainer() == NULL)
#endif
   {
      Con::warnf(ConsoleLogEntry::General, "calcExplosionCoverage: object is on the client, or not in the container system");
      return 1.0;
   }

   sceneObject->getObjBox().getCenter(&center);
   center.convolve(sceneObject->getScale());
   sceneObject->getTransform().mulP(center);

   RayInfo rayInfo;
   sceneObject->disableCollision();
   if (sceneObject->getContainer()->castRay(pos, center, covMask, &rayInfo) == true)
   {
      // Try casting up and then out
      if (sceneObject->getContainer()->castRay(pos, pos + Point3F(0, 0, 1), covMask, &rayInfo) == false)
      {
         if (sceneObject->getContainer()->castRay(pos + Point3F(0, 0, 1), center, covMask, &rayInfo) == false)
         {
            sceneObject->enableCollision();
            return 1.0;
         }
      }

      sceneObject->enableCollision();
      return 0.0;
   }
   else
   {
      sceneObject->enableCollision();
      return 1.0;
   }
}

//----------------------------------------------------------------------------
//
IMPLEMENT_CO_DATABLOCK_V1(ExplosionData);

ExplosionData::ExplosionData()
{
   dtsFileName  = NULL;
   particleDensity = 10;
   particleRadius = 1;

   faceViewer   = false;

   soundProfile      = NULL;
   particleEmitter   = NULL;
   soundProfileId    = 0;
   particleEmitterId = 0;

   explosionScale.set(1, 1, 1);
   playSpeed = 1.0;

   dMemset( emitterList, 0, sizeof( emitterList ) );
   dMemset( emitterIDList, 0, sizeof( emitterIDList ) );
   dMemset( debrisList, 0, sizeof( debrisList ) );
   dMemset( debrisIDList, 0, sizeof( debrisIDList ) );

   debrisThetaMin = 0;
   debrisThetaMax = 90;
   debrisPhiMin = 0;
   debrisPhiMax = 360;
   debrisNum = 1;
   debrisNumVariance = 0;
   debrisVelocity = 2.0;
   debrisVelocityVariance = 0.0;

   dMemset( explosionList, 0, sizeof( explosionList ) );
   dMemset( explosionIDList, 0, sizeof( explosionIDList ) );

   delayMS = 0;
   delayVariance = 0;
   lifetimeMS = 1000;
   lifetimeVariance = 0;
   offset = 0;

   shockwave = NULL;
   shockwaveID = 0;
   shockwaveOnTerrain = false;

   shakeCamera = false;
   camShakeFreq.set( 10.0, 10.0, 10.0 );
   camShakeAmp.set( 1.0, 1.0, 1.0 );
   camShakeDuration = 1.5;
   camShakeRadius = 10.0;
   camShakeFalloff = 10.0;

   for( U32 i=0; i<EC_NUM_TIME_KEYS; i++ )
   {
      times[i] = 1.0;
   }
   times[0] = 0.0;

   for( U32 j=0; j<EC_NUM_TIME_KEYS; j++ )
   {
      sizes[j].set( 1.0, 1.0, 1.0 );
   }

   //
   lightStartRadius = lightEndRadius = 0;
   lightStartColor.set(1,1,1);
   lightEndColor.set(1,1,1);
}

IMPLEMENT_CONSOLETYPE(ExplosionData)
IMPLEMENT_SETDATATYPE(ExplosionData)
IMPLEMENT_GETDATATYPE(ExplosionData)

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

   addField("explosionShape",  TypeFilename,                Offset(dtsFileName,     ExplosionData));
   addField("soundProfile",    TypeAudioProfilePtr,         Offset(soundProfile,    ExplosionData));
   addField("faceViewer",      TypeBool,                    Offset(faceViewer,      ExplosionData));
   addField("particleEmitter", TypeParticleEmitterDataPtr,  Offset(particleEmitter, ExplosionData));
   addField("particleDensity", TypeS32,                     Offset(particleDensity, ExplosionData));
   addField("particleRadius",  TypeF32,                     Offset(particleRadius,  ExplosionData));
   addField("explosionScale",  TypePoint3F,                 Offset(explosionScale,  ExplosionData));
   addField("playSpeed",       TypeF32,                     Offset(playSpeed,       ExplosionData));

   addField("emitter",         TypeParticleEmitterDataPtr,  Offset(emitterList,     ExplosionData), EC_NUM_EMITTERS);
   addField("debris",          TypeDebrisDataPtr,           Offset(debrisList,      ExplosionData), EC_NUM_DEBRIS_TYPES);

   addField("debrisThetaMin",    TypeF32, Offset(debrisThetaMin,     ExplosionData));
   addField("debrisThetaMax",    TypeF32, Offset(debrisThetaMax,     ExplosionData));
   addField("debrisPhiMin",      TypeF32, Offset(debrisPhiMin,       ExplosionData));
   addField("debrisPhiMax",      TypeF32, Offset(debrisPhiMax,       ExplosionData));
   addField("debrisNum",         TypeS32, Offset(debrisNum,          ExplosionData));
   addField("debrisNumVariance", TypeS32, Offset(debrisNumVariance,  ExplosionData));
   addField("debrisVelocity",    TypeF32, Offset(debrisVelocity,     ExplosionData));
   addField("debrisVelocityVariance",    TypeF32, Offset(debrisVelocityVariance,     ExplosionData));

   addField("subExplosion",      TypeExplosionDataPtr, Offset(explosionList, ExplosionData), EC_MAX_SUB_EXPLOSIONS );

   addField("delayMS",           TypeS32, Offset(delayMS,            ExplosionData));
   addField("delayVariance",     TypeS32, Offset(delayVariance,      ExplosionData));
   addField("lifetimeMS",        TypeS32, Offset(lifetimeMS,         ExplosionData));
   addField("lifetimeVariance",  TypeS32, Offset(lifetimeVariance,   ExplosionData));
   addField("offset",            TypeF32, Offset(offset,             ExplosionData));

   addField("times",             TypeF32,       Offset(times,        ExplosionData), EC_NUM_TIME_KEYS );
   addField("sizes",             TypePoint3F,   Offset(sizes,       ExplosionData), EC_NUM_TIME_KEYS );

   addField("shakeCamera",       TypeBool,      Offset(shakeCamera,        ExplosionData));
   addField("camShakeFreq",      TypePoint3F,   Offset(camShakeFreq,       ExplosionData));
   addField("camShakeAmp",       TypePoint3F,   Offset(camShakeAmp,        ExplosionData));
   addField("camShakeDuration",  TypeF32,       Offset(camShakeDuration,   ExplosionData));
   addField("camShakeRadius",    TypeF32,       Offset(camShakeRadius,     ExplosionData));
   addField("camShakeFalloff",   TypeF32,       Offset(camShakeFalloff,    ExplosionData));

   addNamedFieldV(lightStartRadius, TypeF32, ExplosionData, new FRangeValidator(0, MaxLightRadius));
   addNamedFieldV(lightEndRadius, TypeF32, ExplosionData, new FRangeValidator(0, MaxLightRadius));
   addNamedField(lightStartColor, TypeColorF, ExplosionData);
   addNamedField(lightEndColor, TypeColorF, ExplosionData);
}

bool ExplosionData::onAdd()
{
   if (Parent::onAdd() == false)
      return false;

   if (!soundProfile && soundProfileId != 0)
      if (Sim::findObject(soundProfileId, soundProfile) == false)
         Con::errorf(ConsoleLogEntry::General, "Error, unable to load sound profile for explosion datablock");
   if (!particleEmitter && particleEmitterId != 0)
      if (Sim::findObject(particleEmitterId, particleEmitter) == false)
         Con::errorf(ConsoleLogEntry::General, "Error, unable to load particle emitter for explosion datablock");

   if (explosionScale.x < 0.01 || explosionScale.y < 0.01 || explosionScale.z < 0.01)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s)::onAdd: ExplosionScale components must be >= 0.01", getName());
      explosionScale.x = explosionScale.x < 0.01 ? 0.01 : explosionScale.x;
      explosionScale.y = explosionScale.y < 0.01 ? 0.01 : explosionScale.y;
      explosionScale.z = explosionScale.z < 0.01 ? 0.01 : explosionScale.z;
   }

   if (debrisThetaMin < 0.0f)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisThetaMin < 0.0", getName());
      debrisThetaMin = 0.0f;
   }

   if (debrisThetaMax > 180.0f)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisThetaMax > 180.0", getName());
      debrisThetaMax = 180.0f;
   }

   if (debrisThetaMin > debrisThetaMax)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisThetaMin > debrisThetaMax", getName());
      debrisThetaMin = debrisThetaMax;
   }

   if (debrisPhiMin < 0.0f)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisPhiMin < 0.0", getName());
      debrisPhiMin = 0.0f;
   }

   if (debrisPhiMax > 360.0f)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisPhiMax > 360.0", getName());
      debrisPhiMax = 360.0f;
   }

   if (debrisPhiMin > debrisPhiMax)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisPhiMin > debrisPhiMax", getName());
      debrisPhiMin = debrisPhiMax;
   }

   if (debrisNum > 1000)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisNum > 1000", getName());
      debrisNum = 1000;
   }

   if (debrisNumVariance > 1000)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisNumVariance > 1000", getName());
      debrisNumVariance = 1000;
   }

   if (debrisVelocity < 0.1)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisVelocity < 0.1", getName());
      debrisVelocity = 0.1;
   }

   if (debrisVelocityVariance > 1000)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) debrisVelocityVariance > 1000", getName());
      debrisVelocityVariance = 1000;
   }

   if (playSpeed < 0.05)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) playSpeed < 0.05", getName());
      playSpeed = 0.05;
   }

   if (lifetimeMS < 1)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) lifetimeMS < 1", getName());
      lifetimeMS = 1;
   }

   if (lifetimeVariance > lifetimeMS)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) lifetimeVariance > lifetimeMS", getName());
      lifetimeVariance = lifetimeMS;
   }

   if (delayMS < 0)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) delayMS < 0", getName());
      delayMS = 0;
   }

   if (delayVariance > delayMS)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) delayVariance > delayMS", getName());
      delayVariance = delayMS;
   }

   if (offset < 0.0)
   {
      Con::warnf(ConsoleLogEntry::General, "ExplosionData(%s) offset < 0.0", getName());
      offset = 0.0;
   }

   S32 i;

   for( i=0; i<EC_NUM_DEBRIS_TYPES; i++ )
   {
      if( !debrisList[i] && debrisIDList[i] != 0 )
      {
         if( !Sim::findObject( debrisIDList[i], debrisList[i] ) )
         {
            Con::errorf( ConsoleLogEntry::General, "ExplosionData::onAdd: Invalid packet, bad datablockId(debris): 0x%x", debrisIDList[i] );
         }
      }
   }

   for( i=0; i<EC_NUM_EMITTERS; i++ )
   {
      if( !emitterList[i] && emitterIDList[i] != 0 )
      {
         if( Sim::findObject( emitterIDList[i], emitterList[i] ) == false)
         {
            Con::errorf( ConsoleLogEntry::General, "ExplosionData::onAdd: Invalid packet, bad datablockId(particle emitter): 0x%x", emitterIDList[i] );
         }
      }
   }

   for( S32 k=0; k<EC_MAX_SUB_EXPLOSIONS; k++ )
   {
      if( !explosionList[k] && explosionIDList[k] != 0 )
      {
         if( Sim::findObject( explosionIDList[k], explosionList[k] ) == false)
         {
            Con::errorf( ConsoleLogEntry::General, "ExplosionData::onAdd: Invalid packet, bad datablockId(explosion): 0x%x", explosionIDList[k] );
         }
      }
   }

   return true;
}

void ExplosionData::packData(BitStream* stream)
{
   Parent::packData(stream);

   stream->writeString(dtsFileName);

   if (stream->writeFlag(soundProfile != NULL))
      stream->writeRangedU32(soundProfile->getId(), DataBlockObjectIdFirst,
                                                    DataBlockObjectIdLast);
   if (stream->writeFlag(particleEmitter))
      stream->writeRangedU32(particleEmitter->getId(),DataBlockObjectIdFirst,DataBlockObjectIdLast);

   stream->writeInt(particleDensity, 14);
   stream->write(particleRadius);
   stream->writeFlag(faceViewer);
   if(stream->writeFlag(explosionScale.x != 1 || explosionScale.y != 1 || explosionScale.z != 1))

⌨️ 快捷键说明

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