Torque3D Documentation / _generateds / tsShapeOldRead.cpp

tsShapeOldRead.cpp

Engine/source/ts/tsShapeOldRead.cpp

More...

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
define
writeVectorSimpleMinus(a, m) {\
   s->write(() - m); \
    ( =m;<();++) \
      s->write([]); \
}
define
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