diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp index b9d84b58a..dac541b2d 100644 --- a/components/nif/controlled.hpp +++ b/components/nif/controlled.hpp @@ -36,7 +36,7 @@ class Controlled : public Extra public: ControllerPtr controller; - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); controller.read(nif); @@ -55,7 +55,7 @@ class Named : public Controlled public: std::string name; - void read(NIFFile *nif) + void read(NIFStream *nif) { name = nif->getString(); Controlled::read(nif); @@ -66,7 +66,7 @@ typedef Named NiSequenceStreamHelper; class NiParticleGrowFade : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); @@ -80,7 +80,7 @@ class NiParticleColorModifier : public Controlled public: NiColorDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); data.read(nif); @@ -96,7 +96,7 @@ public: class NiGravity : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); @@ -109,7 +109,7 @@ public: class NiPlanarCollider : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); @@ -121,7 +121,7 @@ public: class NiParticleRotation : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index cbc19cd8f..4f7ef3c0f 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -40,7 +40,7 @@ public: float timeStart, timeStop; ControlledPtr target; - void read(NIFFile *nif) + void read(NIFStream *nif) { next.read(nif); @@ -65,7 +65,7 @@ public: class NiBSPArrayController : public Controller { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); @@ -82,7 +82,7 @@ class NiMaterialColorController : public Controller public: NiPosDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -101,7 +101,7 @@ public: NiPosDataPtr posData; NiFloatDataPtr floatData; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); @@ -129,7 +129,7 @@ class NiUVController : public Controller public: NiUVDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); @@ -149,7 +149,7 @@ class NiKeyframeController : public Controller public: NiKeyframeDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -167,7 +167,7 @@ class NiAlphaController : public Controller public: NiFloatDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -185,7 +185,7 @@ class NiGeomMorpherController : public Controller public: NiMorphDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -204,7 +204,7 @@ class NiVisController : public Controller public: NiVisDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 46b58da8f..5f18800f0 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -65,7 +65,7 @@ public: */ int alpha; - void read(NIFFile *nif) + void read(NIFStream *nif) { Named::read(nif); @@ -102,7 +102,7 @@ public: Ogre::Vector3 center; float radius; - void read(NIFFile *nif) + void read(NIFStream *nif) { int verts = nif->getUShort(); @@ -138,7 +138,7 @@ public: // Triangles, three vertex indices per triangle std::vector triangles; - void read(NIFFile *nif) + void read(NIFStream *nif) { ShapeData::read(nif); @@ -167,7 +167,7 @@ class NiAutoNormalParticlesData : public ShapeData public: int activeCount; - void read(NIFFile *nif) + void read(NIFStream *nif) { ShapeData::read(nif); @@ -189,7 +189,7 @@ public: class NiRotatingParticlesData : public NiAutoNormalParticlesData { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { NiAutoNormalParticlesData::read(nif); @@ -208,7 +208,7 @@ class NiPosData : public Record public: Vector3KeyList mKeyList; - void read(NIFFile *nif) + void read(NIFStream *nif) { mKeyList.read(nif); } @@ -219,7 +219,7 @@ class NiUVData : public Record public: FloatKeyList mKeyList[4]; - void read(NIFFile *nif) + void read(NIFStream *nif) { for(int i = 0;i < 4;i++) mKeyList[i].read(nif); @@ -231,7 +231,7 @@ class NiFloatData : public Record public: FloatKeyList mKeyList; - void read(NIFFile *nif) + void read(NIFStream *nif) { mKeyList.read(nif); } @@ -243,7 +243,7 @@ public: unsigned int rmask, gmask, bmask, amask; int bpp, mips; - void read(NIFFile *nif) + void read(NIFStream *nif) { nif->getInt(); // always 0 or 1 @@ -281,7 +281,7 @@ class NiColorData : public Record public: Vector4KeyList mKeyList; - void read(NIFFile *nif) + void read(NIFStream *nif) { mKeyList.read(nif); } @@ -295,7 +295,7 @@ public: char isSet; }; - void read(NIFFile *nif) + void read(NIFStream *nif) { int count = nif->getInt(); @@ -311,7 +311,7 @@ public: NodePtr root; NodeList bones; - void read(NIFFile *nif) + void read(NIFStream *nif) { data.read(nif); root.read(nif); @@ -347,7 +347,7 @@ public: BoneTrafo trafo; std::vector bones; - void read(NIFFile *nif) + void read(NIFStream *nif) { trafo.rotation = nif->getMatrix3(); trafo.trans = nif->getVector3(); @@ -385,7 +385,7 @@ struct NiMorphData : public Record }; std::vector mMorphs; - void read(NIFFile *nif) + void read(NIFStream *nif) { int morphCount = nif->getInt(); int vertCount = nif->getInt(); @@ -410,7 +410,7 @@ struct NiKeyframeData : public Record Vector3KeyList mTranslations; FloatKeyList mScales; - void read(NIFFile *nif) + void read(NIFStream *nif) { mRotations.read(nif); mTranslations.read(nif); diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 850415dad..b07a39303 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -42,7 +42,7 @@ struct NiLight : Effect Ogre::Vector3 diffuse; Ogre::Vector3 specular; - void read(NIFFile *nif) + void read(NIFStream *nif) { dimmer = nif->getFloat(); ambient = nif->getVector3(); @@ -52,7 +52,7 @@ struct NiLight : Effect }; SLight light; - void read(NIFFile *nif) + void read(NIFStream *nif) { Effect::read(nif); @@ -66,7 +66,7 @@ struct NiTextureEffect : Effect { NiSourceTexturePtr texture; - void read(NIFFile *nif) + void read(NIFStream *nif) { Effect::read(nif); diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 35781dbf5..b5335f987 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -40,14 +40,14 @@ class Extra : public Record public: ExtraPtr extra; - void read(NIFFile *nif) { extra.read(nif); } + void read(NIFStream *nif) { extra.read(nif); } void post(NIFFile *nif) { extra.post(nif); } }; class NiVertWeightsExtraData : public Extra { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); @@ -70,7 +70,7 @@ public: }; std::vector list; - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); @@ -95,7 +95,7 @@ public: */ std::string string; - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 6e806e7ec..f3faf563c 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -174,10 +174,7 @@ NIFFile::ptr NIFFile::create (const std::string &name) { return LoadedCache::cre NIFFile::NIFFile(const std::string &name, psudo_private_modifier) : filename(name) { - inp = Ogre::ResourceGroupManager::getSingleton().openResource(name); parse(); - // Make sure to close the file after it was loaded into memory - inp.setNull(); } NIFFile::~NIFFile() @@ -195,18 +192,20 @@ NIFFile::~NIFFile() void NIFFile::parse() { + NIFStream nif (this, Ogre::ResourceGroupManager::getSingleton().openResource(filename)); + // Check the header string - std::string head = getString(40); + std::string head = nif.getString(40); if(head.compare(0, 22, "NetImmerse File Format") != 0) fail("Invalid NIF header"); // Get BCD version - ver = getInt(); + ver = nif.getInt(); if(ver != VER_MW) fail("Unsupported NIF version"); // Number of records - size_t recNum = getInt(); + size_t recNum = nif.getInt(); records.resize(recNum); /* The format for 10.0.1.0 seems to be a bit different. After the @@ -222,7 +221,7 @@ void NIFFile::parse() { Record *r = NULL; - std::string rec = getString(); + std::string rec = nif.getString(); /* These are all the record types we know how to read. @@ -312,7 +311,7 @@ void NIFFile::parse() r->recName = rec; r->recIndex = i; records[i] = r; - r->read(this); + r->read(&nif); // Discard tranformations for the root node, otherwise some meshes // occasionally get wrong orientation. Only for NiNode-s for now, but diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 5e9694f4b..a406de4a0 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -46,6 +46,7 @@ #include "record.hpp" #include "nif_types.hpp" +#include "nif_stream.hpp" namespace Nif { @@ -59,9 +60,6 @@ class NIFFile /// Nif file version int ver; - /// Input stream - Ogre::DataStreamPtr inp; - /// File name, used for error messages std::string filename; @@ -71,33 +69,6 @@ class NIFFile /// Parse the file void parse(); - uint8_t read_byte() - { - uint8_t byte; - if(inp->read(&byte, 1) != 1) return 0; - return byte; - } - uint16_t read_le16() - { - uint8_t buffer[2]; - if(inp->read(buffer, 2) != 2) return 0; - return buffer[0] | (buffer[1]<<8); - } - uint32_t read_le32() - { - uint8_t buffer[4]; - if(inp->read(buffer, 4) != 4) return 0; - return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); - } - float read_le32f() - { - union { - uint32_t i; - float f; - } u = { read_le32() }; - return u.f; - } - class LoadedCache; friend class LoadedCache; @@ -117,8 +88,8 @@ public: void warn(const std::string &msg) { - std::cerr<< "NIFFile Warning: "< ptr; @@ -147,111 +118,6 @@ public: /// Number of records size_t numRecords() { return records.size(); } - - /************************************************* - Parser functions - ****************************************************/ - - void skip(size_t size) { inp->skip(size); } - - char getChar() { return read_byte(); } - short getShort() { return read_le16(); } - unsigned short getUShort() { return read_le16(); } - int getInt() { return read_le32(); } - unsigned int getUInt() { return read_le32(); } - float getFloat() { return read_le32f(); } - Ogre::Vector2 getVector2() - { - float a[2]; - for(size_t i = 0;i < 2;i++) - a[i] = getFloat(); - return Ogre::Vector2(a); - } - Ogre::Vector3 getVector3() - { - float a[3]; - for(size_t i = 0;i < 3;i++) - a[i] = getFloat(); - return Ogre::Vector3(a); - } - Ogre::Vector4 getVector4() - { - float a[4]; - for(size_t i = 0;i < 4;i++) - a[i] = getFloat(); - return Ogre::Vector4(a); - } - Ogre::Matrix3 getMatrix3() - { - Ogre::Real a[3][3]; - for(size_t i = 0;i < 3;i++) - { - for(size_t j = 0;j < 3;j++) - a[i][j] = Ogre::Real(getFloat()); - } - return Ogre::Matrix3(a); - } - Ogre::Quaternion getQuaternion() - { - float a[4]; - for(size_t i = 0;i < 4;i++) - a[i] = getFloat(); - return Ogre::Quaternion(a); - } - Transformation getTrafo() - { - Transformation t; - t.pos = getVector3(); - t.rotation = getMatrix3(); - t.scale = getFloat(); - return t; - } - - std::string getString(size_t length) - { - std::vector str (length+1, 0); - - if(inp->read(&str[0], length) != length) - throw std::runtime_error ("string length in NIF file does not match"); - - return &str[0]; - } - std::string getString() - { - size_t size = read_le32(); - return getString(size); - } - - void getShorts(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getShort(); - } - void getFloats(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getFloat(); - } - void getVector2s(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector2(); - } - void getVector3s(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector3(); - } - void getVector4s(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector4(); - } }; @@ -270,7 +136,7 @@ typedef KeyT Vector3Key; typedef KeyT Vector4Key; typedef KeyT QuaternionKey; -template +template struct KeyListT { typedef std::vector< KeyT > VecType; @@ -281,7 +147,7 @@ struct KeyListT { int mInterpolationType; VecType mKeys; - void read(NIFFile *nif, bool force=false) + void read(NIFStream *nif, bool force=false) { size_t count = nif->getInt(); if(count == 0 && !force) @@ -322,13 +188,13 @@ struct KeyListT { } } else - nif->warn("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); + nif->file->warn("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); } }; -typedef KeyListT FloatKeyList; -typedef KeyListT Vector3KeyList; -typedef KeyListT Vector4KeyList; -typedef KeyListT QuaternionKeyList; +typedef KeyListT FloatKeyList; +typedef KeyListT Vector3KeyList; +typedef KeyListT Vector4KeyList; +typedef KeyListT QuaternionKeyList; } // Namespace #endif diff --git a/components/nif/nif_stream.hpp b/components/nif/nif_stream.hpp new file mode 100644 index 000000000..8fb98f3d6 --- /dev/null +++ b/components/nif/nif_stream.hpp @@ -0,0 +1,175 @@ +#ifndef _NIF_STREAM_HPP_ +#define _NIF_STREAM_HPP_ + +namespace Nif +{ + +class NIFFile; + +class NIFStream { + + /// Input stream + Ogre::DataStreamPtr inp; + + uint8_t read_byte() + { + uint8_t byte; + if(inp->read(&byte, 1) != 1) return 0; + return byte; + } + uint16_t read_le16() + { + uint8_t buffer[2]; + if(inp->read(buffer, 2) != 2) return 0; + return buffer[0] | (buffer[1]<<8); + } + uint32_t read_le32() + { + uint8_t buffer[4]; + if(inp->read(buffer, 4) != 4) return 0; + return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); + } + float read_le32f() + { + union { + uint32_t i; + float f; + } u = { read_le32() }; + return u.f; + } + +public: + + NIFFile * const file; + + NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {} + + /************************************************* + Parser functions + ****************************************************/ + + template + struct GetHandler + { + typedef T (NIFStream::*fn_t)(); + + static const fn_t sValue; // this is specialized per supported type in the .cpp file + + static T read (NIFStream* nif) + { + return (nif->*sValue) (); + } + }; + + template + void read (NIFStream* nif, T & Value) + { + Value = GetHandler ::read (nif); + } + + void skip(size_t size) { inp->skip(size); } + void read (void * data, size_t size) { inp->read (data, size); } + + char getChar() { return read_byte(); } + short getShort() { return read_le16(); } + unsigned short getUShort() { return read_le16(); } + int getInt() { return read_le32(); } + int getUInt() { return read_le32(); } + float getFloat() { return read_le32f(); } + Ogre::Vector2 getVector2() + { + float a[2]; + for(size_t i = 0;i < 2;i++) + a[i] = getFloat(); + return Ogre::Vector2(a); + } + Ogre::Vector3 getVector3() + { + float a[3]; + for(size_t i = 0;i < 3;i++) + a[i] = getFloat(); + return Ogre::Vector3(a); + } + Ogre::Vector4 getVector4() + { + float a[4]; + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); + return Ogre::Vector4(a); + } + Ogre::Matrix3 getMatrix3() + { + Ogre::Real a[3][3]; + for(size_t i = 0;i < 3;i++) + { + for(size_t j = 0;j < 3;j++) + a[i][j] = Ogre::Real(getFloat()); + } + return Ogre::Matrix3(a); + } + Ogre::Quaternion getQuaternion() + { + float a[4]; + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); + return Ogre::Quaternion(a); + } + Transformation getTrafo() + { + Transformation t; + t.pos = getVector3(); + t.rotation = getMatrix3(); + t.scale = getFloat(); + return t; + } + + std::string getString(size_t length) + { + std::vector str (length+1, 0); + + if(inp->read(&str[0], length) != length) + throw std::runtime_error ("string length in NIF file does not match"); + + return &str[0]; + } + std::string getString() + { + size_t size = read_le32(); + return getString(size); + } + + void getShorts(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getShort(); + } + void getFloats(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getFloat(); + } + void getVector2s(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector2(); + } + void getVector3s(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector3(); + } + void getVector4s(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector4(); + } +}; + +} + +#endif diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 07e7868cc..e08703756 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -54,7 +54,7 @@ public: Ogre::Matrix3 boundRot; Ogre::Vector3 boundXYZ; // Box size - void read(NIFFile *nif) + void read(NIFStream *nif) { Named::read(nif); @@ -128,7 +128,7 @@ struct NiNode : Node 0x20, 0x40, 0x80 unknown */ - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); children.read(nif); @@ -162,7 +162,7 @@ struct NiTriShape : Node NiTriShapeDataPtr data; NiSkinInstancePtr skin; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); data.read(nif); @@ -190,7 +190,7 @@ struct NiCamera : Node // Level of detail modifier float LOD; - void read(NIFFile *nif) + void read(NIFStream *nif) { left = nif->getFloat(); right = nif->getFloat(); @@ -209,7 +209,7 @@ struct NiCamera : Node }; Camera cam; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); @@ -224,7 +224,7 @@ struct NiAutoNormalParticles : Node { NiAutoNormalParticlesDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); data.read(nif); @@ -242,7 +242,7 @@ struct NiRotatingParticles : Node { NiRotatingParticlesDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); data.read(nif); diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 046fb0465..cdf97986c 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -35,7 +35,7 @@ public: // The meaning of these depends on the actual property type. int flags; - void read(NIFFile *nif) + void read(NIFStream *nif) { Named::read(nif); flags = nif->getUShort(); @@ -67,7 +67,7 @@ public: int clamp, set, filter; short unknown2; - void read(NIFFile *nif) + void read(NIFStream *nif) { inUse = !!nif->getInt(); if(!inUse) return; @@ -111,7 +111,7 @@ public: */ Texture textures[7]; - void read(NIFFile *nif) + void read(NIFStream *nif) { Property::read(nif); apply = nif->getInt(); @@ -157,7 +157,7 @@ struct StructPropT : Property { T data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Property::read(nif); data.read(nif); @@ -170,7 +170,7 @@ struct S_MaterialProperty Ogre::Vector3 ambient, diffuse, specular, emissive; float glossiness, alpha; - void read(NIFFile *nif) + void read(NIFStream *nif) { ambient = nif->getVector3(); diffuse = nif->getVector3(); @@ -194,7 +194,7 @@ struct S_VertexColorProperty */ int vertmode, lightmode; - void read(NIFFile *nif) + void read(NIFStream *nif) { vertmode = nif->getInt(); lightmode = nif->getInt(); @@ -251,7 +251,7 @@ struct S_AlphaProperty // Tested against when certain flags are set (see above.) unsigned char threshold; - void read(NIFFile *nif) + void read(NIFStream *nif) { threshold = nif->getChar(); } @@ -300,7 +300,7 @@ struct S_StencilProperty */ int drawMode; - void read(NIFFile *nif) + void read(NIFStream *nif) { enabled = nif->getChar(); compareFunc = nif->getInt(); diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 073f4657c..9f0645dfd 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -30,6 +30,7 @@ namespace Nif { class NIFFile; +class NIFStream; enum RecordType { @@ -97,7 +98,7 @@ struct Record Record() : recType(RC_MISSING), recIndex(~(size_t)0) {} /// Parses the record from file - virtual void read(NIFFile *nif) = 0; + virtual void read(NIFStream *nif) = 0; /// Does post-processing, after the entire tree is loaded virtual void post(NIFFile *nif) {} diff --git a/components/nif/record_ptr.hpp b/components/nif/record_ptr.hpp index ef5bb1dee..855099a04 100644 --- a/components/nif/record_ptr.hpp +++ b/components/nif/record_ptr.hpp @@ -46,7 +46,7 @@ public: RecordPtrT() : index(-2) {} /// Read the index from the nif - void read(NIFFile *nif) + void read(NIFStream *nif) { // Can only read the index once assert(index == -2); @@ -99,7 +99,7 @@ class RecordListT std::vector list; public: - void read(NIFFile *nif) + void read(NIFStream *nif) { int len = nif->getInt(); list.resize(len);