Initial commit
This commit is contained in:
776
Torque/SDK/lib/dtsSDK/DTSShape.cpp
Normal file
776
Torque/SDK/lib/dtsSDK/DTSShape.cpp
Normal file
@@ -0,0 +1,776 @@
|
||||
|
||||
#pragma warning ( disable: 4786 )
|
||||
|
||||
#include "DTSShape.h"
|
||||
#include "DTSBrushMesh.h"
|
||||
#include "DTSOutputStream.h"
|
||||
#include "DTSInputStream.h"
|
||||
#include "DTSEndian.h"
|
||||
#include "DTSTypes.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Helper macro -- assumes output stream "out"
|
||||
#define writeEndian(a,sz) out.write((char*) &FIX_ENDIAN(a),sz)
|
||||
|
||||
namespace DTS
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Constructor (create an empty shape)
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Shape::Shape()
|
||||
{
|
||||
}
|
||||
|
||||
Sequence::Sequence()
|
||||
{
|
||||
baseDecalState = 0 ;
|
||||
baseObjectState = 0 ;
|
||||
baseRotation = 0 ;
|
||||
baseScale = 0 ;
|
||||
baseTranslation = 0 ;
|
||||
duration = 1.0f ;
|
||||
firstGroundFrame = 0 ;
|
||||
flags = 0 ;
|
||||
nameIndex = 0 ;
|
||||
numGroundFrames = 0 ;
|
||||
numKeyFrames = 0 ;
|
||||
priority = 1 ;
|
||||
toolBegin = 0.0f ;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Loads a DTS file
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void Shape::read (std::istream &in)
|
||||
{
|
||||
InputStream stream(in) ;
|
||||
int version = stream.version() ;
|
||||
|
||||
if (version < 19)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MessageBox (NULL, "The DTS file is of a older, unsupported version", "Error",
|
||||
MB_ICONHAND | MB_OK) ;
|
||||
#else
|
||||
assert(0 && "The DTS file is of a older, unsupported version");
|
||||
#endif
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
// Header
|
||||
|
||||
int numNodes ;
|
||||
int numObjects ;
|
||||
int numDecals ;
|
||||
int numSubshapes ;
|
||||
int numIFLmaterials ;
|
||||
int numNodeRotations ;
|
||||
int numNodeTranslations ;
|
||||
int numNodeScalesUniform ;
|
||||
int numNodeScalesAligned ;
|
||||
int numNodeScalesArbitrary ;
|
||||
int numGroundFrames ;
|
||||
int numObjectStates ;
|
||||
int numDecalStates ;
|
||||
int numTriggers ;
|
||||
int numDetailLevels ;
|
||||
int numMeshes ;
|
||||
int numSkins ;
|
||||
int numNames ;
|
||||
|
||||
stream >> numNodes >> numObjects >> numDecals >> numSubshapes >> numIFLmaterials ;
|
||||
|
||||
if (version < 22)
|
||||
{
|
||||
stream >> numNodeRotations ;
|
||||
numNodeRotations -= numNodes ;
|
||||
numNodeTranslations = numNodeRotations ;
|
||||
numNodeScalesUniform = 0 ;
|
||||
numNodeScalesAligned = 0 ;
|
||||
numNodeScalesArbitrary = 0 ;
|
||||
numGroundFrames = 0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream >> numNodeRotations ;
|
||||
stream >> numNodeTranslations ;
|
||||
stream >> numNodeScalesUniform ;
|
||||
stream >> numNodeScalesAligned ;
|
||||
stream >> numNodeScalesArbitrary ;
|
||||
if (version > 23)
|
||||
stream >> numGroundFrames ;
|
||||
}
|
||||
|
||||
stream >> numObjectStates ;
|
||||
stream >> numDecalStates ;
|
||||
stream >> numTriggers ;
|
||||
stream >> numDetailLevels ;
|
||||
stream >> numMeshes ;
|
||||
|
||||
if (version < 23)
|
||||
stream >> numSkins ;
|
||||
else
|
||||
numSkins = 0 ;
|
||||
|
||||
stream >> numNames ;
|
||||
|
||||
int smallestSizeInt ;
|
||||
stream >> smallestSizeInt ;
|
||||
stream >> smallestDetailLevel ;
|
||||
smallestSize = (float)smallestSizeInt ;
|
||||
|
||||
stream.readCheck(0) ;
|
||||
|
||||
// Bounds
|
||||
|
||||
stream >> radius ;
|
||||
stream >> tubeRadius ;
|
||||
stream >> center ;
|
||||
stream >> bounds ;
|
||||
|
||||
stream.readCheck(1) ;
|
||||
|
||||
// Nodes
|
||||
|
||||
nodes.resize(numNodes) ;
|
||||
stream >> nodes ;
|
||||
stream.readCheck(2) ;
|
||||
|
||||
// Objects
|
||||
|
||||
objects.resize(numObjects) ;
|
||||
stream >> objects ;
|
||||
stream.readCheck(3) ;
|
||||
|
||||
// Decals
|
||||
|
||||
decals.resize(numDecals) ;
|
||||
stream >> decals ;
|
||||
stream.readCheck(4) ;
|
||||
|
||||
// IFL Materials
|
||||
|
||||
IFLmaterials.resize(numIFLmaterials) ;
|
||||
stream >> IFLmaterials ;
|
||||
stream.readCheck(5) ;
|
||||
|
||||
// Subshapes
|
||||
|
||||
subshapes.resize(numSubshapes) ;
|
||||
std::vector<Subshape>::iterator shape ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream >> shape->firstNode ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream >> shape->firstObject ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream >> shape->firstDecal ;
|
||||
stream.readCheck(6) ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream >> shape->numNodes ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream >> shape->numObjects ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream >> shape->numDecals ;
|
||||
stream.readCheck(7) ;
|
||||
|
||||
// MeshIndexList (obsolete data)
|
||||
|
||||
if (version < 16)
|
||||
{
|
||||
int size, temp ;
|
||||
stream >> size ;
|
||||
while (size--) stream >> temp ;
|
||||
}
|
||||
|
||||
// Default translations and rotations
|
||||
|
||||
nodeDefRotations.resize(numNodes) ;
|
||||
nodeDefTranslations.resize(numNodes) ;
|
||||
|
||||
for (int n = 0 ; n < nodes.size() ; n++)
|
||||
{
|
||||
stream >> nodeDefRotations[n] ;
|
||||
stream >> nodeDefTranslations[n] ;
|
||||
}
|
||||
|
||||
// Animation translations and rotations
|
||||
|
||||
nodeTranslations.resize(numNodeTranslations) ;
|
||||
nodeRotations.resize(numNodeRotations) ;
|
||||
stream >> nodeTranslations ;
|
||||
stream >> nodeRotations ;
|
||||
stream.readCheck(8) ;
|
||||
|
||||
// Default scales
|
||||
|
||||
nodeScalesUniform.resize (numNodeScalesUniform) ;
|
||||
nodeScalesAligned.resize (numNodeScalesAligned) ;
|
||||
nodeScalesArbitrary.resize (numNodeScalesArbitrary) ;
|
||||
|
||||
if (version > 21)
|
||||
{
|
||||
stream >> numNodeScalesUniform ;
|
||||
stream >> numNodeScalesAligned ;
|
||||
stream >> numNodeScalesArbitrary ;
|
||||
stream.readCheck(9) ;
|
||||
}
|
||||
|
||||
// Ground transformations
|
||||
|
||||
groundTranslations.resize (numGroundFrames) ;
|
||||
groundRotations.resize (numGroundFrames) ;
|
||||
|
||||
if (version > 23)
|
||||
{
|
||||
stream >> groundTranslations ;
|
||||
stream >> groundRotations ;
|
||||
stream.readCheck() ;
|
||||
}
|
||||
|
||||
// Object states
|
||||
|
||||
objectStates.resize (numObjectStates) ;
|
||||
stream >> objectStates ;
|
||||
stream.readCheck() ;
|
||||
|
||||
// Decal states
|
||||
|
||||
decalStates.resize (numDecalStates) ;
|
||||
stream >> decalStates ;
|
||||
stream.readCheck() ;
|
||||
|
||||
// Triggers
|
||||
|
||||
triggers.resize (numTriggers) ;
|
||||
stream >> triggers ;
|
||||
stream.readCheck() ;
|
||||
|
||||
// Detail Levels
|
||||
|
||||
detailLevels.resize (numDetailLevels) ;
|
||||
stream >> detailLevels ;
|
||||
stream.readCheck() ;
|
||||
|
||||
// Meshes
|
||||
|
||||
meshes.resize (numMeshes) ;
|
||||
stream >> meshes ;
|
||||
stream.readCheck() ;
|
||||
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Saves a DTS file
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
void Shape::save (std::ostream & out) const
|
||||
{
|
||||
OutputStream stream (out, 24) ;
|
||||
|
||||
// Header
|
||||
|
||||
stream << (int) nodes.size() ;
|
||||
stream << (int) objects.size() ;
|
||||
stream << (int) decals.size() ;
|
||||
stream << (int) subshapes.size() ;
|
||||
stream << (int) IFLmaterials.size() ;
|
||||
stream << (int) nodeRotations.size() ;
|
||||
stream << (int) nodeTranslations.size() ;
|
||||
stream << (int) nodeScalesUniform.size() ;
|
||||
stream << (int) nodeScalesAligned.size() ;
|
||||
stream << (int) nodeScalesArbitrary.size() ;
|
||||
stream << (int) groundTranslations.size() ;
|
||||
stream << (int) objectStates.size() ;
|
||||
stream << (int) decalStates.size() ;
|
||||
stream << (int) triggers.size() ;
|
||||
stream << (int) detailLevels.size() ;
|
||||
stream << (int) meshes.size() ;
|
||||
stream << (int) names.size() ;
|
||||
stream << (int) smallestSize ;
|
||||
stream << smallestDetailLevel ;
|
||||
|
||||
stream.storeCheck(0) ;
|
||||
|
||||
// Bounds
|
||||
|
||||
stream << radius ;
|
||||
stream << tubeRadius ;
|
||||
stream << center ;
|
||||
stream << bounds ;
|
||||
|
||||
stream.storeCheck(1) ;
|
||||
|
||||
// Nodes
|
||||
|
||||
stream << nodes ;
|
||||
stream.storeCheck(2) ;
|
||||
|
||||
// Objects
|
||||
|
||||
stream << objects ;
|
||||
stream.storeCheck(3) ;
|
||||
|
||||
// Decals
|
||||
|
||||
stream << decals ;
|
||||
stream.storeCheck(4) ;
|
||||
|
||||
// IFL Materials
|
||||
|
||||
stream << IFLmaterials ;
|
||||
stream.storeCheck(5) ;
|
||||
|
||||
// Subshapes
|
||||
|
||||
std::vector<Subshape>::const_iterator shape ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream << shape->firstNode ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream << shape->firstObject ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream << shape->firstDecal ;
|
||||
stream.storeCheck(6) ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream << shape->numNodes ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream << shape->numObjects ;
|
||||
for (shape = subshapes.begin() ; shape != subshapes.end() ; shape++)
|
||||
stream << shape->numDecals ;
|
||||
stream.storeCheck(7) ;
|
||||
|
||||
// Default translations and rotations
|
||||
|
||||
assert (nodeDefRotations.size() == nodes.size()) ;
|
||||
assert (nodeDefTranslations.size() == nodes.size()) ;
|
||||
|
||||
for (int n = 0 ; n < nodes.size() ; n++)
|
||||
{
|
||||
stream << nodeDefRotations[n] ;
|
||||
stream << nodeDefTranslations[n] ;
|
||||
}
|
||||
|
||||
// Animation translations and rotations
|
||||
|
||||
stream << nodeTranslations ; // As current position, we store the same values
|
||||
stream << nodeRotations ;
|
||||
stream.storeCheck(8) ;
|
||||
|
||||
// Default scales
|
||||
|
||||
stream << nodeScalesUniform ;
|
||||
stream << nodeScalesAligned ;
|
||||
stream << nodeScalesArbitrary ;
|
||||
stream << nodeScaleRotsArbitrary ;
|
||||
stream.storeCheck(9) ;
|
||||
|
||||
// Ground transformations
|
||||
|
||||
stream << groundTranslations ;
|
||||
stream << groundRotations ;
|
||||
stream.storeCheck(10) ;
|
||||
|
||||
// Object states
|
||||
|
||||
stream << objectStates ;
|
||||
stream.storeCheck(11) ;
|
||||
|
||||
// Decal states
|
||||
|
||||
stream << decalStates ;
|
||||
stream.storeCheck(12) ;
|
||||
|
||||
// Triggers
|
||||
|
||||
stream << triggers ;
|
||||
stream.storeCheck(13) ;
|
||||
|
||||
// Detail levels
|
||||
|
||||
stream << detailLevels ;
|
||||
stream.storeCheck(14) ;
|
||||
|
||||
// Meshes
|
||||
|
||||
stream << meshes ;
|
||||
stream.storeCheck() ; // Many checks stored within the meshes
|
||||
|
||||
// Names
|
||||
|
||||
stream << names ;
|
||||
stream.storeCheck() ;
|
||||
|
||||
// Finished with the 3-buffer stuff
|
||||
|
||||
stream.flush() ;
|
||||
|
||||
// Sequences
|
||||
|
||||
int numSequences = sequences.size() ;
|
||||
out.write ((char *)&FIX_ENDIAN(numSequences), 4) ;
|
||||
|
||||
for (int seq = 0 ; seq < sequences.size() ; seq++)
|
||||
{
|
||||
const Sequence &p = sequences[seq] ;
|
||||
|
||||
out.write ((char *) &FIX_ENDIAN(p.nameIndex), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.flags), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.numKeyFrames), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.duration), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.priority), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.firstGroundFrame), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.numGroundFrames), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.baseRotation), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.baseTranslation), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.baseScale), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.baseObjectState), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.baseDecalState), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.firstTrigger), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.numTriggers), 4) ;
|
||||
out.write ((char *) &FIX_ENDIAN(p.toolBegin), 4) ;
|
||||
|
||||
write(out,&p.matters.rotation);
|
||||
write(out,&p.matters.translation);
|
||||
write(out,&p.matters.scale);
|
||||
write(out,&p.matters.decal);
|
||||
write(out,&p.matters.ifl);
|
||||
write(out,&p.matters.vis);
|
||||
write(out,&p.matters.frame);
|
||||
write(out,&p.matters.matframe);
|
||||
}
|
||||
|
||||
// Materials
|
||||
|
||||
char materialListVersion = 1 ;
|
||||
out.write (&materialListVersion, 1) ;
|
||||
int count = materials.size() ;
|
||||
out.write ((char *) &FIX_ENDIAN(count), 4) ;
|
||||
|
||||
std::vector<Material>::const_iterator mat ;
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
{
|
||||
char length = mat->name.size() ;
|
||||
out.write (&length, 1) ;
|
||||
std::string::const_iterator pos = mat->name.begin() ;
|
||||
while (pos != mat->name.end())
|
||||
out.write (&*(pos++), 1) ;
|
||||
}
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
out.write ((char *) &FIX_ENDIAN(mat->flags), 4) ;
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
out.write ((char *) &FIX_ENDIAN(mat->reflectance), 4) ;
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
out.write ((char *) &FIX_ENDIAN(mat->bump), 4) ;
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
out.write ((char *) &FIX_ENDIAN(mat->detail), 4) ;
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
out.write ((char *) &FIX_ENDIAN(mat->detailScale), 4) ;
|
||||
for (mat = materials.begin() ; mat != materials.end() ; mat++)
|
||||
out.write ((char *) &FIX_ENDIAN(mat->reflection), 4) ;
|
||||
|
||||
// Done!
|
||||
}
|
||||
|
||||
void Shape::saveSequences(std::ostream & out) const
|
||||
{
|
||||
int i;
|
||||
|
||||
// write version info
|
||||
writeEndian((int)24,4);
|
||||
|
||||
// write node names
|
||||
// -- this is how we will map imported sequence nodes to shape nodes
|
||||
writeEndian(nodes.size(),4);
|
||||
for (i=0; i<nodes.size(); i++)
|
||||
{
|
||||
const char * name = names[nodes[i].name].c_str();
|
||||
writeEndian(strlen(name),4);
|
||||
out.write(name,strlen(name));
|
||||
}
|
||||
|
||||
// legacy write -- write zero objects, don't pretend to support object export anymore
|
||||
writeEndian((int)0,4);
|
||||
|
||||
// on import, we will need to adjust keyframe data based on number of
|
||||
// nodes/objects in this shape...number of nodes can be inferred from
|
||||
// above, but number of objects cannot be. Write that quantity here:
|
||||
writeEndian(objects.size(),4);
|
||||
|
||||
writeEndian(nodeRotations.size(),4);
|
||||
for (i=0; i<nodeRotations.size(); i++)
|
||||
{
|
||||
writeEndian((short)(nodeRotations[i].x() * 32767.0f),2);
|
||||
writeEndian((short)(nodeRotations[i].y() * 32767.0f),2);
|
||||
writeEndian((short)(nodeRotations[i].z() * 32767.0f),2);
|
||||
writeEndian((short)(nodeRotations[i].w() * 32767.0f),2);
|
||||
}
|
||||
|
||||
writeEndian(nodeTranslations.size(),4);
|
||||
for (i=0; i<nodeTranslations.size(); i++)
|
||||
{
|
||||
writeEndian(nodeTranslations[i].x(),4);
|
||||
writeEndian(nodeTranslations[i].y(),4);
|
||||
writeEndian(nodeTranslations[i].z(),4);
|
||||
}
|
||||
|
||||
writeEndian(nodeScalesUniform.size(),4);
|
||||
for (i=0; i<nodeScalesUniform.size(); i++)
|
||||
{
|
||||
writeEndian(nodeScalesUniform[i],4);
|
||||
}
|
||||
|
||||
writeEndian(nodeScalesAligned.size(),4);
|
||||
for (i=0; i<nodeScalesAligned.size(); i++)
|
||||
{
|
||||
writeEndian(nodeScalesAligned[i].x(),4);
|
||||
writeEndian(nodeScalesAligned[i].y(),4);
|
||||
writeEndian(nodeScalesAligned[i].z(),4);
|
||||
}
|
||||
|
||||
writeEndian(nodeScaleRotsArbitrary.size(),4);
|
||||
for (i=0; i<nodeScaleRotsArbitrary.size(); i++)
|
||||
{
|
||||
writeEndian((short)(nodeScaleRotsArbitrary[i].x() * 32767.0f),2);
|
||||
writeEndian((short)(nodeScaleRotsArbitrary[i].y() * 32767.0f),2);
|
||||
writeEndian((short)(nodeScaleRotsArbitrary[i].z() * 32767.0f),2);
|
||||
writeEndian((short)(nodeScaleRotsArbitrary[i].w() * 32767.0f),2);
|
||||
}
|
||||
// same number as above...
|
||||
for (i=0; i<nodeScalesArbitrary.size(); i++)
|
||||
{
|
||||
writeEndian(nodeScalesArbitrary[i].x(),4);
|
||||
writeEndian(nodeScalesArbitrary[i].y(),4);
|
||||
writeEndian(nodeScalesArbitrary[i].z(),4);
|
||||
}
|
||||
|
||||
writeEndian(groundTranslations.size(),4);
|
||||
for (i=0; i<groundTranslations.size(); i++)
|
||||
{
|
||||
writeEndian(groundTranslations[i].x(),4);
|
||||
writeEndian(groundTranslations[i].y(),4);
|
||||
writeEndian(groundTranslations[i].z(),4);
|
||||
}
|
||||
// same number as above
|
||||
for (i=0; i<groundRotations.size(); i++)
|
||||
{
|
||||
writeEndian((short)(groundRotations[i].x() * 32767.0f),2);
|
||||
writeEndian((short)(groundRotations[i].y() * 32767.0f),2);
|
||||
writeEndian((short)(groundRotations[i].z() * 32767.0f),2);
|
||||
writeEndian((short)(groundRotations[i].w() * 32767.0f),2);
|
||||
}
|
||||
|
||||
// legacy write -- write zero objects, don't pretend to support object export anymore
|
||||
writeEndian((int)0,4);
|
||||
|
||||
// Sequences
|
||||
|
||||
int numSequences = sequences.size() ;
|
||||
writeEndian(numSequences,4);
|
||||
|
||||
for (int seq = 0 ; seq < sequences.size() ; seq++)
|
||||
{
|
||||
const Sequence &p = sequences[seq] ;
|
||||
|
||||
// write sequence name
|
||||
const char * seqname = names[p.nameIndex].c_str();
|
||||
writeEndian(strlen(seqname),4);
|
||||
out.write((char*)seqname,strlen(seqname));
|
||||
|
||||
// skip name index...
|
||||
writeEndian(p.flags,4);
|
||||
writeEndian(p.numKeyFrames,4);
|
||||
writeEndian(p.duration,4);
|
||||
writeEndian(p.priority,4);
|
||||
writeEndian(p.firstGroundFrame,4);
|
||||
writeEndian(p.numGroundFrames,4);
|
||||
writeEndian(p.baseRotation,4);
|
||||
writeEndian(p.baseTranslation,4);
|
||||
writeEndian(p.baseScale,4);
|
||||
writeEndian(p.baseObjectState,4);
|
||||
writeEndian(p.baseDecalState,4);
|
||||
writeEndian(p.firstTrigger,4);
|
||||
writeEndian(p.numTriggers,4);
|
||||
writeEndian(p.toolBegin,4);
|
||||
|
||||
write(out,&p.matters.rotation);
|
||||
write(out,&p.matters.translation);
|
||||
write(out,&p.matters.scale);
|
||||
write(out,&p.matters.decal);
|
||||
write(out,&p.matters.ifl);
|
||||
write(out,&p.matters.vis);
|
||||
write(out,&p.matters.frame);
|
||||
write(out,&p.matters.matframe);
|
||||
}
|
||||
|
||||
writeEndian(triggers.size(),4);
|
||||
for (i=0; i<triggers.size(); i++)
|
||||
{
|
||||
writeEndian(triggers[i].state,4);
|
||||
writeEndian(triggers[i].pos,4);
|
||||
}
|
||||
}
|
||||
|
||||
void Shape::write (std::ostream & out,const std::vector<bool> * ptr) const
|
||||
{
|
||||
// Save out the bool array as an array of bits, in 32bit chunks.
|
||||
int words[32], use = ptr->size() / 32 ;
|
||||
if (use * 32 < ptr->size()) use++ ;
|
||||
|
||||
memset(words, 0, sizeof(words));
|
||||
for (int i = 0 ; i < ptr->size() ; i++)
|
||||
if ((*ptr)[i])
|
||||
words[i >> 5] |= 1 << (i & 31);
|
||||
for (int j = 0; j < sizeof(words)/sizeof(int); j++)
|
||||
words[j] = FIX_ENDIAN(words[j]);
|
||||
|
||||
|
||||
out.write ((char *)&FIX_ENDIAN(use), 4) ;
|
||||
out.write ((char *)&FIX_ENDIAN(use), 4) ;
|
||||
if (use > 0)
|
||||
out.write ((char *)&words, 4*use) ;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Utility methods
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
int Shape::addName (std::string s)
|
||||
{
|
||||
// Don't store duplicated names
|
||||
|
||||
for (int i = 0 ; i < names.size() ; i++)
|
||||
{
|
||||
#if _WIN32
|
||||
if (!stricmp(names[i].data(),s.data()))
|
||||
#else
|
||||
if (!strcasecmp(names[i].data(),s.data()))
|
||||
#endif
|
||||
return i ;
|
||||
}
|
||||
names.push_back(s) ;
|
||||
return names.size() - 1 ;
|
||||
}
|
||||
|
||||
void Shape::calculateBounds()
|
||||
{
|
||||
if (!objects.size()) return ;
|
||||
|
||||
bounds.max = Point(-10E30F, -10E30F, -10E30F) ;
|
||||
bounds.min = Point( 10E30F, 10E30F, 10E30F) ;
|
||||
|
||||
// Iterate through the objects instead of the meshes
|
||||
// so we can easily get the default transforms.
|
||||
for (int i = 0 ; i < objects.size() ; i++)
|
||||
{
|
||||
const Object &obj = objects[i];
|
||||
|
||||
Point trans;
|
||||
Quaternion rot;
|
||||
getNodeWorldPosRot(obj.node,trans,rot);
|
||||
|
||||
for (int j = 0 ; j < obj.numMeshes ; j++)
|
||||
{
|
||||
Box bounds2 = meshes[obj.firstMesh + j].getBounds(trans,rot) ;
|
||||
bounds.min.x(min(bounds.min.x(), bounds2.min.x())) ;
|
||||
bounds.min.y(min(bounds.min.y(), bounds2.min.y())) ;
|
||||
bounds.min.z(min(bounds.min.z(), bounds2.min.z())) ;
|
||||
bounds.max.x(max(bounds.max.x(), bounds2.max.x())) ;
|
||||
bounds.max.y(max(bounds.max.y(), bounds2.max.y())) ;
|
||||
bounds.max.z(max(bounds.max.z(), bounds2.max.z())) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Shape::calculateCenter()
|
||||
{
|
||||
center = bounds.min.midpoint(bounds.max) ;
|
||||
}
|
||||
|
||||
void Shape::calculateTubeRadius()
|
||||
{
|
||||
float maxRadius = 0.0f ;
|
||||
|
||||
for (int i = 0 ; i < objects.size() ; i++)
|
||||
{
|
||||
const Object &obj = objects[i];
|
||||
|
||||
Point trans;
|
||||
Quaternion rot;
|
||||
getNodeWorldPosRot(obj.node,trans,rot);
|
||||
|
||||
for (int j = 0 ; j < obj.numMeshes ; j++)
|
||||
{
|
||||
const Mesh &m = meshes[obj.firstMesh + j];
|
||||
float meshRadius = m.getTubeRadiusFrom(trans,rot,center) ;
|
||||
if (meshRadius > maxRadius)
|
||||
maxRadius = meshRadius ;
|
||||
}
|
||||
}
|
||||
tubeRadius = maxRadius ;
|
||||
}
|
||||
|
||||
void Shape::calculateRadius()
|
||||
{
|
||||
float maxRadius = 0.0f ;
|
||||
|
||||
for (int i = 0 ; i < objects.size() ; i++)
|
||||
{
|
||||
const Object &obj = objects[i];
|
||||
|
||||
Point trans;
|
||||
Quaternion rot;
|
||||
getNodeWorldPosRot(obj.node,trans,rot);
|
||||
|
||||
for (int j = 0 ; j < obj.numMeshes ; j++)
|
||||
{
|
||||
const Mesh &m = meshes[obj.firstMesh + j];
|
||||
float meshRadius = m.getRadiusFrom(trans,rot,center) ;
|
||||
if (meshRadius > maxRadius)
|
||||
maxRadius = meshRadius ;
|
||||
}
|
||||
}
|
||||
radius = maxRadius ;
|
||||
}
|
||||
|
||||
void Shape::setSmallestSize(int pixels)
|
||||
{
|
||||
if (pixels < 1)
|
||||
pixels = 1;
|
||||
|
||||
smallestSize = pixels;
|
||||
|
||||
int i=0;
|
||||
|
||||
for (i = 0; i < detailLevels.size(); i++)
|
||||
{
|
||||
if (detailLevels[i].size < pixels)
|
||||
break ;
|
||||
}
|
||||
smallestDetailLevel = i;
|
||||
}
|
||||
|
||||
void Shape::getNodeWorldPosRot(int n, Point &trans, Quaternion &rot)
|
||||
{
|
||||
// Build total translation & rotation for this node
|
||||
std::vector <int> nidx;
|
||||
nidx.push_back(n);
|
||||
while ((n = nodes[n].parent) >= 0)
|
||||
nidx.push_back(n);
|
||||
|
||||
trans = Point(0,0,0);
|
||||
rot = Quaternion::identity;
|
||||
for (int i = nidx.size() - 1; i >= 0; i--)
|
||||
{
|
||||
trans += rot.apply(nodeDefTranslations[nidx[i]]);
|
||||
rot = nodeDefRotations[nidx[i]] * rot;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user