tsShapeOldRead.cpp
Engine/source/ts/tsShapeOldRead.cpp
Public Defines
define
appendVectorSimple(a) { \ sz; \ oldSz = (); \ s->read(&sz); \ a.setSize(oldSz + sz); \ ( =0;<sz;++) \ s->read(&[ + oldSz]); \ }
define
appendVectorStruct(a) { \ sz; \ oldSz = (); \ s->read(&sz); \ a.setSize(oldSz + sz); \ ( =0;<sz;++) \ [ + oldSz].read(s); \ }
define
readVectorSimple(a) { \ sz; \ s->read(&sz); \ a.setSize(sz); \ ( =0;<sz;++) \ s->read(&[]); \ }
define
readVectorStruct(a) { \ sz; \ s->read(&sz); \ a.setSize(sz); \ ( =0;<sz;++) \ [].read(s); \ }
define
writeVectorSimple(a) (,0)
define
writeVectorSimpleMinus(a, m) {\ s->write(() - m); \ ( =m;<();++) \ s->write([]); \ }
define
writeVectorStruct(a) (,0)
define
writeVectorStructMinus(a, m) {\ s->write(() - m); \ ( =m;<();++) \ [].write(s); \ }
Detailed Description
Public Defines
appendVectorSimple(a) { \ sz; \ oldSz = (); \ s->read(&sz); \ a.setSize(oldSz + sz); \ ( =0;<sz;++) \ s->read(&[ + oldSz]); \ }
appendVectorStruct(a) { \ sz; \ oldSz = (); \ s->read(&sz); \ a.setSize(oldSz + sz); \ ( =0;<sz;++) \ [ + oldSz].read(s); \ }
readVectorSimple(a) { \ sz; \ s->read(&sz); \ a.setSize(sz); \ ( =0;<sz;++) \ s->read(&[]); \ }
readVectorStruct(a) { \ sz; \ s->read(&sz); \ a.setSize(sz); \ ( =0;<sz;++) \ [].read(s); \ }
writeVectorSimple(a) (,0)
writeVectorSimpleMinus(a, m) {\ s->write(() - m); \ ( =m;<();++) \ s->write([]); \ }
writeVectorStruct(a) (,0)
writeVectorStructMinus(a, m) {\ s->write(() - m); \ ( =m;<();++) \ [].write(s); \ }
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "core/strings/stringFunctions.h" 25#include "core/util/endian.h" 26 27#include "ts/tsShapeInstance.h" 28 29//------------------------------------------------- 30// put old skins into object list 31//------------------------------------------------- 32 33void TSShape::fixupOldSkins(S32 numMeshes, S32 numSkins, S32 numDetails, S32 * detFirstSkin, S32 * detailNumSkins) 34{ 35#if !defined(TORQUE_MAX_LIB) 36 // this method not necessary in exporter, and a couple lines won't compile for exporter 37 if (!objects.address() || !meshes.address() || !numSkins) 38 // not ready for this yet, will catch it on the next pass 39 return; 40 S32 numObjects = objects.size(); 41 TSObject * newObjects = objects.address() + objects.size(); 42 TSSkinMesh ** skins = (TSSkinMesh**)&meshes[numMeshes]; 43 Vector<TSSkinMesh*> skinsCopy; 44 // Note: newObjects has as much free space as we need, so we just need to keep track of the 45 // number of objects we use and then update objects.size 46 S32 numSkinObjects = 0; 47 S32 skinsUsed = 0; 48 S32 emptySkins = 0; 49 S32 i; 50 for (i=0; i<numSkins; i++) 51 if (skins[i]==<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>) 52 emptySkins++; // probably never, but just in case 53 while (skinsUsed<numSkins-emptySkins) 54 { 55 TSObject & object = newObjects[numSkinObjects++]; 56 objects.increment(); 57 object.nameIndex = 0; // no name 58 object.numMeshes = 0; 59 object.startMeshIndex = numMeshes + skinsCopy.size(); 60 object.nodeIndex = -1; 61 object.nextSibling = -1; 62 for (S32 dl=0; dl<numDetails; dl++) 63 { 64 // find one mesh per detail to add to this object 65 // don't really need to be versions of the same object 66 i = 0; 67 while (i<detFirstSkin[dl] || detFirstSkin[dl]<0) 68 i++; 69 for (; i<numSkins && i<detFirstSkin[dl]+detailNumSkins[dl]; i++) 70 { 71 if (skins[i]) 72 { 73 // found an unused skin... copy it to skinsCopy and set to NULL 74 skinsCopy.push_back(skins[i]); 75 skins[i]=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>; 76 object.numMeshes++; 77 skinsUsed++; 78 break; 79 } 80 } 81 if (i==numSkins || i==detFirstSkin[dl]+detailNumSkins[dl]) 82 { 83 skinsCopy.push_back(NULL); 84 object.numMeshes++; 85 } 86 } 87 // exit above loop with one skin per detail...despose of trailing null meshes 88 while (!skinsCopy.empty() && skinsCopy.last()==<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>) 89 { 90 skinsCopy.decrement(); 91 object.numMeshes--; 92 } 93 // if no meshes, don't need object 94 if (!object.numMeshes) 95 { 96 objects.decrement(); 97 numSkinObjects--; 98 } 99 } 100 dMemcpy(skins,skinsCopy.address(),skinsCopy.size()*sizeof(TSSkinMesh*)); 101 102 if (subShapeFirstObject.size()==1) 103 // as long as only one subshape, we'll now be rendered 104 subShapeNumObjects[0] += numSkinObjects; 105 106 // now for something ugly -- we've added somoe objects to hold the skins... 107 // now we have to add default states for those objects 108 // we also have to increment base states on all the sequences that are loaded 109 dMemmove(objectStates.address()+numObjects+numSkinObjects,objectStates.address()+numObjects,(objectStates.size()-numObjects)*sizeof(ObjectState)); 110 for (i=numObjects; i<numObjects+numSkinObjects; i++) 111 { 112 objectStates[i].vis=1.0f; 113 objectStates[i].frameIndex=0; 114 objectStates[i].matFrameIndex=0; 115 } 116 for (i=0;i<sequences.size();i++) 117 { 118 sequences[i].baseObjectState += numSkinObjects; 119 } 120#endif 121} 122 123//------------------------------------------------- 124// some macros used for read/write 125//------------------------------------------------- 126 127// write a vector of structs (minus the first 'm') 128#define writeVectorStructMinus(a,m) \ 129{\ 130 s->write(a.size() - m); \ 131 for (S32 i=m;i<a.size();i++) \ 132 a[i].write(s); \ 133} 134 135// write a vector of simple types (minus the first 'm') 136#define writeVectorSimpleMinus(a,m) \ 137{\ 138 s->write(a.size() - m); \ 139 for (S32 i=m;i<a.size();i++) \ 140 s->write(a[i]); \ 141} 142 143// same as above with m=0 144#define writeVectorStruct(a) writeVectorStructMinus(a,0) 145#define writeVectorSimple(a) writeVectorSimpleMinus(a,0) 146 147// read a vector of structs -- over-writing any existing data 148#define readVectorStruct(a) \ 149{ \ 150 S32 sz; \ 151 s->read(&sz); \ 152 a.setSize(sz); \ 153 for (S32 i=0;i<sz;i++) \ 154 a[i].read(s); \ 155} 156 157// read a vector of simple types -- over-writing any existing data 158#define readVectorSimple(a) \ 159{ \ 160 S32 sz; \ 161 s->read(&sz); \ 162 a.setSize(sz); \ 163 for (S32 i=0;i<sz;i++) \ 164 s->read(&a[i]); \ 165} 166 167// read a vector of structs -- append to any existing data 168#define appendVectorStruct(a) \ 169{ \ 170 S32 sz; \ 171 S32 oldSz = a.size(); \ 172 s->read(&sz); \ 173 a.setSize(oldSz + sz); \ 174 for (S32 i=0;i<sz;i++) \ 175 a[i + oldSz].read(s); \ 176} 177 178// read a vector of simple types -- append to any existing data 179#define appendVectorSimple(a) \ 180{ \ 181 S32 sz; \ 182 S32 oldSz = a.size(); \ 183 s->read(&sz); \ 184 a.setSize(oldSz + sz); \ 185 for (S32 i=0;i<sz;i++) \ 186 s->read(&a[i + oldSz]); \ 187} 188 189//------------------------------------------------- 190// export all sequences 191//------------------------------------------------- 192void TSShape::exportSequences(Stream * s) 193{ 194 // write version 195 s->write(smVersion); 196 197 S32 i,sz; 198 199 // write node names 200 // -- this is how we will map imported sequence nodes to shape nodes 201 sz = nodes.size(); 202 s->write(sz); 203 for (i=0;i<nodes.size();i++) 204 writeName(s,nodes[i].nameIndex); 205 206 // legacy write -- write zero objects, don't pretend to support object export anymore 207 s->write(0); 208 209 // on import, we will need to adjust keyframe data based on number of 210 // nodes/objects in this shape...number of nodes can be inferred from 211 // above, but number of objects cannot be. Write that quantity here: 212 s->write(objects.size()); 213 214 // write node states -- skip default node states 215 s->write(nodeRotations.size()); 216 for (i=0;i<nodeRotations.size();i++) 217 { 218 s->write(nodeRotations[i].x); 219 s->write(nodeRotations[i].y); 220 s->write(nodeRotations[i].z); 221 s->write(nodeRotations[i].w); 222 } 223 s->write(nodeTranslations.size()); 224 for (i=0;i<nodeTranslations.size(); i++) 225 { 226 s->write(nodeTranslations[i].x); 227 s->write(nodeTranslations[i].y); 228 s->write(nodeTranslations[i].z); 229 } 230 s->write(nodeUniformScales.size()); 231 for (i=0;i<nodeUniformScales.size();i++) 232 s->write(nodeUniformScales[i]); 233 s->write(nodeAlignedScales.size()); 234 for (i=0;i<nodeAlignedScales.size();i++) 235 { 236 s->write(nodeAlignedScales[i].x); 237 s->write(nodeAlignedScales[i].y); 238 s->write(nodeAlignedScales[i].z); 239 } 240 s->write(nodeArbitraryScaleRots.size()); 241 for (i=0;i<nodeArbitraryScaleRots.size();i++) 242 { 243 s->write(nodeArbitraryScaleRots[i].x); 244 s->write(nodeArbitraryScaleRots[i].y); 245 s->write(nodeArbitraryScaleRots[i].z); 246 s->write(nodeArbitraryScaleRots[i].w); 247 } 248 for (i=0;i<nodeArbitraryScaleFactors.size();i++) 249 { 250 s->write(nodeArbitraryScaleFactors[i].x); 251 s->write(nodeArbitraryScaleFactors[i].y); 252 s->write(nodeArbitraryScaleFactors[i].z); 253 } 254 s->write(groundTranslations.size()); 255 for (i=0;i<groundTranslations.size();i++) 256 { 257 s->write(groundTranslations[i].x); 258 s->write(groundTranslations[i].y); 259 s->write(groundTranslations[i].z); 260 } 261 for (i=0;i<groundRotations.size();i++) 262 { 263 s->write(groundRotations[i].x); 264 s->write(groundRotations[i].y); 265 s->write(groundRotations[i].z); 266 s->write(groundRotations[i].w); 267 } 268 269 // write object states -- legacy..no object states 270 s->write((S32)0); 271 272 // write sequences 273 s->write(sequences.size()); 274 for (i=0;i<sequences.size();i++) 275 { 276 Sequence & seq = sequences[i]; 277 278 // first write sequence name 279 writeName(s,seq.nameIndex); 280 281 // now write the sequence itself 282 seq.write(s,false); // false --> don't write name index 283 } 284 285 // write out all the triggers... 286 s->write(triggers.size()); 287 for (i=0; i<triggers.size(); i++) 288 { 289 s->write(triggers[i].state); 290 s->write(triggers[i].pos); 291 } 292} 293 294//------------------------------------------------- 295// export a single sequence 296//------------------------------------------------- 297void TSShape::exportSequence(Stream * s, const TSShape::Sequence& seq, bool saveOldFormat) 298{ 299 S32 currentVersion = smVersion; 300 if ( saveOldFormat ) 301 smVersion = 24; 302 303 // write version 304 s->write(smVersion); 305 306 // write node names 307 s->write( nodes.size() ); 308 for ( S32 i = 0; i < nodes.size(); i++ ) 309 writeName( s, nodes[i].nameIndex ); 310 311 // legacy write -- write zero objects, don't pretend to support object export anymore 312 s->write( (S32)0 ); 313 314 // on import, we will need to adjust keyframe data based on number of 315 // nodes/objects in this shape...number of nodes can be inferred from 316 // above, but number of objects cannot be. Write that quantity here: 317 s->write( objects.size() ); 318 319 // write node states -- skip default node states 320 S32 count = seq.rotationMatters.count() * seq.numKeyframes; 321 s->write( count ); 322 for ( S32 i = seq.baseRotation; i < seq.baseRotation + count; i++ ) 323 { 324 s->write( nodeRotations[i].x ); 325 s->write( nodeRotations[i].y ); 326 s->write( nodeRotations[i].z ); 327 s->write( nodeRotations[i].w ); 328 } 329 330 count = seq.translationMatters.count() * seq.numKeyframes; 331 s->write( count ); 332 for ( S32 i = seq.baseTranslation; i < seq.baseTranslation + count; i++ ) 333 { 334 s->write( nodeTranslations[i].x ); 335 s->write( nodeTranslations[i].y ); 336 s->write( nodeTranslations[i].z ); 337 } 338 339 count = seq.scaleMatters.count() * seq.numKeyframes; 340 if ( seq.animatesUniformScale() ) 341 { 342 s->write( count ); 343 for ( S32 i = seq.baseScale; i < seq.baseScale + count; i++ ) 344 s->write( nodeUniformScales[i] ); 345 } 346 else 347 s->write( (S32)0 ); 348 349 if ( seq.animatesAlignedScale() ) 350 { 351 s->write( count ); 352 for ( S32 i = seq.baseScale; i < seq.baseScale + count; i++ ) 353 { 354 s->write( nodeAlignedScales[i].x ); 355 s->write( nodeAlignedScales[i].y ); 356 s->write( nodeAlignedScales[i].z ); 357 } 358 } 359 else 360 s->write( (S32)0 ); 361 362 if ( seq.animatesArbitraryScale() ) 363 { 364 s->write( count ); 365 for ( S32 i = seq.baseScale; i < seq.baseScale + count; i++ ) 366 { 367 s->write( nodeArbitraryScaleRots[i].x ); 368 s->write( nodeArbitraryScaleRots[i].y ); 369 s->write( nodeArbitraryScaleRots[i].z ); 370 s->write( nodeArbitraryScaleRots[i].w ); 371 } 372 for ( S32 i = seq.baseScale; i < seq.baseScale + count; i++ ) 373 { 374 s->write( nodeArbitraryScaleFactors[i].x ); 375 s->write( nodeArbitraryScaleFactors[i].y ); 376 s->write( nodeArbitraryScaleFactors[i].z ); 377 } 378 } 379 else 380 s->write( (S32)0 ); 381 382 s->write( seq.numGroundFrames ); 383 for ( S32 i = seq.firstGroundFrame; i < seq.firstGroundFrame + seq.numGroundFrames; i++ ) 384 { 385 s->write( groundTranslations[i].x ); 386 s->write( groundTranslations[i].y ); 387 s->write( groundTranslations[i].z ); 388 } 389 for ( S32 i = seq.firstGroundFrame; i < seq.firstGroundFrame + seq.numGroundFrames; i++ ) 390 { 391 s->write( groundRotations[i].x ); 392 s->write( groundRotations[i].y ); 393 s->write( groundRotations[i].z ); 394 s->write( groundRotations[i].w ); 395 } 396 397 // write object states -- legacy..no object states 398 s->write( (S32)0 ); 399 400 // write the sequence 401 s->write( (S32)1 ); 402 writeName( s, seq.nameIndex ); 403 { 404 // Write a copy of the sequence with all offsets set to 0 405 TSShape::Sequence tmpSeq(seq); 406 tmpSeq.baseDecalState = 0; 407 tmpSeq.baseObjectState = 0; 408 tmpSeq.baseTranslation = 0; 409 tmpSeq.baseRotation = 0; 410 tmpSeq.baseScale = 0; 411 tmpSeq.firstGroundFrame = 0; 412 tmpSeq.firstTrigger = 0; 413 414 tmpSeq.write( s, false ); 415 } 416 417 // write the sequence triggers 418 s->write( seq.numTriggers ); 419 for ( S32 i = seq.firstTrigger; i < seq.firstTrigger + seq.numTriggers; i++ ) 420 { 421 s->write( triggers[i].state ); 422 s->write( triggers[i].pos ); 423 } 424 425 smVersion = currentVersion; 426} 427 428//------------------------------------------------- 429// import sequences into existing shape 430//------------------------------------------------- 431bool TSShape::importSequences(Stream * s, const String& sequencePath) 432{ 433 // write version 434 s->read(&smReadVersion); 435 if (smReadVersion>smVersion) 436 { 437 // error -- don't support future version yet :> 438 Con::errorf(ConsoleLogEntry::General, 439 "Sequence import failed: shape exporter newer than running executable."); 440 return false; 441 } 442 if (smReadVersion<19) 443 { 444 // error -- don't support future version yet :> 445 Con::errorf(ConsoleLogEntry::General, 446 "Sequence import failed: deprecated version (%i).",smReadVersion); 447 return false; 448 } 449 450 Vector<S32> nodeMap; // node index of each node from imported sequences 451 Vector<S32> objectMap; // object index of objects from imported sequences 452 VECTOR_SET_ASSOCIATION(nodeMap); 453 VECTOR_SET_ASSOCIATION(objectMap); 454 455 S32 i,sz; 456 457 // read node names 458 // -- this is how we will map imported sequence nodes to our nodes 459 s->read(&sz); 460 nodeMap.setSize(sz); 461 462 for (i=0;i<sz;i++) 463 { 464 U32 startSize = names.size(); 465 S32 nameIndex = readName(s,true); 466 467 nodeMap[i] = findNode(nameIndex); 468 469 if (nodeMap[i] < 0) 470 { 471 // node found in sequence but not shape => remove the added node name 472 if (names.size() != startSize) 473 { 474 names.decrement(); 475 476 if (names.size() != startSize) 477 Con::errorf(ConsoleLogEntry::General, "TSShape::importSequence: failed to remove unused node correctly for dsq %s.", names[nameIndex].c_str(), sequencePath.c_str()); 478 } 479 } 480 } 481 482 // read the following size, but won't do anything with it...legacy: was going to support 483 // import of sequences that animate objects...we don't... 484 s->read(&sz); 485 486 // before reading keyframes, take note of a couple numbers 487 S32 oldShapeNumObjects; 488 s->read(&oldShapeNumObjects); 489 490 // adjust all the new keyframes 491 S32 adjNodeRots = smReadVersion<22 ? nodeRotations.size() - nodeMap.size() : nodeRotations.size(); 492 S32 adjNodeTrans = smReadVersion<22 ? nodeTranslations.size() - nodeMap.size() : nodeTranslations.size(); 493 S32 adjGroundStates = smReadVersion<22 ? 0 : groundTranslations.size(); // groundTrans==groundRot 494 495 // Read the node states into temporary vectors, then use the 496 // nodeMap to discard unused transforms and map others to our nodes 497 Vector<Quat16> seqRotations; 498 Vector<Point3F> seqTranslations; 499 Vector<F32> seqUniformScales; 500 Vector<Point3F> seqAlignedScales; 501 Vector<Quat16> seqArbitraryScaleRots; 502 Vector<Point3F> seqArbitraryScaleFactors; 503 504 if (smReadVersion>21) 505 { 506 s->read(&sz); 507 seqRotations.setSize(sz); 508 for (i=0; i < sz; i++) 509 { 510 s->read(&seqRotations[i].x); 511 s->read(&seqRotations[i].y); 512 s->read(&seqRotations[i].z); 513 s->read(&seqRotations[i].w); 514 } 515 s->read(&sz); 516 seqTranslations.setSize(sz); 517 for (i=0; i <sz; i++) 518 { 519 s->read(&seqTranslations[i].x); 520 s->read(&seqTranslations[i].y); 521 s->read(&seqTranslations[i].z); 522 } 523 s->read(&sz); 524 seqUniformScales.setSize(sz); 525 for (i = 0; i < sz; i++) 526 s->read(&seqUniformScales[i]); 527 s->read(&sz); 528 seqAlignedScales.setSize(sz); 529 for (i = 0; i < sz; i++) 530 { 531 s->read(&seqAlignedScales[i].x); 532 s->read(&seqAlignedScales[i].y); 533 s->read(&seqAlignedScales[i].z); 534 } 535 s->read(&sz); 536 seqArbitraryScaleRots.setSize(sz); 537 for (i = 0; i <sz; i++) 538 { 539 s->read(&seqArbitraryScaleRots[i].x); 540 s->read(&seqArbitraryScaleRots[i].y); 541 s->read(&seqArbitraryScaleRots[i].z); 542 s->read(&seqArbitraryScaleRots[i].w); 543 } 544 seqArbitraryScaleFactors.setSize(sz); 545 for (i = 0; i < sz; i++) 546 { 547 s->read(&seqArbitraryScaleFactors[i].x); 548 s->read(&seqArbitraryScaleFactors[i].y); 549 s->read(&seqArbitraryScaleFactors[i].z); 550 } 551 552 // ground transforms can be read directly into the shape (none will be 553 // discarded) 554 s->read(&sz); 555 S32 oldSz = groundTranslations.size(); 556 groundTranslations.setSize(sz+oldSz); 557 for (i=oldSz;i<sz+oldSz;i++) 558 { 559 s->read(&groundTranslations[i].x); 560 s->read(&groundTranslations[i].y); 561 s->read(&groundTranslations[i].z); 562 } 563 groundRotations.setSize(sz+oldSz); 564 for (i=oldSz;i<sz+oldSz;i++) 565 { 566 s->read(&groundRotations[i].x); 567 s->read(&groundRotations[i].y); 568 s->read(&groundRotations[i].z); 569 s->read(&groundRotations[i].w); 570 } 571 } 572 else 573 { 574 s->read(&sz); 575 seqRotations.setSize(sz); 576 seqTranslations.setSize(sz); 577 for (i = 0; i < sz; i++) 578 { 579 s->read(&seqRotations[i].x); 580 s->read(&seqRotations[i].y); 581 s->read(&seqRotations[i].z); 582 s->read(&seqRotations[i].w); 583 s->read(&seqTranslations[i].x); 584 s->read(&seqTranslations[i].y); 585 s->read(&seqTranslations[i].z); 586 } 587 } 588 589 // add these object states to our own -- shouldn't be any...assume it 590 s->read(&sz); 591 592 // read sequences 593 s->read(&sz); 594 S32 startSeqNum = sequences.size(); 595 for (i=0;i<sz;i++) 596 { 597 sequences.increment(); 598 Sequence & seq = sequences.last(); 599 600 // read name 601 seq.nameIndex = readName(s,true); 602 603 // read the rest of the sequence 604 seq.read(s,false); 605 seq.baseRotation = nodeRotations.size(); 606 seq.baseTranslation = nodeTranslations.size(); 607 608 if (smReadVersion > 21) 609 { 610 if (seq.animatesUniformScale()) 611 seq.baseScale = nodeUniformScales.size(); 612 else if (seq.animatesAlignedScale()) 613 seq.baseScale = nodeAlignedScales.size(); 614 else if (seq.animatesArbitraryScale()) 615 seq.baseScale = nodeArbitraryScaleFactors.size(); 616 } 617 618 // remap the node matters arrays 619 S32 j; 620 TSIntegerSet newTransMembership; 621 TSIntegerSet newRotMembership; 622 TSIntegerSet newScaleMembership; 623 for (j = 0; j < (S32)nodeMap.size(); j++) 624 { 625 if (nodeMap[j] < 0) 626 continue; 627 628 if (seq.translationMatters.test(j)) 629 newTransMembership.set(nodeMap[j]); 630 if (seq.rotationMatters.test(j)) 631 newRotMembership.set(nodeMap[j]); 632 if (seq.scaleMatters.test(j)) 633 newScaleMembership.set(nodeMap[j]); 634 } 635 636 // resize node transform arrays 637 nodeTranslations.increment(newTransMembership.count() * seq.numKeyframes); 638 nodeRotations.increment(newRotMembership.count() * seq.numKeyframes); 639 if (seq.flags & TSShape::ArbitraryScale) 640 { 641 S32 scaleCount = newScaleMembership.count() * seq.numKeyframes; 642 nodeArbitraryScaleRots.increment(scaleCount); 643 nodeArbitraryScaleFactors.increment(scaleCount); 644 } 645 else if (seq.flags & TSShape::AlignedScale) 646 nodeAlignedScales.increment(newScaleMembership.count() * seq.numKeyframes); 647 else 648 nodeUniformScales.increment(newScaleMembership.count() * seq.numKeyframes); 649 650 // remap node transforms from temporary arrays 651 for (S32 nodeID = 0; nodeID < nodeMap.size(); nodeID++) 652 { 653 if (nodeMap[nodeID] < 0) 654 continue; 655 656 if (newTransMembership.test(nodeMap[nodeID])) 657 { 658 S32 src = seq.numKeyframes * seq.translationMatters.count(nodeID); 659 S32 dest = seq.baseTranslation + seq.numKeyframes * newTransMembership.count(nodeMap[nodeID]); 660 dCopyArray(&nodeTranslations[dest], &seqTranslations[src], seq.numKeyframes); 661 } 662 if (newRotMembership.test(nodeMap[nodeID])) 663 { 664 S32 src = seq.numKeyframes * seq.rotationMatters.count(nodeID); 665 S32 dest = seq.baseRotation + seq.numKeyframes * newRotMembership.count(nodeMap[nodeID]); 666 dCopyArray(&nodeRotations[dest], &seqRotations[src], seq.numKeyframes); 667 } 668 if (newScaleMembership.test(nodeMap[nodeID])) 669 { 670 S32 src = seq.numKeyframes * seq.scaleMatters.count(nodeID); 671 S32 dest = seq.baseScale + seq.numKeyframes * newScaleMembership.count(nodeMap[nodeID]); 672 if (seq.flags & TSShape::ArbitraryScale) 673 { 674 dCopyArray(&nodeArbitraryScaleRots[dest], &seqArbitraryScaleRots[src], seq.numKeyframes); 675 dCopyArray(&nodeArbitraryScaleFactors[dest], &seqArbitraryScaleFactors[src], seq.numKeyframes); 676 } 677 else if (seq.flags & TSShape::AlignedScale) 678 dCopyArray(&nodeAlignedScales[dest], &seqAlignedScales[src], seq.numKeyframes); 679 else 680 dCopyArray(&nodeUniformScales[dest], &seqUniformScales[src], seq.numKeyframes); 681 } 682 } 683 684 seq.translationMatters = newTransMembership; 685 seq.rotationMatters = newRotMembership; 686 seq.scaleMatters = newScaleMembership; 687 688 // adjust trigger numbers...we'll read triggers after sequences... 689 seq.firstTrigger += triggers.size(); 690 691 // finally, adjust ground transform's nodes states 692 seq.firstGroundFrame += adjGroundStates; 693 } 694 695 if (smReadVersion<22) 696 { 697 for (i=startSeqNum; i<sequences.size(); i++) 698 { 699 // move ground transform data to ground vectors 700 Sequence & seq = sequences[i]; 701 S32 oldSz = groundTranslations.size(); 702 groundTranslations.setSize(oldSz+seq.numGroundFrames); 703 groundRotations.setSize(oldSz+seq.numGroundFrames); 704 for (S32 j=0;j<seq.numGroundFrames;j++) 705 { 706 groundTranslations[j+oldSz] = nodeTranslations[seq.firstGroundFrame+adjNodeTrans+j]; 707 groundRotations[j+oldSz] = nodeRotations[seq.firstGroundFrame+adjNodeRots+j]; 708 } 709 seq.firstGroundFrame = oldSz; 710 } 711 } 712 713 // add the new triggers 714 S32 oldSz = triggers.size(); 715 s->read(&sz); 716 triggers.setSize(oldSz+sz); 717 for (S32 triggerID=0; triggerID<sz; triggerID++) 718 { 719 s->read(&triggers[triggerID +oldSz].state); 720 s->read(&triggers[triggerID +oldSz].pos); 721 } 722 723 if (smInitOnRead) 724 init(); 725 726 return true; 727} 728 729//------------------------------------------------- 730// read/write sequence 731//------------------------------------------------- 732void TSShape::Sequence::read(Stream * s, bool readNameIndex) 733{ 734 AssertISV(smReadVersion>=19,"Reading old sequence"); 735 736 if (readNameIndex) 737 s->read(&nameIndex); 738 flags = 0; 739 if (TSShape::smReadVersion>21) 740 s->read(&flags); 741 else 742 flags=0; 743 744 s->read(&numKeyframes); 745 s->read(&duration); 746 747 if (TSShape::smReadVersion<22) 748 { 749 bool tmp = false; 750 s->read(&tmp); 751 if (tmp) 752 flags |= Blend; 753 s->read(&tmp); 754 if (tmp) 755 flags |= Cyclic; 756 s->read(&tmp); 757 if (tmp) 758 flags |= MakePath; 759 } 760 761 s->read(&priority); 762 s->read(&firstGroundFrame); 763 s->read(&numGroundFrames); 764 if (TSShape::smReadVersion>21) 765 { 766 s->read(&baseRotation); 767 s->read(&baseTranslation); 768 s->read(&baseScale); 769 s->read(&baseObjectState); 770 s->read(&baseDecalState); 771 } 772 else 773 { 774 s->read(&baseRotation); 775 baseTranslation=<a href="/coding/class/structtsshape_1_1sequence/#structtsshape_1_1sequence_1a75a024c482fec4f7e9affc725cbb1224">baseRotation</a>; 776 s->read(&baseObjectState); 777 s->read(&baseDecalState); 778 } 779 780 s->read(&firstTrigger); 781 s->read(&numTriggers); 782 s->read(&toolBegin); 783 784 // now the membership sets: 785 rotationMatters.read(s); 786 if (TSShape::smReadVersion<22) 787 translationMatters=<a href="/coding/class/structtsshape_1_1sequence/#structtsshape_1_1sequence_1a12f1288abe8cee756d100aca32334325">rotationMatters</a>; 788 else 789 { 790 translationMatters.read(s); 791 scaleMatters.read(s); 792 } 793 794 TSIntegerSet dummy; 795 dummy.read(s); // DEPRECIATED: Decals 796 dummy.read(s); // DEPRECIATED: Ifl materials 797 798 visMatters.read(s); 799 frameMatters.read(s); 800 matFrameMatters.read(s); 801 802 dirtyFlags = 0; 803 if (rotationMatters.testAll() || translationMatters.testAll() || scaleMatters.testAll()) 804 dirtyFlags |= TSShapeInstance::TransformDirty; 805 if (visMatters.testAll()) 806 dirtyFlags |= TSShapeInstance::VisDirty; 807 if (frameMatters.testAll()) 808 dirtyFlags |= TSShapeInstance::FrameDirty; 809 if (matFrameMatters.testAll()) 810 dirtyFlags |= TSShapeInstance::MatFrameDirty; 811} 812 813void TSShape::Sequence::write(Stream * s, bool writeNameIndex) const 814{ 815 if (writeNameIndex) 816 s->write(nameIndex); 817 s->write(flags); 818 s->write(numKeyframes); 819 s->write(duration); 820 s->write(priority); 821 s->write(firstGroundFrame); 822 s->write(numGroundFrames); 823 s->write(baseRotation); 824 s->write(baseTranslation); 825 s->write(baseScale); 826 s->write(baseObjectState); 827 s->write(baseDecalState); 828 s->write(firstTrigger); 829 s->write(numTriggers); 830 s->write(toolBegin); 831 832 // now the membership sets: 833 rotationMatters.write(s); 834 translationMatters.write(s); 835 scaleMatters.write(s); 836 837 TSIntegerSet dummy; 838 dummy.write(s); // DEPRECIATED: Decals 839 dummy.write(s); // DEPRECIATED: Ifl materials 840 841 visMatters.write(s); 842 frameMatters.write(s); 843 matFrameMatters.write(s); 844} 845 846void TSShape::writeName(Stream * s, S32 nameIndex) 847{ 848 const char * name = ""; 849 if (nameIndex>=0) 850 name = names[nameIndex]; 851 S32 sz = (S32)dStrlen(name); 852 s->write(sz); 853 if (sz) 854 s->write(sz*sizeof(char),name); 855} 856 857S32 TSShape::readName(Stream * s, bool addName) 858{ 859 static char buffer[256]; 860 U32 sz; 861 S32 nameIndex = -1; 862 s->read(&sz); 863 if (sz>0 && sz<255) 864 { 865 s->read(sz,buffer); 866 buffer[sz] = '\0'; 867 nameIndex = findName(buffer); 868 869 // Many modeling apps don't support spaces in names, so if the lookup 870 // failed, try the name again with spaces replaced by underscores 871 if (nameIndex < 0) 872 { 873 while (char *p = dStrchr(buffer, ' ')) 874 *p = '_'; 875 nameIndex = findName(buffer); 876 } 877 878 if (nameIndex<0 && addName) 879 { 880 nameIndex = names.size(); 881 names.increment(); 882 names.last() = buffer; 883 } 884 } 885 else 886 Con::errorf("invalid TSShape::readName length!"); 887 888 return nameIndex; 889} 890