From b7e01947a71239a21e2d40b527a0b1beaaf32440 Mon Sep 17 00:00:00 2001 From: Shon Ferguson <shonferg@users.sourceforge.net> Date: Fri, 9 Dec 2005 23:41:35 +0000 Subject: [PATCH] Attempted to fix NiSkinData to be const friendly. --- NIF_Blocks.cpp | 123 +++++++++++++++++++++++++------------------------ NIF_Blocks.h | 5 +- niflib.cpp | 28 +++++------ niflib.h | 4 +- 4 files changed, 82 insertions(+), 78 deletions(-) diff --git a/NIF_Blocks.cpp b/NIF_Blocks.cpp index 4d006c0d..650327ea 100644 --- a/NIF_Blocks.cpp +++ b/NIF_Blocks.cpp @@ -1496,21 +1496,26 @@ void NiSkinData::Write( ofstream& out, unsigned int version ) const { WriteByte( unknownByte, out ); } - map<IBlock *, Bone>::const_iterator it; - for( it = bone_map.begin(); it != bone_map.end(); ++it ) { + //Get parent node for bone calculations + INode const * const par_node = this->GetNodeParent(); + Bone bone; // temporary value + + map<IBlock *, Bone >::const_iterator it; + int num = 0; + for( it = bone_map.begin(); it != bone_map.end(); ++it ) { + //Calculae offset for this bone (data is not stored) + CalculateBoneOffset( par_node, it->first, bone ); + for (int c = 0; c < 3; ++c) { for (int r = 0; r < 3; ++r) { - WriteFloat( it->second.rotation[r][c], out ); + WriteFloat( bone.rotation[r][c], out ); } } - WriteFVector3( it->second.translation, out ); - WriteFloat( it->second.scale, out ); + WriteFVector3( bone.translation, out ); + WriteFloat( bone.scale, out ); + + WriteFVector4( bone.unknown4Floats, out ); - WriteFVector4( it->second.unknown4Floats, out ); - //WriteFloat( 0.0f, out ); - //WriteFloat( 0.0f, out ); - //WriteFloat( 0.0f, out ); - //WriteFloat( 0.0f, out ); WriteUShort( short(it->second.weights.size() ), out ); map<int, float>::const_iterator it2; @@ -1564,9 +1569,6 @@ string NiSkinData::asString() const { out.setf(ios::fixed, ios::floatfield); out << setprecision(1); - //Calculate bone offsets pior to printing readout - //CalculateBoneOffsets(); // non-const! - out << "Rotate:" << endl << " |" << setw(6) << rotation[0][0] << "," << setw(6) << rotation[0][1] << "," << setw(6) << rotation[0][2] << " |" << endl << " |" << setw(6) << rotation[1][0] << "," << setw(6) << rotation[1][1] << "," << setw(6) << rotation[1][2] << " |" << endl @@ -1578,12 +1580,15 @@ string NiSkinData::asString() const { << "Unknown Byte: " << int(unknownByte) << endl << "Bones:" << endl; - map<IBlock *, Bone>::const_iterator it; - //vector<Bone>::iterator it; + //Get parent node for bone calculations + INode const * const par_node = this->GetNodeParent(); + Bone bone; // temporary value + + map<IBlock *, Bone >::const_iterator it; int num = 0; for( it = bone_map.begin(); it != bone_map.end(); ++it ) { - //Friendlier name - Bone const & bone = it->second; + //Calculae offset for this bone (data is not stored) + CalculateBoneOffset( par_node, it->first, bone ); num++; out << "Bone " << num << ":" << endl @@ -1603,11 +1608,11 @@ string NiSkinData::asString() const { out << "Unknown 4 Floats: " << setw(6) << q[0] << "," << setw(6) << q[1] << "," << setw(6) << q[2] << "," << setw(6) << q[3] << endl; - out << " Weights: " << uint(bone.weights.size()) << endl; + out << " Weights: " << uint( it->second.weights.size()) << endl; if (verbose) { map<int, float>::const_iterator it2; - for ( it2 = bone.weights.begin(); it2 != bone.weights.end(); ++it2 ){ + for ( it2 = it->second.weights.begin(); it2 != it->second.weights.end(); ++it2 ){ out << " Vertex: " << it2->first << "\tWeight: " << it2->second << endl; } } else { @@ -1869,8 +1874,7 @@ NiSkinData::~NiSkinData() { } } -void NiSkinData::CalculateBoneOffsets() { - +INode * NiSkinData::GetNodeParent() const { //--Get Node Parent Bind Pose--// blk_ref par_block; @@ -1881,60 +1885,59 @@ void NiSkinData::CalculateBoneOffsets() { throw runtime_error("SkinData block does not have parent of parent."); } - INode * par_node = QueryNode(par_block); + INode * par_node = (INode*)par_block->QueryInterface(ID_NODE); if ( par_node == NULL ) throw runtime_error("SkinData block's parent of parent is not a node."); + return par_node; +} - //Cycle through all bones, calculating their offsets and storing the values - map<IBlock *, Bone>::iterator it; - for( it = bone_map.begin(); it != bone_map.end(); ++it ) { - //--Get Bone Bind Pose--// +void NiSkinData::CalculateBoneOffset( INode const * const par_node, IBlock const * const bone_block, Bone & result ) const { - //Get Bone Node - INode * bone_node = (INode*)it->first->QueryInterface(ID_NODE); + //--Get Bone Bind Pose--// - //Get bind matricies + //Get Bone Node + INode * const bone_node = (INode*)bone_block->QueryInterface(ID_NODE); - Matrix44 par_mat, bone_mat, inv_mat, res_mat; - par_mat = par_node->GetBindPosition(); - bone_mat = bone_node->GetBindPosition(); + //Get bind matricies + Matrix44 par_mat, bone_mat, inv_mat, res_mat; + par_mat = par_node->GetBindPosition(); + bone_mat = bone_node->GetBindPosition(); - //Inverse bone matrix & multiply with parent node matrix - inv_mat = InverseMatrix44(bone_mat); - res_mat = MultMatrix44(par_mat, inv_mat); + //Inverse bone matrix & multiply with parent node matrix + inv_mat = InverseMatrix44(bone_mat); + res_mat = MultMatrix44(par_mat, inv_mat); - //--Extract Scale from first 3 rows--// - float scale[3]; - for (int r = 0; r < 3; ++r) { - //Get scale for this row - scale[r] = sqrt(res_mat[r][0] * res_mat[r][0] + res_mat[r][1] * res_mat[r][1] + res_mat[r][2] * res_mat[r][2] + res_mat[r][3] * res_mat[r][3]); + //--Extract Scale from first 3 rows--// + float scale[3]; + for (int r = 0; r < 3; ++r) { + //Get scale for this row + scale[r] = sqrt(res_mat[r][0] * res_mat[r][0] + res_mat[r][1] * res_mat[r][1] + res_mat[r][2] * res_mat[r][2] + res_mat[r][3] * res_mat[r][3]); - //Normalize the row by dividing each factor by scale - res_mat[r][0] /= scale[r]; - res_mat[r][1] /= scale[r]; - res_mat[r][2] /= scale[r]; - res_mat[r][3] /= scale[r]; - } + //Normalize the row by dividing each factor by scale + res_mat[r][0] /= scale[r]; + res_mat[r][1] /= scale[r]; + res_mat[r][2] /= scale[r]; + res_mat[r][3] /= scale[r]; + } - //--Store Results--// + //--Store Result--// - //Store rotation matrix - for (int c = 0; c < 3; ++c) { - for (int r = 0; r < 3; ++r) { - it->second.rotation[r][c] = res_mat[r][c]; - } + //Store rotation matrix + for (int c = 0; c < 3; ++c) { + for (int r = 0; r < 3; ++r) { + result.rotation[r][c] = res_mat[r][c]; } + } - //Store translate vector - it->second.translation[0] = res_mat[3][0]; - it->second.translation[1] = res_mat[3][1]; - it->second.translation[2] = res_mat[3][2]; + //Store translate vector + result.translation[0] = res_mat[3][0]; + result.translation[1] = res_mat[3][1]; + result.translation[2] = res_mat[3][2]; - - //Store average scale - it->second.scale = (scale[0] + scale[1] + scale[2]) / 3.0f; - } + + //Store average scale + result.scale = (scale[0] + scale[1] + scale[2]) / 3.0f; } /*********************************************************** diff --git a/NIF_Blocks.h b/NIF_Blocks.h index 9a8f8a79..f7844c23 100644 --- a/NIF_Blocks.h +++ b/NIF_Blocks.h @@ -1200,13 +1200,14 @@ class NiSkinData : public AData, public ISkinData, public ISkinDataInternal { map<int, float> weights; }; - void CalculateBoneOffsets(); + INode * GetNodeParent() const; + void CalculateBoneOffset( INode const * const par_node, IBlock const * const bone_block, Bone & result ) const; Matrix33 rotation; fVector3 translation; float scale; int unknownInt; byte unknownByte; - map<IBlock *, Bone> bone_map; + map<IBlock *, Bone > bone_map; vector<Bone> bones; }; diff --git a/niflib.cpp b/niflib.cpp index d9c68cf6..dda8be85 100644 --- a/niflib.cpp +++ b/niflib.cpp @@ -478,18 +478,18 @@ list<blk_ref> SearchAllNifTree( blk_ref const & root_block, string block_name ) return result; }; -list<blk_ref> GetNifTree( blk_ref const & root_block ) { - list<blk_ref> result; - result.push_back( root_block ); - list<blk_ref> links = root_block->GetLinks(); - for (list<blk_ref>::iterator it = links.begin(); it != links.end(); ++it ) { - if ( it->is_null() == false && (*it)->GetParent() == root_block ) { - list<blk_ref> childresult = GetNifTree( *it ); - result.merge( childresult ); - }; - }; - return result; -}; +//list<blk_ref> GetNifTree( blk_ref const & root_block ) { +// list<blk_ref> result; +// result.push_back( root_block ); +// list<blk_ref> links = root_block->GetLinks(); +// for (list<blk_ref>::iterator it = links.begin(); it != links.end(); ++it ) { +// if ( it->is_null() == false && (*it)->GetParent() == root_block ) { +// list<blk_ref> childresult = GetNifTree( *it ); +// result.merge( childresult ); +// }; +// }; +// return result; +//}; // Writes valid XNif & XKf Files given a file name, and a pointer to the root block of the Nif file tree. // (XNif and XKf file blocks are automatically extracted from the Nif tree if there are animation groups.) @@ -502,10 +502,10 @@ void WriteNifTree( string const & file_name, blk_ref const & root_block, unsigne blk_ref txtkey_block = SearchNifTree( root_block, "NiTextKeyExtraData" ); if ( txtkey_block.is_null() == false ) { // Create file names for the XKf and XNif files. - int file_name_slash = file_name.rfind("\\") + 1; + uint file_name_slash = uint(file_name.rfind("\\") + 1); string file_name_path = file_name.substr(0, file_name_slash); string file_name_base = file_name.substr(file_name_slash, file_name.length()); - int file_name_dot = file_name_base.rfind("."); + uint file_name_dot = uint(file_name_base.rfind(".")); file_name_base = file_name_base.substr(0, file_name_dot); string xkf_name = file_name_path + "x" + file_name_base + ".kf"; string xnif_name = file_name_path + "x" + file_name_base + ".nif"; diff --git a/niflib.h b/niflib.h index f4e2460a..89a16f30 100644 --- a/niflib.h +++ b/niflib.h @@ -127,8 +127,8 @@ blk_ref ReadNifTree( string const & file_name ); //Writes a valid Nif File given a file name, a pointer to the root block of a file tree void WriteNifTree( string const & file_name, blk_ref const & root_block, unsigned int version = VER_4_0_0_2 ); -// Returns list of all blocks in the tree rooted by root block. -list<blk_ref> GetNifTree( blk_ref const & root_block ); +//// Returns list of all blocks in the tree rooted by root block. +//list<blk_ref> GetNifTree( blk_ref const & root_block ); ////Returns the NIF spec version of a file, given a file name. //string GetFileVersion(string file_name); -- GitLab