From 8696388eec2c04c53680c380c9e75b8e8ede14f2 Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Sat, 13 May 2006 09:33:21 +0000
Subject: [PATCH] Moved math-related structures to nif_math files and began
 porting operations to member functions.

---
 NIF_Blocks.h        |   4 +
 NIF_IO.cpp          |  56 ----
 NIF_IO.h            |  11 -
 nif_attrs.h         |   1 +
 nif_math.cpp        | 365 +++++++++++++++-------
 nif_math.h          | 734 +++++++++++++++++++++++++++++++++++++++++++-
 niflib.h            | 568 +---------------------------------
 niflib_internal.cpp |  54 ++++
 niflib_internal.h   | 107 +++++++
 9 files changed, 1149 insertions(+), 751 deletions(-)

diff --git a/NIF_Blocks.h b/NIF_Blocks.h
index c1d1c3a1..5583a82c 100644
--- a/NIF_Blocks.h
+++ b/NIF_Blocks.h
@@ -60,14 +60,18 @@ const int SkinDataInternal = -3;
 
 class AControllable : public ABlock {
 public:
+	static const Type TYPE;
 	AControllable();
 	void Init() {}
 	bool IsControllable() const { return true; }
 	~AControllable() {}
 };
 
+const Type AControllable::TYPE("AControllable", &ABlock::TYPE);
+
 class ANode : public AControllable, public INode {
 public:
+	static const Type TYPE;
 	ANode();
 	void Init() { 
 		//Start the bind pose at an identity matrix
diff --git a/NIF_IO.cpp b/NIF_IO.cpp
index e608867c..a34448ab 100644
--- a/NIF_IO.cpp
+++ b/NIF_IO.cpp
@@ -355,10 +355,6 @@ void NifStream( TexCoord const & val, ostream& out, uint version ) {
 	WriteFloat( val.v, out );
 };
 
-ostream & operator<<( ostream & out, TexCoord const & val ) {
-	return out << "(" << setw(6) << val.u << "," << setw(6) << val.v << ")";
-}
-
 //Triangle
 void NifStream( Triangle & val, istream& in, uint version ) {
 	val.v1 = ReadUShort( in );
@@ -372,10 +368,6 @@ void NifStream( Triangle const & val, ostream& out, uint version ) {
 	WriteUShort( val.v3, out );
 };
 
-ostream & operator<<( ostream & out, Triangle const & val ) {
-	return out << "{" << setw(6) << val.v1 << "," << setw(6) << val.v2 << "," << setw(6) << val.v3 << "}";
-}
-
 //Vector3
 void NifStream( Vector3 & val, istream& in, uint version ) {
 	val.x = ReadFloat( in );
@@ -389,10 +381,6 @@ void NifStream( Vector3 const & val, ostream& out, uint version ) {
 	WriteFloat( val.z, out );
 };
 
-ostream & operator<<( ostream & out, Vector3 const & val ) {
-	return out << "(" << setw(6) << val.x << "," << setw(6) << val.y << "," << setw(6) << val.z << ")";
-}
-
 //Float2
 void NifStream( Float2 & val, istream& in, uint version ) {
 	val.data[0] = ReadFloat( in );
@@ -404,10 +392,6 @@ void NifStream( Float2 const & val, ostream& out, uint version ) {
 	WriteFloat( val.data[1], out );
 };
 
-ostream & operator<<( ostream & out, Float2 const & val ) {
-	return out << "{" << setw(6) << val.data[0] << "," << setw(6) << val.data[1] << "}";
-}
-
 //Matrix22
 void NifStream( Matrix22 & val, istream& in, uint version ) {
 	for (int c = 0; c < 2; ++c) {
@@ -425,13 +409,6 @@ void NifStream( Matrix22 const & val, ostream& out, uint version ) {
 	}
 }
 
-ostream & operator<<( ostream & out, Matrix22 const & val ) {
-	out << endl
-		<< "   |" << setw(6) << val[0][0] << "," << setw(6) << val[0][1] << " |" << endl
-		<< "   |" << setw(6) << val[1][0] << "," << setw(6) << val[1][1] << " |";
-	return out;
-}
-
 //Float3
 void NifStream( Float3 & val, istream& in, uint version ) {
 	val.data[0] = ReadFloat( in );
@@ -445,10 +422,6 @@ void NifStream( Float3 const & val, ostream& out, uint version ) {
 	WriteFloat( val.data[2], out );
 };
 
-ostream & operator<<( ostream & out, Float3 const & val ) {
-	return out << "{" << setw(6) << val.data[0] << "," << setw(6) << val.data[1] << "," << setw(6) << val.data[2] << "}";
-}
-
 //Matrix33
 void NifStream( Matrix33 & val, istream& in, uint version ) {
 	for (int c = 0; c < 3; ++c) {
@@ -466,14 +439,6 @@ void NifStream( Matrix33 const & val, ostream& out, uint version ) {
 	}
 }
 
-ostream & operator<<( ostream & out, Matrix33 const & val ) {
-	out << endl
-		<< "   |" << setw(6) << val[0][0] << "," << setw(6) << val[0][1] << "," << setw(6) << val[0][2] << " |" << endl
-		<< "   |" << setw(6) << val[1][0] << "," << setw(6) << val[1][1] << "," << setw(6) << val[1][2] << " |" << endl
-		<< "   |" << setw(6) << val[2][0] << "," << setw(6) << val[2][1] << "," << setw(6) << val[2][2] << " |";
-	return out;
-}
-
 //Float4
 void NifStream( Float4 & val, istream& in, uint version ) {
 	val.data[0] = ReadFloat( in );
@@ -489,10 +454,6 @@ void NifStream( Float4 const & val, ostream& out, uint version ) {
 	WriteFloat( val.data[4], out );
 };
 
-ostream & operator<<( ostream & out, Float4 const & val ) {
-	return out << "{" << setw(6) << val.data[0] << "," << setw(6) << val.data[1] << "," << setw(6) << val.data[2] << "," << setw(6) << val.data[3] << "}";
-}
-
 //Matrix44
 void NifStream( Matrix44 & val, istream& in, uint version ) {
 	for (int c = 0; c < 4; ++c) {
@@ -510,15 +471,6 @@ void NifStream( Matrix44 const & val, ostream& out, uint version ) {
 	}
 }
 
-ostream & operator<<( ostream & out, Matrix44 const & val ) {
-	out << endl
-		<< "   |" << setw(6) << val[0][0] << "," << setw(6) << val[0][1] << "," << setw(6) << val[0][2] << "," << setw(6) << val[0][3] << " |" << endl
-		<< "   |" << setw(6) << val[1][0] << "," << setw(6) << val[1][1] << "," << setw(6) << val[1][2] << "," << setw(6) << val[1][3] << " |" << endl
-		<< "   |" << setw(6) << val[2][0] << "," << setw(6) << val[2][1] << "," << setw(6) << val[2][2] << "," << setw(6) << val[2][3] << " |" << endl
-		<< "   |" << setw(6) << val[3][0] << "," << setw(6) << val[3][1] << "," << setw(6) << val[3][2] << "," << setw(6) << val[3][3] << " |";
-	return out;
-}
-
 //Color4
 void NifStream( Color4 & val, istream& in, uint version ) {
 	val.r = ReadFloat( in );
@@ -534,10 +486,6 @@ void NifStream( Color4 const & val, ostream& out, uint version ) {
 	WriteFloat( val.a, out );
 };
 
-ostream & operator<<( ostream & out, Color4 const & val ) {
-	return out << "R:" << setw(6) << val.r << " G:" << setw(6) << val.g << " B:" << setw(6) << val.b << " A:" << setw(6) << val.a << "}";
-}
-
 //Quaternion
 void NifStream( Quaternion & val, istream& in, uint version ) {
 	val.w = ReadFloat( in );
@@ -553,10 +501,6 @@ void NifStream( Quaternion const & val, ostream& out, uint version ) {
 	WriteFloat( val.z, out );
 };
 
-ostream & operator<<( ostream & out, Quaternion const & val ) {
-	return out << "[" << setw(6) << val.w << ",(" << setw(6) << val.x << "," << setw(6) << val.y << "," << setw(6) << val.z << ")]";
-}
-
 //BoundingBox
 void NifStream( BoundingBox & val, istream& in, uint version ) {
 	NifStream( val.isUsed, in, version );
diff --git a/NIF_IO.h b/NIF_IO.h
index 83a6116d..f5366640 100644
--- a/NIF_IO.h
+++ b/NIF_IO.h
@@ -140,57 +140,46 @@ ostream & operator<<( ostream & out, HeaderString const & val );
 //TexCoord
 void NifStream( TexCoord & val, istream& in, uint version = 0 );
 void NifStream( TexCoord const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, TexCoord const & val );
 
 //Triangle
 void NifStream( Triangle & val, istream& in, uint version = 0 );
 void NifStream( Triangle const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, Triangle const & val );
 
 //Vector3
 void NifStream( Vector3 & val, istream& in, uint version = 0 );
 void NifStream( Vector3 const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, Vector3 const & val );
 
 //Float2
 void NifStream( Float2 & val, istream& in, uint version = 0 );
 void NifStream( Float2 const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, Float2 const & val );
 
 //Matrix22
 void NifStream( Matrix22 & val, istream& in, uint version = 0 );
 void NifStream( Matrix22 const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, Matrix22 const & val );
 
 //Float3
 void NifStream( Float3 & val, istream& in, uint version = 0 );
 void NifStream( Float3 const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, Float3 const & val );
 
 //Matrix33
 void NifStream( Matrix33 & val, istream& in, uint version = 0 );
 void NifStream( Matrix33 const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, Matrix33 const & val );
 
 //Float4
 void NifStream( Float4 & val, istream& in, uint version = 0 );
 void NifStream( Float4 const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, Float4 const & val );
 
 //Matrix44
 void NifStream( Matrix44 & val, istream& in, uint version = 0 );
 void NifStream( Matrix44 const & val, ostream& out, uint version = 0 );
-ostream & operator<<( ostream & out, Matrix44 const & val );
 
 //Color4
 void NifStream( Color4 & val, istream& in, uint version = 0 );
 void NifStream( Color4 const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, Color4 const & val );
 
 //Quaternion
 void NifStream( Quaternion & val, istream& in, uint version = 0 );
 void NifStream( Quaternion const & val, ostream& out, uint version = 0  );
-ostream & operator<<( ostream & out, Quaternion const & val );
 
 //BoundingBox
 void NifStream( BoundingBox & val, istream& in, uint version = 0 );
diff --git a/nif_attrs.h b/nif_attrs.h
index f37033a5..1b1b392a 100644
--- a/nif_attrs.h
+++ b/nif_attrs.h
@@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 #define endl "\r\n"
 
+
 class IntAttr : public AAttr {
 public:
 	IntAttr( string const & name, IBlock * owner, int * data ) : AAttr( name, owner ), _data(data) {}
diff --git a/nif_math.cpp b/nif_math.cpp
index 99a177ad..583aec2c 100644
--- a/nif_math.cpp
+++ b/nif_math.cpp
@@ -32,6 +32,7 @@ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE. */
 
 #include "nif_math.h"
+#include <iomanip>
 
 void PrintMatrix33( Matrix33 const & m, ostream & out ) {
 	out << endl
@@ -70,52 +71,6 @@ void SetIdentity44( Matrix44 & m ) {
 	m[3][0] = 0.0f;	m[3][1] = 0.0f;	m[3][2] = 0.0f;	m[3][3] = 1.0f;
 }
 
-//Vector3 MatrixToEuler( Matrix33 & m ) {}
-
-Quaternion MatrixToQuat( Matrix33 const & m ) {
-	Quaternion quat;
-	float tr, s, q[4];
-	int i, j, k;
-
-	int nxt[3] = {1, 2, 0};
-
-	// compute the trace of the matrix
-	tr = m[0][0] + m[1][1] + m[2][2];
-
-	// check if the trace is positive or negative
-	if (tr > 0.0) {
-		s = sqrt (tr + 1.0f);
-		quat.w = s / 2.0f;
-		s = 0.5f / s;
-		quat.x = (m[1][2] - m[2][1]) * s;
-		quat.y = (m[2][0] - m[0][2]) * s;
-		quat.z = (m[0][1] - m[1][0]) * s;
-	}
-	else {
-		// trace is negative
-		i = 0;
-		if ( m[1][1] > m[0][0])
-			i = 1;
-		if ( m[2][2] > m[i][i] )
-			i = 2;
-		j = nxt[i];
-		k = nxt[j];
-
-		s = sqrt( ( m[i][i] - (m[j][j] + m[k][k]) ) + 1.0f );
-		q[i] = s * 0.5f;
-		if (s != 0.0f) s = 0.5f / s;
-		q[3] = (m[j][k] - m[k][j]) * s;
-		q[j] = (m[i][j] + m[j][i]) * s;
-		q[k] = (m[i][k] + m[k][i]) * s;
-		quat.x = q[0];
-		quat.y= q[1];
-		quat.z = q[2];
-		quat.w = q[3];
-	}
-
-	return quat;
-}
-
 Matrix33 MultMatrix33( Matrix33 const & a, Matrix33 const & b ) {
 	Matrix33 result;
 	for (int i = 0; i < 3; i++) {
@@ -211,13 +166,196 @@ Matrix44 InverseMatrix44( Matrix44 const & m ) {
 	return result;
 }
 
-void QuatToMatrix( Quaternion const & quat, ostream & out ) {
-	Matrix33 m;
+/*
+ * Vector3 Methods
+ */
+
+float Vector3::Magnitude() const {
+	return sqrt( x * x + y * y + z * z );
+}
+
+Vector3 Vector3::Normalized() const {
+	Vector3 v(*this);
+	float m = Magnitude();
+	return Vector3(
+		x / m, //x
+		y / m, //y
+		z / m //z
+	);
+}
+
+Vector3 Vector3::operator+( const Vector3 & rh) const {
+	Vector3 v(*this);
+	v += rh;
+	return v;
+}
+
+Vector3 & Vector3::operator+=( const Vector3 & rh ) {
+	x += rh.x;
+	y += rh.y;
+	z += rh.z;
+
+	return *this;
+}
+
+Vector3 Vector3::operator-( const Vector3 & rh) const {
+	Vector3 v(*this);
+	v -= rh;
+	return v;
+}
+
+Vector3 & Vector3::operator-=( const Vector3 & rh ) {
+	x -= rh.x;
+	y -= rh.y;
+	z -= rh.z;
+
+	return *this;
+}
+
+Vector3 Vector3::operator*( const float & rh) const {
+	Vector3 v(*this);
+	v *= rh;
+	return v;
+}
+
+Vector3 & Vector3::operator*=( const float & rh) {
+	x *= rh;
+	y *= rh;
+	z *= rh;
+
+	return *this;
+}
+
+Vector3 Vector3::operator/( const float & rh ) const {
+	Vector3 v(*this);
+	v /= rh;
+	return v;
+}
+
+Vector3 & Vector3::operator/=( const float & rh ) {
+	x /= rh;
+	y /= rh;
+	z /= rh;
+
+	return *this;
+}
+
+bool Vector3::operator==( const Vector3 & rh) const {
+	if (rh.x == x && rh.y == y && rh.z == z)
+		return true;
+	else
+		return false;
+}
+
+float Vector3::DotProduct( const Vector3 & rh) const {
+	return x * rh.x + y * rh.y + z * rh.z;
+}
+
+Vector3 Vector3::CrossProduct( const Vector3 & rh) const {
+	return Vector3(
+		y * rh.z - z * rh.y, //x
+		z * rh.x - x * rh.z, //y
+		x * rh.y - y * rh.x //z
+	);
+}
+
+//Vector3 Vector3::operator*( const Matrix44 & rh) const {
+//	return rh * (*this);
+//}
+//
+//Vector & Vector3::operator*=( const Matrix44 & rh) {
+//	*this = rh * (*this);
+//	return *this;
+//}
+
+/*
+ * Matrix33 Methods
+ */
+
+Quaternion Matrix33::AsQuaternion() {
+	Quaternion quat;
+	float tr, s, q[4];
+	int i, j, k;
+
+	int nxt[3] = {1, 2, 0};
+
+	Matrix33 & m = *this;
 
-	float w = quat.w;
-	float x = quat.x;
-	float y = quat.y;
-	float z = quat.z;
+	// compute the trace of the matrix
+	tr = m[0][0] + m[1][1] + m[2][2];
+
+	// check if the trace is positive or negative
+	if (tr > 0.0) {
+		s = sqrt (tr + 1.0f);
+		quat.w = s / 2.0f;
+		s = 0.5f / s;
+		quat.x = (m[1][2] - m[2][1]) * s;
+		quat.y = (m[2][0] - m[0][2]) * s;
+		quat.z = (m[0][1] - m[1][0]) * s;
+	}
+	else {
+		// trace is negative
+		i = 0;
+		if ( m[1][1] > m[0][0])
+			i = 1;
+		if ( m[2][2] > m[i][i] )
+			i = 2;
+		j = nxt[i];
+		k = nxt[j];
+
+		s = sqrt( ( m[i][i] - (m[j][j] + m[k][k]) ) + 1.0f );
+		q[i] = s * 0.5f;
+		if (s != 0.0f) s = 0.5f / s;
+		q[3] = (m[j][k] - m[k][j]) * s;
+		q[j] = (m[i][j] + m[j][i]) * s;
+		q[k] = (m[i][k] + m[k][i]) * s;
+		quat.x = q[0];
+		quat.y= q[1];
+		quat.z = q[2];
+		quat.w = q[3];
+	}
+
+	return quat;
+}
+
+/*
+ * Matrix44 Methods
+ */
+
+Matrix44::Matrix44() {
+	*this = IDENTITY44;
+}
+
+/*
+ * Quaternion Methods
+ */
+
+Float3 Quaternion::AsEulerYawPitchRoll() {
+	float yaw, pitch, roll;
+
+	if ( x*y + z*w == 0.5 ) {
+		//North Pole
+		yaw = 2 * atan2(x,w);
+		pitch = asin(2*x*y + 2*z*w);
+		roll = 0.0f;
+	}
+	else if ( x*y + z*w == -0.5 ) {
+		//South Pole
+		yaw =  -2 * atan2(x,w);
+		pitch = asin(2*x*y + 2*z*w);
+		roll = 0.0f;
+	}
+	else {
+		yaw = atan2(2*y*w-2*x*z , 1 - 2*y*y - 2*z*z);
+		pitch = asin(2*x*y + 2*z*w);
+		roll = atan2(2*x*w-2*y*z , 1 - 2*x*x - 2*z*z);
+	}
+
+	return Float3( yaw, pitch, roll );
+}
+
+Matrix33 Quaternion::AsMatrix() {
+	Matrix33 m;
 
 	float w2 = w * w;
 	float x2 = x * x;
@@ -236,65 +374,76 @@ void QuatToMatrix( Quaternion const & quat, ostream & out ) {
 	m[2][1] = 2.0f*y*z + 2.0f*w*x;
 	m[2][2] = w2 - x2 - y2 + z2;
 
+	return m;
+
+	//out << endl
+	//	<< "         |" << setw(8) << m[0][0] << "," << setw(8) << m[0][1] << "," << setw(8) << m[0][2] << " |" << endl
+	//	<< "         |" << setw(8) << m[1][0] << "," << setw(8) << m[1][1] << "," << setw(8) << m[1][2] << " |" << endl
+	//	<< "         |" << setw(8) << m[2][0] << "," << setw(8) << m[2][1] << "," << setw(8) << m[2][2] << " |" << endl;
+
+	//float pi = 3.141592653589793f;
+	//out << "      Euler Angles:" << endl
+	//	<< "         X:  " << atan2( m[1][2], m[2][2] ) / pi * 180.0 << endl
+	//	<< "         Y:  " << asin( -m[0][2] ) / pi * 180.0 << endl
+	//	<< "         Z:  " << atan2( m[0][1], m[0][0] ) / pi * 180.0 << endl;
+}
+
+/*
+ * ostream functions for printing with cout
+ */
+
+ostream & operator<<( ostream & out, TexCoord const & val ) {
+	return out << "(" << setw(6) << val.u << "," << setw(6) << val.v << ")";
+}
+
+ostream & operator<<( ostream & out, Triangle const & val ) {
+	return out << "{" << setw(6) << val.v1 << "," << setw(6) << val.v2 << "," << setw(6) << val.v3 << "}";
+}
+
+ostream & operator<<( ostream & out, Vector3 const & val ) {
+	return out << "(" << setw(6) << val.x << "," << setw(6) << val.y << "," << setw(6) << val.z << ")";
+}
+
+ostream & operator<<( ostream & out, Float2 const & val ) {
+	return out << "{" << setw(6) << val.data[0] << "," << setw(6) << val.data[1] << "}";
+}
+
+ostream & operator<<( ostream & out, Matrix22 const & val ) {
 	out << endl
-		<< "         |" << setw(8) << m[0][0] << "," << setw(8) << m[0][1] << "," << setw(8) << m[0][2] << " |" << endl
-		<< "         |" << setw(8) << m[1][0] << "," << setw(8) << m[1][1] << "," << setw(8) << m[1][2] << " |" << endl
-		<< "         |" << setw(8) << m[2][0] << "," << setw(8) << m[2][1] << "," << setw(8) << m[2][2] << " |" << endl;
-
-	float pi = 3.141592653589793f;
-	out << "      Euler Angles:" << endl
-		<< "         X:  " << atan2( m[1][2], m[2][2] ) / pi * 180.0 << endl
-		<< "         Y:  " << asin( -m[0][2] ) / pi * 180.0 << endl
-		<< "         Z:  " << atan2( m[0][1], m[0][0] ) / pi * 180.0 << endl;
-}
-
-void QuatToEuler( Quaternion const & quat, ostream & out ) {
-	float w = quat.w;
-	float x = quat.x;
-	float y = quat.y;
-	float z = quat.z;
-
-//heading = atan2(2*qy*qw-2*qx*qz , 1 - 2*qy2 - 2*qz2)
-//attitude = asin(2*qx*qy + 2*qz*qw)
-//bank = atan2(2*qx*qw-2*qy*qz , 1 - 2*qx2 - 2*qz2)
-//
-//except when qx*qy + qz*qw = 0.5 (north pole)
-//which gives:
-//heading = 2 * atan2(x,w)
-//bank = 0
-//and when qx*qy + qz*qw = -0.5 (south pole)
-//which gives:
-//heading = -2 * atan2(x,w)
-//bank = 0 
-
-	float h, a, b;
-	float pi = 3.141592653589793f;
+		<< "   |" << setw(6) << val[0][0] << "," << setw(6) << val[0][1] << " |" << endl
+		<< "   |" << setw(6) << val[1][0] << "," << setw(6) << val[1][1] << " |";
+	return out;
+}
 
-	if ( x*y + z*w == 0.5 ) {
-		//North Pole
-		h = 2 * atan2(x,w);
-		a = asin(2*x*y + 2*z*w);
-		b = 0.0f;
-	}
-	else if ( x*y + z*w == -0.5 ) {
-		//South Pole
-		h =  -2 * atan2(x,w);
-		a = asin(2*x*y + 2*z*w);
-		b = 0.0f;
-	}
-	else {
-		h = atan2(2*y*w-2*x*z , 1 - 2*y*y - 2*z*z);
-		a = asin(2*x*y + 2*z*w);
-		b = atan2(2*x*w-2*y*z , 1 - 2*x*x - 2*z*z);
-	}
+ostream & operator<<( ostream & out, Float3 const & val ) {
+	return out << "{" << setw(6) << val.data[0] << "," << setw(6) << val.data[1] << "," << setw(6) << val.data[2] << "}";
+}
 
-	h = h / pi * 180;
-	a = a / pi * 180;
-	b = b / pi * 180;
+ostream & operator<<( ostream & out, Matrix33 const & val ) {
+	out << endl
+		<< "   |" << setw(6) << val[0][0] << "," << setw(6) << val[0][1] << "," << setw(6) << val[0][2] << " |" << endl
+		<< "   |" << setw(6) << val[1][0] << "," << setw(6) << val[1][1] << "," << setw(6) << val[1][2] << " |" << endl
+		<< "   |" << setw(6) << val[2][0] << "," << setw(6) << val[2][1] << "," << setw(6) << val[2][2] << " |";
+	return out;
+}
+
+ostream & operator<<( ostream & out, Float4 const & val ) {
+	return out << "{" << setw(6) << val.data[0] << "," << setw(6) << val.data[1] << "," << setw(6) << val.data[2] << "," << setw(6) << val.data[3] << "}";
+}
 
+ostream & operator<<( ostream & out, Matrix44 const & val ) {
 	out << endl
-		<< "         Heading:  " << h << endl
-		<< "         Attitude:  " << a << endl
-		<< "         Bank:  " << b << endl;
-	
+		<< "   |" << setw(6) << val[0][0] << "," << setw(6) << val[0][1] << "," << setw(6) << val[0][2] << "," << setw(6) << val[0][3] << " |" << endl
+		<< "   |" << setw(6) << val[1][0] << "," << setw(6) << val[1][1] << "," << setw(6) << val[1][2] << "," << setw(6) << val[1][3] << " |" << endl
+		<< "   |" << setw(6) << val[2][0] << "," << setw(6) << val[2][1] << "," << setw(6) << val[2][2] << "," << setw(6) << val[2][3] << " |" << endl
+		<< "   |" << setw(6) << val[3][0] << "," << setw(6) << val[3][1] << "," << setw(6) << val[3][2] << "," << setw(6) << val[3][3] << " |";
+	return out;
+}
+
+ostream & operator<<( ostream & out, Color4 const & val ) {
+	return out << "R:" << setw(6) << val.r << " G:" << setw(6) << val.g << " B:" << setw(6) << val.b << " A:" << setw(6) << val.a << "}";
+}
+
+ostream & operator<<( ostream & out, Quaternion const & val ) {
+	return out << "[" << setw(6) << val.w << ",(" << setw(6) << val.x << "," << setw(6) << val.y << "," << setw(6) << val.z << ")]";
 }
diff --git a/nif_math.h b/nif_math.h
index 8d30a887..7642c4e5 100644
--- a/nif_math.h
+++ b/nif_math.h
@@ -36,17 +36,734 @@ POSSIBILITY OF SUCH DAMAGE. */
 
 #include <cmath>
 #include <iostream>
-#include "niflib.h"
-#include "NIF_IO.h"
+//#include "NIF_IO.h"
 using namespace std;
 
-//struct Quat {
-//	float w, x, y, z;
-//};
+#ifndef PI
+#define PI 3.14159265358979323846f
+#endif
+
+//Forward declarations
+struct TexCoord;
+struct Triangle;
+struct Vector3;
+struct Color4;
+struct Quaternion;
+struct Float2;
+struct Matrix22;
+struct Float3;
+struct Matrix33;
+struct Float4;
+struct Matrix44;
+
+/*! Stores 2D texture coordinates – two floating point variables, u and v. */
+struct TexCoord {
+	float u; /*!< The U value in this coordinate pair. */ 
+	float v; /*!< The V value in this coordinate pair. */ 
+
+	/*! Default constructor	*/
+	TexCoord() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param u The value to set U to.
+	 * \param v The value to set V to.
+	 */
+	TexCoord(float u, float v) {
+		this->u = u;
+		this->v = v;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param u The value to set U to.
+	 * \param v The value to set V to.
+	 */
+	void Set(float u, float v) {
+		this->u = u;
+		this->v = v;
+	}
+};
+
+/*! Represents a triangle face formed between three vertices referenced by number */
+struct Triangle {
+	short v1; /*!< The index of the first vertex. */ 
+	short v2; /*!< The index of the second vertex. */ 
+	short v3; /*!< The index of the third vertex. */ 
+
+	/*! Default constructor */
+	Triangle() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param v1 The index of the first vertex.
+	 * \param v2 The index of the second vertex.
+	 * \param v3 The index of the third vertex.
+	 */
+	Triangle(short v1, short v2, short v3) {
+		this->v1 = v1;
+		this->v2 = v2;
+		this->v3 = v3;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param v1 The index of the first vertex.
+	 * \param v2 The index of the second vertex.
+	 * \param v3 The index of the third vertex.
+	 */
+	void Set(short v1, short v2, short v3) {
+		this->v1 = v1;
+		this->v2 = v2;
+		this->v3 = v3;
+	}
+
+	/*! The bracket operator makes it possible to use this structure like a C++ array.
+	 * \param n The index into the data array.  Should be 0, 1, or 2.
+	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
+	 */
+	short & operator[](int n) {
+		switch (n) {
+			case 0: return v1; break;
+			case 1: return v2; break;
+			case 2: return v3; break;
+			default: throw std::out_of_range("Index out of range for Triangle");
+		};
+	}
+	short operator[](int n) const {
+		switch (n) {
+			case 0: return v1; break;
+			case 1: return v2; break;
+			case 2: return v3; break;
+			default: throw std::out_of_range("Index out of range for Triangle");
+		};
+	}
+};
+
+/*!Represents a position or direction in 3D space*/
+struct Vector3 {
+	float x; /*!< The X component of this vector. */ 
+	float y; /*!< The Y component of this vector. */ 
+	float z; /*!< The Z component of this vector. */ 
+
+	/*!Default constructor.*/
+	Vector3() { x = y = z = 0.0f; }
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param x The value to set X to.
+	 * \param y The value to set Y to.
+	 * \param z The value to set Z to.
+	 */
+	Vector3(float x, float y, float z) {
+		this->x = x;
+		this->y = y;
+		this->z = z;
+	}
+
+	/*! This constructor can be used to initialize this Vector3 with another Vector3
+	 * \param v The Vector3 to construct this one from
+	 */
+	Vector3( const Vector3 & v) { x = v.x; y = v.y; z = v.z; }
+	
+	/*! Destructor */
+	~Vector3() {}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param x The value to set X to.
+	 * \param y The value to set Y to.
+	 * \param z The value to set Z to.
+	 */
+	void Set(float x, float y, float z) {
+		this->x = x;
+		this->y = y;
+		this->z = z;
+	}
+
+	/* This function calculates the magnitude of this vector
+	 * \return the magnitude of the vector; its length.
+	 */
+	float Magnitude() const;
+
+	/* This function returns a normalization of this vector.  A vecctor pointing in the same
+	 * direction but with a magnitude, or length, of 1.
+	 */
+	Vector3 Normalized() const;
+
+	/* Allows the addition of vectors.  Each component, x, y, y, is added with
+	 * the same component of the other vector.
+	 * \return The result of the addition.
+	 */
+	Vector3 operator+( const Vector3 & rh ) const;
+
+	/* Adds the two vectors and then sets the result to the left-hand vector.
+	 * \return This vector is returned.
+	 */
+	Vector3 & operator+=( const Vector3 & rh );
+
+	/* Allows the subtraction of vectors.  Each component, x, y, y, is subtracted from
+	 * the same component of the other vector.
+	 * \return The result of the subtraction.
+	 */
+	Vector3 operator-( const Vector3 & rh ) const;
+
+	/* This operator subtracts the two vectors and then sets the result to the left-hand vector.
+	 * \return This vector is returned.
+	 */
+	Vector3 & operator-=( const Vector3 & rh);
+
+	/* Allows scaler multiplication, that is multipying all components of the
+	 * vector, x, y and z, by the same number.
+	 * \return The result of the multiplication.
+	 */
+	Vector3 operator*( const float & rh) const; //Scalar Multiply
+
+	/* Multipies a vector by a scalar and then sets the result to the left-hand vector.
+	 * \return This vector is returned.
+	 */
+	Vector3 & operator*=( const float & rh );
+
+	/* Allows scaler division, that is dividing all components of the
+	 * vector, x, y and z, by the same number.
+	 * \return The result of the division.
+	 */
+	Vector3 operator/( const float & rh ) const;
+
+	/* Divides a vector by a scalar and then sets the result to the left-hand vector.
+	 * \return This vector is returned.
+	 */
+	Vector3 & operator/=( const float & rh );
+
+	/* Sets the components of this Vector3 to those of another Vector3 
+	 * \return This vector is returned.
+	 */
+	Vector3 & operator=( const Vector3 & v ) { x = v.x; y = v.y; z = v.z;  return *this; }
+
+	/* Tests the equality of two Vector3 structures.  Vectors are considered equal if all
+	 * three components are equal.
+	 */
+	bool operator==( const Vector3 & rh ) const;
+
+	/* Computes the dot product of two vectors; the angle between two vectors.
+	 * \param rh The vector to perform the dot product with
+	 * \return The angle in radians between this vector and the one given
+	 */
+	float DotProduct( const Vector3 & rh ) const;
+
+	/* Computes the cross product of two vectors; a vector perpendicular to both of them.
+	 * \param The vector to perform the cross product with
+	 * \return A vector perpendicular to this vector and the one given
+	 */
+	Vector3 CrossProduct( const Vector3 & rh) const; //Cross Product
+
+
+	///* Multiplies this Vector with a 4x4 matrix
+	// * \param The 4x4 matrix to multiply this vector with. 
+	// * \return The new vector resulting from the multiplication.
+	// */
+	//Vector3 operator*( const Matrix44 & rh ) const;
+
+	///* Multiplies this Vector with a 4x4 matrix and sets the result to itself
+	// * \param The 4x4 matrix to multiply this vector with.
+	// * \return This vector is returned.
+	// */
+	//Vector3 & operator*=( const Matrix44 & rh );
+
+	friend ostream & operator<<( ostream & out, const Vector3 & rh );
+};
+
+/* Stores two floating point numbers.  Used as a row of a Matrix22 */
+struct Float2 {
+	float data[2]; /*!< The two floating point numbers stored as an array. */ 
+	
+	/*! The bracket operator makes it possible to use this structure like a C++ array.
+	 * \param n The index into the data array.  Should be 0 or 1.
+	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
+	 */
+	float & operator[](int n) {
+		return data[n];
+	}
+	float operator[](int n) const {
+		return data[n];
+	}
+
+	/*! Default constructor. */
+	Float2() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param f1 The value to set the first floating point number to.
+	 * \param f2 The value to set the second floating point number to.
+	 */
+	Float2( float f1, float f2 ) {
+		data[0] = f1;
+		data[1] = f2;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param f1 The value to set the first floating point number to.
+	 * \param f2 The value to set the second floating point number to.
+	 */
+	void Set( float f1, float f2 ) {
+		data[0] = f1;
+		data[1] = f2;
+	}
+
+	//Python Operator Overloads
+	float __getitem__(int n) {
+		if (n > 1 || n < 0)
+			throw std::out_of_range("Index out of range for MatrixRow3");
+        return data[n];
+    }
+	void __setitem__(int n, float value) {
+		if (n > 1 || n < 0)
+			throw std::out_of_range("Index out of range for MatrixRow3");
+		data[n] = value;
+	}
+};
+
+/*! Stores a 2 by 2 matrix used for bump maps. */
+struct Matrix22 {
+	Float2 rows[2];  /*!< The two rows of Float2 structures which hold two floating point numbers each. */ 
+	
+	/*! The bracket operator makes it possible to use this structure like a 2x2 C++ array.
+	 * \param n The index into the row array.  Should be 0 or 1.
+	 * \return The Float2 structure for the given row index by reference so it can be read or set via the bracket operator.
+	 */
+	Float2 & operator[](int n) {
+		return rows[n];
+	}
+	const Float2 & operator[](int n) const {
+		return rows[n];
+	}
+
+	/*! Default Constructor */
+	Matrix22() {}
+
+	/*! This constructor can be used to set all values in this matrix during initialization
+	 * \param m11 The value to set at row 1, column 1.
+	 * \param m12 The value to set at row 1, column 2.
+	 * \param m21 The value to set at row 2, column 1.
+	 * \param m22 The value to set at row 2, column 2.
+	 */
+	Matrix22(
+		float m11, float m12,
+		float m21, float m22
+	) {
+		rows[0][0] = m11; rows[0][1] = m12;
+		rows[1][0] = m21; rows[1][1] = m22;
+	}
+
+	/*! This function can be used to set all values in this matrix at the same time.
+	 * \param m11 The value to set at row 1, column 1.
+	 * \param m12 The value to set at row 1, column 2.
+	 * \param m21 The value to set at row 2, column 1.
+	 * \param m22 The value to set at row 2, column 2.
+	 */
+	void Set(
+		float m11, float m12,
+		float m21, float m22
+	) {
+		rows[0][0] = m11; rows[0][1] = m12;
+		rows[1][0] = m21; rows[1][1] = m22;
+	}
+
+	Quaternion AsQuaternion();
+
+	//Python Operator Overloads
+	Float2 & __getitem__(int n) {
+		if (n > 1 || n < 0)
+			throw std::out_of_range("Index out of range for MatrixRow3");
+        return rows[n];
+    }
+};
+
+/* Stores three floating point numbers.  Used as a row of a Matrix33 and to store the data in attr_vector3 and attr_color3 type attributes. */
+struct Float3 {
+	float data[3]; /*!< The three floating point numbers stored as an array. */ 
+
+	/*! The bracket operator makes it possible to use this structure like a C++ array.
+	 * \param n The index into the data array.  Should be 0, 1, or 2.
+	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
+	 */
+	float & operator[](int n) {
+		return data[n];
+	}
+	float operator[](int n) const {
+		return data[n];
+	}
+
+	/*!Default constructor.*/
+	Float3() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param f1 The value to set the first floating point number to.
+	 * \param f2 The value to set the second floating point number to.
+	 * \param f3 The value to set the third floating point number to.
+	 */
+	Float3( float f1, float f2, float f3 ) {
+		data[0] = f1;
+		data[1] = f2;
+		data[2] = f3;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param f1 The value to set the first floating point number to.
+	 * \param f2 The value to set the second floating point number to.
+	 * \param f3 The value to set the third floating point number to.
+	 */
+	void Set( float f1, float f2, float f3 ) {
+		data[0] = f1;
+		data[1] = f2;
+		data[2] = f3;
+	}
+
+	//Python Operator Overloads
+	float __getitem__(int n) {
+		if (n > 2 || n < 0)
+			throw std::out_of_range("Index out of range for Float3");
+		return data[n];
+	}
+	void __setitem__(int n, float value) {
+		if (n > 2 || n < 0)
+			throw std::out_of_range("Index out of range for Float3");
+		data[n] = value;
+	}
+};
+
+/*! Stores a 3 by 3 matrix used for rotation. */
+struct Matrix33 {
+	Float3 rows[3]; /*!< The three rows of Float3 structures which hold three floating point numbers each. */ 
+	
+	/*! The bracket operator makes it possible to use this structure like a 3x3 C++ array.
+	 * \param n The index into the row array.  Should be 0, 1, or 2.
+	 * \return The Float3 structure for the given row index by reference so it can be read or set via the bracket operator.
+	 */
+	Float3 & operator[](int n) {
+		return rows[n];
+	}
+	const Float3 & operator[](int n) const {
+		return rows[n];
+	}
+
+	/*! Default constructor. */
+	Matrix33() {}
+
+	/*! This constructor can be used to set all values in this matrix during initialization
+	 * \param m11 The value to set at row 1, column 1.
+	 * \param m12 The value to set at row 1, column 2.
+	 * \param m13 The value to set at row 1, column 3.
+	 * \param m21 The value to set at row 2, column 1.
+	 * \param m22 The value to set at row 2, column 2.
+	 * \param m23 The value to set at row 2, column 3.
+	 * \param m31 The value to set at row 3, column 1.
+	 * \param m32 The value to set at row 3, column 2.
+	 * \param m33 The value to set at row 3, column 3.
+	 */
+	Matrix33(
+		float m11, float m12, float m13,
+		float m21, float m22, float m23,
+		float m31, float m32, float m33
+	) {
+		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13;
+		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23;
+		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33;
+	}
+
+	/*! This function can be used to set all values in this matrix at the same time.
+	 * \param m11 The value to set at row 1, column 1.
+	 * \param m12 The value to set at row 1, column 2.
+	 * \param m13 The value to set at row 1, column 3.
+	 * \param m21 The value to set at row 2, column 1.
+	 * \param m22 The value to set at row 2, column 2.
+	 * \param m23 The value to set at row 2, column 3.
+	 * \param m31 The value to set at row 3, column 1.
+	 * \param m32 The value to set at row 3, column 2.
+	 * \param m33 The value to set at row 3, column 3.
+	 */
+	void Set(
+		float m11, float m12, float m13,
+		float m21, float m22, float m23,
+		float m31, float m32, float m33
+	) {
+		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13;
+		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23;
+		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33;
+	}
+
+	Quaternion AsQuaternion();
+
+	void AsFloatArr( float out[3][3] ) {
+		out[0][0] = rows[0][0]; out[0][1] = rows[0][1]; out[0][2] = rows[0][2];
+		out[1][0] = rows[1][0]; out[1][1] = rows[1][1]; out[1][2] = rows[1][2];
+		out[2][0] = rows[2][0]; out[2][1] = rows[2][1]; out[2][2] = rows[2][2];
+	}
+
+	//Python Operator Overloads
+	Float3 & __getitem__(int n) {
+		if (n > 2 || n < 0)
+			throw std::out_of_range("Index out of range for MatrixRow3");
+        return rows[n];
+    }
+};
+
+/* Stores four floating point numbers.  Used as a row of a Matrix44. */
+struct Float4 {
+	float data[4]; /*!< The four floating point numbers stored as an array. */ 
+
+	/*! The bracket operator makes it possible to use this structure like a C++ array.
+	 * \param n The index into the data array.  Should be 0, 1, 2, or 3.
+	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
+	 */
+	float & operator[](int n) {
+		return data[n];
+	}
+	float operator[](int n) const {
+		return data[n];
+	}
+
+	/*! Default Constructor.*/
+	Float4() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param f1 The value to set the first floating point number to.
+	 * \param f2 The value to set the second floating point number to.
+	 * \param f3 The value to set the third floating point number to.
+	 * \param f4 The value to set the fourth floating point number to.
+	 */
+	Float4( float f1, float f2, float f3, float f4 ) {
+		data[0] = f1;
+		data[1] = f2;
+		data[3] = f3;
+		data[4] = f4;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param f1 The value to set the first floating point number to.
+	 * \param f2 The value to set the second floating point number to.
+	 * \param f3 The value to set the third floating point number to.
+	 * \param f4 The value to set the fourth floating point number to.
+	 */
+	void Set( float f1, float f2, float f3, float f4 ) {
+		data[0] = f1;
+		data[1] = f2;
+		data[3] = f3;
+		data[4] = f4;
+	}
+
+	//Python Operator Overloads
+	float __getitem__(int n) {
+		if (n > 3 || n < 0)
+			throw std::out_of_range("Index out of range for Float4");
+        return data[n];
+    }
+	void __setitem__(int n, float value) {
+		if (n > 3 || n < 0)
+			throw std::out_of_range("Index out of range for Float4");
+		data[n] = value;
+	}
+};
+
+/*! Stores a 4 by 4 matrix used for combined transformations. */
+struct Matrix44 {
+	Float4 rows[4]; /*!< The three rows of Float3 structures which hold three floating point numbers each. */ 
+	
+	/*! The bracket operator makes it possible to use this structure like a 4x4 C++ array.
+	 * \param n The index into the row array.  Should be 0, 1, 2, or 3.
+	 * \return The Float4 structure for the given row index by reference so it can be read or set via the bracket operator.
+	 */
+	Float4 & operator[](int n) {
+		return rows[n];
+	}
+	Float4 const & operator[](int n) const {
+		return rows[n];
+	}
+
+	/*! Default constructor. Initializes Matrix to Identity. */
+	Matrix44();
+
+	/*! Copy constructor.  Initializes Matrix to another Matrix44.
+	 * \param The matrix to initialize this one to. 
+	 */
+	Matrix44( const Matrix44 & m ) { memcpy(rows, m.rows, sizeof(Float4) * 4); }
+
+	/*! This constructor can be used to set all values in this matrix during initialization
+	 * \param m11 The value to set at row 1, column 1.
+	 * \param m12 The value to set at row 1, column 2.
+	 * \param m13 The value to set at row 1, column 3.
+	 * \param m14 The value to set at row 1, column 4.
+	 * \param m21 The value to set at row 2, column 1.
+	 * \param m22 The value to set at row 2, column 2.
+	 * \param m23 The value to set at row 2, column 3.
+	 * \param m24 The value to set at row 2, column 4.
+	 * \param m31 The value to set at row 3, column 1.
+	 * \param m32 The value to set at row 3, column 2.
+	 * \param m33 The value to set at row 3, column 3.
+	 * \param m34 The value to set at row 3, column 4.
+	 * \param m41 The value to set at row 4, column 1.
+	 * \param m42 The value to set at row 4, column 2.
+	 * \param m43 The value to set at row 4, column 3.
+	 * \param m44 The value to set at row 4, column 4.
+	 */
+	Matrix44(
+		float m11, float m12, float m13, float m14,
+		float m21, float m22, float m23, float m24,
+		float m31, float m32, float m33, float m34,
+		float m41, float m42, float m43, float m44
+	) {
+		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13; rows[0][3] = m14;
+		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23; rows[1][3] = m24;
+		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33; rows[2][3] = m34;
+		rows[3][0] = m41; rows[3][1] = m42; rows[3][2] = m43; rows[3][3] = m44;
+	}
+
+	/*! This function can be used to set all values in this matrix at the same time.
+	 * \param m11 The value to set at row 1, column 1.
+	 * \param m12 The value to set at row 1, column 2.
+	 * \param m13 The value to set at row 1, column 3.
+	 * \param m14 The value to set at row 1, column 4.
+	 * \param m21 The value to set at row 2, column 1.
+	 * \param m22 The value to set at row 2, column 2.
+	 * \param m23 The value to set at row 2, column 3.
+	 * \param m24 The value to set at row 2, column 4.
+	 * \param m31 The value to set at row 3, column 1.
+	 * \param m32 The value to set at row 3, column 2.
+	 * \param m33 The value to set at row 3, column 3.
+	 * \param m34 The value to set at row 3, column 4.
+	 * \param m41 The value to set at row 4, column 1.
+	 * \param m42 The value to set at row 4, column 2.
+	 * \param m43 The value to set at row 4, column 3.
+	 * \param m44 The value to set at row 4, column 4.
+	 */
+	void Set(
+		float m11, float m12, float m13, float m14,
+		float m21, float m22, float m23, float m24,
+		float m31, float m32, float m33, float m34,
+		float m41, float m42, float m43, float m44
+	) {
+		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13; rows[0][3] = m14;
+		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23; rows[1][3] = m24;
+		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33; rows[2][3] = m34;
+		rows[3][0] = m41; rows[3][1] = m42; rows[3][2] = m43; rows[3][3] = m44;
+	}
+
+	//undocumented
+	void AsFloatArr( float out[4][4] ) {
+		out[0][0] = rows[0][0]; out[0][1] = rows[0][1]; out[0][2] = rows[0][2]; out[0][3] = rows[0][3];
+		out[1][0] = rows[1][0]; out[1][1] = rows[1][1]; out[1][2] = rows[1][2]; out[1][3] = rows[1][3];
+		out[2][0] = rows[2][0]; out[2][1] = rows[2][1]; out[2][2] = rows[2][2]; out[2][3] = rows[2][3];
+		out[3][0] = rows[3][0]; out[3][1] = rows[3][1]; out[3][2] = rows[3][2]; out[3][3] = rows[3][3];
+	}
+
+	//Python Operator Overloads
+	Float4 & __getitem__(int n) {
+		if (n > 3 || n < 0)
+			throw std::out_of_range("Index out of range for Matrix44");
+        return rows[n];
+    }
+};
+
+/*! The 4x4 identity matrix */
+const Matrix44 IDENTITY44( 1.0f, 0.0f, 0.0f, 0.0f,
+						   0.0f, 1.0f, 0.0f, 0.0f,
+						   0.0f, 0.0f, 1.0f, 0.0f,
+						   0.0f, 0.0f, 0.0f, 1.0f );
+
+/*! Stores a color along with alpha translucency */
+struct Color4 {
+	float r; /*!< The red component of this color.  Should be between 0.0f and 1.0f. */ 
+	float g; /*!< The green component of this color.  Should be between 0.0f and 1.0f. */ 
+	float b; /*!< The blue component of this color.  Should be between 0.0f and 1.0f. */ 
+	float a; /*!< The alpha translucency component of this color.  Should be between 0.0f and 1.0f. */ 
+
+	/*! Default constructor */
+	Color4() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param r The value to set the red component of this color to.  Should be between 0.0f and 1.0f.
+	 * \param g The value to set the green component of this color to. Should be between 0.0f and 1.0f.
+	 * \param b The value to set the blue component of this color to.  Should be between 0.0f and 1.0f.
+	 * \param a The value to set the alpha translucency component of this color to.  Should be between 0.0f and 1.0f.
+	 */
+	Color4(float r, float g, float b, float a = 1.0f) {
+		this->r = r;
+		this->g = g;
+		this->b = b;
+		this->a = a;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param r The value to set the red component of this color to.  Should be between 0.0f and 1.0f.
+	 * \param g The value to set the green component of this color to. Should be between 0.0f and 1.0f.
+	 * \param b The value to set the blue component of this color to.  Should be between 0.0f and 1.0f.
+	 * \param a The value to set the alpha translucency component of this color to.  Should be between 0.0f and 1.0f.
+	 */
+	void Set(float r, float g, float b, float a = 1.0f) {
+		this->r = r;
+		this->g = g;
+		this->b = b;
+		this->a = a;
+	}
+};
+
+/*! Represents a quaternion - a 4D extention of complex numbers used as an alternitive to matrices to represent rotation.*/
+struct Quaternion {
+	float w; /*!< The W scalar component of this Quaternion. */ 
+	float x; /*!< The X vector component of this Quaternion. */ 
+	float y; /*!< The Y vector component of this Quaternion. */ 
+	float z; /*!< The Z vector component of this Quaternion. */ 
+
+	/*! Default constructor. */
+	Quaternion() {}
+
+	/*! This constructor can be used to set all values in this structure during initialization
+	 * \param w The value to set the W scalar component of this quaternion to.
+	 * \param x The value to set the X vector component of this quaternion to.
+	 * \param y The value to set the Y vector component of this quaternion to.
+	 * \param z The value to set the Z vector component of this quaternion to.
+	 */
+	Quaternion(float w, float x, float y, float z) {
+		this->w = w;
+		this->x = x;
+		this->y = y;
+		this->z = z;
+	}
+
+	/*! This function can be used to set all values in the structure at the same time.
+	 * \param w The value to set the W scalar component of this quaternion to.
+	 * \param x The value to set the X vector component of this quaternion to.
+	 * \param y The value to set the Y vector component of this quaternion to.
+	 * \param z The value to set the Z vector component of this quaternion to.
+	 */
+	void Set(float w, float x, float y, float z) {
+		this->w = w;
+		this->x = x;
+		this->y = y;
+		this->z = z;
+	}
+
+	/*! This function returns a 3x3 matrix representation of the rotation stored in this quaternion.
+	 * \return a Matrix33 structure with an equivalent rotation to this quaternion.
+	 */
+	Matrix33 AsMatrix();
+
+	/*! This function returns a Euler Angle representation of the rotation stored in this quaternion.
+	 * The angles returned correspond to yaw, pitch, and roll and are in radiens.
+	 * \return a Float3 structure with the first value containing the yaw, the second the pitch,
+	 * and the third the roll.  The values are in radians.
+	 */
+	Float3 AsEulerYawPitchRoll();
+};
+
+//--ostream functions for printing with cout--//
+
+ostream & operator<<( ostream & out, TexCoord const & val );
+ostream & operator<<( ostream & out, Triangle const & val );
+ostream & operator<<( ostream & out, Float2 const & val );
+ostream & operator<<( ostream & out, Matrix22 const & val );
+ostream & operator<<( ostream & out, Float3 const & val );
+ostream & operator<<( ostream & out, Matrix33 const & val );
+ostream & operator<<( ostream & out, Float4 const & val );
+ostream & operator<<( ostream & out, Matrix44 const & val );
+ostream & operator<<( ostream & out, Color4 const & val );
+ostream & operator<<( ostream & out, Quaternion const & val );
+
+
 
-void QuatToMatrix( Quaternion const & quat, ostream & out );
-void QuatToEuler( Quaternion const & quat, ostream & out );
-Vector3 MultVector3( Vector3 const & a, Vector3 const & b);
 Matrix33 MultMatrix33( Matrix33 const & a, Matrix33 const & b );
 Matrix44 MultMatrix44( Matrix44 const & a, Matrix44 const & b );
 float DetMatrix33( Matrix33 const & m );
@@ -57,6 +774,5 @@ void SetIdentity33( Matrix33 & m );
 void SetIdentity44( Matrix44 & m );
 void PrintMatrix33( Matrix33 const & m, ostream & out );
 void PrintMatrix44( Matrix44 const & m, ostream & out );
-Quaternion MatrixToQuat( Matrix33 const & m );
 
 #endif
diff --git a/niflib.h b/niflib.h
index 46034722..8f04580c 100644
--- a/niflib.h
+++ b/niflib.h
@@ -47,6 +47,7 @@ POSSIBILITY OF SUCH DAMAGE. */
 #include <vector>
 #include <list>
 #include <map>
+#include "nif_math.h"
 using namespace std;
 
 //--Forward Declarations of Classes & Structs--//
@@ -798,573 +799,6 @@ IPosData const * QueryPosData ( blk_ref const & block );
 
 //--Simple Structures--//
 
-/*! Stores 2D texture coordinates – two floating point variables, u and v. */
-struct TexCoord {
-	float u; /*!< The U value in this coordinate pair. */ 
-	float v; /*!< The V value in this coordinate pair. */ 
-
-	/*! Default constructor	*/
-	TexCoord() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param u The value to set U to.
-	 * \param v The value to set V to.
-	 */
-	TexCoord(float u, float v) {
-		this->u = u;
-		this->v = v;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param u The value to set U to.
-	 * \param v The value to set V to.
-	 */
-	void Set(float u, float v) {
-		this->u = u;
-		this->v = v;
-	}
-};
-
-/*! Represents a triangle face formed between three vertices referenced by number */
-struct Triangle {
-	short v1; /*!< The index of the first vertex. */ 
-	short v2; /*!< The index of the second vertex. */ 
-	short v3; /*!< The index of the third vertex. */ 
-
-	/*! Default constructor */
-	Triangle() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param v1 The index of the first vertex.
-	 * \param v2 The index of the second vertex.
-	 * \param v3 The index of the third vertex.
-	 */
-	Triangle(short v1, short v2, short v3) {
-		this->v1 = v1;
-		this->v2 = v2;
-		this->v3 = v3;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param v1 The index of the first vertex.
-	 * \param v2 The index of the second vertex.
-	 * \param v3 The index of the third vertex.
-	 */
-	void Set(short v1, short v2, short v3) {
-		this->v1 = v1;
-		this->v2 = v2;
-		this->v3 = v3;
-	}
-
-	/*! The bracket operator makes it possible to use this structure like a C++ array.
-	 * \param n The index into the data array.  Should be 0, 1, or 2.
-	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
-	 */
-	short & operator[](int n) {
-		switch (n) {
-			case 0: return v1; break;
-			case 1: return v2; break;
-			case 2: return v3; break;
-			default: throw std::out_of_range("Index out of range for Triangle");
-		};
-	}
-	short operator[](int n) const {
-		switch (n) {
-			case 0: return v1; break;
-			case 1: return v2; break;
-			case 2: return v3; break;
-			default: throw std::out_of_range("Index out of range for Triangle");
-		};
-	}
-};
-
-/*!Represents a position or direction in 3D space*/
-struct Vector3 {
-	float x; /*!< The X component of this vector. */ 
-	float y; /*!< The Y component of this vector. */ 
-	float z; /*!< The Z component of this vector. */ 
-
-	/*!Default constructor.*/
-	Vector3() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param x The value to set X to.
-	 * \param y The value to set Y to.
-	 * \param z The value to set Z to.
-	 */
-	Vector3(float x, float y, float z) {
-		this->x = x;
-		this->y = y;
-		this->z = z;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param x The value to set X to.
-	 * \param y The value to set Y to.
-	 * \param z The value to set Z to.
-	 */
-	void Set(float x, float y, float z) {
-		this->x = x;
-		this->y = y;
-		this->z = z;
-	}
-};
-
-/* Stores two floating point numbers.  Used as a row of a Matrix22 */
-struct Float2 {
-	float data[2]; /*!< The two floating point numbers stored as an array. */ 
-	
-	/*! The bracket operator makes it possible to use this structure like a C++ array.
-	 * \param n The index into the data array.  Should be 0 or 1.
-	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
-	 */
-	float & operator[](int n) {
-		return data[n];
-	}
-	float operator[](int n) const {
-		return data[n];
-	}
-
-	/*! Default constructor. */
-	Float2() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param f1 The value to set the first floating point number to.
-	 * \param f2 The value to set the second floating point number to.
-	 */
-	Float2( float f1, float f2 ) {
-		data[0] = f1;
-		data[1] = f2;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param f1 The value to set the first floating point number to.
-	 * \param f2 The value to set the second floating point number to.
-	 */
-	void Set( float f1, float f2 ) {
-		data[0] = f1;
-		data[1] = f2;
-	}
-
-	//Python Operator Overloads
-	float __getitem__(int n) {
-		if (n > 1 || n < 0)
-			throw std::out_of_range("Index out of range for MatrixRow3");
-        return data[n];
-    }
-	void __setitem__(int n, float value) {
-		if (n > 1 || n < 0)
-			throw std::out_of_range("Index out of range for MatrixRow3");
-		data[n] = value;
-	}
-};
-
-/*! Stores a 2 by 2 matrix used for bump maps. */
-struct Matrix22 {
-	Float2 rows[2];  /*!< The two rows of Float2 structures which hold two floating point numbers each. */ 
-	
-	/*! The bracket operator makes it possible to use this structure like a 2x2 C++ array.
-	 * \param n The index into the row array.  Should be 0 or 1.
-	 * \return The Float2 structure for the given row index by reference so it can be read or set via the bracket operator.
-	 */
-	Float2 & operator[](int n) {
-		return rows[n];
-	}
-	const Float2 & operator[](int n) const {
-		return rows[n];
-	}
-
-	/*! Default Constructor */
-	Matrix22() {}
-
-	/*! This constructor can be used to set all values in this matrix during initialization
-	 * \param m11 The value to set at row 1, column 1.
-	 * \param m12 The value to set at row 1, column 2.
-	 * \param m21 The value to set at row 2, column 1.
-	 * \param m22 The value to set at row 2, column 2.
-	 */
-	Matrix22(
-		float m11, float m12,
-		float m21, float m22
-	) {
-		rows[0][0] = m11; rows[0][1] = m12;
-		rows[1][0] = m21; rows[1][1] = m22;
-	}
-
-	/*! This function can be used to set all values in this matrix at the same time.
-	 * \param m11 The value to set at row 1, column 1.
-	 * \param m12 The value to set at row 1, column 2.
-	 * \param m21 The value to set at row 2, column 1.
-	 * \param m22 The value to set at row 2, column 2.
-	 */
-	void Set(
-		float m11, float m12,
-		float m21, float m22
-	) {
-		rows[0][0] = m11; rows[0][1] = m12;
-		rows[1][0] = m21; rows[1][1] = m22;
-	}
-
-	//Python Operator Overloads
-	Float2 & __getitem__(int n) {
-		if (n > 1 || n < 0)
-			throw std::out_of_range("Index out of range for MatrixRow3");
-        return rows[n];
-    }
-};
-
-/* Stores three floating point numbers.  Used as a row of a Matrix33 and to store the data in attr_vector3 and attr_color3 type attributes. */
-struct Float3 {
-	float data[3]; /*!< The three floating point numbers stored as an array. */ 
-
-	/*! The bracket operator makes it possible to use this structure like a C++ array.
-	 * \param n The index into the data array.  Should be 0, 1, or 2.
-	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
-	 */
-	float & operator[](int n) {
-		return data[n];
-	}
-	float operator[](int n) const {
-		return data[n];
-	}
-
-	/*!Default constructor.*/
-	Float3() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param f1 The value to set the first floating point number to.
-	 * \param f2 The value to set the second floating point number to.
-	 * \param f3 The value to set the third floating point number to.
-	 */
-	Float3( float f1, float f2, float f3 ) {
-		data[0] = f1;
-		data[1] = f2;
-		data[2] = f3;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param f1 The value to set the first floating point number to.
-	 * \param f2 The value to set the second floating point number to.
-	 * \param f3 The value to set the third floating point number to.
-	 */
-	void Set( float f1, float f2, float f3 ) {
-		data[0] = f1;
-		data[1] = f2;
-		data[2] = f3;
-	}
-
-	//Python Operator Overloads
-	float __getitem__(int n) {
-		if (n > 2 || n < 0)
-			throw std::out_of_range("Index out of range for Float3");
-		return data[n];
-	}
-	void __setitem__(int n, float value) {
-		if (n > 2 || n < 0)
-			throw std::out_of_range("Index out of range for Float3");
-		data[n] = value;
-	}
-};
-
-/*! Stores a 3 by 3 matrix used for rotation. */
-struct Matrix33 {
-	Float3 rows[3]; /*!< The three rows of Float3 structures which hold three floating point numbers each. */ 
-	
-	/*! The bracket operator makes it possible to use this structure like a 3x3 C++ array.
-	 * \param n The index into the row array.  Should be 0, 1, or 2.
-	 * \return The Float3 structure for the given row index by reference so it can be read or set via the bracket operator.
-	 */
-	Float3 & operator[](int n) {
-		return rows[n];
-	}
-	const Float3 & operator[](int n) const {
-		return rows[n];
-	}
-
-	/*! Default constructor. */
-	Matrix33() {}
-
-	/*! This constructor can be used to set all values in this matrix during initialization
-	 * \param m11 The value to set at row 1, column 1.
-	 * \param m12 The value to set at row 1, column 2.
-	 * \param m13 The value to set at row 1, column 3.
-	 * \param m21 The value to set at row 2, column 1.
-	 * \param m22 The value to set at row 2, column 2.
-	 * \param m23 The value to set at row 2, column 3.
-	 * \param m31 The value to set at row 3, column 1.
-	 * \param m32 The value to set at row 3, column 2.
-	 * \param m33 The value to set at row 3, column 3.
-	 */
-	Matrix33(
-		float m11, float m12, float m13,
-		float m21, float m22, float m23,
-		float m31, float m32, float m33
-	) {
-		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13;
-		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23;
-		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33;
-	}
-
-	/*! This function can be used to set all values in this matrix at the same time.
-	 * \param m11 The value to set at row 1, column 1.
-	 * \param m12 The value to set at row 1, column 2.
-	 * \param m13 The value to set at row 1, column 3.
-	 * \param m21 The value to set at row 2, column 1.
-	 * \param m22 The value to set at row 2, column 2.
-	 * \param m23 The value to set at row 2, column 3.
-	 * \param m31 The value to set at row 3, column 1.
-	 * \param m32 The value to set at row 3, column 2.
-	 * \param m33 The value to set at row 3, column 3.
-	 */
-	void Set(
-		float m11, float m12, float m13,
-		float m21, float m22, float m23,
-		float m31, float m32, float m33
-	) {
-		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13;
-		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23;
-		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33;
-	}
-
-	void AsFloatArr( float out[3][3] ) {
-		out[0][0] = rows[0][0]; out[0][1] = rows[0][1]; out[0][2] = rows[0][2];
-		out[1][0] = rows[1][0]; out[1][1] = rows[1][1]; out[1][2] = rows[1][2];
-		out[2][0] = rows[2][0]; out[2][1] = rows[2][1]; out[2][2] = rows[2][2];
-	}
-
-	//Python Operator Overloads
-	Float3 & __getitem__(int n) {
-		if (n > 2 || n < 0)
-			throw std::out_of_range("Index out of range for MatrixRow3");
-        return rows[n];
-    }
-};
-
-/* Stores four floating point numbers.  Used as a row of a Matrix44. */
-struct Float4 {
-	float data[4]; /*!< The four floating point numbers stored as an array. */ 
-
-	/*! The bracket operator makes it possible to use this structure like a C++ array.
-	 * \param n The index into the data array.  Should be 0, 1, 2, or 3.
-	 * \return The value at the given array index by reference so it can be read or set via the bracket operator.
-	 */
-	float & operator[](int n) {
-		return data[n];
-	}
-	float operator[](int n) const {
-		return data[n];
-	}
-
-	/*! Default Constructor.*/
-	Float4() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param f1 The value to set the first floating point number to.
-	 * \param f2 The value to set the second floating point number to.
-	 * \param f3 The value to set the third floating point number to.
-	 * \param f4 The value to set the fourth floating point number to.
-	 */
-	Float4( float f1, float f2, float f3, float f4 ) {
-		data[0] = f1;
-		data[1] = f2;
-		data[3] = f3;
-		data[4] = f4;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param f1 The value to set the first floating point number to.
-	 * \param f2 The value to set the second floating point number to.
-	 * \param f3 The value to set the third floating point number to.
-	 * \param f4 The value to set the fourth floating point number to.
-	 */
-	void Set( float f1, float f2, float f3, float f4 ) {
-		data[0] = f1;
-		data[1] = f2;
-		data[3] = f3;
-		data[4] = f4;
-	}
-
-	//Python Operator Overloads
-	float __getitem__(int n) {
-		if (n > 3 || n < 0)
-			throw std::out_of_range("Index out of range for Float4");
-        return data[n];
-    }
-	void __setitem__(int n, float value) {
-		if (n > 3 || n < 0)
-			throw std::out_of_range("Index out of range for Float4");
-		data[n] = value;
-	}
-};
-
-/*! Stores a 4 by 4 matrix used for combined transformations. */
-struct Matrix44 {
-	Float4 rows[4]; /*!< The three rows of Float3 structures which hold three floating point numbers each. */ 
-	
-	/*! The bracket operator makes it possible to use this structure like a 4x4 C++ array.
-	 * \param n The index into the row array.  Should be 0, 1, 2, or 3.
-	 * \return The Float4 structure for the given row index by reference so it can be read or set via the bracket operator.
-	 */
-	Float4 & operator[](int n) {
-		return rows[n];
-	}
-	Float4 const & operator[](int n) const {
-		return rows[n];
-	}
-
-	/*! Default constructor. */
-	Matrix44() {}
-
-	/*! This constructor can be used to set all values in this matrix during initialization
-	 * \param m11 The value to set at row 1, column 1.
-	 * \param m12 The value to set at row 1, column 2.
-	 * \param m13 The value to set at row 1, column 3.
-	 * \param m14 The value to set at row 1, column 4.
-	 * \param m21 The value to set at row 2, column 1.
-	 * \param m22 The value to set at row 2, column 2.
-	 * \param m23 The value to set at row 2, column 3.
-	 * \param m24 The value to set at row 2, column 4.
-	 * \param m31 The value to set at row 3, column 1.
-	 * \param m32 The value to set at row 3, column 2.
-	 * \param m33 The value to set at row 3, column 3.
-	 * \param m34 The value to set at row 3, column 4.
-	 * \param m41 The value to set at row 4, column 1.
-	 * \param m42 The value to set at row 4, column 2.
-	 * \param m43 The value to set at row 4, column 3.
-	 * \param m44 The value to set at row 4, column 4.
-	 */
-	Matrix44(
-		float m11, float m12, float m13, float m14,
-		float m21, float m22, float m23, float m24,
-		float m31, float m32, float m33, float m34,
-		float m41, float m42, float m43, float m44
-	) {
-		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13; rows[0][3] = m14;
-		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23; rows[1][3] = m24;
-		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33; rows[2][3] = m34;
-		rows[3][0] = m41; rows[3][1] = m42; rows[3][2] = m43; rows[3][3] = m44;
-	}
-
-	/*! This function can be used to set all values in this matrix at the same time.
-	 * \param m11 The value to set at row 1, column 1.
-	 * \param m12 The value to set at row 1, column 2.
-	 * \param m13 The value to set at row 1, column 3.
-	 * \param m14 The value to set at row 1, column 4.
-	 * \param m21 The value to set at row 2, column 1.
-	 * \param m22 The value to set at row 2, column 2.
-	 * \param m23 The value to set at row 2, column 3.
-	 * \param m24 The value to set at row 2, column 4.
-	 * \param m31 The value to set at row 3, column 1.
-	 * \param m32 The value to set at row 3, column 2.
-	 * \param m33 The value to set at row 3, column 3.
-	 * \param m34 The value to set at row 3, column 4.
-	 * \param m41 The value to set at row 4, column 1.
-	 * \param m42 The value to set at row 4, column 2.
-	 * \param m43 The value to set at row 4, column 3.
-	 * \param m44 The value to set at row 4, column 4.
-	 */
-	void Set(
-		float m11, float m12, float m13, float m14,
-		float m21, float m22, float m23, float m24,
-		float m31, float m32, float m33, float m34,
-		float m41, float m42, float m43, float m44
-	) {
-		rows[0][0] = m11; rows[0][1] = m12; rows[0][2] = m13; rows[0][3] = m14;
-		rows[1][0] = m21; rows[1][1] = m22; rows[1][2] = m23; rows[1][3] = m24;
-		rows[2][0] = m31; rows[2][1] = m32; rows[2][2] = m33; rows[2][3] = m34;
-		rows[3][0] = m41; rows[3][1] = m42; rows[3][2] = m43; rows[3][3] = m44;
-	}
-
-	//undocumented
-	void AsFloatArr( float out[4][4] ) {
-		out[0][0] = rows[0][0]; out[0][1] = rows[0][1]; out[0][2] = rows[0][2]; out[0][3] = rows[0][3];
-		out[1][0] = rows[1][0]; out[1][1] = rows[1][1]; out[1][2] = rows[1][2]; out[1][3] = rows[1][3];
-		out[2][0] = rows[2][0]; out[2][1] = rows[2][1]; out[2][2] = rows[2][2]; out[2][3] = rows[2][3];
-		out[3][0] = rows[3][0]; out[3][1] = rows[3][1]; out[3][2] = rows[3][2]; out[3][3] = rows[3][3];
-	}
-
-	//Python Operator Overloads
-	Float4 & __getitem__(int n) {
-		if (n > 3 || n < 0)
-			throw std::out_of_range("Index out of range for Matrix44");
-        return rows[n];
-    }
-};
-
-/*! Stores a color along with alpha translucency */
-struct Color4 {
-	float r; /*!< The red component of this color.  Should be between 0.0f and 1.0f. */ 
-	float g; /*!< The green component of this color.  Should be between 0.0f and 1.0f. */ 
-	float b; /*!< The blue component of this color.  Should be between 0.0f and 1.0f. */ 
-	float a; /*!< The alpha translucency component of this color.  Should be between 0.0f and 1.0f. */ 
-
-	/*! Default constructor */
-	Color4() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param r The value to set the red component of this color to.  Should be between 0.0f and 1.0f.
-	 * \param g The value to set the green component of this color to. Should be between 0.0f and 1.0f.
-	 * \param b The value to set the blue component of this color to.  Should be between 0.0f and 1.0f.
-	 * \param a The value to set the alpha translucency component of this color to.  Should be between 0.0f and 1.0f.
-	 */
-	Color4(float r, float g, float b, float a = 1.0f) {
-		this->r = r;
-		this->g = g;
-		this->b = b;
-		this->a = a;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param r The value to set the red component of this color to.  Should be between 0.0f and 1.0f.
-	 * \param g The value to set the green component of this color to. Should be between 0.0f and 1.0f.
-	 * \param b The value to set the blue component of this color to.  Should be between 0.0f and 1.0f.
-	 * \param a The value to set the alpha translucency component of this color to.  Should be between 0.0f and 1.0f.
-	 */
-	void Set(float r, float g, float b, float a = 1.0f) {
-		this->r = r;
-		this->g = g;
-		this->b = b;
-		this->a = a;
-	}
-};
-
-/*! Represents a quaternion - a 4D extention of complex numbers used as an alternitive to matrices to represent rotation.*/
-struct Quaternion {
-	float w; /*!< The W scalar component of this Quaternion. */ 
-	float x; /*!< The X vector component of this Quaternion. */ 
-	float y; /*!< The Y vector component of this Quaternion. */ 
-	float z; /*!< The Z vector component of this Quaternion. */ 
-
-	/*! Default constructor. */
-	Quaternion() {}
-
-	/*! This constructor can be used to set all values in this structure during initialization
-	 * \param w The value to set the W scalar component of this quaternion to.
-	 * \param x The value to set the X vector component of this quaternion to.
-	 * \param y The value to set the Y vector component of this quaternion to.
-	 * \param z The value to set the Z vector component of this quaternion to.
-	 */
-	Quaternion(float w, float x, float y, float z) {
-		this->w = w;
-		this->x = x;
-		this->y = y;
-		this->z = z;
-	}
-
-	/*! This function can be used to set all values in the structure at the same time.
-	 * \param w The value to set the W scalar component of this quaternion to.
-	 * \param x The value to set the X vector component of this quaternion to.
-	 * \param y The value to set the Y vector component of this quaternion to.
-	 * \param z The value to set the Z vector component of this quaternion to.
-	 */
-	void Set(float w, float x, float y, float z) {
-		this->w = w;
-		this->x = x;
-		this->y = y;
-		this->z = z;
-	}
-};
-
 /*! Represents a bounding box - the smallest rectangular shape that a particular node can fit inside. */
 struct BoundingBox {
 	bool isUsed; /*!< Determines whether this bounding box is used or not.  If this value is true, the other members of this structure are significant.  If false, they are ignored. */ 
diff --git a/niflib_internal.cpp b/niflib_internal.cpp
index 6436e0f3..831f55f0 100644
--- a/niflib_internal.cpp
+++ b/niflib_internal.cpp
@@ -34,6 +34,60 @@ POSSIBILITY OF SUCH DAMAGE. */
 #include "niflib_internal.h"
 
 extern unsigned int blocks_in_memory;
+const Type ABlock::TYPE("ABlock", NULL );
+
+/*
+ * Type Methods
+ */
+
+bool Type::IsSameType( const Type & compare_to ) const {
+	return &compare_to == this;
+}
+
+bool Type::IsDerivedType( const Type & compare_to ) const {
+
+	const Type * search = this;
+	while ( search != NULL ) {
+		if ( search == &compare_to ) {
+			return true;
+		}
+		search = search->base_type;
+	}
+	return false;
+}
+
+/*
+ * NiObject Methods
+ */
+
+bool NiObject::IsSameType( const Type & compare_to) const {
+	return GetType().IsSameType( compare_to );
+}
+
+bool NiObject::IsSameType( const NiObject * object ) const {
+	return GetType().IsSameType( object->GetType() );
+}
+
+bool NiObject::IsDerivedType( const Type & compare_to) const {
+	return GetType().IsDerivedType( compare_to );
+}
+
+bool NiObject::IsDerivedType( const NiObject * object ) const {
+	return GetType().IsDerivedType( object->GetType() );
+}
+
+void NiObject::AddRef() {
+	++_ref_count;
+}
+
+void NiObject::SubtractRef() {
+	--_ref_count;
+
+	if ( _ref_count < 1 ) {
+		delete this;
+	}
+}
+
 
 /***********************************************************
  * ABlock methods
diff --git a/niflib_internal.h b/niflib_internal.h
index a7973037..aa004493 100644
--- a/niflib_internal.h
+++ b/niflib_internal.h
@@ -84,12 +84,119 @@ protected:
 	IBlock * _owner;
 };
 
+/**
+ * Run Time Type Inforamtion Class
+ */
+class Type {
+public:
+	Type (const string & type_name, const Type * base_type );
+	~Type();
+
+	string GetTypeName() const;
+
+	bool IsSameType ( const Type & compare_to ) const;
+	bool IsDerivedType ( const Type & compare_to ) const;
+private:
+	string name;
+	const Type * base_type;
+};
+
+/**
+ * Smart Pointer Template
+ */
+template <class T> class Ref {
+public:
+	Ref( T * object = NULL );
+	Ref(const Ref & ref_to_copy );
+
+	operator T*() const;
+	T& operator*() const;
+	T* operator->() const;
+
+	Ref & operator=( T * object );
+	Ref & operator=( const Ref & ref );
+
+	bool operator==(T * object) const;
+	bool operator!=(T * object) const;
+	bool operator==(const Ref & ref) const;
+	bool operator!=(const Ref & ref) const;
+
+protected:
+	//The shared object
+	T* _object;
+};
+
+
+
+/**
+ * Base Object class from which all other objects derive
+ */
+
+class NiObject {
+public:
+	NiObject();
+	~NiObject();
+	//Run-Time Type Information
+	static const Type TYPE;
+	virtual const Type & GetType() const { return TYPE; };
+	bool IsSameType( const Type & compare_to ) const;
+	bool IsSameType( const NiObject * object ) const;
+	bool IsDerivedType (const Type & compare_to ) const;
+	bool IsDerivedType( const NiObject * objct ) const;
+
+	//Streaming Functions
+	virtual void Read( istream& in, unsigned int version ) {};
+	virtual void Write( ostream& out, unsigned int version ) const {};
+	//TODO Register objects in list
+	//TODO Link up objects from previously created list
+
+	//Reference Counting
+	void AddRef(); //Should not be called directly
+	void SubtractRef(); //Should not be called directly
+	unsigned int GetNumRefs() { return _ref_count; }
+	
+private:
+	unsigned int _ref_count;
+};
+
+/*
+ * Casting Templates
+ */
+
+template <class T> T* StaticCast( NiObject * object ) {
+	return (T*)object;
+}
+
+template <class T> const T* SaticCast (const NiObject * object) {
+	return (const T*)object;
+}
+
+template <class T> T* DynamicCast( NiObject * object ) {
+	if ( object->IsDerivedType(T::TYPE) ) {
+		return (T*)object;
+	} else {
+		return NULL;
+	}
+}
+
+template <class T> const T* DynamicCast( const NiObject * object ) {
+	if ( object->IsDerivedType(T::TYPE) ) {
+		return (const T*)object;
+	} else {
+		return NULL;
+	}
+}
+
+
+const Type NiObject::TYPE("NiObject", NULL );
+
 //Internal Abstract Block Class
 
 class ABlock : public IBlock {
 public:
 	ABlock();
 	~ABlock();
+	static const Type TYPE;
 	blk_ref Clone( unsigned int version = 0xFFFFFFFF );
 	//void AddAttr( AttrType type, string const & name, unsigned int first_ver = 0, unsigned int last_ver = 0xFFFFFFFF );
 	attr_ref GetAttr(string const & attr_name) const;
-- 
GitLab