OpenMW
|
00001 /* 00002 OpenMW - The completely unofficial reimplementation of Morrowind 00003 Copyright (C) 2008-2010 Nicolay Korslund 00004 Email: < korslund@gmail.com > 00005 WWW: http://openmw.sourceforge.net/ 00006 00007 This file (data.h) is part of the OpenMW package. 00008 00009 OpenMW is distributed as free software: you can redistribute it 00010 and/or modify it under the terms of the GNU General Public License 00011 version 3, as published by the Free Software Foundation. 00012 00013 This program is distributed in the hope that it will be useful, but 00014 WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 version 3 along with this program. If not, see 00020 http://www.gnu.org/licenses/ . 00021 00022 */ 00023 00024 #ifndef OPENMW_COMPONENTS_NIF_DATA_HPP 00025 #define OPENMW_COMPONENTS_NIF_DATA_HPP 00026 00027 #include "controlled.hpp" 00028 00029 #include <OgreQuaternion.h> 00030 #include <OgreVector3.h> 00031 00032 namespace Nif 00033 { 00034 00035 class NiSourceTexture : public Named 00036 { 00037 public: 00038 // Is this an external (references a separate texture file) or 00039 // internal (data is inside the nif itself) texture? 00040 bool external; 00041 00042 std::string filename; // In case of external textures 00043 NiPixelDataPtr data; // In case of internal textures 00044 00045 /* Pixel layout 00046 0 - Palettised 00047 1 - High color 16 00048 2 - True color 32 00049 3 - Compressed 00050 4 - Bumpmap 00051 5 - Default */ 00052 int pixel; 00053 00054 /* Mipmap format 00055 0 - no 00056 1 - yes 00057 2 - default */ 00058 int mipmap; 00059 00060 /* Alpha 00061 0 - none 00062 1 - binary 00063 2 - smooth 00064 3 - default (use material alpha, or multiply material with texture if present) 00065 */ 00066 int alpha; 00067 00068 void read(NIFStream *nif) 00069 { 00070 Named::read(nif); 00071 00072 external = !!nif->getChar(); 00073 if(external) 00074 filename = nif->getString(); 00075 else 00076 { 00077 nif->getChar(); // always 1 00078 data.read(nif); 00079 } 00080 00081 pixel = nif->getInt(); 00082 mipmap = nif->getInt(); 00083 alpha = nif->getInt(); 00084 00085 nif->getChar(); // always 1 00086 } 00087 00088 void post(NIFFile *nif) 00089 { 00090 Named::post(nif); 00091 data.post(nif); 00092 } 00093 }; 00094 00095 // Common ancestor for several data classes 00096 class ShapeData : public Record 00097 { 00098 public: 00099 std::vector<Ogre::Vector3> vertices, normals; 00100 std::vector<Ogre::Vector4> colors; 00101 std::vector< std::vector<Ogre::Vector2> > uvlist; 00102 Ogre::Vector3 center; 00103 float radius; 00104 00105 void read(NIFStream *nif) 00106 { 00107 int verts = nif->getUShort(); 00108 00109 if(nif->getInt()) 00110 nif->getVector3s(vertices, verts); 00111 00112 if(nif->getInt()) 00113 nif->getVector3s(normals, verts); 00114 00115 center = nif->getVector3(); 00116 radius = nif->getFloat(); 00117 00118 if(nif->getInt()) 00119 nif->getVector4s(colors, verts); 00120 00121 // Only the first 6 bits are used as a count. I think the rest are 00122 // flags of some sort. 00123 int uvs = nif->getUShort(); 00124 uvs &= 0x3f; 00125 00126 if(nif->getInt()) 00127 { 00128 uvlist.resize(uvs); 00129 for(int i = 0;i < uvs;i++) 00130 nif->getVector2s(uvlist[i], verts); 00131 } 00132 } 00133 }; 00134 00135 class NiTriShapeData : public ShapeData 00136 { 00137 public: 00138 // Triangles, three vertex indices per triangle 00139 std::vector<short> triangles; 00140 00141 void read(NIFStream *nif) 00142 { 00143 ShapeData::read(nif); 00144 00145 /*int tris =*/ nif->getUShort(); 00146 00147 // We have three times as many vertices as triangles, so this 00148 // is always equal to tris*3. 00149 int cnt = nif->getInt(); 00150 nif->getShorts(triangles, cnt); 00151 00152 // Read the match list, which lists the vertices that are equal to 00153 // vertices. We don't actually need need this for anything, so 00154 // just skip it. 00155 int verts = nif->getUShort(); 00156 for(int i=0;i < verts;i++) 00157 { 00158 // Number of vertices matching vertex 'i' 00159 int num = nif->getUShort(); 00160 nif->skip(num * sizeof(short)); 00161 } 00162 } 00163 }; 00164 00165 class NiAutoNormalParticlesData : public ShapeData 00166 { 00167 public: 00168 int numParticles; 00169 00170 float particleRadius; 00171 00172 int activeCount; 00173 00174 std::vector<float> sizes; 00175 00176 void read(NIFStream *nif) 00177 { 00178 ShapeData::read(nif); 00179 00180 // Should always match the number of vertices 00181 numParticles = nif->getUShort(); 00182 00183 particleRadius = nif->getFloat(); 00184 activeCount = nif->getUShort(); 00185 00186 if(nif->getInt()) 00187 { 00188 // Particle sizes 00189 nif->getFloats(sizes, vertices.size()); 00190 } 00191 } 00192 }; 00193 00194 class NiRotatingParticlesData : public NiAutoNormalParticlesData 00195 { 00196 public: 00197 std::vector<Ogre::Quaternion> rotations; 00198 00199 void read(NIFStream *nif) 00200 { 00201 NiAutoNormalParticlesData::read(nif); 00202 00203 if(nif->getInt()) 00204 { 00205 // Rotation quaternions. 00206 nif->getQuaternions(rotations, vertices.size()); 00207 } 00208 } 00209 }; 00210 00211 class NiPosData : public Record 00212 { 00213 public: 00214 Vector3KeyList mKeyList; 00215 00216 void read(NIFStream *nif) 00217 { 00218 mKeyList.read(nif); 00219 } 00220 }; 00221 00222 class NiUVData : public Record 00223 { 00224 public: 00225 FloatKeyList mKeyList[4]; 00226 00227 void read(NIFStream *nif) 00228 { 00229 for(int i = 0;i < 4;i++) 00230 mKeyList[i].read(nif); 00231 } 00232 }; 00233 00234 class NiFloatData : public Record 00235 { 00236 public: 00237 FloatKeyList mKeyList; 00238 00239 void read(NIFStream *nif) 00240 { 00241 mKeyList.read(nif); 00242 } 00243 }; 00244 00245 class NiPixelData : public Record 00246 { 00247 public: 00248 unsigned int rmask, gmask, bmask, amask; 00249 int bpp, mips; 00250 00251 void read(NIFStream *nif) 00252 { 00253 nif->getInt(); // always 0 or 1 00254 00255 rmask = nif->getInt(); // usually 0xff 00256 gmask = nif->getInt(); // usually 0xff00 00257 bmask = nif->getInt(); // usually 0xff0000 00258 amask = nif->getInt(); // usually 0xff000000 or zero 00259 00260 bpp = nif->getInt(); 00261 00262 // Unknown 00263 nif->skip(12); 00264 00265 mips = nif->getInt(); 00266 00267 // Bytes per pixel, should be bpp * 8 00268 /*int bytes =*/ nif->getInt(); 00269 00270 for(int i=0; i<mips; i++) 00271 { 00272 // Image size and offset in the following data field 00273 /*int x =*/ nif->getInt(); 00274 /*int y =*/ nif->getInt(); 00275 /*int offset =*/ nif->getInt(); 00276 } 00277 00278 // Skip the data 00279 unsigned int dataSize = nif->getInt(); 00280 nif->skip(dataSize); 00281 } 00282 }; 00283 00284 class NiColorData : public Record 00285 { 00286 public: 00287 Vector4KeyList mKeyList; 00288 00289 void read(NIFStream *nif) 00290 { 00291 mKeyList.read(nif); 00292 } 00293 }; 00294 00295 class NiVisData : public Record 00296 { 00297 public: 00298 struct VisData { 00299 float time; 00300 char isSet; 00301 }; 00302 std::vector<VisData> mVis; 00303 00304 void read(NIFStream *nif) 00305 { 00306 int count = nif->getInt(); 00307 mVis.resize(count); 00308 for(size_t i = 0;i < mVis.size();i++) 00309 { 00310 mVis[i].time = nif->getFloat(); 00311 mVis[i].isSet = nif->getChar(); 00312 } 00313 } 00314 }; 00315 00316 class NiSkinInstance : public Record 00317 { 00318 public: 00319 NiSkinDataPtr data; 00320 NodePtr root; 00321 NodeList bones; 00322 00323 void read(NIFStream *nif) 00324 { 00325 data.read(nif); 00326 root.read(nif); 00327 bones.read(nif); 00328 } 00329 00330 void post(NIFFile *nif); 00331 }; 00332 00333 class NiSkinData : public Record 00334 { 00335 public: 00336 struct BoneTrafo 00337 { 00338 Ogre::Matrix3 rotation; // Rotation offset from bone? 00339 Ogre::Vector3 trans; // Translation 00340 float scale; // Probably scale (always 1) 00341 }; 00342 00343 struct VertWeight 00344 { 00345 short vertex; 00346 float weight; 00347 }; 00348 00349 struct BoneInfo 00350 { 00351 BoneTrafo trafo; 00352 Ogre::Vector4 unknown; 00353 std::vector<VertWeight> weights; 00354 }; 00355 00356 BoneTrafo trafo; 00357 std::vector<BoneInfo> bones; 00358 00359 void read(NIFStream *nif) 00360 { 00361 trafo.rotation = nif->getMatrix3(); 00362 trafo.trans = nif->getVector3(); 00363 trafo.scale = nif->getFloat(); 00364 00365 int boneNum = nif->getInt(); 00366 nif->getInt(); // -1 00367 00368 bones.resize(boneNum); 00369 for(int i=0;i<boneNum;i++) 00370 { 00371 BoneInfo &bi = bones[i]; 00372 00373 bi.trafo.rotation = nif->getMatrix3(); 00374 bi.trafo.trans = nif->getVector3(); 00375 bi.trafo.scale = nif->getFloat(); 00376 bi.unknown = nif->getVector4(); 00377 00378 // Number of vertex weights 00379 bi.weights.resize(nif->getUShort()); 00380 for(size_t j = 0;j < bi.weights.size();j++) 00381 { 00382 bi.weights[j].vertex = nif->getUShort(); 00383 bi.weights[j].weight = nif->getFloat(); 00384 } 00385 } 00386 } 00387 }; 00388 00389 struct NiMorphData : public Record 00390 { 00391 struct MorphData { 00392 FloatKeyList mData; 00393 std::vector<Ogre::Vector3> mVertices; 00394 }; 00395 std::vector<MorphData> mMorphs; 00396 00397 void read(NIFStream *nif) 00398 { 00399 int morphCount = nif->getInt(); 00400 int vertCount = nif->getInt(); 00401 /*relative targets?*/nif->getChar(); 00402 00403 mMorphs.resize(morphCount); 00404 for(int i = 0;i < morphCount;i++) 00405 { 00406 mMorphs[i].mData.read(nif, true); 00407 nif->getVector3s(mMorphs[i].mVertices, vertCount); 00408 } 00409 } 00410 }; 00411 00412 00413 struct NiKeyframeData : public Record 00414 { 00415 QuaternionKeyList mRotations; 00416 Vector3KeyList mTranslations; 00417 FloatKeyList mScales; 00418 00419 void read(NIFStream *nif) 00420 { 00421 mRotations.read(nif); 00422 mTranslations.read(nif); 00423 mScales.read(nif); 00424 } 00425 }; 00426 00427 } // Namespace 00428 #endif