tsMesh.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _TSMESH_H_
  23. #define _TSMESH_H_
  24. #ifndef _STREAM_H_
  25. #include "core/stream/stream.h"
  26. #endif
  27. #ifndef _MMATH_H_
  28. #include "math/mMath.h"
  29. #endif
  30. #ifndef _TVECTOR_H_
  31. #include "core/util/tVector.h"
  32. #endif
  33. #ifndef _ABSTRACTPOLYLIST_H_
  34. #include "collision/abstractPolyList.h"
  35. #endif
  36. #ifndef _GFXDEVICE_H_
  37. #include "gfx/gfxDevice.h"
  38. #endif
  39. #ifndef _GFXPRIMITIVEBUFFER_H_
  40. #include "gfx/gfxPrimitiveBuffer.h"
  41. #endif
  42. #ifndef _TSPARSEARRAY_H_
  43. #include "core/tSparseArray.h"
  44. #endif
  45. #include "core/util/safeDelete.h"
  46. #if defined(TORQUE_OS_XENON)
  47. //# define USE_MEM_VERTEX_BUFFERS
  48. #endif
  49. #if defined(USE_MEM_VERTEX_BUFFERS)
  50. # include "gfx/D3D9/360/gfx360MemVertexBuffer.h"
  51. #endif
  52. namespace Opcode { class Model; class MeshInterface; }
  53. namespace IceMaths { class IndexedTriangle; class Point; }
  54. class Convex;
  55. class SceneRenderState;
  56. class SceneObject;
  57. struct MeshRenderInst;
  58. class TSRenderState;
  59. class RenderPassManager;
  60. class TSMaterialList;
  61. class TSShapeInstance;
  62. struct RayInfo;
  63. class ConvexFeature;
  64. class ShapeBase;
  65. struct TSDrawPrimitive
  66. {
  67. enum
  68. {
  69. Triangles = 0 << 30, ///< bits 30 and 31 index element type
  70. Strip = 1 << 30, ///< bits 30 and 31 index element type
  71. Fan = 2 << 30, ///< bits 30 and 31 index element type
  72. Indexed = BIT(29), ///< use glDrawElements if indexed, glDrawArrays o.w.
  73. NoMaterial = BIT(28), ///< set if no material (i.e., texture missing)
  74. MaterialMask = ~(Strip|Fan|Triangles|Indexed|NoMaterial),
  75. TypeMask = Strip|Fan|Triangles
  76. };
  77. S32 start;
  78. S32 numElements;
  79. S32 matIndex; ///< holds material index & element type (see above enum)
  80. };
  81. #if defined(USE_MEM_VERTEX_BUFFERS)
  82. struct __NullVertexStruct {};
  83. typedef GFX360MemVertexBufferHandle<__NullVertexStruct> TSVertexBufferHandle;
  84. #else
  85. typedef GFXVertexBufferDataHandle TSVertexBufferHandle;
  86. #endif
  87. ///
  88. class TSMesh
  89. {
  90. friend class TSShape;
  91. public:
  92. struct TSMeshVertexArray;
  93. protected:
  94. U32 meshType;
  95. Box3F mBounds;
  96. Point3F mCenter;
  97. F32 mRadius;
  98. F32 mVisibility;
  99. bool mDynamic;
  100. const GFXVertexFormat *mVertexFormat;
  101. U32 mVertSize;
  102. TSVertexBufferHandle mVB;
  103. GFXPrimitiveBufferHandle mPB;
  104. void _convertToAlignedMeshData( TSMeshVertexArray &vertexData, const Vector<Point3F> &_verts, const Vector<Point3F> &_norms );
  105. void _createVBIB( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb );
  106. public:
  107. enum
  108. {
  109. /// types...
  110. StandardMeshType = 0,
  111. SkinMeshType = 1,
  112. DecalMeshType = 2,
  113. SortedMeshType = 3,
  114. NullMeshType = 4,
  115. TypeMask = StandardMeshType|SkinMeshType|DecalMeshType|SortedMeshType|NullMeshType,
  116. /// flags (stored with meshType)...
  117. Billboard = BIT(31), HasDetailTexture = BIT(30),
  118. BillboardZAxis = BIT(29), UseEncodedNormals = BIT(28),
  119. FlagMask = Billboard|BillboardZAxis|HasDetailTexture|UseEncodedNormals
  120. };
  121. U32 getMeshType() const { return meshType & TypeMask; }
  122. void setFlags(U32 flag) { meshType |= flag; }
  123. void clearFlags(U32 flag) { meshType &= ~flag; }
  124. U32 getFlags( U32 flag = 0xFFFFFFFF ) const { return meshType & flag; }
  125. const Point3F* getNormals( S32 firstVert );
  126. S32 parentMesh; ///< index into shapes mesh list
  127. S32 numFrames;
  128. S32 numMatFrames;
  129. S32 vertsPerFrame;
  130. /// @name Aligned Vertex Data
  131. /// @{
  132. #pragma pack(1)
  133. struct __TSMeshVertexBase
  134. {
  135. Point3F _vert;
  136. F32 _tangentW;
  137. Point3F _normal;
  138. Point3F _tangent;
  139. Point2F _tvert;
  140. const Point3F &vert() const { return _vert; }
  141. void vert(const Point3F &v) { _vert = v; }
  142. const Point3F &normal() const { return _normal; }
  143. void normal(const Point3F &n) { _normal = n; }
  144. Point4F tangent() const { return Point4F(_tangent.x, _tangent.y, _tangent.z, _tangentW); }
  145. void tangent(const Point4F &t) { _tangent = t.asPoint3F(); _tangentW = t.w; }
  146. const Point2F &tvert() const { return _tvert; }
  147. void tvert(const Point2F &tv) { _tvert = tv;}
  148. // Don't call these unless it's actually a __TSMeshVertex_3xUVColor, for real.
  149. // We don't want a vftable for virtual methods.
  150. Point2F &tvert2() const { return *reinterpret_cast<Point2F *>(reinterpret_cast<U8 *>(const_cast<__TSMeshVertexBase *>(this)) + 0x30); }
  151. void tvert2(const Point2F &tv) { (*reinterpret_cast<Point2F *>(reinterpret_cast<U8 *>(this) + 0x30)) = tv; }
  152. GFXVertexColor &color() const { return *reinterpret_cast<GFXVertexColor *>(reinterpret_cast<U8 *>(const_cast<__TSMeshVertexBase *>(this)) + 0x38); }
  153. void color(const GFXVertexColor &c) { (*reinterpret_cast<GFXVertexColor *>(reinterpret_cast<U8 *>(this) + 0x38)) = c; }
  154. };
  155. struct __TSMeshVertex_3xUVColor : public __TSMeshVertexBase
  156. {
  157. Point2F _tvert2;
  158. GFXVertexColor _color;
  159. F32 _tvert3; // Unused, but needed for alignment purposes
  160. };
  161. #pragma pack()
  162. struct TSMeshVertexArray
  163. {
  164. protected:
  165. U8 *base;
  166. dsize_t vertSz;
  167. bool vertexDataReady;
  168. U32 numElements;
  169. public:
  170. TSMeshVertexArray() : base(NULL), vertexDataReady(false), numElements(0) {}
  171. virtual ~TSMeshVertexArray() { set(NULL, 0, 0); }
  172. virtual void set(void *b, dsize_t s, U32 n, bool autoFree = true )
  173. {
  174. if(base && autoFree)
  175. dFree_aligned(base);
  176. base = reinterpret_cast<U8 *>(b);
  177. vertSz = s;
  178. numElements = n;
  179. }
  180. // Vector-like interface
  181. __TSMeshVertexBase &operator[](S32 idx) const { AssertFatal(idx < numElements, "Out of bounds access!"); return *reinterpret_cast<__TSMeshVertexBase *>(base + idx * vertSz); }
  182. __TSMeshVertexBase *address() const { return reinterpret_cast<__TSMeshVertexBase *>(base); }
  183. U32 size() const { return numElements; }
  184. dsize_t mem_size() const { return numElements * vertSz; }
  185. dsize_t vertSize() const { return vertSz; }
  186. bool isReady() const { return vertexDataReady; }
  187. void setReady(bool r) { vertexDataReady = r; }
  188. };
  189. bool mHasColor;
  190. bool mHasTVert2;
  191. TSMeshVertexArray mVertexData;
  192. dsize_t mNumVerts;
  193. virtual void convertToAlignedMeshData();
  194. /// @}
  195. /// @name Vertex data
  196. /// @{
  197. template<class T>
  198. class FreeableVector : public Vector<T>
  199. {
  200. public:
  201. bool free_memory() { return Vector<T>::resize(0); }
  202. FreeableVector<T>& operator=(const Vector<T>& p) { Vector<T>::operator=(p); return *this; }
  203. FreeableVector<T>& operator=(const FreeableVector<T>& p) { Vector<T>::operator=(p); return *this; }
  204. };
  205. FreeableVector<Point3F> verts;
  206. FreeableVector<Point3F> norms;
  207. FreeableVector<Point2F> tverts;
  208. FreeableVector<Point4F> tangents;
  209. // Optional second texture uvs.
  210. FreeableVector<Point2F> tverts2;
  211. // Optional vertex colors data.
  212. FreeableVector<ColorI> colors;
  213. /// @}
  214. Vector<TSDrawPrimitive> primitives;
  215. Vector<U8> encodedNorms;
  216. Vector<U32> indices;
  217. /// billboard data
  218. Point3F billboardAxis;
  219. /// @name Convex Hull Data
  220. /// Convex hulls are convex (no angles >= 180º) meshes used for collision
  221. /// @{
  222. Vector<Point3F> planeNormals;
  223. Vector<F32> planeConstants;
  224. Vector<U32> planeMaterials;
  225. S32 planesPerFrame;
  226. U32 mergeBufferStart;
  227. /// @}
  228. /// @name Render Methods
  229. /// @{
  230. /// This is used by sgShadowProjector to render the
  231. /// mesh directly, skipping the render manager.
  232. virtual void render( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb );
  233. void innerRender( TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb );
  234. virtual void render( TSMaterialList *,
  235. const TSRenderState &data,
  236. bool isSkinDirty,
  237. const Vector<MatrixF> &transforms,
  238. TSVertexBufferHandle &vertexBuffer,
  239. GFXPrimitiveBufferHandle &primitiveBuffer );
  240. void innerRender( TSMaterialList *, const TSRenderState &data, TSVertexBufferHandle &vb, GFXPrimitiveBufferHandle &pb );
  241. /// @}
  242. /// @name Material Methods
  243. /// @{
  244. void setFade( F32 fade ) { mVisibility = fade; }
  245. void clearFade() { setFade( 1.0f ); }
  246. /// @}
  247. /// @name Collision Methods
  248. /// @{
  249. virtual bool buildPolyList( S32 frame, AbstractPolyList * polyList, U32 & surfaceKey, TSMaterialList* materials );
  250. virtual bool getFeatures( S32 frame, const MatrixF&, const VectorF&, ConvexFeature*, U32 &surfaceKey );
  251. virtual void support( S32 frame, const Point3F &v, F32 *currMaxDP, Point3F *currSupport );
  252. virtual bool castRay( S32 frame, const Point3F & start, const Point3F & end, RayInfo * rayInfo, TSMaterialList* materials );
  253. virtual bool castRayRendered( S32 frame, const Point3F & start, const Point3F & end, RayInfo * rayInfo, TSMaterialList* materials );
  254. virtual bool buildConvexHull(); ///< returns false if not convex (still builds planes)
  255. bool addToHull( U32 idx0, U32 idx1, U32 idx2 );
  256. /// @}
  257. /// @name Bounding Methods
  258. /// calculate and get bounding information
  259. /// @{
  260. void computeBounds();
  261. virtual void computeBounds( const MatrixF &transform, Box3F &bounds, S32 frame = 0, Point3F *center = NULL, F32 *radius = NULL );
  262. void computeBounds( const Point3F *, S32 numVerts, S32 stride, const MatrixF &transform, Box3F &bounds, Point3F *center, F32 *radius );
  263. const Box3F& getBounds() const { return mBounds; }
  264. const Point3F& getCenter() const { return mCenter; }
  265. F32 getRadius() const { return mRadius; }
  266. virtual S32 getNumPolys() const;
  267. static U8 encodeNormal( const Point3F &normal );
  268. static const Point3F& decodeNormal( U8 ncode ) { return smU8ToNormalTable[ncode]; }
  269. /// @}
  270. /// persist methods...
  271. virtual void assemble( bool skip );
  272. static TSMesh* assembleMesh( U32 meshType, bool skip );
  273. virtual void disassemble();
  274. void createVBIB();
  275. void createTangents(const Vector<Point3F> &_verts, const Vector<Point3F> &_norms);
  276. void findTangent( U32 index1,
  277. U32 index2,
  278. U32 index3,
  279. Point3F *tan0,
  280. Point3F *tan1,
  281. const Vector<Point3F> &_verts);
  282. /// on load...optionally convert primitives to other form
  283. static bool smUseTriangles;
  284. static bool smUseOneStrip;
  285. static S32 smMinStripSize;
  286. static bool smUseEncodedNormals;
  287. /// Enables mesh instancing on non-skin meshes that
  288. /// have less that this count of verts.
  289. static S32 smMaxInstancingVerts;
  290. /// convert primitives on load...
  291. void convertToTris(const TSDrawPrimitive *primitivesIn, const S32 *indicesIn,
  292. S32 numPrimIn, S32 & numPrimOut, S32 & numIndicesOut,
  293. TSDrawPrimitive *primitivesOut, S32 *indicesOut) const;
  294. void convertToSingleStrip(const TSDrawPrimitive *primitivesIn, const S32 *indicesIn,
  295. S32 numPrimIn, S32 &numPrimOut, S32 &numIndicesOut,
  296. TSDrawPrimitive *primitivesOut, S32 *indicesOut) const;
  297. void leaveAsMultipleStrips(const TSDrawPrimitive *primitivesIn, const S32 *indicesIn,
  298. S32 numPrimIn, S32 &numPrimOut, S32 &numIndicesOut,
  299. TSDrawPrimitive *primitivesOut, S32 *indicesOut) const;
  300. /// methods used during assembly to share vertexand other info
  301. /// between meshes (and for skipping detail levels on load)
  302. S32* getSharedData32( S32 parentMesh, S32 size, S32 **source, bool skip );
  303. S8* getSharedData8( S32 parentMesh, S32 size, S8 **source, bool skip );
  304. /// @name Assembly Variables
  305. /// variables used during assembly (for skipping mesh detail levels
  306. /// on load and for sharing verts between meshes)
  307. /// @{
  308. static Vector<Point3F*> smVertsList;
  309. static Vector<Point3F*> smNormsList;
  310. static Vector<U8*> smEncodedNormsList;
  311. static Vector<Point2F*> smTVertsList;
  312. // Optional second texture uvs.
  313. static Vector<Point2F*> smTVerts2List;
  314. // Optional vertex colors.
  315. static Vector<ColorI*> smColorsList;
  316. static Vector<bool> smDataCopied;
  317. static const Point3F smU8ToNormalTable[];
  318. /// @}
  319. TSMesh();
  320. virtual ~TSMesh();
  321. Opcode::Model *mOptTree;
  322. Opcode::MeshInterface* mOpMeshInterface;
  323. IceMaths::IndexedTriangle* mOpTris;
  324. IceMaths::Point* mOpPoints;
  325. void prepOpcodeCollision();
  326. bool buildConvexOpcode( const MatrixF &mat, const Box3F &bounds, Convex *c, Convex *list );
  327. bool buildPolyListOpcode( const S32 od, AbstractPolyList *polyList, const Box3F &nodeBox, TSMaterialList *materials );
  328. bool castRayOpcode( const Point3F &start, const Point3F &end, RayInfo *rayInfo, TSMaterialList *materials );
  329. static const F32 VISIBILITY_EPSILON;
  330. };
  331. class TSSkinMesh : public TSMesh
  332. {
  333. public:
  334. struct BatchData
  335. {
  336. enum Constants
  337. {
  338. maxBonePerVert = 16, // Abitrarily chosen
  339. };
  340. /// @name Batch by vertex
  341. /// These are used for batches where each element is a vertex, built by
  342. /// iterating over 0..maxBonePerVert bone transforms
  343. /// @{
  344. struct TransformOp
  345. {
  346. S32 transformIndex;
  347. F32 weight;
  348. TransformOp() : transformIndex( -1 ), weight( -1.0f ) {}
  349. TransformOp( const S32 tIdx, const F32 w ) : transformIndex( tIdx ), weight( w ) {};
  350. };
  351. struct BatchedVertex
  352. {
  353. S32 vertexIndex;
  354. S32 transformCount;
  355. TransformOp transform[maxBonePerVert];
  356. BatchedVertex() : vertexIndex( -1 ), transformCount( -1 ) {}
  357. };
  358. Vector<BatchedVertex> vertexBatchOperations;
  359. /// @}
  360. /// @name Batch by Bone Transform
  361. /// These are used for batches where each element is a bone transform,
  362. /// and verts/normals are batch transformed against each element
  363. /// @{
  364. #pragma pack(1)
  365. dALIGN(
  366. struct BatchedVertWeight
  367. {
  368. Point3F vert; // Do not change the ordering of these members
  369. F32 weight;
  370. Point3F normal;
  371. S32 vidx;
  372. }
  373. ); // dALIGN
  374. #pragma pack()
  375. struct BatchedTransform
  376. {
  377. public:
  378. BatchedVertWeight *alignedMem;
  379. dsize_t numElements;
  380. Vector<BatchedVertWeight> *_tmpVec;
  381. BatchedTransform() : alignedMem(NULL), numElements(0), _tmpVec(NULL) {}
  382. virtual ~BatchedTransform()
  383. {
  384. if(alignedMem)
  385. dFree_aligned(alignedMem);
  386. alignedMem = NULL;
  387. SAFE_DELETE(_tmpVec);
  388. }
  389. };
  390. SparseArray<BatchedTransform> transformBatchOperations;
  391. Vector<S32> transformKeys;
  392. /// @}
  393. // # = num bones
  394. Vector<S32> nodeIndex;
  395. Vector<MatrixF> initialTransforms;
  396. // # = numverts
  397. Vector<Point3F> initialVerts;
  398. Vector<Point3F> initialNorms;
  399. };
  400. /// This method will build the batch operations and prepare the BatchData
  401. /// for use.
  402. void createBatchData();
  403. virtual void convertToAlignedMeshData();
  404. public:
  405. typedef TSMesh Parent;
  406. /// Structure containing data needed to batch skinning
  407. BatchData batchData;
  408. bool batchDataInitialized;
  409. /// vectors that define the vertex, weight, bone tuples
  410. Vector<F32> weight;
  411. Vector<S32> boneIndex;
  412. Vector<S32> vertexIndex;
  413. /// set verts and normals...
  414. void updateSkin( const Vector<MatrixF> &transforms, TSVertexBufferHandle &instanceVB, GFXPrimitiveBufferHandle &instancePB );
  415. // render methods..
  416. void render( TSVertexBufferHandle &instanceVB, GFXPrimitiveBufferHandle &instancePB );
  417. void render( TSMaterialList *,
  418. const TSRenderState &data,
  419. bool isSkinDirty,
  420. const Vector<MatrixF> &transforms,
  421. TSVertexBufferHandle &vertexBuffer,
  422. GFXPrimitiveBufferHandle &primitiveBuffer );
  423. // collision methods...
  424. bool buildPolyList( S32 frame, AbstractPolyList *polyList, U32 &surfaceKey, TSMaterialList *materials );
  425. bool castRay( S32 frame, const Point3F &start, const Point3F &end, RayInfo *rayInfo, TSMaterialList *materials );
  426. bool buildConvexHull(); // does nothing, skins don't use this
  427. void computeBounds( const MatrixF &transform, Box3F &bounds, S32 frame, Point3F *center, F32 *radius );
  428. /// persist methods...
  429. void assemble( bool skip );
  430. void disassemble();
  431. /// variables used during assembly (for skipping mesh detail levels
  432. /// on load and for sharing verts between meshes)
  433. static Vector<MatrixF*> smInitTransformList;
  434. static Vector<S32*> smVertexIndexList;
  435. static Vector<S32*> smBoneIndexList;
  436. static Vector<F32*> smWeightList;
  437. static Vector<S32*> smNodeIndexList;
  438. TSSkinMesh();
  439. };
  440. #endif // _TSMESH_H_