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