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

Fixed Matrix44::Inverse.

GoToSkeletonBindPosition also works now as well.
parent 9953b9b6
No related branches found
No related tags found
No related merge requests found
......@@ -229,7 +229,7 @@ Matrix33 Matrix44::GetRotation() const {
float scale[3];
for (int r = 0; r < 3; ++r) {
//Get scale for this row
scale[r] = sqrt(m[r][0] * m[r][0] + m[r][1] * m[r][1] + m[r][2] * m[r][2]);
scale[r] = Vector3( m[r][0], m[r][1], m[r][2] ).Magnitude();
//Normalize the row by dividing each factor by scale
m[r][0] /= scale[r];
......@@ -246,7 +246,7 @@ Vector3 Matrix44::GetScale() const {
float scale[3];
for (int r = 0; r < 3; ++r) {
//Get scale for this row
scale[r] = sqrt(m[r][0] * m[r][0] + m[r][1] * m[r][1] + m[r][2] * m[r][2]);
scale[r] = Vector3( m[r][0], m[r][1], m[r][2] ).Magnitude();
}
return Vector3( scale[0], scale[1], scale[2] );
}
......@@ -331,10 +331,10 @@ Matrix33 Matrix44::Submatrix( int skip_r, int skip_c ) const {
Matrix33 sub;
int i = 0, j = 0;
for (int r = 0; r < 4; r++) {
if (r == skip_c)
if (r == skip_r)
continue;
for (int c = 0; c < 4; c++) {
if (c == skip_r)
if (c == skip_c)
continue;
sub[i][j] = (*this)[r][c];
j++;
......@@ -345,7 +345,7 @@ Matrix33 Matrix44::Submatrix( int skip_r, int skip_c ) const {
return sub;
}
float Matrix44::Adjunct( int skip_r, int skip_c ) const {
float Matrix44::Adjoint( int skip_r, int skip_c ) const {
Matrix33 sub = Submatrix( skip_r, skip_c );
return pow(-1.0f, float(skip_r + skip_c)) * sub.Determinant();
}
......@@ -354,9 +354,11 @@ Matrix44 Matrix44::Inverse() const {
Matrix44 result;
float det = Determinant();
cout << "Determinant: " << det << endl;
for (int r = 0; r < 4; r++) {
for (int c = 0; c < 4; c++) {
result[r][c] = Adjunct(r, c) / det;
//cout << "Adjoint(" << r << "," << c << "): " << Adjunct(r, c) << endl;
result[c][r] = Adjoint(r, c) / det;
}
}
......
......@@ -727,7 +727,7 @@ struct Matrix44 {
* \param skip_c The colum to skip. Must be a value between 0 and 3.
* \return The adjunct obtained by skipping the indicated row and column.
*/
NIFLIB_API float Adjunct( int skip_r, int skip_c ) const;
NIFLIB_API float Adjoint( int skip_r, int skip_c ) const;
NIFLIB_API Matrix33 GetRotation() const;
NIFLIB_API Vector3 GetScale() const;
......
......@@ -336,21 +336,23 @@ vector<NiObjectRef> ReadNifList( istream & in ) {
blocks[i]->FixLinks( blocks, link_stack, version, user_version );
}
//TODO: Make this an optional step?
for (uint i = 0; i < blocks.size(); ++i) {
NiNodeRef node = DynamicCast<NiNode>(blocks[i]);
if ( node != NULL && node->IsSkeletonRoot() ) {
node->GoToSkeletonBindPosition();
}
}
//TODO: No longer necessary?
////TODO: Make this an optional step?
////Build up the bind pose matricies into their world-space equivalents
//NiAVObjectRef av_root = DynamicCast<NiAVObject>( FindRoot(blocks) );
//if ( av_root != NULL ) {
// BuildUpBindPositions( av_root );
//}
//Send all skeleton roots to bind position
for (uint i = 0; i < blocks.size(); ++i) {
NiNodeRef node = DynamicCast<NiNode>(blocks[i]);
if ( node != NULL && node->IsSkeletonRoot() ) {
node->GoToSkeletonBindPosition();
}
}
//TODO: Evaluate this and see if it can be moved to NiTriBasedGeom::FixLinks()
//// Re-position any TriShapes with a SkinInstance
//for (uint i = 0; i < blocks.size(); ++i) {
......
......@@ -143,4 +143,4 @@ Vector3 NiAVObject::GetVelocity() const {
void NiAVObject::SetVelocity( const Vector3 & n ) {
velocity = n;
}
\ No newline at end of file
}
......@@ -156,7 +156,7 @@ void NiNode::SetSkinFlag( bool n ) {
}
void NiNode::GoToSkeletonBindPosition() {
map<NiNodeRef, Matrix44> world_positions;
//map<NiNodeRef, Matrix44> world_positions;
//Loop through all attached skins, straightening the skeleton on each
for ( list<NiSkinInstance*>::iterator it = skins.begin(); it != skins.end(); ++it ) {
......@@ -177,26 +177,51 @@ void NiNode::GoToSkeletonBindPosition() {
throw runtime_error( "Bone counts in NiSkinInstance and attached NiSkinData must match" );
}
//Loop through all bones influing this skin
//Loop through all bones influencing this skin
for ( uint i = 0; i < bones.size(); ++i ) {
//Get current offset Matrix for this bone
Matrix44 parent_offset( bone_data[i].translation,
bone_data[i].rotation,
bone_data[i].scale );
//Matrix44 parent_offset( bone_data[i].translation,
// bone_data[i].rotation,
// bone_data[i].scale );
Matrix44 parent_offset(
bone_data[i].rotation[0][0], bone_data[i].rotation[0][1], bone_data[i].rotation[0][2], 0.0f,
bone_data[i].rotation[1][0], bone_data[i].rotation[1][1], bone_data[i].rotation[1][2], 0.0f,
bone_data[i].rotation[2][0], bone_data[i].rotation[2][1], bone_data[i].rotation[2][2], 0.0f,
bone_data[i].translation.x, bone_data[i].translation.y, bone_data[i].translation.z, 1.0f
);
//Loop through all bones again, checking for any that have this bone as a parent
for ( uint j = 0; j < bones.size(); ++j ) {
if ( bones[j]->GetParent() == bones[i] ) {
cout << "Bone " << bones[j] << " has bone " << bones[i] << " as parent." << endl;
//Node 2 has node 1 as a parent
//Get child offset Matrix33
Matrix44 child_offset( bone_data[j].translation,
/*Matrix44 child_offset( bone_data[j].translation,
bone_data[j].rotation,
bone_data[j].scale );
bone_data[j].scale );*/
Matrix44 child_offset(
bone_data[j].rotation[0][0], bone_data[j].rotation[0][1], bone_data[j].rotation[0][2], 0.0f,
bone_data[j].rotation[1][0], bone_data[j].rotation[1][1], bone_data[j].rotation[1][2], 0.0f,
bone_data[j].rotation[2][0], bone_data[j].rotation[2][1], bone_data[j].rotation[2][2], 0.0f,
bone_data[j].translation.x, bone_data[j].translation.y, bone_data[j].translation.z, 1.0f
);
//Do calculation to get correct bone postion in relation to parent
//Matrix44 inverse_co = child_offset.Inverse();
//world_positions[bones[j]] = inverse_co * parent_offset;
Matrix44 inverse_co = child_offset.Inverse();
world_positions[bones[j]] = inverse_co * parent_offset;
Matrix44 child_pos = inverse_co * parent_offset;
//bones[j]->SetWorldBindPos( child_pos );
bones[j]->SetLocalRotation( child_pos.GetRotation() );
bones[j]->SetLocalScale( 1.0f );
bones[j]->SetLocalTranslation( child_pos.GetTranslation() );
//cout << "Matrix: " << cout << "Translation: " << world_positions[bones[j]] << endl;
//cout << "Translation: " << world_positions[bones[j]].GetTranslation() << endl;
//cout << "Rotation: " << world_positions[bones[j]].GetRotation() << endl;
//cout << "Scale: " << world_positions[bones[j]].GetScale() << endl;
}
}
}
......@@ -205,20 +230,25 @@ void NiNode::GoToSkeletonBindPosition() {
//All the world positoins have been calculated, so use them to set the local
//positoins
//Put skeleton root into world positions if it's not already there
if ( world_positions.find( this ) == world_positions.end() ) {
world_positions[this] = GetWorldTransform();
}
//Now loop through all nodes in the world_positions map
for ( map< NiNodeRef, Matrix44>::iterator it = world_positions.begin(); it != world_positions.end(); ++it ) {
Matrix44 res_mat = world_positions[it->first] * world_positions[it->first->GetParent()].Inverse();
//Store result in node's local transforms
it->first->SetLocalRotation( res_mat.GetRotation() );
it->first->SetLocalTranslation( res_mat.GetTranslation());
Vector3 scale = res_mat.GetScale();
it->first->SetLocalScale( 1.0f );//scale.x + scale.y + scale.z / 3.0f );
}
////Put skeleton root into world positions if it's not already there
//if ( world_positions.find( this ) == world_positions.end() ) {
// world_positions[this] = GetWorldTransform();
//}
////Now loop through all nodes in the world_positions map
//for ( map< NiNodeRef, Matrix44>::iterator it = world_positions.begin(); it != world_positions.end(); ++it ) {
// if ( world_positions.find(it->first->GetParent()) != world_positions.end() ) {
// Matrix44 res_mat = world_positions[it->first] * world_positions[it->first->GetParent()].Inverse();
// //Store result in node's local transforms
// it->first->SetLocalRotation( Matrix33(
// res_mat[0][0], res_mat[0][1], res_mat[0][2],
// res_mat[1][0], res_mat[1][1], res_mat[1][2],
// res_mat[2][0], res_mat[2][1], res_mat[2][2]
// ) );
// it->first->SetLocalTranslation( Vector3( res_mat[3][0], res_mat[3][1], res_mat[3][2] ) );
// //Vector3 scale = res_mat.GetScale();
// it->first->SetLocalScale( 1.0f );//scale.x + scale.y + scale.z / 3.0f );
// }
//}
}
\ No newline at end of file
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