diff options
| author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
|---|---|---|
| committer | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
| commit | 1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch) | |
| tree | ab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llfloaterbvhpreview.cpp | |
| parent | 6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff) | |
| parent | e1623bb276f83a43ce7a197e388720c05bdefe61 (diff) | |
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts:
# autobuild.xml
# indra/cmake/CMakeLists.txt
# indra/cmake/GoogleMock.cmake
# indra/llaudio/llaudioengine_fmodstudio.cpp
# indra/llaudio/llaudioengine_fmodstudio.h
# indra/llaudio/lllistener_fmodstudio.cpp
# indra/llaudio/lllistener_fmodstudio.h
# indra/llaudio/llstreamingaudio_fmodstudio.cpp
# indra/llaudio/llstreamingaudio_fmodstudio.h
# indra/llcharacter/llmultigesture.cpp
# indra/llcharacter/llmultigesture.h
# indra/llimage/llimage.cpp
# indra/llimage/llimagepng.cpp
# indra/llimage/llimageworker.cpp
# indra/llimage/tests/llimageworker_test.cpp
# indra/llmessage/tests/llmockhttpclient.h
# indra/llprimitive/llgltfmaterial.h
# indra/llrender/llfontfreetype.cpp
# indra/llui/llcombobox.cpp
# indra/llui/llfolderview.cpp
# indra/llui/llfolderviewmodel.h
# indra/llui/lllineeditor.cpp
# indra/llui/lllineeditor.h
# indra/llui/lltextbase.cpp
# indra/llui/lltextbase.h
# indra/llui/lltexteditor.cpp
# indra/llui/lltextvalidate.cpp
# indra/llui/lltextvalidate.h
# indra/llui/lluictrl.h
# indra/llui/llview.cpp
# indra/llwindow/llwindowmacosx.cpp
# indra/newview/app_settings/settings.xml
# indra/newview/llappearancemgr.cpp
# indra/newview/llappearancemgr.h
# indra/newview/llavatarpropertiesprocessor.cpp
# indra/newview/llavatarpropertiesprocessor.h
# indra/newview/llbreadcrumbview.cpp
# indra/newview/llbreadcrumbview.h
# indra/newview/llbreastmotion.cpp
# indra/newview/llbreastmotion.h
# indra/newview/llconversationmodel.h
# indra/newview/lldensityctrl.cpp
# indra/newview/lldensityctrl.h
# indra/newview/llface.inl
# indra/newview/llfloatereditsky.cpp
# indra/newview/llfloatereditwater.cpp
# indra/newview/llfloateremojipicker.h
# indra/newview/llfloaterimsessiontab.cpp
# indra/newview/llfloaterprofiletexture.cpp
# indra/newview/llfloaterprofiletexture.h
# indra/newview/llgesturemgr.cpp
# indra/newview/llgesturemgr.h
# indra/newview/llimpanel.cpp
# indra/newview/llimpanel.h
# indra/newview/llinventorybridge.cpp
# indra/newview/llinventorybridge.h
# indra/newview/llinventoryclipboard.cpp
# indra/newview/llinventoryclipboard.h
# indra/newview/llinventoryfunctions.cpp
# indra/newview/llinventoryfunctions.h
# indra/newview/llinventorygallery.cpp
# indra/newview/lllistbrowser.cpp
# indra/newview/lllistbrowser.h
# indra/newview/llpanelobjectinventory.cpp
# indra/newview/llpanelprofile.cpp
# indra/newview/llpanelprofile.h
# indra/newview/llpreviewgesture.cpp
# indra/newview/llsavedsettingsglue.cpp
# indra/newview/llsavedsettingsglue.h
# indra/newview/lltooldraganddrop.cpp
# indra/newview/llurllineeditorctrl.cpp
# indra/newview/llvectorperfoptions.cpp
# indra/newview/llvectorperfoptions.h
# indra/newview/llviewerparceloverlay.cpp
# indra/newview/llviewertexlayer.cpp
# indra/newview/llviewertexturelist.cpp
# indra/newview/macmain.h
# indra/test/test.cpp
Diffstat (limited to 'indra/newview/llfloaterbvhpreview.cpp')
| -rw-r--r-- | indra/newview/llfloaterbvhpreview.cpp | 2390 |
1 files changed, 1195 insertions, 1195 deletions
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index a21ed1ac90..43e1effdd8 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1,1195 +1,1195 @@ -/** - * @file llfloaterbvhpreview.cpp - * @brief LLFloaterBvhPreview class implementation - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterbvhpreview.h" - -#include "llbvhloader.h" -#include "lldatapacker.h" -#include "lldir.h" -#include "llnotificationsutil.h" -#include "llfilesystem.h" -#include "llapr.h" -#include "llstring.h" - -#include "llagent.h" -#include "llagentbenefits.h" -#include "llanimationstates.h" -#include "llbbox.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "lldrawable.h" -#include "lldrawpoolavatar.h" -#include "llrender.h" -#include "llface.h" -#include "llfocusmgr.h" -#include "llkeyframemotion.h" -#include "lllineeditor.h" -#include "llfloaterperms.h" -#include "llsliderctrl.h" -#include "llspinctrl.h" -#include "lltextbox.h" -#include "lltoolmgr.h" -#include "llui.h" -#include "llviewercamera.h" -#include "llviewerobjectlist.h" -#include "llviewerwindow.h" -#include "llviewermenufile.h" // upload_new_resource() -#include "llvoavatar.h" -#include "pipeline.h" -#include "lluictrlfactory.h" -#include "lltrans.h" - -const S32 PREVIEW_BORDER_WIDTH = 2; -const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; -const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; -const S32 PREVIEW_VPAD = 35; -const S32 PREF_BUTTON_HEIGHT = 16 + 35; -const S32 PREVIEW_TEXTURE_HEIGHT = 300; - -const F32 PREVIEW_CAMERA_DISTANCE = 4.f; - -const F32 MIN_CAMERA_ZOOM = 0.5f; -const F32 MAX_CAMERA_ZOOM = 10.f; - -const F32 BASE_ANIM_TIME_OFFSET = 5.f; - -std::string STATUS[] = -{ - "E_ST_OK", - "E_ST_EOF", - "E_ST_NO_CONSTRAINT", - "E_ST_NO_FILE", - "E_ST_NO_HIER", - "E_ST_NO_JOINT", - "E_ST_NO_NAME", - "E_ST_NO_OFFSET", - "E_ST_NO_CHANNELS", - "E_ST_NO_ROTATION", - "E_ST_NO_AXIS", - "E_ST_NO_MOTION", - "E_ST_NO_FRAMES", - "E_ST_NO_FRAME_TIME", - "E_ST_NO_POS", - "E_ST_NO_ROT", - "E_ST_NO_XLT_FILE", - "E_ST_NO_XLT_HEADER", - "E_ST_NO_XLT_NAME", - "E_ST_NO_XLT_IGNORE", - "E_ST_NO_XLT_RELATIVE", - "E_ST_NO_XLT_OUTNAME", - "E_ST_NO_XLT_MATRIX", - "E_ST_NO_XLT_MERGECHILD", - "E_ST_NO_XLT_MERGEPARENT", - "E_ST_NO_XLT_PRIORITY", - "E_ST_NO_XLT_LOOP", - "E_ST_NO_XLT_EASEIN", - "E_ST_NO_XLT_EASEOUT", - "E_ST_NO_XLT_HAND", - "E_ST_NO_XLT_EMOTE", -"E_ST_BAD_ROOT" -}; - -//----------------------------------------------------------------------------- -// LLFloaterBvhPreview() -//----------------------------------------------------------------------------- -LLFloaterBvhPreview::LLFloaterBvhPreview(const std::string& filename) : - LLFloaterNameDesc(filename) -{ - mLastMouseX = 0; - mLastMouseY = 0; - - mIDList["Standing"] = ANIM_AGENT_STAND; - mIDList["Walking"] = ANIM_AGENT_FEMALE_WALK; - mIDList["Sitting"] = ANIM_AGENT_SIT_FEMALE; - mIDList["Flying"] = ANIM_AGENT_HOVER; - - mIDList["[None]"] = LLUUID::null; - mIDList["Aaaaah"] = ANIM_AGENT_EXPRESS_OPEN_MOUTH; - mIDList["Afraid"] = ANIM_AGENT_EXPRESS_AFRAID; - mIDList["Angry"] = ANIM_AGENT_EXPRESS_ANGER; - mIDList["Big Smile"] = ANIM_AGENT_EXPRESS_TOOTHSMILE; - mIDList["Bored"] = ANIM_AGENT_EXPRESS_BORED; - mIDList["Cry"] = ANIM_AGENT_EXPRESS_CRY; - mIDList["Disdain"] = ANIM_AGENT_EXPRESS_DISDAIN; - mIDList["Embarrassed"] = ANIM_AGENT_EXPRESS_EMBARRASSED; - mIDList["Frown"] = ANIM_AGENT_EXPRESS_FROWN; - mIDList["Kiss"] = ANIM_AGENT_EXPRESS_KISS; - mIDList["Laugh"] = ANIM_AGENT_EXPRESS_LAUGH; - mIDList["Plllppt"] = ANIM_AGENT_EXPRESS_TONGUE_OUT; - mIDList["Repulsed"] = ANIM_AGENT_EXPRESS_REPULSED; - mIDList["Sad"] = ANIM_AGENT_EXPRESS_SAD; - mIDList["Shrug"] = ANIM_AGENT_EXPRESS_SHRUG; - mIDList["Smile"] = ANIM_AGENT_EXPRESS_SMILE; - mIDList["Surprise"] = ANIM_AGENT_EXPRESS_SURPRISE; - mIDList["Wink"] = ANIM_AGENT_EXPRESS_WINK; - mIDList["Worry"] = ANIM_AGENT_EXPRESS_WORRY; -} - -//----------------------------------------------------------------------------- -// setAnimCallbacks() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::setAnimCallbacks() -{ - getChild<LLUICtrl>("playback_slider")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onSliderMove, this)); - - getChild<LLUICtrl>("preview_base_anim")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitBaseAnim, this)); - getChild<LLUICtrl>("preview_base_anim")->setValue("Standing"); - - getChild<LLUICtrl>("priority")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitPriority, this)); - getChild<LLUICtrl>("loop_check")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoop, this)); - getChild<LLUICtrl>("loop_in_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopIn, this)); - getChild<LLUICtrl>("loop_in_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopIn, this, _1)); - getChild<LLUICtrl>("loop_out_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopOut, this)); - getChild<LLUICtrl>("loop_out_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopOut, this, _1)); - - getChild<LLUICtrl>("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitHandPose, this)); - - getChild<LLUICtrl>("emote_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEmote, this)); - getChild<LLUICtrl>("emote_combo")->setValue("[None]"); - - getChild<LLUICtrl>("ease_in_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseIn, this)); - getChild<LLUICtrl>("ease_in_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseIn, this, _1)); - getChild<LLUICtrl>("ease_out_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseOut, this)); - getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); -} - -std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases() -{ - LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar(); - return av->getJointAliases(); -} - -//----------------------------------------------------------------------------- -// postBuild() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::postBuild() -{ - LLKeyframeMotion* motionp = NULL; - LLBVHLoader* loaderp = NULL; - - if (!LLFloaterNameDesc::postBuild()) - { - return false; - } - - getChild<LLUICtrl>("name_form")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitName, this)); - - childSetAction("ok_btn", onBtnOK, this); - setDefaultBtn(); - - mPreviewRect.set(PREVIEW_HPAD, - PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD, - getRect().getWidth() - PREVIEW_HPAD, - PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f); - - mPlayButton = getChild<LLButton>( "play_btn"); - mPlayButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnPlay, this)); - mPlayButton->setVisible(true); - - mPauseButton = getChild<LLButton>( "pause_btn"); - mPauseButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnPause, this)); - mPauseButton->setVisible(false); - - mStopButton = getChild<LLButton>( "stop_btn"); - mStopButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnStop, this)); - - getChildView("bad_animation_text")->setVisible(false); - - mAnimPreview = new LLPreviewAnimation(256, 256); - - std::string exten = gDirUtilp->getExtension(mFilename); - if (exten == "bvh") - { - // loading a bvh file - - // now load bvh file - S32 file_size; - - LLAPRFile infile ; - infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size); - - if (!infile.getFileHandle()) - { - LL_WARNS() << "Can't open BVH file:" << mFilename << LL_ENDL; - } - else - { - char* file_buffer; - - file_buffer = new char[file_size + 1]; - - if (file_size == infile.read(file_buffer, file_size)) - { - file_buffer[file_size] = '\0'; - LL_INFOS() << "Loading BVH file " << mFilename << LL_ENDL; - ELoadStatus load_status = E_ST_OK; - S32 line_number = 0; - - std::map<std::string, std::string> joint_alias_map = getJointAliases(); - - loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map); - std::string status = getString(STATUS[load_status]); - - if(load_status == E_ST_NO_XLT_FILE) - { - LL_WARNS() << "NOTE: No translation table found." << LL_ENDL; - } - else - { - LL_WARNS() << "ERROR: [line: " << line_number << "] " << status << LL_ENDL; - } - } - - infile.close() ; - delete[] file_buffer; - } - } - - if (loaderp && loaderp->isInitialized() && loaderp->getDuration() <= MAX_ANIM_DURATION) - { - // generate unique id for this motion - mTransactionID.generate(); - mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID()); - - // 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 - motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID); - - // create data buffer for keyframe initialization - S32 buffer_size = loaderp->getOutputSize(); - U8* buffer = new U8[buffer_size]; - - LLDataPackerBinaryBuffer dp(buffer, buffer_size); - - // pass animation data through memory buffer - LL_INFOS("BVH") << "Serializing loaderp" << LL_ENDL; - loaderp->serialize(dp); - dp.reset(); - LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; - bool success = motionp && motionp->deserialize(dp, mMotionID, false); - LL_INFOS("BVH") << "Done" << LL_ENDL; - - delete []buffer; - - if (success) - { - setAnimCallbacks() ; - - const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox(); - - LLVector3 temp = pelvis_bbox.getCenter(); - // only consider XY? - //temp.mV[VZ] = 0.f; - F32 pelvis_offset = temp.magVec(); - - temp = pelvis_bbox.getExtent(); - //temp.mV[VZ] = 0.f; - F32 pelvis_max_displacement = pelvis_offset + (temp.magVec() * 0.5f) + 1.f; - - F32 camera_zoom = LLViewerCamera::getInstance()->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE)); - - mAnimPreview->setZoom(camera_zoom); - - motionp->setName(getChild<LLUICtrl>("name_form")->getValue().asString()); - mAnimPreview->getDummyAvatar()->startMotion(mMotionID); - - getChild<LLSlider>("playback_slider")->setMinValue(0.0); - getChild<LLSlider>("playback_slider")->setMaxValue(1.0); - - getChild<LLUICtrl>("loop_check")->setValue(LLSD(motionp->getLoop())); - getChild<LLUICtrl>("loop_in_point")->setValue(LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f)); - getChild<LLUICtrl>("loop_out_point")->setValue(LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f)); - getChild<LLUICtrl>("priority")->setValue(LLSD((F32)motionp->getPriority())); - getChild<LLUICtrl>("hand_pose_combo")->setValue(LLHandMotion::getHandPoseName(motionp->getHandPose())); - getChild<LLUICtrl>("ease_in_time")->setValue(LLSD(motionp->getEaseInDuration())); - getChild<LLUICtrl>("ease_out_time")->setValue(LLSD(motionp->getEaseOutDuration())); - setEnabled(true); - std::string seconds_string; - seconds_string = llformat(" - %.2f seconds", motionp->getDuration()); - - setTitle(mFilename + std::string(seconds_string)); - } - else - { - mAnimPreview = NULL; - mMotionID.setNull(); - getChild<LLUICtrl>("bad_animation_text")->setValue(getString("failed_to_initialize")); - } - } - else - { - if ( loaderp ) - { - if (loaderp->getDuration() > MAX_ANIM_DURATION) - { - LLUIString out_str = getString("anim_too_long"); - out_str.setArg("[LENGTH]", llformat("%.1f", loaderp->getDuration())); - out_str.setArg("[MAX_LENGTH]", llformat("%.1f", MAX_ANIM_DURATION)); - getChild<LLUICtrl>("bad_animation_text")->setValue(out_str.getString()); - } - else - { - LLUIString out_str = getString("failed_file_read"); - out_str.setArg("[STATUS]", getString(STATUS[loaderp->getStatus()])); - getChild<LLUICtrl>("bad_animation_text")->setValue(out_str.getString()); - } - } - - //setEnabled(false); - mMotionID.setNull(); - mAnimPreview = NULL; - } - - refresh(); - - delete loaderp; - - return true; -} - -//----------------------------------------------------------------------------- -// LLFloaterBvhPreview() -//----------------------------------------------------------------------------- -LLFloaterBvhPreview::~LLFloaterBvhPreview() -{ - mAnimPreview = NULL; - - setEnabled(false); -} - -//----------------------------------------------------------------------------- -// draw() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::draw() -{ - LLFloater::draw(); - LLRect r = getRect(); - - refresh(); - - if (mMotionID.notNull() && mAnimPreview) - { - gGL.color3f(1.f, 1.f, 1.f); - - gGL.getTexUnit(0)->bind(mAnimPreview); - - gGL.begin( LLRender::QUADS ); - { - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); - gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); - } - gGL.end(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - if (!avatarp->areAnimationsPaused()) - { - mAnimPreview->requestUpdate(); - } - } -} - -//----------------------------------------------------------------------------- -// resetMotion() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::resetMotion() -{ - if (!mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - bool paused = avatarp->areAnimationsPaused(); - - LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*>(avatarp->findMotion(mMotionID)); - if( motionp ) - { - // Set emotion - std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString(); - motionp->setEmote(mIDList[emote]); - } - - LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()]; - avatarp->deactivateAllMotions(); - avatarp->startMotion(mMotionID, 0.0f); - avatarp->startMotion(base_id, BASE_ANIM_TIME_OFFSET); - getChild<LLUICtrl>("playback_slider")->setValue(0.0f); - - // Set pose - std::string handpose = getChild<LLUICtrl>("hand_pose_combo")->getValue().asString(); - avatarp->startMotion( ANIM_AGENT_HAND_MOTION, 0.0f ); - - if( motionp ) - { - motionp->setHandPose(LLHandMotion::getHandPose(handpose)); - } - - if (paused) - { - mPauseRequest = avatarp->requestPause(); - } - else - { - mPauseRequest = NULL; - } -} - -//----------------------------------------------------------------------------- -// handleMouseDown() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::handleMouseDown(S32 x, S32 y, MASK mask) -{ - if (mPreviewRect.pointInRect(x, y)) - { - bringToFront( x, y ); - gFocusMgr.setMouseCapture(this); - gViewerWindow->hideCursor(); - mLastMouseX = x; - mLastMouseY = y; - return true; - } - - return LLFloater::handleMouseDown(x, y, mask); -} - -//----------------------------------------------------------------------------- -// handleMouseUp() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::handleMouseUp(S32 x, S32 y, MASK mask) -{ - gFocusMgr.setMouseCapture(nullptr); - gViewerWindow->showCursor(); - return LLFloater::handleMouseUp(x, y, mask); -} - -//----------------------------------------------------------------------------- -// handleHover() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::handleHover(S32 x, S32 y, MASK mask) -{ - MASK local_mask = mask & ~MASK_ALT; - - if (mAnimPreview && hasMouseCapture()) - { - if (local_mask == MASK_PAN) - { - // pan here - mAnimPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); - } - else if (local_mask == MASK_ORBIT) - { - F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; - F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f; - - mAnimPreview->rotate(yaw_radians, pitch_radians); - } - else - { - F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; - F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; - - mAnimPreview->rotate(yaw_radians, 0.f); - mAnimPreview->zoom(zoom_amt); - } - - mAnimPreview->requestUpdate(); - - LLUI::getInstance()->setMousePositionLocal(this, mLastMouseX, mLastMouseY); - } - - if (!mPreviewRect.pointInRect(x, y) || !mAnimPreview) - { - return LLFloater::handleHover(x, y, mask); - } - else if (local_mask == MASK_ORBIT) - { - gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA); - } - else if (local_mask == MASK_PAN) - { - gViewerWindow->setCursor(UI_CURSOR_TOOLPAN); - } - else - { - gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); - } - - return true; -} - -//----------------------------------------------------------------------------- -// handleScrollWheel() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) -{ - if (!mAnimPreview) - return false; - - mAnimPreview->zoom((F32)clicks * -0.2f); - mAnimPreview->requestUpdate(); - - return true; -} - -//----------------------------------------------------------------------------- -// onMouseCaptureLost() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onMouseCaptureLost() -{ - gViewerWindow->showCursor(); -} - -//----------------------------------------------------------------------------- -// onBtnPlay() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onBtnPlay() -{ - if (!getEnabled()) - return; - - if (mMotionID.notNull() && mAnimPreview) - { - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - - if (!avatarp->isMotionActive(mMotionID)) - { - resetMotion(); - mPauseRequest = NULL; - } - else if (avatarp->areAnimationsPaused()) - { - mPauseRequest = NULL; - } - } -} - -//----------------------------------------------------------------------------- -// onBtnPause() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onBtnPause() -{ - if (!getEnabled()) - return; - - if (mMotionID.notNull() && mAnimPreview) - { - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - - if (avatarp->isMotionActive(mMotionID)) - { - if (!avatarp->areAnimationsPaused()) - { - mPauseRequest = avatarp->requestPause(); - } - } - } -} - -//----------------------------------------------------------------------------- -// onBtnStop() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onBtnStop() -{ - if (!getEnabled()) - return; - - if (mMotionID.notNull() && mAnimPreview) - { - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - resetMotion(); - mPauseRequest = avatarp->requestPause(); - } -} - -//----------------------------------------------------------------------------- -// onSliderMove() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onSliderMove() -{ - if (!getEnabled()) - return; - - if (mAnimPreview) - { - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - F32 slider_value = (F32)getChild<LLUICtrl>("playback_slider")->getValue().asReal(); - LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()]; - LLMotion* motionp = avatarp->findMotion(mMotionID); - F32 duration = motionp->getDuration();// + motionp->getEaseOutDuration(); - F32 delta_time = duration * slider_value; - avatarp->deactivateAllMotions(); - avatarp->startMotion(base_id, delta_time + BASE_ANIM_TIME_OFFSET); - avatarp->startMotion(mMotionID, delta_time); - mPauseRequest = avatarp->requestPause(); - refresh(); - } - -} - -//----------------------------------------------------------------------------- -// onCommitBaseAnim() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitBaseAnim() -{ - if (!getEnabled()) - return; - - if (mAnimPreview) - { - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - - bool paused = avatarp->areAnimationsPaused(); - - // stop all other possible base motions - avatarp->stopMotion(mIDList["Standing"], true); - avatarp->stopMotion(mIDList["Walking"], true); - avatarp->stopMotion(mIDList["Sitting"], true); - avatarp->stopMotion(mIDList["Flying"], true); - - resetMotion(); - - if (!paused) - { - mPauseRequest = NULL; - } - } -} - -//----------------------------------------------------------------------------- -// onCommitLoop() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitLoop() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - if (motionp) - { - motionp->setLoop(getChild<LLUICtrl>("loop_check")->getValue().asBoolean()); - motionp->setLoopIn((F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal() * 0.01f * motionp->getDuration()); - motionp->setLoopOut((F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal() * 0.01f * motionp->getDuration()); - } -} - -//----------------------------------------------------------------------------- -// onCommitLoopIn() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitLoopIn() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - if (motionp) - { - motionp->setLoopIn((F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal() / 100.f); - resetMotion(); - getChild<LLUICtrl>("loop_check")->setValue(LLSD(true)); - onCommitLoop(); - } -} - -//----------------------------------------------------------------------------- -// onCommitLoopOut() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitLoopOut() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - if (motionp) - { - motionp->setLoopOut((F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal() * 0.01f * motionp->getDuration()); - resetMotion(); - getChild<LLUICtrl>("loop_check")->setValue(LLSD(true)); - onCommitLoop(); - } -} - -//----------------------------------------------------------------------------- -// onCommitName() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitName() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - if (motionp) - { - motionp->setName(getChild<LLUICtrl>("name_form")->getValue().asString()); - } - - doCommit(); -} - -//----------------------------------------------------------------------------- -// onCommitHandPose() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitHandPose() -{ - if (!getEnabled()) - return; - - resetMotion(); // sets hand pose -} - -//----------------------------------------------------------------------------- -// onCommitEmote() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitEmote() -{ - if (!getEnabled()) - return; - - resetMotion(); // ssts emote -} - -//----------------------------------------------------------------------------- -// onCommitPriority() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitPriority() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - motionp->setPriority(llfloor((F32)getChild<LLUICtrl>("priority")->getValue().asReal())); -} - -//----------------------------------------------------------------------------- -// onCommitEaseIn() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitEaseIn() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - motionp->setEaseIn((F32)getChild<LLUICtrl>("ease_in_time")->getValue().asReal()); - resetMotion(); -} - -//----------------------------------------------------------------------------- -// onCommitEaseOut() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onCommitEaseOut() -{ - if (!getEnabled() || !mAnimPreview) - return; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - motionp->setEaseOut((F32)getChild<LLUICtrl>("ease_out_time")->getValue().asReal()); - resetMotion(); -} - -//----------------------------------------------------------------------------- -// validateEaseIn() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data) -{ - if (!getEnabled() || !mAnimPreview) - return false; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - if (!motionp->getLoop()) - { - F32 new_ease_in = llclamp((F32)getChild<LLUICtrl>("ease_in_time")->getValue().asReal(), 0.f, motionp->getDuration() - motionp->getEaseOutDuration()); - getChild<LLUICtrl>("ease_in_time")->setValue(LLSD(new_ease_in)); - } - - return true; -} - -//----------------------------------------------------------------------------- -// validateEaseOut() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::validateEaseOut(const LLSD& data) -{ - if (!getEnabled() || !mAnimPreview) - return false; - - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - - if (!motionp->getLoop()) - { - F32 new_ease_out = llclamp((F32)getChild<LLUICtrl>("ease_out_time")->getValue().asReal(), 0.f, motionp->getDuration() - motionp->getEaseInDuration()); - getChild<LLUICtrl>("ease_out_time")->setValue(LLSD(new_ease_out)); - } - - return true; -} - -//----------------------------------------------------------------------------- -// validateLoopIn() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::validateLoopIn(const LLSD& data) -{ - if (!getEnabled()) - return false; - - F32 loop_in_value = (F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal(); - F32 loop_out_value = (F32)getChild<LLUICtrl>("loop_out_point")->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<LLUICtrl>("loop_in_point")->setValue(LLSD(loop_in_value)); - return true; -} - -//----------------------------------------------------------------------------- -// validateLoopOut() -//----------------------------------------------------------------------------- -bool LLFloaterBvhPreview::validateLoopOut(const LLSD& data) -{ - if (!getEnabled()) - return false; - - F32 loop_out_value = (F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal(); - F32 loop_in_value = (F32)getChild<LLUICtrl>("loop_in_point")->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<LLUICtrl>("loop_out_point")->setValue(LLSD(loop_out_value)); - return true; -} - - -//----------------------------------------------------------------------------- -// refresh() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::refresh() -{ - // Are we showing the play button (default) or the pause button? - bool show_play = true; - if (!mAnimPreview) - { - getChildView("bad_animation_text")->setVisible(true); - // play button visible but disabled - mPlayButton->setEnabled(false); - mStopButton->setEnabled(false); - getChildView("ok_btn")->setEnabled(false); - } - else - { - getChildView("bad_animation_text")->setVisible(false); - // re-enabled in case previous animation was bad - mPlayButton->setEnabled(true); - mStopButton->setEnabled(true); - LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar(); - if (avatarp->isMotionActive(mMotionID)) - { - mStopButton->setEnabled(true); - LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID); - if (!avatarp->areAnimationsPaused()) - { - // animation is playing - if (motionp) - { - F32 fraction_complete = motionp->getLastUpdateTime() / motionp->getDuration(); - getChild<LLUICtrl>("playback_slider")->setValue(fraction_complete); - } - show_play = false; - } - } - else - { - // Motion just finished playing - mPauseRequest = avatarp->requestPause(); - } - getChildView("ok_btn")->setEnabled(true); - mAnimPreview->requestUpdate(); - } - mPlayButton->setVisible(show_play); - mPauseButton->setVisible(!show_play); -} - -//----------------------------------------------------------------------------- -// onBtnOK() -//----------------------------------------------------------------------------- -void LLFloaterBvhPreview::onBtnOK(void* userdata) -{ - LLFloaterBvhPreview* floaterp = (LLFloaterBvhPreview*)userdata; - if (!floaterp->getEnabled()) return; - - if (floaterp->mAnimPreview) - { - LLKeyframeMotion* motionp = (LLKeyframeMotion*)floaterp->mAnimPreview->getDummyAvatar()->findMotion(floaterp->mMotionID); - - S32 file_size = motionp->getFileSize(); - U8* buffer = new U8[file_size]; - - LLDataPackerBinaryBuffer dp(buffer, file_size); - if (motionp->serialize(dp)) - { - LLFileSystem file(motionp->getID(), LLAssetType::AT_ANIMATION, LLFileSystem::APPEND); - - S32 size = dp.getCurrentSize(); - if (file.write((U8*)buffer, size)) - { - std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString(); - std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString(); - S32 expected_upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost(); - - LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( - floaterp->mTransactionID, LLAssetType::AT_ANIMATION, - name, desc, 0, - LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); - - upload_new_resource(assetUploadInfo); - } - else - { - LL_WARNS() << "Failure writing animation data." << LL_ENDL; - LLNotificationsUtil::add("WriteAnimationFail"); - } - } - - delete [] buffer; - // clear out cache for motion data - floaterp->mAnimPreview->getDummyAvatar()->removeMotion(floaterp->mMotionID); - LLKeyframeDataCache::removeKeyframeData(floaterp->mMotionID); - } - - floaterp->closeFloater(false); -} - -//----------------------------------------------------------------------------- -// LLPreviewAnimation -//----------------------------------------------------------------------------- -LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, false) -{ - mNeedsUpdate = true; - mCameraDistance = PREVIEW_CAMERA_DISTANCE; - mCameraYaw = 0.f; - mCameraPitch = 0.f; - mCameraZoom = 1.f; - - mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR); - mDummyAvatar->mSpecialRenderMode = 1; - mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); - - // on idle overall apperance update will set skirt to visible, so either - // call early or account for mSpecialRenderMode in updateMeshVisibility - mDummyAvatar->updateOverallAppearance(); - mDummyAvatar->hideHair(); - mDummyAvatar->hideSkirt(); - - // stop extraneous animations - mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, true ); - mDummyAvatar->stopMotion( ANIM_AGENT_EYE, true ); - mDummyAvatar->stopMotion( ANIM_AGENT_BODY_NOISE, true ); - mDummyAvatar->stopMotion( ANIM_AGENT_BREATHE_ROT, true ); -} - -//----------------------------------------------------------------------------- -// LLPreviewAnimation() -//----------------------------------------------------------------------------- -LLPreviewAnimation::~LLPreviewAnimation() -{ - mDummyAvatar->markDead(); -} - -//virtual -S8 LLPreviewAnimation::getType() const -{ - return LLViewerDynamicTexture::LL_PREVIEW_ANIMATION ; -} - -//----------------------------------------------------------------------------- -// update() -//----------------------------------------------------------------------------- -bool LLPreviewAnimation::render() -{ - mNeedsUpdate = false; - LLVOAvatar* avatarp = mDummyAvatar; - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); - - gUIProgram.bind(); - - LLGLSUIDefault def; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.color4f(0.15f, 0.2f, 0.3f, 1.f); - - gl_rect_2d_simple( mFullWidth, mFullHeight ); - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - - gGL.flush(); - - LLVector3 target_pos = avatarp->mRoot->getWorldPosition(); - - LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * - LLQuaternion(mCameraYaw, LLVector3::z_axis); - - LLViewerCamera* camera = LLViewerCamera::getInstance(); - - LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot; - camera->setOriginAndLookAt( - target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera - LLVector3::z_axis, // up - target_pos + (mCameraOffset * av_rot) ); // point of interest - - camera->setViewNoBroadcast(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); - camera->setAspect((F32) mFullWidth / (F32) mFullHeight); - camera->setPerspective(false, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, false); - - //SJB: Animation is updated in LLVOAvatar::updateCharacter - - if (avatarp->mDrawable.notNull()) - { - avatarp->updateLOD(); - - LLVertexBuffer::unbind(); - LLGLDepthTest gls_depth(GL_TRUE); - - LLFace* face = avatarp->mDrawable->getFace(0); - if (face) - { - LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); - avatarp->dirtyMesh(); - gPipeline.enableLightsPreview(); - avatarPoolp->renderAvatars(avatarp); // renders only one avatar - } - } - - gGL.color4f(1,1,1,1); - return true; -} - -//----------------------------------------------------------------------------- -// requestUpdate() -//----------------------------------------------------------------------------- -void LLPreviewAnimation::requestUpdate() -{ - mNeedsUpdate = true; -} - -//----------------------------------------------------------------------------- -// rotate() -//----------------------------------------------------------------------------- -void LLPreviewAnimation::rotate(F32 yaw_radians, F32 pitch_radians) -{ - mCameraYaw = mCameraYaw + yaw_radians; - - mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); -} - -//----------------------------------------------------------------------------- -// zoom() -//----------------------------------------------------------------------------- -void LLPreviewAnimation::zoom(F32 zoom_delta) -{ - setZoom(mCameraZoom + zoom_delta); -} - -//----------------------------------------------------------------------------- -// setZoom() -//----------------------------------------------------------------------------- -void LLPreviewAnimation::setZoom(F32 zoom_amt) -{ - mCameraZoom = llclamp(zoom_amt, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM); -} - -//----------------------------------------------------------------------------- -// pan() -//----------------------------------------------------------------------------- -void LLPreviewAnimation::pan(F32 right, F32 up) -{ - mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); - mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); -} - - - +/**
+ * @file llfloaterbvhpreview.cpp
+ * @brief LLFloaterBvhPreview class implementation
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterbvhpreview.h"
+
+#include "llbvhloader.h"
+#include "lldatapacker.h"
+#include "lldir.h"
+#include "llnotificationsutil.h"
+#include "llfilesystem.h"
+#include "llapr.h"
+#include "llstring.h"
+
+#include "llagent.h"
+#include "llagentbenefits.h"
+#include "llanimationstates.h"
+#include "llbbox.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "lldrawable.h"
+#include "lldrawpoolavatar.h"
+#include "llrender.h"
+#include "llface.h"
+#include "llfocusmgr.h"
+#include "llkeyframemotion.h"
+#include "lllineeditor.h"
+#include "llfloaterperms.h"
+#include "llsliderctrl.h"
+#include "llspinctrl.h"
+#include "lltextbox.h"
+#include "lltoolmgr.h"
+#include "llui.h"
+#include "llviewercamera.h"
+#include "llviewerobjectlist.h"
+#include "llviewerwindow.h"
+#include "llviewermenufile.h" // upload_new_resource()
+#include "llvoavatar.h"
+#include "pipeline.h"
+#include "lluictrlfactory.h"
+#include "lltrans.h"
+
+const S32 PREVIEW_BORDER_WIDTH = 2;
+const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
+const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
+const S32 PREVIEW_VPAD = 35;
+const S32 PREF_BUTTON_HEIGHT = 16 + 35;
+const S32 PREVIEW_TEXTURE_HEIGHT = 300;
+
+const F32 PREVIEW_CAMERA_DISTANCE = 4.f;
+
+const F32 MIN_CAMERA_ZOOM = 0.5f;
+const F32 MAX_CAMERA_ZOOM = 10.f;
+
+const F32 BASE_ANIM_TIME_OFFSET = 5.f;
+
+std::string STATUS[] =
+{
+ "E_ST_OK",
+ "E_ST_EOF",
+ "E_ST_NO_CONSTRAINT",
+ "E_ST_NO_FILE",
+ "E_ST_NO_HIER",
+ "E_ST_NO_JOINT",
+ "E_ST_NO_NAME",
+ "E_ST_NO_OFFSET",
+ "E_ST_NO_CHANNELS",
+ "E_ST_NO_ROTATION",
+ "E_ST_NO_AXIS",
+ "E_ST_NO_MOTION",
+ "E_ST_NO_FRAMES",
+ "E_ST_NO_FRAME_TIME",
+ "E_ST_NO_POS",
+ "E_ST_NO_ROT",
+ "E_ST_NO_XLT_FILE",
+ "E_ST_NO_XLT_HEADER",
+ "E_ST_NO_XLT_NAME",
+ "E_ST_NO_XLT_IGNORE",
+ "E_ST_NO_XLT_RELATIVE",
+ "E_ST_NO_XLT_OUTNAME",
+ "E_ST_NO_XLT_MATRIX",
+ "E_ST_NO_XLT_MERGECHILD",
+ "E_ST_NO_XLT_MERGEPARENT",
+ "E_ST_NO_XLT_PRIORITY",
+ "E_ST_NO_XLT_LOOP",
+ "E_ST_NO_XLT_EASEIN",
+ "E_ST_NO_XLT_EASEOUT",
+ "E_ST_NO_XLT_HAND",
+ "E_ST_NO_XLT_EMOTE",
+"E_ST_BAD_ROOT"
+};
+
+//-----------------------------------------------------------------------------
+// LLFloaterBvhPreview()
+//-----------------------------------------------------------------------------
+LLFloaterBvhPreview::LLFloaterBvhPreview(const std::string& filename) :
+ LLFloaterNameDesc(filename)
+{
+ mLastMouseX = 0;
+ mLastMouseY = 0;
+
+ mIDList["Standing"] = ANIM_AGENT_STAND;
+ mIDList["Walking"] = ANIM_AGENT_FEMALE_WALK;
+ mIDList["Sitting"] = ANIM_AGENT_SIT_FEMALE;
+ mIDList["Flying"] = ANIM_AGENT_HOVER;
+
+ mIDList["[None]"] = LLUUID::null;
+ mIDList["Aaaaah"] = ANIM_AGENT_EXPRESS_OPEN_MOUTH;
+ mIDList["Afraid"] = ANIM_AGENT_EXPRESS_AFRAID;
+ mIDList["Angry"] = ANIM_AGENT_EXPRESS_ANGER;
+ mIDList["Big Smile"] = ANIM_AGENT_EXPRESS_TOOTHSMILE;
+ mIDList["Bored"] = ANIM_AGENT_EXPRESS_BORED;
+ mIDList["Cry"] = ANIM_AGENT_EXPRESS_CRY;
+ mIDList["Disdain"] = ANIM_AGENT_EXPRESS_DISDAIN;
+ mIDList["Embarrassed"] = ANIM_AGENT_EXPRESS_EMBARRASSED;
+ mIDList["Frown"] = ANIM_AGENT_EXPRESS_FROWN;
+ mIDList["Kiss"] = ANIM_AGENT_EXPRESS_KISS;
+ mIDList["Laugh"] = ANIM_AGENT_EXPRESS_LAUGH;
+ mIDList["Plllppt"] = ANIM_AGENT_EXPRESS_TONGUE_OUT;
+ mIDList["Repulsed"] = ANIM_AGENT_EXPRESS_REPULSED;
+ mIDList["Sad"] = ANIM_AGENT_EXPRESS_SAD;
+ mIDList["Shrug"] = ANIM_AGENT_EXPRESS_SHRUG;
+ mIDList["Smile"] = ANIM_AGENT_EXPRESS_SMILE;
+ mIDList["Surprise"] = ANIM_AGENT_EXPRESS_SURPRISE;
+ mIDList["Wink"] = ANIM_AGENT_EXPRESS_WINK;
+ mIDList["Worry"] = ANIM_AGENT_EXPRESS_WORRY;
+}
+
+//-----------------------------------------------------------------------------
+// setAnimCallbacks()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::setAnimCallbacks()
+{
+ getChild<LLUICtrl>("playback_slider")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onSliderMove, this));
+
+ getChild<LLUICtrl>("preview_base_anim")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitBaseAnim, this));
+ getChild<LLUICtrl>("preview_base_anim")->setValue("Standing");
+
+ getChild<LLUICtrl>("priority")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitPriority, this));
+ getChild<LLUICtrl>("loop_check")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoop, this));
+ getChild<LLUICtrl>("loop_in_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopIn, this));
+ getChild<LLUICtrl>("loop_in_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopIn, this, _1));
+ getChild<LLUICtrl>("loop_out_point")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitLoopOut, this));
+ getChild<LLUICtrl>("loop_out_point")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateLoopOut, this, _1));
+
+ getChild<LLUICtrl>("hand_pose_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitHandPose, this));
+
+ getChild<LLUICtrl>("emote_combo")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEmote, this));
+ getChild<LLUICtrl>("emote_combo")->setValue("[None]");
+
+ getChild<LLUICtrl>("ease_in_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseIn, this));
+ getChild<LLUICtrl>("ease_in_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseIn, this, _1));
+ getChild<LLUICtrl>("ease_out_time")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitEaseOut, this));
+ getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1));
+}
+
+std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases()
+{
+ LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar();
+ return av->getJointAliases();
+}
+
+//-----------------------------------------------------------------------------
+// postBuild()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::postBuild()
+{
+ LLKeyframeMotion* motionp = NULL;
+ LLBVHLoader* loaderp = NULL;
+
+ if (!LLFloaterNameDesc::postBuild())
+ {
+ return false;
+ }
+
+ getChild<LLUICtrl>("name_form")->setCommitCallback(boost::bind(&LLFloaterBvhPreview::onCommitName, this));
+
+ childSetAction("ok_btn", onBtnOK, this);
+ setDefaultBtn();
+
+ mPreviewRect.set(PREVIEW_HPAD,
+ PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,
+ getRect().getWidth() - PREVIEW_HPAD,
+ PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
+
+ mPlayButton = getChild<LLButton>( "play_btn");
+ mPlayButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnPlay, this));
+ mPlayButton->setVisible(true);
+
+ mPauseButton = getChild<LLButton>( "pause_btn");
+ mPauseButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnPause, this));
+ mPauseButton->setVisible(false);
+
+ mStopButton = getChild<LLButton>( "stop_btn");
+ mStopButton->setClickedCallback(boost::bind(&LLFloaterBvhPreview::onBtnStop, this));
+
+ getChildView("bad_animation_text")->setVisible(false);
+
+ mAnimPreview = new LLPreviewAnimation(256, 256);
+
+ std::string exten = gDirUtilp->getExtension(mFilename);
+ if (exten == "bvh")
+ {
+ // loading a bvh file
+
+ // now load bvh file
+ S32 file_size;
+
+ LLAPRFile infile ;
+ infile.open(mFilenameAndPath, LL_APR_RB, NULL, &file_size);
+
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Can't open BVH file:" << mFilename << LL_ENDL;
+ }
+ else
+ {
+ char* file_buffer;
+
+ file_buffer = new char[file_size + 1];
+
+ if (file_size == infile.read(file_buffer, file_size))
+ {
+ file_buffer[file_size] = '\0';
+ LL_INFOS() << "Loading BVH file " << mFilename << LL_ENDL;
+ ELoadStatus load_status = E_ST_OK;
+ S32 line_number = 0;
+
+ std::map<std::string, std::string> joint_alias_map = getJointAliases();
+
+ loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map);
+ std::string status = getString(STATUS[load_status]);
+
+ if(load_status == E_ST_NO_XLT_FILE)
+ {
+ LL_WARNS() << "NOTE: No translation table found." << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "ERROR: [line: " << line_number << "] " << status << LL_ENDL;
+ }
+ }
+
+ infile.close() ;
+ delete[] file_buffer;
+ }
+ }
+
+ if (loaderp && loaderp->isInitialized() && loaderp->getDuration() <= MAX_ANIM_DURATION)
+ {
+ // generate unique id for this motion
+ mTransactionID.generate();
+ mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
+
+ // 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
+ motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID);
+
+ // create data buffer for keyframe initialization
+ S32 buffer_size = loaderp->getOutputSize();
+ U8* buffer = new U8[buffer_size];
+
+ LLDataPackerBinaryBuffer dp(buffer, buffer_size);
+
+ // pass animation data through memory buffer
+ LL_INFOS("BVH") << "Serializing loaderp" << LL_ENDL;
+ loaderp->serialize(dp);
+ dp.reset();
+ LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL;
+ bool success = motionp && motionp->deserialize(dp, mMotionID, false);
+ LL_INFOS("BVH") << "Done" << LL_ENDL;
+
+ delete []buffer;
+
+ if (success)
+ {
+ setAnimCallbacks() ;
+
+ const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox();
+
+ LLVector3 temp = pelvis_bbox.getCenter();
+ // only consider XY?
+ //temp.mV[VZ] = 0.f;
+ F32 pelvis_offset = temp.magVec();
+
+ temp = pelvis_bbox.getExtent();
+ //temp.mV[VZ] = 0.f;
+ F32 pelvis_max_displacement = pelvis_offset + (temp.magVec() * 0.5f) + 1.f;
+
+ F32 camera_zoom = LLViewerCamera::getInstance()->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE));
+
+ mAnimPreview->setZoom(camera_zoom);
+
+ motionp->setName(getChild<LLUICtrl>("name_form")->getValue().asString());
+ mAnimPreview->getDummyAvatar()->startMotion(mMotionID);
+
+ getChild<LLSlider>("playback_slider")->setMinValue(0.0);
+ getChild<LLSlider>("playback_slider")->setMaxValue(1.0);
+
+ getChild<LLUICtrl>("loop_check")->setValue(LLSD(motionp->getLoop()));
+ getChild<LLUICtrl>("loop_in_point")->setValue(LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
+ getChild<LLUICtrl>("loop_out_point")->setValue(LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f));
+ getChild<LLUICtrl>("priority")->setValue(LLSD((F32)motionp->getPriority()));
+ getChild<LLUICtrl>("hand_pose_combo")->setValue(LLHandMotion::getHandPoseName(motionp->getHandPose()));
+ getChild<LLUICtrl>("ease_in_time")->setValue(LLSD(motionp->getEaseInDuration()));
+ getChild<LLUICtrl>("ease_out_time")->setValue(LLSD(motionp->getEaseOutDuration()));
+ setEnabled(true);
+ std::string seconds_string;
+ seconds_string = llformat(" - %.2f seconds", motionp->getDuration());
+
+ setTitle(mFilename + std::string(seconds_string));
+ }
+ else
+ {
+ mAnimPreview = NULL;
+ mMotionID.setNull();
+ getChild<LLUICtrl>("bad_animation_text")->setValue(getString("failed_to_initialize"));
+ }
+ }
+ else
+ {
+ if ( loaderp )
+ {
+ if (loaderp->getDuration() > MAX_ANIM_DURATION)
+ {
+ LLUIString out_str = getString("anim_too_long");
+ out_str.setArg("[LENGTH]", llformat("%.1f", loaderp->getDuration()));
+ out_str.setArg("[MAX_LENGTH]", llformat("%.1f", MAX_ANIM_DURATION));
+ getChild<LLUICtrl>("bad_animation_text")->setValue(out_str.getString());
+ }
+ else
+ {
+ LLUIString out_str = getString("failed_file_read");
+ out_str.setArg("[STATUS]", getString(STATUS[loaderp->getStatus()]));
+ getChild<LLUICtrl>("bad_animation_text")->setValue(out_str.getString());
+ }
+ }
+
+ //setEnabled(false);
+ mMotionID.setNull();
+ mAnimPreview = NULL;
+ }
+
+ refresh();
+
+ delete loaderp;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// LLFloaterBvhPreview()
+//-----------------------------------------------------------------------------
+LLFloaterBvhPreview::~LLFloaterBvhPreview()
+{
+ mAnimPreview = NULL;
+
+ setEnabled(false);
+}
+
+//-----------------------------------------------------------------------------
+// draw()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::draw()
+{
+ LLFloater::draw();
+ LLRect r = getRect();
+
+ refresh();
+
+ if (mMotionID.notNull() && mAnimPreview)
+ {
+ gGL.color3f(1.f, 1.f, 1.f);
+
+ gGL.getTexUnit(0)->bind(mAnimPreview);
+
+ gGL.begin( LLRender::QUADS );
+ {
+ gGL.texCoord2f(0.f, 1.f);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
+ gGL.texCoord2f(0.f, 0.f);
+ gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ gGL.texCoord2f(1.f, 0.f);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
+ gGL.texCoord2f(1.f, 1.f);
+ gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
+ }
+ gGL.end();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ if (!avatarp->areAnimationsPaused())
+ {
+ mAnimPreview->requestUpdate();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// resetMotion()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::resetMotion()
+{
+ if (!mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ bool paused = avatarp->areAnimationsPaused();
+
+ LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*>(avatarp->findMotion(mMotionID));
+ if( motionp )
+ {
+ // Set emotion
+ std::string emote = getChild<LLUICtrl>("emote_combo")->getValue().asString();
+ motionp->setEmote(mIDList[emote]);
+ }
+
+ LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()];
+ avatarp->deactivateAllMotions();
+ avatarp->startMotion(mMotionID, 0.0f);
+ avatarp->startMotion(base_id, BASE_ANIM_TIME_OFFSET);
+ getChild<LLUICtrl>("playback_slider")->setValue(0.0f);
+
+ // Set pose
+ std::string handpose = getChild<LLUICtrl>("hand_pose_combo")->getValue().asString();
+ avatarp->startMotion( ANIM_AGENT_HAND_MOTION, 0.0f );
+
+ if( motionp )
+ {
+ motionp->setHandPose(LLHandMotion::getHandPose(handpose));
+ }
+
+ if (paused)
+ {
+ mPauseRequest = avatarp->requestPause();
+ }
+ else
+ {
+ mPauseRequest = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// handleMouseDown()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+ if (mPreviewRect.pointInRect(x, y))
+ {
+ bringToFront( x, y );
+ gFocusMgr.setMouseCapture(this);
+ gViewerWindow->hideCursor();
+ mLastMouseX = x;
+ mLastMouseY = y;
+ return true;
+ }
+
+ return LLFloater::handleMouseDown(x, y, mask);
+}
+
+//-----------------------------------------------------------------------------
+// handleMouseUp()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+ gFocusMgr.setMouseCapture(nullptr);
+ gViewerWindow->showCursor();
+ return LLFloater::handleMouseUp(x, y, mask);
+}
+
+//-----------------------------------------------------------------------------
+// handleHover()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::handleHover(S32 x, S32 y, MASK mask)
+{
+ MASK local_mask = mask & ~MASK_ALT;
+
+ if (mAnimPreview && hasMouseCapture())
+ {
+ if (local_mask == MASK_PAN)
+ {
+ // pan here
+ mAnimPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
+ }
+ else if (local_mask == MASK_ORBIT)
+ {
+ F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
+ F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
+
+ mAnimPreview->rotate(yaw_radians, pitch_radians);
+ }
+ else
+ {
+ F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
+ F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
+
+ mAnimPreview->rotate(yaw_radians, 0.f);
+ mAnimPreview->zoom(zoom_amt);
+ }
+
+ mAnimPreview->requestUpdate();
+
+ LLUI::getInstance()->setMousePositionLocal(this, mLastMouseX, mLastMouseY);
+ }
+
+ if (!mPreviewRect.pointInRect(x, y) || !mAnimPreview)
+ {
+ return LLFloater::handleHover(x, y, mask);
+ }
+ else if (local_mask == MASK_ORBIT)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
+ }
+ else if (local_mask == MASK_PAN)
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
+ }
+ else
+ {
+ gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// handleScrollWheel()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ if (!mAnimPreview)
+ return false;
+
+ mAnimPreview->zoom((F32)clicks * -0.2f);
+ mAnimPreview->requestUpdate();
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// onMouseCaptureLost()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onMouseCaptureLost()
+{
+ gViewerWindow->showCursor();
+}
+
+//-----------------------------------------------------------------------------
+// onBtnPlay()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onBtnPlay()
+{
+ if (!getEnabled())
+ return;
+
+ if (mMotionID.notNull() && mAnimPreview)
+ {
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+
+ if (!avatarp->isMotionActive(mMotionID))
+ {
+ resetMotion();
+ mPauseRequest = NULL;
+ }
+ else if (avatarp->areAnimationsPaused())
+ {
+ mPauseRequest = NULL;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onBtnPause()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onBtnPause()
+{
+ if (!getEnabled())
+ return;
+
+ if (mMotionID.notNull() && mAnimPreview)
+ {
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+
+ if (avatarp->isMotionActive(mMotionID))
+ {
+ if (!avatarp->areAnimationsPaused())
+ {
+ mPauseRequest = avatarp->requestPause();
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onBtnStop()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onBtnStop()
+{
+ if (!getEnabled())
+ return;
+
+ if (mMotionID.notNull() && mAnimPreview)
+ {
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ resetMotion();
+ mPauseRequest = avatarp->requestPause();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onSliderMove()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onSliderMove()
+{
+ if (!getEnabled())
+ return;
+
+ if (mAnimPreview)
+ {
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ F32 slider_value = (F32)getChild<LLUICtrl>("playback_slider")->getValue().asReal();
+ LLUUID base_id = mIDList[getChild<LLUICtrl>("preview_base_anim")->getValue().asString()];
+ LLMotion* motionp = avatarp->findMotion(mMotionID);
+ F32 duration = motionp->getDuration();// + motionp->getEaseOutDuration();
+ F32 delta_time = duration * slider_value;
+ avatarp->deactivateAllMotions();
+ avatarp->startMotion(base_id, delta_time + BASE_ANIM_TIME_OFFSET);
+ avatarp->startMotion(mMotionID, delta_time);
+ mPauseRequest = avatarp->requestPause();
+ refresh();
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// onCommitBaseAnim()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitBaseAnim()
+{
+ if (!getEnabled())
+ return;
+
+ if (mAnimPreview)
+ {
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+
+ bool paused = avatarp->areAnimationsPaused();
+
+ // stop all other possible base motions
+ avatarp->stopMotion(mIDList["Standing"], true);
+ avatarp->stopMotion(mIDList["Walking"], true);
+ avatarp->stopMotion(mIDList["Sitting"], true);
+ avatarp->stopMotion(mIDList["Flying"], true);
+
+ resetMotion();
+
+ if (!paused)
+ {
+ mPauseRequest = NULL;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onCommitLoop()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitLoop()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ if (motionp)
+ {
+ motionp->setLoop(getChild<LLUICtrl>("loop_check")->getValue().asBoolean());
+ motionp->setLoopIn((F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal() * 0.01f * motionp->getDuration());
+ motionp->setLoopOut((F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal() * 0.01f * motionp->getDuration());
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onCommitLoopIn()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitLoopIn()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ if (motionp)
+ {
+ motionp->setLoopIn((F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal() / 100.f);
+ resetMotion();
+ getChild<LLUICtrl>("loop_check")->setValue(LLSD(true));
+ onCommitLoop();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onCommitLoopOut()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitLoopOut()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ if (motionp)
+ {
+ motionp->setLoopOut((F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal() * 0.01f * motionp->getDuration());
+ resetMotion();
+ getChild<LLUICtrl>("loop_check")->setValue(LLSD(true));
+ onCommitLoop();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// onCommitName()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitName()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ if (motionp)
+ {
+ motionp->setName(getChild<LLUICtrl>("name_form")->getValue().asString());
+ }
+
+ doCommit();
+}
+
+//-----------------------------------------------------------------------------
+// onCommitHandPose()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitHandPose()
+{
+ if (!getEnabled())
+ return;
+
+ resetMotion(); // sets hand pose
+}
+
+//-----------------------------------------------------------------------------
+// onCommitEmote()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitEmote()
+{
+ if (!getEnabled())
+ return;
+
+ resetMotion(); // ssts emote
+}
+
+//-----------------------------------------------------------------------------
+// onCommitPriority()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitPriority()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ motionp->setPriority(llfloor((F32)getChild<LLUICtrl>("priority")->getValue().asReal()));
+}
+
+//-----------------------------------------------------------------------------
+// onCommitEaseIn()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitEaseIn()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ motionp->setEaseIn((F32)getChild<LLUICtrl>("ease_in_time")->getValue().asReal());
+ resetMotion();
+}
+
+//-----------------------------------------------------------------------------
+// onCommitEaseOut()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onCommitEaseOut()
+{
+ if (!getEnabled() || !mAnimPreview)
+ return;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ motionp->setEaseOut((F32)getChild<LLUICtrl>("ease_out_time")->getValue().asReal());
+ resetMotion();
+}
+
+//-----------------------------------------------------------------------------
+// validateEaseIn()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data)
+{
+ if (!getEnabled() || !mAnimPreview)
+ return false;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ if (!motionp->getLoop())
+ {
+ F32 new_ease_in = llclamp((F32)getChild<LLUICtrl>("ease_in_time")->getValue().asReal(), 0.f, motionp->getDuration() - motionp->getEaseOutDuration());
+ getChild<LLUICtrl>("ease_in_time")->setValue(LLSD(new_ease_in));
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// validateEaseOut()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::validateEaseOut(const LLSD& data)
+{
+ if (!getEnabled() || !mAnimPreview)
+ return false;
+
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+
+ if (!motionp->getLoop())
+ {
+ F32 new_ease_out = llclamp((F32)getChild<LLUICtrl>("ease_out_time")->getValue().asReal(), 0.f, motionp->getDuration() - motionp->getEaseInDuration());
+ getChild<LLUICtrl>("ease_out_time")->setValue(LLSD(new_ease_out));
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// validateLoopIn()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::validateLoopIn(const LLSD& data)
+{
+ if (!getEnabled())
+ return false;
+
+ F32 loop_in_value = (F32)getChild<LLUICtrl>("loop_in_point")->getValue().asReal();
+ F32 loop_out_value = (F32)getChild<LLUICtrl>("loop_out_point")->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<LLUICtrl>("loop_in_point")->setValue(LLSD(loop_in_value));
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// validateLoopOut()
+//-----------------------------------------------------------------------------
+bool LLFloaterBvhPreview::validateLoopOut(const LLSD& data)
+{
+ if (!getEnabled())
+ return false;
+
+ F32 loop_out_value = (F32)getChild<LLUICtrl>("loop_out_point")->getValue().asReal();
+ F32 loop_in_value = (F32)getChild<LLUICtrl>("loop_in_point")->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<LLUICtrl>("loop_out_point")->setValue(LLSD(loop_out_value));
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// refresh()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::refresh()
+{
+ // Are we showing the play button (default) or the pause button?
+ bool show_play = true;
+ if (!mAnimPreview)
+ {
+ getChildView("bad_animation_text")->setVisible(true);
+ // play button visible but disabled
+ mPlayButton->setEnabled(false);
+ mStopButton->setEnabled(false);
+ getChildView("ok_btn")->setEnabled(false);
+ }
+ else
+ {
+ getChildView("bad_animation_text")->setVisible(false);
+ // re-enabled in case previous animation was bad
+ mPlayButton->setEnabled(true);
+ mStopButton->setEnabled(true);
+ LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
+ if (avatarp->isMotionActive(mMotionID))
+ {
+ mStopButton->setEnabled(true);
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
+ if (!avatarp->areAnimationsPaused())
+ {
+ // animation is playing
+ if (motionp)
+ {
+ F32 fraction_complete = motionp->getLastUpdateTime() / motionp->getDuration();
+ getChild<LLUICtrl>("playback_slider")->setValue(fraction_complete);
+ }
+ show_play = false;
+ }
+ }
+ else
+ {
+ // Motion just finished playing
+ mPauseRequest = avatarp->requestPause();
+ }
+ getChildView("ok_btn")->setEnabled(true);
+ mAnimPreview->requestUpdate();
+ }
+ mPlayButton->setVisible(show_play);
+ mPauseButton->setVisible(!show_play);
+}
+
+//-----------------------------------------------------------------------------
+// onBtnOK()
+//-----------------------------------------------------------------------------
+void LLFloaterBvhPreview::onBtnOK(void* userdata)
+{
+ LLFloaterBvhPreview* floaterp = (LLFloaterBvhPreview*)userdata;
+ if (!floaterp->getEnabled()) return;
+
+ if (floaterp->mAnimPreview)
+ {
+ LLKeyframeMotion* motionp = (LLKeyframeMotion*)floaterp->mAnimPreview->getDummyAvatar()->findMotion(floaterp->mMotionID);
+
+ S32 file_size = motionp->getFileSize();
+ U8* buffer = new U8[file_size];
+
+ LLDataPackerBinaryBuffer dp(buffer, file_size);
+ if (motionp->serialize(dp))
+ {
+ LLFileSystem file(motionp->getID(), LLAssetType::AT_ANIMATION, LLFileSystem::APPEND);
+
+ S32 size = dp.getCurrentSize();
+ if (file.write((U8*)buffer, size))
+ {
+ std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();
+ std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString();
+ S32 expected_upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
+
+ LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo(
+ floaterp->mTransactionID, LLAssetType::AT_ANIMATION,
+ name, desc, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(assetUploadInfo);
+ }
+ else
+ {
+ LL_WARNS() << "Failure writing animation data." << LL_ENDL;
+ LLNotificationsUtil::add("WriteAnimationFail");
+ }
+ }
+
+ delete [] buffer;
+ // clear out cache for motion data
+ floaterp->mAnimPreview->getDummyAvatar()->removeMotion(floaterp->mMotionID);
+ LLKeyframeDataCache::removeKeyframeData(floaterp->mMotionID);
+ }
+
+ floaterp->closeFloater(false);
+}
+
+//-----------------------------------------------------------------------------
+// LLPreviewAnimation
+//-----------------------------------------------------------------------------
+LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, false)
+{
+ mNeedsUpdate = true;
+ mCameraDistance = PREVIEW_CAMERA_DISTANCE;
+ mCameraYaw = 0.f;
+ mCameraPitch = 0.f;
+ mCameraZoom = 1.f;
+
+ mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR);
+ mDummyAvatar->mSpecialRenderMode = 1;
+ mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
+
+ // on idle overall apperance update will set skirt to visible, so either
+ // call early or account for mSpecialRenderMode in updateMeshVisibility
+ mDummyAvatar->updateOverallAppearance();
+ mDummyAvatar->hideHair();
+ mDummyAvatar->hideSkirt();
+
+ // stop extraneous animations
+ mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, true );
+ mDummyAvatar->stopMotion( ANIM_AGENT_EYE, true );
+ mDummyAvatar->stopMotion( ANIM_AGENT_BODY_NOISE, true );
+ mDummyAvatar->stopMotion( ANIM_AGENT_BREATHE_ROT, true );
+}
+
+//-----------------------------------------------------------------------------
+// LLPreviewAnimation()
+//-----------------------------------------------------------------------------
+LLPreviewAnimation::~LLPreviewAnimation()
+{
+ mDummyAvatar->markDead();
+}
+
+//virtual
+S8 LLPreviewAnimation::getType() const
+{
+ return LLViewerDynamicTexture::LL_PREVIEW_ANIMATION ;
+}
+
+//-----------------------------------------------------------------------------
+// update()
+//-----------------------------------------------------------------------------
+bool LLPreviewAnimation::render()
+{
+ mNeedsUpdate = false;
+ LLVOAvatar* avatarp = mDummyAvatar;
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gUIProgram.bind();
+
+ LLGLSUIDefault def;
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
+
+ gl_rect_2d_simple( mFullWidth, mFullHeight );
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ gGL.flush();
+
+ LLVector3 target_pos = avatarp->mRoot->getWorldPosition();
+
+ LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
+ LLQuaternion(mCameraYaw, LLVector3::z_axis);
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
+ camera->setOriginAndLookAt(
+ target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
+ LLVector3::z_axis, // up
+ target_pos + (mCameraOffset * av_rot) ); // point of interest
+
+ camera->setViewNoBroadcast(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
+ camera->setAspect((F32) mFullWidth / (F32) mFullHeight);
+ camera->setPerspective(false, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, false);
+
+ //SJB: Animation is updated in LLVOAvatar::updateCharacter
+
+ if (avatarp->mDrawable.notNull())
+ {
+ avatarp->updateLOD();
+
+ LLVertexBuffer::unbind();
+ LLGLDepthTest gls_depth(GL_TRUE);
+
+ LLFace* face = avatarp->mDrawable->getFace(0);
+ if (face)
+ {
+ LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+ avatarp->dirtyMesh();
+ gPipeline.enableLightsPreview();
+ avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ }
+ }
+
+ gGL.color4f(1,1,1,1);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// requestUpdate()
+//-----------------------------------------------------------------------------
+void LLPreviewAnimation::requestUpdate()
+{
+ mNeedsUpdate = true;
+}
+
+//-----------------------------------------------------------------------------
+// rotate()
+//-----------------------------------------------------------------------------
+void LLPreviewAnimation::rotate(F32 yaw_radians, F32 pitch_radians)
+{
+ mCameraYaw = mCameraYaw + yaw_radians;
+
+ mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
+}
+
+//-----------------------------------------------------------------------------
+// zoom()
+//-----------------------------------------------------------------------------
+void LLPreviewAnimation::zoom(F32 zoom_delta)
+{
+ setZoom(mCameraZoom + zoom_delta);
+}
+
+//-----------------------------------------------------------------------------
+// setZoom()
+//-----------------------------------------------------------------------------
+void LLPreviewAnimation::setZoom(F32 zoom_amt)
+{
+ mCameraZoom = llclamp(zoom_amt, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM);
+}
+
+//-----------------------------------------------------------------------------
+// pan()
+//-----------------------------------------------------------------------------
+void LLPreviewAnimation::pan(F32 right, F32 up)
+{
+ mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
+}
+
+
+
|
