aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llfloaterimagepreview.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/llfloaterimagepreview.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 'linden/indra/newview/llfloaterimagepreview.cpp')
-rw-r--r--linden/indra/newview/llfloaterimagepreview.cpp698
1 files changed, 698 insertions, 0 deletions
diff --git a/linden/indra/newview/llfloaterimagepreview.cpp b/linden/indra/newview/llfloaterimagepreview.cpp
new file mode 100644
index 0000000..c741bdb
--- /dev/null
+++ b/linden/indra/newview/llfloaterimagepreview.cpp
@@ -0,0 +1,698 @@
1/**
2 * @file llfloaterimagepreview.cpp
3 * @brief LLFloaterImagePreview 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 "llfloaterimagepreview.h"
31
32#include "llimagebmp.h"
33#include "llimagetga.h"
34#include "llimagejpeg.h"
35
36#include "llagent.h"
37#include "llbutton.h"
38#include "llcombobox.h"
39#include "lldrawable.h"
40#include "lldrawpoolavatar.h"
41#include "llface.h"
42#include "lltextbox.h"
43#include "lltoolmgr.h"
44#include "llui.h"
45#include "llviewercamera.h"
46#include "llviewerwindow.h"
47#include "llvoavatar.h"
48#include "pipeline.h"
49#include "viewer.h"
50#include "llvieweruictrlfactory.h"
51
52//static
53S32 LLFloaterImagePreview::sUploadAmount = 10;
54
55const S32 PREVIEW_BORDER_WIDTH = 2;
56const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
57const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
58const S32 PREF_BUTTON_HEIGHT = 16;
59const S32 PREVIEW_TEXTURE_HEIGHT = 300;
60
61//-----------------------------------------------------------------------------
62// LLFloaterImagePreview()
63//-----------------------------------------------------------------------------
64LLFloaterImagePreview::LLFloaterImagePreview(const char* filename) :
65 LLFloaterNameDesc(filename)
66{
67 mLastMouseX = 0;
68 mLastMouseY = 0;
69 mGLName = 0;
70 loadImage(mFilenameAndPath.c_str());
71}
72
73//-----------------------------------------------------------------------------
74// postBuild()
75//-----------------------------------------------------------------------------
76BOOL LLFloaterImagePreview::postBuild()
77{
78 if (!LLFloaterNameDesc::postBuild())
79 {
80 return FALSE;
81 }
82
83 childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount));
84
85 LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
86 if (iface)
87 {
88 iface->selectFirstItem();
89 }
90 childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this);
91
92 mPreviewRect.set(PREVIEW_HPAD,
93 PREVIEW_TEXTURE_HEIGHT,
94 getRect().getWidth() - PREVIEW_HPAD,
95 PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
96 mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
97
98 childHide("bad_image_text");
99
100 if (mRawImagep.notNull())
101 {
102 mAvatarPreview = new LLImagePreviewAvatar(256, 256);
103 mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE);
104 }
105 else
106 {
107 mAvatarPreview = NULL;
108 childShow("bad_image_text");
109 childDisable("clothing_type_combo");
110 childDisable("ok_btn");
111 }
112
113 return TRUE;
114}
115
116//-----------------------------------------------------------------------------
117// LLFloaterImagePreview()
118//-----------------------------------------------------------------------------
119LLFloaterImagePreview::~LLFloaterImagePreview()
120{
121 mRawImagep = NULL;
122 delete mAvatarPreview;
123 if (mGLName)
124 {
125 glDeleteTextures(1, &mGLName );
126 }
127}
128
129//static
130//-----------------------------------------------------------------------------
131// onPreviewTypeCommit()
132//-----------------------------------------------------------------------------
133void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata)
134{
135 LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata;
136
137 if (!fp->mAvatarPreview)
138 {
139 return;
140 }
141
142 S32 which_mode = 0;
143
144 LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("clothing_type_combo");
145 if (iface)
146 {
147 which_mode = iface->getFirstSelectedIndex();
148 }
149
150 switch(which_mode)
151 {
152 case 0:
153 break;
154 case 1:
155 fp->mAvatarPreview->setPreviewTarget("mSkull", "mHairMesh0", fp->mRawImagep, 0.4f, FALSE);
156 break;
157 case 2:
158 fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, FALSE);
159 break;
160 case 3:
161 fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.0f, FALSE);
162 break;
163 case 4:
164 fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, FALSE);
165 break;
166 case 5:
167 fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, TRUE);
168 break;
169 case 6:
170 fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
171 break;
172 case 7:
173 fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
174 break;
175 case 8:
176 fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE);
177 break;
178 default:
179 break;
180 }
181 fp->mAvatarPreview->refresh();
182 //gViewerWindow->requestFastFrame(fp);
183}
184
185//-----------------------------------------------------------------------------
186// draw()
187//-----------------------------------------------------------------------------
188void LLFloaterImagePreview::draw()
189{
190 LLFloater::draw();
191 LLRect r = getRect();
192
193 if (mRawImagep.notNull())
194 {
195 LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
196 if (iface && iface->getFirstSelectedIndex() <= 0)
197 {
198 gl_rect_2d_checkerboard(mPreviewRect);
199 LLGLDisable gls_alpha(GL_ALPHA_TEST);
200
201 GLenum format_options[4] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA };
202 GLenum format = format_options[mRawImagep->getComponents()-1];
203
204 GLenum internal_format_options[4] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 };
205 GLenum internal_format = internal_format_options[mRawImagep->getComponents()-1];
206
207 if (mGLName)
208 {
209 LLImageGL::bindExternalTexture( mGLName, 0, GL_TEXTURE_2D );
210 }
211 else
212 {
213 glGenTextures(1, &mGLName );
214 stop_glerror();
215
216 LLImageGL::bindExternalTexture( mGLName, 0, GL_TEXTURE_2D );
217 stop_glerror();
218
219 glTexImage2D(
220 GL_TEXTURE_2D, 0, internal_format,
221 mRawImagep->getWidth(), mRawImagep->getHeight(),
222 0, format, GL_UNSIGNED_BYTE, mRawImagep->getData());
223 stop_glerror();
224
225 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
227
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
230 if (mAvatarPreview)
231 {
232 mAvatarPreview->setTexture(mGLName);
233 }
234 }
235
236 glColor3f(1.f, 1.f, 1.f);
237 glBegin( GL_QUADS );
238 {
239 glTexCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop);
240 glVertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
241 glTexCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom);
242 glVertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
243 glTexCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom);
244 glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
245 glTexCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop);
246 glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
247 }
248 glEnd();
249
250 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
251
252 stop_glerror();
253 }
254 else
255 {
256 if (mAvatarPreview)
257 {
258 glColor3f(1.f, 1.f, 1.f);
259 mAvatarPreview->bindTexture();
260
261 glBegin( GL_QUADS );
262 {
263 glTexCoord2f(0.f, 1.f);
264 glVertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
265 glTexCoord2f(0.f, 0.f);
266 glVertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
267 glTexCoord2f(1.f, 0.f);
268 glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
269 glTexCoord2f(1.f, 1.f);
270 glVertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT);
271 }
272 glEnd();
273
274 mAvatarPreview->unbindTexture();
275 }
276 }
277 }
278}
279
280//-----------------------------------------------------------------------------
281// loadImage()
282//-----------------------------------------------------------------------------
283bool LLFloaterImagePreview::loadImage(const char *src_filename)
284{
285 // U32 length = strlen(src_filename);
286 const char* ext = strrchr(src_filename, '.');
287 char error_message[MAX_STRING];
288 error_message[0] = '\0';
289
290 U32 codec = IMG_CODEC_INVALID;
291 LLString temp_str;
292 if( 0 == strnicmp(ext, ".bmp", 4) )
293 {
294 codec = IMG_CODEC_BMP;
295 }
296 else if( 0 == strnicmp(ext, ".tga", 4) )
297 {
298 codec = IMG_CODEC_TGA;
299 }
300 else if( 0 == strnicmp(ext, ".jpg", 4) || 0 == strnicmp(ext, ".jpeg", 5))
301 {
302 codec = IMG_CODEC_JPEG;
303 }
304
305 LLPointer<LLImageRaw> raw_image = new LLImageRaw;
306
307 switch (codec)
308 {
309 case IMG_CODEC_BMP:
310 {
311 LLPointer<LLImageBMP> bmp_image = new LLImageBMP;
312
313 if (!bmp_image->load(src_filename))
314 {
315 return false;
316 }
317
318 if (!bmp_image->decode(raw_image))
319 {
320 return false;
321 }
322 }
323 break;
324 case IMG_CODEC_TGA:
325 {
326 LLPointer<LLImageTGA> tga_image = new LLImageTGA;
327
328 if (!tga_image->load(src_filename))
329 {
330 return false;
331 }
332
333 if (!tga_image->decode(raw_image))
334 {
335 return false;
336 }
337
338 if( (tga_image->getComponents() != 3) &&
339 (tga_image->getComponents() != 4) )
340 {
341 tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." );
342 return false;
343 }
344 }
345 break;
346 case IMG_CODEC_JPEG:
347 {
348 LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG;
349
350 if (!jpeg_image->load(src_filename))
351 {
352 return false;
353 }
354
355 if (!jpeg_image->decode(raw_image))
356 {
357 return false;
358 }
359 }
360 break;
361 default:
362 return false;
363 }
364
365 raw_image->biasedScaleToPowerOfTwo(1024);
366 mRawImagep = raw_image;
367
368 return true;
369}
370
371//-----------------------------------------------------------------------------
372// handleMouseDown()
373//-----------------------------------------------------------------------------
374BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask)
375{
376 if (mPreviewRect.pointInRect(x, y))
377 {
378 bringToFront( x, y );
379 gViewerWindow->setMouseCapture(this, onMouseCaptureLost);
380 gViewerWindow->hideCursor();
381 mLastMouseX = x;
382 mLastMouseY = y;
383 return TRUE;
384 }
385
386 return LLFloater::handleMouseDown(x, y, mask);
387}
388
389//-----------------------------------------------------------------------------
390// handleMouseUp()
391//-----------------------------------------------------------------------------
392BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask)
393{
394 gViewerWindow->setMouseCapture(FALSE, NULL);
395 gViewerWindow->showCursor();
396 return LLFloater::handleMouseUp(x, y, mask);
397}
398
399//-----------------------------------------------------------------------------
400// handleHover()
401//-----------------------------------------------------------------------------
402BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
403{
404 MASK local_mask = mask & ~MASK_ALT;
405
406 if (mAvatarPreview && gViewerWindow->hasMouseCapture(this))
407 {
408 if (local_mask == MASK_PAN)
409 {
410 // pan here
411 LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
412 if (iface && iface->getFirstSelectedIndex() <= 0)
413 {
414 mPreviewImageRect.translate((F32)(x - mLastMouseX) * -0.005f * mPreviewImageRect.getWidth(),
415 (F32)(y - mLastMouseY) * -0.005f * mPreviewImageRect.getHeight());
416 }
417 else
418 {
419 mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
420 }
421 }
422 else if (local_mask == MASK_ORBIT)
423 {
424 F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
425 F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
426
427 mAvatarPreview->rotate(yaw_radians, pitch_radians);
428 }
429 else
430 {
431 LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
432 if (iface && iface->getFirstSelectedIndex() <= 0)
433 {
434 F32 zoom_amt = (F32)(y - mLastMouseY) * -0.002f;
435 mPreviewImageRect.stretch(zoom_amt);
436 }
437 else
438 {
439 F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
440 F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
441
442 mAvatarPreview->rotate(yaw_radians, 0.f);
443 mAvatarPreview->zoom(zoom_amt);
444 }
445 }
446
447 LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
448 if (iface && iface->getFirstSelectedIndex() <= 0)
449 {
450 if (mPreviewImageRect.getWidth() > 1.f)
451 {
452 mPreviewImageRect.stretch((1.f - mPreviewImageRect.getWidth()) * 0.5f);
453 }
454 else if (mPreviewImageRect.getWidth() < 0.1f)
455 {
456 mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getWidth()) * 0.5f);
457 }
458
459 if (mPreviewImageRect.getHeight() > 1.f)
460 {
461 mPreviewImageRect.stretch((1.f - mPreviewImageRect.getHeight()) * 0.5f);
462 }
463 else if (mPreviewImageRect.getHeight() < 0.1f)
464 {
465 mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getHeight()) * 0.5f);
466 }
467
468 if (mPreviewImageRect.mLeft < 0.f)
469 {
470 mPreviewImageRect.translate(-mPreviewImageRect.mLeft, 0.f);
471 }
472 else if (mPreviewImageRect.mRight > 1.f)
473 {
474 mPreviewImageRect.translate(1.f - mPreviewImageRect.mRight, 0.f);
475 }
476
477 if (mPreviewImageRect.mBottom < 0.f)
478 {
479 mPreviewImageRect.translate(0.f, -mPreviewImageRect.mBottom);
480 }
481 else if (mPreviewImageRect.mTop > 1.f)
482 {
483 mPreviewImageRect.translate(0.f, 1.f - mPreviewImageRect.mTop);
484 }
485 }
486 else
487 {
488 mAvatarPreview->refresh();
489 }
490
491 LLUI::setCursorPositionLocal(this, mLastMouseX, mLastMouseY);
492 //gViewerWindow->requestFastFrame(this);
493 }
494
495 if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview)
496 {
497 return LLFloater::handleHover(x, y, mask);
498 }
499 else if (local_mask == MASK_ORBIT)
500 {
501 gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
502 }
503 else if (local_mask == MASK_PAN)
504 {
505 gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
506 }
507 else
508 {
509 gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
510 }
511
512 return TRUE;
513}
514
515//-----------------------------------------------------------------------------
516// handleScrollWheel()
517//-----------------------------------------------------------------------------
518BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
519{
520 if (mPreviewRect.pointInRect(x, y) && mAvatarPreview)
521 {
522 mAvatarPreview->zoom((F32)clicks * -0.2f);
523 mAvatarPreview->refresh();
524 //gViewerWindow->requestFastFrame(this);
525 }
526
527 return TRUE;
528}
529
530//-----------------------------------------------------------------------------
531// onMouseCaptureLost()
532//-----------------------------------------------------------------------------
533void LLFloaterImagePreview::onMouseCaptureLost(LLMouseHandler* handler)
534{
535 gViewerWindow->showCursor();
536}
537
538
539//-----------------------------------------------------------------------------
540// LLImagePreviewAvatar
541//-----------------------------------------------------------------------------
542LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
543{
544 mNeedsUpdate = TRUE;
545 mTargetJoint = NULL;
546 mTargetMesh = NULL;
547 mCameraDistance = 0.f;
548 mCameraYaw = 0.f;
549 mCameraPitch = 0.f;
550 mCameraZoom = 1.f;
551
552 mDummyAvatar = new LLVOAvatar(LLUUID::null, LL_PCODE_LEGACY_AVATAR, gAgent.getRegion());
553 mDummyAvatar->createDrawable(&gPipeline);
554 mDummyAvatar->mIsDummy = TRUE;
555 mDummyAvatar->mSpecialRenderMode = 2;
556 mDummyAvatar->setPositionAgent(LLVector3::zero);
557 mDummyAvatar->slamPosition();
558 mDummyAvatar->updateJointLODs();
559 mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
560 gPipeline.markVisible(mDummyAvatar->mDrawable);
561
562 mTextureName = 0;
563}
564
565LLImagePreviewAvatar::~LLImagePreviewAvatar()
566{
567 mDummyAvatar->markDead();
568}
569
570
571void LLImagePreviewAvatar::setPreviewTarget(const char* joint_name, const char* mesh_name, LLImageRaw* imagep, F32 distance, BOOL male)
572{
573 mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name);
574 // clear out existing test mesh
575 if (mTargetMesh)
576 {
577 mTargetMesh->setTestTexture(0);
578 }
579
580 if (male)
581 {
582 mDummyAvatar->setVisualParamWeight( "male", 1.f );
583 mDummyAvatar->updateVisualParams();
584 mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
585 }
586 else
587 {
588 mDummyAvatar->setVisualParamWeight( "male", 0.f );
589 mDummyAvatar->updateVisualParams();
590 mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
591 }
592 mDummyAvatar->mRoot.setVisible(FALSE, TRUE);
593
594 mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
595 mTargetMesh->setTestTexture(mTextureName);
596 mTargetMesh->setVisible(TRUE, FALSE);
597 mCameraDistance = distance;
598 mCameraZoom = 1.f;
599 mCameraPitch = 0.f;
600 mCameraYaw = 0.f;
601 mCameraOffset.clearVec();
602}
603
604//-----------------------------------------------------------------------------
605// update()
606//-----------------------------------------------------------------------------
607BOOL LLImagePreviewAvatar::render()
608{
609 mNeedsUpdate = FALSE;
610 LLVOAvatar* avatarp = mDummyAvatar;
611
612 glMatrixMode(GL_PROJECTION);
613 glPushMatrix();
614 glLoadIdentity();
615 glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
616
617 glMatrixMode(GL_MODELVIEW);
618 glPushMatrix();
619 glLoadIdentity();
620
621 LLGLSUIDefault def;
622 glColor4f(0.15f, 0.2f, 0.3f, 1.f);
623
624 gl_rect_2d_simple( mWidth, mHeight );
625
626 glMatrixMode(GL_PROJECTION);
627 glPopMatrix();
628
629 glMatrixMode(GL_MODELVIEW);
630 glPopMatrix();
631
632 LLVector3 target_pos = mTargetJoint->getWorldPosition();
633
634 LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
635 LLQuaternion(mCameraYaw, LLVector3::z_axis);
636
637 LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot;
638 gCamera->setOriginAndLookAt(
639 target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
640 LLVector3::z_axis, // up
641 target_pos + (mCameraOffset * av_rot) ); // point of interest
642
643 stop_glerror();
644
645 gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom);
646 gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
647
648 if (avatarp->mDrawable.notNull())
649 {
650 LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
651 // make sure alpha=0 shows avatar material color
652 LLGLDisable no_blend(GL_BLEND);
653
654 LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
655
656 gPipeline.unbindAGP();
657 avatarPoolp->syncAGP();
658 if (avatarPoolp->canUseAGP() && gPipeline.usingAGP())
659 {
660 gPipeline.bindAGP();
661 }
662 avatarPoolp->renderAvatars(avatarp, TRUE); // renders only one avatar (no shaders)
663 }
664
665 return TRUE;
666}
667
668//-----------------------------------------------------------------------------
669// refresh()
670//-----------------------------------------------------------------------------
671void LLImagePreviewAvatar::refresh()
672{
673 mNeedsUpdate = TRUE;
674}
675
676//-----------------------------------------------------------------------------
677// rotate()
678//-----------------------------------------------------------------------------
679void LLImagePreviewAvatar::rotate(F32 yaw_radians, F32 pitch_radians)
680{
681 mCameraYaw = mCameraYaw + yaw_radians;
682
683 mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
684}
685
686//-----------------------------------------------------------------------------
687// zoom()
688//-----------------------------------------------------------------------------
689void LLImagePreviewAvatar::zoom(F32 zoom_amt)
690{
691 mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
692}
693
694void LLImagePreviewAvatar::pan(F32 right, F32 up)
695{
696 mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
697 mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
698}