diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index de16d86ff4..c2c755664e 100755 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -296,6 +296,10 @@ public: ELoadStatus getStatus() { return mStatus; } + // FIRE-17277: Allow entering Loop In/Loop Out as frames + S32 getNumFrames() { return mNumFrames; } + // + protected: // Consumes one line of input from file. diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 3b1aee77d1..4ad9774397 100755 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -176,6 +176,12 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild("loop_in_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopIn, this, _1)); getChild("loop_out_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopOut, this)); getChild("loop_out_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopOut, this, _1)); + // FIRE-17277: Allow entering Loop In/Loop Out as frames + getChild("loop_in_frames")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopInFrames, this)); + getChild("loop_in_frames")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopInFrames, this, _1)); + getChild("loop_out_frames")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopOutFrames, this)); + getChild("loop_out_frames")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopOutFrames, this, _1)); + // getChild("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitHandPose, this)); @@ -329,6 +335,20 @@ BOOL LLFloaterBvhPreview::loadBVH() // motion will be returned, but it will be in a load-pending state, as this is a new motion // this motion will not request an asset transfer until next update, so we have a chance to // load the keyframe data locally + // FIRE-17277: Allow entering Loop In/Loop Out as frames + mNumFrames = loaderp->getNumFrames(); + getChild("loop_in_frames")->setMaxValue(LLSD((F32)mNumFrames)); + getChild("loop_out_frames")->setMaxValue(LLSD((F32)mNumFrames)); + // (Re)assign loop frames spinners from loop percentages. + getChild("loop_in_frames")->setValue(LLSD((F32)getChild("loop_in_point")->getValue().asReal() / 100.f * (F32)mNumFrames)); + getChild("loop_out_frames")->setValue(LLSD((F32)getChild("loop_out_point")->getValue().asReal() / 100.f * (F32)mNumFrames)); + + LLUIString out_str = getString("FS_report_frames"); + out_str.setArg("[F]", llformat("%d", mNumFrames)); + out_str.setArg("[S]", llformat("%.1f", loaderp->getDuration())); + out_str.setArg("[FPS]", llformat("%.1f", (F32)mNumFrames / loaderp->getDuration())); + getChild("frames_label")->setValue(LLSD(out_str)); + // // Preview on own avatar //motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID); motionp = dynamic_cast(mAnimPreview->getPreviewAvatar(this)->createMotion(mMotionID)); @@ -869,7 +889,10 @@ void LLFloaterBvhPreview::onCommitLoopIn() if (motionp) { - motionp->setLoopIn((F32)getChild("loop_in_point")->getValue().asReal() / 100.f); + // FIRE-17277: Allow entering Loop In/Loop Out as frames + //motionp->setLoopIn((F32)getChild("loop_in_point")->getValue().asReal() / 100.f); + getChild("loop_in_frames")->setValue(LLSD((F32)getChild("loop_in_point")->getValue().asReal() / 100.f * (F32)mNumFrames)); + // resetMotion(); getChild("loop_check")->setValue(LLSD(TRUE)); onCommitLoop(); @@ -893,13 +916,61 @@ void LLFloaterBvhPreview::onCommitLoopOut() if (motionp) { - motionp->setLoopOut((F32)getChild("loop_out_point")->getValue().asReal() * 0.01f * motionp->getDuration()); + // FIRE-17277: Allow entering Loop In/Loop Out as frames + //motionp->setLoopOut((F32)getChild("loop_out_point")->getValue().asReal() * 0.01f * motionp->getDuration()); + getChild("loop_out_frames")->setValue(LLSD((F32)getChild("loop_out_point")->getValue().asReal() / 100.f * (F32)mNumFrames)); + // resetMotion(); getChild("loop_check")->setValue(LLSD(TRUE)); onCommitLoop(); } } +// FIRE-17277: Allow entering Loop In/Loop Out as frames +//----------------------------------------------------------------------------- +// onCommitLoopInFrames() +//----------------------------------------------------------------------------- +void LLFloaterBvhPreview::onCommitLoopInFrames() +{ + if (!getEnabled() || !mAnimPreview) + return; + + // Preview on own avatar + LLVOAvatar* avatarp = mAnimPreview->getPreviewAvatar(this); + LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); + + if (motionp) + { + getChild("loop_in_point")->setValue(LLSD(mNumFrames == 0 ? 0.f : 100.f * (F32)getChild("loop_in_frames")->getValue().asReal() / (F32)mNumFrames)); + resetMotion(); + getChild("loop_check")->setValue(LLSD(TRUE)); + // The values are actually set here: + onCommitLoop(); + } +} + +//----------------------------------------------------------------------------- +// onCommitLoopOutFrames() +//----------------------------------------------------------------------------- +void LLFloaterBvhPreview::onCommitLoopOutFrames() +{ + if (!getEnabled() || !mAnimPreview) + return; + + // Preview on own avatar + LLVOAvatar* avatarp = mAnimPreview->getPreviewAvatar(this); + LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); + + if (motionp) + { + getChild("loop_out_point")->setValue(LLSD(mNumFrames == 0 ? 100.f : 100.f * (F32)getChild("loop_out_frames")->getValue().asReal() / (F32)mNumFrames)); + resetMotion(); + getChild("loop_check")->setValue(LLSD(TRUE)); + onCommitLoop(); + } +} +// + //----------------------------------------------------------------------------- // onCommitName() //----------------------------------------------------------------------------- @@ -1083,6 +1154,9 @@ bool LLFloaterBvhPreview::validateLoopIn(const LLSD& data) } getChild("loop_in_point")->setValue(LLSD(loop_in_value)); + // FIRE-17277: Allow entering Loop In/Loop Out as frames + getChild("loop_in_frames")->setValue(LLSD(loop_in_value / 100.f * (F32)mNumFrames)); + // return true; } @@ -1111,10 +1185,74 @@ bool LLFloaterBvhPreview::validateLoopOut(const LLSD& data) } getChild("loop_out_point")->setValue(LLSD(loop_out_value)); + // FIRE-17277: Allow entering Loop In/Loop Out as frames + getChild("loop_out_frames")->setValue(LLSD(loop_out_value / 100.f * (F32)mNumFrames)); + // return true; } +// FIRE-17277: Allow entering Loop In/Loop Out as frames +//----------------------------------------------------------------------------- +// validateLoopInFrames() +//----------------------------------------------------------------------------- +bool LLFloaterBvhPreview::validateLoopInFrames(const LLSD& data) +{ + if (!getEnabled()) + return false; + + F32 loop_in_value = (F32)getChild("loop_in_frames")->getValue().asReal(); + F32 loop_out_value = (F32)getChild("loop_out_frames")->getValue().asReal(); + + if (loop_in_value < 0.f) + { + loop_in_value = 0.f; + } + else if (loop_in_value > 100.f) + { + loop_in_value = 100.f; + } + else if (loop_in_value > loop_out_value) + { + loop_in_value = loop_out_value; + } + + getChild("loop_in_frames")->setValue(LLSD(loop_in_value)); + getChild("loop_in_point")->setValue(LLSD(mNumFrames == 0 ? 0.f : 100.f * loop_in_value / (F32)mNumFrames)); + return true; +} + +//----------------------------------------------------------------------------- +// validateLoopOutFrames() +//----------------------------------------------------------------------------- +bool LLFloaterBvhPreview::validateLoopOutFrames(const LLSD& data) +{ + if (!getEnabled()) + return false; + + F32 loop_out_value = (F32)getChild("loop_out_frames")->getValue().asReal(); + F32 loop_in_value = (F32)getChild("loop_in_frames")->getValue().asReal(); + + if (loop_out_value < 0.f) + { + loop_out_value = 0.f; + } + else if (loop_out_value > 100.f) + { + loop_out_value = 100.f; + } + else if (loop_out_value < loop_in_value) + { + loop_out_value = loop_in_value; + } + + getChild("loop_out_frames")->setValue(LLSD(loop_out_value)); + getChild("loop_out_point")->setValue(LLSD(mNumFrames == 0 ? 100.f : 100.f * loop_out_value / (F32)mNumFrames)); + return true; +} +// + + //----------------------------------------------------------------------------- // refresh() //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index 6b7e6c3c5d..a803c411ba 100755 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -116,6 +116,12 @@ public: LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); + // FIRE-17277: Allow entering Loop In/Loop Out as frames + void onCommitLoopInFrames(); + void onCommitLoopOutFrames(); + bool validateLoopInFrames(const LLSD& data); + bool validateLoopOutFrames(const LLSD& data); + // private: void setAnimCallbacks() ; // Reload animation from disk @@ -146,6 +152,9 @@ protected: // FIRE-2083: Slider in upload animation floater doesn't work LLFrameTimer mTimer; + + // FIRE-17277: Allow entering Loop In/Loop Out as frames + S32 mNumFrames; }; #endif // LL_LLFLOATERBVHPREVIEW_H diff --git a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml index 453a92c5e5..ef02e1e690 100755 --- a/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_animation_bvh_preview.xml @@ -2,7 +2,7 @@ Incorrect root joint name, use "hip". + + [F] frm. [S] s. [FPS] fps + + + 300 frm. 30 s. 10 fps + + + Unable to read animation file. We recommend BVH files exported from Poser 4.