Skip to content
Snippets Groups Projects
Commit 72d87b7c authored by Shon Ferguson's avatar Shon Ferguson
Browse files

More functions implemented. NiNode and NiObjectNET are now good examples of...

More functions implemented.  NiNode and NiObjectNET are now good examples of how to deal with pointers.
With implementation of NiNode::GetChildren function, I was able to re-enable the building up of the bind position.
parent a6a20d38
No related branches found
No related tags found
No related merge requests found
......@@ -1399,7 +1399,7 @@ float frequency; \
float phase; \
float startTime; \
float stopTime; \
NiObject * target; \
NiObjectNET * target; \
#define NI_TIME_CONTROLLER_INCLUDE "NiObject.h" \
......@@ -1463,7 +1463,7 @@ link_stack.pop_front(); \
if (link_stack.empty()) \
throw runtime_error("Trying to pop a link from empty stack. This is probably a bug."); \
if (link_stack.front() != 0xffffffff) { \
target = DynamicCast<NiObject>(objects[link_stack.front()]); \
target = DynamicCast<NiObjectNET>(objects[link_stack.front()]); \
if ( target == NULL ) \
throw runtime_error("Link could not be cast to required type during file read. This NIF file may be invalid or improperly understood."); \
} else \
......
......@@ -17,7 +17,7 @@ map<string, blk_factory_func> global_block_map;
//Utility Functions
void EnumerateObjects( NiObjectRef const & root, map<Type*,uint> & type_map, map<NiObjectRef, uint> & link_map );
void BuildUpBindPositions( const NiAVObjectRef & av );
void BuildUpBindPositions( const NiAVObjectRef & root );
NiObjectRef FindRoot( vector<NiObjectRef> const & blocks );
void RegisterBlockFactories ();
NiObjectRef GetObjectByType( const NiObjectRef & root, const Type & block_type );
......@@ -509,30 +509,30 @@ void EnumerateObjects( NiObjectRef const & root, map<Type*,uint> & type_map, map
}
}
void BuildUpBindPositions( const NiAVObjectRef & av ) {
void BuildUpBindPositions( const NiAVObjectRef & root ) {
//Get parent if there is one
NiNodeRef par = av->GetParent();
NiNodeRef par = root->GetParent();
if ( par != NULL ) {
//There is a node parent
//Post-multipy the block's bind matrix with the parent's bind matrix
Matrix44 result = av->GetWorldBindPos() * par->GetWorldBindPos();
Matrix44 result = root->GetWorldBindPos() * par->GetWorldBindPos();
//Store result back to block bind position
av->SetWorldBindPos( result );
root->SetWorldBindPos( result );
}
//TODO: Implement Child storage and access functions in NiNode
////Call this function for all child nodes if any
//attr_ref child_attr = block["Children"];
//if ( child_attr.is_null() == false ) {
// list<NiObjectRef> children = child_attr->asLinkList();
// list<NiObjectRef>::iterator it;
// for (it = children.begin(); it != children.end(); ++it) {
// BuildUpBindPositions( *it );
// }
//}
//If this is a NiNode, call this function for all child AVObjects
NiNodeRef node = DynamicCast<NiNode>(root);
if ( node != NULL ) {
vector<NiAVObjectRef> children = node->GetChildren();
for (vector<NiAVObjectRef>::iterator it = children.begin(); it != children.end(); ++it) {
if ( *it != NULL ) {
BuildUpBindPositions( *it );
}
}
}
}
//TODO: Should this be returning an object of a derived type too?
......
......@@ -12,7 +12,10 @@ const Type NiAVObject::TYPE("NiAVObject", &NI_A_V_OBJECT_PARENT::TYPE );
NiAVObject::NiAVObject() NI_A_V_OBJECT_CONSTRUCT, parent(NULL) {}
NiAVObject::~NiAVObject() {}
NiAVObject::~NiAVObject() {
//Clear Properties
ClearProperties();
}
void NiAVObject::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
NI_A_V_OBJECT_READ
......@@ -93,7 +96,7 @@ Matrix44 NiAVObject::GetLocalBindPos() const {
*/
void NiAVObject::SetWorldBindPos( Matrix44 const & m ) {}
void NiAVObject::SetParent( Ref<NiNode> new_parent ) {
void NiAVObject::SetParent( NiNode * new_parent ) {
parent = new_parent;
}
......
......@@ -36,7 +36,6 @@ public:
virtual void FixLinks( const vector<NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
virtual list<NiObjectRef> GetRefs() const;
//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?
/*!
......@@ -74,7 +73,7 @@ public:
void SetWorldBindPos( Matrix44 const & m );
/*! Meant to be called by NiNode during the addition of new children. Should not be called directly. */
void SetParent( Ref<NiNode> new_parent );
void SetParent( NiNode * new_parent );
Ref<NiNode> GetParent() const;
......
......@@ -10,7 +10,10 @@ const Type NiNode::TYPE("NiNode", &NI_NODE_PARENT::TYPE );
NiNode::NiNode() NI_NODE_CONSTRUCT {}
NiNode::~NiNode() {}
NiNode::~NiNode() {
//Clear Children
ClearChildren();
}
void NiNode::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
NI_NODE_READ
......@@ -36,3 +39,33 @@ const Type & NiNode::GetType() const {
return TYPE;
};
void NiNode::AddChild( Ref<NiAVObject> & obj ) {
if ( obj->GetParent() != NULL ) {
throw runtime_error( "You have attempted to add a child to a NiNode which already is the child of another NiNode." );
}
obj->SetParent( this );
children.push_back( obj );
}
void NiNode::RemoveChild( Ref<NiAVObject> obj ) {
//Search child list for the one to remove
for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ) {
if ( *it == obj ) {
(*it)->SetParent(NULL);
it = children.erase( it );
} else {
++it;
}
}
}
void NiNode::ClearChildren() {
for ( vector< NiAVObjectRef >::iterator it = children.begin(); it != children.end(); ) {
(*it)->SetParent(NULL);
}
children.clear();
}
vector< Ref<NiAVObject> > NiNode::GetChildren() const {
return children;
}
......@@ -14,6 +14,7 @@ class NiDynamicEffect;
#include "../gen/obj_defines.h"
class NiNode;
class NiAVObject;
typedef Ref<NiNode> NiNodeRef;
/*!
......@@ -32,6 +33,11 @@ public:
virtual void FixLinks( const vector<NiObjectRef> & objects, list<uint> & link_stack, unsigned int version, unsigned int user_version );
virtual list<NiObjectRef> GetRefs() const;
virtual const Type & GetType() const;
void AddChild( Ref<NiAVObject> & obj );
void RemoveChild( Ref<NiAVObject> obj );
void ClearChildren();
vector< Ref<NiAVObject> > GetChildren() const;
protected:
NI_NODE_MEMBERS
};
......
......@@ -10,7 +10,11 @@ const Type NiObjectNET::TYPE("NiObjectNET", &NI_OBJECT_N_E_T_PARENT::TYPE );
NiObjectNET::NiObjectNET() NI_OBJECT_N_E_T_CONSTRUCT {}
NiObjectNET::~NiObjectNET() {}
NiObjectNET::~NiObjectNET() {
//Clear Lists
ClearExtraData();
ClearControllers();
}
void NiObjectNET::Read( istream& in, list<uint> & link_stack, unsigned int version, unsigned int user_version ) {
NI_OBJECT_N_E_T_READ
......@@ -129,6 +133,7 @@ list< Ref<NiExtraData> > NiObjectNET::GetExtraData() const {
void NiObjectNET::AddController( Ref<NiTimeController> & obj ) {
//Insert at begining of list
obj->SetTarget( this );
obj->SetNextController( controller );
controller = obj;
}
......@@ -138,6 +143,7 @@ void NiObjectNET::RemoveController( Ref<NiTimeController> obj ) {
while ( (*cont) != NULL ) {
if ( (*cont) == obj ) {
//Cut this reference out of the list
(*cont)->SetTarget( NULL );
(*cont) = (*cont)->GetNextController();
} else {
//Advance to the next controller
......@@ -146,6 +152,10 @@ void NiObjectNET::RemoveController( Ref<NiTimeController> obj ) {
}
}
void NiObjectNET::ClearControllers() {
NiTimeControllerRef cont = controller;
while ( cont != NULL ) {
cont->SetTarget(NULL);
}
controller = NULL;
}
......
......@@ -2,7 +2,7 @@
All rights reserved. Please see niflib.h for licence. */
#include "NiTimeController.h"
#include "NiObject.h"
#include "NiObjectNET.h"
//Definition of TYPE constant
const Type NiTimeController::TYPE("NiTimeController", &NI_TIME_CONTROLLER_PARENT::TYPE );
......@@ -42,3 +42,11 @@ NiTimeControllerRef NiTimeController::GetNextController() const {
void NiTimeController::SetNextController( const NiTimeControllerRef & obj ) {
nextController = obj;
}
void NiTimeController::SetTarget( NiObjectNET * new_target ) {
target = new_target;
}
Ref<NiObjectNET> NiTimeController::GetTarget() {
return target;
}
......@@ -13,6 +13,7 @@ class NiObject;
#include "../gen/obj_defines.h"
class NiTimeController;
class NiObjectNET;
typedef Ref<NiTimeController> NiTimeControllerRef;
/*!
......@@ -43,6 +44,17 @@ public:
* \param obj A reference to the object to set as the one after this in the chain.
*/
void SetNextController( const NiTimeControllerRef & obj );
/*! This function should only be called by NiObjectNET. It sets the target of
* this controller when it is attatched to the NiObjectNET class. */
void SetTarget( NiObjectNET * new_target );
/*! This function returns the current target NiObjectNET, if any, that this controller
* is acting on.
* \return A reference to the current target of this controller.
*/
Ref<NiObjectNET> GetTarget();
protected:
NI_TIME_CONTROLLER_MEMBERS
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment