1// tMesh.cpp 
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#include <System/tChunk.h> 
16#include "Scene/tMesh.h" 
17using namespace tStd
18using namespace tMath
19namespace tScene 
20
21 
22 
23tMesh& tMesh::operator=(const tMesh& src
24
25 if (this == &src
26 return *this
27 Clear(); 
28 
29 NumFaces = src.NumFaces
30 FaceTableVertPositionIndices = src.FaceTableVertPositionIndices ? new tTriFace[NumFaces] : nullptr
31 if (FaceTableVertPositionIndices
32 tMemcpy(FaceTableVertPositionIndices, src.FaceTableVertPositionIndices, NumFaces * sizeof(tTriFace)); 
33 
34 FaceTableVertWeightSetIndices = src.FaceTableVertWeightSetIndices ? new tTriFace[NumFaces] : nullptr
35 if (FaceTableVertWeightSetIndices
36 tMemcpy(FaceTableVertWeightSetIndices, src.FaceTableVertWeightSetIndices, NumFaces * sizeof(tTriFace)); 
37 
38 FaceTableVertNormalIndices = src.FaceTableVertNormalIndices ? new tTriFace[NumFaces] : nullptr
39 if (FaceTableVertNormalIndices
40 tMemcpy(FaceTableVertNormalIndices, src.FaceTableVertNormalIndices, NumFaces * sizeof(tTriFace)); 
41 
42 FaceTableUVIndices = src.FaceTableUVIndices ? new tTriFace[NumFaces] : nullptr
43 if (FaceTableUVIndices
44 tMemcpy(FaceTableUVIndices, src.FaceTableUVIndices, NumFaces * sizeof(tTriFace)); 
45 
46 FaceTableNormalMapUVIndices = src.FaceTableNormalMapUVIndices ? new tTriFace[NumFaces] : nullptr
47 if (FaceTableNormalMapUVIndices
48 tMemcpy(FaceTableNormalMapUVIndices, src.FaceTableNormalMapUVIndices, NumFaces * sizeof(tTriFace)); 
49 
50 FaceTableColourIndices = src.FaceTableColourIndices ? new tTriFace[NumFaces] : nullptr
51 if (FaceTableColourIndices
52 tMemcpy(FaceTableColourIndices, src.FaceTableColourIndices, NumFaces * sizeof(tTriFace)); 
53 
54 FaceTableFaceNormals = src.FaceTableFaceNormals ? new tVector3[NumFaces] : nullptr
55 if (FaceTableFaceNormals
56 tMemcpy(FaceTableFaceNormals , src.FaceTableFaceNormals, NumFaces * sizeof(tVector3)); 
57 
58 FaceTableMaterialIDs = src.FaceTableMaterialIDs ? new uint32[NumFaces] : nullptr
59 if (FaceTableMaterialIDs
60 tMemcpy(FaceTableMaterialIDs, src.FaceTableMaterialIDs, NumFaces * sizeof(uint32)); 
61 
62 FaceTableTangentIndices = src.FaceTableTangentIndices ? new tTriFace[NumFaces] : nullptr
63 if (FaceTableTangentIndices
64 tMemcpy(FaceTableTangentIndices, src.FaceTableTangentIndices, NumFaces * sizeof(tTriFace)); 
65 
66 NumEdges = src.NumEdges
67 EdgeTableVertPositionIndices = src.EdgeTableVertPositionIndices ? new tEdge[NumEdges] : nullptr
68 if (EdgeTableVertPositionIndices
69 tMemcpy(EdgeTableVertPositionIndices, src.EdgeTableVertPositionIndices, NumEdges * sizeof(tEdge)); 
70 
71 NumVertPositions = src.NumVertPositions
72 VertTablePositions = src.VertTablePositions ? new tVector3[NumVertPositions] : nullptr
73 if (VertTablePositions
74 tMemcpy(VertTablePositions, src.VertTablePositions, NumVertPositions * sizeof(tVector3)); 
75 
76 NumVertWeightSets = src.NumVertWeightSets
77 VertTableWeightSets = src.VertTableWeightSets ? new tWeightSet[NumVertWeightSets] : nullptr
78 if (VertTableWeightSets
79 tMemcpy(VertTableWeightSets, src.VertTableWeightSets, NumVertWeightSets * sizeof(tWeightSet)); 
80 
81 NumVertNormals = src.NumVertNormals
82 VertTableNormals = src.VertTableNormals ? new tVector3[NumVertNormals] : nullptr
83 if (VertTableNormals
84 tMemcpy(VertTableNormals, src.VertTableNormals, NumVertNormals * sizeof(tVector3)); 
85 
86 NumVertUVs = src.NumVertUVs
87 VertTableUVs = src.VertTableUVs ? new tVector2[NumVertUVs] : nullptr
88 if (VertTableUVs
89 tMemcpy(VertTableUVs, src.VertTableUVs, NumVertUVs * sizeof(tVector2)); 
90 
91 NumVertNormalMapUVs = src.NumVertNormalMapUVs
92 VertTableNormalMapUVs = src.VertTableNormalMapUVs ? new tVector2[NumVertNormalMapUVs] : nullptr
93 if (VertTableNormalMapUVs
94 tMemcpy(VertTableNormalMapUVs, src.VertTableNormalMapUVs, NumVertNormalMapUVs * sizeof(tVector2)); 
95 
96 NumVertColours = src.NumVertColours
97 VertTableColours = src.VertTableColours ? new tColouri[NumVertColours] : nullptr
98 if (VertTableColours
99 tMemcpy(VertTableColours, src.VertTableColours, NumVertColours * sizeof(tColouri)); 
100 
101 NumVertTangents = src.NumVertTangents
102 VertTableTangents = src.VertTableTangents ? new tVector4[NumVertTangents] : nullptr
103 if (VertTableTangents
104 tMemcpy(VertTableTangents, src.VertTableTangents, NumVertTangents * sizeof(tVector4)); 
105 
106 return *this
107
108 
109 
110void tMesh::Clear() 
111
112 SetNumFaces(0); 
113 DestroyFaceTableVertPositionIndices(); 
114 DestroyFaceTableVertWeightSetIndices(); 
115 DestroyFaceTableVertNormalIndices(); 
116 DestroyFaceTableFaceNormals(); 
117 DestroyFaceTableUVIndices(); 
118 DestroyFaceTableNormalMapUVIndices(); 
119 DestroyFaceTableColourIndices(); 
120 DestroyFaceTableMaterialIDs(); 
121 DestroyFaceTableTangentIndices(); 
122 
123 SetNumEdges(0); 
124 DestroyEdgeTableVertPositionIndices(); 
125 
126 SetNumVertPositions(0); 
127 DestroyVertTablePositions(); 
128 
129 SetNumVertWeightSets(0); 
130 DestroyVertTableWeightSets(); 
131 
132 SetNumVertNormals(0); 
133 DestroyVertTableNormals(); 
134 
135 SetNumVertUVs(0); 
136 DestroyVertTableUVs(); 
137 
138 SetNumVertNormalMapUVs(0); 
139 DestroyVertTableNormalMapUVs(); 
140 
141 SetNumVertColours(0); 
142 DestroyVertTableColours(); 
143 
144 SetNumVertTangents(0); 
145 DestroyVertTableTangents(); 
146
147 
148 
149void tMesh::Load(const tChunk& meshChunk
150
151 tAssert(meshChunk.ID() == tChunkID::Scene_Mesh); 
152 Clear(); 
153 
154 for (tChunk chunk = meshChunk.First(); chunk.Valid(); chunk = chunk.Next()) 
155
156 switch (chunk.ID()) 
157
158 case tChunkID::Scene_MeshProperties
159 chunk.GetItem(NumFaces); 
160 chunk.GetItem(NumEdges); 
161 chunk.GetItem(NumVertPositions); 
162 chunk.GetItem(NumVertWeightSets); 
163 chunk.GetItem(NumVertNormals); 
164 chunk.GetItem(NumVertUVs); 
165 chunk.GetItem(NumVertNormalMapUVs); 
166 chunk.GetItem(NumVertColours); 
167 chunk.GetItem(NumVertTangents); 
168 break
169 
170 case tChunkID::Scene_FaceTable_VertPositionIndices
171
172 tAssert(NumFaces); 
173 FaceTableVertPositionIndices = new tTriFace[NumFaces]; 
174 tTriFace* faces = (tTriFace*)chunk.Data(); 
175 for (int f = 0; f < NumFaces; f++) 
176 FaceTableVertPositionIndices[f] = faces[f]; 
177 
178 break
179
180 
181 case tChunkID::Scene_FaceTable_VertWeightSetIndices
182
183 tAssert(NumFaces); 
184 FaceTableVertWeightSetIndices = new tTriFace[NumFaces]; 
185 tTriFace* faces = (tTriFace*)chunk.Data(); 
186 for (int f = 0; f < NumFaces; f++) 
187 FaceTableVertWeightSetIndices[f] = faces[f]; 
188 
189 break
190
191 
192 case tChunkID::Scene_FaceTable_VertNormalIndices
193
194 tAssert(NumFaces); 
195 FaceTableVertNormalIndices = new tTriFace[NumFaces]; 
196 tTriFace* normalFaces = (tTriFace*)chunk.Data(); 
197 for (int f = 0; f < NumFaces; f++) 
198 FaceTableVertNormalIndices[f] = normalFaces[f]; 
199 
200 break
201
202 
203 case tChunkID::Scene_FaceTable_FaceNormals
204
205 tAssert(NumFaces); 
206 FaceTableFaceNormals = new tVector3[NumFaces]; 
207 tVector3* normals = (tVector3*)chunk.Data(); 
208 for (int f = 0; f < NumFaces; f++) 
209 FaceTableFaceNormals[f] = normals[f]; 
210 
211 break
212
213 
214 case tChunkID::Scene_FaceTable_TexCoordIndices
215
216 tAssert(NumFaces); 
217 FaceTableUVIndices = new tTriFace[NumFaces]; 
218 tTriFace* uvFaces = (tTriFace*)chunk.Data(); 
219 for (int f = 0; f < NumFaces; f++) 
220 FaceTableUVIndices[f] = uvFaces[f]; 
221 
222 break
223
224 
225 case tChunkID::Scene_FaceTable_NormalMapTexCoordIndices
226
227 tAssert(NumFaces); 
228 FaceTableNormalMapUVIndices = new tTriFace[NumFaces]; 
229 tTriFace* normalMapUVFaces = (tTriFace*)chunk.Data(); 
230 for (int f = 0; f < NumFaces; f++) 
231 FaceTableNormalMapUVIndices[f] = normalMapUVFaces[f]; 
232 
233 break
234
235 
236 case tChunkID::Scene_FaceTable_ColourIndices
237
238 tAssert(NumFaces); 
239 FaceTableColourIndices = new tTriFace[NumFaces]; 
240 tTriFace* colourFaces = (tTriFace*)chunk.Data(); 
241 for (int f = 0; f < NumFaces; f++) 
242 FaceTableColourIndices[f] = colourFaces[f]; 
243 
244 break
245
246 
247 case tChunkID::Scene_FaceTable_MaterialIDs
248
249 tAssert(NumFaces); 
250 FaceTableMaterialIDs = new uint32[NumFaces]; 
251 uint32* matIDs = (uint32*)chunk.Data(); 
252 for (int f = 0; f < NumFaces; f++) 
253 FaceTableMaterialIDs[f] = matIDs[f]; 
254 
255 break
256
257 
258 case tChunkID::Scene_FaceTable_TangentIndices
259
260 tAssert(NumFaces); 
261 FaceTableTangentIndices = new tTriFace[NumFaces]; 
262 tTriFace* tangentFaces = (tTriFace*)chunk.Data(); 
263 for (int f = 0; f < NumFaces; f++) 
264 FaceTableTangentIndices[f] = tangentFaces[f]; 
265 
266 break
267
268 
269 case tChunkID::Scene_EdgeTable_VertPositionIndices
270
271 tAssert(NumEdges); 
272 EdgeTableVertPositionIndices = new tEdge[NumEdges]; 
273 tEdge* edges = (tEdge*)chunk.Data(); 
274 for (int e = 0; e < NumEdges; e++) 
275 EdgeTableVertPositionIndices[e] = edges[e]; 
276 
277 break
278
279 
280 case tChunkID::Scene_VertTable_Positions
281
282 tAssert(NumVertPositions); 
283 VertTablePositions = new tVector3[NumVertPositions]; 
284 tVector3* verts = (tVector3*)chunk.Data(); 
285 for (int v = 0; v < NumVertPositions; v++) 
286 VertTablePositions[v] = verts[v]; 
287 
288 break
289
290 
291 case tChunkID::Scene_VertTable_WeightSets
292
293 tAssert(NumVertWeightSets); 
294 VertTableWeightSets = new tWeightSet[NumVertWeightSets]; 
295 tWeightSet* weightSets = (tWeightSet*)chunk.GetData(); 
296 for (int s = 0; s < NumVertWeightSets; s++) 
297 VertTableWeightSets[s] = weightSets[s]; 
298 
299 break
300
301 
302 case tChunkID::Scene_VertTable_Normals
303
304 tAssert(NumVertNormals); 
305 VertTableNormals = new tVector3[NumVertNormals]; 
306 tVector3* normals = (tVector3*)chunk.Data(); 
307 for (int n = 0; n < NumVertNormals; n++) 
308 VertTableNormals[n] = normals[n]; 
309 
310 break
311
312 
313 case tChunkID::Scene_VertTable_TexCoords
314
315 tAssert(NumVertUVs); 
316 VertTableUVs = new tVector2[NumVertUVs]; 
317 tVector2* uvs = (tVector2*)chunk.Data(); 
318 for (int uv = 0; uv < NumVertUVs; uv++) 
319 VertTableUVs[uv] = uvs[uv]; 
320 
321 break
322
323 
324 case tChunkID::Scene_VertTable_NormalMapTexCoords
325
326 tAssert(NumVertNormalMapUVs); 
327 VertTableNormalMapUVs = new tVector2[NumVertNormalMapUVs]; 
328 tVector2* uvs = (tVector2*)chunk.Data(); 
329 for (int uv = 0; uv < NumVertNormalMapUVs; uv++) 
330 VertTableNormalMapUVs[uv] = uvs[uv]; 
331 
332 break
333
334 
335 case tChunkID::Scene_VertTable_Colours
336
337 tAssert(NumVertColours); 
338 VertTableColours = new tColouri[NumVertColours]; 
339 tColouri* colours = (tColouri*)chunk.Data(); 
340 for (int c = 0; c < NumVertColours; c++) 
341 VertTableColours[c] = colours[c]; 
342 
343 break
344
345 
346 case tChunkID::Scene_VertTable_Tangents
347
348 tAssert(NumVertTangents); 
349 VertTableTangents = new tVector4[NumVertTangents]; 
350 tVector4* tangents = (tVector4*)chunk.Data(); 
351 for (int t = 0; t < NumVertTangents; t++) 
352 VertTableTangents[t] = tangents[t]; 
353 
354 break
355
356
357
358
359 
360 
361void tMesh::Save(tChunkWriter& chunk) const 
362
363 chunk.Begin(tChunkID::Scene_Mesh); 
364
365 chunk.Begin(tChunkID::Scene_MeshProperties); 
366
367 chunk.Write(NumFaces); 
368 chunk.Write(NumEdges); 
369 chunk.Write(NumVertPositions); 
370 chunk.Write(NumVertWeightSets); 
371 chunk.Write(NumVertNormals); 
372 chunk.Write(NumVertUVs); 
373 chunk.Write(NumVertNormalMapUVs); 
374 chunk.Write(NumVertColours); 
375 chunk.Write(NumVertTangents); 
376
377 chunk.End(); 
378 
379 // Table chunks only written if table is present. 
380 if (FaceTableVertPositionIndices
381
382 chunk.Begin(tChunkID::Scene_FaceTable_VertPositionIndices); 
383 chunk.Write(FaceTableVertPositionIndices, NumFaces); 
384 chunk.End(); 
385
386 
387 if (FaceTableVertWeightSetIndices
388
389 chunk.Begin(tChunkID::Scene_FaceTable_VertWeightSetIndices); 
390 chunk.Write(FaceTableVertWeightSetIndices, NumFaces); 
391 chunk.End(); 
392
393 
394 if (FaceTableVertNormalIndices
395
396 chunk.Begin(tChunkID::Scene_FaceTable_VertNormalIndices); 
397 chunk.Write(FaceTableVertNormalIndices, NumFaces); 
398 chunk.End(); 
399
400 
401 if (FaceTableFaceNormals
402
403 chunk.Begin(tChunkID::Scene_FaceTable_FaceNormals); 
404 chunk.Write(FaceTableFaceNormals, NumFaces); 
405 chunk.End(); 
406
407 
408 if (FaceTableUVIndices
409
410 chunk.Begin(tChunkID::Scene_FaceTable_TexCoordIndices); 
411 chunk.Write(FaceTableUVIndices, NumFaces); 
412 chunk.End(); 
413
414 
415 if (FaceTableNormalMapUVIndices
416
417 chunk.Begin(tChunkID::Scene_FaceTable_NormalMapTexCoordIndices); 
418 chunk.Write(FaceTableNormalMapUVIndices, NumFaces); 
419 chunk.End(); 
420
421 
422 if (FaceTableColourIndices
423
424 chunk.Begin(tChunkID::Scene_FaceTable_ColourIndices); 
425 chunk.Write(FaceTableColourIndices, NumFaces); 
426 chunk.End(); 
427
428 
429 if (FaceTableMaterialIDs
430
431 chunk.Begin(tChunkID::Scene_FaceTable_MaterialIDs); 
432 chunk.Write(FaceTableMaterialIDs, NumFaces); 
433 chunk.End(); 
434
435 
436 if (FaceTableTangentIndices
437
438 chunk.Begin(tChunkID::Scene_FaceTable_TangentIndices); 
439 chunk.Write(FaceTableTangentIndices, NumFaces); 
440 chunk.End(); 
441
442 
443 if (EdgeTableVertPositionIndices
444
445 chunk.Begin(tChunkID::Scene_EdgeTable_VertPositionIndices); 
446 chunk.Write(EdgeTableVertPositionIndices, NumEdges); 
447 chunk.End(); 
448
449 
450 if (VertTablePositions
451
452 chunk.Begin(tChunkID::Scene_VertTable_Positions); 
453 chunk.Write(VertTablePositions, NumVertPositions); 
454 chunk.End(); 
455
456 
457 if (VertTableWeightSets
458
459 chunk.Begin(tChunkID::Scene_VertTable_WeightSets); 
460 chunk.Write((char*)VertTableWeightSets, NumVertWeightSets * sizeof(tWeightSet)); 
461 chunk.End(); 
462
463 
464 if (VertTableNormals
465
466 chunk.Begin(tChunkID::Scene_VertTable_Normals); 
467 chunk.Write(VertTableNormals, NumVertNormals); 
468 chunk.End(); 
469
470 
471 if (VertTableUVs
472
473 chunk.Begin(tChunkID::Scene_VertTable_TexCoords); 
474 chunk.Write(VertTableUVs, NumVertUVs); 
475 chunk.End(); 
476
477 
478 if (VertTableNormalMapUVs
479
480 chunk.Begin(tChunkID::Scene_VertTable_NormalMapTexCoords); 
481 chunk.Write(VertTableNormalMapUVs, NumVertNormalMapUVs); 
482 chunk.End(); 
483
484 
485 if (VertTableColours
486
487 chunk.Begin(tChunkID::Scene_VertTable_Colours); 
488 chunk.Write(VertTableColours, NumVertColours); 
489 chunk.End(); 
490
491 
492 if (VertTableTangents
493
494 chunk.Begin(tChunkID::Scene_VertTable_Tangents); 
495 chunk.Write(VertTableTangents, NumVertTangents); 
496 chunk.End(); 
497
498
499 chunk.End(); 
500
501 
502 
503void tMesh::Scale(float scale
504
505 for (int v = 0; v < NumVertPositions; v++) 
506 VertTablePositions[v] *= scale
507
508 
509 
510void tMesh::ReverseWinding() 
511
512 for (int f = 0; f < NumFaces; f++) 
513
514 if (FaceTableVertPositionIndices
515 tStd::tSwap(FaceTableVertPositionIndices[f].Index[0], FaceTableVertPositionIndices[f].Index[2]); 
516 
517 if (FaceTableVertWeightSetIndices
518 tStd::tSwap(FaceTableVertWeightSetIndices[f].Index[0], FaceTableVertWeightSetIndices[f].Index[2]); 
519 
520 if (FaceTableVertNormalIndices
521 tStd::tSwap(FaceTableVertNormalIndices[f].Index[0], FaceTableVertNormalIndices[f].Index[2]); 
522 
523 if (FaceTableUVIndices
524 tStd::tSwap(FaceTableUVIndices[f].Index[0], FaceTableUVIndices[f].Index[2]); 
525 
526 if (FaceTableNormalMapUVIndices
527 tStd::tSwap(FaceTableNormalMapUVIndices[f].Index[0], FaceTableNormalMapUVIndices[f].Index[2]); 
528 
529 if (FaceTableColourIndices
530 tStd::tSwap(FaceTableColourIndices[f].Index[0], FaceTableColourIndices[f].Index[2]); 
531 
532 if (FaceTableTangentIndices
533 tStd::tSwap(FaceTableTangentIndices[f].Index[0], FaceTableTangentIndices[f].Index[2]); 
534
535
536 
537 
538
539