1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339 |
- /**
- * @file llfloateranimpreview.cpp
- * @brief LLFloaterAnimPreview class implementation
- *
- * $LicenseInfo:firstyear=2004&license=viewergpl$
- *
- * Copyright (c) 2004-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llfloateranimpreview.h"
- #include "llanimationstates.h"
- #include "llbbox.h"
- #include "llbboxlocal.h"
- #include "llbutton.h"
- #include "llbvhloader.h"
- #include "lldatapacker.h"
- #include "lldir.h"
- #include "llfilesystem.h"
- #include "llkeyframemotion.h"
- #include "llnotifications.h"
- #include "llrender.h"
- #include "llresizehandle.h" // For RESIZE_HANDLE_WIDTH
- #include "lluictrlfactory.h"
- #include "llagent.h"
- #include "lldrawable.h"
- #include "lldrawpoolavatar.h"
- #include "llface.h"
- #include "llfloaterperms.h"
- #include "llpipeline.h"
- #include "lltoolmgr.h" // For MASK_* constants
- #include "llviewerassetupload.h" // For upload_new_resource()
- #include "llviewercamera.h"
- #include "llviewercontrol.h"
- #include "llviewerobjectlist.h"
- #include "llviewershadermgr.h"
- #include "llviewerwindow.h"
- #include "llvoavatarself.h"
- constexpr S32 PREVIEW_BORDER_WIDTH = 2;
- constexpr S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) +
- PREVIEW_BORDER_WIDTH;
- constexpr S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
- constexpr S32 PREF_BUTTON_HEIGHT = 16;
- constexpr S32 PREVIEW_TEXTURE_HEIGHT = 300;
- constexpr F32 PREVIEW_CAMERA_DISTANCE = 4.f;
- constexpr F32 MIN_CAMERA_ZOOM = 0.5f;
- constexpr F32 MAX_CAMERA_ZOOM = 10.f;
- constexpr F32 BASE_ANIM_TIME_OFFSET = 5.f;
- static 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"
- };
- //-----------------------------------------------------------------------------
- // LLFloaterAnimPreview()
- //-----------------------------------------------------------------------------
- LLFloaterAnimPreview::LLFloaterAnimPreview(const std::string& filename)
- : HBFloaterUploadAsset(filename, LLInventoryType::IT_ANIMATION),
- mAnimPreview(NULL),
- mInWorld(false),
- mBadAnimation(false)
- {
- 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;
- mPlayImage = LLUI::getUIImage("button_anim_play.tga");
- mPlaySelectedImage = LLUI::getUIImage("button_anim_play_selected.tga");
- mPauseImage = LLUI::getUIImage("button_anim_pause.tga");
- mPauseSelectedImage = LLUI::getUIImage("button_anim_pause_selected.tga");
- LLUICtrlFactory::getInstance()->buildFloater(this,
- "floater_animation_preview.xml");
- }
- //virtual
- LLFloaterAnimPreview::~LLFloaterAnimPreview()
- {
- if (mInWorld && isAgentAvatarValid())
- {
- if (mMotionID.notNull())
- {
- gAgentAvatarp->stopMotion(mMotionID, true);
- gAgentAvatarp->removeMotion(mMotionID);
- }
- gAgentAvatarp->deactivateAllMotions();
- gAgentAvatarp->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- gAgentAvatarp->startDefaultMotions();
- }
- mAnimPreview = NULL;
- setEnabled(false);
- }
- //virtual
- bool LLFloaterAnimPreview::postBuild()
- {
- LLRect r;
- LLBVHLoader* loaderp = NULL;
- if (!HBFloaterUploadAsset::postBuild())
- {
- return false;
- }
- mInWorld = isAgentAvatarValid() &&
- gSavedSettings.getBool("PreviewAnimInWorld");
- childSetCommitCallback("name_form", onCommitName, this);
- setDefaultBtn();
- if (mInWorld)
- {
- r = getRect();
- translate(0, 230);
- reshape(r.getWidth(), r.getHeight() - 230);
- childSetValue("bad_animation_text", getString("in_world"));
- childShow("bad_animation_text");
- }
- else
- {
- childHide("bad_animation_text");
- }
- mPreviewRect.set(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT,
- getRect().getWidth() - PREVIEW_HPAD,
- PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
- S32 y = mPreviewRect.mTop + gBtnHeight;
- S32 btn_left = PREVIEW_HPAD;
- r.set(btn_left, y, btn_left + 32, y - gBtnHeight);
- mPlayButton = getChild<LLButton>("play_btn");
- mPlayButton->setClickedCallback(onBtnPlay);
- mPlayButton->setCallbackUserData(this);
- mPlayButton->setImageUnselected(mPlayImage);
- mPlayButton->setImageSelected(mPlaySelectedImage);
- mPlayButton->setDisabledImages(LLStringUtil::null, LLStringUtil::null);
- mPlayButton->setScaleImage(true);
- mStopButton = getChild<LLButton>("stop_btn");
- mStopButton->setClickedCallback(onBtnStop);
- mStopButton->setCallbackUserData(this);
- mStopButton->setImages("button_anim_stop.tga",
- "button_anim_stop_selected.tga");
- mStopButton->setDisabledImages(LLStringUtil::null, LLStringUtil::null);
- mStopButton->setScaleImage(true);
- r.set(r.mRight + PREVIEW_HPAD, y, getRect().getWidth() - PREVIEW_HPAD,
- y - gBtnHeight);
- if (!mInWorld)
- {
- mAnimPreview = new LLPreviewAnimation(256, 256);
- }
- std::string exten = gDirUtil.getExtension(mFilename);
- if (exten == "bvh")
- {
- // Loading a bvh file
- S64 file_size = 0;
- LLFile infile(mFilenameAndPath, "rb", &file_size);
- if (infile)
- {
- char* file_buffer = new char[file_size + 1];
- if (infile.read((U8*)file_buffer, file_size) == file_size)
- {
- file_buffer[file_size] = '\0';
- ELoadStatus load_status = E_ST_OK;
- S32 line_number = 0;
- llinfos << "Loading BVH file " << mFilename << llendl;
- std::map<std::string, std::string> joint_alias_map =
- getJointAliases();
- loaderp = new LLBVHLoader(file_buffer, load_status,
- line_number, joint_alias_map);
- if (load_status == E_ST_NO_XLT_FILE)
- {
- llwarns << "NOTE: No translation table found." << llendl;
- }
- else if (load_status != E_ST_OK)
- {
- llwarns << "ERROR: [line: " << line_number << "] "
- << getString(STATUS[load_status]) << llendl;
- }
- }
- delete[] file_buffer;
- }
- else
- {
- llwarns << "Cannot open BVH file: " << mFilename << llendl;
- }
- }
- F32 max_anim_duration =
- llclamp(gSavedSettings.getF32("AnimationsMaxDuration"), 30.f,
- ABSOLUTE_MAX_ANIM_DURATION);
- if (loaderp && loaderp->isInitialized() &&
- loaderp->getDuration() <= max_anim_duration)
- {
- // Generate an 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
- LLKeyframeMotion* motionp =
- mInWorld ?
- (LLKeyframeMotion*)gAgentAvatarp->createMotion(mMotionID) :
- (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
- llinfos << "Serializing loader..." << llendl;
- loaderp->serialize(dp);
- dp.reset();
- llinfos << "De-serializing motions..." << llendl;
- bool success = motionp && motionp->deserialize(dp, mMotionID, false);
- llinfos << "Done." << llendl;
- delete[] buffer;
- if (success)
- {
- setAnimCallbacks();
- if (!mInWorld)
- {
- const LLBBoxLocal& pelvis_bbox = motionp->getPelvisBBox();
- LLVector3 temp = pelvis_bbox.getCenter();
- #if 0 // only consider XY ?
- temp.mV[VZ] = 0.f;
- #endif
- F32 pelvis_offset = temp.length();
- temp = pelvis_bbox.getExtent();
- #if 0
- temp.mV[VZ] = 0.f;
- #endif
- F32 pelvis_max_displacement =
- pelvis_offset + 0.5f * temp.length() + 1.f;
- F32 camera_zoom =
- gViewerCamera.getDefaultFOV() * 0.5f /
- tanf(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE);
- mAnimPreview->setZoom(camera_zoom);
- }
- motionp->setName(childGetValue("name_form").asString());
- if (!mInWorld)
- {
- mAnimPreview->getDummyAvatar()->startMotion(mMotionID);
- }
- childSetMinValue("playback_slider", 0.0);
- childSetMaxValue("playback_slider", 1.0);
- childSetValue("loop_check", LLSD(motionp->getLoop()));
- childSetValue("loop_in_point",
- LLSD(motionp->getLoopIn() /
- motionp->getDuration() * 100.f));
- childSetValue("loop_out_point",
- LLSD(motionp->getLoopOut() /
- motionp->getDuration() * 100.f));
- childSetMaxValue("priority",
- (F32)llclamp(gSavedSettings.getU32("AnimationsMaxPriority"),
- 4U, 5U));
- childSetValue("priority", LLSD((F32)motionp->getPriority()));
- childSetValue("hand_pose_combo",
- LLHandMotion::getHandPoseName(motionp->getHandPose()));
- childSetValue("ease_in_time", LLSD(motionp->getEaseInDuration()));
- childSetValue("ease_out_time", 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();
- childSetValue("bad_animation_text",
- 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));
- childSetValue("bad_animation_text", out_str.getString());
- }
- else
- {
- LLUIString out_str = getString("failed_file_read");
- // *TODO:Translate
- out_str.setArg("[STATUS]",
- getString(STATUS[loaderp->getStatus()]));
- childSetValue("bad_animation_text", out_str.getString());
- mBadAnimation = true;
- mUploadButton->setEnabled(false);
- }
- }
- //setEnabled(false);
- mMotionID.setNull();
- mAnimPreview = NULL;
- }
- refresh();
- delete loaderp;
- return true;
- }
- void LLFloaterAnimPreview::setAnimCallbacks()
- {
- childSetCommitCallback("playback_slider", onSliderMove, this);
- childSetCommitCallback("preview_base_anim", onCommitBaseAnim, this);
- childSetValue("preview_base_anim", "Standing");
- childSetCommitCallback("priority", onCommitPriority, this);
- childSetCommitCallback("loop_check", onCommitLoop, this);
- childSetCommitCallback("loop_in_point", onCommitLoopIn, this);
- childSetValidate("loop_in_point", validateLoopIn);
- childSetCommitCallback("loop_out_point", onCommitLoopOut, this);
- childSetValidate("loop_out_point", validateLoopOut);
- childSetCommitCallback("hand_pose_combo", onCommitHandPose, this);
- childSetCommitCallback("emote_combo", onCommitEmote, this);
- childSetValue("emote_combo", "[None]");
- childSetCommitCallback("ease_in_time", onCommitEaseIn, this);
- childSetValidate("ease_in_time", validateEaseIn);
- childSetCommitCallback("ease_out_time", onCommitEaseOut, this);
- childSetValidate("ease_out_time", validateEaseOut);
- }
- //virtual
- void LLFloaterAnimPreview::draw()
- {
- refresh();
- LLFloater::draw();
- if (!mInWorld && mAnimPreview && mMotionID.notNull())
- {
- gGL.color3f(1.f, 1.f, 1.f);
- LLTexUnit* unit0 = gGL.getTexUnit(0);
- unit0->bind(mAnimPreview);
- gGL.begin(LLRender::TRIANGLES);
- {
- S32 right = getRect().getWidth() - PREVIEW_HPAD;
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
- 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(right,
- PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- gGL.texCoord2f(0.f, 1.f);
- gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
- gGL.texCoord2f(1.f, 0.f);
- gGL.vertex2i(right,
- PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
- gGL.texCoord2f(1.f, 1.f);
- gGL.vertex2i(right, PREVIEW_TEXTURE_HEIGHT);
- }
- gGL.end();
- unit0->unbind(LLTexUnit::TT_TEXTURE);
- }
- }
- //virtual
- void LLFloaterAnimPreview::refresh()
- {
- if (mBadAnimation ||
- (!mAnimPreview && !(mInWorld && isAgentAvatarValid())))
- {
- childShow("bad_animation_text");
- mPlayButton->setEnabled(false);
- mStopButton->setEnabled(false);
- mUploadButton->setEnabled(false);
- }
- else
- {
- if (!mInWorld)
- {
- childHide("bad_animation_text");
- }
- mPlayButton->setEnabled(true);
- LLVOAvatar* avatarp = getAvatar();
- if (!avatarp)
- {
- return;
- }
- if (avatarp->isMotionActive(mMotionID))
- {
- mStopButton->setEnabled(true);
- if (avatarp->areAnimationsPaused())
- {
- mPlayButton->setImageUnselected(mPlayImage);
- mPlayButton->setImageSelected(mPlaySelectedImage);
- }
- else
- {
- LLKeyframeMotion* motionp = getMotion();
- if (motionp)
- {
- F32 fraction_complete = motionp->getLastUpdateTime() /
- motionp->getDuration();
- childSetValue("playback_slider", fraction_complete);
- }
- mPlayButton->setImageUnselected(mPauseImage);
- mPlayButton->setImageSelected(mPauseSelectedImage);
- }
- }
- else
- {
- mPauseRequest = avatarp->requestPause();
- mPlayButton->setImageUnselected(mPlayImage);
- mPlayButton->setImageSelected(mPlaySelectedImage);
- mStopButton->setEnabled(true); // stop also resets, leave enabled.
- }
- mUploadButton->setEnabled(true);
- }
- }
- //virtual
- bool LLFloaterAnimPreview::handleMouseDown(S32 x, S32 y, MASK mask)
- {
- if (!mInWorld && mPreviewRect.pointInRect(x, y))
- {
- bringToFront(x, y);
- gFocusMgr.setMouseCapture(this);
- gViewerWindowp->hideCursor();
- mLastMouseX = x;
- mLastMouseY = y;
- return true;
- }
- return LLFloater::handleMouseDown(x, y, mask);
- }
- //virtual
- bool LLFloaterAnimPreview::handleMouseUp(S32 x, S32 y, MASK mask)
- {
- if (!mInWorld)
- {
- gFocusMgr.setMouseCapture(NULL);
- gViewerWindowp->showCursor();
- }
- return LLFloater::handleMouseUp(x, y, mask);
- }
- //virtual
- bool LLFloaterAnimPreview::handleHover(S32 x, S32 y, MASK mask)
- {
- if (mInWorld)
- {
- return true;
- }
- 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);
- }
- LLUI::setCursorPositionLocal(this, mLastMouseX, mLastMouseY);
- }
- if (!mPreviewRect.pointInRect(x, y) || !mAnimPreview)
- {
- return LLFloater::handleHover(x, y, mask);
- }
- else if (local_mask == MASK_ORBIT)
- {
- gViewerWindowp->setCursor(UI_CURSOR_TOOLCAMERA);
- }
- else if (local_mask == MASK_PAN)
- {
- gViewerWindowp->setCursor(UI_CURSOR_TOOLPAN);
- }
- else
- {
- gViewerWindowp->setCursor(UI_CURSOR_TOOLZOOMIN);
- }
- return true;
- }
- //virtual
- bool LLFloaterAnimPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
- {
- if (!mInWorld)
- {
- mAnimPreview->zoom((F32)clicks * -0.2f);
- }
- return true;
- }
- //virtual
- void LLFloaterAnimPreview::onMouseCaptureLost()
- {
- if (!mInWorld)
- {
- gViewerWindowp->showCursor();
- }
- }
- std::map <std::string, std::string> LLFloaterAnimPreview::getJointAliases()
- {
- LLPointer<LLVOAvatar> av = mInWorld ? (LLVOAvatar*)gAgentAvatarp
- : mAnimPreview->getDummyAvatar();
- return av->getJointAliases();
- }
- LLKeyframeMotion* LLFloaterAnimPreview::getMotion()
- {
- LLMotion* motionp = NULL;
- LLVOAvatar* avatarp = getAvatar();
- if (avatarp)
- {
- motionp = avatarp->findMotion(mMotionID);
- }
- return motionp ? motionp->asKeyframeMotion() : NULL;
- }
- void LLFloaterAnimPreview::resetMotion()
- {
- LLVOAvatar* avatarp = getAvatar();
- if (!avatarp)
- {
- return;
- }
- bool paused = avatarp->areAnimationsPaused();
- LLKeyframeMotion* motionp = getMotion();
- if (motionp)
- {
- // Set emotion
- std::string emote = childGetValue("emote_combo").asString();
- motionp->setEmote(mIDList[emote]);
- }
- LLUUID base_id = mIDList[childGetValue("preview_base_anim").asString()];
- avatarp->deactivateAllMotions();
- avatarp->startMotion(base_id, BASE_ANIM_TIME_OFFSET);
- avatarp->startMotion(mMotionID, 0.0f);
- childSetValue("playback_slider", 0.0f);
- // Set pose
- std::string handpose = childGetValue("hand_pose_combo").asString();
- avatarp->startMotion(ANIM_AGENT_HAND_MOTION, 0.f);
- if (motionp)
- {
- motionp->setHandPose(LLHandMotion::getHandPose(handpose));
- }
- if (paused)
- {
- mPauseRequest = avatarp->requestPause();
- }
- else
- {
- mPauseRequest = NULL;
- }
- }
- LLVOAvatar* LLFloaterAnimPreview::getAvatar()
- {
- LLVOAvatar* avatarp = NULL;
- if (mInWorld)
- {
- if (isAgentAvatarValid())
- {
- avatarp = gAgentAvatarp.get();
- }
- }
- else if (mAnimPreview)
- {
- avatarp = mAnimPreview->getDummyAvatar();
- }
- return avatarp;
- }
- //virtual
- void LLFloaterAnimPreview::uploadAsset()
- {
- if (!getEnabled()) return;
- LLKeyframeMotion* motionp = getMotion();
- if (!motionp)
- {
- return;
- }
- // Make sure the animation is stopped since we sill destroy the motion once
- // uploaded
- LLVOAvatar* avatarp = getAvatar();
- avatarp->stopMotion(mMotionID, true);
- S32 file_size = motionp->getFileSize();
- U8* buffer = new U8[file_size];
- LLDataPackerBinaryBuffer dp(buffer, file_size);
- if (motionp->serialize(dp))
- {
- LLFileSystem file(motionp->getID(), LLFileSystem::APPEND);
- S32 size = dp.getCurrentSize();
- if (file.write((U8*)buffer, size))
- {
- LLResourceUploadInfo::ptr_t
- info(new LLResourceUploadInfo(mTransactionID,
- LLAssetType::AT_ANIMATION,
- mNameEditor->getText(),
- mDescEditor->getText(), 0,
- LLFolderType::FT_ANIMATION,
- LLInventoryType::IT_ANIMATION,
- LLFloaterPerms::getNextOwnerPerms(),
- LLFloaterPerms::getGroupPerms(),
- LLFloaterPerms::getEveryonePerms(),
- mCost));
- upload_new_resource(info);
- }
- else
- {
- gNotifications.add("WriteAnimationFail");
- }
- }
- delete[] buffer;
- // Clear out cache for motion data
- avatarp->removeMotion(mMotionID);
- if (mInWorld)
- {
- avatarp->deactivateAllMotions();
- }
- LLKeyframeDataCache::removeKeyframeData(mMotionID);
- }
- //static
- void LLFloaterAnimPreview::onBtnPlay(void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- if (self->mMotionID.notNull())
- {
- LLVOAvatar* avatarp = self->getAvatar();
- if (avatarp)
- {
- if (!avatarp->isMotionActive(self->mMotionID))
- {
- self->resetMotion();
- self->mPauseRequest = NULL;
- }
- else
- {
- if (avatarp->areAnimationsPaused())
- {
- self->mPauseRequest = NULL;
- }
- else
- {
- self->mPauseRequest = avatarp->requestPause();
- }
- }
- }
- }
- }
- //static
- void LLFloaterAnimPreview::onBtnStop(void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- if (self->mMotionID.notNull())
- {
- LLVOAvatar* avatarp = self->getAvatar();
- if (avatarp)
- {
- #if 0
- self->resetMotion();
- self->mPauseRequest = avatarp->requestPause();
- #else
- F32 loop_in = self->childGetValue("loop_in_point").asReal();
- F32 playback = self->childGetValue("playback_slider").asReal();
- bool stop_now = !self->childGetValue("loop_check").asBoolean() ||
- loop_in > playback * 100.f;
- avatarp->stopMotion(self->mMotionID, stop_now);
- #endif
- }
- }
- }
- //static
- void LLFloaterAnimPreview::onSliderMove(LLUICtrl* ctrl, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLVOAvatar* avatarp = self->getAvatar();
- if (!avatarp)
- {
- return;
- }
- LLUUID base_id =
- self->mIDList[self->childGetValue("preview_base_anim").asString()];
- LLMotion* motionp = avatarp->findMotion(self->mMotionID);
- if (!motionp)
- {
- return;
- }
- F32 duration = motionp->getDuration();// + motionp->getEaseOutDuration();
- F32 delta_time = duration *
- (F32)self->childGetValue("playback_slider").asReal();
- avatarp->deactivateAllMotions();
- avatarp->startMotion(base_id, delta_time + BASE_ANIM_TIME_OFFSET);
- avatarp->startMotion(self->mMotionID, delta_time);
- self->mPauseRequest = avatarp->requestPause();
- self->refresh();
- }
- //static
- void LLFloaterAnimPreview::onCommitBaseAnim(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLVOAvatar* avatarp = self->getAvatar();
- if (!avatarp)
- {
- return;
- }
- bool paused = avatarp->areAnimationsPaused();
- // stop all other possible base motions
- avatarp->stopMotion(ANIM_AGENT_STAND, true);
- avatarp->stopMotion(ANIM_AGENT_WALK, true);
- avatarp->stopMotion(ANIM_AGENT_SIT, true);
- avatarp->stopMotion(ANIM_AGENT_HOVER, true);
- self->resetMotion();
- if (!paused)
- {
- self->mPauseRequest = NULL;
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitLoop(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setLoop(self->childGetValue("loop_check").asBoolean());
- motionp->setLoopIn((F32)self->childGetValue("loop_in_point").asReal() *
- 0.01f * motionp->getDuration());
- motionp->setLoopOut((F32)self->childGetValue("loop_out_point").asReal() *
- 0.01f * motionp->getDuration());
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitLoopIn(LLUICtrl* ctrlp, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !ctrlp || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setLoopIn((F32)self->childGetValue("loop_in_point").asReal() *
- 0.01f);
- self->resetMotion();
- self->childSetValue("loop_check", LLSD(true));
- onCommitLoop(ctrlp, userdata);
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitLoopOut(LLUICtrl* ctrlp, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !ctrlp || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setLoopOut((F32)self->childGetValue("loop_out_point").asReal() *
- 0.01f * motionp->getDuration());
- self->resetMotion();
- self->childSetValue("loop_check", LLSD(true));
- onCommitLoop(ctrlp, userdata);
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitName(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setName(self->childGetValue("name_form").asString());
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitHandPose(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (self && self->getEnabled())
- {
- self->resetMotion(); // Sets hand pose
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitEmote(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (self && self->getEnabled())
- {
- self->resetMotion(); // Sets emote
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitPriority(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setPriority(llfloor((F32)self->childGetValue("priority").asReal()));
- }
- }
- //static
- void LLFloaterAnimPreview::onCommitEaseIn(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setEaseIn((F32)self->childGetValue("ease_in_time").asReal());
- }
- self->resetMotion();
- }
- //static
- void LLFloaterAnimPreview::onCommitEaseOut(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (motionp)
- {
- motionp->setEaseOut((F32)self->childGetValue("ease_out_time").asReal());
- }
- self->resetMotion();
- }
- //static
- bool LLFloaterAnimPreview::validateEaseIn(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return false;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (!motionp)
- {
- return false;
- }
- if (!motionp->getLoop())
- {
- F32 new_ease_in = llclamp((F32)self->childGetValue("ease_in_time").asReal(),
- 0.f,
- motionp->getDuration() -
- motionp->getEaseOutDuration());
- self->childSetValue("ease_in_time", LLSD(new_ease_in));
- }
- return true;
- }
- //static
- bool LLFloaterAnimPreview::validateEaseOut(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return false;
- }
- LLKeyframeMotion* motionp = self->getMotion();
- if (!motionp)
- {
- return false;
- }
- if (!motionp->getLoop())
- {
- F32 new_ease_out = llclamp((F32)self->childGetValue("ease_out_time").asReal(),
- 0.f,
- motionp->getDuration() -
- motionp->getEaseInDuration());
- self->childSetValue("ease_out_time", LLSD(new_ease_out));
- }
- return true;
- }
- //static
- bool LLFloaterAnimPreview::validateLoopIn(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return false;
- }
- F32 loop_in_val = (F32)self->childGetValue("loop_in_point").asReal();
- F32 loop_out_val = (F32)self->childGetValue("loop_out_point").asReal();
- if (loop_in_val < 0.f)
- {
- loop_in_val = 0.f;
- }
- else if (loop_in_val > 100.f)
- {
- loop_in_val = 100.f;
- }
- else if (loop_in_val > loop_out_val)
- {
- loop_in_val = loop_out_val;
- }
- self->childSetValue("loop_in_point", LLSD(loop_in_val));
- return true;
- }
- //static
- bool LLFloaterAnimPreview::validateLoopOut(LLUICtrl*, void* userdata)
- {
- LLFloaterAnimPreview* self = (LLFloaterAnimPreview*)userdata;
- if (!self || !self->getEnabled())
- {
- return false;
- }
- F32 loop_out_val =(F32)self->childGetValue("loop_out_point").asReal();
- F32 loop_in_val = (F32)self->childGetValue("loop_in_point").asReal();
- if (loop_out_val < 0.f)
- {
- loop_out_val = 0.f;
- }
- else if (loop_out_val > 100.f)
- {
- loop_out_val = 100.f;
- }
- else if (loop_out_val < loop_in_val)
- {
- loop_out_val = loop_in_val;
- }
- self->childSetValue("loop_out_point", LLSD(loop_out_val));
- return true;
- }
- //-----------------------------------------------------------------------------
- // LLPreviewAnimation
- //-----------------------------------------------------------------------------
- LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height)
- : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, false)
- {
- 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);
- if (!mDummyAvatar)
- {
- llwarns << "Cannot create a dummy avatar !" << llendl;
- return;
- }
- mDummyAvatar->createDrawable();
- mDummyAvatar->mSpecialRenderMode = 1;
- mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET);
- mDummyAvatar->hideHair();
- mDummyAvatar->hideSkirt();
- // Give a default texture to the avatar body parts. HB
- U32 texname = LLViewerFetchedTexture::sDefaultImagep->getTexName();
- LLAvatarJoint* rootp = mDummyAvatar->mRoot;
- LLViewerJointMesh* meshp =
- dynamic_cast<LLViewerJointMesh*>(rootp->findJoint("mHairMesh0"));
- meshp->setTestTexture(texname);
- meshp = dynamic_cast<LLViewerJointMesh*>(rootp->findJoint("mHeadMesh0"));
- meshp->setTestTexture(texname);
- meshp =
- dynamic_cast<LLViewerJointMesh*>(rootp->findJoint("mUpperBodyMesh0"));
- meshp->setTestTexture(texname);
- meshp =
- dynamic_cast<LLViewerJointMesh*>(rootp->findJoint("mLowerBodyMesh0"));
- meshp->setTestTexture(texname);
- // 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);
- #if LL_PUPPETRY
- mDummyAvatar->stopMotion(ANIM_AGENT_PUPPET_MOTION, true);
- #endif
- mDummyAvatar->stopMotion(ANIM_AGENT_PHYSICS_MOTION, true);
- }
- LLPreviewAnimation::~LLPreviewAnimation()
- {
- if (mDummyAvatar)
- {
- mDummyAvatar->markDead();
- }
- }
- //virtual
- S8 LLPreviewAnimation::getType() const
- {
- return LLViewerDynamicTexture::LL_PREVIEW_ANIMATION;
- }
- bool LLPreviewAnimation::render()
- {
- LLVOAvatar* avatarp = mDummyAvatar.get();
- if (!avatarp || avatarp->mDrawable.isNull())
- {
- return true;
- }
- gGL.pushUIMatrix();
- gGL.loadUIIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.ortho(0.f, mFullWidth, 0.f, mFullHeight, -1.f, 1.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
- LLGLSUIDefault def;
- gUIProgram.bind();
- gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
- gl_rect_2d_simple(mFullWidth, mFullHeight);
- gGL.color4f(1.f, 1.f, 1.f, 1.f);
- 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);
- LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
- gViewerCamera.setOriginAndLookAt(target_pos +
- ((LLVector3(mCameraDistance, 0.f, 0.f) +
- mCameraOffset) * av_rot), // Camera
- LLVector3::z_axis, // Up
- // point of interest
- target_pos + mCameraOffset * av_rot);
- gViewerCamera.setAspect((F32)mFullWidth / (F32)mFullHeight);
- gViewerCamera.setViewNoBroadcast(gViewerCamera.getDefaultFOV() /
- mCameraZoom);
- gViewerCamera.setPerspective(false, mOrigin.mX, mOrigin.mY, mFullWidth,
- mFullHeight, false);
- avatarp->updateLOD();
- avatarp->dirtyMesh();
- LLVertexBuffer::unbind();
- // Do not let environment settings influence our scene lighting.
- HBPreviewLighting preview_light;
- LLDisableOcclusionCulling no_occlusion;
- LLGLDepthTest gls_depth(GL_TRUE);
- // Make sure alpha=0 shows avatar material color
- LLGLDisable no_blend(GL_BLEND);
- LLFace* facep = avatarp->mDrawable->getFace(0);
- if (facep) // Paranoia
- {
- LLDrawPoolAvatar* poolp = (LLDrawPoolAvatar*)facep->getPool();
- if (poolp) // More paranoia !
- {
- // Render only our dummy avatar
- poolp->renderAvatars(avatarp);
- }
- }
- gGL.popUIMatrix();
- return true;
- }
- 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);
- }
- void LLPreviewAnimation::zoom(F32 zoom_delta)
- {
- setZoom(mCameraZoom + zoom_delta);
- }
- void LLPreviewAnimation::setZoom(F32 zoom_amt)
- {
- mCameraZoom = llclamp(zoom_amt, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM);
- }
- 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);
- }
|