From 4344700e85c2ad9c4683a5a0ef38a641068f6525 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Sun, 1 Mar 2009 04:40:54 -0700 Subject: Backported fix for VWR-996 (wrong visualisation of animations) from 1.22 --- ChangeLog.txt | 5 ++-- linden/indra/llcharacter/llbvhloader.cpp | 45 +++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 0a2561a..b3689d6 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -13,7 +13,6 @@ * linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml: Ditto. - * linden/indra/newview/llfilepicker.cpp: Applied patch for VWR-5575 (crash in the file picker dealing with accented characters and bad locale) by Alissa Sabre. @@ -27,12 +26,14 @@ * linden/indra/newview/lldrawable.cpp: Backported fix for VWR-3871 (prim position appears to be off) from 1.22. - * linden/indra/newview/llcompilequeue.cpp: Backported fix for SVC-2771 (script resetting can fail) from 1.22. * linden/indra/newview/llviewermenu.cpp: Ditto. + * linden/indra/llcharacter/llbvhloader.cpp: + Backported fix for VWR-996 (wrong visualisation of animations) from 1.22. + =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =- 1.1.0 RC2 -= diff --git a/linden/indra/llcharacter/llbvhloader.cpp b/linden/indra/llcharacter/llbvhloader.cpp index cd1f492..938f47d 100644 --- a/linden/indra/llcharacter/llbvhloader.cpp +++ b/linden/indra/llcharacter/llbvhloader.cpp @@ -1133,6 +1133,8 @@ void LLBVHLoader::optimize() F32 rot_threshold = ROTATION_KEYFRAME_THRESHOLD / llmax((F32)joint->mChildTreeMaxDepth * 0.33f, 1.f); + double diff_max = 0; + KeyVector::iterator ki_max = ki; for (; ki != joint->mKeys.end(); ++ki) { if (ki_prev == ki_last_good_pos) @@ -1193,30 +1195,55 @@ void LLBVHLoader::optimize() F32 x_delta; F32 y_delta; F32 rot_test; - + + // Test if the rotation has changed significantly since the very first frame. If false + // for all frames, then we'll just throw out this joint's rotation entirely. x_delta = dist_vec(LLVector3::x_axis * first_frame_rot, LLVector3::x_axis * test_rot); y_delta = dist_vec(LLVector3::y_axis * first_frame_rot, LLVector3::y_axis * test_rot); rot_test = x_delta + y_delta; - if (rot_test > ROTATION_MOTION_THRESHOLD) { rot_changed = TRUE; } - x_delta = dist_vec(LLVector3::x_axis * interp_rot, LLVector3::x_axis * test_rot); y_delta = dist_vec(LLVector3::y_axis * interp_rot, LLVector3::y_axis * test_rot); rot_test = x_delta + y_delta; - if (rot_test < rot_threshold) - { - ki_prev->mIgnoreRot = TRUE; - numRotFramesConsidered++; - } - else + // Draw a line between the last good keyframe and current. Test the distance between the last frame (current-1, i.e. ki_prev) + // and the line. If it's greater than some threshold, then it represents a significant frame and we want to include it. + if (rot_test >= rot_threshold || + (ki+1 == joint->mKeys.end() && numRotFramesConsidered > 2)) { + // Add the current test keyframe (which is technically the previous key, i.e. ki_prev). numRotFramesConsidered = 2; ki_last_good_rot = ki_prev; joint->mNumRotKeys++; + + // Add another keyframe between the last good keyframe and current, at whatever point was the most "significant" (i.e. + // had the largest deviation from the earlier tests). Note that a more robust approach would be test all intermediate + // keyframes against the line between the last good keyframe and current, but we're settling for this other method + // because it's significantly faster. + if (diff_max > 0) + { + if (ki_max->mIgnoreRot == TRUE) + { + ki_max->mIgnoreRot = FALSE; + joint->mNumRotKeys++; + } + diff_max = 0; + } + } + else + { + // This keyframe isn't significant enough, throw it away. + ki_prev->mIgnoreRot = TRUE; + numRotFramesConsidered++; + // Store away the keyframe that has the largest deviation from the interpolated line, for insertion later. + if (rot_test > diff_max) + { + diff_max = rot_test; + ki_max = ki; + } } } -- cgit v1.1