OpenMW
|
00001 #ifndef OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP 00002 #define OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP 00003 00004 namespace Nif 00005 { 00006 00007 class NIFFile; 00008 00009 class NIFStream { 00010 00012 Ogre::DataStreamPtr inp; 00013 00014 uint8_t read_byte() 00015 { 00016 uint8_t byte; 00017 if(inp->read(&byte, 1) != 1) return 0; 00018 return byte; 00019 } 00020 uint16_t read_le16() 00021 { 00022 uint8_t buffer[2]; 00023 if(inp->read(buffer, 2) != 2) return 0; 00024 return buffer[0] | (buffer[1]<<8); 00025 } 00026 uint32_t read_le32() 00027 { 00028 uint8_t buffer[4]; 00029 if(inp->read(buffer, 4) != 4) return 0; 00030 return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); 00031 } 00032 float read_le32f() 00033 { 00034 union { 00035 uint32_t i; 00036 float f; 00037 } u = { read_le32() }; 00038 return u.f; 00039 } 00040 00041 public: 00042 00043 NIFFile * const file; 00044 00045 NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {} 00046 00047 /************************************************* 00048 Parser functions 00049 ****************************************************/ 00050 00051 template <typename T> 00052 struct GetHandler 00053 { 00054 typedef T (NIFStream::*fn_t)(); 00055 00056 static const fn_t sValue; // this is specialized per supported type in the .cpp file 00057 00058 static T read (NIFStream* nif) 00059 { 00060 return (nif->*sValue) (); 00061 } 00062 }; 00063 00064 template <typename T> 00065 void read (NIFStream* nif, T & Value) 00066 { 00067 Value = GetHandler <T>::read (nif); 00068 } 00069 00070 void skip(size_t size) { inp->skip(size); } 00071 void read (void * data, size_t size) { inp->read (data, size); } 00072 00073 char getChar() { return read_byte(); } 00074 short getShort() { return read_le16(); } 00075 unsigned short getUShort() { return read_le16(); } 00076 int getInt() { return read_le32(); } 00077 int getUInt() { return read_le32(); } 00078 float getFloat() { return read_le32f(); } 00079 Ogre::Vector2 getVector2() 00080 { 00081 float a[2]; 00082 for(size_t i = 0;i < 2;i++) 00083 a[i] = getFloat(); 00084 return Ogre::Vector2(a); 00085 } 00086 Ogre::Vector3 getVector3() 00087 { 00088 float a[3]; 00089 for(size_t i = 0;i < 3;i++) 00090 a[i] = getFloat(); 00091 return Ogre::Vector3(a); 00092 } 00093 Ogre::Vector4 getVector4() 00094 { 00095 float a[4]; 00096 for(size_t i = 0;i < 4;i++) 00097 a[i] = getFloat(); 00098 return Ogre::Vector4(a); 00099 } 00100 Ogre::Matrix3 getMatrix3() 00101 { 00102 Ogre::Real a[3][3]; 00103 for(size_t i = 0;i < 3;i++) 00104 { 00105 for(size_t j = 0;j < 3;j++) 00106 a[i][j] = Ogre::Real(getFloat()); 00107 } 00108 return Ogre::Matrix3(a); 00109 } 00110 Ogre::Quaternion getQuaternion() 00111 { 00112 float a[4]; 00113 for(size_t i = 0;i < 4;i++) 00114 a[i] = getFloat(); 00115 return Ogre::Quaternion(a); 00116 } 00117 Transformation getTrafo() 00118 { 00119 Transformation t; 00120 t.pos = getVector3(); 00121 t.rotation = getMatrix3(); 00122 t.scale = getFloat(); 00123 return t; 00124 } 00125 00126 std::string getString(size_t length) 00127 { 00128 std::vector<char> str (length+1, 0); 00129 00130 if(inp->read(&str[0], length) != length) 00131 throw std::runtime_error ("string length in NIF file does not match"); 00132 00133 return &str[0]; 00134 } 00135 std::string getString() 00136 { 00137 size_t size = read_le32(); 00138 return getString(size); 00139 } 00140 00141 void getShorts(std::vector<short> &vec, size_t size) 00142 { 00143 vec.resize(size); 00144 for(size_t i = 0;i < vec.size();i++) 00145 vec[i] = getShort(); 00146 } 00147 void getFloats(std::vector<float> &vec, size_t size) 00148 { 00149 vec.resize(size); 00150 for(size_t i = 0;i < vec.size();i++) 00151 vec[i] = getFloat(); 00152 } 00153 void getVector2s(std::vector<Ogre::Vector2> &vec, size_t size) 00154 { 00155 vec.resize(size); 00156 for(size_t i = 0;i < vec.size();i++) 00157 vec[i] = getVector2(); 00158 } 00159 void getVector3s(std::vector<Ogre::Vector3> &vec, size_t size) 00160 { 00161 vec.resize(size); 00162 for(size_t i = 0;i < vec.size();i++) 00163 vec[i] = getVector3(); 00164 } 00165 void getVector4s(std::vector<Ogre::Vector4> &vec, size_t size) 00166 { 00167 vec.resize(size); 00168 for(size_t i = 0;i < vec.size();i++) 00169 vec[i] = getVector4(); 00170 } 00171 void getQuaternions(std::vector<Ogre::Quaternion> &quat, size_t size) 00172 { 00173 quat.resize(size); 00174 for(size_t i = 0;i < quat.size();i++) 00175 quat[i] = getQuaternion(); 00176 } 00177 }; 00178 00179 } 00180 00181 #endif