OpenMW
components/nif/data.hpp
Go to the documentation of this file.
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