From f38e79d18332838f31c6c5c83db1f525e8b267c3 Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Sun, 16 Oct 2005 19:07:02 +0000
Subject: [PATCH] Finished NiMorphData interface and functions. Added template
 directives for new key templates to pyniflib.i.

---
 NIF_Blocks.cpp | 80 ++++++++++++++++++++++++++++++++++++++------------
 NIF_Blocks.h   | 28 +++++++++++++++---
 niflib.cpp     |  4 +++
 niflib.h       | 26 ++++++++++++----
 pyniflib.i     | 68 +++++++++++++++++++++++++++++++++++-------
 5 files changed, 167 insertions(+), 39 deletions(-)

diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp
index bec326b7..e27f1eb4 100644
--- a/NIF_Blocks.cpp
+++ b/NIF_Blocks.cpp
@@ -1437,7 +1437,9 @@ void NiKeyframeData::Read( ifstream& in ) {
 			}
 
 			if (rotationType == 3) {
-				ReadFVector3( rotKeys[i].tbc, in ) ;
+				rotKeys[i].tension = ReadFloat( in );
+				rotKeys[i].bias = ReadFloat( in );
+				rotKeys[i].continuity = ReadFloat( in );
 			} else if (rotationType == 4) {
 				throw runtime_error("NiKeyframeData rotation type 4 currently unsupported");
 				//cout << "Rotation Type 4 Unsupported - Data will not be read" << endl;
@@ -1477,13 +1479,22 @@ void NiKeyframeData::Read( ifstream& in ) {
 		for ( unsigned int i = 0; i < numTranslations; ++i ) {
 			transKeys[i].time = ReadFloat( in );
 			
-			ReadFVector3( transKeys[i].data, in );
+			transKeys[i].data.x = ReadFloat( in );
+			transKeys[i].data.y = ReadFloat( in );
+			transKeys[i].data.z = ReadFloat( in );
 
 			if (translationType == 2) {
-				ReadFVector3( transKeys[i].forward_tangent, in );
-				ReadFVector3( transKeys[i].backward_tangent, in );
+				transKeys[i].forward_tangent.x = ReadFloat( in );
+				transKeys[i].forward_tangent.y = ReadFloat( in );
+				transKeys[i].forward_tangent.y = ReadFloat( in );
+
+				transKeys[i].backward_tangent.x = ReadFloat( in );
+				transKeys[i].backward_tangent.y = ReadFloat( in );
+				transKeys[i].backward_tangent.y = ReadFloat( in );
 			}else if (translationType == 3) {
-				ReadFVector3( transKeys[i].tbc, in );
+				transKeys[i].tension = ReadFloat( in );
+				transKeys[i].bias = ReadFloat( in );
+				transKeys[i].continuity = ReadFloat( in );
 			}
 		}
 	}
@@ -1505,7 +1516,9 @@ void NiKeyframeData::Read( ifstream& in ) {
 				scaleKeys[i].forward_tangent = ReadFloat( in );
 				scaleKeys[i].backward_tangent = ReadFloat( in );
 			} else if (scaleType == 3) {
-				ReadFVector3( scaleKeys[i].tbc, in );
+				scaleKeys[i].tension = ReadFloat( in );
+				scaleKeys[i].bias = ReadFloat( in );
+				scaleKeys[i].continuity = ReadFloat( in );
 			}
 		}
 	}
@@ -1532,7 +1545,9 @@ void NiKeyframeData::Write( ofstream& out ) {
 			}
 
 			if (rotationType == 3) {
-				WriteFVector3( rotKeys[i].tbc, out ) ;
+				WriteFloat( rotKeys[i].tension, out );
+				WriteFloat( rotKeys[i].bias, out );
+				WriteFloat( rotKeys[i].continuity, out );
 			} else if (rotationType == 4) {
 				throw runtime_error("NiKeyframeData rotation type 4 currently unsupported");
 			}
@@ -1548,14 +1563,23 @@ void NiKeyframeData::Write( ofstream& out ) {
 
 		for ( unsigned int i = 0; i < transKeys.size(); ++i ) {
 			WriteFloat( transKeys[i].time, out );
-			
-			WriteFVector3( transKeys[i].data, out );
+
+			WriteFloat( transKeys[i].data.x, out );
+			WriteFloat( transKeys[i].data.y, out );
+			WriteFloat( transKeys[i].data.z, out );
 
 			if (translationType == 2) {
-				WriteFVector3( transKeys[i].forward_tangent, out );
-				WriteFVector3( transKeys[i].backward_tangent, out );
+				WriteFloat( transKeys[i].forward_tangent.x, out );
+				WriteFloat( transKeys[i].forward_tangent.y, out );
+				WriteFloat( transKeys[i].forward_tangent.z, out );
+
+				WriteFloat( transKeys[i].backward_tangent.x, out );
+				WriteFloat( transKeys[i].backward_tangent.y, out );
+				WriteFloat( transKeys[i].backward_tangent.z, out );
 			}else if (translationType == 3) {
-				WriteFVector3( transKeys[i].tbc, out );
+				WriteFloat( transKeys[i].tension, out );
+				WriteFloat( transKeys[i].bias, out );
+				WriteFloat( transKeys[i].continuity, out );
 			}
 		}
 	}
@@ -1575,7 +1599,9 @@ void NiKeyframeData::Write( ofstream& out ) {
 				WriteFloat( scaleKeys[i].forward_tangent, out );
 				WriteFloat( scaleKeys[i].backward_tangent, out );
 			} else if (scaleType == 3) {
-				WriteFVector3( scaleKeys[i].tbc, out );
+				WriteFloat( scaleKeys[i].tension, out );
+				WriteFloat( scaleKeys[i].bias, out );
+				WriteFloat( scaleKeys[i].continuity, out );
 			}
 		}
 	}
@@ -1606,7 +1632,7 @@ string NiKeyframeData::asString() {
 				}
 				
 				if (rotationType == 3) {
-					out << ",  TBC" << rotKeys[i].tbc;
+					out << ", T " << rotKeys[i].tension << ", B " << rotKeys[i].bias << ", C " << rotKeys[i].continuity;
 				} else if (rotationType == 4) {
 					out << "Rotation Type 4 Unsupported - Data was not read" << endl;
 				}
@@ -1627,12 +1653,12 @@ string NiKeyframeData::asString() {
 			for (unsigned int i = 0; i < transKeys.size(); i++) {
 				out << "Key Time:  " << transKeys[i].time << "  ";
 				
-				out << "Data:  V" << transKeys[i].data;
+				out << "Data:  V(" << transKeys[i].data.x << ", " << transKeys[i].data.y << ", " << transKeys[i].data.z;
 
 				if (translationType == 2) {
-					out << ", F" << transKeys[i].forward_tangent << ", B" << transKeys[i].backward_tangent;
+					out << "), F(" << transKeys[i].forward_tangent.x << ", " << transKeys[i].forward_tangent.y << ", " << transKeys[i].forward_tangent.z << "), B(" << transKeys[i].backward_tangent.x << ", " << transKeys[i].backward_tangent.y << ", " << transKeys[i].backward_tangent.z << ")";
 				}else if (translationType == 3) {
-					out << ", TBC" << transKeys[i].tbc;
+					out << ", T " << transKeys[i].tension << ", B " << transKeys[i].bias << ", C " << transKeys[i].continuity;
 				}
 				out << endl;
 			}
@@ -1655,9 +1681,9 @@ string NiKeyframeData::asString() {
 				out << "Data:  S(" << scaleKeys[i].data << ")";
 
 				if (scaleType == 2) {
-					out << ", F(" << scaleKeys[i].forward_tangent << "), B(" << scaleKeys[i].backward_tangent << ")";
+					out << ", FT(" << scaleKeys[i].forward_tangent << "), BT(" << scaleKeys[i].backward_tangent << ")";
 				} else if (scaleType == 3) {
-					out << ", TBC" << scaleKeys[i].tbc;
+					out << ", T " << scaleKeys[i].tension << ", B " << scaleKeys[i].bias << ", C " << scaleKeys[i].continuity;
 				}
 				out << endl;
 			}
@@ -1898,6 +1924,22 @@ string NiMorphData::asString() {
 	return out.str();
 }
 
+void NiMorphData::SetVertexCount( int n ) {
+	vertCount = n;
+	for ( uint i = 0; i < morphs.size(); ++i ) {
+		morphs[i].morph.resize( n );
+	}
+}
+
+void NiMorphData::SetMorphVerts( int n, const vector<Vector3D> & in ) {
+	// Make sure the size of the incoming vector equal vertCount
+	if ( in.size() != vertCount )
+		throw runtime_error("Input array size must equal Vertex Count.  Call SetVertexCount() to resize.");
+
+	//It's the right size, so go ahead and set it
+	morphs[n].morph = in;
+}
+
 /***********************************************************
  * NiPixelData methods
  **********************************************************/
diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index d1b898a4..e334dfc1 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -939,8 +939,8 @@ class NiKeyframeData : public ABlock, public IKeyframeData {
 		//Translate
 		KeyType GetTranslateType() { return translationType; }
 		void SetTranslateType( KeyType t ) { translationType = t; }
-		vector< Key<float3> > GetTranslateKeys() { return transKeys; }
-		void SetTranslateKeys( vector< Key<float3> > & keys ) { transKeys = keys; }
+		vector< Key<Vector3D> > GetTranslateKeys() { return transKeys; }
+		void SetTranslateKeys( vector< Key<Vector3D> > & keys ) { transKeys = keys; }
 		//Scale
 		KeyType GetScaleType() { return scaleType; }
 		void SetScaleType( KeyType t ) { scaleType = t; }
@@ -952,7 +952,7 @@ class NiKeyframeData : public ABlock, public IKeyframeData {
 		vector< Key<Quaternion> > rotKeys;
 
 		KeyType translationType;
-		vector< Key<float3> >	transKeys;
+		vector< Key<Vector3D> >	transKeys;
 
 		KeyType scaleType;
 		vector< Key<float> > scaleKeys;
@@ -1137,7 +1137,7 @@ class NiStringExtraData : public AExtraData{
 		string strData;
 };
 
-class NiMorphData : public ABlock{
+class NiMorphData : public ABlock, public IMorphData {
 
 	public:
 
@@ -1151,8 +1151,28 @@ class NiMorphData : public ABlock{
 		string asString();
 		string GetBlockType() { return "NiMorphData"; };
 
+		void * QueryInterface( int id ) {
+			if ( id == MorphData ) {
+				return (void*)static_cast<IMorphData*>(this);;
+			} else {
+				return ABlock::QueryInterface( id );
+			}
+		}
+
+		//--IMorphData Functions --//
+		int GetVertexCount() { return vertCount; }
+		void SetVertexCount( int n );
+		int GetMorphCount() { return int(morphs.size()); }
+		void SetMorphCount( int n ) { morphs.resize( n ); }
+		vector< Key<float> > GetMorphKeys( int n ) { return morphs[n].keys; }
+		void SetMorphKeys( int n, vector< Key<float> > & keys ) { morphs[n].keys = keys; }
+		vector<Vector3D> GetMorphVerts( int n) { return morphs[n].morph; }
+		void SetMorphVerts( int n, const vector<Vector3D> & in );
+
 	private:
 		struct Morph {
+			Morph() :  keyType(QUADRATIC_KEY) {}
+			~Morph() {}
 			KeyType keyType;
 			vector< Key<float> > keys;
 			vector< Vector3D > morph;
diff --git a/niflib.cpp b/niflib.cpp
index 7a96c9c6..b61d1f4a 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -486,3 +486,7 @@ IKeyframeData * QueryKeyframeData( blk_ref & block ) {
 ITextKeyExtraData * QueryTextKeyExtraData ( blk_ref & block ) {
 	return (ITextKeyExtraData*)block->QueryInterface( TextKeyExtraData );
 }
+
+IMorphData * QueryMorphData ( blk_ref & block ) {
+	return (IMorphData*)block->QueryInterface( MorphData );
+}
diff --git a/niflib.h b/niflib.h
index cb477d83..1c83a3b1 100644
--- a/niflib.h
+++ b/niflib.h
@@ -56,6 +56,7 @@ class ITriShapeData;
 class ISkinData;
 class IKeyframeData;
 class ITextKeyExtraData;
+class IMorphData;
 class INode;
 class blk_ref;
 class attr_ref;
@@ -75,6 +76,7 @@ const int SkinData = 1;
 const int Node = 2;
 const int KeyframeData = 3;
 const int TextKeyExtraData = 4;
+const int MorphData = 5;
 
 //--Main Functions--//
 
@@ -106,7 +108,7 @@ ISkinData * QuerySkinData( blk_ref & block );
 INode * QueryNode( blk_ref & block );
 IKeyframeData * QueryKeyframeData( blk_ref & block );
 ITextKeyExtraData * QueryTextKeyExtraData ( blk_ref & block );
-
+IMorphData * QueryMorphData ( blk_ref & block );
 //--TypeDefs--//
 
 typedef float float3[3];
@@ -209,11 +211,11 @@ struct Quaternion {
 	float w, x, y, z;
 };
 
-template <class T>
+template <class T> 
 struct Key {
 	float time;
 	T data, forward_tangent, backward_tangent;
-	float3 tbc;
+	float tension, bias, continuity;
 };
 
 enum KeyType { LINEAR_KEY = 1, QUADRATIC_KEY = 2, TBC_KEY = 3 };
@@ -279,8 +281,8 @@ public:
 	//Translate
 	virtual KeyType GetTranslateType() = 0;
 	virtual void SetTranslateType( KeyType t ) = 0;
-	virtual vector< Key<float3> > GetTranslateKeys() = 0;
-	virtual void SetTranslateKeys( vector< Key<float3> > & keys ) = 0;
+	virtual vector< Key<Vector3D> > GetTranslateKeys() = 0;
+	virtual void SetTranslateKeys( vector< Key<Vector3D> > & keys ) = 0;
 	//Scale
 	virtual KeyType GetScaleType() = 0;
 	virtual void SetScaleType( KeyType t ) = 0;
@@ -296,6 +298,20 @@ public:
 	virtual void SetRotateKeys( vector< Key<string> > & keys ) = 0;
 };
 
+class IMorphData {
+public:
+	IMorphData() {}
+	virtual ~IMorphData () {}
+	virtual int GetVertexCount() = 0;
+	virtual void SetVertexCount( int n ) = 0;
+	virtual int GetMorphCount() = 0;
+	virtual void SetMorphCount( int n ) = 0;
+	virtual vector< Key<float> > GetMorphKeys( int n ) = 0;
+	virtual void SetMorphKeys( int n, vector< Key<float> > & keys ) = 0;
+	virtual vector<Vector3D> GetMorphVerts( int n) = 0;
+	virtual void SetMorphVerts( int n, const vector<Vector3D> & in ) = 0;
+};
+
 //--Attribute Reference--//
 class attr_ref {
 public:
diff --git a/pyniflib.i b/pyniflib.i
index 7c7120c3..c6106b52 100644
--- a/pyniflib.i
+++ b/pyniflib.i
@@ -1,6 +1,39 @@
 // Swig module description file for a C dynamic library source file
 // Generate with: swig -c++ -python -o py_wrap.cpp pyniflib.i
 
+/* Copyright (c) 2005, NIF File Format Library and Tools
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+
+   * Redistributions in binary form must reproduce the above
+     copyright notice, this list of conditions and the following
+     disclaimer in the documentation and/or other materials provided
+     with the distribution.
+
+   * Neither the name of the NIF File Format Library and Tools
+     project nor the names of its contributors may be used to endorse
+     or promote products derived from this software without specific
+     prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. */
+
 %module niflib
 %include "stl.i"
 %include "std_map.i"
@@ -17,21 +50,34 @@
 }
 
 %{
-  #include "NIFlib/niflib.h"
+	#include "NIFlib/niflib.h"
 %}
 
-namespace std {
-	%template(vector_float) vector<float>;
-	%template(vector_blk_ref) vector<blk_ref>;
-	%template(vector_Vector3D) vector<Vector3D>;
-	%template(vector_Color) vector<Color>;
-	%template(vector_UVCoord) vector<UVCoord>;
-	%template(vector_Triangle) vector<Triangle>;
-	%template(vector_SkinWeight) vector<SkinWeight>;
-	%template(pair_int_float) pair<int, float>;
-	%template(map_int_float) map<int, float>;
+template <class T> 
+struct Key {
+	float time;
+	T data, forward_tangent, backward_tangent;
+	float tension, bias, continuity;
 };
 
+%template(vector_float) std::vector<float>;
+%template(vector_blk_ref) std::vector<blk_ref>;
+%template(vector_Vector3D) std::vector<Vector3D>;
+%template(vector_Color) std::vector<Color>;
+%template(vector_UVCoord) std::vector<UVCoord>;
+%template(vector_Triangle) std::vector<Triangle>;
+%template(vector_SkinWeight) std::vector<SkinWeight>;
+%template(pair_int_float) std::pair<int, float>;
+%template(map_int_float) std::map<int, float>;
+%template(Key_Quaternion) Key<Quaternion>;
+%template(vector_Key_Quaternion) std::vector< Key<Quaternion> >;
+%template(Key_Vector3D) Key<Vector3D>;
+%template(vector_Key_Vector3D) std::vector< Key<Vector3D> >;
+%template(Key_float) Key<float>;
+%template(vector_Key_float) std::vector< Key<float> >;
+%template(Key_string) Key<std::string>;
+%template(vector_Key_string) std::vector< Key<std::string> >;
+
 %include "../NIFlib/niflib.h"
 
 
-- 
GitLab