PageRenderTime 36ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llfloaterimagepreview.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 949 lines | 693 code | 148 blank | 108 comment | 80 complexity | b605ce28ace9f7662d03a85a3a4c10d2 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llfloaterimagepreview.cpp
  3. * @brief LLFloaterImagePreview class implementation
  4. *
  5. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llfloaterimagepreview.h"
  28. #include "llimagebmp.h"
  29. #include "llimagetga.h"
  30. #include "llimagejpeg.h"
  31. #include "llimagepng.h"
  32. #include "llagent.h"
  33. #include "llbutton.h"
  34. #include "llcombobox.h"
  35. #include "lldrawable.h"
  36. #include "lldrawpoolavatar.h"
  37. #include "llrender.h"
  38. #include "llface.h"
  39. #include "llfocusmgr.h"
  40. #include "lltextbox.h"
  41. #include "lltoolmgr.h"
  42. #include "llui.h"
  43. #include "llviewercamera.h"
  44. #include "llviewerwindow.h"
  45. #include "llviewerobjectlist.h"
  46. #include "llvoavatar.h"
  47. #include "pipeline.h"
  48. #include "lluictrlfactory.h"
  49. #include "llviewershadermgr.h"
  50. #include "llviewertexturelist.h"
  51. #include "llstring.h"
  52. #include "llendianswizzle.h"
  53. #include "llviewercontrol.h"
  54. #include "lltrans.h"
  55. #include "llimagedimensionsinfo.h"
  56. const S32 PREVIEW_BORDER_WIDTH = 2;
  57. const S32 PREVIEW_RESIZE_HANDLE_SIZE = S32(RESIZE_HANDLE_WIDTH * OO_SQRT2) + PREVIEW_BORDER_WIDTH;
  58. const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE;
  59. const S32 PREVIEW_VPAD = -24; // yuk, hard coded
  60. const S32 PREF_BUTTON_HEIGHT = 16 + 7 + 16;
  61. const S32 PREVIEW_TEXTURE_HEIGHT = 320;
  62. //-----------------------------------------------------------------------------
  63. // LLFloaterImagePreview()
  64. //-----------------------------------------------------------------------------
  65. LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) :
  66. LLFloaterNameDesc(filename),
  67. mAvatarPreview(NULL),
  68. mSculptedPreview(NULL),
  69. mLastMouseX(0),
  70. mLastMouseY(0),
  71. mImagep(NULL)
  72. {
  73. loadImage(mFilenameAndPath);
  74. }
  75. //-----------------------------------------------------------------------------
  76. // postBuild()
  77. //-----------------------------------------------------------------------------
  78. BOOL LLFloaterImagePreview::postBuild()
  79. {
  80. if (!LLFloaterNameDesc::postBuild())
  81. {
  82. return FALSE;
  83. }
  84. LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
  85. if (iface)
  86. {
  87. iface->selectFirstItem();
  88. }
  89. childSetCommitCallback("clothing_type_combo", onPreviewTypeCommit, this);
  90. mPreviewRect.set(PREVIEW_HPAD,
  91. PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD,
  92. getRect().getWidth() - PREVIEW_HPAD,
  93. PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
  94. mPreviewImageRect.set(0.f, 1.f, 1.f, 0.f);
  95. getChildView("bad_image_text")->setVisible(FALSE);
  96. if (mRawImagep.notNull() && gAgent.getRegion() != NULL)
  97. {
  98. mAvatarPreview = new LLImagePreviewAvatar(256, 256);
  99. mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE);
  100. mSculptedPreview = new LLImagePreviewSculpted(256, 256);
  101. mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f);
  102. if (mRawImagep->getWidth() * mRawImagep->getHeight () <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)
  103. getChildView("lossless_check")->setEnabled(TRUE);
  104. }
  105. else
  106. {
  107. mAvatarPreview = NULL;
  108. mSculptedPreview = NULL;
  109. getChildView("bad_image_text")->setVisible(TRUE);
  110. getChildView("clothing_type_combo")->setEnabled(FALSE);
  111. getChildView("ok_btn")->setEnabled(FALSE);
  112. if(!mImageLoadError.empty())
  113. {
  114. getChild<LLUICtrl>("bad_image_text")->setValue(mImageLoadError.c_str());
  115. }
  116. }
  117. getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
  118. return TRUE;
  119. }
  120. //-----------------------------------------------------------------------------
  121. // LLFloaterImagePreview()
  122. //-----------------------------------------------------------------------------
  123. LLFloaterImagePreview::~LLFloaterImagePreview()
  124. {
  125. clearAllPreviewTextures();
  126. mRawImagep = NULL;
  127. mImagep = NULL ;
  128. }
  129. //static
  130. //-----------------------------------------------------------------------------
  131. // onPreviewTypeCommit()
  132. //-----------------------------------------------------------------------------
  133. void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata)
  134. {
  135. LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata;
  136. if (!fp->mAvatarPreview || !fp->mSculptedPreview)
  137. {
  138. return;
  139. }
  140. S32 which_mode = 0;
  141. LLCtrlSelectionInterface* iface = fp->childGetSelectionInterface("clothing_type_combo");
  142. if (iface)
  143. {
  144. which_mode = iface->getFirstSelectedIndex();
  145. }
  146. switch(which_mode)
  147. {
  148. case 0:
  149. break;
  150. case 1:
  151. fp->mAvatarPreview->setPreviewTarget("mSkull", "mHairMesh0", fp->mRawImagep, 0.4f, FALSE);
  152. break;
  153. case 2:
  154. fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, FALSE);
  155. break;
  156. case 3:
  157. fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.0f, FALSE);
  158. break;
  159. case 4:
  160. fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, FALSE);
  161. break;
  162. case 5:
  163. fp->mAvatarPreview->setPreviewTarget("mSkull", "mHeadMesh0", fp->mRawImagep, 0.4f, TRUE);
  164. break;
  165. case 6:
  166. fp->mAvatarPreview->setPreviewTarget("mChest", "mUpperBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
  167. break;
  168. case 7:
  169. fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mLowerBodyMesh0", fp->mRawImagep, 1.2f, TRUE);
  170. break;
  171. case 8:
  172. fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE);
  173. break;
  174. case 9:
  175. fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f);
  176. break;
  177. default:
  178. break;
  179. }
  180. fp->mAvatarPreview->refresh();
  181. fp->mSculptedPreview->refresh();
  182. }
  183. //-----------------------------------------------------------------------------
  184. // clearAllPreviewTextures()
  185. //-----------------------------------------------------------------------------
  186. void LLFloaterImagePreview::clearAllPreviewTextures()
  187. {
  188. if (mAvatarPreview)
  189. {
  190. mAvatarPreview->clearPreviewTexture("mHairMesh0");
  191. mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0");
  192. mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0");
  193. mAvatarPreview->clearPreviewTexture("mHeadMesh0");
  194. mAvatarPreview->clearPreviewTexture("mUpperBodyMesh0");
  195. mAvatarPreview->clearPreviewTexture("mLowerBodyMesh0");
  196. mAvatarPreview->clearPreviewTexture("mSkirtMesh0");
  197. }
  198. }
  199. //-----------------------------------------------------------------------------
  200. // draw()
  201. //-----------------------------------------------------------------------------
  202. void LLFloaterImagePreview::draw()
  203. {
  204. LLFloater::draw();
  205. LLRect r = getRect();
  206. if (mRawImagep.notNull())
  207. {
  208. LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
  209. U32 selected = 0;
  210. if (iface)
  211. selected = iface->getFirstSelectedIndex();
  212. if (selected <= 0)
  213. {
  214. gl_rect_2d_checkerboard(mPreviewRect);
  215. LLGLDisable gls_alpha(GL_ALPHA_TEST);
  216. if(mImagep.notNull())
  217. {
  218. gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
  219. }
  220. else
  221. {
  222. mImagep = LLViewerTextureManager::getLocalTexture(mRawImagep.get(), FALSE) ;
  223. gGL.getTexUnit(0)->unbind(mImagep->getTarget()) ;
  224. gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mImagep->getTexName());
  225. stop_glerror();
  226. gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
  227. gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
  228. if (mAvatarPreview)
  229. {
  230. mAvatarPreview->setTexture(mImagep->getTexName());
  231. mSculptedPreview->setTexture(mImagep->getTexName());
  232. }
  233. }
  234. gGL.color3f(1.f, 1.f, 1.f);
  235. gGL.begin( LLRender::QUADS );
  236. {
  237. gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop);
  238. gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
  239. gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom);
  240. gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
  241. gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom);
  242. gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
  243. gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop);
  244. gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
  245. }
  246. gGL.end();
  247. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  248. stop_glerror();
  249. }
  250. else
  251. {
  252. if ((mAvatarPreview) && (mSculptedPreview))
  253. {
  254. gGL.color3f(1.f, 1.f, 1.f);
  255. if (selected == 9)
  256. {
  257. gGL.getTexUnit(0)->bind(mSculptedPreview);
  258. }
  259. else
  260. {
  261. gGL.getTexUnit(0)->bind(mAvatarPreview);
  262. }
  263. gGL.begin( LLRender::QUADS );
  264. {
  265. gGL.texCoord2f(0.f, 1.f);
  266. gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
  267. gGL.texCoord2f(0.f, 0.f);
  268. gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
  269. gGL.texCoord2f(1.f, 0.f);
  270. gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD);
  271. gGL.texCoord2f(1.f, 1.f);
  272. gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD);
  273. }
  274. gGL.end();
  275. gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
  276. }
  277. }
  278. }
  279. }
  280. //-----------------------------------------------------------------------------
  281. // loadImage()
  282. //-----------------------------------------------------------------------------
  283. bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
  284. {
  285. std::string exten = gDirUtilp->getExtension(src_filename);
  286. U32 codec = LLImageBase::getCodecFromExtension(exten);
  287. LLImageDimensionsInfo image_info;
  288. if (!image_info.load(src_filename,codec))
  289. {
  290. mImageLoadError = image_info.getLastError();
  291. return false;
  292. }
  293. S32 max_width = gSavedSettings.getS32("max_texture_dimension_X");
  294. S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y");
  295. if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
  296. {
  297. LLStringUtil::format_map_t args;
  298. args["WIDTH"] = llformat("%d", max_width);
  299. args["HEIGHT"] = llformat("%d", max_height);
  300. mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
  301. return false;
  302. }
  303. // Load the image
  304. LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
  305. if (image.isNull())
  306. {
  307. return false;
  308. }
  309. if (!image->load(src_filename))
  310. {
  311. return false;
  312. }
  313. // Decompress or expand it in a raw image structure
  314. LLPointer<LLImageRaw> raw_image = new LLImageRaw;
  315. if (!image->decode(raw_image, 0.0f))
  316. {
  317. return false;
  318. }
  319. // Check the image constraints
  320. if ((image->getComponents() != 3) && (image->getComponents() != 4))
  321. {
  322. image->setLastError("Image files with less than 3 or more than 4 components are not supported.");
  323. return false;
  324. }
  325. raw_image->biasedScaleToPowerOfTwo(1024);
  326. mRawImagep = raw_image;
  327. return true;
  328. }
  329. //-----------------------------------------------------------------------------
  330. // handleMouseDown()
  331. //-----------------------------------------------------------------------------
  332. BOOL LLFloaterImagePreview::handleMouseDown(S32 x, S32 y, MASK mask)
  333. {
  334. if (mPreviewRect.pointInRect(x, y))
  335. {
  336. bringToFront( x, y );
  337. gFocusMgr.setMouseCapture(this);
  338. gViewerWindow->hideCursor();
  339. mLastMouseX = x;
  340. mLastMouseY = y;
  341. return TRUE;
  342. }
  343. return LLFloater::handleMouseDown(x, y, mask);
  344. }
  345. //-----------------------------------------------------------------------------
  346. // handleMouseUp()
  347. //-----------------------------------------------------------------------------
  348. BOOL LLFloaterImagePreview::handleMouseUp(S32 x, S32 y, MASK mask)
  349. {
  350. gFocusMgr.setMouseCapture(FALSE);
  351. gViewerWindow->showCursor();
  352. return LLFloater::handleMouseUp(x, y, mask);
  353. }
  354. //-----------------------------------------------------------------------------
  355. // handleHover()
  356. //-----------------------------------------------------------------------------
  357. BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
  358. {
  359. MASK local_mask = mask & ~MASK_ALT;
  360. if (mAvatarPreview && hasMouseCapture())
  361. {
  362. if (local_mask == MASK_PAN)
  363. {
  364. // pan here
  365. LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
  366. if (iface && iface->getFirstSelectedIndex() <= 0)
  367. {
  368. mPreviewImageRect.translate((F32)(x - mLastMouseX) * -0.005f * mPreviewImageRect.getWidth(),
  369. (F32)(y - mLastMouseY) * -0.005f * mPreviewImageRect.getHeight());
  370. }
  371. else
  372. {
  373. mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
  374. mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
  375. }
  376. }
  377. else if (local_mask == MASK_ORBIT)
  378. {
  379. F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
  380. F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
  381. mAvatarPreview->rotate(yaw_radians, pitch_radians);
  382. mSculptedPreview->rotate(yaw_radians, pitch_radians);
  383. }
  384. else
  385. {
  386. LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
  387. if (iface && iface->getFirstSelectedIndex() <= 0)
  388. {
  389. F32 zoom_amt = (F32)(y - mLastMouseY) * -0.002f;
  390. mPreviewImageRect.stretch(zoom_amt);
  391. }
  392. else
  393. {
  394. F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f;
  395. F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f;
  396. mAvatarPreview->rotate(yaw_radians, 0.f);
  397. mAvatarPreview->zoom(zoom_amt);
  398. mSculptedPreview->rotate(yaw_radians, 0.f);
  399. mSculptedPreview->zoom(zoom_amt);
  400. }
  401. }
  402. LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
  403. if (iface && iface->getFirstSelectedIndex() <= 0)
  404. {
  405. if (mPreviewImageRect.getWidth() > 1.f)
  406. {
  407. mPreviewImageRect.stretch((1.f - mPreviewImageRect.getWidth()) * 0.5f);
  408. }
  409. else if (mPreviewImageRect.getWidth() < 0.1f)
  410. {
  411. mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getWidth()) * 0.5f);
  412. }
  413. if (mPreviewImageRect.getHeight() > 1.f)
  414. {
  415. mPreviewImageRect.stretch((1.f - mPreviewImageRect.getHeight()) * 0.5f);
  416. }
  417. else if (mPreviewImageRect.getHeight() < 0.1f)
  418. {
  419. mPreviewImageRect.stretch((0.1f - mPreviewImageRect.getHeight()) * 0.5f);
  420. }
  421. if (mPreviewImageRect.mLeft < 0.f)
  422. {
  423. mPreviewImageRect.translate(-mPreviewImageRect.mLeft, 0.f);
  424. }
  425. else if (mPreviewImageRect.mRight > 1.f)
  426. {
  427. mPreviewImageRect.translate(1.f - mPreviewImageRect.mRight, 0.f);
  428. }
  429. if (mPreviewImageRect.mBottom < 0.f)
  430. {
  431. mPreviewImageRect.translate(0.f, -mPreviewImageRect.mBottom);
  432. }
  433. else if (mPreviewImageRect.mTop > 1.f)
  434. {
  435. mPreviewImageRect.translate(0.f, 1.f - mPreviewImageRect.mTop);
  436. }
  437. }
  438. else
  439. {
  440. mAvatarPreview->refresh();
  441. mSculptedPreview->refresh();
  442. }
  443. LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY);
  444. }
  445. if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview)
  446. {
  447. return LLFloater::handleHover(x, y, mask);
  448. }
  449. else if (local_mask == MASK_ORBIT)
  450. {
  451. gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA);
  452. }
  453. else if (local_mask == MASK_PAN)
  454. {
  455. gViewerWindow->setCursor(UI_CURSOR_TOOLPAN);
  456. }
  457. else
  458. {
  459. gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN);
  460. }
  461. return TRUE;
  462. }
  463. //-----------------------------------------------------------------------------
  464. // handleScrollWheel()
  465. //-----------------------------------------------------------------------------
  466. BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
  467. {
  468. if (mPreviewRect.pointInRect(x, y) && mAvatarPreview)
  469. {
  470. mAvatarPreview->zoom((F32)clicks * -0.2f);
  471. mAvatarPreview->refresh();
  472. mSculptedPreview->zoom((F32)clicks * -0.2f);
  473. mSculptedPreview->refresh();
  474. }
  475. return TRUE;
  476. }
  477. //-----------------------------------------------------------------------------
  478. // onMouseCaptureLost()
  479. //-----------------------------------------------------------------------------
  480. // static
  481. void LLFloaterImagePreview::onMouseCaptureLostImagePreview(LLMouseHandler* handler)
  482. {
  483. gViewerWindow->showCursor();
  484. }
  485. //-----------------------------------------------------------------------------
  486. // LLImagePreviewAvatar
  487. //-----------------------------------------------------------------------------
  488. LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
  489. {
  490. mNeedsUpdate = TRUE;
  491. mTargetJoint = NULL;
  492. mTargetMesh = NULL;
  493. mCameraDistance = 0.f;
  494. mCameraYaw = 0.f;
  495. mCameraPitch = 0.f;
  496. mCameraZoom = 1.f;
  497. mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion());
  498. mDummyAvatar->createDrawable(&gPipeline);
  499. mDummyAvatar->mIsDummy = TRUE;
  500. mDummyAvatar->mSpecialRenderMode = 2;
  501. mDummyAvatar->setPositionAgent(LLVector3::zero);
  502. mDummyAvatar->slamPosition();
  503. mDummyAvatar->updateJointLODs();
  504. mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
  505. // gPipeline.markVisible(mDummyAvatar->mDrawable, *LLViewerCamera::getInstance());
  506. mTextureName = 0;
  507. }
  508. LLImagePreviewAvatar::~LLImagePreviewAvatar()
  509. {
  510. mDummyAvatar->markDead();
  511. }
  512. //virtual
  513. S8 LLImagePreviewAvatar::getType() const
  514. {
  515. return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_AVATAR ;
  516. }
  517. void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male)
  518. {
  519. mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name);
  520. // clear out existing test mesh
  521. if (mTargetMesh)
  522. {
  523. mTargetMesh->setTestTexture(0);
  524. }
  525. if (male)
  526. {
  527. mDummyAvatar->setVisualParamWeight( "male", 1.f );
  528. mDummyAvatar->updateVisualParams();
  529. mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
  530. }
  531. else
  532. {
  533. mDummyAvatar->setVisualParamWeight( "male", 0.f );
  534. mDummyAvatar->updateVisualParams();
  535. mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
  536. }
  537. mDummyAvatar->mRoot.setVisible(FALSE, TRUE);
  538. mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
  539. mTargetMesh->setTestTexture(mTextureName);
  540. mTargetMesh->setVisible(TRUE, FALSE);
  541. mCameraDistance = distance;
  542. mCameraZoom = 1.f;
  543. mCameraPitch = 0.f;
  544. mCameraYaw = 0.f;
  545. mCameraOffset.clearVec();
  546. }
  547. //-----------------------------------------------------------------------------
  548. // clearPreviewTexture()
  549. //-----------------------------------------------------------------------------
  550. void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)
  551. {
  552. if (mDummyAvatar)
  553. {
  554. LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
  555. // clear out existing test mesh
  556. if (mesh)
  557. {
  558. mesh->setTestTexture(0);
  559. }
  560. }
  561. }
  562. //-----------------------------------------------------------------------------
  563. // update()
  564. //-----------------------------------------------------------------------------
  565. BOOL LLImagePreviewAvatar::render()
  566. {
  567. mNeedsUpdate = FALSE;
  568. LLVOAvatar* avatarp = mDummyAvatar;
  569. gGL.pushUIMatrix();
  570. gGL.loadUIIdentity();
  571. gGL.matrixMode(LLRender::MM_PROJECTION);
  572. gGL.pushMatrix();
  573. gGL.loadIdentity();
  574. gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
  575. gGL.matrixMode(LLRender::MM_MODELVIEW);
  576. gGL.pushMatrix();
  577. gGL.loadIdentity();
  578. LLGLSUIDefault def;
  579. gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
  580. if (LLGLSLShader::sNoFixedFunction)
  581. {
  582. gUIProgram.bind();
  583. }
  584. gl_rect_2d_simple( mFullWidth, mFullHeight );
  585. gGL.matrixMode(LLRender::MM_PROJECTION);
  586. gGL.popMatrix();
  587. gGL.matrixMode(LLRender::MM_MODELVIEW);
  588. gGL.popMatrix();
  589. gGL.flush();
  590. LLVector3 target_pos = mTargetJoint->getWorldPosition();
  591. LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
  592. LLQuaternion(mCameraYaw, LLVector3::z_axis);
  593. LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot;
  594. LLViewerCamera::getInstance()->setOriginAndLookAt(
  595. target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
  596. LLVector3::z_axis, // up
  597. target_pos + (mCameraOffset * av_rot) ); // point of interest
  598. stop_glerror();
  599. LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / mFullHeight);
  600. LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
  601. LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
  602. LLVertexBuffer::unbind();
  603. avatarp->updateLOD();
  604. if (avatarp->mDrawable.notNull())
  605. {
  606. LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
  607. // make sure alpha=0 shows avatar material color
  608. LLGLDisable no_blend(GL_BLEND);
  609. LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
  610. gPipeline.enableLightsPreview();
  611. avatarPoolp->renderAvatars(avatarp); // renders only one avatar
  612. }
  613. gGL.popUIMatrix();
  614. gGL.color4f(1,1,1,1);
  615. return TRUE;
  616. }
  617. //-----------------------------------------------------------------------------
  618. // refresh()
  619. //-----------------------------------------------------------------------------
  620. void LLImagePreviewAvatar::refresh()
  621. {
  622. mNeedsUpdate = TRUE;
  623. }
  624. //-----------------------------------------------------------------------------
  625. // rotate()
  626. //-----------------------------------------------------------------------------
  627. void LLImagePreviewAvatar::rotate(F32 yaw_radians, F32 pitch_radians)
  628. {
  629. mCameraYaw = mCameraYaw + yaw_radians;
  630. mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
  631. }
  632. //-----------------------------------------------------------------------------
  633. // zoom()
  634. //-----------------------------------------------------------------------------
  635. void LLImagePreviewAvatar::zoom(F32 zoom_amt)
  636. {
  637. mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
  638. }
  639. void LLImagePreviewAvatar::pan(F32 right, F32 up)
  640. {
  641. mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
  642. mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
  643. }
  644. //-----------------------------------------------------------------------------
  645. // LLImagePreviewSculpted
  646. //-----------------------------------------------------------------------------
  647. LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
  648. {
  649. mNeedsUpdate = TRUE;
  650. mCameraDistance = 0.f;
  651. mCameraYaw = 0.f;
  652. mCameraPitch = 0.f;
  653. mCameraZoom = 1.f;
  654. mTextureName = 0;
  655. LLVolumeParams volume_params;
  656. volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE);
  657. volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_SPHERE);
  658. F32 const HIGHEST_LOD = 4.0f;
  659. mVolume = new LLVolume(volume_params, HIGHEST_LOD);
  660. }
  661. LLImagePreviewSculpted::~LLImagePreviewSculpted()
  662. {
  663. }
  664. //virtual
  665. S8 LLImagePreviewSculpted::getType() const
  666. {
  667. return LLViewerDynamicTexture::LL_IMAGE_PREVIEW_SCULPTED ;
  668. }
  669. void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
  670. {
  671. mCameraDistance = distance;
  672. mCameraZoom = 1.f;
  673. mCameraPitch = 0.f;
  674. mCameraYaw = 0.f;
  675. mCameraOffset.clearVec();
  676. if (imagep)
  677. {
  678. mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0);
  679. }
  680. const LLVolumeFace &vf = mVolume->getVolumeFace(0);
  681. U32 num_indices = vf.mNumIndices;
  682. U32 num_vertices = vf.mNumVertices;
  683. mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0, 0);
  684. mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
  685. LLStrider<LLVector3> vertex_strider;
  686. LLStrider<LLVector3> normal_strider;
  687. LLStrider<LLVector2> tc_strider;
  688. LLStrider<U16> index_strider;
  689. mVertexBuffer->getVertexStrider(vertex_strider);
  690. mVertexBuffer->getNormalStrider(normal_strider);
  691. mVertexBuffer->getTexCoord0Strider(tc_strider);
  692. mVertexBuffer->getIndexStrider(index_strider);
  693. // build vertices and normals
  694. LLStrider<LLVector3> pos;
  695. pos = (LLVector3*) vf.mPositions; pos.setStride(16);
  696. LLStrider<LLVector3> norm;
  697. norm = (LLVector3*) vf.mNormals; norm.setStride(16);
  698. LLStrider<LLVector2> tc;
  699. tc = (LLVector2*) vf.mTexCoords; tc.setStride(8);
  700. for (U32 i = 0; i < num_vertices; i++)
  701. {
  702. *(vertex_strider++) = *pos++;
  703. LLVector3 normal = *norm++;
  704. normal.normalize();
  705. *(normal_strider++) = normal;
  706. *(tc_strider++) = *tc++;
  707. }
  708. // build indices
  709. for (U16 i = 0; i < num_indices; i++)
  710. {
  711. *(index_strider++) = vf.mIndices[i];
  712. }
  713. }
  714. //-----------------------------------------------------------------------------
  715. // render()
  716. //-----------------------------------------------------------------------------
  717. BOOL LLImagePreviewSculpted::render()
  718. {
  719. mNeedsUpdate = FALSE;
  720. LLGLSUIDefault def;
  721. LLGLDisable no_blend(GL_BLEND);
  722. LLGLEnable cull(GL_CULL_FACE);
  723. LLGLDepthTest depth(GL_TRUE);
  724. gGL.matrixMode(LLRender::MM_PROJECTION);
  725. gGL.pushMatrix();
  726. gGL.loadIdentity();
  727. gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
  728. gGL.matrixMode(LLRender::MM_MODELVIEW);
  729. gGL.pushMatrix();
  730. gGL.loadIdentity();
  731. gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);
  732. if (LLGLSLShader::sNoFixedFunction)
  733. {
  734. gUIProgram.bind();
  735. }
  736. gl_rect_2d_simple( mFullWidth, mFullHeight );
  737. gGL.matrixMode(LLRender::MM_PROJECTION);
  738. gGL.popMatrix();
  739. gGL.matrixMode(LLRender::MM_MODELVIEW);
  740. gGL.popMatrix();
  741. glClear(GL_DEPTH_BUFFER_BIT);
  742. LLVector3 target_pos(0, 0, 0);
  743. LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
  744. LLQuaternion(mCameraYaw, LLVector3::z_axis);
  745. LLQuaternion av_rot = camera_rot;
  746. LLViewerCamera::getInstance()->setOriginAndLookAt(
  747. target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
  748. LLVector3::z_axis, // up
  749. target_pos + (mCameraOffset * av_rot) ); // point of interest
  750. stop_glerror();
  751. LLViewerCamera::getInstance()->setAspect((F32) mFullWidth / mFullHeight);
  752. LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
  753. LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
  754. const LLVolumeFace &vf = mVolume->getVolumeFace(0);
  755. U32 num_indices = vf.mNumIndices;
  756. gPipeline.enableLightsAvatar();
  757. if (LLGLSLShader::sNoFixedFunction)
  758. {
  759. gObjectPreviewProgram.bind();
  760. }
  761. gGL.pushMatrix();
  762. const F32 SCALE = 1.25f;
  763. gGL.scalef(SCALE, SCALE, SCALE);
  764. const F32 BRIGHTNESS = 0.9f;
  765. gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
  766. mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
  767. mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
  768. gGL.popMatrix();
  769. if (LLGLSLShader::sNoFixedFunction)
  770. {
  771. gObjectPreviewProgram.unbind();
  772. }
  773. return TRUE;
  774. }
  775. //-----------------------------------------------------------------------------
  776. // refresh()
  777. //-----------------------------------------------------------------------------
  778. void LLImagePreviewSculpted::refresh()
  779. {
  780. mNeedsUpdate = TRUE;
  781. }
  782. //-----------------------------------------------------------------------------
  783. // rotate()
  784. //-----------------------------------------------------------------------------
  785. void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians)
  786. {
  787. mCameraYaw = mCameraYaw + yaw_radians;
  788. mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
  789. }
  790. //-----------------------------------------------------------------------------
  791. // zoom()
  792. //-----------------------------------------------------------------------------
  793. void LLImagePreviewSculpted::zoom(F32 zoom_amt)
  794. {
  795. mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
  796. }
  797. void LLImagePreviewSculpted::pan(F32 right, F32 up)
  798. {
  799. mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
  800. mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
  801. }