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 (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