2012-09-19 15:15:01 +00:00
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
# ifndef _TSMESH_H_
# define _TSMESH_H_
# ifndef _STREAM_H_
# include "core/stream/stream.h"
# endif
# ifndef _MMATH_H_
# include "math/mMath.h"
# endif
# ifndef _TVECTOR_H_
# include "core/util/tVector.h"
# endif
# ifndef _ABSTRACTPOLYLIST_H_
# include "collision/abstractPolyList.h"
# endif
# ifndef _GFXDEVICE_H_
# include "gfx/gfxDevice.h"
# endif
# ifndef _GFXPRIMITIVEBUFFER_H_
# include "gfx/gfxPrimitiveBuffer.h"
# endif
# ifndef _TSPARSEARRAY_H_
# include "core/tSparseArray.h"
# endif
# include "core/util/safeDelete.h"
namespace Opcode { class Model ; class MeshInterface ; }
namespace IceMaths { class IndexedTriangle ; class Point ; }
class Convex ;
class SceneRenderState ;
class SceneObject ;
struct MeshRenderInst ;
class TSRenderState ;
class RenderPassManager ;
class TSMaterialList ;
class TSShapeInstance ;
struct RayInfo ;
class ConvexFeature ;
class ShapeBase ;
struct TSDrawPrimitive
{
enum
{
Triangles = 0 < < 30 , ///< bits 30 and 31 index element type
Strip = 1 < < 30 , ///< bits 30 and 31 index element type
Fan = 2 < < 30 , ///< bits 30 and 31 index element type
Indexed = BIT ( 29 ) , ///< use glDrawElements if indexed, glDrawArrays o.w.
NoMaterial = BIT ( 28 ) , ///< set if no material (i.e., texture missing)
MaterialMask = ~ ( Strip | Fan | Triangles | Indexed | NoMaterial ) ,
TypeMask = Strip | Fan | Triangles
} ;
S32 start ;
S32 numElements ;
S32 matIndex ; ///< holds material index & element type (see above enum)
} ;
typedef GFXVertexBufferDataHandle TSVertexBufferHandle ;
2015-01-10 19:41:25 +00:00
class TSMesh ;
class TSShapeAlloc ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
/// @name Vertex format serialization
/// {
struct TSBasicVertexFormat
2012-09-19 15:15:01 +00:00
{
2015-01-10 19:41:25 +00:00
S16 texCoordOffset ;
S16 boneOffset ;
S16 colorOffset ;
S16 numBones ;
S16 vertexSize ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
TSBasicVertexFormat ( ) ;
TSBasicVertexFormat ( TSMesh * mesh ) ;
void getFormat ( GFXVertexFormat & fmt ) ;
void calculateSize ( ) ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
void writeAlloc ( TSShapeAlloc * alloc ) ;
void readAlloc ( TSShapeAlloc * alloc ) ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
void addMeshRequirements ( TSMesh * mesh ) ;
} ;
/// }
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
///
class TSMesh
{
friend class TSShape ;
public :
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
/// Helper class for a freeable vector
template < class T >
class FreeableVector : public Vector < T >
2012-09-19 15:15:01 +00:00
{
2015-01-10 19:41:25 +00:00
public :
bool free_memory ( ) { return Vector < T > : : resize ( 0 ) ; }
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
FreeableVector < T > & operator = ( const Vector < T > & p ) { Vector < T > : : operator = ( p ) ; return * this ; }
FreeableVector < T > & operator = ( const FreeableVector < T > & p ) { Vector < T > : : operator = ( p ) ; return * this ; }
2012-09-19 15:15:01 +00:00
} ;
2015-01-10 19:41:25 +00:00
/// @name Aligned Vertex Data
/// {
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
# pragma pack(1)
2012-09-19 15:15:01 +00:00
struct __TSMeshVertexBase
{
Point3F _vert ;
F32 _tangentW ;
Point3F _normal ;
Point3F _tangent ;
Point2F _tvert ;
const Point3F & vert ( ) const { return _vert ; }
void vert ( const Point3F & v ) { _vert = v ; }
const Point3F & normal ( ) const { return _normal ; }
void normal ( const Point3F & n ) { _normal = n ; }
Point4F tangent ( ) const { return Point4F ( _tangent . x , _tangent . y , _tangent . z , _tangentW ) ; }
void tangent ( const Point4F & t ) { _tangent = t . asPoint3F ( ) ; _tangentW = t . w ; }
const Point2F & tvert ( ) const { return _tvert ; }
2015-01-10 19:41:25 +00:00
void tvert ( const Point2F & tv ) { _tvert = tv ; }
2012-09-19 15:15:01 +00:00
} ;
2015-01-10 19:41:25 +00:00
struct __TSMeshVertex_3xUVColor
2012-09-19 15:15:01 +00:00
{
Point2F _tvert2 ;
GFXVertexColor _color ;
2015-01-10 19:41:25 +00:00
const Point2F & tvert2 ( ) const { return _tvert2 ; }
void tvert2 ( const Point2F & c ) { _tvert2 = c ; }
const GFXVertexColor & color ( ) const { return _color ; }
void color ( const GFXVertexColor & c ) { _color = c ; }
2012-09-19 15:15:01 +00:00
} ;
2015-01-10 19:41:25 +00:00
struct __TSMeshIndex_List {
U8 x ;
U8 y ;
U8 z ;
U8 w ;
} ;
struct __TSMeshVertex_BoneData
{
__TSMeshIndex_List _indexes ;
Point4F _weights ;
const __TSMeshIndex_List & index ( ) const { return _indexes ; }
void index ( const __TSMeshIndex_List & c ) { _indexes = c ; }
const Point4F & weight ( ) const { return _weights ; }
void weight ( const Point4F & w ) { _weights = w ; }
} ;
2012-09-19 15:15:01 +00:00
# pragma pack()
struct TSMeshVertexArray
{
protected :
U8 * base ;
dsize_t vertSz ;
U32 numElements ;
2015-01-10 19:41:25 +00:00
U32 colorOffset ;
U32 boneOffset ;
bool vertexDataReady ;
bool ownsData ;
2012-09-19 15:15:01 +00:00
public :
2020-05-11 20:40:55 +00:00
TSMeshVertexArray ( ) : base ( NULL ) , vertSz ( 0 ) , numElements ( 0 ) , colorOffset ( 0 ) , boneOffset ( 0 ) , vertexDataReady ( false ) , ownsData ( false ) { }
2015-01-10 19:41:25 +00:00
virtual ~ TSMeshVertexArray ( ) { set ( NULL , 0 , 0 , 0 , 0 ) ; }
virtual void set ( void * b , dsize_t s , U32 n , S32 inColorOffset , S32 inBoneOffset , bool nowOwnsData = true )
{
if ( base & & ownsData )
dFree_aligned ( base ) ;
base = reinterpret_cast < U8 * > ( b ) ;
vertSz = s ;
numElements = n ;
colorOffset = inColorOffset > = 0 ? inColorOffset : 0 ;
boneOffset = inBoneOffset > = 0 ? inBoneOffset : 0 ;
ownsData = nowOwnsData ;
}
/// Gets pointer to __TSMeshVertexBase for vertex idx
__TSMeshVertexBase & getBase ( int idx ) const
{
AssertFatal ( idx < numElements , " Out of bounds access! " ) ; return * reinterpret_cast < __TSMeshVertexBase * > ( base + ( idx * vertSz ) ) ;
}
/// Gets pointer to __TSMeshVertex_3xUVColor for vertex idx
__TSMeshVertex_3xUVColor & getColor ( int idx ) const
{
AssertFatal ( idx < numElements , " Out of bounds access! " ) ; return * reinterpret_cast < __TSMeshVertex_3xUVColor * > ( base + ( idx * vertSz ) + colorOffset ) ;
}
/// Gets pointer to __TSMeshVertex_BoneData for vertex idx, additionally offsetted by subBoneList
__TSMeshVertex_BoneData & getBone ( int idx , int subBoneList ) const
{
AssertFatal ( idx < numElements , " Out of bounds access! " ) ; return * reinterpret_cast < __TSMeshVertex_BoneData * > ( base + ( idx * vertSz ) + boneOffset + ( sizeof ( __TSMeshVertex_BoneData ) * subBoneList ) ) ;
}
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
/// Returns base address of vertex data
__TSMeshVertexBase * address ( ) const
2012-09-19 15:15:01 +00:00
{
2015-01-10 19:41:25 +00:00
return reinterpret_cast < __TSMeshVertexBase * > ( base ) ;
2012-09-19 15:15:01 +00:00
}
U32 size ( ) const { return numElements ; }
dsize_t mem_size ( ) const { return numElements * vertSz ; }
dsize_t vertSize ( ) const { return vertSz ; }
bool isReady ( ) const { return vertexDataReady ; }
void setReady ( bool r ) { vertexDataReady = r ; }
2015-01-10 19:41:25 +00:00
U8 * getPtr ( ) { return base ; }
inline U32 getColorOffset ( ) const { return colorOffset ; }
inline U32 getBoneOffset ( ) const { return boneOffset ; }
2012-09-19 15:15:01 +00:00
} ;
2015-01-10 19:41:25 +00:00
protected :
2012-09-19 15:15:01 +00:00
2018-03-13 19:53:23 +00:00
U32 mMeshType ;
2024-12-12 14:32:20 +00:00
2015-01-10 19:41:25 +00:00
Point3F mCenter ;
F32 mRadius ;
F32 mVisibility ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
const GFXVertexFormat * mVertexFormat ;
2012-09-19 15:15:01 +00:00
2018-03-13 19:53:23 +00:00
TSMesh * mParentMeshObject ; ///< Current parent object instance
2015-01-10 19:41:25 +00:00
U32 mPrimBufferOffset ;
GFXVertexBufferDataHandle mVB ;
GFXPrimitiveBufferHandle mPB ;
public :
2018-03-13 16:36:36 +00:00
S32 mParentMesh ; ///< index into shapes mesh list
2015-01-10 19:41:25 +00:00
S32 numFrames ;
S32 numMatFrames ;
S32 vertsPerFrame ;
2024-12-12 14:32:20 +00:00
Box3F mBounds ;
2015-01-10 19:41:25 +00:00
U32 mVertOffset ;
U32 mVertSize ;
protected :
void _convertToVertexData ( TSMeshVertexArray & outArray , const Vector < Point3F > & _verts , const Vector < Point3F > & _norms ) ;
public :
enum
2012-09-19 15:15:01 +00:00
{
2015-01-10 19:41:25 +00:00
/// types...
StandardMeshType = 0 ,
SkinMeshType = 1 ,
DecalMeshType = 2 ,
SortedMeshType = 3 ,
NullMeshType = 4 ,
TypeMask = StandardMeshType | SkinMeshType | DecalMeshType | SortedMeshType | NullMeshType ,
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
/// flags (stored with meshType)...
Billboard = BIT ( 31 ) , HasDetailTexture = BIT ( 30 ) ,
BillboardZAxis = BIT ( 29 ) , UseEncodedNormals = BIT ( 28 ) ,
HasColor = BIT ( 27 ) , HasTVert2 = BIT ( 26 ) ,
FlagMask = Billboard | BillboardZAxis | HasDetailTexture | UseEncodedNormals | HasColor | HasTVert2
2012-09-19 15:15:01 +00:00
} ;
2018-03-13 19:53:23 +00:00
U32 getMeshType ( ) const { return mMeshType & TypeMask ; }
U32 getHasColor ( ) const { return mColors . size ( ) > 0 | | mMeshType & HasColor ; }
U32 getHasTVert2 ( ) const { return mTverts2 . size ( ) > 0 | | mMeshType & HasTVert2 ; }
void setFlags ( U32 flag ) { mMeshType | = flag ; }
void clearFlags ( U32 flag ) { mMeshType & = ~ flag ; }
U32 getFlags ( U32 flag = 0xFFFFFFFF ) const { return mMeshType & flag ; }
2015-01-10 19:41:25 +00:00
const Point3F * getNormals ( S32 firstVert ) ;
TSMeshVertexArray mVertexData ;
U32 mNumVerts ; ///< Number of verts allocated in main vertex buffer
virtual void convertToVertexData ( ) ;
virtual void copySourceVertexDataFrom ( const TSMesh * srcMesh ) ;
/// @}
/// @name Vertex data
/// @{
2018-03-13 19:53:23 +00:00
FreeableVector < Point3F > mVerts ;
FreeableVector < Point3F > mNorms ;
FreeableVector < Point2F > mTverts ;
FreeableVector < Point4F > mTangents ;
2012-09-19 15:15:01 +00:00
// Optional second texture uvs.
2018-03-13 19:53:23 +00:00
FreeableVector < Point2F > mTverts2 ;
2012-09-19 15:15:01 +00:00
// Optional vertex colors data.
2018-03-13 19:53:23 +00:00
FreeableVector < ColorI > mColors ;
2012-09-19 15:15:01 +00:00
/// @}
2018-03-13 19:53:23 +00:00
Vector < TSDrawPrimitive > mPrimitives ;
Vector < U8 > mEncodedNorms ;
2018-03-13 16:36:36 +00:00
Vector < U32 > mIndices ;
2012-09-19 15:15:01 +00:00
/// billboard data
2018-03-13 19:53:23 +00:00
Point3F mBillboardAxis ;
2012-09-19 15:15:01 +00:00
/// @name Convex Hull Data
2020-05-11 20:40:55 +00:00
/// Convex hulls are convex (no angles >= 180º) meshes used for collision
2012-09-19 15:15:01 +00:00
/// @{
2018-03-13 19:53:23 +00:00
Vector < Point3F > mPlaneNormals ;
Vector < F32 > mPlaneConstants ;
Vector < U32 > mPlaneMaterials ;
S32 mPlanesPerFrame ;
U32 mMergeBufferStart ;
2012-09-19 15:15:01 +00:00
/// @}
/// @name Render Methods
/// @{
/// This is used by sgShadowProjector to render the
/// mesh directly, skipping the render manager.
2015-01-10 19:41:25 +00:00
virtual void render ( TSVertexBufferHandle & vb ) ;
2012-09-19 15:15:01 +00:00
void innerRender ( TSVertexBufferHandle & vb , GFXPrimitiveBufferHandle & pb ) ;
virtual void render ( TSMaterialList * ,
const TSRenderState & data ,
bool isSkinDirty ,
const Vector < MatrixF > & transforms ,
TSVertexBufferHandle & vertexBuffer ,
2015-01-10 19:41:25 +00:00
const char * meshName ) ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
void innerRender ( TSMaterialList * , const TSRenderState & data , TSVertexBufferHandle & vb , GFXPrimitiveBufferHandle & pb , const char * meshName ) ;
2012-09-19 15:15:01 +00:00
/// @}
/// @name Material Methods
/// @{
void setFade ( F32 fade ) { mVisibility = fade ; }
void clearFade ( ) { setFade ( 1.0f ) ; }
/// @}
/// @name Collision Methods
/// @{
virtual bool buildPolyList ( S32 frame , AbstractPolyList * polyList , U32 & surfaceKey , TSMaterialList * materials ) ;
virtual bool getFeatures ( S32 frame , const MatrixF & , const VectorF & , ConvexFeature * , U32 & surfaceKey ) ;
virtual void support ( S32 frame , const Point3F & v , F32 * currMaxDP , Point3F * currSupport ) ;
virtual bool castRay ( S32 frame , const Point3F & start , const Point3F & end , RayInfo * rayInfo , TSMaterialList * materials ) ;
virtual bool castRayRendered ( S32 frame , const Point3F & start , const Point3F & end , RayInfo * rayInfo , TSMaterialList * materials ) ;
virtual bool buildConvexHull ( ) ; ///< returns false if not convex (still builds planes)
bool addToHull ( U32 idx0 , U32 idx1 , U32 idx2 ) ;
/// @}
/// @name Bounding Methods
/// calculate and get bounding information
/// @{
void computeBounds ( ) ;
virtual void computeBounds ( const MatrixF & transform , Box3F & bounds , S32 frame = 0 , Point3F * center = NULL , F32 * radius = NULL ) ;
void computeBounds ( const Point3F * , S32 numVerts , S32 stride , const MatrixF & transform , Box3F & bounds , Point3F * center , F32 * radius ) ;
const Box3F & getBounds ( ) const { return mBounds ; }
const Point3F & getCenter ( ) const { return mCenter ; }
F32 getRadius ( ) const { return mRadius ; }
virtual S32 getNumPolys ( ) const ;
static U8 encodeNormal ( const Point3F & normal ) ;
static const Point3F & decodeNormal ( U8 ncode ) { return smU8ToNormalTable [ ncode ] ; }
/// @}
2015-01-10 19:41:25 +00:00
virtual U32 getMaxBonesPerVert ( ) { return 0 ; }
2012-09-19 15:15:01 +00:00
/// persist methods...
virtual void assemble ( bool skip ) ;
static TSMesh * assembleMesh ( U32 meshType , bool skip ) ;
virtual void disassemble ( ) ;
void createTangents ( const Vector < Point3F > & _verts , const Vector < Point3F > & _norms ) ;
void findTangent ( U32 index1 ,
U32 index2 ,
U32 index3 ,
Point3F * tan0 ,
Point3F * tan1 ,
const Vector < Point3F > & _verts ) ;
/// on load...optionally convert primitives to other form
static bool smUseTriangles ;
static bool smUseOneStrip ;
static S32 smMinStripSize ;
static bool smUseEncodedNormals ;
/// Enables mesh instancing on non-skin meshes that
/// have less that this count of verts.
static S32 smMaxInstancingVerts ;
2015-01-10 19:41:25 +00:00
/// Default node transform for standard meshes which have blend indices
static MatrixF smDummyNodeTransform ;
2012-09-19 15:15:01 +00:00
/// convert primitives on load...
void convertToTris ( const TSDrawPrimitive * primitivesIn , const S32 * indicesIn ,
S32 numPrimIn , S32 & numPrimOut , S32 & numIndicesOut ,
TSDrawPrimitive * primitivesOut , S32 * indicesOut ) const ;
void convertToSingleStrip ( const TSDrawPrimitive * primitivesIn , const S32 * indicesIn ,
S32 numPrimIn , S32 & numPrimOut , S32 & numIndicesOut ,
TSDrawPrimitive * primitivesOut , S32 * indicesOut ) const ;
void leaveAsMultipleStrips ( const TSDrawPrimitive * primitivesIn , const S32 * indicesIn ,
S32 numPrimIn , S32 & numPrimOut , S32 & numIndicesOut ,
TSDrawPrimitive * primitivesOut , S32 * indicesOut ) const ;
2015-01-10 19:41:25 +00:00
/// Moves vertices from the vertex buffer back into the split vert lists, unless verts already exist
virtual void makeEditable ( ) ;
/// Clears split vertex lists
virtual void clearEditable ( ) ;
void updateMeshFlags ( ) ;
2012-09-19 15:15:01 +00:00
/// methods used during assembly to share vertexand other info
/// between meshes (and for skipping detail levels on load)
S32 * getSharedData32 ( S32 parentMesh , S32 size , S32 * * source , bool skip ) ;
S8 * getSharedData8 ( S32 parentMesh , S32 size , S8 * * source , bool skip ) ;
/// @name Assembly Variables
/// variables used during assembly (for skipping mesh detail levels
/// on load and for sharing verts between meshes)
/// @{
static Vector < Point3F * > smVertsList ;
static Vector < Point3F * > smNormsList ;
static Vector < U8 * > smEncodedNormsList ;
static Vector < Point2F * > smTVertsList ;
// Optional second texture uvs.
static Vector < Point2F * > smTVerts2List ;
// Optional vertex colors.
static Vector < ColorI * > smColorsList ;
static Vector < bool > smDataCopied ;
static const Point3F smU8ToNormalTable [ ] ;
/// @}
TSMesh ( ) ;
virtual ~ TSMesh ( ) ;
Opcode : : Model * mOptTree ;
Opcode : : MeshInterface * mOpMeshInterface ;
IceMaths : : IndexedTriangle * mOpTris ;
IceMaths : : Point * mOpPoints ;
void prepOpcodeCollision ( ) ;
bool buildConvexOpcode ( const MatrixF & mat , const Box3F & bounds , Convex * c , Convex * list ) ;
bool buildPolyListOpcode ( const S32 od , AbstractPolyList * polyList , const Box3F & nodeBox , TSMaterialList * materials ) ;
bool castRayOpcode ( const Point3F & start , const Point3F & end , RayInfo * rayInfo , TSMaterialList * materials ) ;
2015-01-10 19:41:25 +00:00
void dumpPrimitives ( U32 startVertex , U32 startIndex , GFXPrimitive * piArray , U16 * ibIndices ) ;
virtual U32 getNumVerts ( ) ;
2012-09-19 15:15:01 +00:00
static const F32 VISIBILITY_EPSILON ;
} ;
class TSSkinMesh : public TSMesh
{
public :
struct BatchData
{
enum Constants
{
2015-01-10 19:41:25 +00:00
maxBonePerVert = 16 , // Assumes a maximum of 4 blocks of bone indices for HW skinning
2012-09-19 15:15:01 +00:00
} ;
/// @name Batch by vertex
/// These are used for batches where each element is a vertex, built by
/// iterating over 0..maxBonePerVert bone transforms
/// @{
struct TransformOp
{
S32 transformIndex ;
F32 weight ;
TransformOp ( ) : transformIndex ( - 1 ) , weight ( - 1.0f ) { }
TransformOp ( const S32 tIdx , const F32 w ) : transformIndex ( tIdx ) , weight ( w ) { } ;
} ;
struct BatchedVertex
{
S32 vertexIndex ;
S32 transformCount ;
TransformOp transform [ maxBonePerVert ] ;
BatchedVertex ( ) : vertexIndex ( - 1 ) , transformCount ( - 1 ) { }
} ;
Vector < BatchedVertex > vertexBatchOperations ;
/// @}
// # = num bones
Vector < S32 > nodeIndex ;
Vector < MatrixF > initialTransforms ;
// # = numverts
Vector < Point3F > initialVerts ;
Vector < Point3F > initialNorms ;
2015-01-10 19:41:25 +00:00
bool initialized ;
BatchData ( ) : initialized ( false ) { ; }
2012-09-19 15:15:01 +00:00
} ;
/// This method will build the batch operations and prepare the BatchData
/// for use.
2015-01-10 19:41:25 +00:00
void createSkinBatchData ( ) ;
/// Inserts transform indices and weights into vertex data
void setupVertexTransforms ( ) ;
/// Returns maximum bones used per vertex
2024-03-18 18:13:00 +00:00
U32 getMaxBonesPerVert ( ) override ;
2015-01-10 19:41:25 +00:00
2024-03-18 18:13:00 +00:00
void convertToVertexData ( ) override ;
void copySourceVertexDataFrom ( const TSMesh * srcMesh ) override ;
2015-01-10 19:41:25 +00:00
void printVerts ( ) ;
void addWeightsFromVertexBuffer ( ) ;
2024-03-18 18:13:00 +00:00
void makeEditable ( ) override ;
void clearEditable ( ) override ;
2012-09-19 15:15:01 +00:00
public :
typedef TSMesh Parent ;
2015-01-10 19:41:25 +00:00
/// @name Vertex tuples
/// {
FreeableVector < F32 > weight ; ///< blend weight
FreeableVector < S32 > boneIndex ; ///< Maps from mesh node to bone in shape
FreeableVector < S32 > vertexIndex ; ///< index of affected vertex
/// }
/// Maximum number of bones referenced by this skin mesh
S32 maxBones ;
2012-09-19 15:15:01 +00:00
/// Structure containing data needed to batch skinning
2015-03-04 00:55:30 +00:00
BatchData batchData ;
2012-09-19 15:15:01 +00:00
/// set verts and normals...
2015-01-10 19:41:25 +00:00
void updateSkinBuffer ( const Vector < MatrixF > & transforms , U8 * buffer ) ;
/// update bone transforms for this mesh
void updateSkinBones ( const Vector < MatrixF > & transforms , Vector < MatrixF > & destTransforms ) ;
2012-09-19 15:15:01 +00:00
// render methods..
2024-03-18 18:13:00 +00:00
void render ( TSVertexBufferHandle & instanceVB ) override ;
2012-09-19 15:15:01 +00:00
void render ( TSMaterialList * ,
const TSRenderState & data ,
bool isSkinDirty ,
const Vector < MatrixF > & transforms ,
TSVertexBufferHandle & vertexBuffer ,
2024-03-18 18:13:00 +00:00
const char * meshName ) override ;
2012-09-19 15:15:01 +00:00
// collision methods...
2024-03-18 18:13:00 +00:00
bool buildPolyList ( S32 frame , AbstractPolyList * polyList , U32 & surfaceKey , TSMaterialList * materials ) override ;
bool castRay ( S32 frame , const Point3F & start , const Point3F & end , RayInfo * rayInfo , TSMaterialList * materials ) override ;
bool buildConvexHull ( ) override ; // does nothing, skins don't use this
2012-09-19 15:15:01 +00:00
2024-03-18 18:13:00 +00:00
void computeBounds ( const MatrixF & transform , Box3F & bounds , S32 frame , Point3F * center , F32 * radius ) override ;
2012-09-19 15:15:01 +00:00
/// persist methods...
2024-03-18 18:13:00 +00:00
void assemble ( bool skip ) override ;
void disassemble ( ) override ;
2012-09-19 15:15:01 +00:00
2015-01-10 19:41:25 +00:00
/// Helper method to add a blend tuple for a vertex
inline void addWeightForVert ( U32 vi , U32 bi , F32 w )
{
weight . push_back ( w ) ;
boneIndex . push_back ( bi ) ;
vertexIndex . push_back ( vi ) ;
}
2012-09-19 15:15:01 +00:00
/// variables used during assembly (for skipping mesh detail levels
/// on load and for sharing verts between meshes)
static Vector < MatrixF * > smInitTransformList ;
static Vector < S32 * > smVertexIndexList ;
static Vector < S32 * > smBoneIndexList ;
static Vector < F32 * > smWeightList ;
static Vector < S32 * > smNodeIndexList ;
2015-01-10 19:41:25 +00:00
static bool smDebugSkinVerts ;
2012-09-19 15:15:01 +00:00
TSSkinMesh ( ) ;
} ;
# endif // _TSMESH_H_