tge/engine/ts/tsMesh.h
2025-02-17 23:17:30 -06:00

306 lines
10 KiB
C++
Executable File
Raw Blame History

//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef _TSMESH_H_
#define _TSMESH_H_
#ifndef _PLATFORM_H_
#include "platform/platform.h"
#endif
#ifndef _STREAM_H_
#include "core/stream.h"
#endif
#ifndef _MMATH_H_
#include "math/mMath.h"
#endif
#ifndef _TVECTOR_H_
#include "core/tVector.h"
#endif
#ifndef _MATERIALLIST_H_
#include "dgl/materialList.h"
#endif
#ifndef _ABSTRACTPOLYLIST_H_
#include "collision/abstractPolyList.h"
#endif
// when working with 3dsmax, we want some things to be vectors that otherwise
// are pointers to non-resizeable blocks of memory
#if defined(TORQUE_LIB)
#define ToolVector Vector
#else
template<class A> class ToolVector
{
public:
A * addr;
U32 sz;
void increment(U32 p = 1) { sz += p; }
void decrement(U32 p = 1) { sz -= p; }
U32 size() const { return sz; }
bool empty() const { return sz==0; }
A & operator[](U32 idx) { return addr[idx]; }
A const & operator[](U32 idx) const { return addr[idx]; }
A * address() { return addr; }
void set(void * _addr, U32 _sz) { addr = (A*)_addr; sz = _sz; }
};
#endif
class TSMaterialList;
class TSShapeInstance;
struct RayInfo;
class ConvexFeature;
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
};
S16 start;
S16 numElements;
S32 matIndex; ///< holds material index & element type (see above enum)
};
class TSMesh
{
protected:
U32 meshType;
Box3F mBounds;
Point3F mCenter;
F32 mRadius;
static F32 overrideFadeVal;
public:
enum
{
/// types...
StandardMeshType = 0,
SkinMeshType = 1,
DecalMeshType = 2,
SortedMeshType = 3,
NullMeshType = 4,
TypeMask = StandardMeshType|SkinMeshType|DecalMeshType|SortedMeshType|NullMeshType,
/// flags (stored with meshType)...
Billboard = BIT(31), HasDetailTexture = BIT(30),
BillboardZAxis = BIT(29), UseEncodedNormals = BIT(28),
FlagMask = Billboard|BillboardZAxis|HasDetailTexture|UseEncodedNormals
};
U32 getMeshType() { return meshType & TypeMask; }
void setFlags(U32 flag) { meshType |= flag; }
void clearFlags(U32 flag) { meshType &= ~flag; }
U32 getFlags(U32 flag = 0xFFFFFFFF) { return meshType & flag; }
const Point3F * getNormals(S32 firstVert);
S32 parentMesh; ///< index into shapes mesh list
S32 numFrames;
S32 numMatFrames;
S32 vertsPerFrame;
ToolVector<Point3F> verts;
ToolVector<Point3F> norms;
ToolVector<Point2F> tverts;
ToolVector<TSDrawPrimitive> primitives;
ToolVector<U8> encodedNorms;
ToolVector<U16> indices;
ToolVector<U16> mergeIndices; ///< the last so many verts merge with these
///< verts to form the next detail level
///< NOT IMPLEMENTED YET
/// billboard data
Point3F billboardAxis;
/// @name Convex Hull Data
/// Convex hulls are convex (no angles >= 180<38>) meshes used for collision
/// @{
Vector<Point3F> planeNormals;
Vector<F32> planeConstants;
Vector<U32> planeMaterials;
S32 planesPerFrame;
S32 vbOffset;
U32 mergeBufferStart;
/// @}
/// @name Render Methods
/// @{
virtual void fillVB(S32 vb, S32 frame, S32 matFrame, TSMaterialList *materials);
virtual void morphVB(S32 vb, S32 morph, S32 frame, S32 matFrame, TSMaterialList *materials);
virtual void renderVB(S32 frame, S32 matFrame, TSMaterialList *materials);
virtual void render(S32 frame, S32 matFrame, TSMaterialList *);
virtual void renderShadow(S32 frame, const MatrixF & mat, S32 dim, U32 * bits, TSMaterialList *);
void renderEnvironmentMap(S32 frame, S32 matFrame, TSMaterialList *);
void renderDetailMap(S32 frame, S32 matFrame, TSMaterialList *);
void renderFog(S32 frame, TSMaterialList* materials);
/// @}
/// @name Material Methods
/// @{
static void initMaterials();
static void resetMaterials();
static void initEnvironmentMapMaterials();
static void resetEnvironmentMapMaterials();
static void initDetailMapMaterials();
static void resetDetailMapMaterials();
static void setMaterial(S32 matIndex, TSMaterialList *);
static void setFade(F32 fadeValue);
static void clearFade();
static void setOverrideFade(F32 fadeValue){ overrideFadeVal = fadeValue; }
static F32 getOverrideFade(){ return overrideFadeVal; }
/// @}
/// @name Collision Methods
/// @{
virtual bool buildPolyList(S32 frame, AbstractPolyList * polyList, U32 & surfaceKey);
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);
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(MatrixF & transform, Box3F & bounds, S32 frame = 0, Point3F * center = NULL, F32 * radius = NULL);
void computeBounds(Point3F *, S32 numVerts, MatrixF & transform, Box3F & bounds, Point3F * center, F32 * radius);
Box3F & getBounds() { return mBounds; }
Point3F & getCenter() { return mCenter; }
F32 getRadius() { return mRadius; }
virtual S32 getNumPolys();
U8 encodeNormal(const Point3F & normal);
const Point3F & decodeNormal(U8 ncode);
/// @}
void saveMergeVerts(); ///< called by shapeinstance in setStatics
void restoreMergeVerts(); ///< called by shapeinstance in clearStatics
void saveMergeNormals(); ///< called by mesh at start of render (decals don't bother)
void restoreMergeNormals(); ///< called by mesh at end of render
/// persist methods...
virtual void assemble(bool skip);
static TSMesh * assembleMesh(U32 meshType, bool skip);
virtual void disassemble();
/// on load...optionally convert primitives to other form
static bool smUseTriangles;
static bool smUseOneStrip;
static S32 smMinStripSize;
static bool smUseEncodedNormals;
/// convert primitives on load...
void convertToTris(S16 * primitiveDataIn, S32 * primitiveMatIn, S16 * indicesIn,
S32 numPrimIn, S32 & numPrimOut, S32 & numIndicesOut,
S32 * primitivesOut, S16 * indicesOut);
void convertToSingleStrip(S16 * primitiveDataIn, S32 * primitiveMatIn, S16 * indicesIn,
S32 numPrimIn, S32 & numPrimOut, S32 & numIndicesOut,
S32 * primitivesOut, S16 * indicesOut);
void leaveAsMultipleStrips(S16 * primitiveDataIn, S32 * primitiveMatIn, S16 * indicesIn,
S32 numPrimIn, S32 & numPrimOut, S32 & numIndicesOut,
S32 * primitivesOut, S16 * indicesOut);
/// 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;
static Vector<bool> smDataCopied;
static Vector<Point3F> smSaveVerts;
static Vector<Point3F> smSaveNorms;
static Vector<Point2F> smSaveTVerts;
static const Point3F smU8ToNormalTable[];
/// @}
TSMesh() : meshType(StandardMeshType) {
VECTOR_SET_ASSOCIATION(planeNormals);
VECTOR_SET_ASSOCIATION(planeConstants);
VECTOR_SET_ASSOCIATION(planeMaterials);
parentMesh = -1;
}
virtual ~TSMesh();
};
inline const Point3F & TSMesh::decodeNormal(U8 ncode) { return smU8ToNormalTable[ncode]; }
class TSSkinMesh : public TSMesh
{
public:
typedef TSMesh Parent;
/// vectors that define the vertex, weight, bone tuples
ToolVector<F32> weight;
ToolVector<S32> boneIndex;
ToolVector<S32> vertexIndex;
/// vectors indexed by bone number
ToolVector<S32> nodeIndex;
ToolVector<MatrixF> initialTransforms;
/// initial values of verts and normals
/// these get transformed into initial bone space,
/// from there into world space relative to current bone
/// pos, and then weighted by bone weights...
ToolVector<Point3F> initialVerts;
ToolVector<Point3F> initialNorms;
/// set verts and normals...
void updateSkin();
// render methods..
void render(S32 frame, S32 matFrame, TSMaterialList *);
void renderShadow(S32 frame, const MatrixF & mat, S32 dim, U32 * bits, TSMaterialList *);
// collision methods...
bool buildPolyList(S32 frame, AbstractPolyList * polyList, U32 & surfaceKey);
bool castRay(S32 frame, const Point3F & start, const Point3F & end, RayInfo * rayInfo);
bool buildConvexHull(); // does nothing, skins don't use this
void computeBounds(MatrixF & transform, Box3F & bounds, S32 frame, Point3F * center, F32 * radius);
/// persist methods...
void assemble(bool skip);
void disassemble();
/// 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;
TSSkinMesh() { meshType = SkinMeshType; }
};
#endif