diff options
author | Dave Parks <davep@lindenlab.com> | 2010-09-19 23:07:15 -0500 |
---|---|---|
committer | Dave Parks <davep@lindenlab.com> | 2010-09-19 23:07:15 -0500 |
commit | 90da6d6fdc33343be72252101aed1be641e822b5 (patch) | |
tree | 66f6045cdf869324d16a57af613ab8213fedab42 | |
parent | 3cda7606380109beb3f331b8b53d38914f8ba8f5 (diff) |
Raycasting for rigged attachments now works for your own attachments while in edit mode.
-rw-r--r-- | indra/llmath/llvolume.cpp | 17 | ||||
-rw-r--r-- | indra/llmath/llvolume.h | 4 | ||||
-rw-r--r-- | indra/llmath/llvolumeoctree.cpp | 8 | ||||
-rw-r--r-- | indra/newview/lldrawable.cpp | 14 | ||||
-rw-r--r-- | indra/newview/lldrawable.h | 56 | ||||
-rw-r--r-- | indra/newview/llface.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 80 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 230 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 22 |
10 files changed, 372 insertions, 75 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4798197921..07339f7526 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2569,14 +2569,13 @@ void LLVolume::makeTetrahedron() mIsTetrahedron = TRUE; } -void LLVolume::copyVolumeFaces(LLVolume* volume) +void LLVolume::copyVolumeFaces(const LLVolume* volume) { mVolumeFaces = volume->mVolumeFaces; mSculptLevel = 0; mIsTetrahedron = FALSE; } - S32 LLVolume::getNumFaces() const { #if LL_MESH_ENABLED @@ -5462,12 +5461,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff) } -void LLVolumeFace::createOctree() +void LLVolumeFace::createOctree(F32 scaler) { + if (mOctree) + { + return; + } + LLVector4a center; LLVector4a size; center.splat(0.f); - size.splat(1.f); + size.splat(0.5f); mOctree = new LLOctreeRoot<LLVolumeTriangle>(center, size, NULL); new LLVolumeOctreeListener(mOctree); @@ -5511,12 +5515,15 @@ void LLVolumeFace::createOctree() LLVector4a size; size.setSub(max,min); - tri->mRadius = size.getLength3().getF32() * 0.5f; + tri->mRadius = size.getLength3().getF32() * scaler; //insert mOctree->insert(tri); } + //remove unneeded octree layers + while (!mOctree->balance()) { } + //calculate AABB for each node LLVolumeOctreeRebound rebound(this); rebound.traverse(mOctree); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index af28337f57..ff5e3d9dfa 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(); + void createOctree(F32 scaler = 0.25f); enum { @@ -1044,7 +1044,7 @@ public: LLVector3 mLODScaleBias; // vector for biasing LOD based on scale void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level); - void copyVolumeFaces(LLVolume* volume); + void copyVolumeFaces(const LLVolume* volume); private: void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 12fe90f35d..cb6211f63c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -223,14 +223,14 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch) test_min.setSub(center, size); test_max.setAdd(center, size); - if (!test_min.equals3(min) || - !test_max.equals3(max)) + if (!test_min.equals3(min, 0.001f) || + !test_max.equals3(max, 0.001f)) { llerrs << "Bad bounding box data found." << llendl; } - test_min.sub(LLVector4a::getEpsilon()); - test_max.add(LLVector4a::getEpsilon()); + test_min.sub(LLVector4a(0.001f)); + test_max.add(LLVector4a(0.001f)); for (U32 i = 0; i < branch->getChildCount(); ++i) { diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 68f52e04bc..5949a373ae 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -189,6 +189,20 @@ 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(); +} + BOOL LLDrawable::isLight() const { LLViewerObject* objectp = mVObjp; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index fc90bc57c4..a17e2172aa 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -101,7 +101,7 @@ public: LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); } - const LLMatrix4& getRenderMatrix() const { return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); } + const LLMatrix4& getRenderMatrix() const; void setPosition(LLVector3 v) const { } const LLVector3& getPosition() const { return mXform.getPosition(); } const LLVector3& getWorldPosition() const { return mXform.getPositionW(); } @@ -250,35 +250,37 @@ public: typedef enum e_drawable_flags { - IN_REBUILD_Q1 = 0x00000002, - IN_REBUILD_Q2 = 0x00000004, - IN_LIGHT_Q = 0x00000008, - EARLY_MOVE = 0x00000010, - MOVE_UNDAMPED = 0x00000020, - ON_MOVE_LIST = 0x00000040, - USE_BACKLIGHT = 0x00000080, - UV = 0x00000100, - UNLIT = 0x00000200, - LIGHT = 0x00000400, - LIGHTING_BUILT = 0x00000800, - REBUILD_VOLUME = 0x00001000, //volume changed LOD or parameters, or vertex buffer changed - REBUILD_TCOORD = 0x00002000, //texture coordinates changed - REBUILD_COLOR = 0x00004000, //color changed - REBUILD_POSITION= 0x00010000, //vertex positions/normals changed + IN_REBUILD_Q1 = 0x00000001, + IN_REBUILD_Q2 = 0x00000002, + IN_LIGHT_Q = 0x00000004, + EARLY_MOVE = 0x00000008, + MOVE_UNDAMPED = 0x00000010, + ON_MOVE_LIST = 0x00000020, + USE_BACKLIGHT = 0x00000040, + UV = 0x00000080, + UNLIT = 0x00000100, + LIGHT = 0x00000200, + LIGHTING_BUILT = 0x00000400, + REBUILD_VOLUME = 0x00000800, //volume changed LOD or parameters, or vertex buffer changed + REBUILD_TCOORD = 0x00001000, //texture coordinates changed + REBUILD_COLOR = 0x00002000, //color changed + REBUILD_POSITION= 0x00004000, //vertex positions/normals changed REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, - ON_SHIFT_LIST = 0x00100000, - BLOCKER = 0x00400000, - ACTIVE = 0x00800000, - DEAD = 0x01000000, - INVISIBLE = 0x02000000, // stay invisible until flag is cleared - NEARBY_LIGHT = 0x04000000, // In gPipeline.mNearbyLightSet - BUILT = 0x08000000, - FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) - CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame - REBUILD_SHADOW = 0x40000000, - HAS_ALPHA = 0x80000000, + REBUILD_RIGGED = 0x00008000, + ON_SHIFT_LIST = 0x00010000, + BLOCKER = 0x00020000, + ACTIVE = 0x00040000, + DEAD = 0x00080000, + INVISIBLE = 0x00100000, // stay invisible until flag is cleared + NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet + BUILT = 0x00400000, + FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) + CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame + REBUILD_SHADOW = 0x02000000, + HAS_ALPHA = 0x04000000, + RIGGED = 0x08000000, } EDrawableFlags; LLXformMatrix mXform; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 7c24eb77cd..9a178985cf 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -720,7 +720,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, LLMemType mt1(LLMemType::MTYPE_DRAWABLE); //get bounding box - if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) + if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { //VECTORIZE THIS LLMatrix4a mat_vert; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 2f0641489d..191cdac981 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3047,19 +3047,21 @@ public: LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); LLVector3 center, size; - center.set(vl->mBounds[0].getF32ptr()); - size.set(vl->mBounds[1].getF32ptr()); - + if (branch->getData().empty()) { gGL.color3f(1.f,0.2f,0.f); + center.set(branch->getCenter().getF32ptr()); + size.set(branch->getSize().getF32ptr()); } else { gGL.color3f(0.75f, 1.f, 0.f); + center.set(vl->mBounds[0].getF32ptr()); + size.set(vl->mBounds[1].getF32ptr()); } - - drawBoxOutline(center, size); + + drawBoxOutline(center, size); for (U32 i = 0; i < 2; i++) { @@ -3072,10 +3074,7 @@ public: else { gGL.color4f(0,0.5f,0.5f, 0.25f); - if (!branch->getData().empty()) - { - drawBoxOutline(center, size); - } + drawBoxOutline(center, size); } if (i == 1) @@ -3121,34 +3120,53 @@ void renderRaycast(LLDrawable* drawablep) LLVOVolume* vobj = drawablep->getVOVolume(); LLVolume* volume = vobj->getVolume(); - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + + if (drawablep->isState(LLDrawable::RIGGED)) + { + volume = NULL; + } + + if (volume) { - const LLVolumeFace& face = volume->getVolumeFace(i); - if (!face.mOctree) + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) { - ((LLVolumeFace*) &face)->createOctree(); - } + const LLVolumeFace& face = volume->getVolumeFace(i); + if (!face.mOctree) + { + ((LLVolumeFace*) &face)->createOctree(); + } - gGL.pushMatrix(); - glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); - LLVector3 start, end; - start = vobj->agentPositionToVolume(gDebugRaycastStart); - end = vobj->agentPositionToVolume(gDebugRaycastEnd); + gGL.pushMatrix(); + glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); - LLVector4a starta, enda; - starta.load3(start.mV); - enda.load3(end.mV); - LLVector4a dir; - dir.setSub(enda, starta); + LLVector3 start, end; + start = vobj->agentPositionToVolume(gDebugRaycastStart); + end = vobj->agentPositionToVolume(gDebugRaycastEnd); - F32 t = 1.f; + LLVector4a starta, enda; + starta.load3(start.mV); + enda.load3(end.mV); + LLVector4a dir; + dir.setSub(enda, starta); - LLRenderOctreeRaycast render(starta, dir, &t); - gGL.flush(); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - render.traverse(face.mOctree); - gGL.popMatrix(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + F32 t = 1.f; + + LLRenderOctreeRaycast render(starta, dir, &t); + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + { + //render face positions + LLVertexBuffer::unbind(); + glColor4f(0,1,1,0.5f); + glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions); + glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); + } + + render.traverse(face.mOctree); + gGL.popMatrix(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } } } else if (drawablep->isAvatar()) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index fd2212f25d..4c1a1958e8 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3279,6 +3279,15 @@ const LLVector3 LLViewerObject::getPositionEdit() const const LLVector3 LLViewerObject::getRenderPosition() const { + if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) + { + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + return avatar->getPositionAgent(); + } + } + if (mDrawable.isNull() || mDrawable->getGeneration() < 0) { return getPositionAgent(); @@ -3297,6 +3306,11 @@ const LLVector3 LLViewerObject::getPivotPositionAgent() const const LLQuaternion LLViewerObject::getRenderRotation() const { LLQuaternion ret; + if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) + { + return ret; + } + if (mDrawable.isNull() || mDrawable->isStatic()) { ret = getRotationEdit(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 5448e7dcd9..60bdfc24b9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -41,9 +41,11 @@ #include "llviewercontrol.h" #include "lldir.h" #include "llflexibleobject.h" +#include "llfloatertools.h" #include "llmaterialtable.h" #include "llprimitive.h" #include "llvolume.h" +#include "llvolumeoctree.h" #include "llvolumemgr.h" #include "llvolumemessage.h" #include "material_codes.h" @@ -70,6 +72,7 @@ #include "llselectmgr.h" #include "pipeline.h" #include "llsdutil.h" +#include "llmatrix4a.h" #include "llmediaentry.h" #include "llmediadataclient.h" #include "llmeshrepository.h" @@ -1355,7 +1358,13 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) LLVector4a min,max; - BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION); + BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION) || mRiggedVolume.notNull(); + + LLVolume* volume = mRiggedVolume; + if (!volume) + { + volume = getVolume(); + } for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++) { @@ -1364,7 +1373,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) { continue; } - res &= face->genVolumeBBoxes(*getVolume(), i, + res &= face->genVolumeBBoxes(*volume, i, mRelativeXform, mRelativeXformInvTrans, (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); @@ -1415,7 +1424,12 @@ void LLVOVolume::updateRelativeXform() LLDrawable* drawable = mDrawable; - if (drawable->isActive()) + if (drawable->isState(LLDrawable::RIGGED)) + { + mRelativeXform.setIdentity(); + mRelativeXformInvTrans.setIdentity(); + } + else if (drawable->isActive()) { // setup relative transforms LLQuaternion delta_rot; @@ -1497,11 +1511,22 @@ void LLVOVolume::updateRelativeXform() static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies"); static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives"); +static LLFastTimer::DeclareTimer FTM_UPDATE_RIGGED_VOLUME("Update Rigged"); BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LLFastTimer t(FTM_UPDATE_PRIMITIVES); + if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) + { + { + LLFastTimer t(FTM_UPDATE_RIGGED_VOLUME); + updateRiggedVolume(); + } + genBBoxes(FALSE); + mDrawable->clearState(LLDrawable::REBUILD_RIGGED); + } + if (mVolumeImpl != NULL) { BOOL res; @@ -1597,7 +1622,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LLPipeline::sCompiles++; } - + mVolumeChanged = FALSE; mLODChanged = FALSE; mSculptChanged = FALSE; @@ -2724,6 +2749,11 @@ BOOL LLVOVolume::isVolumeGlobal() const { return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE; } + else if (mRiggedVolume.notNull()) + { + return TRUE; + } + return FALSE; } @@ -3390,6 +3420,20 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e BOOL ret = FALSE; LLVolume* volume = getVolume(); + + if (mDrawable->isState(LLDrawable::RIGGED)) + { + if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); + volume = mRiggedVolume; + } + else + { //cannot pick rigged attachments on other avatars or when not in build mode + return FALSE; + } + } + if (volume) { LLVector3 v_start, v_end, v_dir; @@ -3484,6 +3528,170 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return ret; } +void LLVOVolume::updateRiggedVolume() +{ + //Update mRiggedVolume to match current animation frame of avatar. + //Also update position/size in octree. + + LLVolume* volume = getVolume(); + + const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID()); + + if (!skin) + { + mRiggedVolume = NULL; + return; + } + + LLVOAvatar* avatar = getAvatar(); + + if (!avatar) + { + mRiggedVolume = NULL; + return; + } + + if (!mRiggedVolume) + { + LLVolumeParams p; + mRiggedVolume = new LLRiggedVolume(p); + } + + mRiggedVolume->update(skin, avatar, volume); + +} + +static LLFastTimer::DeclareTimer FTM_SKIN_RIGGED("Skin"); +static LLFastTimer::DeclareTimer FTM_RIGGED_OCTREE("Octree"); + +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) +{ + bool copy = false; + if (volume->getNumVolumeFaces() != getNumVolumeFaces()) + { + copy = true; + } + + for (S32 i = 0; i < volume->getNumVolumeFaces() && !copy; ++i) + { + const LLVolumeFace& src_face = volume->getVolumeFace(i); + const LLVolumeFace& dst_face = getVolumeFace(i); + + if (src_face.mNumIndices != dst_face.mNumIndices || + src_face.mNumVertices != dst_face.mNumVertices) + { + copy = true; + } + } + + if (copy) + { + copyVolumeFaces(volume); + } + + //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]); + if (joint) + { + mat[j] = skin->mInvBindMatrix[j]; + mat[j] *= joint->getWorldMatrix(); + } + } + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& vol_face = volume->getVolumeFace(i); + + LLVolumeFace& dst_face = mVolumeFaces[i]; + + LLVector4a* weight = vol_face.mWeights; + + LLMatrix4a bind_shape_matrix; + bind_shape_matrix.loadu(skin->mBindShapeMatrix); + + LLVector4a* pos = dst_face.mPositions; + + { + LLFastTimer t(FTM_SKIN_RIGGED); + + for (U32 j = 0; j < dst_face.mNumVertices; ++j) + { + LLMatrix4a final_mat; + final_mat.clear(); + + S32 idx[4]; + + LLVector4 wght; + + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weight[j][k]; + + idx[k] = (S32) floorf(w); + wght[k] = w - floorf(w); + scale += wght[k]; + } + + wght *= 1.f/scale; + + for (U32 k = 0; k < 4; k++) + { + F32 w = wght[k]; + + LLMatrix4a src; + src.setMul(mp[idx[k]], w); + + final_mat.add(src); + } + + + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + dst.sub(origin); + pos[j] = dst; + } + + //update bounding box + LLVector4a& min = dst_face.mExtents[0]; + LLVector4a& max = dst_face.mExtents[1]; + + min = pos[0]; + max = pos[1]; + + for (U32 j = 1; j < dst_face.mNumVertices; ++j) + { + min.setMin(min, pos[j]); + max.setMax(max, pos[j]); + } + + dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); + dst_face.mCenter->mul(0.5f); + + } + + { + LLFastTimer t(FTM_RIGGED_OCTREE); + delete dst_face.mOctree; + dst_face.mOctree = NULL; + dst_face.createOctree(2.f); + } + } +} + U32 LLVOVolume::getPartitionType() const { if (isHUDAttachment()) @@ -3732,6 +3940,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + bool is_rigged = false; + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -3747,8 +3957,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->mVertexBuffer = NULL; facep->mLastVertexBuffer = NULL; } - + facep->setState(LLFace::RIGGED); + is_rigged = true; //get drawpool of avatar with rigged face LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); @@ -3958,6 +4169,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) facep->mLastVertexBuffer = NULL; } } + + if (is_rigged) + { + drawablep->setState(LLDrawable::RIGGED); + } + else + { + drawablep->clearState(LLDrawable::RIGGED); + } } group->mBufferUsage = useage; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index eeb98726c9..d868099eeb 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -46,6 +46,8 @@ class LLDrawPool; class LLSelectNode; class LLObjectMediaDataClient; class LLObjectMediaNavigateClient; +class LLVOAvatar; +class LLMeshSkinInfo; typedef std::vector<viewer_media_t> media_list_t; @@ -54,6 +56,18 @@ enum LLVolumeInterfaceType INTERFACE_FLEXIBLE = 1, }; + +class LLRiggedVolume : public LLVolume +{ +public: + LLRiggedVolume(const LLVolumeParams& params) + : LLVolume(params, 0.f) + { + } + + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); +}; + // Base class for implementations of the volume - Primitive, Flexible Object, etc. class LLVolumeInterface { @@ -289,6 +303,11 @@ public: void removeMDCImpl() { --mMDCImplCount; } S32 getMDCImplCount() { return mMDCImplCount; } + + //rigged volume update (for raycasting) + void updateRiggedVolume(); + LLRiggedVolume* getRiggedVolume() { return mRiggedVolume; } + protected: S32 computeLODDetail(F32 distance, F32 radius); BOOL calcLOD(); @@ -322,6 +341,9 @@ private: S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 S32 mIndexInTex; S32 mMDCImplCount; + + LLPointer<LLRiggedVolume> mRiggedVolume; + // statics public: static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop |