diff --git a/include/niflib.h b/include/niflib.h index 939f01bede42902c791dc2cdf4d69395113991e0..114ff8279de570aad7715478e932bc6c58f541a7 100644 --- a/include/niflib.h +++ b/include/niflib.h @@ -110,7 +110,7 @@ NIFLIB_API unsigned int GetNifVersion( string const & file_name ); /*! * Return the missing link stack with objects replaced from nif trees at specified roots. */ -NIFLIB_API list<Ref<NiObject> > ProcessMissingLinkStack( +NIFLIB_API list<Ref<NiObject> > ResolveMissingLinkStack( list<Ref<NiObject> > const & roots, const list<NiObject *> & missing_link_stack); diff --git a/src/niflib.cpp b/src/niflib.cpp index 5bed1efb1b748ffe9b41482e338e79bcf5ef7438..6d889bc130443ed76154da1c3189bb0436818cef 100644 --- a/src/niflib.cpp +++ b/src/niflib.cpp @@ -407,7 +407,7 @@ vector<NiObjectRef> ReadNifList( istream & in, list<NiObjectRef> & missing_link_ return obj_list; } -NiObjectRef _ProcessMissingLinkStackHelper(NiObjectRef root, NiObject *obj) { +NiObjectRef _ResolveMissingLinkStackHelper(NiObjectRef root, NiObject *obj) { // search by name NiNodeRef rootnode = DynamicCast<NiNode>(root); NiNodeRef objnode = DynamicCast<NiNode>(obj); @@ -415,10 +415,9 @@ NiObjectRef _ProcessMissingLinkStackHelper(NiObjectRef root, NiObject *obj) { if (!(rootnode->GetName().empty()) && rootnode->GetName() == objnode->GetName()) { return StaticCast<NiObject>(rootnode); } - } else if (root != NULL) { list<NiObjectRef> children = root->GetRefs(); for (list<NiObjectRef>::iterator child = children.begin(); child != children.end(); ++child) { - NiObjectRef result = _ProcessMissingLinkStackHelper(*child, obj); + NiObjectRef result = _ResolveMissingLinkStackHelper(*child, obj); if (result != NULL) { return result; } @@ -428,15 +427,21 @@ NiObjectRef _ProcessMissingLinkStackHelper(NiObjectRef root, NiObject *obj) { return NiObjectRef(); } -list<NiObjectRef> ProcessMissingLinkStack( +list<NiObjectRef> ResolveMissingLinkStack( list<NiObjectRef> const & roots, const list<NiObject *> & missing_link_stack) { list<NiObjectRef> result; for (list<NiObject *>::const_iterator obj = missing_link_stack.begin(); obj != missing_link_stack.end(); ++obj) { - for (list<NiObjectRef>::const_iterator root = roots.begin(); root != roots.end(); ++root) { - result.push_back(_ProcessMissingLinkStackHelper(*root, *obj)); + NiObjectRef resolved; + if (*obj != NULL) { + for (list<NiObjectRef>::const_iterator root = roots.begin(); root != roots.end(); ++root) { + resolved = _ResolveMissingLinkStackHelper(*root, *obj); + if (resolved != NULL) + break; + } } + result.push_back(resolved); } return result; } diff --git a/test/missing_link_stack_test.cpp b/test/missing_link_stack_test.cpp index e25c343302c29bec1b84cf9c40857ccb803448ab..59abb87978607a7c2330da3ba4be2643e8b5e370 100644 --- a/test/missing_link_stack_test.cpp +++ b/test/missing_link_stack_test.cpp @@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(missing_link_stack_simple_test) BOOST_CHECK_NO_THROW(WriteNifTree(ss, roots, missing_link_stack, NifInfo(VER_20_0_0_5))); bool has_root = false; bool has_bone = false; - // check that root and bone are missing + // check that root and bone are in the missing link stack for (list<NiObject *>::iterator it = missing_link_stack.begin(); it != missing_link_stack.end(); it++) { if ((*it) != NULL) { if (!has_root && (*it) == root) { @@ -62,6 +62,21 @@ BOOST_AUTO_TEST_CASE(missing_link_stack_simple_test) } BOOST_CHECK_EQUAL(has_root, true); BOOST_CHECK_EQUAL(has_bone, true); + // read it again + roots.clear(); + roots.push_back(StaticCast<NiObject>(root)); + list<NiObjectRef> resolved_link_stack = ResolveMissingLinkStack(roots, missing_link_stack); + ss.seekg(0); + NifInfo info; + NiObjectRef new_root; + BOOST_CHECK_NO_THROW(new_root = ReadNifTree(ss, resolved_link_stack, &info)); + NiTriStripsRef new_shape = DynamicCast<NiTriStrips>(new_root); + // check for references to the old tree + BOOST_CHECK(new_shape != NULL); + BOOST_CHECK(new_shape->skinInstance != NULL); + BOOST_CHECK_EQUAL(new_shape->skinInstance->skeletonRoot, root); + BOOST_CHECK_EQUAL(new_shape->skinInstance->bones.size(), 1); + BOOST_CHECK_EQUAL(new_shape->skinInstance->bones[0], bone); } BOOST_AUTO_TEST_SUITE_END()