diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llfloateranimpreview.cpp | |
parent | README.txt (diff) | |
download | meta-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.cpp | 1158 |
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 | |||
62 | S32 LLFloaterAnimPreview::sUploadAmount = 10; | ||
63 | |||
64 | const S32 PREVIEW_BORDER_WIDTH = 2; | ||
65 | const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH; | ||
66 | const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; | ||
67 | const S32 PREF_BUTTON_HEIGHT = 16; | ||
68 | const S32 PREVIEW_TEXTURE_HEIGHT = 300; | ||
69 | |||
70 | const F32 PREVIEW_CAMERA_DISTANCE = 4.f; | ||
71 | |||
72 | const F32 MIN_CAMERA_ZOOM = 0.5f; | ||
73 | const F32 MAX_CAMERA_ZOOM = 10.f; | ||
74 | |||
75 | //----------------------------------------------------------------------------- | ||
76 | // LLFloaterAnimPreview() | ||
77 | //----------------------------------------------------------------------------- | ||
78 | LLFloaterAnimPreview::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 | //----------------------------------------------------------------------------- | ||
115 | BOOL 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 | //----------------------------------------------------------------------------- | ||
334 | LLFloaterAnimPreview::~LLFloaterAnimPreview() | ||
335 | { | ||
336 | delete mAnimPreview; | ||
337 | mAnimPreview = NULL; | ||
338 | |||
339 | mEnabled = FALSE; | ||
340 | } | ||
341 | |||
342 | //----------------------------------------------------------------------------- | ||
343 | // draw() | ||
344 | //----------------------------------------------------------------------------- | ||
345 | void 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 | //----------------------------------------------------------------------------- | ||
383 | void 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 | //----------------------------------------------------------------------------- | ||
407 | BOOL 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 | //----------------------------------------------------------------------------- | ||
425 | BOOL 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 | //----------------------------------------------------------------------------- | ||
435 | BOOL 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 | //----------------------------------------------------------------------------- | ||
490 | BOOL 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 | //----------------------------------------------------------------------------- | ||
501 | void LLFloaterAnimPreview::onMouseCaptureLost(LLMouseHandler* handler) | ||
502 | { | ||
503 | gViewerWindow->showCursor(); | ||
504 | } | ||
505 | |||
506 | //----------------------------------------------------------------------------- | ||
507 | // onBtnPlay() | ||
508 | //----------------------------------------------------------------------------- | ||
509 | void 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 | //----------------------------------------------------------------------------- | ||
540 | void 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 | //----------------------------------------------------------------------------- | ||
565 | void 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 | //----------------------------------------------------------------------------- | ||
610 | void 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 | //----------------------------------------------------------------------------- | ||
640 | void 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 | //----------------------------------------------------------------------------- | ||
659 | void 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 | //----------------------------------------------------------------------------- | ||
679 | void 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 | //----------------------------------------------------------------------------- | ||
699 | void 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 | //----------------------------------------------------------------------------- | ||
718 | void 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 | //----------------------------------------------------------------------------- | ||
733 | void 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 | //----------------------------------------------------------------------------- | ||
748 | void 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 | //----------------------------------------------------------------------------- | ||
762 | void 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 | //----------------------------------------------------------------------------- | ||
777 | void 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 | //----------------------------------------------------------------------------- | ||
792 | BOOL 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 | //----------------------------------------------------------------------------- | ||
813 | BOOL 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 | //----------------------------------------------------------------------------- | ||
834 | BOOL 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 | //----------------------------------------------------------------------------- | ||
863 | BOOL 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 | //----------------------------------------------------------------------------- | ||
893 | void 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 | //----------------------------------------------------------------------------- | ||
949 | void 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 | //----------------------------------------------------------------------------- | ||
1001 | LLPreviewAnimation::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 | //----------------------------------------------------------------------------- | ||
1031 | LLPreviewAnimation::~LLPreviewAnimation() | ||
1032 | { | ||
1033 | mDummyAvatar->markDead(); | ||
1034 | } | ||
1035 | |||
1036 | //----------------------------------------------------------------------------- | ||
1037 | // update() | ||
1038 | //----------------------------------------------------------------------------- | ||
1039 | BOOL 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 | //----------------------------------------------------------------------------- | ||
1119 | void LLPreviewAnimation::requestUpdate() | ||
1120 | { | ||
1121 | mNeedsUpdate = TRUE; | ||
1122 | } | ||
1123 | |||
1124 | //----------------------------------------------------------------------------- | ||
1125 | // rotate() | ||
1126 | //----------------------------------------------------------------------------- | ||
1127 | void 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 | //----------------------------------------------------------------------------- | ||
1137 | void LLPreviewAnimation::zoom(F32 zoom_delta) | ||
1138 | { | ||
1139 | setZoom(mCameraZoom + zoom_delta); | ||
1140 | } | ||
1141 | |||
1142 | //----------------------------------------------------------------------------- | ||
1143 | // setZoom() | ||
1144 | //----------------------------------------------------------------------------- | ||
1145 | void LLPreviewAnimation::setZoom(F32 zoom_amt) | ||
1146 | { | ||
1147 | mCameraZoom = llclamp(zoom_amt, MIN_CAMERA_ZOOM, MAX_CAMERA_ZOOM); | ||
1148 | } | ||
1149 | |||
1150 | //----------------------------------------------------------------------------- | ||
1151 | // pan() | ||
1152 | //----------------------------------------------------------------------------- | ||
1153 | void 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 | |||