diff --git a/docsys b/docsys index 28339aff1ebfa5b4a0e6306c851cf4c1dc020360..fb34fc4f6fbeb650c1d21d4a1e1a406da8f28bc1 160000 --- a/docsys +++ b/docsys @@ -1 +1 @@ -Subproject commit 28339aff1ebfa5b4a0e6306c851cf4c1dc020360 +Subproject commit fb34fc4f6fbeb650c1d21d4a1e1a406da8f28bc1 diff --git a/include/obj/NiGeometryData.h b/include/obj/NiGeometryData.h index d2fd36a9aa632a777e02056419053524ec35a730..51a623889ca4b263854fdb735a2e5cc0dc56d564 100644 --- a/include/obj/NiGeometryData.h +++ b/include/obj/NiGeometryData.h @@ -255,6 +255,10 @@ public: // \param[in] value The new value. NIFLIB_API void SetTangents( const vector<Vector3 >& value ); +private: + unsigned short numUvSetsCalc() const; + unsigned short bsNumUvSetsCalc() const; + //--END CUSTOM CODE--// protected: /*! Unknown identifier. Always 0. */ diff --git a/src/obj/NiGeometryData.cpp b/src/obj/NiGeometryData.cpp index c0008bd185942a04ea6d26e57c75d1532b3aa5c5..5d080b6668841ad5fd07ddb01c67aeb3c78f00f0 100644 --- a/src/obj/NiGeometryData.cpp +++ b/src/obj/NiGeometryData.cpp @@ -122,22 +122,11 @@ void NiGeometryData::Read( istream& in, list<unsigned int> & link_stack, const N if ( info.version <= 0x04000002 ) { NifStream( hasUv, in, info ); }; - if ( (!((info.version >= 0x14020007) && (info.userVersion >= 11))) ) { - uvSets.resize((numUvSets & 63)); - for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) { - uvSets[i2].resize(numVertices); - for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) { - NifStream( uvSets[i2][i3], in, info ); - }; - }; - }; - if ( ((info.version >= 0x14020007) && (info.userVersion >= 11)) ) { - uvSets.resize((bsNumUvSets & 1)); - for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) { - uvSets[i2].resize(numVertices); - for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) { - NifStream( uvSets[i2][i3], in, info ); - }; + uvSets.resize(((numUvSets & 63) | (bsNumUvSets & 1))); + for (unsigned int i1 = 0; i1 < uvSets.size(); i1++) { + uvSets[i1].resize(numVertices); + for (unsigned int i2 = 0; i2 < uvSets[i1].size(); i2++) { + NifStream( uvSets[i1][i2], in, info ); }; }; if ( ( info.version >= 0x0A000100 ) && ( (info.userVersion < 12) ) ) { @@ -168,8 +157,8 @@ void NiGeometryData::Write( ostream& out, const map<NiObjectRef,unsigned int> & //--END CUSTOM CODE--// NiObject::Write( out, link_map, missing_link_stack, info ); - bsNumUvSets = (unsigned short)(uvSets.size()); - numUvSets = (unsigned short)(uvSets.size()); + bsNumUvSets = bsNumUvSetsCalc(); + numUvSets = numUvSetsCalc(); numVertices = (unsigned short)(vertices.size()); if ( info.version >= 0x0A020000 ) { NifStream( unknownInt, out, info ); @@ -243,18 +232,9 @@ void NiGeometryData::Write( ostream& out, const map<NiObjectRef,unsigned int> & if ( info.version <= 0x04000002 ) { NifStream( hasUv, out, info ); }; - if ( (!((info.version >= 0x14020007) && (info.userVersion >= 11))) ) { - for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) { - for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) { - NifStream( uvSets[i2][i3], out, info ); - }; - }; - }; - if ( ((info.version >= 0x14020007) && (info.userVersion >= 11)) ) { - for (unsigned int i2 = 0; i2 < uvSets.size(); i2++) { - for (unsigned int i3 = 0; i3 < uvSets[i2].size(); i3++) { - NifStream( uvSets[i2][i3], out, info ); - }; + for (unsigned int i1 = 0; i1 < uvSets.size(); i1++) { + for (unsigned int i2 = 0; i2 < uvSets[i1].size(); i2++) { + NifStream( uvSets[i1][i2], out, info ); }; }; if ( ( info.version >= 0x0A000100 ) && ( (info.userVersion < 12) ) ) { @@ -317,8 +297,8 @@ std::string NiGeometryData::asString( bool verbose ) const { stringstream out; unsigned int array_output_count = 0; out << NiObject::asString(); - bsNumUvSets = (unsigned short)(uvSets.size()); - numUvSets = (unsigned short)(uvSets.size()); + bsNumUvSets = bsNumUvSetsCalc(); + numUvSets = numUvSetsCalc(); numVertices = (unsigned short)(vertices.size()); out << " Unknown Int: " << unknownInt << endl; if ( (!IsDerivedType(NiPSysData::TYPE)) ) { @@ -739,4 +719,12 @@ void NiGeometryData::SetTangents( const vector<Vector3 >& value ) { tangents = value; } +unsigned short NiGeometryData::numUvSetsCalc() const { + return (numUvSets & (~63)) | (unsigned short)(uvSets.size() & 63); +} + +unsigned short NiGeometryData::bsNumUvSetsCalc() const { + return (numUvSets & (~1)) | (unsigned short)(uvSets.size() & 1); +} + //--END CUSTOM CODE--// diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f17393e44ba85ee3cc2548fe7caf88af73e29e00..f544ab6d2b11583fd55f83ab803fbc2f56a79f58 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,7 +11,8 @@ foreach(TEST ninode_test skin_test missing_link_stack_test - trishape_test) + trishape_test + numuvsets_test) add_executable(${TEST} ${TEST}.cpp) target_link_libraries(${TEST} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} niflib) add_test(niflib::${TEST} ${TEST}) diff --git a/test/numuvsets_test.cpp b/test/numuvsets_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc086744379806acef264380b684b04eeefdaa53 --- /dev/null +++ b/test/numuvsets_test.cpp @@ -0,0 +1,51 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MAIN +#include <boost/test/unit_test.hpp> + +#include <sstream> // stringstream + +// evil hack to allow testing of private and protected data +#define private public +#define protected public + +#include "niflib.h" +#include "obj/NiNode.h" +#include "obj/NiTriShape.h" +#include "obj/NiTriShapeData.h" + +using namespace Niflib; +using namespace std; + +BOOST_AUTO_TEST_SUITE(numuvsets_test_suite) + +BOOST_AUTO_TEST_CASE(numuvsets_write_test) +{ + stringstream ss; + stringstream ss2; + + // create a simple nif tree with a trishape + NiNodeRef root = new NiNode; + NiTriShapeRef shape = new NiTriShape; + NiTriShapeDataRef data = new NiTriShapeData; + // set hierarchy + shape->SetData(data); + root->AddChild(DynamicCast<NiAVObject>(shape)); + // set flag + data->SetTspaceFlag(1); + // write and read + NiObjectRef obj; + BOOST_CHECK_NO_THROW(WriteNifTree(ss, root, NifInfo(VER_20_0_0_5))); + ss.seekg(0); + BOOST_CHECK_NO_THROW(obj = ReadNifTree(ss)); + // check flag + root = DynamicCast<NiNode>(obj); + BOOST_REQUIRE(root != NULL); + BOOST_REQUIRE_EQUAL(root->GetChildren().size(), 1); + shape = DynamicCast<NiTriShape>(root->GetChildren()[0]); + BOOST_REQUIRE(shape != NULL); + data = DynamicCast<NiTriShapeData>(shape->GetData()); + BOOST_REQUIRE(data != NULL); + BOOST_CHECK_EQUAL(data->GetTspaceFlag(), 1); +} + +BOOST_AUTO_TEST_SUITE_END()