diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp index e9e985f7aad755a8f5dd7406422d8456f9d0d3c3..4740457edef1a4d0d3e15afdf0d30cae93cd3a61 100644 --- a/NIF_Blocks.cpp +++ b/NIF_Blocks.cpp @@ -2124,35 +2124,34 @@ string NiKeyframeData::asString() { void NiColorData::Read( ifstream& file, unsigned int version ) { uint keyCount = ReadUInt( file ); - NifStream( keyType, file ); + NifStream( _type, file ); - keys.resize( keyCount ); - for (uint i = 0; i < keys.size(); i++) { - NifStream( keys[i], file, keyType ); + _keys.resize( keyCount ); + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, _type ); } } void NiColorData::Write( ofstream& file, unsigned int version ) { - WriteUInt( uint(keys.size()), file ); - NifStream( keyType, file ); + WriteUInt( uint(_keys.size()), file ); + NifStream( _type, file ); - for (uint i = 0; i < keys.size(); i++) { - NifStream( keys[i], file, keyType ); + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, _type ); } } - string NiColorData::asString() { stringstream out; out.setf(ios::fixed, ios::floatfield); out << setprecision(1); - out << "Color Count: " << uint(keys.size()) << endl - << "Key Type: " << keyType << endl; + out << "Key Count: " << uint(_keys.size()) << endl + << "Key Type: " << _type << endl; if (verbose) { vector< Key<Color> >::iterator it; - for ( it = keys.begin(); it != keys.end(); ++it ) { + for ( it = _keys.begin(); it != _keys.end(); ++it ) { out << "Key Time: " << it->time << " Color: " << it->data.r << ", " << it->data.g << ", " << it->data.b << ", " << it->data.a << endl; } } else { @@ -2166,58 +2165,22 @@ string NiColorData::asString() { * NiFloatData methods **********************************************************/ -void NiFloatData::Read( ifstream& in, unsigned int version ) { - uint keyCount = ReadUInt( in ); - keyType = ReadUInt( in ); - - if (keyCount > 0 && (keyType < 1 || keyType > 3 ) ) { - stringstream s; - s << "NiFloatData is thought to only support keyType of 1, 2, or 3, but this NIF has a keyType of " << keyType << "."; - throw runtime_error(s.str()); - } +void NiFloatData::Read( ifstream& file, unsigned int version ) { + uint keyCount = ReadUInt( file ); + NifStream( _type, file ); - keys.resize( keyCount ); - for (uint i = 0; i < keys.size(); i++) { - //Always read the time and data - keys[i].time = ReadFloat( in ); - keys[i].data = ReadFloat( in ); - if ( keyType == 2 ) { - //Uses Quadratic interpolation - keys[i].forward_tangent = ReadFloat( in ); - keys[i].backward_tangent = ReadFloat( in ); - } else if ( keyType == 3 ) { - //Uses TBC interpolation - keys[i].tension = ReadFloat( in ); - keys[i].bias = ReadFloat( in ); - keys[i].continuity = ReadFloat( in ); - } + _keys.resize( keyCount ); + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, _type ); } } -void NiFloatData::Write( ofstream& out, unsigned int version ) { - WriteUInt( uint(keys.size()), out ); - WriteUInt( keyType, out ); - - if (keys.size() > 0 && (keyType < 1 || keyType > 3 ) ) { - stringstream s; - s << "NiFloatData is thought to only support keyType of 1, 2, or 3, but this NIF has a keyType of " << keyType << "."; - throw runtime_error(s.str()); - } +void NiFloatData::Write( ofstream& file, unsigned int version ) { + WriteUInt( uint(_keys.size()), file ); + NifStream( _type, file ); - for (uint i = 0; i < keys.size(); i++) { - //Always write the time and data - WriteFloat( keys[i].time, out ); - WriteFloat( keys[i].data, out ); - if ( keyType == 2 ) { - //Uses Quadratic interpolation - WriteFloat( keys[i].forward_tangent, out ); - WriteFloat( keys[i].backward_tangent, out ); - } else if ( keyType == 3 ) { - //Uses TBC interpolation - WriteFloat( keys[i].tension, out ); - WriteFloat( keys[i].bias, out ); - WriteFloat( keys[i].continuity, out ); - } + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, _type ); } } @@ -2226,30 +2189,18 @@ string NiFloatData::asString() { out.setf(ios::fixed, ios::floatfield); out << setprecision(1); - out << "Key Count: " << uint(keys.size()) << endl - << "Key Type: " << keyType << endl - << "Keys:" << endl; + out << "Key Count: " << uint(_keys.size()) << endl + << "Key Type: " << _type << endl; if (verbose) { - vector<Key<float> >::iterator it; - for ( it = keys.begin(); it != keys.end(); ++it ) { - for (uint i = 0; i < keys.size(); i++) { - //Always print the time and data - out << " " << i + 1 << ") Time: " << it->time << " Data: " << it->data; - if ( keyType == 2 ) { - //Uses Quadratic interpolation - out << " FT: " << it->forward_tangent << " BT: " << it->backward_tangent; - } else if ( keyType == 3 ) { - //Uses TBC interpolation - out << " T: " << it->tension << " B: " << it->bias << " C: " << it->continuity; - } - out << endl; - } + vector< Key<float> >::iterator it; + for ( it = _keys.begin(); it != _keys.end(); ++it ) { + out << "Key Time: " << it->time << " Float Value: " << it->data << endl; } } else { - out << " <<Data Not Shown>>" << endl; + out << "<<Data Not Shown>>" << endl; } - + return out.str(); } @@ -2826,46 +2777,22 @@ string NiPixelData::asString() { * NiPosData methods **********************************************************/ -void NiPosData::Read( ifstream& in, unsigned int version ) { - uint keyCount = ReadUInt( in ); - keyType = ReadUInt( in ); - - keys.resize(keyCount); - for (uint i = 0; i < keys.size(); i++) { - keys[i].time = ReadFloat( in ); - ReadFVector3( keys[i].data, in ); - - if (keyType == 2) { - ReadFVector3( keys[i].forward_tangent, in ); - ReadFVector3( keys[i].backward_tangent, in ); - } +void NiPosData::Read( ifstream& file, unsigned int version ) { + uint keyCount = ReadUInt( file ); + NifStream( _type, file ); - if (keyType != 1 && keyType != 2) { - stringstream str; - str << "NiPosData is thought to only support keyTypes of 1 and 2, but this NIF has a keyType of " << keyType << "."; - throw runtime_error( str.str() ); - } + _keys.resize( keyCount ); + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, _type ); } } -void NiPosData::Write( ofstream& out, unsigned int version ) { - WriteUInt( uint(keys.size()), out ); - WriteUInt( keyType, out ); - - for (uint i = 0; i < keys.size(); i++) { - WriteFloat( keys[i].time, out ); - WriteFVector3( keys[i].data, out ); - - if (keyType == 2) { - WriteFVector3( keys[i].forward_tangent, out ); - WriteFVector3( keys[i].backward_tangent, out ); - } +void NiPosData::Write( ofstream& file, unsigned int version ) { + WriteUInt( uint(_keys.size()), file ); + NifStream( _type, file ); - if (keyType != 1 && keyType != 2) { - stringstream str; - str << "NiPosData is thought to only support keyTypes of 1 and 2, but this NIF has a keyType of " << keyType << "."; - throw runtime_error( str.str() ); - } + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, _type ); } } @@ -2874,22 +2801,18 @@ string NiPosData::asString() { out.setf(ios::fixed, ios::floatfield); out << setprecision(1); - out << "Key Count: " << uint(keys.size()) << endl - << "Key Type: " << keyType << endl; + out << "Key Count: " << uint(_keys.size()) << endl + << "Key Type: " << _type << endl; if (verbose) { - for (uint i = 0; i < keys.size(); i++) { - out << "Key Time: " << keys[i].time << " Position: " << keys[i].data; - - if (keyType == 2) { - out << " F: " << keys[i].forward_tangent << " B: " << keys[i].backward_tangent; - } - out << endl; + vector< Key<Vector3> >::iterator it; + for ( it = _keys.begin(); it != _keys.end(); ++it ) { + out << "Key Time: " << it->time << " Position: " << it->data.x << ", " << it->data.y << ", " << it->data.z << endl; } } else { out << "<<Data Not Shown>>" << endl; } - + return out.str(); } @@ -2897,27 +2820,24 @@ string NiPosData::asString() { * NiTextKeyExtraData methods **********************************************************/ -void NiTextKeyExtraData::Read( ifstream& in, unsigned int version ) { - ABlock::Read( in, version ); - - uint keyCount = ReadUInt( in ); +void NiTextKeyExtraData::Read( ifstream& file, unsigned int version ) { + uint keyCount = ReadUInt( file ); + //Read type but throw it away, always LINEAR_KEY + ReadUInt( file ); - _keys.resize(keyCount); - for (uint i = 0; i < _keys.size(); ++i ) { - _keys[i].time = ReadFloat( in ); - _keys[i].data = ReadString( in ); + _keys.resize( keyCount ); + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, LINEAR_KEY ); } } -void NiTextKeyExtraData::Write( ofstream& out, unsigned int version ) { +void NiTextKeyExtraData::Write( ofstream& file, unsigned int version ) { + WriteUInt( uint(_keys.size()), file ); + KeyType _type = LINEAR_KEY; + NifStream( _type, file ); - ABlock::Write( out, version ); - - WriteUInt( uint(_keys.size()), out ); - - for (uint i = 0; i < _keys.size(); ++i ) { - WriteFloat( _keys[i].time, out ); - WriteString( _keys[i].data, out ); + for (uint i = 0; i < _keys.size(); i++) { + NifStream( _keys[i], file, LINEAR_KEY ); } } @@ -2926,19 +2846,17 @@ string NiTextKeyExtraData::asString() { out.setf(ios::fixed, ios::floatfield); out << setprecision(1); - out << "Next Extra Data: " << GetAttr("Next Extra Data")->asLink() << endl - << "Unknown Int (Key Type?): " << GetAttr("Unknown Int")->asInt() << endl - << "Key Count: " << uint(_keys.size()) << endl; + out << "Key Count: " << uint(_keys.size()) << endl; if (verbose) { - for (uint i = 0; i < _keys.size(); ++i ) { - out << "Key Time: " << _keys[i].time << endl - << "Key Text: " << _keys[i].data << endl; + vector< Key<string> >::iterator it; + for ( it = _keys.begin(); it != _keys.end(); ++it ) { + out << "Key Time: " << it->time << " Key Text: " << it->data << endl; } } else { out << "<<Data Not Shown>>" << endl; } - + return out.str(); } diff --git a/NIF_Blocks.h b/NIF_Blocks.h index 78afb0a43d58ff303790513212dfa6bac8db1b6a..5d012a0a97cbb0226b18420afa2306247f43cd34 100644 --- a/NIF_Blocks.h +++ b/NIF_Blocks.h @@ -1195,7 +1195,7 @@ public: string GetBlockType() { return "NiGeomMorpherController"; } }; -class NiColorData : public AData { +class NiColorData : public AData, public IColorData { public: NiColorData() {} ~NiColorData() {} @@ -1205,9 +1205,23 @@ public: string asString(); string GetBlockType() { return "NiColorData"; }; + void * QueryInterface( int id ) { + if ( id == ID_COLOR_DATA ) { + return (void*)static_cast<IColorData*>(this);; + } else { + return AData::QueryInterface( id ); + } + } + + //--IColorData Functions--// + KeyType GetKeyType() { return _type; } + void SetKeyType( KeyType t ) { _type = t; } + vector< Key<Color> > GetKeys() { return _keys; } + void SetKeys( vector< Key<Color> > & keys ) { _keys = keys; } + private: - KeyType keyType; - vector< Key<Color> > keys; + KeyType _type; + vector<Key<Color> > _keys; }; /** @@ -1225,7 +1239,7 @@ private: vector< pair< string, blk_ref> > controllers; }; -class NiFloatData : public AData { +class NiFloatData : public AData, public IFloatData { public: NiFloatData() {} ~NiFloatData() {} @@ -1235,9 +1249,23 @@ public: string asString(); string GetBlockType() { return "NiFloatData"; }; + void * QueryInterface( int id ) { + if ( id == ID_FLOAT_DATA ) { + return (void*)static_cast<IFloatData*>(this);; + } else { + return AData::QueryInterface( id ); + } + } + + //--IFloatData Functions--// + KeyType GetKeyType() { return _type; } + void SetKeyType( KeyType t ) { _type = t; } + vector< Key<float> > GetKeys() { return _keys; } + void SetKeys( vector< Key<float> > & keys ) { _keys = keys; } + private: - uint keyType; - vector<Key<float> > keys; + KeyType _type; + vector<Key<float> > _keys; }; class NiStringExtraData : public AExtraData { @@ -1316,7 +1344,7 @@ private: vector<Morph> morphs; }; -class NiPosData : public AData { +class NiPosData : public AData, public IPosData { public: NiPosData() {} ~NiPosData() {} @@ -1326,9 +1354,23 @@ public: string asString(); string GetBlockType() { return "NiPosData"; } + void * QueryInterface( int id ) { + if ( id == ID_POS_DATA ) { + return (void*)static_cast<IPosData*>(this);; + } else { + return AData::QueryInterface( id ); + } + } + + //--IPosData Functions--// + KeyType GetKeyType() { return _type; } + void SetKeyType( KeyType t ) { _type = t; } + vector< Key<Vector3> > GetKeys() { return _keys; } + void SetKeys( vector< Key<Vector3> > & keys ) { _keys = keys; } + private: - uint keyType; - vector<Key<fVector3> > keys; + KeyType _type; + vector<Key<Vector3> > _keys; }; class NiRotatingParticlesData : public ARotatingParticlesData { diff --git a/niflib.cpp b/niflib.cpp index 1e1dbc116c55267fbf84a264c3082d51896506ae..68c342e52bb494932af36bddd1b85f6ca5cf2fb7 100644 --- a/niflib.cpp +++ b/niflib.cpp @@ -606,3 +606,15 @@ IMorphData * QueryMorphData ( blk_ref & block ) { ITriStripsData * QueryTriStripsData ( blk_ref & block ) { return (ITriStripsData*)block->QueryInterface( ID_TRI_STRIPS_DATA ); } + +IColorData * QueryColorData ( blk_ref & block ) { + return (IColorData*)block->QueryInterface( ID_COLOR_DATA ); +} + +IFloatData * QueryFloatData ( blk_ref & block ) { + return (IFloatData*)block->QueryInterface( ID_FLOAT_DATA ); +} + +IPosData * QueryPosData ( blk_ref & block ) { + return (IPosData*)block->QueryInterface( ID_POS_DATA ); +} \ No newline at end of file diff --git a/niflib.h b/niflib.h index 6d97b537a07c7697e6b2c063fd9dea27ffdeae40..382f252537c7a6bab03b68575673db8dc022bddf 100644 --- a/niflib.h +++ b/niflib.h @@ -59,6 +59,9 @@ class IKeyframeData; class ITextKeyExtraData; class IMorphData; class ITriStripsData; +class IColorData; +class IFloatData; +class IPosData; class INode; class blk_ref; class attr_ref; @@ -80,6 +83,9 @@ const int ID_TEXT_KEY_EXTRA_DATA = 4; const int ID_MORPH_DATA = 5; const int ID_SHAPE_DATA = 6; const int ID_TRI_STRIPS_DATA = 7; +const int ID_COLOR_DATA = 8; +const int ID_FLOAT_DATA = 9; +const int ID_POS_DATA = 10; //Attribute types enum AttrType { @@ -146,6 +152,9 @@ IKeyframeData * QueryKeyframeData( blk_ref & block ); ITextKeyExtraData * QueryTextKeyExtraData ( blk_ref & block ); IMorphData * QueryMorphData ( blk_ref & block ); ITriStripsData * QueryTriStripsData ( blk_ref & block ); +IColorData * QueryColorData ( blk_ref & block ); +IFloatData * QueryFloatData ( blk_ref & block ); +IPosData * QueryPosData ( blk_ref & block ); //--Simple Structures--// @@ -628,8 +637,40 @@ public: virtual ~ITextKeyExtraData () {} virtual vector< Key<string> > GetKeys() = 0; virtual void SetKeys( vector< Key<string> > const & keys ) = 0; + +}; + +class IColorData { +public: + IColorData() {} + virtual ~IColorData () {} + virtual KeyType GetKeyType() = 0; + virtual void SetKeyType( KeyType t ) = 0; + virtual vector< Key<Color> > GetKeys() = 0; + virtual void SetKeys( vector< Key<Color> > & keys ) = 0; }; +class IFloatData { +public: + IFloatData() {} + virtual ~IFloatData () {} + virtual KeyType GetKeyType() = 0; + virtual void SetKeyType( KeyType t ) = 0; + virtual vector< Key<float> > GetKeys() = 0; + virtual void SetKeys( vector< Key<float> > & keys ) = 0; +}; + +class IPosData { +public: + IPosData() {} + virtual ~IPosData () {} + virtual KeyType GetKeyType() = 0; + virtual void SetKeyType( KeyType t ) = 0; + virtual vector< Key<Vector3> > GetKeys() = 0; + virtual void SetKeys( vector< Key<Vector3> > & keys ) = 0; +}; + + class IMorphData { public: IMorphData() {} diff --git a/pyniflib.i b/pyniflib.i index 131d3642179ab553a02fb4e16bc0ce8774f3469a..1985d3f644adb917d79c3a520367ee6fa12f1bfd 100644 --- a/pyniflib.i +++ b/pyniflib.i @@ -95,6 +95,8 @@ struct Key { %template(vector_Key_Vector3) std::vector< Key<Vector3> >; %template(Key_float) Key<float>; %template(vector_Key_float) std::vector< Key<float> >; +%template(Key_Color) Key<Color>; +%template(vector_Key_Color) std::vector< Key<Color> >; %template(Key_string) Key<std::string>; %template(vector_Key_string) std::vector< Key<std::string> >; %template(blablabla) Key<double>;