1 | // tMesh.h  |
2 | //  |
3 | // This file implements a mesh. A tMesh is not a tObject, but rather a member of a tPolyModel.  |
4 | //  |
5 | // Copyright (c) 2006, 2017 Tristan Grimmer.  |
6 | // Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby  |
7 | // granted, provided that the above copyright notice and this permission notice appear in all copies.  |
8 | //  |
9 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL  |
10 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,  |
11 | // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  |
12 | // AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR  |
13 | // PERFORMANCE OF THIS SOFTWARE.  |
14 |   |
15 | #pragma once  |
16 | #include <Foundation/tStandard.h>  |
17 | #include <System/tChunk.h>  |
18 | namespace tScene  |
19 | {  |
20 |   |
21 |   |
22 | struct tVertWeight  |
23 | {  |
24 | bool operator==(const tVertWeight& w) const { return ((SkeletonID == w.SkeletonID) && (JointID == w.JointID) && (Weight == w.Weight)) ? true : false; }  |
25 | bool operator!=(const tVertWeight& w) const { return !(*this == w); }  |
26 |   |
27 | uint32 SkeletonID;  |
28 | uint32 JointID;  |
29 | float Weight;  |
30 | };  |
31 |   |
32 |   |
33 | struct tWeightSet  |
34 | {  |
35 | tWeightSet() { tStd::tMemset(this, 0, sizeof(tWeightSet)); }  |
36 | bool operator==(const tWeightSet& s) const { if (NumWeights != s.NumWeights) return false; for (int i = 0; i < NumWeights; i++) if (Weights[i] != s.Weights[i]) return false; return true; }  |
37 | bool operator!=(const tWeightSet& s) const { return !(*this == s); }  |
38 |   |
39 | // The number of weights that are non-zero in the weight table.  |
40 | int NumWeights;  |
41 |   |
42 | // Max number of joints that can affect a single vertex. If you change this, you'll need to re-export everything.  |
43 | static const int MaxJointInfluences = 8;  |
44 | tVertWeight Weights[MaxJointInfluences];  |
45 | };  |
46 |   |
47 |   |
48 | class tMesh  |
49 | {  |
50 | public:  |
51 | tMesh() { }  |
52 | tMesh(const tChunk& chunk) { Load(chunk); }  |
53 | tMesh(const tMesh& src) { *this = src; }  |
54 | virtual ~tMesh() { }  |
55 |   |
56 | void Save(tChunkWriter&) const;  |
57 | void Load(const tChunk&);  |
58 | void Clear();  |
59 | void Scale(float);  |
60 |   |
61 | // Reverses the winding order of all face index tables. That is, those tables that are arrays of tTriFaces.  |
62 | void ReverseWinding();  |
63 | tMesh& operator=(const tMesh&);  |
64 |   |
65 | // Faces. Note that some tables may be nullptr. If a particular table does exist it will have NumFaces elements.  |
66 | // The Create table functions assume that the number of faces has been previously set. The created table is  |
67 | // uninitialized -- you must populate it. If num faces is 0 calling create will destroy the table. Setting the  |
68 | // number of faces does _not_ modify or delete the associated tables.  |
69 | void SetNumFaces(int numFaces) { NumFaces = numFaces; }  |
70 | int GetNumFaces() const { return NumFaces; }  |
71 | void CreateFaceTableVertPositionIndices() { DestroyFaceTableVertPositionIndices(); if (NumFaces) FaceTableVertPositionIndices = new tMath::tTriFace[NumFaces]; }  |
72 | void DestroyFaceTableVertPositionIndices() { delete[] FaceTableVertPositionIndices; FaceTableVertPositionIndices = nullptr; }  |
73 | void CreateFaceTableVertWeightSetIndices() { DestroyFaceTableVertWeightSetIndices(); if (NumFaces) FaceTableVertWeightSetIndices = new tMath::tTriFace[NumFaces]; }  |
74 | void DestroyFaceTableVertWeightSetIndices() { delete[] FaceTableVertWeightSetIndices; FaceTableVertWeightSetIndices = nullptr; }  |
75 | void CreateFaceTableVertNormalIndices() { DestroyFaceTableVertNormalIndices(); if (NumFaces) FaceTableVertNormalIndices = new tMath::tTriFace[NumFaces]; }  |
76 | void DestroyFaceTableVertNormalIndices() { delete[] FaceTableVertNormalIndices; FaceTableVertNormalIndices = nullptr; }  |
77 | void CreateFaceTableFaceNormals() { DestroyFaceTableFaceNormals(); if (NumFaces) FaceTableFaceNormals = new tMath::tVector3[NumFaces]; }  |
78 | void DestroyFaceTableFaceNormals() { delete[] FaceTableFaceNormals; FaceTableFaceNormals = nullptr; }  |
79 | void CreateFaceTableUVIndices() { DestroyFaceTableUVIndices(); if (NumFaces) FaceTableUVIndices = new tMath::tTriFace[NumFaces]; }  |
80 | void DestroyFaceTableUVIndices() { delete[] FaceTableUVIndices; FaceTableUVIndices = nullptr; }  |
81 | void CreateFaceTableNormalMapUVIndices() { DestroyFaceTableNormalMapUVIndices(); if (NumFaces) FaceTableNormalMapUVIndices = new tMath::tTriFace[NumFaces]; }  |
82 | void DestroyFaceTableNormalMapUVIndices() { delete[] FaceTableNormalMapUVIndices; FaceTableNormalMapUVIndices = nullptr; }  |
83 | void CreateFaceTableColourIndices() { DestroyFaceTableColourIndices(); if (NumFaces) FaceTableColourIndices = new tMath::tTriFace[NumFaces]; }  |
84 | void DestroyFaceTableColourIndices() { delete[] FaceTableColourIndices; FaceTableColourIndices = nullptr; }  |
85 | void CreateFaceTableMaterialIDs() { DestroyFaceTableMaterialIDs(); if (NumFaces) FaceTableMaterialIDs = new uint32[NumFaces]; }  |
86 | void DestroyFaceTableMaterialIDs() { delete[] FaceTableMaterialIDs; FaceTableMaterialIDs = nullptr; }  |
87 | void CreateFaceTableTangentIndices() { DestroyFaceTableTangentIndices(); if (NumFaces) FaceTableTangentIndices = new tMath::tTriFace[NumFaces]; }  |
88 | void DestroyFaceTableTangentIndices() { delete[] FaceTableTangentIndices; FaceTableTangentIndices = nullptr; }  |
89 |   |
90 | int NumFaces;  |
91 | tMath::tTriFace* FaceTableVertPositionIndices = nullptr; // Contains indices into the vert position table.  |
92 | tMath::tTriFace* FaceTableVertWeightSetIndices = nullptr; // Contains indices into the vert weight table.  |
93 | tMath::tTriFace* FaceTableVertNormalIndices = nullptr; // Contains indices into the vertex normal table.  |
94 | tMath::tVector3* FaceTableFaceNormals = nullptr; // Contains unit length face normals.  |
95 | tMath::tTriFace* FaceTableUVIndices = nullptr; // Contains indices into the UV table.  |
96 | tMath::tTriFace* FaceTableNormalMapUVIndices = nullptr; // Contains indices into the normal/bump map UV table.  |
97 | tMath::tTriFace* FaceTableColourIndices = nullptr; // Contains indices into the colour table.  |
98 | uint32* FaceTableMaterialIDs = nullptr; // Contains material ids.  |
99 | tMath::tTriFace* FaceTableTangentIndices = nullptr; // Contains indices into the table of tangents.  |
100 |   |
101 | // Edges.  |
102 | void SetNumEdges(int numEdges) { NumEdges = numEdges; }  |
103 | int GetNumEdges() const { return NumEdges; }  |
104 | int FindEdgeIndex(const tMath::tEdge& edge) const { for (int e = 0; e < NumEdges; e++) if (EdgeTableVertPositionIndices[e] == edge) return e; return -1; }  |
105 | void CreateEdgeTableVertPositionIndices() { DestroyEdgeTableVertPositionIndices(); if (NumEdges) EdgeTableVertPositionIndices = new tMath::tEdge[NumEdges]; }  |
106 | void DestroyEdgeTableVertPositionIndices() { delete[] EdgeTableVertPositionIndices; EdgeTableVertPositionIndices = nullptr; }  |
107 | int NumEdges;  |
108 | tMath::tEdge* EdgeTableVertPositionIndices = nullptr; // Contains indices into the vert pos table, 2 per edge.  |
109 |   |
110 | // Vertices.  |
111 | void SetNumVertPositions(int numVertPositions) { NumVertPositions = numVertPositions; }  |
112 | int GetNumVertPositions() const { return NumVertPositions; }  |
113 | int FindVertPositionIndex(const tMath::tVector3& pos) const { for (int p = 0; p < NumVertPositions; p++) if (VertTablePositions[p] == pos) return p; return -1; }  |
114 | void CreateVertTablePositions() { DestroyVertTablePositions(); if (NumVertPositions) VertTablePositions = new tMath::tVector3[NumVertPositions]; }  |
115 | void DestroyVertTablePositions() { delete[] VertTablePositions; VertTablePositions = nullptr; }  |
116 | int NumVertPositions;  |
117 | tMath::tVector3* VertTablePositions = nullptr;  |
118 |   |
119 | void SetNumVertWeightSets(int numVertWeightSets) { NumVertWeightSets = numVertWeightSets; }  |
120 | int GetNumVertWeightSets() const { return NumVertWeightSets; }  |
121 | int FindWeightSetIndex(const tWeightSet& set) const { for (int s = 0; s < NumVertWeightSets; s++) if (VertTableWeightSets[s] == set) return s; return -1; }  |
122 | void CreateVertTableWeightSets() { DestroyVertTableWeightSets(); if (NumVertWeightSets) VertTableWeightSets = new tWeightSet[NumVertWeightSets]; }  |
123 | void DestroyVertTableWeightSets() { delete[] VertTableWeightSets; VertTableWeightSets = nullptr; }  |
124 | int NumVertWeightSets;  |
125 | tWeightSet* VertTableWeightSets = nullptr;  |
126 |   |
127 | void SetNumVertNormals(int numVertNormals) { NumVertNormals = numVertNormals; }  |
128 | int GetNumVertNormals() const { return NumVertNormals; }  |
129 | int FindVertNormalIndex(const tMath::tVector3& normal) const { for (int n = 0; n < NumVertNormals; n++) if (VertTableNormals[n] == normal) return n; return -1; }  |
130 | void CreateVertTableNormals() { DestroyVertTableNormals(); if (NumVertNormals) VertTableNormals = new tMath::tVector3[NumVertNormals]; }  |
131 | void DestroyVertTableNormals() { delete[] VertTableNormals; VertTableNormals = nullptr; }  |
132 | int NumVertNormals;  |
133 | tMath::tVector3* VertTableNormals = nullptr;  |
134 |   |
135 | void SetNumVertUVs(int numVertUVs) { NumVertUVs = numVertUVs; }  |
136 | int GetNumVertUVs() const { return NumVertUVs; }  |
137 | int FindVertUVIndex(const tMath::tVector2& uv) const { for (int u = 0; u < NumVertUVs; u++) if (VertTableUVs[u] == uv) return u; return -1; }  |
138 | void CreateVertTableUVs() { DestroyVertTableUVs(); if (NumVertUVs) VertTableUVs = new tMath::tVector2[NumVertUVs]; }  |
139 | void DestroyVertTableUVs() { delete[] VertTableUVs; VertTableUVs = nullptr; }  |
140 | int NumVertUVs;  |
141 | tMath::tVector2* VertTableUVs = nullptr;  |
142 |   |
143 | void SetNumVertNormalMapUVs(int numVertNormalMapUVs) { NumVertNormalMapUVs = numVertNormalMapUVs; }  |
144 | int GetNumVertNormalMapUVs() const { return NumVertNormalMapUVs; }  |
145 | int FindNormalMapUVIndex(const tMath::tVector2& uv) const { for (int u = 0; u < NumVertNormalMapUVs; u++) if (VertTableNormalMapUVs[u] == uv) return u; return -1; }  |
146 | void CreateVertTableNormalMapUVs() { DestroyVertTableNormalMapUVs(); if (NumVertNormalMapUVs) VertTableNormalMapUVs = new tMath::tVector2[NumVertNormalMapUVs]; }  |
147 | void DestroyVertTableNormalMapUVs() { delete[] VertTableNormalMapUVs; VertTableNormalMapUVs = nullptr; }  |
148 | int NumVertNormalMapUVs;  |
149 | tMath::tVector2* VertTableNormalMapUVs = nullptr;  |
150 |   |
151 | void SetNumVertColours(int numVertColours) { NumVertColours = numVertColours; }  |
152 | int GetNumVertColours() const { return NumVertColours; }  |
153 | int FindVertColourIndex(const tColouri& colour) const { for (int c = 0; c < NumVertColours; c++) if (VertTableColours[c] == colour) return c; return -1; }  |
154 | void CreateVertTableColours() { DestroyVertTableColours(); if (NumVertColours) VertTableColours = new tColouri[NumVertColours]; }  |
155 | void DestroyVertTableColours() { delete[] VertTableColours; VertTableColours = nullptr; }  |
156 | int NumVertColours;  |
157 | tColouri* VertTableColours = nullptr;  |
158 |   |
159 | void SetNumVertTangents(int numVertTangents) { NumVertTangents = numVertTangents; }  |
160 | int GetNumVertTangents() const { return NumVertTangents; }  |
161 | int FindVertTangentIndex(const tMath::tVector4& tangent) const { for (int t = 0; t < NumVertTangents; t++) if (VertTableTangents[t] == tangent) return t; return -1; }  |
162 | void CreateVertTableTangents() { DestroyVertTableTangents(); if (NumVertTangents) VertTableTangents = new tMath::tVector4[NumVertTangents]; }  |
163 | void DestroyVertTableTangents() { delete[] VertTableTangents; VertTableTangents = nullptr; }  |
164 | int NumVertTangents;  |
165 | tMath::tVector4* VertTableTangents = nullptr;  |
166 | };  |
167 |   |
168 |   |
169 | }  |
170 | |