Skip to content
Snippets Groups Projects
Commit 36bc689a authored by Amorilia's avatar Amorilia
Browse files

Merge branch 'feature/bugfix_for_numuvsets'

Bugfix for writing numuvsets (aka the dreaded 4097 issue for Skyrim exports).
parents ef1296e0 c58d3e57
No related branches found
No related tags found
No related merge requests found
docsys @ fb34fc4f
Subproject commit 28339aff1ebfa5b4a0e6306c851cf4c1dc020360
Subproject commit fb34fc4f6fbeb650c1d21d4a1e1a406da8f28bc1
......@@ -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. */
......
......@@ -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--//
......@@ -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})
......
#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()
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