OpenMW
components/nif/node.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 (node.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_NODE_HPP
00025 #define OPENMW_COMPONENTS_NIF_NODE_HPP
00026 
00027 #include <OgreMatrix4.h>
00028 
00029 #include "controlled.hpp"
00030 #include "data.hpp"
00031 #include "property.hpp"
00032 
00033 namespace Nif
00034 {
00035 
00036 class NiNode;
00037 
00042 class Node : public Named
00043 {
00044 public:
00045     // Node flags. Interpretation depends somewhat on the type of node.
00046     int flags;
00047     Transformation trafo;
00048     Ogre::Vector3 velocity; // Unused? Might be a run-time game state
00049     PropertyList props;
00050 
00051     // Bounding box info
00052     bool hasBounds;
00053     Ogre::Vector3 boundPos;
00054     Ogre::Matrix3 boundRot;
00055     Ogre::Vector3 boundXYZ; // Box size
00056 
00057     void read(NIFStream *nif)
00058     {
00059         Named::read(nif);
00060 
00061         flags = nif->getUShort();
00062         trafo = nif->getTrafo();
00063         velocity = nif->getVector3();
00064         props.read(nif);
00065 
00066         hasBounds = !!nif->getInt();
00067         if(hasBounds)
00068         {
00069             nif->getInt(); // always 1
00070             boundPos = nif->getVector3();
00071             boundRot = nif->getMatrix3();
00072             boundXYZ = nif->getVector3();
00073         }
00074 
00075         parent = NULL;
00076 
00077         boneTrafo = NULL;
00078         boneIndex = -1;
00079     }
00080 
00081     void post(NIFFile *nif)
00082     {
00083         Named::post(nif);
00084         props.post(nif);
00085     }
00086 
00087     // Parent node, or NULL for the root node. As far as I'm aware, only
00088     // NiNodes (or types derived from NiNodes) can be parents.
00089     NiNode *parent;
00090 
00091     // Bone transformation. If set, node is a part of a skeleton.
00092     const NiSkinData::BoneTrafo *boneTrafo;
00093 
00094     // Bone weight info, from NiSkinData
00095     const NiSkinData::BoneInfo *boneInfo;
00096 
00097     // Bone index. If -1, this node is either not a bone, or if
00098     // boneTrafo is set it is the root bone in the skeleton.
00099     short boneIndex;
00100 
00101     void makeRootBone(const NiSkinData::BoneTrafo *tr)
00102     {
00103         boneTrafo = tr;
00104         boneIndex = -1;
00105     }
00106 
00107     void makeBone(short ind, const NiSkinData::BoneInfo &bi)
00108     {
00109         boneInfo = &bi;
00110         boneTrafo = &bi.trafo;
00111         boneIndex = ind;
00112     }
00113 
00114     void getProperties(const Nif::NiTexturingProperty *&texprop,
00115                        const Nif::NiMaterialProperty *&matprop,
00116                        const Nif::NiAlphaProperty *&alphaprop,
00117                        const Nif::NiVertexColorProperty *&vertprop,
00118                        const Nif::NiZBufferProperty *&zprop,
00119                        const Nif::NiSpecularProperty *&specprop,
00120                        const Nif::NiWireframeProperty *&wireprop) const;
00121 
00122     Ogre::Matrix4 getLocalTransform() const;
00123     Ogre::Matrix4 getWorldTransform() const;
00124 };
00125 
00126 struct NiNode : Node
00127 {
00128     NodeList children;
00129     NodeList effects;
00130 
00131     enum Flags {
00132         Flag_Hidden = 0x0001,
00133         Flag_MeshCollision = 0x0002,
00134         Flag_BBoxCollision = 0x0004
00135     };
00136     enum BSAnimFlags {
00137         AnimFlag_AutoPlay = 0x0020
00138     };
00139     enum BSParticleFlags {
00140         ParticleFlag_AutoPlay = 0x0020,
00141         ParticleFlag_LocalSpace = 0x0080
00142     };
00143 
00144     void read(NIFStream *nif)
00145     {
00146         Node::read(nif);
00147         children.read(nif);
00148         effects.read(nif);
00149     }
00150 
00151     void post(NIFFile *nif)
00152     {
00153         Node::post(nif);
00154         children.post(nif);
00155         effects.post(nif);
00156 
00157         for(size_t i = 0;i < children.length();i++)
00158         {
00159             // Why would a unique list of children contain empty refs?
00160             if(!children[i].empty())
00161                 children[i]->parent = this;
00162         }
00163     }
00164 };
00165 
00166 struct NiTriShape : Node
00167 {
00168     /* Possible flags:
00169         0x40 - mesh has no vertex normals ?
00170 
00171         Only flags included in 0x47 (ie. 0x01, 0x02, 0x04 and 0x40) have
00172         been observed so far.
00173     */
00174 
00175     NiTriShapeDataPtr data;
00176     NiSkinInstancePtr skin;
00177 
00178     void read(NIFStream *nif)
00179     {
00180         Node::read(nif);
00181         data.read(nif);
00182         skin.read(nif);
00183     }
00184 
00185     void post(NIFFile *nif)
00186     {
00187         Node::post(nif);
00188         data.post(nif);
00189         skin.post(nif);
00190     }
00191 };
00192 
00193 struct NiCamera : Node
00194 {
00195     struct Camera
00196     {
00197         // Camera frustrum
00198         float left, right, top, bottom, nearDist, farDist;
00199 
00200         // Viewport
00201         float vleft, vright, vtop, vbottom;
00202 
00203         // Level of detail modifier
00204         float LOD;
00205 
00206         void read(NIFStream *nif)
00207         {
00208             left = nif->getFloat();
00209             right = nif->getFloat();
00210             top = nif->getFloat();
00211             bottom = nif->getFloat();
00212             nearDist = nif->getFloat();
00213             farDist = nif->getFloat();
00214 
00215             vleft = nif->getFloat();
00216             vright = nif->getFloat();
00217             vtop = nif->getFloat();
00218             vbottom = nif->getFloat();
00219 
00220             LOD = nif->getFloat();
00221         }
00222     };
00223     Camera cam;
00224 
00225     void read(NIFStream *nif)
00226     {
00227         Node::read(nif);
00228 
00229         cam.read(nif);
00230 
00231         nif->getInt(); // -1
00232         nif->getInt(); // 0
00233     }
00234 };
00235 
00236 struct NiAutoNormalParticles : Node
00237 {
00238     NiAutoNormalParticlesDataPtr data;
00239 
00240     void read(NIFStream *nif)
00241     {
00242         Node::read(nif);
00243         data.read(nif);
00244         nif->getInt(); // -1
00245     }
00246 
00247     void post(NIFFile *nif)
00248     {
00249         Node::post(nif);
00250         data.post(nif);
00251     }
00252 };
00253 
00254 struct NiRotatingParticles : Node
00255 {
00256     NiRotatingParticlesDataPtr data;
00257 
00258     void read(NIFStream *nif)
00259     {
00260         Node::read(nif);
00261         data.read(nif);
00262         nif->getInt(); // -1
00263     }
00264 
00265     void post(NIFFile *nif)
00266     {
00267         Node::post(nif);
00268         data.post(nif);
00269     }
00270 };
00271 
00272 } // Namespace
00273 #endif