aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloateranimpreview.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloateranimpreview.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/newview/llfloateranimpreview.cpp1158
1 files changed, 1158 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloateranimpreview.cpp b/linden/indra/newview/llfloateranimpreview.cpp
new file mode 100644
index 0000000..ced7a0e
--- /dev/null
+++ b/linden/indra/newview/llfloateranimpreview.cpp
@@ -0,0 +1,1158 @@
1/**
2 * @file llfloateranimpreview.cpp
3 * @brief LLFloaterAnimPreview class implementation
4 *
5 * Copyright (c) 2004-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llfloateranimpreview.h"
31
32#include "llbvhloader.h"
33#include "lldatapacker.h"
34#include "lldir.h"
35#include "llvfile.h"
36#include "llapr.h"
37
38#include "llagent.h"
39#include "llbbox.h"
40#include "llbutton.h"
41#include "llcheckboxctrl.h"
42#include "llcombobox.h"
43#include "lldrawable.h"
44#include "lldrawpoolavatar.h"
45#include "llface.h"
46#include "llkeyframemotion.h"
47#include "lllineeditor.h"
48#include "llsliderctrl.h"
49#include "llspinctrl.h"
50#include "lltextbox.h"
51#include "lltoolmgr.h"
52#include "llui.h"
53#include "llviewercamera.h"
54#include "llviewerobjectlist.h"
55#include "llviewerwindow.h"
56#include "llviewermenu.h"
57#include "llvoavatar.h"
58#include "pipeline.h"
59#include "viewer.h"
60#include "llvieweruictrlfactory.h"
61
62S32 LLFloaterAnimPreview::sUploadAmount = 10;
63
64const S32 PREVIEW_BORDER_WIDTH = 2;
65const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
66const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
67const S32 PREF_BUTTON_HEIGHT = 16;
68const S32 PREVIEW_TEXTURE_HEIGHT = 300;
69
70const F32 PREVIEW_CAMERA_DISTANCE = 4.f;
71
72const F32 MIN_CAMERA_ZOOM = 0.5f;
73const F32 MAX_CAMERA_ZOOM = 10.f;
74
75//-----------------------------------------------------------------------------
76// LLFloaterAnimPreview()
77//-----------------------------------------------------------------------------
78LLFloaterAnimPreview::LLFloaterAnimPreview(const char* filename) :
79 LLFloaterNameDesc(filename)
80{
81 mLastSliderValue = 0.f;
82 mLastMouseX = 0;
83 mLastMouseY = 0;
84
85 mIDList["Standing"] = ANIM_AGENT_STAND;
86 mIDList["Walking"] = ANIM_AGENT_FEMALE_WALK;
87 mIDList["Sitting"] = ANIM_AGENT_SIT_FEMALE;
88 mIDList["Flying"] = ANIM_AGENT_HOVER;
89
90 mIDList["[None]"] = LLUUID::null;
91 mIDList["Aaaaah"] = ANIM_AGENT_EXPRESS_OPEN_MOUTH;
92 mIDList["Afraid"] = ANIM_AGENT_EXPRESS_AFRAID;
93 mIDList["Angry"] = ANIM_AGENT_EXPRESS_ANGER;
94 mIDList["Big Smile"] = ANIM_AGENT_EXPRESS_TOOTHSMILE;
95 mIDList["Bored"] = ANIM_AGENT_EXPRESS_BORED;
96 mIDList["Cry"] = ANIM_AGENT_EXPRESS_CRY;
97 mIDList["Disdain"] = ANIM_AGENT_EXPRESS_DISDAIN;
98 mIDList["Embarrassed"] = ANIM_AGENT_EXPRESS_EMBARRASSED;
99 mIDList["Frown"] = ANIM_AGENT_EXPRESS_FROWN;
100 mIDList["Kiss"] = ANIM_AGENT_EXPRESS_KISS;
101 mIDList["Laugh"] = ANIM_AGENT_EXPRESS_LAUGH;
102 mIDList["Plllppt"] = ANIM_AGENT_EXPRESS_TONGUE_OUT;
103 mIDList["Repulsed"] = ANIM_AGENT_EXPRESS_REPULSED;
104 mIDList["Sad"] = ANIM_AGENT_EXPRESS_SAD;
105 mIDList["Shrug"] = ANIM_AGENT_EXPRESS_SHRUG;
106 mIDList["Smile"] = ANIM_AGENT_EXPRESS_SMILE;
107 mIDList["Surprise"] = ANIM_AGENT_EXPRESS_SURPRISE;
108 mIDList["Wink"] = ANIM_AGENT_EXPRESS_WINK;
109 mIDList["Worry"] = ANIM_AGENT_EXPRESS_WORRY;
110}
111
112//-----------------------------------------------------------------------------
113// postBuild()
114//-----------------------------------------------------------------------------
115BOOL LLFloaterAnimPreview::postBuild()
116{
117 LLRect r;
118 LLKeyframeMotion* motionp = NULL;
119 LLBVHLoader* loaderp = NULL;
120
121 if (!LLFloaterNameDesc::postBuild())
122 {
123 return FALSE;
124 }
125
126 childSetCommitCallback("name_form", onCommitName, this);
127
128 childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
129 childSetAction("ok_btn", onBtnOK, this);
130 setDefaultBtn();
131
132 mPreviewRect.set(PREVIEW_HPAD,
133 PREVIEW_TEXTURE_HEIGHT,
134 getRect().getWidth() - PREVIEW_HPAD,
135 PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
136 mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
137
138 S32 y = mPreviewRect.mTop + BTN_HEIGHT;
139 S32 btn_left = PREVIEW_HPAD;
140
141 r.set( btn_left, y, btn_left + 32, y - BTN_HEIGHT );
142 mPlayButton = LLViewerUICtrlFactory::getButtonByName(this, "play_btn");
143 if (!mPlayButton)
144 {
145 mPlayButton = new LLButton("play_btn", LLRect(0,0,0,0));
146 }
147 mPlayButton->setClickedCallback(onBtnPlay);
148 mPlayButton->setCallbackUserData(this);
149
150 mPlayButton->setImages("button_anim_play.tga",
151 "button_anim_play_selected.tga");
152 mPlayButton->setDisabledImages("","");
153
154 mPlayButton->setScaleImage(TRUE);
155 mPlayButton->setFixedBorder(0, 0);
156
157 mStopButton = LLViewerUICtrlFactory::getButtonByName(this, "stop_btn");
158 if (!mStopButton)
159 {
160 mStopButton = new LLButton("stop_btn", LLRect(0,0,0,0));
161 }
162 mStopButton->setClickedCallback(onBtnStop);
163 mStopButton->setCallbackUserData(this);
164
165 mStopButton->setImages("button_anim_stop.tga",
166 "button_anim_stop_selected.tga");
167 mStopButton->setDisabledImages("","");
168
169 mStopButton->setScaleImage(TRUE);
170 mStopButton->setFixedBorder(0, 0);
171
172 r.set(r.mRight + PREVIEW_HPAD, y, getRect().getWidth() - PREVIEW_HPAD, y - BTN_HEIGHT);
173 childSetCommitCallback("playback_slider", onSliderMove, this);
174
175 childHide("bad_animation_text");
176
177 childSetCommitCallback("preview_base_anim", onCommitBaseAnim, this);
178 childSetValue("preview_base_anim", "Standing");
179
180 childSetCommitCallback("priority", onCommitPriority, this);
181 childSetCommitCallback("loop_check", onCommitLoop, this);
182 childSetCommitCallback("loop_in_point", onCommitLoopIn, this);
183 childSetValidate("loop_in_point", validateLoopIn);
184 childSetCommitCallback("loop_out_point", onCommitLoopOut, this);
185 childSetValidate("loop_out_point", validateLoopOut);
186
187 childSetCommitCallback("hand_pose_combo", onCommitHandPose, this);
188
189 childSetCommitCallback("emote_combo", onCommitEmote, this);
190 childSetValue("emote_combo", "[None]");
191
192 childSetCommitCallback("ease_in_time", onCommitEaseIn, this);
193 childSetValidate("ease_in_time", validateEaseIn);
194 childSetCommitCallback("ease_out_time", onCommitEaseOut, this);
195 childSetValidate("ease_out_time", validateEaseOut);
196
197 if (!stricmp(strrchr(mFilename.c_str(), '.'), ".bvh"))
198 {
199 // loading a bvh file
200
201 // now load bvh file
202 S32 file_size;
203 apr_file_t* fp = ll_apr_file_open(mFilenameAndPath, LL_APR_RB, &file_size);
204
205 if (!fp)
206 {
207 llwarns << "Can't open BVH file:" << mFilename << llendl;
208 }
209 else
210 {
211 char* file_buffer;
212
213 file_buffer = new char[file_size + 1];
214
215 if (file_size == ll_apr_file_read(fp, file_buffer, file_size))
216 {
217 file_buffer[file_size] = '\0';
218 llinfos << "Loading BVH file " << mFilename << llendl;
219 loaderp = new LLBVHLoader(file_buffer);
220 }
221
222 apr_file_close(fp);
223 delete file_buffer;
224 }
225 }
226
227 if (loaderp && loaderp->isInitialized() && loaderp->getDuration() <= MAX_ANIM_DURATION)
228 {
229 // generate unique id for this motion
230 mTransactionID.generate();
231 mMotionID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
232
233 mAnimPreview = new LLPreviewAnimation(256, 256);
234
235 // motion will be returned, but it will be in a load-pending state, as this is a new motion
236 // this motion will not request an asset transfer until next update, so we have a chance to
237 // load the keyframe data locally
238 motionp = (LLKeyframeMotion*)mAnimPreview->getDummyAvatar()->createMotion(mMotionID);
239
240 // create data buffer for keyframe initialization
241 S32 buffer_size = loaderp->getOutputSize();
242 U8* buffer = new U8[buffer_size];
243
244 LLDataPackerBinaryBuffer dp(buffer, buffer_size);
245
246 // pass animation data through memory buffer
247 loaderp->serialize(dp);
248 dp.reset();
249 BOOL success = motionp->deserialize(dp);
250
251 delete []buffer;
252
253 if (motionp && success)
254 {
255 const LLBBoxLocal &pelvis_bbox = motionp->getPelvisBBox();
256
257 LLVector3 temp = pelvis_bbox.getCenter();
258 // only consider XY?
259 //temp.mV[VZ] = 0.f;
260 F32 pelvis_offset = temp.magVec();
261
262 temp = pelvis_bbox.getExtent();
263 //temp.mV[VZ] = 0.f;
264 F32 pelvis_max_displacement = pelvis_offset + (temp.magVec() * 0.5f) + 1.f;
265
266 F32 camera_zoom = gCamera->getDefaultFOV() / (2.f * atan(pelvis_max_displacement / PREVIEW_CAMERA_DISTANCE));
267
268 mAnimPreview->setZoom(camera_zoom);
269
270 motionp->setName(childGetValue("name_form").asString());
271 mAnimPreview->getDummyAvatar()->startMotion(mMotionID);
272 childSetMinValue("playback_slider", 0.0);
273 childSetMaxValue("playback_slider", 1.0);
274
275 childSetValue("loop_check", LLSD(motionp->getLoop()));
276 childSetValue("loop_in_point", LLSD(motionp->getLoopIn() / motionp->getDuration() * 100.f));
277 childSetValue("loop_out_point", LLSD(motionp->getLoopOut() / motionp->getDuration() * 100.f));
278 childSetValue("priority", LLSD((F32)motionp->getPriority()));
279 childSetValue("hand_pose_combo", LLHandMotion::getHandPoseName(motionp->getHandPose()));
280 childSetValue("ease_in_time", LLSD(motionp->getEaseInDuration()));
281 childSetValue("ease_out_time", LLSD(motionp->getEaseOutDuration()));
282 mEnabled = TRUE;
283 char seconds_string[128];
284 sprintf(seconds_string, " - %.2f seconds", motionp->getDuration());
285
286 setTitle(mFilename + LLString(seconds_string));
287 }
288 else
289 {
290 delete mAnimPreview;
291 mAnimPreview = NULL;
292 mMotionID.setNull();
293 // XUI:translate
294 childSetValue("bad_animation_text", LLSD("Failed to initialize motion."));
295 mEnabled = FALSE;
296 }
297 }
298 else
299 {
300 if ( loaderp )
301 {
302 if (loaderp->getDuration() > MAX_ANIM_DURATION)
303 {
304 char output_str[256];
305
306 sprintf(output_str, "Animation file is %.1f seconds in length.\n\nMaximum animation length is %.1f seconds.\n",
307 loaderp->getDuration(), MAX_ANIM_DURATION);
308 childSetValue("bad_animation_text", LLSD(output_str));
309 }
310 else
311 {
312 char* status = loaderp->getStatus();
313 LLString error_string("Unable to read animation file.\n\n");
314 error_string += LLString(status);
315 childSetValue("bad_animation_text", LLSD(error_string));
316 }
317 }
318
319 mEnabled = FALSE;
320 mMotionID.setNull();
321 mAnimPreview = NULL;
322 }
323
324 refresh();
325
326 delete loaderp;
327
328 return TRUE;
329}
330
331//-----------------------------------------------------------------------------
332// LLFloaterAnimPreview()
333//-----------------------------------------------------------------------------
334LLFloaterAnimPreview::~LLFloaterAnimPreview()
335{
336 delete mAnimPreview;
337 mAnimPreview = NULL;
338
339 mEnabled = FALSE;
340}
341
342//-----------------------------------------------------------------------------
343// draw()
344//-----------------------------------------------------------------------------
345void LLFloaterAnimPreview::draw()
346{
347 LLFloater::draw();
348 LLRect r = getRect();
349
350 refresh();
351
352 if (mMotionID.notNull() && mAnimPreview)
353 {
354 glColor3f(1.f, 1.f, 1.f);
355 mAnimPreview->bindTexture();
356
357 glBegin( GL_QUADS );
358 {
359 glTexCoord2f(0.f, 1.f);
360 glVertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
361 glTexCoord2f(0.f, 0.f);
362 glVertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
363 glTexCoord2f(1.f, 0.f);
364 glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
365 glTexCoord2f(1.f, 1.f);
366 glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
367 }
368 glEnd();
369
370 mAnimPreview->unbindTexture();
371
372 LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
373 if (!avatarp->areAnimationsPaused())
374 {
375 mAnimPreview->requestUpdate();
376 }
377 }
378}
379
380//-----------------------------------------------------------------------------
381// resetMotion()
382//-----------------------------------------------------------------------------
383void LLFloaterAnimPreview::resetMotion()
384{
385 LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
386 BOOL paused = avatarp->areAnimationsPaused();
387
388 mPauseRequest = NULL;
389
390 LLUUID anim_id = mIDList[childGetValue("preview_base_anim").asString()];
391 avatarp->stopMotion(anim_id, TRUE);
392 avatarp->stopMotion(mMotionID, TRUE);
393 avatarp->startMotion(anim_id, 5.f);
394 avatarp->startMotion(mMotionID);
395 childSetValue("playback_slider", 0.0);
396 mLastSliderValue = 0.0f;
397
398 if (paused)
399 {
400 mPauseRequest = avatarp->requestPause();
401 }
402}
403
404//-----------------------------------------------------------------------------
405// handleMouseDown()
406//-----------------------------------------------------------------------------
407BOOL LLFloaterAnimPreview::handleMouseDown(S32 x, S32 y, MASK mask)
408{
409 if (mPreviewRect.pointInRect(x, y))
410 {
411 bringToFront( x, y );
412 gViewerWindow->setMouseCapture(this, onMouseCaptureLost);
413 gViewerWindow->hideCursor();
414 mLastMouseX = x;
415 mLastMouseY = y;
416 return TRUE;
417 }
418
419 return LLFloater::handleMouseDown(x, y, mask);
420}
421
422//-----------------------------------------------------------------------------
423// handleMouseUp()
424//-----------------------------------------------------------------------------
425BOOL LLFloaterAnimPreview::handleMouseUp(S32 x, S32 y, MASK mask)
426{
427 gViewerWindow->setMouseCapture(FALSE, NULL);
428 gViewerWindow->showCursor();
429 return LLFloater::handleMouseUp(x, y, mask);
430}
431
432//-----------------------------------------------------------------------------
433// handleHover()
434//-----------------------------------------------------------------------------
435BOOL LLFloaterAnimPreview::handleHover(S32 x, S32 y, MASK mask)
436{
437 MASK local_mask = mask & ~MASK_ALT;
438
439 if (mAnimPreview && gViewerWindow->hasMouseCapture(this))
440 {
441 if (local_mask == MASK_PAN)
442 {
443 // pan here
444 mAnimPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
445 }
446 else if (local_mask == MASK_ORBIT)
447 {
448 F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
449 F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
450
451 mAnimPreview->rotate(yaw_radians, pitch_radians);
452 }
453 else
454 {
455 F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
456 F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
457
458 mAnimPreview->rotate(yaw_radians, 0.f);
459 mAnimPreview->zoom(zoom_amt);
460 }
461
462 mAnimPreview->requestUpdate();
463
464 LLUI::setCursorPositionLocal(this, mLastMouseX, mLastMouseY);
465 }
466
467 if (!mPreviewRect.pointInRect(x, y) || !mAnimPreview)
468 {
469 return LLFloater::handleHover(x, y, mask);
470 }
471 else if (local_mask == MASK_ORBIT)
472 {
473 gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
474 }
475 else if (local_mask == MASK_PAN)
476 {
477 gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
478 }
479 else
480 {
481 gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
482 }
483
484 return TRUE;
485}
486
487//-----------------------------------------------------------------------------
488// handleScrollWheel()
489//-----------------------------------------------------------------------------
490BOOL LLFloaterAnimPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
491{
492 mAnimPreview->zoom((F32)clicks * -0.2f);
493 mAnimPreview->requestUpdate();
494
495 return TRUE;
496}
497
498//-----------------------------------------------------------------------------
499// onMouseCaptureLost()
500//-----------------------------------------------------------------------------
501void LLFloaterAnimPreview::onMouseCaptureLost(LLMouseHandler* handler)
502{
503 gViewerWindow->showCursor();
504}
505
506//-----------------------------------------------------------------------------
507// onBtnPlay()
508//-----------------------------------------------------------------------------
509void LLFloaterAnimPreview::onBtnPlay(void* user_data)
510{
511 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)user_data;
512 if (!previewp->mEnabled) return;
513
514 if (previewp->mMotionID.notNull() && previewp->mAnimPreview)
515 {
516 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
517
518 if(!avatarp->isMotionActive(previewp->mMotionID))
519 {
520 previewp->resetMotion();
521 previewp->mPauseRequest = NULL;
522 }
523 else
524 {
525 if (avatarp->areAnimationsPaused())
526 {
527 previewp->mPauseRequest = NULL;
528 }
529 else
530 {
531 previewp->mPauseRequest = avatarp->requestPause();
532 }
533 }
534 }
535}
536
537//-----------------------------------------------------------------------------
538// onBtnStop()
539//-----------------------------------------------------------------------------
540void LLFloaterAnimPreview::onBtnStop(void* user_data)
541{
542 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)user_data;
543 if (!previewp->mEnabled) return;
544
545 if (previewp->mMotionID.notNull() && previewp->mAnimPreview)
546 {
547 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
548
549 // is the motion looping and have we passed the loop in point?
550 if (previewp->childGetValue("loop_check").asBoolean() &&
551 (F32)previewp->childGetValue("loop_in_point").asReal() <= (F32)previewp->childGetValue("playback_slider").asReal() * 100.f)
552 {
553 avatarp->stopMotion(previewp->mMotionID, FALSE);
554 }
555 else
556 {
557 avatarp->stopMotion(previewp->mMotionID, FALSE);
558 }
559 }
560}
561
562//-----------------------------------------------------------------------------
563// onSliderMove()
564//-----------------------------------------------------------------------------
565void LLFloaterAnimPreview::onSliderMove(LLUICtrl* ctrl, void*user_data)
566{
567 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)user_data;
568 if (!previewp->mEnabled) return;
569
570 if (previewp->mAnimPreview)
571 {
572 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
573 LLMotion* motionp = avatarp->findMotion(previewp->mMotionID);
574 LLMotion* base_motionp =
575 avatarp->findMotion(previewp->mIDList[previewp->childGetValue("preview_base_anim").asString()]);
576
577 if (motionp && base_motionp)
578 {
579 if (!avatarp->isMotionActive(previewp->mMotionID))
580 {
581 previewp->resetMotion();
582 }
583
584 previewp->mPauseRequest = avatarp->requestPause();
585 F32 original_activation_time = motionp->mActivationTimestamp;
586 motionp->mActivationTimestamp -= ((F32)previewp->childGetValue("playback_slider").asReal() - previewp->mLastSliderValue) *
587 motionp->getDuration();
588 base_motionp->mActivationTimestamp -= ((F32)previewp->childGetValue("playback_slider").asReal() - previewp->mLastSliderValue) *
589 base_motionp->getDuration();
590
591 if (motionp->mSendStopTimestamp != F32_MIN)
592 {
593 motionp->mSendStopTimestamp = motionp->mSendStopTimestamp - original_activation_time + motionp->mActivationTimestamp;
594 }
595
596 if (motionp->mStopTimestamp != F32_MIN)
597 {
598 motionp->mStopTimestamp = motionp->mStopTimestamp - original_activation_time + motionp->mActivationTimestamp;
599 }
600 previewp->refresh();
601 }
602 }
603
604 previewp->mLastSliderValue = (F32)previewp->childGetValue("playback_slider").asReal();
605}
606
607//-----------------------------------------------------------------------------
608// onCommitBaseAnim()
609//-----------------------------------------------------------------------------
610void LLFloaterAnimPreview::onCommitBaseAnim(LLUICtrl* ctrl, void* data)
611{
612 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
613
614 if (!previewp->mEnabled) return;
615
616 if (previewp->mAnimPreview)
617 {
618 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
619
620 BOOL paused = avatarp->areAnimationsPaused();
621
622 // stop all other possible base motions
623 avatarp->stopMotion(ANIM_AGENT_STAND, TRUE);
624 avatarp->stopMotion(ANIM_AGENT_WALK, TRUE);
625 avatarp->stopMotion(ANIM_AGENT_SIT, TRUE);
626 avatarp->stopMotion(ANIM_AGENT_HOVER, TRUE);
627
628 previewp->resetMotion();
629
630 if (!paused)
631 {
632 previewp->mPauseRequest = NULL;
633 }
634 }
635}
636
637//-----------------------------------------------------------------------------
638// onCommitLoop()
639//-----------------------------------------------------------------------------
640void LLFloaterAnimPreview::onCommitLoop(LLUICtrl* ctrl, void* data)
641{
642 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
643
644 if (!previewp->mEnabled) return;
645 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
646 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
647
648 if (motionp)
649 {
650 motionp->setLoop(previewp->childGetValue("loop_check").asBoolean());
651 motionp->setLoopIn((F32)previewp->childGetValue("loop_in_point").asReal() * 0.01f * motionp->getDuration());
652 motionp->setLoopOut((F32)previewp->childGetValue("loop_out_point").asReal() * 0.01f * motionp->getDuration());
653 }
654}
655
656//-----------------------------------------------------------------------------
657// onCommitLoopIn()
658//-----------------------------------------------------------------------------
659void LLFloaterAnimPreview::onCommitLoopIn(LLUICtrl* ctrl, void* data)
660{
661 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
662 if (!previewp->mEnabled) return;
663
664 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
665 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
666
667 if (motionp)
668 {
669 motionp->setLoopIn((F32)previewp->childGetValue("loop_in_point").asReal() / 100.f);
670 previewp->resetMotion();
671 previewp->childSetValue("loop_check", LLSD(TRUE));
672 onCommitLoop(ctrl, data);
673 }
674}
675
676//-----------------------------------------------------------------------------
677// onCommitLoopOut()
678//-----------------------------------------------------------------------------
679void LLFloaterAnimPreview::onCommitLoopOut(LLUICtrl* ctrl, void* data)
680{
681 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
682 if (!previewp->mEnabled) return;
683
684 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
685 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
686
687 if (motionp)
688 {
689 motionp->setLoopOut((F32)previewp->childGetValue("loop_out_point").asReal() * 0.01f * motionp->getDuration());
690 previewp->resetMotion();
691 previewp->childSetValue("loop_check", LLSD(TRUE));
692 onCommitLoop(ctrl, data);
693 }
694}
695
696//-----------------------------------------------------------------------------
697// onCommitName()
698//-----------------------------------------------------------------------------
699void LLFloaterAnimPreview::onCommitName(LLUICtrl* ctrl, void* data)
700{
701 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
702 if (!previewp->mEnabled) return;
703
704 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
705 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
706
707 if (motionp)
708 {
709 motionp->setName(previewp->childGetValue("name_form").asString());
710 }
711
712 LLFloaterNameDesc::doCommit(ctrl, data);
713}
714
715//-----------------------------------------------------------------------------
716// onCommitHandPose()
717//-----------------------------------------------------------------------------
718void LLFloaterAnimPreview::onCommitHandPose(LLUICtrl* ctrl, void* data)
719{
720 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
721 if (!previewp->mEnabled) return;
722
723 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
724 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
725
726 motionp->setHandPose(LLHandMotion::getHandPose(previewp->childGetValue("hand_pose_combo").asString()));
727 previewp->resetMotion();
728}
729
730//-----------------------------------------------------------------------------
731// onCommitEmote()
732//-----------------------------------------------------------------------------
733void LLFloaterAnimPreview::onCommitEmote(LLUICtrl* ctrl, void* data)
734{
735 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
736 if (!previewp->mEnabled) return;
737
738 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
739 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
740
741 motionp->setEmote(previewp->mIDList[previewp->childGetValue("emote_combo").asString()]);
742 previewp->resetMotion();
743}
744
745//-----------------------------------------------------------------------------
746// onCommitPriority()
747//-----------------------------------------------------------------------------
748void LLFloaterAnimPreview::onCommitPriority(LLUICtrl* ctrl, void* data)
749{
750 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
751 if (!previewp->mEnabled) return;
752
753 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
754 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
755
756 motionp->setPriority(llfloor((F32)previewp->childGetValue("priority").asReal()));
757}
758
759//-----------------------------------------------------------------------------
760// onCommitEaseIn()
761//-----------------------------------------------------------------------------
762void LLFloaterAnimPreview::onCommitEaseIn(LLUICtrl* ctrl, void* data)
763{
764 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
765 if (!previewp->mEnabled) return;
766
767 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
768 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
769
770 motionp->setEaseIn((F32)previewp->childGetValue("ease_in_time").asReal());
771 previewp->resetMotion();
772}
773
774//-----------------------------------------------------------------------------
775// onCommitEaseOut()
776//-----------------------------------------------------------------------------
777void LLFloaterAnimPreview::onCommitEaseOut(LLUICtrl* ctrl, void* data)
778{
779 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
780 if (!previewp->mEnabled) return;
781
782 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
783 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
784
785 motionp->setEaseOut((F32)previewp->childGetValue("ease_out_time").asReal());
786 previewp->resetMotion();
787}
788
789//-----------------------------------------------------------------------------
790// validateEaseIn()
791//-----------------------------------------------------------------------------
792BOOL LLFloaterAnimPreview::validateEaseIn(LLUICtrl* spin, void* data)
793{
794 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
795
796 if (!previewp->mEnabled) return FALSE;
797
798 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
799 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
800
801 if (!motionp->getLoop())
802 {
803 F32 new_ease_in = llclamp((F32)previewp->childGetValue("ease_in_time").asReal(), 0.f, motionp->getDuration() - motionp->getEaseOutDuration());
804 previewp->childSetValue("ease_in_time", LLSD(new_ease_in));
805 }
806
807 return TRUE;
808}
809
810//-----------------------------------------------------------------------------
811// validateEaseOut()
812//-----------------------------------------------------------------------------
813BOOL LLFloaterAnimPreview::validateEaseOut(LLUICtrl* spin, void* data)
814{
815 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
816
817 if (!previewp->mEnabled) return FALSE;
818
819 LLVOAvatar* avatarp = previewp->mAnimPreview->getDummyAvatar();
820 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(previewp->mMotionID);
821
822 if (!motionp->getLoop())
823 {
824 F32 new_ease_out = llclamp((F32)previewp->childGetValue("ease_out_time").asReal(), 0.f, motionp->getDuration() - motionp->getEaseInDuration());
825 previewp->childSetValue("ease_out_time", LLSD(new_ease_out));
826 }
827
828 return TRUE;
829}
830
831//-----------------------------------------------------------------------------
832// validateLoopIn()
833//-----------------------------------------------------------------------------
834BOOL LLFloaterAnimPreview::validateLoopIn(LLUICtrl* ctrl, void* data)
835{
836 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
837
838 if (!previewp->mEnabled) return FALSE;
839
840 F32 loop_in_value = (F32)previewp->childGetValue("loop_in_point").asReal();
841 F32 loop_out_value = (F32)previewp->childGetValue("loop_out_point").asReal();
842
843 if (loop_in_value < 0.f)
844 {
845 loop_in_value = 0.f;
846 }
847 else if (loop_in_value > 100.f)
848 {
849 loop_in_value = 100.f;
850 }
851 else if (loop_in_value > loop_out_value)
852 {
853 loop_in_value = loop_out_value;
854 }
855
856 previewp->childSetValue("loop_in_point", LLSD(loop_in_value));
857 return TRUE;
858}
859
860//-----------------------------------------------------------------------------
861// validateLoopOut()
862//-----------------------------------------------------------------------------
863BOOL LLFloaterAnimPreview::validateLoopOut(LLUICtrl* spin, void* data)
864{
865 LLFloaterAnimPreview* previewp = (LLFloaterAnimPreview*)data;
866
867 if (!previewp->mEnabled) return FALSE;
868
869 F32 loop_out_value = (F32)previewp->childGetValue("loop_out_point").asReal();
870 F32 loop_in_value = (F32)previewp->childGetValue("loop_in_point").asReal();
871
872 if (loop_out_value < 0.f)
873 {
874 loop_out_value = 0.f;
875 }
876 else if (loop_out_value > 100.f)
877 {
878 loop_out_value = 100.f;
879 }
880 else if (loop_out_value < loop_in_value)
881 {
882 loop_out_value = loop_in_value;
883 }
884
885 previewp->childSetValue("loop_out_point", LLSD(loop_out_value));
886 return TRUE;
887}
888
889
890//-----------------------------------------------------------------------------
891// refresh()
892//-----------------------------------------------------------------------------
893void LLFloaterAnimPreview::refresh()
894{
895 if (!mAnimPreview)
896 {
897 childShow("bad_animation_text");
898 mPlayButton->setEnabled(FALSE);
899 mStopButton->setEnabled(FALSE);
900 childDisable("ok_btn");
901 }
902 else
903 {
904 childHide("bad_animation_text");
905 mPlayButton->setEnabled(TRUE);
906 LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
907 if (avatarp->isMotionActive(mMotionID))
908 {
909 mStopButton->setEnabled(TRUE);
910 LLKeyframeMotion* motionp = (LLKeyframeMotion*)avatarp->findMotion(mMotionID);
911 if (avatarp->areAnimationsPaused())
912 {
913
914 mPlayButton->setImages("button_anim_play.tga",
915 "button_anim_play_selected.tga");
916
917 }
918 else
919 {
920 if (motionp)
921 {
922 F32 fraction_complete;
923 fraction_complete = motionp->getLastUpdateTime() / motionp->getDuration();
924
925 childSetValue("playback_slider", fraction_complete);
926 mLastSliderValue = fraction_complete;
927 }
928 mPlayButton->setImages("button_anim_pause.tga",
929 "button_anim_pause_selected.tga");
930
931 }
932 }
933 else
934 {
935 mPauseRequest = avatarp->requestPause();
936 mPlayButton->setImages("button_anim_play.tga",
937 "button_anim_play_selected.tga");
938
939 mStopButton->setEnabled(FALSE);
940 }
941 childEnable("ok_btn");
942 mAnimPreview->requestUpdate();
943 }
944}
945
946//-----------------------------------------------------------------------------
947// onBtnOK()
948//-----------------------------------------------------------------------------
949void LLFloaterAnimPreview::onBtnOK(void* userdata)
950{
951 LLFloaterAnimPreview* floaterp = (LLFloaterAnimPreview*)userdata;
952 if (!floaterp->mEnabled) return;
953
954 if (floaterp->mAnimPreview)
955 {
956 LLKeyframeMotion* motionp = (LLKeyframeMotion*)floaterp->mAnimPreview->getDummyAvatar()->findMotion(floaterp->mMotionID);
957
958 S32 file_size = motionp->getFileSize();
959 U8* buffer = new U8[file_size];
960
961 LLDataPackerBinaryBuffer dp(buffer, file_size);
962 if (motionp->serialize(dp))
963 {
964 LLVFile file(gVFS, motionp->getID(), LLAssetType::AT_ANIMATION, LLVFile::APPEND);
965
966 S32 size = dp.getCurrentSize();
967 file.setMaxSize(size);
968 if (file.write((U8*)buffer, size))
969 {
970 std::string name = floaterp->childGetValue("name_form").asString();
971 std::string desc = floaterp->childGetValue("description_form").asString();
972 upload_new_resource(floaterp->mTransactionID, // tid
973 LLAssetType::AT_ANIMATION,
974 name,
975 desc,
976 0,
977 LLAssetType::AT_NONE,
978 LLInventoryType::IT_ANIMATION,
979 PERM_NONE,
980 name);
981 }
982 else
983 {
984 llwarns << "Failure writing animation data." << llendl;
985 gViewerWindow->alertXml("WriteAnimationFail");
986 }
987 }
988
989 delete [] buffer;
990 // clear out cache for motion data
991 floaterp->mAnimPreview->getDummyAvatar()->removeMotion(floaterp->mMotionID);
992 LLKeyframeDataCache::removeKeyframeData(floaterp->mMotionID);
993 }
994
995 floaterp->onClose(false);
996}
997
998//-----------------------------------------------------------------------------
999// LLPreviewAnimation
1000//-----------------------------------------------------------------------------
1001LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
1002{
1003 mNeedsUpdate = TRUE;
1004 mCameraDistance = PREVIEW_CAMERA_DISTANCE;
1005 mCameraYaw = 0.f;
1006 mCameraPitch = 0.f;
1007 mCameraZoom = 1.f;
1008
1009 mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion());
1010 mDummyAvatar->createDrawable(&gPipeline);
1011 mDummyAvatar->mIsDummy = TRUE;
1012 mDummyAvatar->mSpecialRenderMode = 1;
1013 mDummyAvatar->setPositionAgent(LLVector3::zero);
1014 mDummyAvatar->slamPosition();
1015 mDummyAvatar->updateJointLODs();
1016 mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
1017 mDummyAvatar->startMotion(ANIM_AGENT_STAND, 5.f);
1018 mDummyAvatar->mSkirtLOD.setVisible(FALSE, TRUE);
1019 gPipeline.markVisible(mDummyAvatar->mDrawable);
1020
1021 // stop extraneous animations
1022 mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE );
1023 mDummyAvatar->stopMotion( ANIM_AGENT_EYE, TRUE );
1024 mDummyAvatar->stopMotion( ANIM_AGENT_BODY_NOISE, TRUE );
1025 mDummyAvatar->stopMotion( ANIM_AGENT_BREATHE_ROT, TRUE );
1026}
1027
1028//-----------------------------------------------------------------------------
1029// LLPreviewAnimation()
1030//-----------------------------------------------------------------------------
1031LLPreviewAnimation::~LLPreviewAnimation()
1032{
1033 mDummyAvatar->markDead();
1034}
1035
1036//-----------------------------------------------------------------------------
1037// update()
1038//-----------------------------------------------------------------------------
1039BOOL LLPreviewAnimation::render()
1040{
1041 mNeedsUpdate = FALSE;
1042 LLVOAvatar* avatarp = mDummyAvatar;
1043
1044 glMatrixMode(GL_PROJECTION);
1045 glPushMatrix();
1046 glLoadIdentity();
1047 glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
1048
1049 glMatrixMode(GL_MODELVIEW);
1050 glPushMatrix();
1051 glLoadIdentity();
1052
1053 LLGLSUIDefault def;
1054 LLGLSNoTexture gls_no_texture;
1055 glColor4f(0.15f, 0.2f, 0.3f, 1.f);
1056
1057 gl_rect_2d_simple( mWidth, mHeight );
1058
1059 glMatrixMode(GL_PROJECTION);
1060 glPopMatrix();
1061
1062 glMatrixMode(GL_MODELVIEW);
1063 glPopMatrix();
1064
1065 LLVector3 target_pos = avatarp->mRoot.getWorldPosition();
1066
1067 LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
1068 LLQuaternion(mCameraYaw, LLVector3::z_axis);
1069
1070 LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot;
1071 gCamera->setOriginAndLookAt(
1072 target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
1073 LLVector3::z_axis, // up
1074 target_pos + (mCameraOffset * av_rot) ); // point of interest
1075
1076 gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom);
1077 gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
1078
1079 mCameraRelPos = gCamera->getOrigin() - avatarp->mHeadp->getWorldPosition();
1080
1081 //avatarp->setAnimationData("LookAtPoint", (void *)&mCameraRelPos);
1082
1083 //RN: timestep must be zero, because paused animations will never initialize
1084 // av skeleton otherwise
1085 avatarp->setTimeStep(0.f);
1086 if (avatarp->areAnimationsPaused())
1087 {
1088 avatarp->updateMotion(TRUE);
1089 }
1090 else
1091 {
1092 avatarp->updateMotion();
1093 }
1094
1095 avatarp->mRoot.updateWorldMatrixChildren();
1096
1097 stop_glerror();
1098
1099 LLGLDepthTest gls_depth(GL_TRUE);
1100
1101 if (avatarp->mDrawable.notNull())
1102 {
1103 LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
1104 gPipeline.unbindAGP();
1105 avatarPoolp->syncAGP();
1106 if (avatarPoolp->canUseAGP() && gPipeline.usingAGP())
1107 {
1108 gPipeline.bindAGP();
1109 }
1110 avatarPoolp->renderAvatars(avatarp, TRUE); // renders only one avatar (no shaders)
1111 }
1112
1113 return TRUE;
1114}
1115
1116//-----------------------------------------------------------------------------
1117// requestUpdate()
1118//-----------------------------------------------------------------------------
1119void LLPreviewAnimation::requestUpdate()
1120{
1121 mNeedsUpdate = TRUE;
1122}
1123
1124//-----------------------------------------------------------------------------
1125// rotate()
1126//-----------------------------------------------------------------------------
1127void LLPreviewAnimation::rotate(F32 yaw_radians, F32 pitch_radians)
1128{
1129 mCameraYaw = mCameraYaw + yaw_radians;
1130
1131 mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
1132}
1133
1134//-----------------------------------------------------------------------------
1135// zoom()
1136//-----------------------------------------------------------------------------
1137void LLPreviewAnimation::zoom(F32 zoom_delta)
1138{
1139 setZoom(mCameraZoom + zoom_delta);
1140}
1141
1142//-----------------------------------------------------------------------------
1143// setZoom()
1144//-----------------------------------------------------------------------------
1145void LLPreviewAnimation::setZoom(F32 zoom_amt)
1146{
1147 mCameraZoom = llclamp(zoom_amt, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM);
1148}
1149
1150//-----------------------------------------------------------------------------
1151// pan()
1152//-----------------------------------------------------------------------------
1153void LLPreviewAnimation::pan(F32 right, F32 up)
1154{
1155 mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
1156 mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
1157}
1158