| 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"  |
| 17 | using namespace tStd;  |
| 18 | using namespace tMath;  |
| 19 | namespace tScene  |
| 20 | {  |
| 21 |   |
| 22 |   |
| 23 | tMesh& 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 |   |
| 110 | void 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 |   |
| 149 | void 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 |   |
| 361 | void 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 |   |
| 503 | void tMesh::Scale(float scale)  |
| 504 | {  |
| 505 | for (int v = 0; v < NumVertPositions; v++)  |
| 506 | VertTablePositions[v] *= scale;  |
| 507 | }  |
| 508 |   |
| 509 |   |
| 510 | void 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 | |