diff options
author | Brad Kittenbrink <brad@lindenlab.com> | 2007-05-23 21:17:34 +0000 |
---|---|---|
committer | Brad Kittenbrink <brad@lindenlab.com> | 2007-05-23 21:17:34 +0000 |
commit | 029130bf9c76139fa836117987b60e801ac7ec7c (patch) | |
tree | ee320f7737ad3edc74a2401b5bd20a027b670487 /indra/newview | |
parent | 0aac2f674e4bd2fc73025ec8b649739cf7be3e4c (diff) |
svn merge svn+ssh://svn.lindenlab.com/svn/linden/release@62339 svn+ssh://svn.lindenlab.com/svn/linden/branches/release-candidate62341 -> release
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/English.lproj/InfoPlist.strings | 4 | ||||
-rw-r--r-- | indra/newview/Info-SecondLife.plist | 2 | ||||
-rw-r--r-- | indra/newview/app_settings/keywords.ini | 6 | ||||
-rw-r--r-- | indra/newview/llagent.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llface.cpp | 21 | ||||
-rw-r--r-- | indra/newview/llfloaterimagepreview.cpp | 215 | ||||
-rw-r--r-- | indra/newview/llfloaterimagepreview.h | 29 | ||||
-rw-r--r-- | indra/newview/llmanipscale.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llpanelobject.cpp | 199 | ||||
-rw-r--r-- | indra/newview/llpanelobject.h | 15 | ||||
-rw-r--r-- | indra/newview/llviewercamera.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 15 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 126 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 4 |
16 files changed, 616 insertions, 33 deletions
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 9142437ac5..8fae01fbdc 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,5 +1,5 @@ /* Localized versions of Info.plist keys */ CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 1.15.2.0"; -CFBundleGetInfoString = "Second Life version 1.15.2.0, Copyright 2004-2007 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 1.16.0.5"; +CFBundleGetInfoString = "Second Life version 1.16.0.5, Copyright 2004-2007 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index a0ee123a6a..764b1520f0 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@ </dict> </array> <key>CFBundleVersion</key> - <string>1.15.2.0</string> + <string>1.16.0.5</string> <key>CSResourcesFileMapped</key> <true/> </dict> diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index c2a2ce2755..c7f8426804 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -346,6 +346,7 @@ PRIM_TYPE_SPHERE Followed by integer hole shape, vector cut, float hollow, vecto PRIM_TYPE_TORUS Followed by integer hole shape, vector cut, float hollow, vector twist,:vector hole size, vector top shear, vector advanced cut, vector taper,:float revolutions, float radius offset, and float skew PRIM_TYPE_TUBE Followed by integer hole shape, vector cut, float hollow, vector twist,:vector hole size, vector top shear, vector advanced cut, vector taper,:float revolutions, float radius offset, and float skew PRIM_TYPE_RING Followed by integer hole shape, vector cut, float hollow, vector twist,:vector hole size, vector top shear, vector advanced cut, vector taper,:float revolutions, float radius offset, and float skew +PRIM_TYPE_SCULPT Followed by a key or string texture uuid. PRIM_HOLE_DEFAULT Sets hole type to match the prim type. PRIM_HOLE_SQUARE Sets hole type to square. @@ -388,6 +389,11 @@ PRIM_BUMP_WEAVE Weave bump map PRIM_TEXGEN_DEFAULT Default texture mapping PRIM_TEXGEN_PLANAR Planar texture mapping +PRIM_SCULPT_TYPE_SPHERE Stitch edges in a sphere-like way +PRIM_SCULPT_TYPE_TORUS Stitch edges in a torus-like way +PRIM_SCULPT_TYPE_PLANE Do not stitch edges +PRIM_SCULPT_TYPE_CYLINDER Stitch edges in a cylinder-like way + MASK_BASE Base permissions MASK_OWNER Owner permissions MASK_GROUP Group permissions diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 9fa5244c39..c6155197f6 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4917,6 +4917,8 @@ void LLAgent::sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimReque num_valid_anims++; } + msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList); + msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0); if (num_valid_anims) { sendReliableMessage(); @@ -4940,6 +4942,8 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request) msg->addUUIDFast(_PREHASH_AnimID, (anim_id) ); msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE); + msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList); + msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0); sendReliableMessage(); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b96ffa46fe..044ae33ccc 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -706,8 +706,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); - const LLVolumeFace &face = volume.getVolumeFace(f); - //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) { @@ -718,9 +716,18 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } LLVector3 min,max; - - min = face.mExtents[0]; - max = face.mExtents[1]; + + if (f >= volume.getNumVolumeFaces()) + { + min = LLVector3(-1,-1,-1); + max = LLVector3(1,1,1); + } + else + { + const LLVolumeFace &face = volume.getVolumeFace(f); + min = face.mExtents[0]; + max = face.mExtents[1]; + } //min, max are in volume space, convert to drawable render space LLVector3 center = ((min + max) * 0.5f)*mat_vert; @@ -884,6 +891,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, full_rebuild = TRUE; } } + else + { + full_rebuild = TRUE; + } } else { diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index f10abc4466..4f7ef34fe1 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -82,10 +82,14 @@ BOOL LLFloaterImagePreview::postBuild() { mAvatarPreview = new LLImagePreviewAvatar(256, 256); mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE); + + mSculptedPreview = new LLImagePreviewSculpted(256, 256); + mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f); } else { mAvatarPreview = NULL; + mSculptedPreview = NULL; childShow("bad_image_text"); childDisable("clothing_type_combo"); childDisable("ok_btn"); @@ -101,6 +105,8 @@ LLFloaterImagePreview::~LLFloaterImagePreview() { mRawImagep = NULL; delete mAvatarPreview; + delete mSculptedPreview; + if (mGLName) { glDeleteTextures(1, &mGLName ); @@ -115,7 +121,7 @@ void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata) { LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata; - if (!fp->mAvatarPreview) + if (!fp->mAvatarPreview || !fp->mSculptedPreview) { return; } @@ -156,10 +162,15 @@ void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata) case 8: fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE); break; + case 9: + fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f); + break; default: break; } + fp->mAvatarPreview->refresh(); + fp->mSculptedPreview->refresh(); } //----------------------------------------------------------------------------- @@ -173,7 +184,11 @@ void LLFloaterImagePreview::draw() if (mRawImagep.notNull()) { LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo"); - if (iface && iface->getFirstSelectedIndex() <= 0) + U32 selected = 0; + if (iface) + selected = iface->getFirstSelectedIndex(); + + if (selected <= 0) { gl_rect_2d_checkerboard(mPreviewRect); LLGLDisable gls_alpha(GL_ALPHA_TEST); @@ -210,6 +225,7 @@ void LLFloaterImagePreview::draw() if (mAvatarPreview) { mAvatarPreview->setTexture(mGLName); + mSculptedPreview->setTexture(mGLName); } } @@ -233,10 +249,14 @@ void LLFloaterImagePreview::draw() } else { - if (mAvatarPreview) + if ((mAvatarPreview) && (mSculptedPreview)) { glColor3f(1.f, 1.f, 1.f); - mAvatarPreview->bindTexture(); + + if (selected == 9) + mSculptedPreview->bindTexture(); + else + mAvatarPreview->bindTexture(); glBegin( GL_QUADS ); { @@ -251,12 +271,16 @@ void LLFloaterImagePreview::draw() } glEnd(); - mAvatarPreview->unbindTexture(); + if (selected == 9) + mSculptedPreview->unbindTexture(); + else + mAvatarPreview->unbindTexture(); } } } } + //----------------------------------------------------------------------------- // loadImage() //----------------------------------------------------------------------------- @@ -397,6 +421,7 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask) else { mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); + mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f); } } else if (local_mask == MASK_ORBIT) @@ -405,6 +430,7 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask) F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f; mAvatarPreview->rotate(yaw_radians, pitch_radians); + mSculptedPreview->rotate(yaw_radians, pitch_radians); } else { @@ -421,6 +447,8 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask) mAvatarPreview->rotate(yaw_radians, 0.f); mAvatarPreview->zoom(zoom_amt); + mSculptedPreview->rotate(yaw_radians, 0.f); + mSculptedPreview->zoom(zoom_amt); } } @@ -466,12 +494,13 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask) else { mAvatarPreview->refresh(); + mSculptedPreview->refresh(); } LLUI::setCursorPositionLocal(this, mLastMouseX, mLastMouseY); } - if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview) + if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview) { return LLFloater::handleHover(x, y, mask); } @@ -500,6 +529,9 @@ BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks) { mAvatarPreview->zoom((F32)clicks * -0.2f); mAvatarPreview->refresh(); + + mSculptedPreview->zoom((F32)clicks * -0.2f); + mSculptedPreview->refresh(); } return TRUE; @@ -540,6 +572,7 @@ LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTex mTextureName = 0; } + LLImagePreviewAvatar::~LLImagePreviewAvatar() { mDummyAvatar->markDead(); @@ -582,7 +615,7 @@ void LLImagePreviewAvatar::setPreviewTarget(const char* joint_name, const char* //----------------------------------------------------------------------------- // update() //----------------------------------------------------------------------------- -BOOL LLImagePreviewAvatar::render() +BOOL LLImagePreviewAvatar::render() { mNeedsUpdate = FALSE; LLVOAvatar* avatarp = mDummyAvatar; @@ -620,6 +653,7 @@ BOOL LLImagePreviewAvatar::render() stop_glerror(); + gCamera->setAspect((F32)mWidth / mHeight); gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom); gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); @@ -672,3 +706,170 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up) mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); } + + +//----------------------------------------------------------------------------- +// LLImagePreviewSculpted +//----------------------------------------------------------------------------- + +LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +{ + mNeedsUpdate = TRUE; + mCameraDistance = 0.f; + mCameraYaw = 0.f; + mCameraPitch = 0.f; + mCameraZoom = 1.f; + mTextureName = 0; + + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE); + mVolume = new LLVolume(volume_params, (F32) MAX_LOD); + + /* + mDummyAvatar = new LLVOAvatar(LLUUID::null, LL_PCODE_LEGACY_AVATAR, gAgent.getRegion()); + mDummyAvatar->createDrawable(&gPipeline); + mDummyAvatar->mIsDummy = TRUE; + mDummyAvatar->mSpecialRenderMode = 2; + mDummyAvatar->setPositionAgent(LLVector3::zero); + mDummyAvatar->slamPosition(); + mDummyAvatar->updateJointLODs(); + mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); + gPipeline.markVisible(mDummyAvatar->mDrawable, *gCamera); + mTextureName = 0; + */ +} + + +LLImagePreviewSculpted::~LLImagePreviewSculpted() +{ + /* + mDummyAvatar->markDead(); + */ +} + + +void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) +{ + mCameraDistance = distance; + mCameraZoom = 1.f; + mCameraPitch = 0.f; + mCameraYaw = 0.f; + mCameraOffset.clearVec(); + + if (imagep) + { + mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0); + } + +} + + +//----------------------------------------------------------------------------- +// render() +//----------------------------------------------------------------------------- +BOOL LLImagePreviewSculpted::render() +{ + mNeedsUpdate = FALSE; + + LLGLSUIDefault def; + LLGLDisable no_blend(GL_BLEND); + LLGLEnable cull(GL_CULL_FACE); + LLGLDepthTest depth(GL_TRUE); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glColor4f(0.15f, 0.2f, 0.3f, 1.f); + + gl_rect_2d_simple( mWidth, mHeight ); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + LLVector3 target_pos(0, 0, 0); + + LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * + LLQuaternion(mCameraYaw, LLVector3::z_axis); + + LLQuaternion av_rot = camera_rot; + gCamera->setOriginAndLookAt( + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos + (mCameraOffset * av_rot) ); // point of interest + + stop_glerror(); + + gCamera->setAspect((F32) mWidth / mHeight); + gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom); + gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE); + + gPipeline.enableLightsAvatar(0.0); + + + glPushMatrix(); + glScalef(0.5, 0.5, 0.5); + + glBegin(GL_TRIANGLES); + glColor3f(0.8f, 0.8f, 0.8f); + + const LLVolumeFace &vf = mVolume->getVolumeFace(0); + S32 num_indices = (S32)vf.mIndices.size(); + for (U32 i = 0; (S32)i < num_indices; i++) + { + LLVector3 normal = vf.mVertices[vf.mIndices[i]].mNormal; + normal.normVec(); + glNormal3f(normal.mV[VX], normal.mV[VY], normal.mV[VZ]); + + LLVector3 position = vf.mVertices[vf.mIndices[i]].mPosition; + glVertex3f(position.mV[VX], position.mV[VY], position.mV[VZ]); + } + + glEnd(); + + glPopMatrix(); + + return TRUE; +} + +//----------------------------------------------------------------------------- +// refresh() +//----------------------------------------------------------------------------- +void LLImagePreviewSculpted::refresh() +{ + mNeedsUpdate = TRUE; +} + +//----------------------------------------------------------------------------- +// rotate() +//----------------------------------------------------------------------------- +void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians) +{ + mCameraYaw = mCameraYaw + yaw_radians; + + mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); +} + +//----------------------------------------------------------------------------- +// zoom() +//----------------------------------------------------------------------------- +void LLImagePreviewSculpted::zoom(F32 zoom_amt) +{ + mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f); +} + +void LLImagePreviewSculpted::pan(F32 right, F32 up) +{ + mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f); + mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f); +} diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index 4978a6ea0b..af98466cf8 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -19,6 +19,34 @@ class LLViewerJointMesh; class LLVOAvatar; class LLTextBox; +class LLImagePreviewSculpted : public LLDynamicTexture +{ + public: + LLImagePreviewSculpted(S32 width, S32 height); + virtual ~LLImagePreviewSculpted(); + + void setPreviewTarget(LLImageRaw *imagep, F32 distance); + void setTexture(U32 name) { mTextureName = name; } + + BOOL render(); + void refresh(); + void rotate(F32 yaw_radians, F32 pitch_radians); + void zoom(F32 zoom_amt); + void pan(F32 right, F32 up); + virtual BOOL needsRender() { return mNeedsUpdate; } + + protected: + BOOL mNeedsUpdate; + U32 mTextureName; + F32 mCameraDistance; + F32 mCameraYaw; + F32 mCameraPitch; + F32 mCameraZoom; + LLVector3 mCameraOffset; + LLPointer<LLVolume> mVolume; +}; + + class LLImagePreviewAvatar : public LLDynamicTexture { public: @@ -71,6 +99,7 @@ protected: LLPointer<LLImageRaw> mRawImagep; LLImagePreviewAvatar* mAvatarPreview; + LLImagePreviewSculpted* mSculptedPreview; S32 mLastMouseX; S32 mLastMouseY; LLRect mPreviewRect; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 56a4352e22..14da426d9a 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -584,6 +584,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox ) if (mManipPart == LL_NO_PART) { glColor4fv( default_normal_color.mV ); + LLGLDepthTest gls_depth(GL_FALSE); glBegin(GL_QUADS); { // Face 0 @@ -746,7 +747,8 @@ void LLManipScale::renderCorners( const LLBBox& bbox ) void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z ) { LLGLDisable gls_tex(GL_TEXTURE_2D); - + LLGLDepthTest gls_depth(GL_FALSE); + glPushMatrix(); { glTranslatef( x, y, z ); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 314b7bed8f..dcfede70aa 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -33,6 +33,7 @@ #include "llresmgr.h" #include "llselectmgr.h" #include "llspinctrl.h" +#include "lltexturectrl.h" #include "lltextbox.h" #include "lltool.h" #include "lltoolcomp.h" @@ -60,6 +61,7 @@ enum { MI_TORUS, MI_TUBE, MI_RING, + MI_SCULPT, MI_NONE, MI_VOLUME_COUNT }; @@ -232,6 +234,34 @@ BOOL LLPanelObject::postBuild() childSetCommitCallback("Revolutions",onCommitParametric,this); mSpinRevolutions->setValidateBeforeCommit( &precommitValidate ); + // Sculpt + mCtrlSculptTexture = LLUICtrlFactory::getTexturePickerByName(this,"sculpt texture control"); + mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE)); + mCtrlSculptTexture->setCommitCallback( LLPanelObject::onCommitSculpt ); + mCtrlSculptTexture->setOnCancelCallback( LLPanelObject::onCancelSculpt ); + mCtrlSculptTexture->setOnSelectCallback( LLPanelObject::onSelectSculpt ); + mCtrlSculptTexture->setDropCallback(LLPanelObject::onDropSculpt); + mCtrlSculptTexture->setCallbackUserData( this ); + // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode + mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER); + // Allow any texture to be used during non-immediate mode. + mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE); + LLAggregatePermissions texture_perms; + if (gSelectMgr->selectGetAggregateTexturePermissions(texture_perms)) + { + BOOL can_copy = + texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY || + texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL; + BOOL can_transfer = + texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY || + texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL; + mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer); + } + else + { + mCtrlSculptTexture->setCanApplyImmediately(FALSE); + } + // Start with everyone disabled clearCtrls(); @@ -583,6 +613,14 @@ void LLPanelObject::getState( ) llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl; selected_item = MI_BOX; } + + + if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) + { + selected_item = MI_SCULPT; + } + + mComboBaseType ->setCurrentByIndex( selected_item ); mSelectedType = selected_item; @@ -740,6 +778,8 @@ void LLPanelObject::getState( ) // Compute control visibility, label names, and twist range. // Start with defaults. + BOOL cut_visible = TRUE; + BOOL hollow_visible = TRUE; BOOL top_size_x_visible = TRUE; BOOL top_size_y_visible = TRUE; BOOL top_shear_x_visible = TRUE; @@ -750,6 +790,7 @@ void LLPanelObject::getState( ) BOOL skew_visible = FALSE; BOOL radius_offset_visible = FALSE; BOOL revolutions_visible = FALSE; + BOOL sculpt_texture_visible = FALSE; F32 twist_min = OBJECT_TWIST_LINEAR_MIN; F32 twist_max = OBJECT_TWIST_LINEAR_MAX; F32 twist_inc = OBJECT_TWIST_LINEAR_INC; @@ -789,6 +830,23 @@ void LLPanelObject::getState( ) twist_inc = OBJECT_TWIST_INC; break; + + case MI_SCULPT: + cut_visible = FALSE; + hollow_visible = FALSE; + twist_visible = FALSE; + top_size_x_visible = FALSE; + top_size_y_visible = FALSE; + top_shear_x_visible = FALSE; + top_shear_y_visible = FALSE; + skew_visible = FALSE; + advanced_cut_visible = FALSE; + taper_visible = FALSE; + radius_offset_visible = FALSE; + revolutions_visible = FALSE; + sculpt_texture_visible = TRUE; + + break; case MI_BOX: case MI_CYLINDER: @@ -909,6 +967,15 @@ void LLPanelObject::getState( ) mSpinRevolutions ->setEnabled( enabled ); // Update field visibility + mLabelCut ->setVisible( cut_visible ); + mSpinCutBegin ->setVisible( cut_visible ); + mSpinCutEnd ->setVisible( cut_visible ); + + mLabelHollow ->setVisible( hollow_visible ); + mSpinHollow ->setVisible( hollow_visible ); + mLabelHoleType ->setVisible( hollow_visible ); + mComboHoleType ->setVisible( hollow_visible ); + mLabelTwist ->setVisible( twist_visible ); mSpinTwist ->setVisible( twist_visible ); mSpinTwistBegin ->setVisible( twist_visible ); @@ -942,6 +1009,30 @@ void LLPanelObject::getState( ) mLabelRevolutions->setVisible( revolutions_visible ); mSpinRevolutions ->setVisible( revolutions_visible ); + mCtrlSculptTexture->setVisible( sculpt_texture_visible ); + + + // sculpt texture + + if (selected_item == MI_SCULPT) + { + LLUUID id; + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + + LLTextureCtrl* mTextureCtrl = LLViewerUICtrlFactory::getTexturePickerByName(this,"sculpt texture control"); + if((mTextureCtrl) && (sculpt_params)) + { + mTextureCtrl->setTentative(FALSE); + mTextureCtrl->setEnabled(editable); + mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture()); + + if (mObject != objectp) // we've just selected a new object, so save for undo + mSculptTextureRevert = sculpt_params->getSculptTexture(); + } + + } + + //---------------------------------------------------------------------------- mObject = objectp; @@ -1063,9 +1154,26 @@ void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata ) LLVolumeParams volume_params; self->getVolumeParams(volume_params); + + + // set sculpting + S32 selected_type = self->mComboBaseType->getCurrentIndex(); + + if (selected_type == MI_SCULPT) + { + self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE); + } + else + { + LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if (sculpt_params) + self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE); + } + // Update the volume, if necessary. self->mObject->updateVolume(volume_params); + // This was added to make sure thate when changes are made, the UI // adjusts to present valid options. // *FIX: only some changes, ie, hollow or primitive type changes, @@ -1118,6 +1226,11 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params) path = LL_PCODE_PATH_CIRCLE; break; + case MI_SCULPT: + profile = LL_PCODE_PROFILE_CIRCLE; + path = LL_PCODE_PATH_CIRCLE; + break; + default: llwarns << "Unknown base type " << selected_type << " in getVolumeParams()" << llendl; @@ -1128,6 +1241,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params) break; } + if (path == LL_PCODE_PATH_LINE) { LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject); @@ -1338,6 +1452,23 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params) F32 shear_x = mSpinShearX->get(); F32 shear_y = mSpinShearY->get(); volume_params.setShear( shear_x, shear_y ); + + if (selected_type == MI_SCULPT) + { + volume_params.setSculptID(LLUUID::null, 0); + volume_params.setBeginAndEndT (0, 1); + volume_params.setBeginAndEndS (0, 1); + volume_params.setHollow (0); + volume_params.setTwistBegin (0); + volume_params.setTwistEnd (0); + volume_params.setRatio (1, 0.5); + volume_params.setShear (0, 0); + volume_params.setTaper (0, 0); + volume_params.setRevolutions (1); + volume_params.setRadiusOffset (0); + volume_params.setSkew (0); + } + } // BUG: Make work with multiple objects @@ -1482,6 +1613,18 @@ void LLPanelObject::sendPosition() } } +void LLPanelObject::sendSculpt() +{ + LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(this,"sculpt texture control"); + if(!mTextureCtrl) + return; + + LLSculptParams sculpt_params; + sculpt_params.setSculptTexture(mTextureCtrl->getImageAssetID()); + sculpt_params.setSculptType(LL_SCULPT_TYPE_SPHERE); + + mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); +} void LLPanelObject::refresh() { @@ -1677,3 +1820,59 @@ void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata ) LLPanelObject* self = (LLPanelObject*) userdata; self->sendCastShadows(); } + + +// static +void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata) +{ + LLPanelObject* self = (LLPanelObject*) userdata; + + LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control"); + + if (mTextureCtrl) + self->mSculptTextureRevert = mTextureCtrl->getImageAssetID(); + + self->sendSculpt(); +} + + +void LLPanelObject::onCommitSculpt( LLUICtrl* ctrl, void* userdata ) +{ + LLPanelObject* self = (LLPanelObject*) userdata; + + self->sendSculpt(); +} + +// static +BOOL LLPanelObject::onDropSculpt(LLUICtrl*, LLInventoryItem* item, void* userdata) +{ + LLPanelObject* self = (LLPanelObject*) userdata; + + LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control"); + + if (mTextureCtrl) + { + LLUUID asset = item->getAssetUUID(); + + mTextureCtrl->setImageAssetID(asset); + self->mSculptTextureRevert = asset; + } + + + return TRUE; +} + + +// static +void LLPanelObject::onCancelSculpt(LLUICtrl* ctrl, void* userdata) +{ + LLPanelObject* self = (LLPanelObject*) userdata; + + LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self,"sculpt texture control"); + if(!mTextureCtrl) + return; + + mTextureCtrl->setImageAssetID(self->mSculptTextureRevert); + + self->sendSculpt(); +} diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 07b65b6372..8c1bea0108 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -23,6 +23,9 @@ class LLViewerObject; class LLComboBox; class LLPanelInventory; class LLColorSwatchCtrl; +class LLTextureCtrl; +class LLInventoryItem; +class LLUUID; class LLPanelObject : public LLPanel { @@ -50,6 +53,11 @@ public: static void onCommitParametric(LLUICtrl* ctrl, void* userdata); static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); + + static void onCommitSculpt( LLUICtrl* ctrl, void* userdata); + static void onCancelSculpt( LLUICtrl* ctrl, void* userdata); + static void onSelectSculpt( LLUICtrl* ctrl, void* userdata); + static BOOL onDropSculpt(LLUICtrl* ctrl, LLInventoryItem* item, void* ud); protected: void getState(); @@ -61,7 +69,8 @@ protected: void sendIsTemporary(); void sendIsPhantom(); void sendCastShadows(); - + void sendSculpt(); + void getVolumeParams(LLVolumeParams& volume_params); protected: @@ -133,12 +142,16 @@ protected: LLCheckBoxCtrl *mCheckPhantom; LLCheckBoxCtrl *mCheckCastShadows; + LLTextureCtrl *mCtrlSculptTexture; + LLVector3 mCurEulerDegrees; // to avoid sending rotation when not changed BOOL mIsPhysical; // to avoid sending "physical" when not changed BOOL mIsTemporary; // to avoid sending "temporary" when not changed BOOL mIsPhantom; // to avoid sending "phantom" when not changed BOOL mCastShadows; // to avoid sending "cast shadows" when not changed S32 mSelectedType; // So we know what selected type we last were + + LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel LLPointer<LLViewerObject> mObject; LLPointer<LLViewerObject> mRootObject; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index a155a7aeec..da93aced1f 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -602,7 +602,7 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition())); - num_faces = volume->getNumFaces(); + num_faces = volume->getNumVolumeFaces(); for (i = 0; i < num_faces; i++) { const LLVolumeFace& face = volume->getVolumeFace(i); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d1a0b3724d..cc31aaef67 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -164,6 +164,7 @@ void LLViewerInventoryItem::updateServer(BOOL is_new) const msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID); msg->nextBlockFast(_PREHASH_InventoryData); msg->addU32Fast(_PREHASH_CallbackID, 0); packMessage(msg); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index bf4ad172e6..279dfe2923 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -1308,9 +1308,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, U32 value; dp->unpackU32(value, "SpecialCode"); - dp->setPassFlags(value); - + dp->unpackUUID(owner_id, "Owner"); if (value & 0x80) { @@ -1449,7 +1448,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if (value & 0x10) { dp->unpackUUID(sound_uuid, "SoundUUID"); - dp->unpackUUID(owner_id, "OwnerID"); dp->unpackF32(gain, "SoundGain"); dp->unpackU8(sound_flags, "SoundFlags"); dp->unpackF32(cutoff, "SoundRadius"); @@ -3996,9 +3994,9 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own } else { + LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num); //If the owner is muted, don't create the system if(gMuteListp->isMuted(owner_id)) return; - LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num); // We need to be able to deal with a particle source that hasn't changed, but still got an update! if (pss) @@ -4045,10 +4043,9 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_ } else { + LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp); //If the owner is muted, don't create the system if(gMuteListp->isMuted(owner_id)) return; - LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp); - // We need to be able to deal with a particle source that hasn't changed, but still got an update! if (pss) { @@ -4240,6 +4237,12 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para new_block = new LLLightParams(); break; } + case LLNetworkData::PARAMS_SCULPT: + { + new_block = new LLSculptParams(); + break; + } + default: { llinfos << "Unknown param type." << llendl; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b53480ec13..6f68f04d67 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -42,7 +42,7 @@ // Viewer object cache version, change if object update // format changes. JC -const U32 INDRA_OBJECT_CACHE_VERSION = 12; +const U32 INDRA_OBJECT_CACHE_VERSION = 14; extern BOOL gNoRender; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 1090bf4210..ec64cc23b3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -69,6 +69,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mGlobalVolume = FALSE; mVObjRadius = LLVector3(1,1,0.5f).magVec(); mNumFaces = 0; + mLODChanged = FALSE; + mSculptChanged = FALSE; } LLVOVolume::~LLVOVolume() @@ -96,6 +98,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // Do base class updates... U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); + LLUUID sculpt_id; + U8 sculpt_type = 0; + if (isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + sculpt_id = sculpt_params->getSculptTexture(); + sculpt_type = sculpt_params->getSculptType(); + } + if (!dp) { if (update_type == OUT_FULL) @@ -137,6 +148,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, // Unpack volume data LLVolumeParams volume_params; LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num); + volume_params.setSculptID(sculpt_id, sculpt_type); if (setVolume(volume_params, 0)) { @@ -166,7 +178,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, llwarns << "Bogus volume parameters in object " << getID() << llendl; llwarns << getRegion()->getOriginGlobal() << llendl; } - + + volume_params.setSculptID(sculpt_id, sculpt_type); + if (setVolume(volume_params, 0)) { markForUpdate(TRUE); @@ -442,6 +456,28 @@ void LLVOVolume::updateTextures() if (pri > max_vsize) max_vsize = pri; } } + + if (isSculpted()) + { + LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLUUID id = sculpt_params->getSculptTexture(); + mSculptTexture = gImageList.getImage(id); + if (mSculptTexture.notNull()) + { + mSculptTexture->addTextureStats(mPixelArea); + } + + S32 desired_discard = MAX_LOD - mLOD; + S32 current_discard = getVolume()->getSculptLevel(); + + if (desired_discard != current_discard) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); + mSculptChanged = TRUE; + } + + } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { @@ -604,22 +640,79 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail } } } + mGlobalVolume = (mVolumeImpl && mVolumeImpl->isVolumeGlobal()); - if (LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) + if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) { mFaceMappingChanged = TRUE; - + if (mVolumeImpl) { mVolumeImpl->onSetVolume(volume_params, detail); } + + if (isSculpted()) + { + mSculptTexture = gImageList.getImage(volume_params.getSculptID()); + if (mSculptTexture.notNull()) + { + sculpt(); + } + } + else + { + mSculptTexture = NULL; + } return TRUE; } return FALSE; } +// sculpt replaces generate() for sculpted surfaces +void LLVOVolume::sculpt() +{ + U16 sculpt_height = 0; + U16 sculpt_width = 0; + S8 sculpt_components = 0; + const U8* sculpt_data = NULL; + + if (mSculptTexture.notNull()) + { + S32 discard_level; + S32 desired_discard = MAX_LOD - mLOD; // desired + + discard_level = desired_discard; + + S32 max_discard = mSculptTexture->getMaxDiscardLevel(); + if (discard_level > max_discard) + discard_level = max_discard; // clamp to the best we can do + + S32 best_discard = mSculptTexture->getDiscardLevel(); + if (discard_level < best_discard) + discard_level = best_discard; // clamp to what we have + + if (best_discard == -1) + discard_level = -1; // and if we have nothing, set to nothing + + + S32 current_discard = getVolume()->getSculptLevel(); + if (current_discard == discard_level) // no work to do here + return; + + LLPointer<LLImageRaw> raw_image = new LLImageRaw(); + mSculptTexture->readBackRaw(discard_level, raw_image, TRUE); + + sculpt_height = raw_image->getHeight(); + sculpt_width = raw_image->getWidth(); + + sculpt_components = raw_image->getComponents(); + sculpt_data = raw_image->getData(); + getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); + } +} + S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius) { S32 cur_detail; @@ -958,7 +1051,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) genBBoxes(FALSE); } } - else if (mLODChanged) + else if ((mLODChanged) || (mSculptChanged)) { LLPointer<LLVolume> old_volumep, new_volumep; F32 old_lod, new_lod; @@ -974,7 +1067,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) new_volumep = getVolume(); new_lod = new_volumep->getDetail(); - if (new_lod != old_lod) + if ((new_lod != old_lod) || mSculptChanged) { compiled = TRUE; sNumLODChanges += getVolume()->getNumFaces(); @@ -1010,6 +1103,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) mVolumeChanged = FALSE; mLODChanged = FALSE; + mSculptChanged = FALSE; mFaceMappingChanged = FALSE; return TRUE; @@ -1017,9 +1111,16 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) void LLVOVolume::updateFaceSize(S32 idx) { - const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); LLFace* facep = mDrawable->getFace(idx); - facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); + if (idx >= getVolume()->getNumVolumeFaces()) + { + facep->setSize(0,0); + } + else + { + const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); + facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); + } } BOOL LLVOVolume::isRootEdit() const @@ -1449,7 +1550,6 @@ BOOL LLVOVolume::isFlexible() const { if (getVolume()->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) { - llwarns << "wtf" << llendl; LLVolumeParams volume_params = getVolume()->getParams(); U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE); @@ -1462,6 +1562,16 @@ BOOL LLVOVolume::isFlexible() const } } +BOOL LLVOVolume::isSculpted() const +{ + if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) + { + return TRUE; + } + + return FALSE; +} + BOOL LLVOVolume::isVolumeGlobal() const { if (mVolumeImpl) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 16a91bce8e..bde9058f4c 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -132,6 +132,7 @@ public: void setTexture(const S32 face); /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false); + void sculpt(); void updateRelativeXform(); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateFaceSize(S32 idx); @@ -177,6 +178,7 @@ public: // Flexible Objects U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; + virtual BOOL isSculpted() const; BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); @@ -203,12 +205,14 @@ protected: LLFrameTimer mTextureUpdateTimer; S32 mLOD; BOOL mLODChanged; + BOOL mSculptChanged; F32 mRadius; LLMatrix4 mRelativeXform; LLMatrix3 mRelativeXformInvTrans; BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; + LLPointer<LLViewerImage> mSculptTexture; // statics public: |