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

📄 tsshapeinstance.cc

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

#include "ts/tsShapeInstance.h"
#include "dgl/dgl.h"
#include "ts/tsLastDetail.h"
#include "console/consoleTypes.h"
#include "ts/tsDecal.h"
#include "platform/profiler.h"
#include "core/frameAllocator.h"

TSShapeInstance::RenderData   TSShapeInstance::smRenderData;
MatrixF *                     TSShapeInstance::ObjectInstance::smTransforms = NULL;
S32                           TSShapeInstance::smMaxSnapshotScale = 2;
bool                          TSShapeInstance::smNoRenderTranslucent = false;
bool                          TSShapeInstance::smNoRenderNonTranslucent = false;
F32                           TSShapeInstance::smDetailAdjust = 1.0f;
F32                           TSShapeInstance::smScreenError = 5.0f;
bool                          TSShapeInstance::smFogExemptionOn = false;
S32                           TSShapeInstance::smNumSkipRenderDetails = 0;
bool                          TSShapeInstance::smSkipFirstFog = false;
bool                          TSShapeInstance::smSkipFog = false;

Vector<QuatF>                 TSShapeInstance::smNodeCurrentRotations(__FILE__, __LINE__);
Vector<Point3F>               TSShapeInstance::smNodeCurrentTranslations(__FILE__, __LINE__);
Vector<F32>                   TSShapeInstance::smNodeCurrentUniformScales(__FILE__, __LINE__);
Vector<Point3F>               TSShapeInstance::smNodeCurrentAlignedScales(__FILE__, __LINE__);
Vector<TSScale>               TSShapeInstance::smNodeCurrentArbitraryScales(__FILE__, __LINE__);

Vector<TSThread*>             TSShapeInstance::smRotationThreads(__FILE__, __LINE__);
Vector<TSThread*>             TSShapeInstance::smTranslationThreads(__FILE__, __LINE__);
Vector<TSThread*>             TSShapeInstance::smScaleThreads(__FILE__, __LINE__);

namespace {

void tsShapeTextureEventCB(const U32 eventCode, void *userData)
{
   TSShape* pShape = reinterpret_cast<TSShape*>(userData);

   if (eventCode == TextureManager::BeginZombification &&
      pShape->mVertexBuffer != -1)
   {
      // ideally we would de-register the callback here, but that would screw up the loop
      if (dglDoesSupportVertexBuffer())
         glFreeVertexBufferEXT(pShape->mVertexBuffer);
      else
         AssertFatal(false,"Vertex buffer should have already been freed!");
      pShape->mVertexBuffer = -1;
      for (S32 i = 0; i < pShape->objects.size(); ++i)
         pShape->mPreviousMerge[i] = -1;
   }
}
}

//-------------------------------------------------------------------------------------
// constructors, destructors, initialization
//-------------------------------------------------------------------------------------

TSShapeInstance::TSShapeInstance(const Resource<TSShape> & shape, bool loadMaterials)
{
   VECTOR_SET_ASSOCIATION(mMeshObjects);
   VECTOR_SET_ASSOCIATION(mDecalObjects);
   VECTOR_SET_ASSOCIATION(mIflMaterialInstances);
   VECTOR_SET_ASSOCIATION(mNodeTransforms);
   VECTOR_SET_ASSOCIATION(mNodeReferenceRotations);
   VECTOR_SET_ASSOCIATION(mNodeReferenceTranslations);
   VECTOR_SET_ASSOCIATION(mNodeReferenceUniformScales);
   VECTOR_SET_ASSOCIATION(mNodeReferenceScaleFactors);
   VECTOR_SET_ASSOCIATION(mNodeReferenceArbitraryScaleRots);
   VECTOR_SET_ASSOCIATION(mThreadList);
   VECTOR_SET_ASSOCIATION(mTransitionThreads);

   // check all skin modifier slots
   for (U32 ss=0; ss<MaxSkinModifiers; ss++)
      mSkinModifiers[ss].skinName = StringTable->getBlank();

   hShape = shape;
   mShape = hShape;
   buildInstanceData(mShape, loadMaterials);

}

TSShapeInstance::TSShapeInstance(TSShape * _shape, bool loadMaterials)
{
   VECTOR_SET_ASSOCIATION(mMeshObjects);
   VECTOR_SET_ASSOCIATION(mDecalObjects);
   VECTOR_SET_ASSOCIATION(mIflMaterialInstances);
   VECTOR_SET_ASSOCIATION(mNodeTransforms);
   VECTOR_SET_ASSOCIATION(mNodeReferenceRotations);
   VECTOR_SET_ASSOCIATION(mNodeReferenceTranslations);
   VECTOR_SET_ASSOCIATION(mNodeReferenceUniformScales);
   VECTOR_SET_ASSOCIATION(mNodeReferenceScaleFactors);
   VECTOR_SET_ASSOCIATION(mNodeReferenceArbitraryScaleRots);
   VECTOR_SET_ASSOCIATION(mThreadList);
   VECTOR_SET_ASSOCIATION(mTransitionThreads);

   // check all skin modifier slots
	for (U32 ss=0; ss<MaxSkinModifiers; ss++)
      mSkinModifiers[ss].skinName = StringTable->getBlank();

   mShape = _shape;
   buildInstanceData(mShape, loadMaterials);


}

TSShapeInstance::~TSShapeInstance()
{
   S32 i;
   for (i=0; i<mMeshObjects.size(); i++)
      destructInPlace(&mMeshObjects[i]);

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

   while (mThreadList.size())
      destroyThread(mThreadList.last());

   clearSkinModifiers();//skin modifier

   setMaterialList(NULL);

   delete [] mDirtyFlags;
}

void TSShapeInstance::init()
{
   smRenderData.fogTexture = false;
   smRenderData.fogBitmap = NULL;
   smRenderData.fogHandle = NULL;
   smRenderData.fogMapHandle = NULL;
   smRenderData.renderDecals = true;

   Con::addVariable("$pref::TS::fogTexture",    TypeBool, &smRenderData.fogTexture);
   Con::addVariable("$pref::TS::detailAdjust",  TypeF32,  &smDetailAdjust);
   Con::addVariable("$pref::TS::skipLoadDLs",   TypeS32,  &TSShape::smNumSkipLoadDetails);
   Con::addVariable("$pref::TS::skipRenderDLs", TypeS32,  &smNumSkipRenderDetails);
   Con::addVariable("$pref::TS::skipFirstFog",  TypeBool, &smSkipFirstFog);
   Con::addVariable("$pref::TS::screenError",   TypeF32,  &smScreenError);
   Con::addVariable("$pref::TS::UseTriangles",  TypeBool, &TSMesh::smUseTriangles);
}

void TSShapeInstance::destroy()
{
   delete smRenderData.fogHandle;
}

void TSShapeInstance::buildInstanceData(TSShape * _shape, bool loadMaterials)
{
   S32 i,dl;

   mShape = _shape;

   debrisRefCount = 0;

   mEnvironmentMapOn = false;
   mEnvironmentMapAlpha = 0.f;
   mAllowTwoPassEnvironmentMap = false;
   mAlphaIsReflectanceMap = true; // turn this off below if we find an exception
   mAllowTwoPassDetailMap = true;

   mMaxEnvironmentMapDL = 1;            // for shapes < version 23

   mMaxDetailMapDL = 0;

   // clear callback function and data
   mCallback = NULL;
   mCallbackData = 0;

   mCurrentDetailLevel = 0;
   mCurrentIntraDetailLevel = 1.0f;

   // all triggers off at start
   mTriggerStates = 0;

   //
   mAlphaAlways = false;
   mAlphaAlwaysValue = 1.0f;

   mBalloonShape = false;
   mBalloonValue = 1.0f;

   mUseOverrideTexture = false;

   // if never set, never draw fog -- do this here just in case
   smRenderData.fogOn = false;

   // material list...
   mMaterialList = NULL;
   mOwnMaterialList = false;

   //
   mData = 0;
   mScaleCurrentlyAnimated = false;

   if(loadMaterials)
   {
      setMaterialList(mShape->materialList);
   }

   // set up node data
   S32 numNodes = mShape->nodes.size();
   mNodeTransforms.setSize(numNodes);

   // add objects to trees
   S32 numObjects = mShape->objects.size();
   mMeshObjects.setSize(numObjects);
   for (i=0; i<numObjects; i++)
   {
      const TSObject * obj = &mShape->objects[i];
      MeshObjectInstance * objInst = &mMeshObjects[i];

      // call objInst constructor
      constructInPlace(objInst);

      // hook up the object to it's node
      objInst->nodeIndex = obj->nodeIndex;

      // set up list of meshes
      if (obj->numMeshes)
         objInst->meshList = &mShape->meshes[obj->startMeshIndex];
      else
         objInst->meshList = NULL;

      objInst->object = obj;
   }

   // set up decal objects
   mDecalObjects.setSize(mShape->decals.size());
   for (i=0; i<mShape->decals.size(); i++)
   {
      const TSShape::Decal * decal = &mShape->decals[i];
      DecalObjectInstance * decalInst = &mDecalObjects[i];

      // call constructor
      constructInPlace(decalInst);
      decalInst->decalObject = decal;

      // hook up to node
      decalInst->targetObject = &mMeshObjects[decal->objectIndex];
      decalInst->nodeIndex = decalInst->targetObject->nodeIndex;

      // set up list of decal meshes
      if (decal->numMeshes)
      {
         decalInst->decalList = (TSDecalMesh**)&mShape->meshes[decal->startMeshIndex];
         for (S32 j=0; j<decal->numMeshes; j++)
            if (decalInst->getDecalMesh(j))
            {
               // point the decal mesh at it's target...
               // this is safe since meshes aren't shared between shapes
               TSDecalMesh * decalMesh = const_cast<TSDecalMesh*>(decalInst->getDecalMesh(j));
               decalMesh->targetMesh = decalInst->targetObject->getMesh(j);
               if (!decalMesh->targetMesh)
               {
                  // detecting this a little late, but we don't need this decal since it isn't doing anything
                  // should only happen on shapes exported before dtsexp 1.18
                  delete decalMesh;
                  TSDecalMesh ** dm = const_cast<TSDecalMesh**>(decalInst->decalList+j);
                  *dm = NULL;
               }
            }
      }
      else
         decalInst->decalList = NULL;
      decalInst->frame = mShape->decalStates[i].frameIndex;
   }

   // construct ifl material objects
   if(loadMaterials)
   {
      for (i=0; i<mShape->iflMaterials.size(); i++)
      {
         mIflMaterialInstances.increment();
         mIflMaterialInstances.last().iflMaterial = &mShape->iflMaterials[i];
         mIflMaterialInstances.last().frame = -1;
      }
   }

   // check to see which dl's have detail texturing
   mMaxDetailMapDL = -1;
   if(loadMaterials)
   {
      for (dl=0; dl<mShape->details.size(); dl++)
      {
         // check meshes on this detail level...
         S32 ss = mShape->details[dl].subShapeNum;
         S32 od = mShape->details[dl].objectDetailNum;
         if (ss<0)
            continue; // this is a billboard detail level
         S32 start = mShape->subShapeFirstObject[ss];
         S32 end = mShape->subShapeNumObjects[ss] + start;
         for (i=start; i<end; i++)
         {
            TSMesh * mesh = mMeshObjects[i].getMesh(od);
            if (!mesh)
               continue;
            for (S32 j=0; j<mesh->primitives.size(); j++)
            {
               if (mesh->primitives[j].matIndex & TSDrawPrimitive::NoMaterial)
                  continue;
               if (mMaterialList->getDetailMap(mesh->primitives[j].matIndex & TSDrawPrimitive::MaterialMask))
               {
                  mesh->setFlags(TSMesh::HasDetailTexture);
                  if (dl>mMaxDetailMapDL)
                     mMaxDetailMapDL = dl;
               }
            }
         }
      }
   }

   // set up subtree data
   S32 ss = mShape->subShapeFirstNode.size(); // we have this many subtrees
   mDirtyFlags = new U32[ss];

   mGroundThread = NULL;
   mCurrentDetailLevel = 0;

   animateSubtrees();

   // Construct billboards if not done already
   if(loadMaterials)
      ((TSShape *) mShape)->setupBillboardDetails(this);

   // Scan out the collision hulls...
   for (U32 i = 0; i < 16; i++)
   {
      char buff[128];
      dSprintf(buff, sizeof(buff), "Collision-%d", i + 1);
      S32 colDetail = mShape->findDetail(buff);
      if (colDetail != -1)
      {
         S32 dl = colDetail;

         // get subshape and object detail
         const TSDetail * detail = &mShape->details[dl];
         S32 ss = detail->subShapeNum;
         S32 od = detail->objectDetailNum;

         S32 start = mShape->subShapeFirstObject[ss];
         S32 end   = mShape->subShapeNumObjects[ss] + start;
         if (start<end)
         {
            // run through objects and validate names...
            for (S32 i=start; i<end; i++)
            {
               MeshObjectInstance * mesh = &mMeshObjects[i];

               if (od >= mesh->object->numMeshes)
                  continue;

               // Yell at them if they named something!
               if (dStrnicmp(mShape->names[mesh->object->nameIndex], "Col", 3) != 0 && dStrnicmp(mShape->names[mesh->object->nameIndex], "LOSCol", 3) != 0)
               {
                  Con::errorf("%s.dts - Collision mesh names should start with Col or LOSCol, encountered '%s' in detail level %d", mShape->mSourceResource->path,mShape->names[mesh->object->nameIndex], dl);
                  continue;
               }
            }
         }

      }
   }
}

void TSShapeInstance::setMaterialList(TSMaterialList * ml)
{
   // get rid of old list
   if (mOwnMaterialList)
      delete mMaterialList;
   mMaterialList = ml;
   mOwnMaterialList = false;

   if (mMaterialList && StringTable) // material lists need the string table to load...
   {
      // read ifl materials if necessary -- this is here rather than in shape because we can't open 2 files at once :(
      if (mShape->materialList == mMaterialList)
         ((TSShape*)mShape)->readIflMaterials(hShape.getFilePath());

      mMaterialList->load(MeshTexture,hShape.getFilePath(),true);

      // check for reflectance map not in alpha of texture -- will require more work to emap
      for (U32 i=0; i<mMaterialList->getMaterialCount(); i++)
      {
         if (mMaterialList->getFlags(i) & (TSMaterialList::AuxiliaryMap|TSMaterialList::NeverEnvMap))
            continue;
         if (!mMaterialList->reflectionInAlpha(i))
         {
            mAlphaIsReflectanceMap = false;
            break; // found our exception
         }
      }
   }
}

void TSShapeInstance::cloneMaterialList()
{
   if (mOwnMaterialList)

⌨️ 快捷键说明

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