OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
nifkey.hpp
Go to the documentation of this file.
1 
3 #ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
4 #define OPENMW_COMPONENTS_NIF_NIFKEY_HPP
5 
6 #include "nifstream.hpp"
7 
8 #include <sstream>
9 #include <map>
10 
11 #include "niffile.hpp"
12 
13 namespace Nif
14 {
15 
16 template<typename T>
17 struct KeyT {
19 
20  // FIXME: Implement Quadratic and TBC interpolation
21  /*
22  T mForwardValue; // Only for Quadratic interpolation, and never for QuaternionKeyList
23  T mBackwardValue; // Only for Quadratic interpolation, and never for QuaternionKeyList
24  float mTension; // Only for TBC interpolation
25  float mBias; // Only for TBC interpolation
26  float mContinuity; // Only for TBC interpolation
27  */
28 };
33 
34 template<typename T, T (NIFStream::*getValue)()>
35 struct KeyMapT {
36  typedef std::map< float, KeyT<T> > MapType;
37 
38  typedef T ValueType;
39  typedef KeyT<T> KeyType;
40 
41  static const unsigned int sLinearInterpolation = 1;
42  static const unsigned int sQuadraticInterpolation = 2;
43  static const unsigned int sTBCInterpolation = 3;
44  static const unsigned int sXYZInterpolation = 4;
45 
46  unsigned int mInterpolationType;
48 
50 
51  //Read in a KeyGroup (see http://niftools.sourceforge.net/doc/nif/NiKeyframeData.html)
52  void read(NIFStream *nif, bool force=false)
53  {
54  assert(nif);
55 
57 
58  size_t count = nif->getUInt();
59  if(count == 0 && !force)
60  return;
61 
62  mKeys.clear();
63 
64  mInterpolationType = nif->getUInt();
65 
66  KeyT<T> key;
67  NIFStream &nifReference = *nif;
68 
70  {
71  for(size_t i = 0;i < count;i++)
72  {
73  float time = nif->getFloat();
74  readValue(nifReference, key);
75  mKeys[time] = key;
76  }
77  }
79  {
80  for(size_t i = 0;i < count;i++)
81  {
82  float time = nif->getFloat();
83  readQuadratic(nifReference, key);
84  mKeys[time] = key;
85  }
86  }
88  {
89  for(size_t i = 0;i < count;i++)
90  {
91  float time = nif->getFloat();
92  readTBC(nifReference, key);
93  mKeys[time] = key;
94  }
95  }
96  //XYZ keys aren't actually read here.
97  //data.hpp sees that the last type read was sXYZInterpolation and:
98  // Eats a floating point number, then
99  // Re-runs the read function 3 more times.
100  // When it does that it's reading in a bunch of sLinearInterpolation keys, not sXYZInterpolation.
102  {
103  //Don't try to read XYZ keys into the wrong part
104  if ( count != 1 )
105  {
106  std::stringstream error;
107  error << "XYZ_ROTATION_KEY count should always be '1' . Retrieved Value: "
108  << count;
109  nif->file->fail(error.str());
110  }
111  }
112  else if (0 == mInterpolationType)
113  {
114  if (count != 0)
115  nif->file->fail("Interpolation type 0 doesn't work with keys");
116  }
117  else
118  {
119  std::stringstream error;
120  error << "Unhandled interpolation type: " << mInterpolationType;
121  nif->file->fail(error.str());
122  }
123  }
124 
125 private:
126  static void readValue(NIFStream &nif, KeyT<T> &key)
127  {
128  key.mValue = (nif.*getValue)();
129  }
130 
131  template <typename U>
132  static void readQuadratic(NIFStream &nif, KeyT<U> &key)
133  {
134  readValue(nif, key);
135  /*key.mForwardValue = */(nif.*getValue)();
136  /*key.mBackwardValue = */(nif.*getValue)();
137  }
138 
139  static void readQuadratic(NIFStream &nif, KeyT<osg::Quat> &key)
140  {
141  readValue(nif, key);
142  }
143 
144  static void readTBC(NIFStream &nif, KeyT<T> &key)
145  {
146  readValue(nif, key);
147  /*key.mTension = */nif.getFloat();
148  /*key.mBias = */nif.getFloat();
149  /*key.mContinuity = */nif.getFloat();
150  }
151 };
156 
157 typedef std::shared_ptr<FloatKeyMap> FloatKeyMapPtr;
158 typedef std::shared_ptr<Vector3KeyMap> Vector3KeyMapPtr;
159 typedef std::shared_ptr<Vector4KeyMap> Vector4KeyMapPtr;
160 typedef std::shared_ptr<QuaternionKeyMap> QuaternionKeyMapPtr;
161 
162 } // Namespace
163 #endif //#ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
static void readValue(NIFStream &nif, KeyT< T > &key)
Definition: nifkey.hpp:126
void fail(const std::string &msg) const override
Used if file parsing fails.
Definition: niffile.hpp:74
void read(NIFStream *nif, bool force=false)
Definition: nifkey.hpp:52
std::shared_ptr< QuaternionKeyMap > QuaternionKeyMapPtr
Definition: nifkey.hpp:160
T ValueType
Definition: nifkey.hpp:38
static void readQuadratic(NIFStream &nif, KeyT< U > &key)
Definition: nifkey.hpp:132
NIFFile *const file
Definition: nifstream.hpp:90
T mValue
Definition: nifkey.hpp:18
KeyMapT< osg::Vec3f,&NIFStream::getVector3 > Vector3KeyMap
Definition: nifkey.hpp:153
MapType mKeys
Definition: nifkey.hpp:47
std::map< float, KeyT< T > > MapType
Definition: nifkey.hpp:36
unsigned int mInterpolationType
Definition: nifkey.hpp:46
static void readTBC(NIFStream &nif, KeyT< T > &key)
Definition: nifkey.hpp:144
KeyMapT< float,&NIFStream::getFloat > FloatKeyMap
Definition: nifkey.hpp:152
KeyT< osg::Vec3f > Vector3Key
Definition: nifkey.hpp:30
std::shared_ptr< Vector4KeyMap > Vector4KeyMapPtr
Definition: nifkey.hpp:159
static const unsigned int sLinearInterpolation
Definition: nifkey.hpp:41
std::shared_ptr< Vector3KeyMap > Vector3KeyMapPtr
Definition: nifkey.hpp:158
static const unsigned int sXYZInterpolation
Definition: nifkey.hpp:44
KeyT< T > KeyType
Definition: nifkey.hpp:39
std::shared_ptr< FloatKeyMap > FloatKeyMapPtr
Definition: nifkey.hpp:157
KeyMapT()
Definition: nifkey.hpp:49
Definition: nifkey.hpp:17
KeyT< osg::Quat > QuaternionKey
Definition: nifkey.hpp:32
KeyMapT< osg::Vec4f,&NIFStream::getVector4 > Vector4KeyMap
Definition: nifkey.hpp:154
float getFloat()
Definition: nifstream.hpp:121
KeyT< float > FloatKey
Definition: nifkey.hpp:29
Definition: nifstream.hpp:83
unsigned int getUInt()
Definition: nifstream.hpp:116
KeyMapT< osg::Quat,&NIFStream::getQuaternion > QuaternionKeyMap
Definition: nifkey.hpp:155
Definition: nifkey.hpp:35
static const unsigned int sQuadraticInterpolation
Definition: nifkey.hpp:42
KeyT< osg::Vec4f > Vector4Key
Definition: nifkey.hpp:31
static const unsigned int sTBCInterpolation
Definition: nifkey.hpp:43
static void readQuadratic(NIFStream &nif, KeyT< osg::Quat > &key)
Definition: nifkey.hpp:139