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> 
18namespace tScene 
19
20 
21 
22struct 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 
33struct 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 
48class tMesh 
49
50public
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