diff options
author | Dave Parks <davep@lindenlab.com> | 2010-09-20 18:45:56 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2010-09-20 18:45:56 -0500 |
commit | c42ed54b0a532cb4e0ad30a1b0b5038cef9938f2 (patch) | |
tree | 39eb08c897f9e59fe448a1f63b354f83b7309f0b /indra | |
parent | 2c4c1c47bce3db7420f0eb27bdaa7598fbbbb65a (diff) |
Stop using ll_aligned_malloc/free in llvolume.
Fix for garbage data in vertex weight array crashing software skinning.
Proper integration of picking for rigged attachhments.
Optimization in LLDrawable::updateDistance (don't call updateRelativeXform, just use spatial group position).
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llmath/llvolume.cpp | 108 | ||||
-rw-r--r-- | indra/llmath/llvolume.h | 2 | ||||
-rw-r--r-- | indra/newview/lldrawable.cpp | 12 | ||||
-rw-r--r-- | indra/newview/lldrawpoolavatar.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llface.cpp | 32 | ||||
-rw-r--r-- | indra/newview/llselectmgr.cpp | 50 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 16 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 114 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 12 |
9 files changed, 247 insertions, 109 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 07339f7526..24528a8ce9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1990,7 +1990,7 @@ void LLVolumeFace::VertexData::init() { if (!mData) { - mData = (LLVector4a*) ll_aligned_malloc_16(32); + mData = new LLVector4a[2]; } } @@ -2019,7 +2019,7 @@ const LLVolumeFace::VertexData& LLVolumeFace::VertexData::operator=(const LLVolu LLVolumeFace::VertexData::~VertexData() { - ll_aligned_free_16(mData); + delete [] mData; } LLVector4a& LLVolumeFace::VertexData::getPosition() @@ -2257,12 +2257,12 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) U32 cur_influence = 0; LLVector4 wght(0,0,0,0); - while (joint != END_INFLUENCES) + while (joint != END_INFLUENCES && idx < weights.size()) { U16 influence = weights[idx++]; influence |= ((U16) weights[idx++] << 8); - F32 w = llmin((F32) influence / 65535.f, 0.99999f); + F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f); wght.mV[cur_influence++] = (F32) joint + w; if (cur_influence >= 4) @@ -5230,7 +5230,7 @@ LLVolumeFace::LLVolumeFace() : mWeights(NULL), mOctree(NULL) { - mExtents = (LLVector4a*) ll_aligned_malloc_16(48); + mExtents = new LLVector4a[3]; mCenter = mExtents+2; } @@ -5251,7 +5251,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mWeights(NULL), mOctree(NULL) { - mExtents = (LLVector4a*) ll_aligned_malloc_16(48); + mExtents = new LLVector4a[3]; mCenter = mExtents+2; *this = src; } @@ -5286,7 +5286,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) if (mNumVertices) { - S32 vert_size = mNumVertices*4*sizeof(F32); + S32 vert_size = mNumVertices*sizeof(LLVector4a); S32 tc_size = (mNumVertices*8+0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) src.mPositions, vert_size); @@ -5301,7 +5301,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } else { - ll_aligned_free_16(mBinormals); + delete [] mBinormals; mBinormals = NULL; } @@ -5312,7 +5312,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } else { - ll_aligned_free_16(mWeights); + delete [] mWeights; mWeights = NULL; } } @@ -5330,7 +5330,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) LLVolumeFace::~LLVolumeFace() { - ll_aligned_free_16(mExtents); + delete [] mExtents; mExtents = NULL; freeData(); @@ -5338,17 +5338,17 @@ LLVolumeFace::~LLVolumeFace() void LLVolumeFace::freeData() { - ll_aligned_free_16(mPositions); + delete [] mPositions; mPositions = NULL; - ll_aligned_free_16(mNormals); + delete [] mNormals; mNormals = NULL; - ll_aligned_free_16(mTexCoords); + delete [] mTexCoords; mTexCoords = NULL; - ll_aligned_free_16(mIndices); + delete [] mIndices; mIndices = NULL; - ll_aligned_free_16(mBinormals); + delete [] mBinormals; mBinormals = NULL; - ll_aligned_free_16(mWeights); + delete [] mWeights; mWeights = NULL; delete mOctree; @@ -5461,18 +5461,13 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } -void LLVolumeFace::createOctree(F32 scaler) +void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVector4a& size) { if (mOctree) { return; } - LLVector4a center; - LLVector4a size; - center.splat(0.f); - size.splat(0.5f); - mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL); new LLVolumeOctreeListener(mOctree); @@ -6166,21 +6161,21 @@ void LLVolumeFace::createBinormals() void LLVolumeFace::resizeVertices(S32 num_verts) { - ll_aligned_free_16(mPositions); - ll_aligned_free_16(mNormals); - ll_aligned_free_16(mBinormals); - ll_aligned_free_16(mTexCoords); + delete [] mPositions; + delete [] mNormals; + delete [] mBinormals; + delete [] mTexCoords; mBinormals = NULL; if (num_verts) { - mPositions = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); - mNormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); + mPositions = new LLVector4a[num_verts]; + mNormals = new LLVector4a[num_verts]; //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*8) + 0xF) & ~0xF; - mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); + mTexCoords = new LLVector2[size/8]; } else { @@ -6204,20 +6199,20 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con S32 old_size = mNumVertices*16; //positions - LLVector4a* dst = (LLVector4a*) ll_aligned_malloc_16(new_size); + LLVector4a* dst = new LLVector4a[new_verts]; if (mPositions) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mPositions, old_size); - ll_aligned_free_16(mPositions); + delete [] mPositions; } mPositions = dst; //normals - dst = (LLVector4a*) ll_aligned_malloc_16(new_size); + dst = new LLVector4a[new_verts]; if (mNormals) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mNormals, old_size); - ll_aligned_free_16(mNormals); + delete [] mNormals; } mNormals = dst; @@ -6225,19 +6220,18 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con new_size = ((new_verts*8)+0xF) & ~0xF; old_size = ((mNumVertices*8)+0xF) & ~0xF; - dst = (LLVector4a*) ll_aligned_malloc_16(new_size); { - LLVector2* dst = (LLVector2*) ll_aligned_malloc_16(new_size); + LLVector2* dst = new LLVector2[new_size/8]; if (mTexCoords) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mTexCoords, old_size); - ll_aligned_free_16(mTexCoords); + delete [] mTexCoords; } + mTexCoords = dst; } - mTexCoords = (LLVector2*) dst; //just clear binormals - ll_aligned_free_16(mBinormals); + delete [] mBinormals; mBinormals = NULL; mPositions[mNumVertices] = pos; @@ -6249,26 +6243,26 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con void LLVolumeFace::allocateBinormals(S32 num_verts) { - ll_aligned_free_16(mBinormals); - mBinormals = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); + delete [] mBinormals; + mBinormals = new LLVector4a[num_verts]; } void LLVolumeFace::allocateWeights(S32 num_verts) { - ll_aligned_free_16(mWeights); - mWeights = (LLVector4a*) ll_aligned_malloc_16(num_verts*16); + delete [] mWeights; + mWeights = new LLVector4a[num_verts]; } void LLVolumeFace::resizeIndices(S32 num_indices) { - ll_aligned_free_16(mIndices); - + delete [] mIndices; + if (num_indices) { //pad index block end to allow for QWORD reads S32 size = ((num_indices*2) + 0xF) & ~0xF; - mIndices = (U16*) ll_aligned_malloc_16(size); + mIndices = new U16[size/2]; } else { @@ -6286,11 +6280,11 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; if (new_size != old_size) { - U16* dst = (U16*) ll_aligned_malloc_16(new_size); + U16* dst = new U16[new_size/2]; if (mIndices) { LLVector4a::memcpyNonAliased16((F32*) dst, (F32*) mIndices, old_size); - ll_aligned_free_16(mIndices); + delete [] mIndices; } mIndices = dst; } @@ -6333,9 +6327,9 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } //allocate new buffer space - LLVector4a* new_pos = (LLVector4a*) ll_aligned_malloc_16(new_count*16); - LLVector4a* new_norm = (LLVector4a*) ll_aligned_malloc_16(new_count*16); - LLVector2* new_tc = (LLVector2*) ll_aligned_malloc_16((new_count*8+0xF) & ~0xF); + LLVector4a* new_pos = new LLVector4a[new_count]; + LLVector4a* new_norm = new LLVector4a[new_count]; + LLVector2* new_tc = new LLVector2[((new_count*8+0xF) & ~0xF)/8]; if (mNumVertices > 0) @@ -6346,10 +6340,10 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } //free old buffer space - ll_aligned_free_16(mPositions); - ll_aligned_free_16(mNormals); - ll_aligned_free_16(mTexCoords); - + delete [] mPositions; + delete [] mNormals; + delete [] mTexCoords; + //point to new buffers mPositions = new_pos; mNormals = new_norm; @@ -6399,7 +6393,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; //allocate new index buffer - U16* new_indices = (U16*) ll_aligned_malloc_16((new_count*2+0xF) & ~0xF); + U16* new_indices = new U16[((new_count*2+0xF) & ~0xF)/2]; if (mNumIndices > 0) { //copy old index buffer S32 old_size = (mNumIndices*2+0xF) & ~0xF; @@ -6407,8 +6401,8 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } //free old index buffer - ll_aligned_free_16(mIndices); - + delete [] mIndices; + //point to new index buffer mIndices = new_indices; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index ff5e3d9dfa..32364bd4b8 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -882,7 +882,7 @@ public: }; void optimize(F32 angle_cutoff = 2.f); - void createOctree(F32 scaler = 0.25f); + void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); enum { diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 5949a373ae..efbb62011c 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -191,15 +191,6 @@ LLVOVolume* LLDrawable::getVOVolume() const const LLMatrix4& LLDrawable::getRenderMatrix() const { - if (LLDrawable::isState(LLDrawable::RIGGED)) - { - LLVOAvatar* avatar = mVObjp->getAvatar(); - if (avatar) - { - return avatar->mDrawable->getWorldMatrix(); - } - } - return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); } @@ -727,8 +718,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLVOVolume* volume = getVOVolume(); if (volume) { - volume->updateRelativeXform(); - pos = volume->getRelativeXform().getTranslation(); + pos.set(getPositionGroup().getF32ptr()); if (isStatic()) { pos += volume->getRegion()->getOriginAgent(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index ccc060f3fa..5cf6082f12 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1325,6 +1325,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) #if LL_MESH_ENABLED void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) { + LLVector4a* weight = vol_face.mWeights; + if (!weight) + { + return; + } + LLVertexBuffer* buffer = face->mVertexBuffer; U32 data_mask = 0; @@ -1403,8 +1409,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* } } - LLVector4a* weight = vol_face.mWeights; - LLMatrix4a bind_shape_matrix; bind_shape_matrix.loadu(skin->mBindShapeMatrix); @@ -1422,7 +1426,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { F32 w = weight[j][k]; - idx[k] = (S32) floorf(w); + idx[k] = llclamp((S32) floorf(w), 0, 63); wght[k] = w - floorf(w); scale += wght[k]; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 9a178985cf..3fa60e9f1e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -556,8 +556,36 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) } glColor4fv(color.mV); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); - mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + + if (mDrawablep->isState(LLDrawable::RIGGED)) + { + LLVOVolume* volume = mDrawablep->getVOVolume(); + if (volume) + { + LLRiggedVolume* rigged = volume->getRiggedVolume(); + if (rigged) + { + LLGLEnable offset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.f, -1.f); + glMultMatrixf((F32*) volume->getRelativeXform().mMatrix); + const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); + LLVertexBuffer::unbind(); + glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions); + if (vol_face.mTexCoords) + { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords); + } + glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + } + else + { + mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); + } gGL.popMatrix(); } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ff2929695d..21f7e780e2 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -5395,6 +5395,42 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id)); } + +//helper function for pushing relevant vertices from drawable to GL +void pushWireframe(LLDrawable* drawable) +{ + if (drawable->isState(LLDrawable::RIGGED)) + { //render straight from rigged volume if this is a rigged attachment + LLVOVolume* vobj = drawable->getVOVolume(); + if (vobj) + { + vobj->updateRiggedVolume(); + LLRiggedVolume* rigged_volume = vobj->getRiggedVolume(); + if (rigged_volume) + { + LLVertexBuffer::unbind(); + gGL.pushMatrix(); + glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); + for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = rigged_volume->getVolumeFace(i); + glVertexPointer(3, GL_FLOAT, 16, face.mPositions); + glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); + } + gGL.popMatrix(); + } + } + } + else + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + pushVerts(face, LLVertexBuffer::MAP_VERTEX); + } + } +} + void LLSelectNode::renderOneWireframe(const LLColor4& color) { LLViewerObject* objectp = getObject(); @@ -5442,11 +5478,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); { glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - pushVerts(face, LLVertexBuffer::MAP_VERTEX); - } + pushWireframe(drawable); } } @@ -5455,13 +5487,9 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color) glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); LLGLEnable offset(GL_POLYGON_OFFSET_LINE); - glPolygonOffset(3.f, 2.f); + glPolygonOffset(3.f, 3.f); glLineWidth(3.f); - for (S32 i = 0; i < drawable->getNumFaces(); ++i) - { - LLFace* face = drawable->getFace(i); - pushVerts(face, LLVertexBuffer::MAP_VERTEX); - } + pushWireframe(drawable); glLineWidth(1.f); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); gGL.popMatrix(); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 191cdac981..0f9f35dc57 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3121,9 +3121,11 @@ void renderRaycast(LLDrawable* drawablep) LLVOVolume* vobj = drawablep->getVOVolume(); LLVolume* volume = vobj->getVolume(); + bool transform = true; if (drawablep->isState(LLDrawable::RIGGED)) { - volume = NULL; + volume = vobj->getRiggedVolume(); + transform = false; } if (volume) @@ -3140,8 +3142,16 @@ void renderRaycast(LLDrawable* drawablep) glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); LLVector3 start, end; - start = vobj->agentPositionToVolume(gDebugRaycastStart); - end = vobj->agentPositionToVolume(gDebugRaycastEnd); + if (transform) + { + start = vobj->agentPositionToVolume(gDebugRaycastStart); + end = vobj->agentPositionToVolume(gDebugRaycastEnd); + } + else + { + start = gDebugRaycastStart; + end = gDebugRaycastEnd; + } LLVector4a starta, enda; starta.load3(start.mV); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 60bdfc24b9..f09ce5b363 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1358,8 +1358,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) LLVector4a min,max; - BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION) || mRiggedVolume.notNull(); + BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); + bool rigged = false; LLVolume* volume = mRiggedVolume; if (!volume) { @@ -1424,10 +1425,19 @@ void LLVOVolume::updateRelativeXform() LLDrawable* drawable = mDrawable; - if (drawable->isState(LLDrawable::RIGGED)) - { - mRelativeXform.setIdentity(); - mRelativeXformInvTrans.setIdentity(); + if (drawable->isState(LLDrawable::RIGGED) && mRiggedVolume.notNull()) + { //rigged volume (which is in agent space) is used for generating bounding boxes etc + //inverse of render matrix should go to partition space + mRelativeXform = getRenderMatrix(); + + F32* dst = (F32*) mRelativeXformInvTrans.mMatrix; + F32* src = (F32*) mRelativeXform.mMatrix; + dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; + dst[3] = src[4]; dst[4] = src[5]; dst[5] = src[6]; + dst[6] = src[8]; dst[7] = src[9]; dst[8] = src[10]; + + mRelativeXform.invert(); + mRelativeXformInvTrans.transpose(); } else if (drawable->isActive()) { @@ -3421,12 +3431,15 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e LLVolume* volume = getVolume(); + bool transform = true; + if (mDrawable->isState(LLDrawable::RIGGED)) { if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); volume = mRiggedVolume; + transform = false; } else { //cannot pick rigged attachments on other avatars or when not in build mode @@ -3438,8 +3451,16 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { LLVector3 v_start, v_end, v_dir; - v_start = agentPositionToVolume(start); - v_end = agentPositionToVolume(end); + if (transform) + { + v_start = agentPositionToVolume(start); + v_end = agentPositionToVolume(end); + } + else + { + v_start = start; + v_end = end; + } LLVector3 p; LLVector3 n; @@ -3499,18 +3520,40 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (intersection != NULL) { - *intersection = volumePositionToAgent(p); // must map back to agent space + if (transform) + { + *intersection = volumePositionToAgent(p); // must map back to agent space + } + else + { + *intersection = p; + } } if (normal != NULL) { - *normal = volumeDirectionToAgent(n); + if (transform) + { + *normal = volumeDirectionToAgent(n); + } + else + { + *normal = n; + } + (*normal).normVec(); } if (bi_normal != NULL) { - *bi_normal = volumeDirectionToAgent(bn); + if (transform) + { + *bi_normal = volumeDirectionToAgent(bn); + } + else + { + *bi_normal = bn; + } (*bi_normal).normVec(); } @@ -3528,18 +3571,49 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return ret; } +bool LLVOVolume::treatAsRigged() +{ + return LLFloater::isVisible(gFloaterTools) && + isAttachment() && + getAvatar() && + getAvatar()->isSelf() && + mDrawable.notNull() && + mDrawable->isState(LLDrawable::RIGGED); +} + +LLRiggedVolume* LLVOVolume::getRiggedVolume() +{ + return mRiggedVolume; +} + +void LLVOVolume::clearRiggedVolume() +{ + if (mRiggedVolume.notNull()) + { + mRiggedVolume = NULL; + updateRelativeXform(); + } +} + void LLVOVolume::updateRiggedVolume() { //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. + if (!treatAsRigged()) + { + clearRiggedVolume(); + + return; + } + LLVolume* volume = getVolume(); const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID()); if (!skin) { - mRiggedVolume = NULL; + clearRiggedVolume(); return; } @@ -3547,7 +3621,7 @@ void LLVOVolume::updateRiggedVolume() if (!avatar) { - mRiggedVolume = NULL; + clearRiggedVolume(); return; } @@ -3555,6 +3629,7 @@ void LLVOVolume::updateRiggedVolume() { LLVolumeParams p; mRiggedVolume = new LLRiggedVolume(p); + updateRelativeXform(); } mRiggedVolume->update(skin, avatar, volume); @@ -3592,12 +3667,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons //build matrix palette LLMatrix4a mp[64]; LLMatrix4* mat = (LLMatrix4*) mp; - - LLMatrix4 agent_to_root; - - LLVector4a origin; - origin.load3(avatar->getPositionAgent().mV); - + for (U32 j = 0; j < skin->mJointNames.size(); ++j) { LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); @@ -3661,7 +3731,6 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLVector4a dst; bind_shape_matrix.affineTransform(v, t); final_mat.affineTransform(t, dst); - dst.sub(origin); pos[j] = dst; } @@ -3687,7 +3756,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons LLFastTimer t(FTM_RIGGED_OCTREE); delete dst_face.mOctree; dst_face.mOctree = NULL; - dst_face.createOctree(2.f); + + LLVector4a size; + size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); + size.splat(size.getLength3().getF32()*0.5f); + + dst_face.createOctree(1.f); } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d868099eeb..f058710a27 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -306,7 +306,17 @@ public: //rigged volume update (for raycasting) void updateRiggedVolume(); - LLRiggedVolume* getRiggedVolume() { return mRiggedVolume; } + LLRiggedVolume* getRiggedVolume(); + + //returns true if volume should be treated as a rigged volume + // - Build tools are open + // - object is an attachment + // - object is attached to self + // - object is rendered as rigged + bool treatAsRigged(); + + //clear out rigged volume and revert back to non-rigged state for picking/LOD/distance updates + void clearRiggedVolume(); protected: S32 computeLODDetail(F32 distance, F32 radius); |