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

📄 shapebase.cc

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

#include "dgl/dgl.h"
#include "platform/platform.h"
#include "core/dnet.h"
#include "audio/audioDataBlock.h"
#include "game/gameConnection.h"
#include "game/moveManager.h"
#include "console/consoleTypes.h"
#include "core/bitStream.h"
#include "ts/tsPartInstance.h"
#include "ts/tsShapeInstance.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sceneState.h"
#include "game/shadow.h"
#include "game/fx/explosion.h"
#include "game/shapeBase.h"
#include "terrain/waterBlock.h"
#include "game/debris.h"
#include "terrain/sky.h"
#include "game/physicalZone.h"
#include "sceneGraph/detailManager.h"
#include "math/mathUtils.h"
#include "math/mMatrix.h"
#include "math/mRandom.h"
#include "platform/profiler.h"

IMPLEMENT_CO_DATABLOCK_V1(ShapeBaseData);



#ifdef TGE_RPG
	//leo 2006.5.12
	//Camera与主角距离
static F32 ms_fCameraYaw	= 0;
static F32 ms_fCameraPitch = 0;//M_PI/4;
static F32 ms_fCameraDist	= 0;

static F32 ms_fCameraMinPitch = 5;
static F32 ms_fCameraMaxPitch = 89.9; //不可为90,相机会倒过来的
#endif


//----------------------------------------------------------------------------
// Timeout for non-looping sounds on a channel
static SimTime sAudioTimeout = 500;
bool ShapeBase::gRenderEnvMaps = true;
F32  ShapeBase::sWhiteoutDec = 0.007;
F32  ShapeBase::sDamageFlashDec = 0.007;
U32  ShapeBase::sLastRenderFrame = 0;

static const char *sDamageStateName[] =
{
   // Index by enum ShapeBase::DamageState
   "Enabled",
   "Disabled",
   "Destroyed"
};


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

ShapeBaseData::ShapeBaseData()
{
   shapeName = "";
   cloakTexName = "";
   mass = 1;
   drag = 0;
   density = 1;
   maxEnergy = 0;
   maxDamage = 1.0;
   disabledLevel = 1.0;
   destroyedLevel = 1.0;
   repairRate = 0.0033;
   eyeNode = -1;
   shadowNode = -1;
   cameraNode = -1;
   damageSequence = -1;
   hulkSequence = -1;
#ifdef TGE_RPG /// TGE_Move
   cameraDefaultDist	= 6.f;
   cameraMaxDist		= 20.f;
   cameraMinDist		= 3.f;
   cameraDefaultYaw	= 0.f;
   cameraDefaultPitch= 35.f;
#else
   cameraMaxDist = 0;
   cameraMinDist = 0.2;
#endif
   cameraDefaultFov = 90.f;
   cameraMinFov = 5.f;
   cameraMaxFov = 120.f;
   emap = false;
   aiAvoidThis = false;
   isInvincible = false;
   renderWhenDestroyed = true;
   debris = NULL;
   debrisID = 0;
   debrisShapeName = NULL;
   explosion = NULL;
   explosionID = 0;
   underwaterExplosion = NULL;
   underwaterExplosionID = 0;
   firstPersonOnly = false;
   useEyePoint = false;

   observeThroughObject = false;
   computeCRC = false;

   // no shadows by default
   genericShadowLevel = 2.0f;
   noShadowLevel = 2.0f;

   inheritEnergyFromMount = false;

   for(U32 j = 0; j < NumHudRenderImages; j++)
   {
      hudImageNameFriendly[j] = 0;
      hudImageNameEnemy[j] = 0;
      hudRenderCenter[j] = false;
      hudRenderModulated[j] = false;
      hudRenderAlways[j] = false;
      hudRenderDistance[j] = false;
      hudRenderName[j] = false;
   }

#ifdef TGE_RPGCLIENT2//TGE_RPGClient2
   mCRC = 1;
#endif

}

static ShapeBaseData gShapeBaseDataProto;

ShapeBaseData::~ShapeBaseData()
{

}

bool ShapeBaseData::preload(bool server, char errorBuffer[256])
{
   if (!Parent::preload(server, errorBuffer))
      return false;

#ifdef TGE_RPG
   if(server)
		return true;
#endif

   bool shapeError = false;

   // Resolve objects transmitted from server
   if (!server) {

      if( !explosion && explosionID != 0 )
      {
         if( Sim::findObject( explosionID, explosion ) == false)
         {
            Con::errorf( ConsoleLogEntry::General, "ShapeBaseData::preload: Invalid packet, bad datablockId(explosion): 0x%x", explosionID );
         }
         AssertFatal(!(explosion && ((explosionID < DataBlockObjectIdFirst) || (explosionID > DataBlockObjectIdLast))),
            "ShapeBaseData::preload: invalid explosion data");
      }

      if( !underwaterExplosion && underwaterExplosionID != 0 )
      {
         if( Sim::findObject( underwaterExplosionID, underwaterExplosion ) == false)
         {
            Con::errorf( ConsoleLogEntry::General, "ShapeBaseData::preload: Invalid packet, bad datablockId(underwaterExplosion): 0x%x", underwaterExplosionID );
         }
         AssertFatal(!(underwaterExplosion && ((underwaterExplosionID < DataBlockObjectIdFirst) || (underwaterExplosionID > DataBlockObjectIdLast))),
            "ShapeBaseData::preload: invalid underwaterExplosion data");
      }

      if( !debris && debrisID != 0 )
      {
         Sim::findObject( debrisID, debris );
         AssertFatal(!(debris && ((debrisID < DataBlockObjectIdFirst) || (debrisID > DataBlockObjectIdLast))),
            "ShapeBaseData::preload: invalid debris data");
      }


      if( debrisShapeName && debrisShapeName[0] != '\0' && !bool(debrisShape) )
      {
         debrisShape = ResourceManager->load(debrisShapeName);
         if( bool(debrisShape) == false )
         {
            dSprintf(errorBuffer, 256, "ShapeBaseData::load: Couldn't load shape \"%s\"", debrisShapeName);
            return false;
         }
         else
         {
            if(!server && !debrisShape->preloadMaterialList() && NetConnection::filesWereDownloaded())
               shapeError = true;

            TSShapeInstance* pDummy = new TSShapeInstance(debrisShape, !server);
            delete pDummy;
         }
      }
   }

   //
   if (shapeName && shapeName[0]) {
      S32 i;

      // Resolve shapename
      shape = ResourceManager->load(shapeName, computeCRC);
      if (!bool(shape)) {
         dSprintf(errorBuffer, 256, "ShapeBaseData: Couldn't load shape \"%s\"",shapeName);
         return false;
      }
      if(!server && !shape->preloadMaterialList() && NetConnection::filesWereDownloaded())
         shapeError = true;

      if(computeCRC)
      {
#ifdef TGE_RPGCLIENT2 // TGE_RPGClientPreload
         mCRC = shape.getCRC();
#else
         Con::printf("Validation required for shape: %s", shapeName);
         if(server)
            mCRC = shape.getCRC();
         else if(mCRC != shape.getCRC())
         {
            dSprintf(errorBuffer, 256, "Shape \"%s\" does not match version on server.",shapeName);
            return false;
         }
#endif
      }

      // Resolve details and camera node indexes.
      for (i = 0; i < shape->details.size(); i++)
      {
         char* name = (char*)shape->names[shape->details[i].nameIndex];

         if (dStrstr((const char *)dStrlwr(name), "collision-"))
         {
            collisionDetails.push_back(i);
            collisionBounds.increment();

            shape->computeBounds(collisionDetails.last(), collisionBounds.last());
            shape->getAccelerator(collisionDetails.last());

            if (!shape->bounds.isContained(collisionBounds.last()))
            {
               Con::warnf("Warning: shape %s collision detail %d (Collision-%d) bounds exceed that of shape.", shapeName, collisionDetails.size() - 1, collisionDetails.last());
               collisionBounds.last() = shape->bounds;
            }
            else if (collisionBounds.last().isValidBox() == false)
            {
               Con::errorf("Error: shape %s-collision detail %d (Collision-%d) bounds box invalid!", shapeName, collisionDetails.size() - 1, collisionDetails.last());
               collisionBounds.last() = shape->bounds;
            }

            // The way LOS works is that it will check to see if there is a LOS detail that matches
            // the the collision detail + 1 + MaxCollisionShapes (this variable name should change in
            // the future). If it can't find a matching LOS it will simply use the collision instead.
            // We check for any "unmatched" LOS's further down
            LOSDetails.increment();

         char buff[128];
            dSprintf(buff, sizeof(buff), "LOS-%d", i + 1 + MaxCollisionShapes);
            U32 los = shape->findDetail(buff);
            if (los == -1)
               LOSDetails.last() = i;
            else
               LOSDetails.last() = los;
         }
      }

      // Snag any "unmatched" LOS details
      for (i = 0; i < shape->details.size(); i++)
            {
         char* name = (char*)shape->names[shape->details[i].nameIndex];

         if (dStrstr((const char *)dStrlwr(name), "los-"))
            {
            // See if we already have this LOS
            bool found = false;
            for (U32 j = 0; j < LOSDetails.size(); j++)
            {
               if (LOSDetails[j] == i)
            {
                  found = true;
                  break;
            }
         }

            if (!found)
               LOSDetails.push_back(i);
         }
      }

      debrisDetail = shape->findDetail("Debris-17");
      eyeNode = shape->findNode("eye");
      cameraNode = shape->findNode("cam");
      if (cameraNode == -1)
         cameraNode = eyeNode;

      // Resolve mount point node indexes
      for (i = 0; i < NumMountPoints; i++) {
         char fullName[256];
         dSprintf(fullName,sizeof(fullName),"mount%d",i);
         mountPointNode[i] = shape->findNode(fullName);
      }

        // find the AIRepairNode - hardcoded to be the last node in the array...
      mountPointNode[AIRepairNode] = shape->findNode("AIRepairNode");

      //
      hulkSequence = shape->findSequence("Visibility");
      damageSequence = shape->findSequence("Damage");

      //
#ifdef TGE_RPG /// TGE_Move 
		cameraDefaultDist = mClamp(cameraDefaultDist, cameraMinDist, cameraMaxDist);
		cameraDefaultPitch = mClampF(cameraDefaultPitch, ms_fCameraMinPitch, ms_fCameraMaxPitch);
		cameraDefaultYaw = mFmod(cameraDefaultYaw, 360.f);
#else
		F32 w = shape->bounds.len_y() / 2;
      if (cameraMaxDist < w)
         cameraMaxDist = w;
#endif
   }

   if(!server)
   {
      // grab all the hud images
      for(U32 i = 0; i < NumHudRenderImages; i++)
      {
         if(hudImageNameFriendly[i] && hudImageNameFriendly[i][0])
            hudImageFriendly[i] = TextureHandle(hudImageNameFriendly[i], BitmapTexture);

         if(hudImageNameEnemy[i] && hudImageNameEnemy[i][0])
            hudImageEnemy[i] = TextureHandle(hudImageNameEnemy[i], BitmapTexture);
      }
   }

   return !shapeError;
}


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

   addGroup("Render");
   addField("shapeFile",      TypeFilename, Offset(shapeName,      ShapeBaseData));
   addField("cloakTexture",   TypeFilename, Offset(cloakTexName,      ShapeBaseData));
   addField("emap",           TypeBool,       Offset(emap,           ShapeBaseData));
   endGroup("Render");

   addGroup("Destruction", "Parameters related to the destruction effects of this object.");
   addField("explosion",      TypeExplosionDataPtr, Offset(explosion, ShapeBaseData));
   addField("underwaterExplosion", TypeExplosionDataPtr, Offset(underwaterExplosion, ShapeBaseData));
   addField("debris",         TypeDebrisDataPtr,    Offset(debris,   ShapeBaseData));
   addField("renderWhenDestroyed",   TypeBool,  Offset(renderWhenDestroyed,   ShapeBaseData));
   addField("debrisShapeName", TypeFilename,  Offset(debrisShapeName, ShapeBaseData));
   endGroup("Destruction");

   addGroup("Physics");
   addField("mass",           TypeF32,        Offset(mass,           ShapeBaseData));
   addField("drag",           TypeF32,        Offset(drag,           ShapeBaseData));
   addField("density",        TypeF32,        Offset(density,        ShapeBaseData));
   endGroup("Physics");

   addGroup("Damage/Energy");
   addField("maxEnergy",      TypeF32,        Offset(maxEnergy,      ShapeBaseData));
   addField("maxDamage",      TypeF32,        Offset(maxDamage,      ShapeBaseData));
   addField("disabledLevel",  TypeF32,        Offset(disabledLevel,  ShapeBaseData));
   addField("destroyedLevel", TypeF32,        Offset(destroyedLevel, ShapeBaseData));
   addField("repairRate",     TypeF32,        Offset(repairRate,     ShapeBaseData));
   addField("inheritEnergyFromMount", TypeBool, Offset(inheritEnergyFromMount, ShapeBaseData));
   addField("isInvincible",   TypeBool,       Offset(isInvincible,   ShapeBaseData));
   endGroup("Damage/Energy");

   addGroup("Camera");
#ifdef TGE_RPG /// TGE_Move
	addField("cameraDefaultDist",  TypeF32,        Offset(cameraDefaultDist,  ShapeBaseData));
#endif
   addField("cameraMaxDist",  TypeF32,        Offset(cameraMaxDist,  ShapeBaseData));
   addField("cameraMinDist",  TypeF32,        Offset(cameraMinDist,  ShapeBaseData));
#ifdef TGE_RPG /// TGE_Move
   addField("cameraDefaultPitch", TypeF32,      Offset(cameraDefaultPitch, ShapeBaseData));
   addField("cameraDefaultYaw", TypeF32,      Offset(cameraDefaultYaw, ShapeBaseData));
#endif
   addField("cameraDefaultFov", TypeF32,      Offset(cameraDefaultFov, ShapeBaseData));
   addField("cameraMinFov",   TypeF32,        Offset(cameraMinFov,   ShapeBaseData));
   addField("cameraMaxFov",   TypeF32,        Offset(cameraMaxFov,   ShapeBaseData));
   addField("firstPersonOnly", TypeBool,      Offset(firstPersonOnly, ShapeBaseData));
   addField("useEyePoint",     TypeBool,      Offset(useEyePoint,     ShapeBaseData));
   addField("observeThroughObject", TypeBool, Offset(observeThroughObject, ShapeBaseData));
   endGroup("Camera");

   // This hud code is going to get ripped out soon...
   addGroup("HUD", "@deprecated Likely to be removed soon.");
   addField("hudImageName",         TypeFilename,    Offset(hudImageNameFriendly, ShapeBaseData), NumHudRenderImages);
   addField("hudImageNameFriendly", TypeFilename,    Offset(hudImageNameFriendly, ShapeBaseData), NumHudRenderImages);
   addField("hudImageNameEnemy",    TypeFilename,    Offset(hudImageNameEnemy, ShapeBaseData), NumHudRenderImages);
   addField("hudRenderCenter",      TypeBool,      Offset(hudRenderCenter, ShapeBaseData), NumHudRenderImages);
   addField("hudRenderModulated",   TypeBool,      Offset(hudRenderModulated, ShapeBaseData), NumHudRenderImages);
   addField("hudRenderAlways",      TypeBool,      Offset(hudRenderAlways, ShapeBaseData), NumHudRenderImages);
   addField("hudRenderDistance",    TypeBool,      Offset(hudRenderDistance, ShapeBaseData), NumHudRenderImages);
   addField("hudRenderName",        TypeBool,      Offset(hudRenderName, ShapeBaseData), NumHudRenderImages);
   endGroup("HUD");

   addGroup("Misc");
   addField("aiAvoidThis",      TypeBool,        Offset(aiAvoidThis,    ShapeBaseData));
   addField("computeCRC",     TypeBool,       Offset(computeCRC,     ShapeBaseData));
   endGroup("Misc");

}

ConsoleMethod( ShapeBaseData, checkDeployPos, bool, 3, 3, "(Transform xform)")
{
   if (bool(object->shape) == false)
      return false;

   Point3F pos(0, 0, 0);
   AngAxisF aa(Point3F(0, 0, 1), 0);
   dSscanf(argv[2],"%g %g %g %g %g %g %g",
           &pos.x,&pos.y,&pos.z,&aa.axis.x,&aa.axis.y,&aa.axis.z,&aa.angle);
   MatrixF mat;
   aa.setMatrix(&mat);
   mat.setColumn(3,pos);

   Box3F objBox = object->shape->bounds;
   Point3F boxCenter = (objBox.min + objBox.max) * 0.5;
   objBox.min = boxCenter + (objBox.min - boxCenter) * 0.9;
   objBox.max = boxCenter + (objBox.max - boxCenter) * 0.9;

   Box3F wBox = objBox;
   mat.mul(wBox);

   EarlyOutPolyList polyList;
   polyList.mNormal.set(0,0,0);
   polyList.mPlaneList.clear();
   polyList.mPlaneList.setSize(6);
   polyList.mPlaneList[0].set(objBox.min,VectorF(-1,0,0));
   polyList.mPlaneList[1].set(objBox.max,VectorF(0,1,0));

⌨️ 快捷键说明

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