From 4fd0e85c721d37ac0a61d9d870b1a6e34501bb51 Mon Sep 17 00:00:00 2001
From: Shon Ferguson <shonferg@users.sourceforge.net>
Date: Sun, 4 Jun 2006 01:12:36 +0000
Subject: [PATCH] Implemented NiAVObject functions.

---
 niflib.cpp         | 18 +++++++++---------
 niflib.vcproj      |  2 +-
 obj/NiAVObject.cpp | 43 ++++++++++++++++++++++++++++++++++++++-----
 obj/NiAVObject.h   | 21 ++++++++++++---------
 obj/NiObject.h     |  5 ++++-
 obj/NiObjectNET.h  |  5 ++++-
 6 files changed, 68 insertions(+), 26 deletions(-)

diff --git a/niflib.cpp b/niflib.cpp
index ba5f9d38..2476e8bc 100644
--- a/niflib.cpp
+++ b/niflib.cpp
@@ -331,13 +331,13 @@ vector<NiObjectRef> ReadNifList( istream & in ) {
 		blocks[i]->FixLinks( blocks, link_stack, version );
 	}
 
-	////Build up the bind pose matricies into their world-space equivalents
-	//NiAVObjectRef av_root = DynamicCast<NiAVObject>( FindRoot(blocks) );
-	//if ( av_root != NULL ) {
-	//	BuildUpBindPositions( av_root );
-	//} else {
-	//	throw runtime_error("Root object is not a NiAVObject derived class.");
-	//}
+	//Build up the bind pose matricies into their world-space equivalents
+	NiAVObjectRef av_root = DynamicCast<NiAVObject>( FindRoot(blocks) );
+	if ( av_root != NULL ) {
+		BuildUpBindPositions( av_root );
+	} else {
+		throw runtime_error("Root object is not a NiAVObject derived class.");
+	}
 
 	//TODO: Evaluate this and see if it can be moved to NiTriBasedGeom::FixLinks()
 	//// Re-position any TriShapes with a SkinInstance
@@ -501,9 +501,9 @@ void EnumerateObjects( NiObjectRef const & root, map<Type,uint> & type_map, map<
 void BuildUpBindPositions( const NiAVObjectRef & av ) {
 
 	//Get parent if there is one
-	NiAVObjectRef par = DynamicCast<NiAVObject>(av->GetParent());
+	NiNodeRef par = av->GetParent();
 	if ( par != NULL ) {
-		//There is an AV Object parent
+		//There is a node parent
 
 		//Post-multipy the block's bind matrix with the parent's bind matrix
 		Matrix44 result = av->GetWorldBindPos() * par->GetWorldBindPos();
diff --git a/niflib.vcproj b/niflib.vcproj
index 58512338..dc6d0047 100644
--- a/niflib.vcproj
+++ b/niflib.vcproj
@@ -61,7 +61,7 @@
 				Name="VCCLCompilerTool"
 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
 				RuntimeLibrary="0"
-				UsePrecompiledHeader="0"
+				UsePrecompiledHeader="2"
 				WarningLevel="3"
 				Detect64BitPortabilityProblems="TRUE"
 				DebugInformationFormat="3"/>
diff --git a/obj/NiAVObject.cpp b/obj/NiAVObject.cpp
index aa467f6a..da7053e1 100644
--- a/obj/NiAVObject.cpp
+++ b/obj/NiAVObject.cpp
@@ -2,6 +2,7 @@
 All rights reserved.  Please see niflib.h for licence. */
 
 #include "NiAVObject.h"
+#include "NiNode.h"
 #include "NiProperty.h"
 #include "NiCollisionData.h"
 #include "NiCollisionObject.h"
@@ -9,7 +10,7 @@ All rights reserved.  Please see niflib.h for licence. */
 //Definition of TYPE constant
 const Type NiAVObject::TYPE("NiAVObject", &NI_A_V_OBJECT_PARENT::TYPE );
 
-NiAVObject::NiAVObject() NI_A_V_OBJECT_CONSTRUCT {}
+NiAVObject::NiAVObject() NI_A_V_OBJECT_CONSTRUCT, parent(NULL) {}
 
 NiAVObject::~NiAVObject() {}
 
@@ -35,7 +36,7 @@ void NiAVObject::FixLinks( const vector<NiObjectRef> & objects, list<uint> & lin
  * \sa INode::GetWorldTransform
  */
 Matrix44 NiAVObject::GetLocalTransform() const {
-	return Matrix44();
+	return Matrix44( translation, rotation, scale );
 }
 /*! 
  * This function will return a transform matrix that represents the location of this node in world space.  In other words, it concatenates all parent transforms up to the root of the scene to give the ultimate combined transform from the origin for this node.
@@ -43,7 +44,17 @@ Matrix44 NiAVObject::GetLocalTransform() const {
  * \sa INode::GetLocalTransform
  */
 Matrix44 NiAVObject::GetWorldTransform() const {
-	return Matrix44();
+	//Get Parent Transform if there is one
+	NiNodeRef par = GetParent();
+
+	if ( par != NULL ) {
+		//Multipy local matrix and parent world matrix for result
+		return GetLocalTransform() * par->GetWorldTransform();
+	}
+	else {
+		//No parent transform, simply return local transform
+		return GetLocalTransform();
+	}
 }
 /*!
  * This function returns the bind position world matrix.  The bind position (also called the rest position) is the position of an object in a skin and bones system before any posing has been done.
@@ -51,14 +62,24 @@ Matrix44 NiAVObject::GetWorldTransform() const {
  * \sa INode::GetLocalBindPos, INode::SetWorldBindPos
  */
 Matrix44 NiAVObject::GetWorldBindPos() const {
-	return Matrix44();
+	return bindPosition;
 }
 /*! This function returns the bind position world matrix of this node multiplied with the inverse of the bind position world matrix of its parent object if any.  Thus it returns the bind position of the object in local coordinates.  The bind position (also called the rest position) is the position of an object in a skin and bones system before any posing has been done.
  * \return The 4x4 local bind position matrix of this node.
  * \sa INode::SetWorldBindPos, INode::GetWorldBindPos
  */
 Matrix44 NiAVObject::GetLocalBindPos() const {
-	return Matrix44();
+	//Get Parent Transform if there is one
+	NiNodeRef par = GetParent();
+	if ( par != NULL ) {
+		//There is a node parent
+		//multiply its inverse with this block's bind position to get the local bind position
+		return bindPosition * par->GetWorldBindPos().Inverse();
+	}
+	else {
+		//No parent transform, simply return local transform
+		return GetWorldBindPos();
+	}
 }
 
 /*!
@@ -67,3 +88,15 @@ Matrix44 NiAVObject::GetLocalBindPos() const {
  * \sa INode::GetLocalBindPos, INode::GetWorldBindPos
  */
 void NiAVObject::SetWorldBindPos( Matrix44 const & m )  {}
+
+void NiAVObject::SetParent( Ref<NiNode> new_parent ) {
+	parent = new_parent;
+}
+
+Ref<NiNode> NiAVObject::GetParent() const {
+	return parent;
+}
+
+void NiAVObject::ResetSkinnedFlag() {
+
+}
diff --git a/obj/NiAVObject.h b/obj/NiAVObject.h
index 5f06cc43..28279f27 100644
--- a/obj/NiAVObject.h
+++ b/obj/NiAVObject.h
@@ -5,10 +5,13 @@ All rights reserved.  Please see niflib.h for licence. */
 #define _NIAVOBJECT_H_
 
 // Includes
-#include "obj/NiProperty.h"
 #include "gen/BoundingBox.h"
-#include "obj/NiCollisionData.h"
-#include "obj/NiCollisionObject.h"
+
+//Forward Defines
+class NiProperty;
+class NiCollisionData;
+class NiCollisionObject;
+class NiNode;
 
 #include "gen/obj_defines.h"
 #include NI_A_V_OBJECT_INCLUDE
@@ -34,7 +37,7 @@ public:
 
 	//TODO: list of NiProperty pointers.  Need functions to add/remove.
 	//TODO:  Bounding Box.  What to do with newer files that have a link?  Wrap this in a function and translate?
-
+	
 	/*! 
 	 * This is a conveniance function that allows you to retrieve the full 4x4 matrix transform of a node.  It accesses the "Rotation," "Translation," and "Scale" attributes and builds a complete 4x4 transformation matrix from them.
 	 * \return A 4x4 transformation matrix built from the node's transform attributes.
@@ -69,15 +72,15 @@ public:
 	 */
 	void SetWorldBindPos( Matrix44 const & m );
 
-	void SetParent( NiAVObjectRef new_parent ) {
-		parent = new_parent;
-	}
-	NiAVObjectRef GetParent() { return parent; }
+	/*! Meant to be called by NiNode during the addition of new children.  Should not be called directly. */
+	void SetParent( Ref<NiNode> new_parent );
+
+	Ref<NiNode> GetParent() const;
 
 private:
 	NI_A_V_OBJECT_MEMBERS
 
-	NiAVObject * parent;
+	NiNode * parent;
 	void ResetSkinnedFlag();
 	Matrix44 bindPosition;
 };
diff --git a/obj/NiObject.h b/obj/NiObject.h
index 1814d39e..68219daf 100644
--- a/obj/NiObject.h
+++ b/obj/NiObject.h
@@ -100,7 +100,10 @@ public:
 	 */
 	virtual string asString( bool verbose = false ) const;
 
-	/*! Formats a human readable string that includes the type of the object */
+	/*!
+	 * Formats a human readable string that includes the type of the object
+	 * \return A string in the form:  address(type)
+	 */
 	virtual string GetIDString();
 
 	/*!
diff --git a/obj/NiObjectNET.h b/obj/NiObjectNET.h
index 1d8753ec..c29176c9 100644
--- a/obj/NiObjectNET.h
+++ b/obj/NiObjectNET.h
@@ -28,7 +28,10 @@ public:
 	virtual void Read( istream& in, list<uint> & link_stack, unsigned int version );
 	virtual void Write( ostream& out, map<NiObjectRef,uint> link_map, unsigned int version ) const;
 	virtual string asString( bool verbose = false ) const;
-	/*! Formats a human readable string that includes the type and name of the object */
+	/*!
+	 * Formats a human readable string that includes the type of the object
+	 * \return A string in the form:  address(type) {name}
+	 */
 	virtual string GetIDString();
 	virtual void FixLinks( const vector<NiObjectRef> & objects, list<uint> & link_stack, unsigned int version );
 	
-- 
GitLab