mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 22:26:41 +00:00 
			
		
		
		
	Clan up compilation warnings like "variable ... set but not used" introduced in some older and recent commits. Signed-off-by: Lukasz Gromanowski <lgromanowski@gmail.com>
		
			
				
	
	
		
			828 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			828 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|   OpenMW - The completely unofficial reimplementation of Morrowind
 | |
|   Copyright (C) 2008-2010  Nicolay Korslund
 | |
|   Email: < korslund@gmail.com >
 | |
|   WWW: http://openmw.sourceforge.net/
 | |
| 
 | |
|   This file (data.h) is part of the OpenMW package.
 | |
| 
 | |
|   OpenMW is distributed as free software: you can redistribute it
 | |
|   and/or modify it under the terms of the GNU General Public License
 | |
|   version 3, as published by the Free Software Foundation.
 | |
| 
 | |
|   This program is distributed in the hope that it will be useful, but
 | |
|   WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|   General Public License for more details.
 | |
| 
 | |
|   You should have received a copy of the GNU General Public License
 | |
|   version 3 along with this program. If not, see
 | |
|   http://www.gnu.org/licenses/ .
 | |
| 
 | |
|  */
 | |
| 
 | |
| #ifndef _NIF_DATA_H_
 | |
| #define _NIF_DATA_H_
 | |
| 
 | |
| #include "controlled.hpp"
 | |
| #include <iostream>
 | |
| #include <Ogre.h>
 | |
| 
 | |
| namespace Nif
 | |
| {
 | |
| 
 | |
| class NiSourceTexture : public Named
 | |
| {
 | |
| public:
 | |
| 
 | |
|   // Is this an external (references a separate texture file) or
 | |
|   // internal (data is inside the nif itself) texture?
 | |
|   bool external;
 | |
| 
 | |
|   Misc::SString filename;    // In case of external textures
 | |
|   NiPixelDataPtr data; // In case of internal textures
 | |
| 
 | |
|   /* Pixel layout
 | |
|      0 - Palettised
 | |
|      1 - High color 16
 | |
|      2 - True color 32
 | |
|      3 - Compressed
 | |
|      4 - Bumpmap
 | |
|      5 - Default */
 | |
|   int pixel;
 | |
| 
 | |
|   /* Mipmap format
 | |
|      0 - no
 | |
|      1 - yes
 | |
|      2 - default */
 | |
|   int mipmap;
 | |
| 
 | |
|   /* Alpha
 | |
|      0 - none
 | |
|      1 - binary
 | |
|      2 - smooth
 | |
|      3 - default (use material alpha, or multiply material with texture if present)
 | |
|   */
 | |
|   int alpha;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     Named::read(nif);
 | |
| 
 | |
|     external = !!nif->getByte();
 | |
| 
 | |
|     if(external) filename = nif->getString();
 | |
|     else
 | |
|       {
 | |
|         nif->getByte(); // always 1
 | |
|         data.read(nif);
 | |
|       }
 | |
| 
 | |
|     pixel = nif->getInt();
 | |
|     mipmap = nif->getInt();
 | |
|     alpha = nif->getInt();
 | |
| 
 | |
|     nif->getByte(); // always 1
 | |
|   }
 | |
| };
 | |
| 
 | |
| // Common ancestor for several data classes
 | |
| class ShapeData : public Record
 | |
| {
 | |
| public:
 | |
|   Misc::FloatArray vertices, normals, colors, uvlist;
 | |
|   const Vector *center;
 | |
|   float radius;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     int verts = nif->getShort();
 | |
| 
 | |
|     if(nif->getInt())
 | |
|       vertices = nif->getFloatLen(verts*3);
 | |
| 
 | |
|     if(nif->getInt())
 | |
|       normals = nif->getFloatLen(verts*3);
 | |
| 
 | |
|     center = nif->getVector();
 | |
|     radius = nif->getFloat();
 | |
| 
 | |
|     if(nif->getInt())
 | |
|       colors = nif->getFloatLen(verts*4);
 | |
| 
 | |
|     int uvs = nif->getShort();
 | |
| 
 | |
|     // Only the first 6 bits are used as a count. I think the rest are
 | |
|     // flags of some sort.
 | |
|     uvs &= 0x3f;
 | |
| 
 | |
|     if(nif->getInt())
 | |
|       uvlist = nif->getFloatLen(uvs*verts*2);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiTriShapeData : public ShapeData
 | |
| {
 | |
| public:
 | |
|   // Triangles, three vertex indices per triangle
 | |
|   Misc::SliceArray<short> triangles;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     ShapeData::read(nif);
 | |
| 
 | |
|     int tris = nif->getShort();
 | |
|     if(tris)
 | |
|       {
 | |
|         // We have three times as many vertices as triangles, so this
 | |
|         // is always equal to tris*3.
 | |
|         int cnt = nif->getInt();
 | |
|         triangles = nif->getArrayLen<short>(cnt);
 | |
|       }
 | |
| 
 | |
|     // Read the match list, which lists the vertices that are equal to
 | |
|     // vertices. We don't actually need need this for anything, so
 | |
|     // just skip it.
 | |
|     int verts = nif->getShort();
 | |
|     if(verts)
 | |
|       {
 | |
|         for(int i=0;i<verts;i++)
 | |
|           {
 | |
|             // Number of vertices matching vertex 'i'
 | |
|             short num = nif->getShort();
 | |
|             nif->skip(num*sizeof(short));
 | |
|           }
 | |
|       }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiAutoNormalParticlesData : public ShapeData
 | |
| {
 | |
| public:
 | |
|   int activeCount;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     ShapeData::read(nif);
 | |
| 
 | |
|     // Should always match the number of vertices
 | |
|     activeCount = nif->getShort();
 | |
| 
 | |
|     // Skip all the info, we don't support particles yet
 | |
|     nif->getFloat();  // Active radius ?
 | |
|     nif->getShort(); // Number of valid entries in the following arrays ?
 | |
| 
 | |
|     if(nif->getInt())
 | |
|       // Particle sizes
 | |
|       nif->getFloatLen(activeCount);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiRotatingParticlesData : public NiAutoNormalParticlesData
 | |
| {
 | |
| public:
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     NiAutoNormalParticlesData::read(nif);
 | |
| 
 | |
|     if(nif->getInt())
 | |
|       // Rotation quaternions. I THINK activeCount is correct here,
 | |
|       // but verts (vertex number) might also be correct, if there is
 | |
|       // any case where the two don't match.
 | |
|       nif->getArrayLen<Vector4>(activeCount);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiPosData : public Record
 | |
| {
 | |
| public:
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     int count = nif->getInt();
 | |
|     int type = nif->getInt();
 | |
|     if(type != 1 && type != 2)
 | |
|       nif->fail("Cannot handle NiPosData type");
 | |
| 
 | |
|     // TODO: Could make structs of these. Seems to be identical to
 | |
|     // translation in NiKeyframeData.
 | |
|     for(int i=0; i<count; i++)
 | |
|       {
 | |
|         /*float time =*/ nif->getFloat();
 | |
|         nif->getVector(); // This isn't really shared between type 1
 | |
|                           // and type 2, most likely
 | |
|         if(type == 2)
 | |
|           {
 | |
|             nif->getVector();
 | |
|             nif->getVector();
 | |
|           }
 | |
|       }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiUVData : public Record
 | |
| {
 | |
| public:
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     // TODO: This is claimed to be a "float animation key", which is
 | |
|     // also used in FloatData and KeyframeData. We could probably
 | |
|     // reuse and refactor a lot of this if we actually use it at some
 | |
|     // point.
 | |
| 
 | |
|     for(int i=0; i<2; i++)
 | |
|       {
 | |
|         int count = nif->getInt();
 | |
| 
 | |
|         if(count)
 | |
|           {
 | |
|             nif->getInt(); // always 2
 | |
|             nif->getArrayLen<Vector4>(count); // Really one time float + one vector
 | |
|           }
 | |
|       }
 | |
|     // Always 0
 | |
|     nif->getInt();
 | |
|     nif->getInt();
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiFloatData : public Record
 | |
| {
 | |
| public:
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     int count = nif->getInt();
 | |
|     nif->getInt(); // always 2
 | |
|     nif->getArrayLen<Vector4>(count); // Really one time float + one vector
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiPixelData : public Record
 | |
| {
 | |
| public:
 | |
|   unsigned int rmask, gmask, bmask, amask;
 | |
|   int bpp, mips;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     nif->getInt(); // always 0 or 1
 | |
| 
 | |
|     rmask = nif->getInt(); // usually 0xff
 | |
|     gmask = nif->getInt(); // usually 0xff00
 | |
|     bmask = nif->getInt(); // usually 0xff0000
 | |
|     amask = nif->getInt(); // usually 0xff000000 or zero
 | |
| 
 | |
|     bpp = nif->getInt();
 | |
| 
 | |
|     // Unknown
 | |
|     nif->skip(12);
 | |
| 
 | |
|     mips = nif->getInt();
 | |
| 
 | |
|     // Bytes per pixel, should be bpp * 8
 | |
|     /*int bytes =*/ nif->getInt();
 | |
| 
 | |
|     for(int i=0; i<mips; i++)
 | |
|       {
 | |
|         // Image size and offset in the following data field
 | |
|         /*int x =*/ nif->getInt();
 | |
|         /*int y =*/ nif->getInt();
 | |
|         /*int offset =*/ nif->getInt();
 | |
|       }
 | |
| 
 | |
|     // Skip the data
 | |
|     unsigned int dataSize = nif->getInt();
 | |
|     nif->skip(dataSize);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiColorData : public Record
 | |
| {
 | |
| public:
 | |
|   struct ColorData
 | |
|   {
 | |
|     float time;
 | |
|     Vector4 rgba;
 | |
|   };
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     int count = nif->getInt();
 | |
|     nif->getInt(); // always 1
 | |
| 
 | |
|     // Skip the data
 | |
|     assert(sizeof(ColorData) == 4*5);
 | |
|     nif->skip(sizeof(ColorData) * count);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiVisData : public Record
 | |
| {
 | |
| public:
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     int count = nif->getInt();
 | |
|     /*
 | |
|       Each VisData consists of:
 | |
|         float time;
 | |
|         byte isSet;
 | |
| 
 | |
|       If you implement this, make sure you use a packed struct
 | |
|       (sizeof==5), or read each element individually.
 | |
|      */
 | |
|     nif->skip(count*5);
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiSkinInstance : public Record
 | |
| {
 | |
| public:
 | |
|   NiSkinDataPtr data;
 | |
|   NodePtr root;
 | |
|   NodeList bones;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     data.read(nif);
 | |
|     root.read(nif);
 | |
|     bones.read(nif);
 | |
| 
 | |
|     if(data.empty() || root.empty())
 | |
|       nif->fail("NiSkinInstance missing root or data");
 | |
|   }
 | |
| 
 | |
|   void post(NIFFile *nif);
 | |
| };
 | |
| 
 | |
| class NiSkinData : public Record
 | |
| {
 | |
| public:
 | |
|   // This is to make sure the structs are packed, ie. that the
 | |
|   // compiler doesn't mess them up with extra alignment bytes.
 | |
| #pragma pack(push)
 | |
| #pragma pack(1)
 | |
| 
 | |
|   struct BoneTrafo
 | |
|   {
 | |
|     Matrix rotation; // Rotation offset from bone?
 | |
|     Vector trans;    // Translation
 | |
|     float scale;     // Probably scale (always 1)
 | |
|   };
 | |
|   struct BoneTrafoCopy
 | |
|   {
 | |
| 	  Ogre::Quaternion rotation;
 | |
| 	  Ogre::Vector3 trans;
 | |
| 	  float scale;
 | |
|   };
 | |
| 
 | |
|   struct VertWeight
 | |
|   {
 | |
|     short vertex;
 | |
|     float weight;
 | |
|   };
 | |
| #pragma pack(pop)
 | |
| 
 | |
|   struct BoneInfo
 | |
|   {
 | |
|     const BoneTrafo *trafo;
 | |
|     const Vector4 *unknown;
 | |
|     Misc::SliceArray<VertWeight> weights;
 | |
|   };
 | |
|   struct BoneInfoCopy
 | |
|   {
 | |
| 	   std::string bonename;
 | |
|        unsigned short bonehandle;
 | |
| 	   BoneTrafoCopy trafo;
 | |
| 	   Vector4 unknown;
 | |
|        //std::vector<VertWeight> weights;
 | |
|   };
 | |
|   struct IndividualWeight
 | |
|   {
 | |
|       float weight;
 | |
|         unsigned int boneinfocopyindex;
 | |
|   };
 | |
| 
 | |
|   const BoneTrafo *trafo;
 | |
|   std::vector<BoneInfo> bones;
 | |
| 
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     assert(sizeof(BoneTrafo) == 4*(9+3+1));
 | |
|     assert(sizeof(VertWeight) == 6);
 | |
| 
 | |
|     trafo = nif->getPtr<BoneTrafo>();
 | |
| 
 | |
|     int boneNum = nif->getInt();
 | |
|     nif->getInt(); // -1
 | |
| 
 | |
|     bones.resize(boneNum);
 | |
| 
 | |
|     for(int i=0;i<boneNum;i++)
 | |
|       {
 | |
|         BoneInfo &bi = bones[i];
 | |
| 
 | |
|         bi.trafo = nif->getPtr<BoneTrafo>();
 | |
|         bi.unknown = nif->getVector4();
 | |
| 
 | |
|         // Number of vertex weights
 | |
|         int count = nif->getShort();
 | |
|         bi.weights = nif->getArrayLen<VertWeight>(count);
 | |
|       }
 | |
|   }
 | |
| };
 | |
| 
 | |
| class NiMorphData : public Record
 | |
| {
 | |
| 	float startTime;
 | |
| 	float stopTime;
 | |
| 	std::vector<Ogre::Vector3> initialVertices;
 | |
| 	std::vector<std::vector<float> > relevantTimes;
 | |
| 	std::vector<std::vector<Ogre::Vector3> > relevantData;
 | |
| 	std::vector<std::vector<Ogre::Vector3> > additionalVertices;
 | |
| 
 | |
| 
 | |
| public:
 | |
| 	  float getStartTime(){
 | |
| 	     return startTime;
 | |
| 	  }
 | |
| 	  float getStopTime(){
 | |
| 	      return stopTime;
 | |
| 	  }
 | |
| 	  void setStartTime(float time){
 | |
| 			startTime = time;
 | |
| 	  }
 | |
| 
 | |
| 	  void setStopTime(float time){
 | |
| 			stopTime = time;
 | |
| 	  }
 | |
| 	  std::vector<Ogre::Vector3> getInitialVertices(){
 | |
| 			return initialVertices;
 | |
| 	  }
 | |
| 	  std::vector<std::vector<Ogre::Vector3> > getRelevantData(){
 | |
| 			return relevantData;
 | |
| 	  }
 | |
| 	  std::vector<std::vector<float> > getRelevantTimes(){
 | |
| 			return relevantTimes;
 | |
| 	  }
 | |
| 	   std::vector<std::vector<Ogre::Vector3> > getAdditionalVertices(){
 | |
| 			return additionalVertices;
 | |
| 	  }
 | |
| 	  
 | |
| void read(NIFFile *nif)
 | |
|   {
 | |
|     int morphCount = nif->getInt();
 | |
|     int vertCount  = nif->getInt();
 | |
|     nif->getByte();
 | |
| 	int magic = nif->getInt();
 | |
| 	/*int type =*/ nif->getInt();
 | |
| 	for(int i = 0; i < vertCount; i++){
 | |
| 
 | |
| 		float x = nif->getFloat();
 | |
| 		float y = nif->getFloat();
 | |
| 		float z = nif->getFloat();
 | |
| 		initialVertices.push_back(Ogre::Vector3(x, y, z));
 | |
| 	}
 | |
| 	
 | |
|     for(int i=1; i<morphCount; i++)
 | |
|     {
 | |
|         magic = nif->getInt();
 | |
|         /*type =*/ nif->getInt();
 | |
| 		std::vector<Ogre::Vector3> current;
 | |
| 		std::vector<float> currentTime;
 | |
|         for(int i = 0; i < magic; i++){
 | |
|         // Time, data, forward, backward tangents
 | |
| 	        float time = nif->getFloat();
 | |
| 		    float x = nif->getFloat();
 | |
| 		    float y = nif->getFloat();
 | |
| 		    float z = nif->getFloat();
 | |
| 		    current.push_back(Ogre::Vector3(x,y,z));
 | |
| 		    currentTime.push_back(time);
 | |
|           //nif->getFloatLen(4*magic);
 | |
| 		}
 | |
| 		if(magic){
 | |
| 			relevantData.push_back(current);
 | |
| 			relevantTimes.push_back(currentTime);
 | |
| 		}
 | |
| 		std::vector<Ogre::Vector3> verts;
 | |
|         for(int i = 0; i < vertCount; i++){
 | |
| 		    float x = nif->getFloat();
 | |
| 		    float y = nif->getFloat();
 | |
| 		    float z = nif->getFloat();
 | |
| 		    verts.push_back(Ogre::Vector3(x, y, z));
 | |
| 		}
 | |
| 		additionalVertices.push_back(verts);
 | |
|       }
 | |
|   }
 | |
| };
 | |
| 
 | |
| 
 | |
| class NiKeyframeData : public Record
 | |
| {
 | |
| 	std::string bonename;
 | |
| 	//Rotations
 | |
| 	std::vector<Ogre::Quaternion> quats;
 | |
| 	std::vector<Ogre::Vector3> tbc;
 | |
| 	std::vector<float> rottime;
 | |
| 	float startTime;
 | |
| 	float stopTime;
 | |
| 	int rtype;
 | |
| 
 | |
| 	//Translations
 | |
| 	std::vector<Ogre::Vector3> translist1;
 | |
| 	std::vector<Ogre::Vector3> translist2;
 | |
| 	std::vector<Ogre::Vector3> translist3;
 | |
| 	std::vector<Ogre::Vector3> transtbc;
 | |
| 	std::vector<float> transtime;
 | |
| 	int ttype;
 | |
| 
 | |
| 	//Scalings
 | |
| 
 | |
| 	std::vector<float> scalefactor;
 | |
| 	std::vector<float> scaletime;
 | |
| 	std::vector<float> forwards;
 | |
| 	std::vector<float> backwards;
 | |
| 	std::vector<Ogre::Vector3> tbcscale;
 | |
| 	int stype;
 | |
| 
 | |
| 	
 | |
| 	
 | |
| public:
 | |
| 	void clone(NiKeyframeData c)
 | |
| 	{
 | |
| 		quats = c.getQuat();
 | |
| 		tbc = c.getrTbc();
 | |
| 		rottime = c.getrTime();
 | |
| 
 | |
| 		//types
 | |
| 		ttype = c.getTtype();
 | |
| 		rtype = c.getRtype();
 | |
| 		stype = c.getStype();
 | |
| 
 | |
| 
 | |
| 		translist1 = c.getTranslist1();
 | |
| 		translist2 =	c.getTranslist2();	
 | |
|         translist3 = c.getTranslist3();
 | |
| 
 | |
| 	    transtime = c.gettTime();
 | |
| 	   
 | |
| 	    bonename = c.getBonename();
 | |
| 
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	void setBonename(std::string bone)
 | |
| 	{
 | |
| 		bonename = bone;
 | |
| 	}
 | |
| 	void setStartTime(float start)
 | |
| 	{
 | |
| 		startTime = start;
 | |
| 	}
 | |
|   	void setStopTime(float end)
 | |
| 	{
 | |
| 		stopTime = end;
 | |
| 	}
 | |
|   void read(NIFFile *nif)
 | |
|   {
 | |
|     // Rotations first
 | |
|     int count = nif->getInt();
 | |
| 	//std::vector<Ogre::Quaternion> quat(count);
 | |
| 	//std::vector<float> rottime(count);
 | |
|     if(count)
 | |
|       {
 | |
| 
 | |
| 		//TYPE1  LINEAR_KEY
 | |
| 		//TYPE2  QUADRATIC_KEY
 | |
| 		//TYPE3  TBC_KEY
 | |
| 		//TYPE4  XYZ_ROTATION_KEY
 | |
| 		//TYPE5  UNKNOWN_KEY
 | |
|         rtype = nif->getInt();
 | |
| 		    //std::cout << "Count: " << count << "Type: " << type << "\n";
 | |
| 
 | |
|         if(rtype == 1)
 | |
| 		{
 | |
| 			//We need to actually read in these values instead of skipping them
 | |
| 			//nif->skip(count*4*5); // time + quaternion
 | |
| 			for (int i = 0; i < count; i++) {
 | |
| 			    float time = nif->getFloat();
 | |
| 			    float w = nif->getFloat();
 | |
| 			    float x = nif->getFloat();
 | |
| 			    float y = nif->getFloat();
 | |
| 			    float z = nif->getFloat();
 | |
| 				Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z));
 | |
| 				quats.push_back(quat);
 | |
| 				rottime.push_back(time);
 | |
| 				//if(time == 0.0 || time > 355.5) 
 | |
| 					// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
 | |
| 			}
 | |
| 		}
 | |
|         else if(rtype == 3)
 | |
| 		{                  //Example - node 116 in base_anim.nif
 | |
| 			for (int i = 0; i < count; i++) {
 | |
| 			    float time = nif->getFloat();
 | |
| 			    float w = nif->getFloat();
 | |
| 			    float x = nif->getFloat();
 | |
| 			    float y = nif->getFloat();
 | |
| 			    float z = nif->getFloat();
 | |
| 
 | |
| 				float tbcx = nif->getFloat();
 | |
| 				float tbcy = nif->getFloat();
 | |
| 				float tbcz = nif->getFloat();
 | |
| 				Ogre::Quaternion quat = Ogre::Quaternion(Ogre::Real(w), Ogre::Real(x), Ogre::Real(y), Ogre::Real(z));
 | |
| 				Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
 | |
| 				quats.push_back(quat);
 | |
| 				rottime.push_back(time);
 | |
| 				tbc.push_back(vec);
 | |
| 				//if(time == 0.0 || time > 355.5) 
 | |
| 					// std::cout <<"Time:" << time << "W:" << w <<"X:" << x << "Y:" << y << "Z:" << z << "\n";
 | |
| 			}
 | |
| 
 | |
|           //nif->skip(count*4*8); // rot1 + tension+bias+continuity
 | |
| 		}
 | |
|         else if(rtype == 4)
 | |
|           {
 | |
|             for(int j=0;j<count;j++)
 | |
|               {
 | |
|                 nif->getFloat(); // time
 | |
|                 for(int i=0; i<3; i++)
 | |
|                   {
 | |
|                     int cnt = nif->getInt();
 | |
|                     int type = nif->getInt();
 | |
|                     if(type == 1)
 | |
|                       nif->skip(cnt*4*2); // time + unknown
 | |
|                     else if(type == 2)
 | |
|                       nif->skip(cnt*4*4); // time + unknown vector
 | |
|                     else nif->fail("Unknown sub-rotation type");
 | |
|                   }
 | |
|               }
 | |
|           }
 | |
|         else nif->fail("Unknown rotation type in NiKeyframeData");
 | |
|       }
 | |
| 	//first = false;
 | |
| 
 | |
|     // Then translation
 | |
|     count = nif->getInt();
 | |
| 	
 | |
|     if(count)
 | |
|       {
 | |
|        ttype = nif->getInt();
 | |
| 
 | |
| 		//std::cout << "TransCount:" << count << " Type: " << type << "\n";
 | |
|         if(ttype == 1) {
 | |
| 			for (int i = 0; i < count; i++) {
 | |
| 				float time = nif->getFloat();
 | |
| 				float x = nif->getFloat();
 | |
| 				float y = nif->getFloat();
 | |
| 				float z = nif->getFloat();
 | |
| 				Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
 | |
| 				translist1.push_back(trans);
 | |
| 				transtime.push_back(time);
 | |
| 			}
 | |
| 			//nif->getFloatLen(count*4); // time + translation
 | |
| 		}
 | |
|         else if(ttype == 2)
 | |
| 		{                                        //Example - node 116 in base_anim.nif
 | |
| 			for (int i = 0; i < count; i++) {
 | |
| 				float time = nif->getFloat();
 | |
| 				float x = nif->getFloat();
 | |
| 				float y = nif->getFloat();
 | |
| 				float z = nif->getFloat();
 | |
| 				float x2 = nif->getFloat();
 | |
| 				float y2 = nif->getFloat();
 | |
| 				float z2 = nif->getFloat();
 | |
| 				float x3 = nif->getFloat();
 | |
| 				float y3 = nif->getFloat();
 | |
| 				float z3 = nif->getFloat();
 | |
| 				Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
 | |
| 				Ogre::Vector3 trans2 = Ogre::Vector3(x2, y2, z2);
 | |
| 				Ogre::Vector3 trans3 = Ogre::Vector3(x3, y3, z3);
 | |
| 				transtime.push_back(time);
 | |
| 				translist1.push_back(trans);
 | |
| 				translist2.push_back(trans2);
 | |
| 				translist3.push_back(trans3);
 | |
| 			}
 | |
| 			
 | |
| 			//nif->getFloatLen(count*10); // trans1 + forward + backward
 | |
| 		}
 | |
|         else if(ttype == 3){
 | |
| 			for (int i = 0; i < count; i++) {
 | |
| 				float time = nif->getFloat();
 | |
| 				float x = nif->getFloat();
 | |
| 				float y = nif->getFloat();
 | |
| 				float z = nif->getFloat();
 | |
| 				float t = nif->getFloat();
 | |
| 				float b = nif->getFloat();
 | |
| 				float c = nif->getFloat();
 | |
| 				Ogre::Vector3 trans = Ogre::Vector3(x, y, z);
 | |
| 				Ogre::Vector3 tbc = Ogre::Vector3(t, b, c);
 | |
| 				translist1.push_back(trans);
 | |
| 				transtbc.push_back(tbc);
 | |
| 				transtime.push_back(time);
 | |
| 			}
 | |
|           //nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
 | |
| 		}
 | |
|         else nif->fail("Unknown translation type");
 | |
|       }
 | |
| 
 | |
|     // Finally, scalings
 | |
|     count = nif->getInt();
 | |
|     if(count)
 | |
|       {
 | |
|         stype = nif->getInt();
 | |
| 
 | |
| 		
 | |
| 		for(int i = 0; i < count; i++){
 | |
| 					
 | |
| 				
 | |
|         //int size = 0;
 | |
|         if(stype >= 1 && stype < 4) 
 | |
| 			{
 | |
| 				float time = nif->getFloat();
 | |
| 				float scale = nif->getFloat();
 | |
| 				scaletime.push_back(time);
 | |
| 				scalefactor.push_back(scale);
 | |
| 				//size = 2; // time+scale
 | |
| 			}
 | |
| 		else nif->fail("Unknown scaling type");
 | |
|          if(stype == 2){
 | |
| 			//size = 4; // 1 + forward + backward (floats)
 | |
| 			float forward = nif->getFloat();
 | |
| 			float backward = nif->getFloat();
 | |
| 			forwards.push_back(forward);
 | |
| 			backwards.push_back(backward);
 | |
| 		}
 | |
| 		else if(stype == 3){
 | |
| 			float tbcx = nif->getFloat();
 | |
| 			float tbcy = nif->getFloat();
 | |
| 			float tbcz = nif->getFloat();
 | |
| 			Ogre::Vector3 vec = Ogre::Vector3(tbcx, tbcy, tbcz);
 | |
| 			tbcscale.push_back(vec);
 | |
| 
 | |
| 			//size = 5; // 1 + tbc
 | |
| 		}
 | |
|         
 | |
| 		}
 | |
|       }
 | |
| 	  else 
 | |
| 		  stype = 0;
 | |
|   }
 | |
|   	int getRtype(){
 | |
| 		return rtype;
 | |
| 	}
 | |
| 	int getStype(){
 | |
| 		return stype;
 | |
| 	}
 | |
| 	int getTtype(){
 | |
| 		return ttype;
 | |
| 	}
 | |
| 	float getStartTime(){
 | |
| 		return startTime;
 | |
| 	}
 | |
| 	float getStopTime(){
 | |
| 		return stopTime;
 | |
| 	}
 | |
| 	std::vector<Ogre::Quaternion> getQuat(){
 | |
| 		return quats;
 | |
| 	}
 | |
| 	std::vector<Ogre::Vector3> getrTbc(){
 | |
| 		return tbc;
 | |
| 	}
 | |
| 	std::vector<float> getrTime(){
 | |
| 		return rottime;
 | |
| 	}
 | |
| 
 | |
| 	std::vector<Ogre::Vector3> getTranslist1(){
 | |
| 		return translist1;
 | |
| 	}
 | |
| 	std::vector<Ogre::Vector3> getTranslist2(){
 | |
| 		return translist2;
 | |
| 	}
 | |
| 	std::vector<Ogre::Vector3> getTranslist3(){
 | |
| 		return translist3;
 | |
| 	}
 | |
| 	std::vector<float> gettTime(){
 | |
| 		return transtime;
 | |
| 	}
 | |
| 	std::vector<float> getScalefactor(){
 | |
| 		return scalefactor;
 | |
| 	}
 | |
| 	std::vector<float> getForwards(){
 | |
| 		return forwards;
 | |
| 	}
 | |
| 	std::vector<float> getBackwards(){
 | |
| 		return backwards;
 | |
| 	}
 | |
| 	std::vector<Ogre::Vector3> getScaleTbc(){
 | |
| 		return tbcscale;
 | |
| 	}
 | |
| 
 | |
| 	std::vector<float> getsTime(){
 | |
| 		return scaletime;
 | |
| 	}
 | |
| 	std::string getBonename(){ return bonename;
 | |
| 	}
 | |
| 
 | |
| 
 | |
| };
 | |
| 
 | |
| } // Namespace
 | |
| #endif
 |