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

📄 tsmesh.cc

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

#include "ts/tsMesh.h"
#include "dgl/dgl.h"
#include "math/mMath.h"
#include "math/mathIO.h"
#include "ts/tsShape.h"
#include "console/console.h"
#include "ts/tsShapeInstance.h"
#include "sim/sceneObject.h"
#include "ts/tsSortedMesh.h"
#include "core/bitRender.h"
#include "collision/convex.h"
#include "core/frameAllocator.h"
#include "platform/profiler.h"

// Not worth the effort, much less the effort to comment, but if the draw types
// are consecutive use addition rather than a table to go from index to command value...
#if ((GL_TRIANGLES+1==GL_TRIANGLE_STRIP) && (GL_TRIANGLE_STRIP+1==GL_TRIANGLE_FAN))
   #define getDrawType(a) (GL_TRIANGLES+(a))
#else
   U32 drawTypes[] = { GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN };
   #define getDrawType(a) (drawTypes[a])
#endif

// structures used to share data between detail levels...
// used (and valid) during load only
Vector<Point3F*> TSMesh::smVertsList;
Vector<Point3F*> TSMesh::smNormsList;
Vector<U8*>      TSMesh::smEncodedNormsList;
Vector<Point2F*> TSMesh::smTVertsList;
Vector<bool>     TSMesh::smDataCopied;

Vector<Point3F>  TSMesh::smSaveVerts;
Vector<Point3F>  TSMesh::smSaveNorms;
Vector<Point2F>  TSMesh::smSaveTVerts;

Vector<MatrixF*> TSSkinMesh::smInitTransformList;
Vector<S32*>     TSSkinMesh::smVertexIndexList;
Vector<S32*>     TSSkinMesh::smBoneIndexList;
Vector<F32*>     TSSkinMesh::smWeightList;
Vector<S32*>     TSSkinMesh::smNodeIndexList;

Vector<Point3F> gNormalStore;

F32 TSMesh::overrideFadeVal = 1.0;

bool TSMesh::smUseTriangles = false; // convert all primitives to triangle lists on load
bool TSMesh::smUseOneStrip  = false; // join triangle strips into one long strip on load
S32  TSMesh::smMinStripSize = 1;     // smallest number of _faces_ allowed per strip (all else put in tri list)
bool TSMesh::smUseEncodedNormals = false;

// quick function to force object to face camera -- currently throws out roll :(
void forceFaceCamera()
{
   MatrixF mat;
   Point4F p;

   dglGetModelview(&mat);
   mat.getColumn(3,&p);
   mat.identity();
   mat.setColumn(3,p);
   dglLoadMatrix(&mat);
   if (TSShapeInstance::smRenderData.objectScale)
      glScalef(TSShapeInstance::smRenderData.objectScale->x,
               TSShapeInstance::smRenderData.objectScale->y,
               TSShapeInstance::smRenderData.objectScale->z);
}

void forceFaceCameraZAxis()
{
   MatrixF mat;
   dglGetModelview(&mat);
   Point3F z;
   mat.getColumn(2,&z); // this is where the z-axis goes, keep it here but reset x and y
   Point3F x,y;
   if (mFabs(z.y) < 0.99f)
   {
      // mCross(Point3F(0,1,0),tAxis,&x);
      x.set(z.z,0,-z.x);
      x.normalize();
      mCross(z,x,&y);
   }
   else
   {
      // mCross(z,Point3F(1,0,0),&y);
      y.set(0,z.z,-z.y);
      y.normalize();
      mCross(y,z,&x);
   }
   mat.setColumn(0,x);
   mat.setColumn(1,y);
   mat.setColumn(2,z);
   dglLoadMatrix(&mat);
   if (TSShapeInstance::smRenderData.objectScale)
      glScalef(TSShapeInstance::smRenderData.objectScale->x,TSShapeInstance::smRenderData.objectScale->y,TSShapeInstance::smRenderData.objectScale->z);
}

void TSMesh::saveMergeVerts()
{
   S32 startMerge = vertsPerFrame - mergeIndices.size();
   S32 j;
   for (j=0; j<mergeIndices.size(); j++)
   {
      smSaveVerts[j+mergeBufferStart]  = verts[j+startMerge];
      smSaveTVerts[j+mergeBufferStart] = tverts[j+startMerge];
   }
   F32 mult = TSShapeInstance::smRenderData.intraDetailLevel;
   for (j=0; j<mergeIndices.size(); j++)
   {
      verts[j+startMerge] *= mult;
      Point3F v = mergeIndices[j]<startMerge ? verts[mergeIndices[j]] : smSaveVerts[mergeIndices[j]-startMerge+mergeBufferStart];
      v *= 1.0f - mult;
      verts[j+startMerge] += v;

      tverts[j+startMerge] *= mult;
      Point2F tv = mergeIndices[j]<startMerge ? tverts[mergeIndices[j]] : smSaveTVerts[mergeIndices[j]-startMerge+mergeBufferStart];
      tv *= 1.0f - mult;
      tverts[j+startMerge] += tv;
   }
}

void TSMesh::restoreMergeVerts()
{
   S32 startMerge = vertsPerFrame - mergeIndices.size();
   for (S32 i=0; i<mergeIndices.size(); i++)
   {
      verts[i+startMerge] = smSaveVerts[i+mergeBufferStart];
      tverts[i+startMerge] = smSaveTVerts[i+mergeBufferStart];
   }
}

void TSMesh::saveMergeNormals()
{
   S32 startMerge = vertsPerFrame - mergeIndices.size();
   S32 j;
   smSaveNorms.setSize(mergeIndices.size());
   for (j=0; j<mergeIndices.size(); j++)
      smSaveNorms[j]  = norms[j+startMerge];
   F32 mult = TSShapeInstance::smRenderData.intraDetailLevel;
   for (j=0; j<mergeIndices.size(); j++)
   {
      norms[j+startMerge] *= mult;
      Point3F n = mergeIndices[j]<startMerge ? norms[mergeIndices[j]] : smSaveNorms[mergeIndices[j]-startMerge];
      n *= 1.0f - mult;
      norms[j+startMerge] += n;
      // norms[j+startMerge].normalize();
   }
}

void TSMesh::restoreMergeNormals()
{
   if (getFlags(UseEncodedNormals))
      return;

   S32 startMerge = vertsPerFrame - mergeIndices.size();
   for (S32 i=0; i<mergeIndices.size(); i++)
      norms[i+startMerge] = smSaveNorms[i];
}

//-----------------------------------------------------
// TSMesh render methods
//-----------------------------------------------------

void TSMesh::fillVB(S32 vb, S32 frame, S32 matFrame, TSMaterialList *materials)
{
   S32 firstVert  = vertsPerFrame * frame;
   S32 firstTVert = vertsPerFrame * matFrame;
   const Point3F *normals = getNormals(firstVert);

   // set up vertex arrays -- already enabled in TSShapeInstance::render
   glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
   glNormalPointer(GL_FLOAT,0,normals);
   glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);

   TSDrawPrimitive &draw = primitives[0];

   AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,
               "TSMesh::render: rendering of non-indexed meshes no longer supported");

   // we do this to enable texturing -- if necessary
   if (((TSShapeInstance::smRenderData.materialIndex ^ draw.matIndex) &
       (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial)) != 0)
      setMaterial(draw.matIndex,materials);

   glFillVertexBufferEXT(vb,0,vertsPerFrame);
}

void TSMesh::morphVB(S32 vb, S32 morph, S32 frame, S32 matFrame, TSMaterialList *materials)
{
   S32 firstVert  = vertsPerFrame * (frame+1) - morph;
   S32 firstTVert = vertsPerFrame * (matFrame+1) - morph;
   const Point3F *normals = getNormals(firstVert);

   saveMergeNormals(); // verts & tverts saved and restored on tsshapeinstance::setStatics

   // set up vertex arrays -- already enabled in TSShapeInstance::render
   glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
   glNormalPointer(GL_FLOAT,0,normals);
   glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);

   TSDrawPrimitive &draw = primitives[0];

   AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,
               "TSMesh::render: rendering of non-indexed meshes no longer supported");

   // we do this to enable texturing -- if necessary
   if (((TSShapeInstance::smRenderData.materialIndex ^ draw.matIndex) &
       (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial)) != 0)
      setMaterial(draw.matIndex,materials);

   glFillVertexBufferEXT(vb,0,morph);

   restoreMergeNormals();
}

void TSMesh::renderVB(S32 frame, S32 matFrame, TSMaterialList *materials)
{
   S32 firstVert  = vertsPerFrame * frame;
   S32 firstTVert = vertsPerFrame * matFrame;

   if (getFlags(Billboard))
   {
      if (getFlags(BillboardZAxis))
         forceFaceCameraZAxis();
      else
         forceFaceCamera();
   }

   const Point3F *normals = getNormals(firstVert);

   // lock...
   bool lockArrays = dglDoesSupportCompiledVertexArray();
   if (lockArrays)
      glLockArraysEXT(0,vertsPerFrame);

   for (S32 i=0; i<primitives.size(); i++)
   {
      PROFILE_START(TSShapeInstanceVBMat);
      TSDrawPrimitive &draw = primitives[i];

      AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,
                  "TSMesh::render: rendering of non-indexed meshes no longer supported");

      // material change?
      if (((TSShapeInstance::smRenderData.materialIndex ^ draw.matIndex) &
           (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial)) != 0)
         setMaterial(draw.matIndex,materials);
      PROFILE_END();

      PROFILE_START(TSShapeInstanceDE);
      S32 drawType = getDrawType(draw.matIndex>>30);

      glDrawElements(drawType,draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
      PROFILE_END();
   }

   // unlock...
   if (lockArrays)
      glUnlockArraysEXT();
}

void TSMesh::render(S32 frame, S32 matFrame, TSMaterialList * materials)
{
   if( vertsPerFrame <= 0 ) {
      return;
   }

   S32 firstVert  = vertsPerFrame * frame;
   S32 firstTVert = vertsPerFrame * matFrame;

   if (getFlags(Billboard))
   {
      if (getFlags(BillboardZAxis))
         forceFaceCameraZAxis();
      else
         forceFaceCamera();
   }

   const Point3F * normals = getNormals(firstVert);
   saveMergeNormals(); // verts & tverts saved and restored on tsshapeinstance::setStatics

   // set up vertex arrays -- already enabled in TSShapeInstance::render
   glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
   glNormalPointer(GL_FLOAT,0,normals);
   glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);
   if (TSShapeInstance::smRenderData.detailMapMethod == TSShapeInstance::DETAIL_MAP_MULTI_1 ||
       TSShapeInstance::smRenderData.detailMapMethod == TSShapeInstance::DETAIL_MAP_MULTI_2)
   {
      glClientActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.detailMapTE);
      glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);
      glClientActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
   }

   // lock...
   bool lockArrays = dglDoesSupportCompiledVertexArray();
   if (lockArrays)
      glLockArraysEXT(0,vertsPerFrame);

   for (S32 i=0; i<primitives.size(); i++)
   {
      TSDrawPrimitive & draw = primitives[i];
      AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,
                  "TSMesh::render: rendering of non-indexed meshes no longer supported");

      // material change?
      if ( ((TSShapeInstance::smRenderData.materialIndex ^ draw.matIndex) &
            (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial)) != 0)
         setMaterial(draw.matIndex,materials);

      S32 drawType = getDrawType(draw.matIndex>>30);

      glDrawElements(drawType,draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
   }

   // unlock...
   if (lockArrays)
      glUnlockArraysEXT();

   restoreMergeNormals();
}

const Point3F * TSMesh::getNormals(S32 firstVert)
{
   if (getFlags(UseEncodedNormals))
   {
      gNormalStore.setSize(vertsPerFrame);
      for (S32 i=0; i<encodedNorms.size(); i++)
         gNormalStore[i]=decodeNormal(encodedNorms[i+firstVert]);
      return gNormalStore.address();
   }
   return &norms[firstVert];
}

void TSMesh::initMaterials()
{

⌨️ 快捷键说明

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