From a57170724344842e26b8cd0fa4a47c24efa834c5 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 3 Aug 2017 14:23:02 +0100 Subject: SL-731 - render metadata includes triangle count, triangle and vertex count included with debug text for control avatar --- indra/llmath/llvolume.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 7a54d83b3f..8c27ef9961 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1,5 +1,4 @@ /** - * @file llvolume.cpp * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ -- cgit v1.3 From 3f9b3e01b9d7ea3a6662adb55027839840198b4c Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 21 Feb 2018 22:02:34 +0000 Subject: MAINT-8264 - prevent at least some cases of LODs getting stuck at too-low values. --- indra/llmath/llmatrix4a.h | 6 +++ indra/llmath/llvector4a.h | 7 +++- indra/llmath/llvolume.cpp | 11 +++-- indra/llprimitive/lldaeloader.cpp | 10 ++++- indra/llprimitive/llmodel.cpp | 1 + indra/newview/lldrawable.cpp | 4 +- indra/newview/llface.cpp | 17 ++++++++ indra/newview/llspatialpartition.cpp | 48 +++++++++++++++++----- indra/newview/llvieweroctree.cpp | 2 +- indra/newview/llvovolume.cpp | 38 ++++++++++++++--- indra/newview/skins/default/xui/en/menu_object.xml | 2 +- 11 files changed, 121 insertions(+), 25 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index 216334752a..baa3a89176 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -176,4 +176,10 @@ inline void matMul(const LLMatrix4a &a, const LLMatrix4a &b, LLMatrix4a &res) res.mMatrix[3] = row3; } +inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) +{ + s << "[" << m.mMatrix[0] << ", " << m.mMatrix[1] << ", " << m.mMatrix[2] << ", " << m.mMatrix[3] << "]"; + return s; +} + #endif diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 79d0a44551..222f3cf235 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -320,7 +320,7 @@ public: inline const LLVector4a& operator= ( const LLQuad& rhs ); inline operator LLQuad() const; - + private: LLQuad mQ; } LL_ALIGN_POSTFIX(16); @@ -331,4 +331,9 @@ inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p max.setMax(max, p); } +inline std::ostream& operator<<(std::ostream& s, const LLVector4a& v) +{ + s << "(" << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ")"; + return s; +} #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f1e9817cb2..8556e5294c 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2636,6 +2636,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } //calculate bounding box + // VFExtents change LLVector4a& min = face.mExtents[0]; LLVector4a& max = face.mExtents[1]; @@ -4721,6 +4722,7 @@ LLVolumeFace::~LLVolumeFace() { ll_aligned_free_16(mExtents); mExtents = NULL; + mCenter = NULL; freeData(); } @@ -5496,7 +5498,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build) // S32 i; S32 grid_size = (profile.size()-1)/4; - + // VFExtents change LLVector4a& min = mExtents[0]; LLVector4a& max = mExtents[1]; @@ -5773,7 +5775,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) LLVector2 cuv; LLVector2 min_uv, max_uv; - + // VFExtents change LLVector4a& min = mExtents[0]; LLVector4a& max = mExtents[1]; @@ -6398,14 +6400,17 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat if (offset == 0 && i == 0) { //initialize bounding box + // VFExtents change mExtents[0] = mExtents[1] = dst_pos[i]; } else { //stretch bounding box + // VFExtents change update_min_max(mExtents[0], mExtents[1], dst_pos[i]); } } + LL_DEBUGS("RiggedBox") << "appendFace got extents " << mExtents[0] << ", " << mExtents[1] << " from dst_pos " << LL_ENDL; new_count = mNumIndices + face.mNumIndices; @@ -6568,7 +6573,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { update_min_max(face_min, face_max, *cur_pos++); } - + // VFExtents change mExtents[0] = face_min; mExtents[1] = face_max; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 8401cb976e..8f75d89e5a 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -192,7 +192,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa { return LLModel::BAD_ELEMENT; } - + // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); } @@ -254,6 +254,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa if (!found) { + // VFExtents change update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); verts.push_back(cv); if (verts.size() >= 65535) @@ -305,6 +306,7 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector& fa } face = LLVolumeFace(); + // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); point_map.clear(); @@ -383,6 +385,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac if (pos_source) { v = pos_source->getFloat_array()->getValue(); + // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); } @@ -482,6 +485,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac if (!found) { + // VFExtents change update_min_max(face.mExtents[0], face.mExtents[1], cv.getPosition()); verts.push_back(cv); if (verts.size() >= 65535) @@ -551,6 +555,7 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector& fac } face = LLVolumeFace(); + // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); verts.clear(); @@ -734,7 +739,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac { return LLModel::NO_ERRORS; } - + // VFExtents change face.mExtents[0] = verts[0].getPosition(); face.mExtents[1] = verts[0].getPosition(); @@ -758,6 +763,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector& fac for (std::map::iterator iter = vert_idx.begin(); iter != vert_idx.end(); ++iter) { new_verts[iter->second] = iter->first; + // VFExtents change update_min_max(face.mExtents[0], face.mExtents[1], iter->first.getPosition()); } diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index db6d00bc2c..597cc66088 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -276,6 +276,7 @@ void LLModel::normalizeVolumeFaces() // We shrink the extents so // that they fall within // the unit cube. + // VFExtents change face.mExtents[0].add(trans); face.mExtents[0].mul(scale); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 6799c3f862..7e51389655 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -51,6 +51,7 @@ #include "llviewerwindow.h" #include "llvocache.h" #include "llcontrolavatar.h" +#include "llcallstack.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -1086,7 +1087,8 @@ void LLDrawable::setGroup(LLViewerOctreeGroup *groupp) llassert(!groupp || (LLSpatialGroup*)groupp->hasElement(this)); if (cur_groupp != groupp && getVOVolume()) - { //NULL out vertex buffer references for volumes on spatial group change to maintain + { + //NULL out vertex buffer references for volumes on spatial group change to maintain //requirement that every face vertex buffer is either NULL or points to a vertex buffer //contained by its drawable's spatial group for (S32 i = 0; i < getNumFaces(); ++i) diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 0a7e0c92be..efd57ec39f 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -831,6 +831,9 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, min = face.mExtents[0]; max = face.mExtents[1]; + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " starting extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1] << " num verts " << face.mNumVertices << LL_ENDL; + llassert(less_than_max_mag(min)); llassert(less_than_max_mag(max)); @@ -859,6 +862,14 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, v[6] = min; v[7] = max; + // MAINT-8264 - stray vertices, especially in low LODs, cause bounding box errors. + if (face.mNumVertices < 3) + { + LL_DEBUGS("RiggedBox") << "skipping face " << f << ", bad num vertices " + << face.mNumVertices << " " << face.mNumIndices << " " << face.mWeights << LL_ENDL; + return FALSE; + } + for (U32 i = 0; i < 6; ++i) { v[i].setSelectWithMask(mask[i], min, max); @@ -866,10 +877,13 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, LLVector4a tv[8]; + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " mat is " << mat_vert << LL_ENDL; + //transform bounding box into drawable space for (U32 i = 0; i < 8; ++i) { mat_vert.affineTransform(v[i], tv[i]); + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " i " << i << " v and tv " << v[i] << ", " << tv[i] << LL_ENDL; } //find bounding box @@ -883,6 +897,7 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, newMin.setMin(newMin, tv[i]); newMax.setMax(newMax, tv[i]); } + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " bbox gave extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; if (!mDrawablep->isActive()) { // Shift position for region @@ -890,8 +905,10 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); newMin.add(offset); newMax.add(offset); + LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " not active, added offset " << offset << LL_ENDL; } + LL_DEBUGS("RiggedBox") << "updated extents for face " << f << " to " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; LLVector4a t; t.setAdd(newMin,newMax); t.mul(0.5f); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d0328a7539..8b1a23fe89 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -29,6 +29,7 @@ #include "llspatialpartition.h" #include "llappviewer.h" +#include "llcallstack.h" #include "lltexturecache.h" #include "lltexturefetch.h" #include "llimageworker.h" @@ -777,6 +778,10 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) dist = eye.getLength3().getF32(); } + LL_DEBUGS("RiggedBox") << "calcDistance, group " << group << " camera " << origin << " obj bounds " + << group->mObjectBounds[0] << ", " << group->mObjectBounds[1] + << " dist " << dist << " radius " << group->mRadius << LL_ENDL; + if (dist < 16.f) { dist /= 16.f; @@ -808,7 +813,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const BOOL LLSpatialGroup::changeLOD() { if (hasState(ALPHA_DIRTY | OBJECT_DIRTY)) - { ///a rebuild is going to happen, update distance and LoD + { + //a rebuild is going to happen, update distance and LoD return TRUE; } @@ -816,8 +822,28 @@ BOOL LLSpatialGroup::changeLOD() { F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); + // MAINT-8264 - this check is not robust if it needs to work + // for bounding boxes much larger than the actual enclosed + // objects, and using distance to box center is also + // problematic. Consider the case that you have a large box + // where the enclosed object is in one corner. As you zoom in + // on the corner, the object gets much closer to the camera, + // but the distance to the box center changes very little, and + // an LOD change will not trigger, so object LOD gets "stuck" + // at a too-low value. In the case of the above JIRA, the box + // was large only due to another error, so this logic did not + // need to be changed. + if (fabsf(ratio) >= getSpatialPartition()->mSlopRatio) { + LL_DEBUGS("RiggedBox") << "changeLOD true because of ratio compare " + << fabsf(ratio) << " " << getSpatialPartition()->mSlopRatio << LL_ENDL; + LL_DEBUGS("RiggedBox") << "sg " << this << "\nmDistance " << mDistance + << " mLastUpdateDistance " << mLastUpdateDistance + << " mRadius " << mRadius + << " fab ratio " << fabsf(ratio) + << " slop " << getSpatialPartition()->mSlopRatio << LL_ENDL; + return TRUE; } @@ -2109,17 +2135,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) { if (drawable->isSpatialBridge()) { - gGL.diffuseColor4f(1,0.5f,0,1); + gGL.diffuseColor4f(1,0.5f,0,1); // orange } else if (drawable->getVOVolume()) - { - if (drawable->isRoot()) + { + if (drawable->isRoot()) { - gGL.diffuseColor4f(1,1,0,1); + gGL.diffuseColor4f(1,1,0,1); // yellow } else { - gGL.diffuseColor4f(0,1,0,1); + gGL.diffuseColor4f(0,1,0,1); // green } } else if (drawable->getVObj()) @@ -2127,24 +2153,24 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) switch (drawable->getVObj()->getPCode()) { case LLViewerObject::LL_VO_SURFACE_PATCH: - gGL.diffuseColor4f(0,1,1,1); + gGL.diffuseColor4f(0,1,1,1); // cyan break; case LLViewerObject::LL_VO_CLOUDS: // no longer used break; case LLViewerObject::LL_VO_PART_GROUP: case LLViewerObject::LL_VO_HUD_PART_GROUP: - gGL.diffuseColor4f(0,0,1,1); + gGL.diffuseColor4f(0,0,1,1); // blue break; case LLViewerObject::LL_VO_VOID_WATER: case LLViewerObject::LL_VO_WATER: - gGL.diffuseColor4f(0,0.5f,1,1); + gGL.diffuseColor4f(0,0.5f,1,1); // medium blue break; case LL_PCODE_LEGACY_TREE: - gGL.diffuseColor4f(0,0.5f,0,1); + gGL.diffuseColor4f(0,0.5f,0,1); // dark green break; default: - gGL.diffuseColor4f(1,0,1,1); + gGL.diffuseColor4f(1,0,1,1); // magenta break; } } diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 023f1b92ba..e7916ebd3b 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -731,7 +731,7 @@ bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4 update_min_max(newMin, newMax, minMax[0]); update_min_max(newMin, newMax, minMax[1]); } - + mObjectBounds[0].setAdd(newMin, newMax); mObjectBounds[0].mul(0.5f); mObjectBounds[1].setSub(newMax, newMin); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c007b446f7..a07e3f8be1 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1515,14 +1515,22 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); - // bool rigged = false; + if (getRiggedVolume()) + { + updateRiggedVolume(TRUE); + } + LLVolume* volume = mRiggedVolume; if (!volume) { volume = getVolume(); } - // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() + if (getRiggedVolume()) + { + LL_DEBUGS("RiggedBox") << "rebuilding box, volume face count " << getVolume()->getNumVolumeFaces() << " drawable face count " << mDrawable->getNumFaces() << LL_ENDL; + } + // There's no guarantee that getVolume()->getNumFaces() == mDrawable->getNumFaces() for (S32 i = 0; i < getVolume()->getNumVolumeFaces() && i < mDrawable->getNumFaces() && i < getNumTEs(); i++) @@ -1532,12 +1540,18 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) { continue; } - res &= face->genVolumeBBoxes(*volume, i, - mRelativeXform, - (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); + + BOOL face_res = face->genVolumeBBoxes(*volume, i, + mRelativeXform, + (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); + res &= face_res; // note that this result is never used if (rebuild) { + if (getRiggedVolume()) + { + LL_DEBUGS("RiggedBox") << "rebuilding box, face " << i << " extents " << face->mExtents[0] << ", " << face->mExtents[1] << LL_ENDL; + } if (i == 0) { min = face->mExtents[0]; @@ -1545,6 +1559,11 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) } else { + if (!face_res) + { + // MAINT-8264 - ignore bboxes of ill-formed faces. + continue; + } min.setMin(min, face->mExtents[0]); max.setMax(max, face->mExtents[1]); } @@ -1553,6 +1572,10 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) if (rebuild) { + if (getRiggedVolume()) + { + LL_DEBUGS("RiggedBox") << "rebuilding got extents " << min << ", " << max << LL_ENDL; + } mDrawable->setSpatialExtents(min,max); min.add(max); min.mul(0.5f); @@ -4512,6 +4535,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } //update bounding box + // VFExtents change LLVector4a& min = dst_face.mExtents[0]; LLVector4a& max = dst_face.mExtents[1]; @@ -4528,6 +4552,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons min.setMin(min, pos[j]); max.setMax(max, pos[j]); } + box_min.setMin(min,box_min); box_max.setMax(max,box_max); @@ -5065,6 +5090,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) << " is_animated " << vobj->isAnimatedObject() << " can_animate " << vobj->canBeAnimatedObject() << " cav " << vobj->getControlAvatar() + << " lod " << vobj->getLOD() + << " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED)) + << " drawable state " << drawablep->getState() << " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false) << " frame " << LLFrameTimer::getFrameCount() << LL_ENDL; diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml index 91e7328979..ce34508303 100644 --- a/indra/newview/skins/default/xui/en/menu_object.xml +++ b/indra/newview/skins/default/xui/en/menu_object.xml @@ -228,6 +228,6 @@ + function="Avatar.EnableResetSkeleton"/> -- cgit v1.3 From e86839fac19753d0fa4006296c7f8909fe781013 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 1 Jun 2018 15:08:59 +0100 Subject: SL-915 - WIP on dynamic joint box tracking --- indra/llcharacter/lljoint.cpp | 53 +++++++++++++++++++++++++ indra/llcharacter/lljoint.h | 22 +++++++++++ indra/llmath/CMakeLists.txt | 1 + indra/llmath/llmatrix4a.cpp | 80 +++++++++++++++++++++++++++++++++++++ indra/llmath/llmatrix4a.h | 8 ++-- indra/llprimitive/llmodel.h | 1 - indra/newview/llface.cpp | 92 +++++++++++-------------------------------- indra/newview/llvoavatar.cpp | 39 ++++++++++++++++-- 8 files changed, 218 insertions(+), 78 deletions(-) create mode 100644 indra/llmath/llmatrix4a.cpp (limited to 'indra/llmath') diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 07fcd99701..68355cbbdc 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -96,6 +96,46 @@ void LLVector3OverrideMap::clear() m_map.clear(); } +//----------------------------------------------------------------------------- +// LLJointRiggingInfo +//----------------------------------------------------------------------------- +LLJointRiggingInfo::LLJointRiggingInfo() +{ + mRiggedExtents[0].clear(); + mRiggedExtents[1].clear(); + mIsRiggedTo = false; +} + +bool LLJointRiggingInfo::isRiggedTo() const +{ + return mIsRiggedTo; +} + +void LLJointRiggingInfo::setIsRiggedTo(bool val) +{ + mIsRiggedTo = val; +} + +LLVector4a *LLJointRiggingInfo::getRiggedExtents() +{ + return mRiggedExtents; +} + +const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const +{ + return mRiggedExtents; +} + +// Combine two rigging info states. +// - isRiggedTo if either of the source infos are rigged to +// - box is union of the two sources +void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) +{ + mIsRiggedTo = mIsRiggedTo || other.mIsRiggedTo; + update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]); + update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]); +} + //----------------------------------------------------------------------------- // LLJoint() // Class Constructor @@ -597,6 +637,19 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const } } +//-------------------------------------------------------------------- +// getRiggingInfo() +//-------------------------------------------------------------------- +LLJointRiggingInfo& LLJoint::getRiggingInfo() +{ + return mRiggingInfo; +} + +const LLJointRiggingInfo& LLJoint::getRiggingInfo() const +{ + return mRiggingInfo; +} + //-------------------------------------------------------------------- // updatePos() //-------------------------------------------------------------------- diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 8112d246f2..ff1e967188 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -70,6 +70,23 @@ private: map_type m_map; }; +// Stores information related to associated rigged mesh vertices +// Extents are in joint space +// isRiggedTo is based on the state of all currently associated rigged meshes +class LLJointRiggingInfo +{ +public: + LLJointRiggingInfo(); + bool isRiggedTo() const; + void setIsRiggedTo(bool val); + LLVector4a *getRiggedExtents(); + const LLVector4a *getRiggedExtents() const; + void merge(const LLJointRiggingInfo& other); +private: + LL_ALIGN_16(LLVector4a mRiggedExtents[2]); + bool mIsRiggedTo; +}; + inline bool operator==(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b) { return a.getMap() == b.getMap(); @@ -158,6 +175,11 @@ public: LLVector3OverrideMap m_attachmentScaleOverrides; LLVector3 m_scaleBeforeOverrides; + // Rigging Info + LLJointRiggingInfo mRiggingInfo; + LLJointRiggingInfo& getRiggingInfo(); + const LLJointRiggingInfo& getRiggingInfo() const; + void updatePos(const std::string& av_info); void updateScale(const std::string& av_info); diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 4c8bcdac91..dab566da56 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -20,6 +20,7 @@ set(llmath_SOURCE_FILES llcoordframe.cpp llline.cpp llmatrix3a.cpp + llmatrix4a.cpp llmodularmath.cpp lloctree.cpp llperlin.cpp diff --git a/indra/llmath/llmatrix4a.cpp b/indra/llmath/llmatrix4a.cpp new file mode 100644 index 0000000000..fe8f0b98f3 --- /dev/null +++ b/indra/llmath/llmatrix4a.cpp @@ -0,0 +1,80 @@ +/** +* @file llmatrix4a.cpp +* @brief Functions for vectorized matrix/vector operations +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llmath.h" +#include "llmatrix4a.h" + +// Convert a bounding box into other coordinate system. Should give +// the same results as transforming every corner of the bounding box +// and extracting the bounding box of that, although that's not +// necessarily the fastest way to implement. +void matMulBoundBox(const LLMatrix4a &mat, const LLVector4a *in_extents, LLVector4a *out_extents) +{ + //get 8 corners of bounding box + LLVector4Logical mask[6]; + + for (U32 i = 0; i < 6; ++i) + { + mask[i].clear(); + } + + mask[0].setElement<2>(); //001 + mask[1].setElement<1>(); //010 + mask[2].setElement<1>(); //011 + mask[2].setElement<2>(); + mask[3].setElement<0>(); //100 + mask[4].setElement<0>(); //101 + mask[4].setElement<2>(); + mask[5].setElement<0>(); //110 + mask[5].setElement<1>(); + + LLVector4a v[8]; + + v[6] = in_extents[0]; + v[7] = in_extents[1]; + + for (U32 i = 0; i < 6; ++i) + { + v[i].setSelectWithMask(mask[i], in_extents[0], in_extents[1]); + } + + LLVector4a tv[8]; + + //transform bounding box into drawable space + for (U32 i = 0; i < 8; ++i) + { + mat.affineTransform(v[i], tv[i]); + } + + //find bounding box + out_extents[0] = out_extents[1] = tv[0]; + + for (U32 i = 1; i < 8; ++i) + { + out_extents[0].setMin(out_extents[0], tv[i]); + out_extents[1].setMax(out_extents[1], tv[i]); + } +} diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h index baa3a89176..7ba347062f 100644 --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -121,7 +121,7 @@ public: res.add(z); } - inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) + inline void affineTransformSSE(const LLVector4a& v, LLVector4a& res) const { LLVector4a x,y,z; @@ -138,7 +138,7 @@ public: res.setAdd(x,z); } - inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) + inline void affineTransformNonSSE(const LLVector4a& v, LLVector4a& res) const { F32 x = v[0] * mMatrix[0][0] + v[1] * mMatrix[1][0] + v[2] * mMatrix[2][0] + mMatrix[3][0]; F32 y = v[0] * mMatrix[0][1] + v[1] * mMatrix[1][1] + v[2] * mMatrix[2][1] + mMatrix[3][1]; @@ -147,7 +147,7 @@ public: res.set(x,y,z,w); } - inline void affineTransform(const LLVector4a& v, LLVector4a& res) + inline void affineTransform(const LLVector4a& v, LLVector4a& res) const { affineTransformSSE(v,res); } @@ -182,4 +182,6 @@ inline std::ostream& operator<<(std::ostream& s, const LLMatrix4a& m) return s; } +void matMulBoundBox(const LLMatrix4a &a, const LLVector4a *in_extents, LLVector4a *out_extents); + #endif diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 097558ef67..53585d2e04 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -38,7 +38,6 @@ class domMesh; #define MAX_MODEL_FACES 8 - class LLMeshSkinInfo { public: diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index efd57ec39f..7bc7814392 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -810,17 +810,11 @@ bool less_than_max_mag(const LLVector4a& vec) } BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, - const LLMatrix4& mat_vert_in, BOOL global_volume) + const LLMatrix4& mat_vert_in, BOOL global_volume) { //get bounding box if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { - //VECTORIZE THIS - LLMatrix4a mat_vert; - mat_vert.loadu(mat_vert_in); - - LLVector4a min,max; - if (f >= volume.getNumVolumeFaces()) { LL_WARNS() << "Generating bounding box for invalid face index!" << LL_ENDL; @@ -828,39 +822,11 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } const LLVolumeFace &face = volume.getVolumeFace(f); - min = face.mExtents[0]; - max = face.mExtents[1]; - LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " starting extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; - LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1] << " num verts " << face.mNumVertices << LL_ENDL; - - llassert(less_than_max_mag(min)); - llassert(less_than_max_mag(max)); - - //min, max are in volume space, convert to drawable render space - - //get 8 corners of bounding box - LLVector4Logical mask[6]; - - for (U32 i = 0; i < 6; ++i) - { - mask[i].clear(); - } - - mask[0].setElement<2>(); //001 - mask[1].setElement<1>(); //010 - mask[2].setElement<1>(); //011 - mask[2].setElement<2>(); - mask[3].setElement<0>(); //100 - mask[4].setElement<0>(); //101 - mask[4].setElement<2>(); - mask[5].setElement<0>(); //110 - mask[5].setElement<1>(); - - LLVector4a v[8]; - - v[6] = min; - v[7] = max; + LL_DEBUGS("RiggedBox") << "updating extents for face " << f + << " starting extents " << mExtents[0] << ", " << mExtents[1] + << " starting vf extents " << face.mExtents[0] << ", " << face.mExtents[1] + << " num verts " << face.mNumVertices << LL_ENDL; // MAINT-8264 - stray vertices, especially in low LODs, cause bounding box errors. if (face.mNumVertices < 3) @@ -870,52 +836,38 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, return FALSE; } - for (U32 i = 0; i < 6; ++i) - { - v[i].setSelectWithMask(mask[i], min, max); - } - - LLVector4a tv[8]; - - LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " mat is " << mat_vert << LL_ENDL; + //VECTORIZE THIS + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); + LLVector4a new_extents[2]; - //transform bounding box into drawable space - for (U32 i = 0; i < 8; ++i) - { - mat_vert.affineTransform(v[i], tv[i]); - LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " i " << i << " v and tv " << v[i] << ", " << tv[i] << LL_ENDL; - } - - //find bounding box - LLVector4a& newMin = mExtents[0]; - LLVector4a& newMax = mExtents[1]; + llassert(less_than_max_mag(face.mExtents[0])); + llassert(less_than_max_mag(face.mExtents[1])); - newMin = newMax = tv[0]; + matMulBoundBox(mat_vert, face.mExtents, mExtents); - for (U32 i = 1; i < 8; ++i) - { - newMin.setMin(newMin, tv[i]); - newMax.setMax(newMax, tv[i]); - } - LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " bbox gave extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; + LL_DEBUGS("RiggedBox") << "updated extents for face " << f + << " bbox gave extents " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; if (!mDrawablep->isActive()) { // Shift position for region LLVector4a offset; offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); - newMin.add(offset); - newMax.add(offset); - LL_DEBUGS("RiggedBox") << "updating extents for face " << f << " not active, added offset " << offset << LL_ENDL; + mExtents[0].add(offset); + mExtents[1].add(offset); + LL_DEBUGS("RiggedBox") << "updating extents for face " << f + << " not active, added offset " << offset << LL_ENDL; } - LL_DEBUGS("RiggedBox") << "updated extents for face " << f << " to " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; + LL_DEBUGS("RiggedBox") << "updated extents for face " << f + << " to " << mExtents[0] << ", " << mExtents[1] << LL_ENDL; LLVector4a t; - t.setAdd(newMin,newMax); + t.setAdd(mExtents[0],mExtents[1]); t.mul(0.5f); mCenterLocal.set(t.getF32ptr()); - t.setSub(newMax,newMin); + t.setSub(mExtents[1],mExtents[0]); mBoundingSphereRadius = t.getLength3().getF32()*0.5f; updateCenterAgent(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 0ea29bae58..277f8e4533 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1277,13 +1277,11 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition(); mDrawable->setPositionGroup(pos_group); } - - } void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { - LLVector4a buffer(0.25f); + LLVector4a buffer(0.0); LLVector4a pos; pos.load3(getRenderPosition().mV); newMin.setSub(pos, buffer); @@ -1312,7 +1310,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); - //stretch bounding box by attachments + //stretch bounding box by static attachments for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -1356,6 +1354,39 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) } } + // Stretch bounding box by rigged mesh joint boxes + for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) + { + LLJoint *joint = getJoint(joint_num); + + // FIXME TEMP HACK FOR TESTING + if (joint) + { + joint->getRiggingInfo().setIsRiggedTo(true); + } + + if (joint && joint->getRiggingInfo().isRiggedTo()) + { + LLViewerJointAttachment *as_joint_attach = dynamic_cast(joint); + if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + { + // Ignore bounding box of HUD joints + continue; + } + LLMatrix4a mat; + LLVector4a new_extents[2]; + mat.loadu(joint->getWorldMatrix()); + matMulBoundBox(mat, joint->getRiggingInfo().getRiggedExtents(), new_extents); + update_min_max(newMin, newMax, new_extents[0]); + update_min_max(newMin, newMax, new_extents[1]); + //if (isSelf()) + //{ + // LL_INFOS() << joint->getName() << " extents " << new_extents[0] << "," << new_extents[1] << LL_ENDL; + // LL_INFOS() << joint->getName() << " av box is " << newMin << "," << newMax << LL_ENDL; + //} + } + } + //pad bounding box newMin.sub(buffer); -- cgit v1.3 From 228525aa27b05cc1aa8be27de4ae59f5ec590ae3 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 4 Jun 2018 14:43:06 +0100 Subject: SL-915 - tracking joint is rigged state --- indra/llcharacter/lljoint.cpp | 53 ---------------------- indra/llcharacter/lljoint.h | 22 --------- indra/llmath/CMakeLists.txt | 2 + indra/llmath/llrigginginfo.cpp | 96 ++++++++++++++++++++++++++++++++++++++++ indra/llmath/llrigginginfo.h | 55 +++++++++++++++++++++++ indra/newview/llskinningutil.cpp | 25 +++++++++++ indra/newview/llskinningutil.h | 4 ++ indra/newview/llviewerobject.h | 5 +++ indra/newview/llvoavatar.cpp | 91 ++++++++++++++++++++++++++++++++++--- indra/newview/llvoavatar.h | 6 +++ indra/newview/llvovolume.cpp | 15 +++++++ indra/newview/llvovolume.h | 3 ++ 12 files changed, 295 insertions(+), 82 deletions(-) create mode 100644 indra/llmath/llrigginginfo.cpp create mode 100644 indra/llmath/llrigginginfo.h (limited to 'indra/llmath') diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 68355cbbdc..07fcd99701 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -96,46 +96,6 @@ void LLVector3OverrideMap::clear() m_map.clear(); } -//----------------------------------------------------------------------------- -// LLJointRiggingInfo -//----------------------------------------------------------------------------- -LLJointRiggingInfo::LLJointRiggingInfo() -{ - mRiggedExtents[0].clear(); - mRiggedExtents[1].clear(); - mIsRiggedTo = false; -} - -bool LLJointRiggingInfo::isRiggedTo() const -{ - return mIsRiggedTo; -} - -void LLJointRiggingInfo::setIsRiggedTo(bool val) -{ - mIsRiggedTo = val; -} - -LLVector4a *LLJointRiggingInfo::getRiggedExtents() -{ - return mRiggedExtents; -} - -const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const -{ - return mRiggedExtents; -} - -// Combine two rigging info states. -// - isRiggedTo if either of the source infos are rigged to -// - box is union of the two sources -void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) -{ - mIsRiggedTo = mIsRiggedTo || other.mIsRiggedTo; - update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]); - update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]); -} - //----------------------------------------------------------------------------- // LLJoint() // Class Constructor @@ -637,19 +597,6 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const } } -//-------------------------------------------------------------------- -// getRiggingInfo() -//-------------------------------------------------------------------- -LLJointRiggingInfo& LLJoint::getRiggingInfo() -{ - return mRiggingInfo; -} - -const LLJointRiggingInfo& LLJoint::getRiggingInfo() const -{ - return mRiggingInfo; -} - //-------------------------------------------------------------------- // updatePos() //-------------------------------------------------------------------- diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index ff1e967188..8112d246f2 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -70,23 +70,6 @@ private: map_type m_map; }; -// Stores information related to associated rigged mesh vertices -// Extents are in joint space -// isRiggedTo is based on the state of all currently associated rigged meshes -class LLJointRiggingInfo -{ -public: - LLJointRiggingInfo(); - bool isRiggedTo() const; - void setIsRiggedTo(bool val); - LLVector4a *getRiggedExtents(); - const LLVector4a *getRiggedExtents() const; - void merge(const LLJointRiggingInfo& other); -private: - LL_ALIGN_16(LLVector4a mRiggedExtents[2]); - bool mIsRiggedTo; -}; - inline bool operator==(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b) { return a.getMap() == b.getMap(); @@ -175,11 +158,6 @@ public: LLVector3OverrideMap m_attachmentScaleOverrides; LLVector3 m_scaleBeforeOverrides; - // Rigging Info - LLJointRiggingInfo mRiggingInfo; - LLJointRiggingInfo& getRiggingInfo(); - const LLJointRiggingInfo& getRiggingInfo() const; - void updatePos(const std::string& av_info); void updateScale(const std::string& av_info); diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index dab566da56..379c3ee9ea 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -25,6 +25,7 @@ set(llmath_SOURCE_FILES lloctree.cpp llperlin.cpp llquaternion.cpp + llrigginginfo.cpp llrect.cpp llsphere.cpp llvector4a.cpp @@ -71,6 +72,7 @@ set(llmath_HEADER_FILES llquaternion2.h llquaternion2.inl llrect.h + llrigginginfo.h llsimdmath.h llsimdtypes.h llsimdtypes.inl diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp new file mode 100644 index 0000000000..925179c2ba --- /dev/null +++ b/indra/llmath/llrigginginfo.cpp @@ -0,0 +1,96 @@ +/** +* @file llrigginginfo.cpp +* @brief Functions for tracking rigged box extents +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llmath.h" +#include "llrigginginfo.h" + +//----------------------------------------------------------------------------- +// LLJointRiggingInfo +//----------------------------------------------------------------------------- +LLJointRiggingInfo::LLJointRiggingInfo() +{ + mRiggedExtents[0].clear(); + mRiggedExtents[1].clear(); + mIsRiggedTo = false; +} + +bool LLJointRiggingInfo::isRiggedTo() const +{ + return mIsRiggedTo; +} + +void LLJointRiggingInfo::setIsRiggedTo(bool val) +{ + mIsRiggedTo = val; +} + +LLVector4a *LLJointRiggingInfo::getRiggedExtents() +{ + return mRiggedExtents; +} + +const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const +{ + return mRiggedExtents; +} + +// Combine two rigging info states. +// - isRiggedTo if either of the source infos are rigged to +// - box is union of the two sources +void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) +{ + if (other.mIsRiggedTo) + { + if (mIsRiggedTo) + { + // Combine existing boxes + update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]); + update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]); + } + else + { + // Initialize box + mIsRiggedTo = true; + mRiggedExtents[0] = other.mRiggedExtents[0]; + mRiggedExtents[1] = other.mRiggedExtents[1]; + } + } +} + +void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src) +{ + // Size should be either LL_CHARACTER_MAX_ANIMATED_JOINTS, or 0 if + // no data. Not necessarily the same for both inputs. + if (src.size() > dst.size()) + { + dst.resize(src.size()); + } + S32 size = llmin(src.size(), dst.size()); + for (S32 i=0; i joint_rig_info_tab; + +void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src); + +#endif diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index dba690242a..7adb2fa8d2 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -216,3 +216,28 @@ void LLSkinningUtil::getPerVertexSkinMatrix( llassert(valid_weights); } +//static +void LLSkinningUtil::initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab) +{ + S32 rigged_count = 0; + rig_info_tab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + S32 joint_num = skin->mJointNums[j]; + if (joint_num != -1) + { + rig_info_tab[joint_num].setIsRiggedTo(true); + rigged_count++; + } + } + //LL_INFOS() << "rigged_count " << rigged_count << LL_ENDL; +} diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 135b25d4d2..3eba3dc93a 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -31,6 +31,9 @@ class LLVOAvatar; class LLMeshSkinInfo; class LLMatrix4a; +#include "llrigginginfo.h" + +// This should probably just be a namespace class LLSkinningUtil { public: @@ -42,6 +45,7 @@ public: static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); + static void initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab); }; #endif diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 9552d4e99e..b9840f629b 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -42,6 +42,7 @@ #include "v3math.h" #include "llvertexbuffer.h" #include "llbbox.h" +#include "llrigginginfo.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -877,6 +878,10 @@ public: BOOL getLastUpdateCached() const; void setLastUpdateCached(BOOL last_update_cached); + virtual void updateRiggingInfo() {} + + joint_rig_info_tab mJointRiggingInfoTab; + private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. EObjectUpdateType mLastUpdateType; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 277f8e4533..50a012ad82 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1355,17 +1355,23 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) } // Stretch bounding box by rigged mesh joint boxes + updateRiggingInfo(); for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { LLJoint *joint = getJoint(joint_num); - - // FIXME TEMP HACK FOR TESTING - if (joint) + LLJointRiggingInfo *rig_info = NULL; + if (joint_num < mJointRiggingInfoTab.size()) { - joint->getRiggingInfo().setIsRiggedTo(true); + rig_info = &mJointRiggingInfoTab[joint_num]; } - if (joint && joint->getRiggingInfo().isRiggedTo()) + // FIXME TEMP HACK FOR TESTING + //if (joint) + //{ + // rig_info.setIsRiggedTo(true); + //} + + if (joint && rig_info && rig_info->isRiggedTo()) { LLViewerJointAttachment *as_joint_attach = dynamic_cast(joint); if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) @@ -1376,7 +1382,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LLMatrix4a mat; LLVector4a new_extents[2]; mat.loadu(joint->getWorldMatrix()); - matMulBoundBox(mat, joint->getRiggingInfo().getRiggedExtents(), new_extents); + matMulBoundBox(mat, rig_info->getRiggedExtents(), new_extents); update_min_max(newMin, newMax, new_extents[0]); update_min_max(newMin, newMax, new_extents[1]); //if (isSelf()) @@ -5777,6 +5783,7 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) return false; } +// AXON update to use LLRiggingInfo bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) { for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -5798,6 +5805,7 @@ bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) return false; } +// AXON update to use LLRiggingInfo bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo) { // Process all children @@ -9420,11 +9428,80 @@ BOOL LLVOAvatar::updateLOD() return res; } -void LLVOAvatar::updateLODRiggedAttachments( void ) +void LLVOAvatar::updateLODRiggedAttachments() { updateLOD(); rebuildRiggedAttachments(); } + +S32 countRigInfoTab(joint_rig_info_tab& tab) +{ + S32 count=0; + for (S32 i=0; isecond; + LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end(); + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin(); + attach_iter != attach_end; ++attach_iter) + { + LLViewerObject* attached_object = *attach_iter; + attached_object->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, attached_object->mJointRiggingInfoTab); + //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + + + LLViewerObject::const_child_list_t& children = attached_object->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; + childp->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + } + } + } + LLControlAvatar *control_av = dynamic_cast(this); + if (control_av) + { + LLVOVolume *volp = control_av->mRootVolp; + if (volp && !volp->isAttachment()) + { + volp->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, volp->mJointRiggingInfoTab); + //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + + LLViewerObject::const_child_list_t& children = volp->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; + childp->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + } + } + } + + //LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; +} + U32 LLVOAvatar::getPartitionType() const { // Avatars merely exist as drawables in the bridge partition diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index cccf857eba..59f88490d0 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -49,6 +49,7 @@ #include "lldriverparam.h" #include "llviewertexlayer.h" #include "material_codes.h" // LL_MCODE_END +#include "llrigginginfo.h" #include "llviewerstats.h" #include "llvovolume.h" #include "llavatarrendernotifier.h" @@ -216,7 +217,12 @@ public: void getAttachmentOverrideNames(std::set& pos_names, std::set& scale_names) const; + // virtual + void updateRiggingInfo(); + std::set mActiveOverrideMeshes; + + /*virtual*/ const LLUUID& getID() const; /*virtual*/ void addDebugText(const std::string& text); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b60ff6d280..321ea22ff9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3564,6 +3564,21 @@ void LLVOVolume::afterReparent() } } +//---------------------------------------------------------------------------- +void LLVOVolume::updateRiggingInfo() +{ + if (isRiggedMesh()) + { + const LLMeshSkinInfo* skin = getSkinInfo(); + LLVOAvatar *avatar = getAvatar(); + if (skin && avatar) + { + LLSkinningUtil::initIsRiggedTo(skin, avatar, mJointRiggingInfoTab); + } + // AXON add bbox processing from volume faces. + } +} + //---------------------------------------------------------------------------- void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index ebf92acc4f..d77c2f231b 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -282,6 +282,9 @@ public: virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent); virtual void afterReparent(); + //virtual + void updateRiggingInfo(); + // Functions that deal with media, or media navigation // Update this object's media data with the given media data array -- cgit v1.3 From 3fcf7a32ee7256ef294c6c01c793f63dfdfb6958 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 5 Jun 2018 15:35:21 +0100 Subject: SL-915 - incremental updates to dynamic bounding box, setting to control detail. --- indra/llmath/llrigginginfo.cpp | 5 + indra/llmath/llvolume.cpp | 5 + indra/llmath/llvolume.h | 5 + indra/newview/app_settings/settings.xml | 11 ++ indra/newview/llskinningutil.cpp | 58 ++++++--- indra/newview/llskinningutil.h | 2 + indra/newview/llvoavatar.cpp | 218 ++++++++++++++++++++------------ indra/newview/llvovolume.cpp | 29 ++++- indra/newview/llvovolume.h | 1 + 9 files changed, 232 insertions(+), 102 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 925179c2ba..18fea2088c 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -27,6 +27,11 @@ #include "llmath.h" #include "llrigginginfo.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif + //----------------------------------------------------------------------------- // LLJointRiggingInfo //----------------------------------------------------------------------------- diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 4613e17605..5aa1f6b44b 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4643,6 +4643,7 @@ LLVolumeFace::LLVolumeFace() : mNumVertices(0), mNumAllocatedVertices(0), mNumIndices(0), + mJointRiggingInfoTabPtr(NULL), mPositions(NULL), mNormals(NULL), mTangents(NULL), @@ -4674,6 +4675,7 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTangents(NULL), mTexCoords(NULL), mIndices(NULL), + mJointRiggingInfoTabPtr(NULL), mWeights(NULL), mWeightsScrubbed(FALSE), mOctree(NULL) @@ -4788,6 +4790,9 @@ void LLVolumeFace::freeData() ll_aligned_free_16(mWeights); mWeights = NULL; + free(mJointRiggingInfoTabPtr); + mJointRiggingInfoTabPtr = NULL; + delete mOctree; mOctree = NULL; } diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 4357b69b90..e92cf0b21f 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -57,6 +57,7 @@ class LLVolumeTriangle; #include "llpointer.h" #include "llfile.h" #include "llalignedarray.h" +#include "llrigginginfo.h" //============================================================================ @@ -958,6 +959,10 @@ public: LLVector4a* mWeights; mutable BOOL mWeightsScrubbed; + + // Which joints are rigged to, and the bounding box of any rigged + // vertices per joint. + joint_rig_info_tab *mJointRiggingInfoTabPtr; LLOctreeNode* mOctree; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cfdf5e546b..ac46106721 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2215,6 +2215,17 @@ Value 0 + AvatarBoundingBoxComplexity + + Comment + How many aspects to consider for avatar bounding box + Persist + 1 + Type + S32 + Value + 3 + DebugAvatarAppearanceMessage Comment diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 7adb2fa8d2..f446c57897 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -31,6 +31,12 @@ #include "llvoavatar.h" #include "llviewercontrol.h" #include "llmeshrepository.h" +#include "llvolume.h" + +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif // static void LLSkinningUtil::initClass() @@ -219,25 +225,47 @@ void LLSkinningUtil::getPerVertexSkinMatrix( //static void LLSkinningUtil::initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab) { - S32 rigged_count = 0; - rig_info_tab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); - for (U32 j = 0; j < skin->mJointNames.size(); ++j) + // AXON REMOVE +} + +//static +void LLSkinningUtil::updateRiggedExtents(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face) +{ + S32 num_verts = vol_face.mNumVertices; + if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0)) { - LLJoint *joint = NULL; - if (skin->mJointNums[j] == -1) + if (!vol_face.mJointRiggingInfoTabPtr) { - joint = avatar->getJoint(skin->mJointNames[j]); - if (joint) + vol_face.mJointRiggingInfoTabPtr = new joint_rig_info_tab(LL_CHARACTER_MAX_ANIMATED_JOINTS); + joint_rig_info_tab& rig_info_tab = *vol_face.mJointRiggingInfoTabPtr; + for (S32 i=0; imJointNums[j] = joint->getJointNum(); + LLVector4a& pos = vol_face.mPositions[i]; + F32 *w = vol_face.mWeights[i].getF32ptr(); + for (U32 k=0; k<4; ++k) + { + S32 joint_index = llfloor(w[k]); + S32 joint_num = skin->mJointNums[joint_index]; + if (joint_num != -1) + { + rig_info_tab[joint_num].setIsRiggedTo(true); + + // AXON can precompute that matMuls. + LLMatrix4a bind_shape; + bind_shape.loadu(skin->mBindShapeMatrix); + LLMatrix4a inv_bind; + inv_bind.loadu(skin->mInvBindMatrix[joint_index]); + LLMatrix4a mat; + matMul(bind_shape, inv_bind, mat); + LLVector4a pos_joint_space; + mat.affineTransform(pos, pos_joint_space); + LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); + update_min_max(extents[0], extents[1], pos_joint_space); + } + } } - } - S32 joint_num = skin->mJointNums[j]; - if (joint_num != -1) - { - rig_info_tab[joint_num].setIsRiggedTo(true); - rigged_count++; + LL_DEBUGS("RigSpammish") << "updated rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices << LL_ENDL; } } - //LL_INFOS() << "rigged_count " << rigged_count << LL_ENDL; } diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 3eba3dc93a..5fd8a08d7a 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -30,6 +30,7 @@ class LLVOAvatar; class LLMeshSkinInfo; class LLMatrix4a; +class LLVolumeFace; #include "llrigginginfo.h" @@ -46,6 +47,7 @@ public: static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); static void initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab); + static void updateRiggedExtents(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); }; #endif diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 50a012ad82..bbb0f732a1 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -112,6 +112,11 @@ #include +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif + extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; extern F32 ANIM_SPEED_MAX; @@ -1281,6 +1286,7 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { + S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); LLVector4a buffer(0.0); LLVector4a pos; pos.load3(getRenderPosition().mV); @@ -1290,106 +1296,115 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) float max_attachment_span = get_default_max_prim_scale() * 5.0f; //stretch bounding box by joint positions - for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) - { - LLPolyMesh* mesh = i->second; - for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++) - { - LLVector4a trans; - trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); - update_min_max(newMin, newMax, trans); - } - } + if (box_detail>=1) + { + for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) + { + LLPolyMesh* mesh = i->second; + for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++) + { + LLVector4a trans; + trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); + update_min_max(newMin, newMax, trans); + } + } - LLVector4a center, size; - center.setAdd(newMin, newMax); - center.mul(0.5f); + LLVector4a center, size; + center.setAdd(newMin, newMax); + center.mul(0.5f); - size.setSub(newMax,newMin); - size.mul(0.5f); + size.setSub(newMax,newMin); + size.mul(0.5f); - mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + mPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + } //stretch bounding box by static attachments - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; + if (box_detail >= 2) + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; - if (attachment->getValid()) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) - { - LLDrawable* drawable = attached_object->mDrawable; - if (drawable && !drawable->isState(LLDrawable::RIGGED)) - { - LLSpatialBridge* bridge = drawable->getSpatialBridge(); - if (bridge) - { - const LLVector4a* ext = bridge->getSpatialExtents(); - LLVector4a distance; - distance.setSub(ext[1], ext[0]); - LLVector4a max_span(max_attachment_span); + if (attachment->getValid()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable && !drawable->isState(LLDrawable::RIGGED)) + { + LLSpatialBridge* bridge = drawable->getSpatialBridge(); + if (bridge) + { + const LLVector4a* ext = bridge->getSpatialExtents(); + LLVector4a distance; + distance.setSub(ext[1], ext[0]); + LLVector4a max_span(max_attachment_span); - S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; + S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; - // Only add the prim to spatial extents calculations if it isn't a megaprim. - // max_attachment_span calculated at the start of the function - // (currently 5 times our max prim size) - if (lt == 0x7) - { - update_min_max(newMin,newMax,ext[0]); - update_min_max(newMin,newMax,ext[1]); - } - } - } - } - } - } - } + // Only add the prim to spatial extents calculations if it isn't a megaprim. + // max_attachment_span calculated at the start of the function + // (currently 5 times our max prim size) + if (lt == 0x7) + { + update_min_max(newMin,newMax,ext[0]); + update_min_max(newMin,newMax,ext[1]); + } + } + } + } + } + } + } + } // Stretch bounding box by rigged mesh joint boxes - updateRiggingInfo(); - for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) + if (box_detail>=3) { - LLJoint *joint = getJoint(joint_num); - LLJointRiggingInfo *rig_info = NULL; - if (joint_num < mJointRiggingInfoTab.size()) - { - rig_info = &mJointRiggingInfoTab[joint_num]; - } - - // FIXME TEMP HACK FOR TESTING - //if (joint) - //{ - // rig_info.setIsRiggedTo(true); - //} - - if (joint && rig_info && rig_info->isRiggedTo()) + updateRiggingInfo(); + for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { - LLViewerJointAttachment *as_joint_attach = dynamic_cast(joint); - if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + LLJoint *joint = getJoint(joint_num); + LLJointRiggingInfo *rig_info = NULL; + if (joint_num < mJointRiggingInfoTab.size()) { - // Ignore bounding box of HUD joints - continue; + rig_info = &mJointRiggingInfoTab[joint_num]; } - LLMatrix4a mat; - LLVector4a new_extents[2]; - mat.loadu(joint->getWorldMatrix()); - matMulBoundBox(mat, rig_info->getRiggedExtents(), new_extents); - update_min_max(newMin, newMax, new_extents[0]); - update_min_max(newMin, newMax, new_extents[1]); - //if (isSelf()) + + // FIXME TEMP HACK FOR TESTING + //if (joint) //{ - // LL_INFOS() << joint->getName() << " extents " << new_extents[0] << "," << new_extents[1] << LL_ENDL; - // LL_INFOS() << joint->getName() << " av box is " << newMin << "," << newMax << LL_ENDL; + // rig_info.setIsRiggedTo(true); //} + + if (joint && rig_info && rig_info->isRiggedTo()) + { + LLViewerJointAttachment *as_joint_attach = dynamic_cast(joint); + if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + { + // Ignore bounding box of HUD joints + continue; + } + LLMatrix4a mat; + LLVector4a new_extents[2]; + mat.loadu(joint->getWorldMatrix()); + matMulBoundBox(mat, rig_info->getRiggedExtents(), new_extents); + update_min_max(newMin, newMax, new_extents[0]); + update_min_max(newMin, newMax, new_extents[1]); + //if (isSelf()) + //{ + // LL_INFOS() << joint->getName() << " extents " << new_extents[0] << "," << new_extents[1] << LL_ENDL; + // LL_INFOS() << joint->getName() << " av box is " << newMin << "," << newMax << LL_ENDL; + //} + } } } @@ -9447,6 +9462,28 @@ S32 countRigInfoTab(joint_rig_info_tab& tab) return count; } +void showRigInfoTabExtents(LLVOAvatar *avatar, joint_rig_info_tab& tab, S32& count_rigged, S32& count_box) +{ + count_rigged = count_box = 0; + LLVector4a zero_vec; + zero_vec.clear(); + for (S32 i=0; igetJoint(i); + LL_DEBUGS("RigSpam") << "joint " << i << " name " << joint->getName() << " box " + << tab[i].getRiggedExtents()[0] << ", " << tab[i].getRiggedExtents()[1] << LL_ENDL; + if ((!tab[i].getRiggedExtents()[0].equals3(zero_vec)) || + (!tab[i].getRiggedExtents()[1].equals3(zero_vec))) + { + count_box++; + } + } + } +} + // virtual void LLVOAvatar::updateRiggingInfo() { @@ -9485,6 +9522,10 @@ void LLVOAvatar::updateRiggingInfo() { volp->updateRiggingInfo(); mergeRigInfoTab(mJointRiggingInfoTab, volp->mJointRiggingInfoTab); + LL_DEBUGS("RigSpammish") << getFullname() << " after cav update rig tab:" << LL_ENDL; + S32 joint_count, box_count; + showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; LLViewerObject::const_child_list_t& children = volp->getChildren(); @@ -9494,12 +9535,21 @@ void LLVOAvatar::updateRiggingInfo() LLViewerObject *childp = *it; childp->updateRiggingInfo(); mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + + LL_DEBUGS("RigSpammish") << getFullname() << " after cav child update rig tab:" << LL_ENDL; + S32 joint_count, box_count; + showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; } } } //LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL; + S32 joint_count, box_count; + showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); + LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; } U32 LLVOAvatar::getPartitionType() const diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 321ea22ff9..81852cd878 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -85,6 +85,11 @@ #include "llviewerinventory.h" #include "llcallstack.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +// AXON to remove +#pragma optimize("", off) +#endif + const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; @@ -230,6 +235,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mLastFetchedMediaVersion = -1; memset(&mIndexInTex, 0, sizeof(S32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS); mMDCImplCount = 0; + mLastRiggingInfoLOD = -1; } LLVOVolume::~LLVOVolume() @@ -3571,11 +3577,28 @@ void LLVOVolume::updateRiggingInfo() { const LLMeshSkinInfo* skin = getSkinInfo(); LLVOAvatar *avatar = getAvatar(); - if (skin && avatar) + if (skin && avatar && getLOD()>mLastRiggingInfoLOD) { - LLSkinningUtil::initIsRiggedTo(skin, avatar, mJointRiggingInfoTab); + LLVolume *volume = getVolume(); + if (volume) + { + mJointRiggingInfoTab.clear(); + for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) + { + LLVolumeFace& vol_face = volume->getVolumeFace(f); + LLSkinningUtil::updateRiggedExtents(skin, avatar, vol_face); + if (vol_face.mJointRiggingInfoTabPtr) + { + mergeRigInfoTab(mJointRiggingInfoTab, *vol_face.mJointRiggingInfoTabPtr); + } + } + // Keep the highest LOD info available. + // AXON would this ever need to be forced to refresh? Set to -1 if so. + mLastRiggingInfoLOD = getLOD(); + LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " + << this << " lod " << mLastRiggingInfoLOD << LL_ENDL; + } } - // AXON add bbox processing from volume faces. } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d77c2f231b..2ba73b9d86 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -284,6 +284,7 @@ public: //virtual void updateRiggingInfo(); + S32 mLastRiggingInfoLOD; // Functions that deal with media, or media navigation -- cgit v1.3 From b269b531706f2490f143bb675398d7c53e2254af Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 5 Jun 2018 19:54:30 +0100 Subject: SL-915 - alignment/optimization changes --- indra/llmath/llrigginginfo.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index 18da905abb..7b36880a39 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -30,8 +30,11 @@ #ifndef LL_LLRIGGINGINFO_H #define LL_LLRIGGINGINFO_H +#include "llvector4a.h" + // Extents are in joint space // isRiggedTo is based on the state of all currently associated rigged meshes +LL_ALIGN_PREFIX(16) class LLJointRiggingInfo { public: @@ -44,7 +47,7 @@ public: private: LL_ALIGN_16(LLVector4a mRiggedExtents[2]); bool mIsRiggedTo; -}; +} LL_ALIGN_POSTFIX(16); // For storing all the rigging info associated with a given avatar or // object, keyed by joint_num. -- cgit v1.3 From 1c62165a2b920c5381e846a5b6d600644d3fb648 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 5 Jun 2018 20:35:48 +0100 Subject: SL-915 - removed no optimize pragmas --- indra/llmath/llrigginginfo.cpp | 5 ----- indra/newview/llskinningutil.cpp | 5 ----- indra/newview/llvoavatar.cpp | 5 ----- indra/newview/llvovolume.cpp | 5 ----- 4 files changed, 20 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 18fea2088c..925179c2ba 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -27,11 +27,6 @@ #include "llmath.h" #include "llrigginginfo.h" -#ifndef LL_RELEASE_FOR_DOWNLOAD -// AXON to remove -#pragma optimize("", off) -#endif - //----------------------------------------------------------------------------- // LLJointRiggingInfo //----------------------------------------------------------------------------- diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index f446c57897..f4298ede23 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -33,11 +33,6 @@ #include "llmeshrepository.h" #include "llvolume.h" -#ifndef LL_RELEASE_FOR_DOWNLOAD -// AXON to remove -#pragma optimize("", off) -#endif - // static void LLSkinningUtil::initClass() { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index bbb0f732a1..93e470e0fb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -112,11 +112,6 @@ #include -#ifndef LL_RELEASE_FOR_DOWNLOAD -// AXON to remove -#pragma optimize("", off) -#endif - extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; extern F32 ANIM_SPEED_MAX; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 81852cd878..997af104c7 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -85,11 +85,6 @@ #include "llviewerinventory.h" #include "llcallstack.h" -#ifndef LL_RELEASE_FOR_DOWNLOAD -// AXON to remove -#pragma optimize("", off) -#endif - const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; -- cgit v1.3 From 430f9420cf0094635b0b0428a29ff7dfaf5718e8 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 7 Jun 2018 22:18:15 +0100 Subject: SL-915 - more on dynamic extent tracking, possible fix for 32-bit crash issues --- indra/llcommon/llerror.cpp | 9 +++-- indra/llmath/llrigginginfo.cpp | 78 ++++++++++++++++++++++++++++++++++++---- indra/llmath/llrigginginfo.h | 32 +++++++++++++++-- indra/llmath/llvolume.cpp | 12 +++---- indra/llmath/llvolume.h | 2 +- indra/newview/llskinningutil.cpp | 54 ++++++++++++++++++++++++---- indra/newview/llskinningutil.h | 1 + indra/newview/llviewerobject.h | 2 +- indra/newview/llvoavatar.cpp | 61 ++++++++++++++++--------------- indra/newview/llvoavatar.h | 4 +-- indra/newview/llvovolume.cpp | 52 +++++++++++++++++++++++---- 11 files changed, 245 insertions(+), 62 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f31a054139..916555a71d 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -51,6 +51,10 @@ #include "llstl.h" #include "lltimer.h" +//#if LL_WINDOWS +//#pragma optimize("", off) +//#endif + namespace { #if LL_WINDOWS void debugger_print(const std::string& s) @@ -361,6 +365,7 @@ namespace } } + LL_INFOS("LogControlFile") << "logging reconfiguring from " << filename() << LL_ENDL; LLError::configure(configuration); LL_INFOS("LogControlFile") << "logging reconfigured from " << filename() << LL_ENDL; return true; @@ -1292,7 +1297,7 @@ namespace LLError #if LL_WINDOWS // VC80 was optimizing the error away. - #pragma optimize("", off) +// #pragma optimize("", off) #endif void crashAndLoop(const std::string& message) { @@ -1310,7 +1315,7 @@ namespace LLError exit(EXIT_FAILURE); } #if LL_WINDOWS - #pragma optimize("", on) +// #pragma optimize("", on) #endif std::string utcTime() diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 925179c2ba..73e1b096cb 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -27,6 +27,10 @@ #include "llmath.h" #include "llrigginginfo.h" +//#if LL_WINDOWS +//#pragma optimize("", off) +//#endif + //----------------------------------------------------------------------------- // LLJointRiggingInfo //----------------------------------------------------------------------------- @@ -80,17 +84,79 @@ void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) } } -void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src) +LLJointRiggingInfoTab::LLJointRiggingInfoTab(): + mRigInfoPtr(NULL), + mSize(0) +{ +} + +LLJointRiggingInfoTab::~LLJointRiggingInfoTab() +{ + clear(); +} + +// This doesn't preserve data if the size changes. In practice +// this doesn't matter because the size is always either +// LL_CHARACTER_MAX_ANIMATED_JOINTS or 0. +void LLJointRiggingInfoTab::resize(S32 size) +{ + if (size != mSize) + { + clear(); + if (size > 0) + { + mRigInfoPtr = new LLJointRiggingInfo[size]; + mSize = size; + } + } +} + +void LLJointRiggingInfoTab::clear() { + if (mRigInfoPtr) + { + delete[](mRigInfoPtr); + mRigInfoPtr = NULL; + mSize = 0; + } +} + +void showDetails(const LLJointRiggingInfoTab& src, const std::string& str) +{ + S32 count_rigged = 0; + S32 count_box = 0; + LLVector4a zero_vec; + zero_vec.clear(); + for (S32 i=0; i dst.size()) + if (src.size() > size()) { - dst.resize(src.size()); + resize(src.size()); } - S32 size = llmin(src.size(), dst.size()); - for (S32 i=0; i joint_rig_info_tab; +// Using direct memory management instead of std::vector<> to avoid alignment issues. +class LLJointRiggingInfoTab +{ +public: + LLJointRiggingInfoTab(); + ~LLJointRiggingInfoTab(); + void resize(S32 size); + void clear(); + S32 size() const { return mSize; } + void merge(const LLJointRiggingInfoTab& src); + LLJointRiggingInfo& operator[](S32 i) { return mRigInfoPtr[i]; } + const LLJointRiggingInfo& operator[](S32 i) const { return mRigInfoPtr[i]; }; +private: + // Not implemented + LLJointRiggingInfoTab& operator=(const LLJointRiggingInfoTab& src); + LLJointRiggingInfoTab(const LLJointRiggingInfoTab& src); -void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src); + LLJointRiggingInfo *mRigInfoPtr; + S32 mSize; +}; #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8f08394ce9..2654e204c2 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4644,7 +4644,6 @@ LLVolumeFace::LLVolumeFace() : mNumVertices(0), mNumAllocatedVertices(0), mNumIndices(0), - mJointRiggingInfoTabPtr(NULL), mPositions(NULL), mNormals(NULL), mTangents(NULL), @@ -4676,7 +4675,6 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTangents(NULL), mTexCoords(NULL), mIndices(NULL), - mJointRiggingInfoTabPtr(NULL), mWeights(NULL), mWeightsScrubbed(FALSE), mOctree(NULL) @@ -4791,9 +4789,6 @@ void LLVolumeFace::freeData() ll_aligned_free_16(mWeights); mWeights = NULL; - free(mJointRiggingInfoTabPtr); - mJointRiggingInfoTabPtr = NULL; - delete mOctree; mOctree = NULL; } @@ -4955,7 +4950,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) // if (new_face.mNumVertices <= mNumVertices) { - llassert(new_face.mNumIndices == mNumIndices); + llassert(new_face.mNumIndices == mNumIndices); swapData(new_face); } @@ -6292,6 +6287,9 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mNumVertices = num_verts; mNumAllocatedVertices = num_verts; + + // Force update + mJointRiggingInfoTab.clear(); } void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) @@ -6413,6 +6411,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, } } +// AXON appendFace/appendFaces not used - referenced by corresponding functions in +// LLModel but these are not called anywhere. void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMatrix4& norm_mat_in) { U16 offset = mNumVertices; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index d518bcf3ef..f92b43e77d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -962,7 +962,7 @@ public: // Which joints are rigged to, and the bounding box of any rigged // vertices per joint. - joint_rig_info_tab *mJointRiggingInfoTabPtr; + LLJointRiggingInfoTab mJointRiggingInfoTab; LLOctreeNode* mOctree; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 14abe9d89a..6484775c40 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -34,6 +34,10 @@ #include "llvolume.h" #include "llrigginginfo.h" +//#if LL_WINDOWS +//#pragma optimize("", off) +//#endif + void LLSkinningUtil::initClass() { } @@ -211,15 +215,36 @@ void LLSkinningUtil::getPerVertexSkinMatrix( llassert(valid_weights); } +// AXON need to remember this has been done +void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) +{ + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + } +} + void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face) { + // AXON cast + initJointNums(const_cast(skin), avatar); S32 num_verts = vol_face.mNumVertices; if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0)) { - if (!vol_face.mJointRiggingInfoTabPtr) + if (vol_face.mJointRiggingInfoTab.size()==0) { - vol_face.mJointRiggingInfoTabPtr = new joint_rig_info_tab(LL_CHARACTER_MAX_ANIMATED_JOINTS); - joint_rig_info_tab& rig_info_tab = *vol_face.mJointRiggingInfoTabPtr; + std::set active_joints; + S32 active_verts = 0; + vol_face.mJointRiggingInfoTab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); + LLJointRiggingInfoTab &rig_info_tab = vol_face.mJointRiggingInfoTab; for (S32 i=0; imJointNums[joint_index]; - if (joint_num != -1) + if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) { rig_info_tab[joint_num].setIsRiggedTo(true); + active_joints.insert(joint_num); + active_verts++; - // AXON can precompute that matMuls. + // AXON can precompute these matMuls. LLMatrix4a bind_shape; bind_shape.loadu(skin->mBindShapeMatrix); LLMatrix4a inv_bind; @@ -246,8 +273,21 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a } } } - LL_DEBUGS("RigSpammish") << "updated rigging info for vf " << &vol_face - << " num_verts " << vol_face.mNumVertices << LL_ENDL; + LL_DEBUGS("RigSpammish") << "built rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices + << " active joints " << active_joints.size() + << " active verts " << active_verts + << LL_ENDL; } } + if (vol_face.mJointRiggingInfoTab.size()!=0) + { + LL_DEBUGS("RigSpammish") << "we have rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices << LL_ENDL; + } + else + { + LL_DEBUGS("RigSpammish") << "no rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices << LL_ENDL; + } } diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 47e12f8adc..e730ef014b 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -42,6 +42,7 @@ namespace LLSkinningUtil void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); + void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar); void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); }; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index eac3f1bbe8..d6c8b76147 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -881,7 +881,7 @@ public: virtual void updateRiggingInfo() {} - joint_rig_info_tab mJointRiggingInfoTab; + LLJointRiggingInfoTab mJointRiggingInfoTab; private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 93e470e0fb..8c3a180570 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -671,7 +671,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mCachedInMuteList(false), mIsControlAvatar(false), mIsUIAvatar(false), - mEnableDefaultMotions(true) + mEnableDefaultMotions(true), + mRiggingInfoNeedsUpdate(true) { LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; @@ -1279,8 +1280,12 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) } } +static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Avatar Update Extent"); + void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { + LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); + S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); LLVector4a buffer(0.0); LLVector4a pos; @@ -1364,7 +1369,13 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) // Stretch bounding box by rigged mesh joint boxes if (box_detail>=3) { - updateRiggingInfo(); + // AXON try to cache unless something has changed about attached rigged meshes. + // Needs more logic based on volume states. + //if (mRiggingInfoNeedsUpdate) + { + updateRiggingInfo(); + mRiggingInfoNeedsUpdate = false; + } for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { LLJoint *joint = getJoint(joint_num); @@ -5854,8 +5865,6 @@ void LLVOAvatar::clearAttachmentOverrides() { LLScopedContextString str("clearAttachmentOverrides " + getFullname()); - mActiveOverrideMeshes.clear(); - for (S32 i=0; i=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; if ( fullRig && !mesh_overrides_loaded ) { - mActiveOverrideMeshes.insert(mesh_id); - for ( int i=0; imJointNames[i].c_str(); @@ -6174,6 +6184,8 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::setupdateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, attached_object->mJointRiggingInfoTab); + mJointRiggingInfoTab.merge(attached_object->mJointRiggingInfoTab); //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; @@ -9504,7 +9504,7 @@ void LLVOAvatar::updateRiggingInfo() { LLViewerObject *childp = *it; childp->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + mJointRiggingInfoTab.merge(childp->mJointRiggingInfoTab); //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; } } @@ -9515,9 +9515,8 @@ void LLVOAvatar::updateRiggingInfo() LLVOVolume *volp = control_av->mRootVolp; if (volp && !volp->isAttachment()) { - volp->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, volp->mJointRiggingInfoTab); - LL_DEBUGS("RigSpammish") << getFullname() << " after cav update rig tab:" << LL_ENDL; + mJointRiggingInfoTab.merge(volp->mJointRiggingInfoTab); + LL_DEBUGS("RigSpammish") << getFullname() << " mRootVolp " << control_av->mRootVolp << " after cav update rig tab:" << LL_ENDL; S32 joint_count, box_count; showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; @@ -9529,7 +9528,7 @@ void LLVOAvatar::updateRiggingInfo() { LLViewerObject *childp = *it; childp->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + mJointRiggingInfoTab.merge(childp->mJointRiggingInfoTab); LL_DEBUGS("RigSpammish") << getFullname() << " after cav child update rig tab:" << LL_ENDL; S32 joint_count, box_count; @@ -9547,6 +9546,12 @@ void LLVOAvatar::updateRiggingInfo() LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; } +// virtual +void LLVOAvatar::onActiveOverrideMeshesChanged() +{ + mRiggingInfoNeedsUpdate = true; +} + U32 LLVOAvatar::getPartitionType() const { // Avatars merely exist as drawables in the bridge partition diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 59f88490d0..924b361f59 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -219,10 +219,10 @@ public: // virtual void updateRiggingInfo(); + bool mRiggingInfoNeedsUpdate; std::set mActiveOverrideMeshes; - - + virtual void onActiveOverrideMeshesChanged(); /*virtual*/ const LLUUID& getID() const; /*virtual*/ void addDebugText(const std::string& text); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2f2a28daff..70c4efb5b8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3597,26 +3597,64 @@ void LLVOVolume::updateRiggingInfo() { const LLMeshSkinInfo* skin = getSkinInfo(); LLVOAvatar *avatar = getAvatar(); - if (skin && avatar && getLOD()>mLastRiggingInfoLOD) + LLVolume *volume = getVolume(); + if (skin && avatar && volume) { - LLVolume *volume = getVolume(); - if (volume) + LL_DEBUGS("RigSpammish") << "starting, vovol " << this << " lod " << getLOD() << " last " << mLastRiggingInfoLOD << LL_ENDL; + // AXON SPAM + for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) { + LLVolumeFace& vol_face = volume->getVolumeFace(f); + if (vol_face.mJointRiggingInfoTab.size()>0) + { + LL_DEBUGS("RigSpammish") << "vovol " << this << " lod " << getLOD() << " face " << f << " vf " << &vol_face << " has rig info" << LL_ENDL; + } + else + { + LL_DEBUGS("RigSpammish") << "vovol " << this << " lod " << getLOD() << " face " << f << " vf " << &vol_face << " needs update" << LL_ENDL; + } + } + // We maintain rigging info based on the highest LOD + // handled so far. Need to update if either the LOD is + // the same but some faces need to be updated, or if + // the LOD has increased. + bool any_face_needs_rebuild = false; + if (getLOD()==mLastRiggingInfoLOD) + { + // See if any volume face needs its rigging info built. + for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) + { + LLVolumeFace& vol_face = volume->getVolumeFace(f); + if (vol_face.mJointRiggingInfoTab.size()==0) + { + // AXON this is overkill since some faces don't contain any valid weights/rigged verts. + any_face_needs_rebuild = true; + break; + } + } + } + + //if (getLOD()>mLastRiggingInfoLOD || + // (getLOD()==mLastRiggingInfoLOD && any_face_needs_rebuild)) + if (getLOD()==3) + { + // Rigging info has changed mJointRiggingInfoTab.clear(); for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) { LLVolumeFace& vol_face = volume->getVolumeFace(f); LLSkinningUtil::updateRiggingInfo(skin, avatar, vol_face); - if (vol_face.mJointRiggingInfoTabPtr) + if (vol_face.mJointRiggingInfoTab.size()>0) { - mergeRigInfoTab(mJointRiggingInfoTab, *vol_face.mJointRiggingInfoTabPtr); + mJointRiggingInfoTab.merge(vol_face.mJointRiggingInfoTab); } } // Keep the highest LOD info available. - // AXON would this ever need to be forced to refresh? Set to -1 if so. mLastRiggingInfoLOD = getLOD(); LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " - << this << " lod " << mLastRiggingInfoLOD << LL_ENDL; + << this << " lod " << mLastRiggingInfoLOD + << " any faces rebuilt? " << any_face_needs_rebuild + << LL_ENDL; } } } -- cgit v1.3 From f30d95ee5feaa3a20ec2f7091324d21179edbbba Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 8 Jun 2018 14:19:46 +0100 Subject: SL-915 - more on alignment for 32-bit --- indra/llmath/llrigginginfo.cpp | 3 ++- indra/llmath/llrigginginfo.h | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'indra/llmath') diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 73e1b096cb..885acb7670 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -86,7 +86,8 @@ void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) LLJointRiggingInfoTab::LLJointRiggingInfoTab(): mRigInfoPtr(NULL), - mSize(0) + mSize(0), + mNeedsUpdate(true) { } diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index b09746a5b7..b3d6bc2d19 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -55,6 +55,17 @@ public: ll_aligned_free_16(ptr); } + void* operator new[](size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete[](void* ptr) + { + ll_aligned_free_16(ptr); + } + + private: LL_ALIGN_16(LLVector4a mRiggedExtents[2]); bool mIsRiggedTo; @@ -74,6 +85,8 @@ public: void merge(const LLJointRiggingInfoTab& src); LLJointRiggingInfo& operator[](S32 i) { return mRigInfoPtr[i]; } const LLJointRiggingInfo& operator[](S32 i) const { return mRigInfoPtr[i]; }; + bool needsUpdate() { return mNeedsUpdate; } + void setNeedsUpdate(bool val) { mNeedsUpdate = val; } private: // Not implemented LLJointRiggingInfoTab& operator=(const LLJointRiggingInfoTab& src); @@ -81,6 +94,7 @@ private: LLJointRiggingInfo *mRigInfoPtr; S32 mSize; + bool mNeedsUpdate; }; #endif -- cgit v1.3 From edf6795edaa4ec822ac0e2bc906c71606b84b5c8 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 13 Jun 2018 21:49:24 +0100 Subject: SL-915, MAINT-8554 - cleanup/reorg, added encroachment fix info to DebugAnimatedObjects output --- indra/llcommon/llerror.cpp | 4 +- indra/llmath/llrigginginfo.cpp | 4 -- indra/llmath/llvolume.cpp | 95 --------------------------------------- indra/llmath/llvolume.h | 2 - indra/llmath/v3math.cpp | 36 +++++++++++++++ indra/llmath/v3math.h | 2 + indra/llprimitive/llmodel.cpp | 34 -------------- indra/llprimitive/llmodel.h | 3 -- indra/newview/llcontrolavatar.cpp | 55 +++++------------------ indra/newview/llmeshrepository.h | 1 - indra/newview/llskinningutil.cpp | 4 -- indra/newview/llvoavatar.cpp | 84 +++++----------------------------- indra/newview/llvoavatar.h | 5 ++- 13 files changed, 65 insertions(+), 264 deletions(-) (limited to 'indra/llmath') diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f81030b0e7..d0e7c06f36 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1293,7 +1293,7 @@ namespace LLError #if LL_WINDOWS // VC80 was optimizing the error away. -// #pragma optimize("", off) + #pragma optimize("", off) #endif void crashAndLoop(const std::string& message) { @@ -1311,7 +1311,7 @@ namespace LLError exit(EXIT_FAILURE); } #if LL_WINDOWS -// #pragma optimize("", on) + #pragma optimize("", on) #endif std::string utcTime() diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 885acb7670..0de07950c1 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -27,10 +27,6 @@ #include "llmath.h" #include "llrigginginfo.h" -//#if LL_WINDOWS -//#pragma optimize("", off) -//#endif - //----------------------------------------------------------------------------- // LLJointRiggingInfo //----------------------------------------------------------------------------- diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2654e204c2..ba284574c8 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6411,101 +6411,6 @@ void LLVolumeFace::fillFromLegacyData(std::vector& v, } } -// AXON appendFace/appendFaces not used - referenced by corresponding functions in -// LLModel but these are not called anywhere. -void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMatrix4& norm_mat_in) -{ - U16 offset = mNumVertices; - - S32 new_count = face.mNumVertices + mNumVertices; - - if (new_count > 65536) - { - LL_ERRS() << "Cannot append face -- 16-bit overflow will occur." << LL_ENDL; - } - - if (face.mNumVertices == 0) - { - LL_ERRS() << "Cannot append empty face." << LL_ENDL; - } - - U32 old_vsize = mNumVertices*16; - U32 new_vsize = new_count * 16; - U32 old_tcsize = (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; - U32 new_tcsize = (new_count*sizeof(LLVector2)+0xF) & ~0xF; - U32 new_size = new_vsize * 2 + new_tcsize; - - //allocate new buffer space - LLVector4a* old_buf = mPositions; - mPositions = (LLVector4a*) ll_aligned_malloc<64>(new_size); - mNormals = mPositions + new_count; - mTexCoords = (LLVector2*) (mNormals+new_count); - - mNumAllocatedVertices = new_count; - - LLVector4a::memcpyNonAliased16((F32*) mPositions, (F32*) old_buf, old_vsize); - LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) (old_buf+mNumVertices), old_vsize); - LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) (old_buf+mNumVertices*2), old_tcsize); - - mNumVertices = new_count; - - //get destination address of appended face - LLVector4a* dst_pos = mPositions+offset; - LLVector2* dst_tc = mTexCoords+offset; - LLVector4a* dst_norm = mNormals+offset; - - //get source addresses of appended face - const LLVector4a* src_pos = face.mPositions; - const LLVector2* src_tc = face.mTexCoords; - const LLVector4a* src_norm = face.mNormals; - - //load aligned matrices - LLMatrix4a mat, norm_mat; - mat.loadu(mat_in); - norm_mat.loadu(norm_mat_in); - - for (U32 i = 0; i < face.mNumVertices; ++i) - { - //transform appended face position and store - mat.affineTransform(src_pos[i], dst_pos[i]); - - //transform appended face normal and store - norm_mat.rotate(src_norm[i], dst_norm[i]); - dst_norm[i].normalize3fast(); - - //copy appended face texture coordinate - dst_tc[i] = src_tc[i]; - - if (offset == 0 && i == 0) - { //initialize bounding box - // VFExtents change - mExtents[0] = mExtents[1] = dst_pos[i]; - } - else - { - //stretch bounding box - // VFExtents change - update_min_max(mExtents[0], mExtents[1], dst_pos[i]); - } - } - LL_DEBUGS("RiggedBox") << "appendFace got extents " << mExtents[0] << ", " << mExtents[1] << " from dst_pos " << LL_ENDL; - - - new_count = mNumIndices + face.mNumIndices; - - //allocate new index buffer - mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF, (mNumIndices*sizeof(U16)+0xF) & ~0xF); - - //get destination address into new index buffer - U16* dst_idx = mIndices+mNumIndices; - mNumIndices = new_count; - - for (U32 i = 0; i < face.mNumIndices; ++i) - { //copy indices, offsetting by old vertex count - dst_idx[i] = face.mIndices[i]+offset; - } -} - BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) { LL_CHECK_MEMORY diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index f92b43e77d..1d6d35c432 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -872,8 +872,6 @@ public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); void createTangents(); - void appendFace(const LLVolumeFace& face, LLMatrix4& transform, LLMatrix4& normal_tranform); - void resizeVertices(S32 num_verts); void allocateTangents(S32 num_verts); void allocateWeights(S32 num_verts); diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index e7107dee16..b04c67d926 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -369,3 +369,39 @@ BOOL LLVector3::parseVector3(const std::string& buf, LLVector3* value) return FALSE; } + +// Displacement from query point to nearest neighbor point on bounding box. +// Returns zero vector for points within or on the box. +LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box) +{ + LLVector3 offset; + for (S32 k=0; k<3; k++) + { + offset[k] = 0; + if (pos[k] < box[0][k]) + { + offset[k] = pos[k] - box[0][k]; + } + else if (pos[k] > box[1][k]) + { + offset[k] = pos[k] - box[1][k]; + } + } + return offset; +} + +bool box_valid_and_non_zero(const LLVector3* box) +{ + if (!box[0].isFinite() || !box[1].isFinite()) + { + return false; + } + LLVector3 zero_vec; + zero_vec.clear(); + if ((box[0] != zero_vec) || (box[1] != zero_vec)) + { + return true; + } + return false; +} + diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index f3fbce4843..6f857d7061 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -163,6 +163,8 @@ LLVector3 inverse_projected_vec(const LLVector3 &a, const LLVector3 &b); // Retu LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec) LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec) LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b +LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box); // Displacement from query point to nearest point on bounding box. +bool box_valid_and_non_zero(const LLVector3* box); inline LLVector3::LLVector3(void) { diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 2a55838a4b..a0e835c577 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -401,40 +401,6 @@ void LLModel::setVolumeFaceData( LLVector4a::memcpyNonAliased16((F32*) face.mIndices, (F32*) ind.get(), size); } -void LLModel::appendFaces(LLModel *model, LLMatrix4 &transform, LLMatrix4& norm_mat) -{ - if (mVolumeFaces.empty()) - { - setNumVolumeFaces(1); - } - - LLVolumeFace& face = mVolumeFaces[mVolumeFaces.size()-1]; - - - for (S32 i = 0; i < model->getNumFaces(); ++i) - { - face.appendFace(model->getVolumeFace(i), transform, norm_mat); - } - -} - -void LLModel::appendFace(const LLVolumeFace& src_face, std::string src_material, LLMatrix4& mat, LLMatrix4& norm_mat) -{ - S32 rindex = getNumVolumeFaces()-1; - if (rindex == -1 || - mVolumeFaces[rindex].mNumVertices + src_face.mNumVertices >= 65536) - { //empty or overflow will occur, append new face - LLVolumeFace cur_face; - cur_face.appendFace(src_face, mat, norm_mat); - addFace(cur_face); - mMaterialList.push_back(src_material); - } - else - { //append to existing end face - mVolumeFaces.rbegin()->appendFace(src_face, mat, norm_mat); - } -} - void LLModel::addFace(const LLVolumeFace& face) { if (face.mNumVertices == 0) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index d7f006753f..cf3288489a 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -158,9 +158,6 @@ public: EModelStatus getStatus() const {return mStatus;} static std::string getStatusString(U32 status) ; - void appendFaces(LLModel* model, LLMatrix4& transform, LLMatrix4& normal_transform); - void appendFace(const LLVolumeFace& src_face, std::string src_material, LLMatrix4& mat, LLMatrix4& norm_mat); - void setNumVolumeFaces(S32 count); void setVolumeFaceData( S32 f, diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 8291df7705..36e728f26d 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -34,10 +34,6 @@ #include "llmeshrepository.h" #include "llviewerregion.h" -#if LL_WINDOWS - #pragma optimize("", off) -#endif - LLControlAvatar::LLControlAvatar(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp) : LLVOAvatar(id, pcode, regionp), mPlaying(false), @@ -68,41 +64,6 @@ void LLControlAvatar::initInstance() hideSkirt(); } -// AXON move to math -bool box_valid_and_non_zero(const LLVector3* box) -{ - if (!box[0].isFinite() || !box[1].isFinite()) - { - return false; - } - LLVector3 zero_vec; - zero_vec.clear(); - if ((box[0] != zero_vec) || (box[1] != zero_vec)) - { - return true; - } - return false; -} - -// AXON move to math -LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box) -{ - LLVector3 offset; - for (S32 k=0; k<3; k++) - { - offset[k] = 0; - if (pos[k] < box[0][k]) - { - offset[k] = pos[k] - box[0][k]; - } - else if (pos[k] > box[1][k]) - { - offset[k] = pos[k] - box[1][k]; - } - } - return offset; -} - void LLControlAvatar::matchVolumeTransform() { if (mRootVolp) @@ -157,11 +118,11 @@ void LLControlAvatar::matchVolumeTransform() F32 target_dist = (offset_dist - MAX_LEGAL_OFFSET); pos_box_offset *= target_dist/offset_dist; } - LL_DEBUGS("FixBox") << getFullname() << " fixup needed for offset " - << pos_box_offset[0] << "," << pos_box_offset[1] << "," << pos_box_offset[2] - << " current fixup " - << mPositionConstraintFixup[0] << "," << mPositionConstraintFixup[1] << "," << mPositionConstraintFixup[2] - << " dist " << offset_dist << LL_ENDL; + //LL_DEBUGS("FixBox") << getFullname() << " fixup needed for offset " + // << pos_box_offset[0] << "," << pos_box_offset[1] << "," << pos_box_offset[2] + // << " current fixup " + // << mPositionConstraintFixup[0] << "," << mPositionConstraintFixup[1] << "," << mPositionConstraintFixup[2] + // << " dist " << offset_dist << LL_ENDL; } mPositionConstraintFixup = pos_box_offset; @@ -380,6 +341,12 @@ void LLControlAvatar::updateDebugText() addDebugText(llformat("flags %s", animated_object_flag_string.c_str())); addDebugText(llformat("tris %d (est %.1f, streaming %.1f), verts %d", total_tris, est_tris, est_streaming_tris, total_verts)); addDebugText(llformat("pxarea %s rank %d", LLStringOps::getReadableNumber(getPixelArea()).c_str(), getVisibilityRank())); + if (mPositionConstraintFixup.length() > 0.0f) + { + addDebugText(llformat("pos fix (%.1f %.1f %.1f)", + mPositionConstraintFixup[0], mPositionConstraintFixup[1], mPositionConstraintFixup[2])); + } + #if 0 std::string region_name = "no region"; if (mRootVolp->getRegion()) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index df8f5c5ff4..cb3903b1d0 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -652,7 +652,6 @@ public: extern LLMeshRepository gMeshRepo; -// AXON make sure this is consistent with the final simulator-side values. const F32 ANIMATED_OBJECT_BASE_COST = 15.0f; const F32 ANIMATED_OBJECT_COST_PER_KTRI = 1.5f; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index db9877f302..0878cee1a3 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -34,10 +34,6 @@ #include "llvolume.h" #include "llrigginginfo.h" -//#if LL_WINDOWS -//#pragma optimize("", off) -//#endif - void LLSkinningUtil::initClass() { } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 6896632597..728155382f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1346,7 +1346,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) attachment_iter != attachment->mAttachedObjects.end(); ++attachment_iter) { - // AXON is this right? Don't we need to look at children of attached_object as well? + // AXON Don't we need to look at children of attached_object as well? const LLViewerObject* attached_object = (*attachment_iter); if (attached_object && !attached_object->isHUDAttachment()) { @@ -1389,10 +1389,11 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { // AXON try to cache unless something has changed about attached rigged meshes. // Needs more logic based on volume states. + //if (mRiggingInfoTab.needsUpdate()) { updateRiggingInfo(); - mJointRiggingInfoTab.setNeedsUpdate(false); + //mJointRiggingInfoTab.setNeedsUpdate(false); } for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { @@ -1403,12 +1404,6 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) rig_info = &mJointRiggingInfoTab[joint_num]; } - // FIXME TEMP HACK FOR TESTING - //if (joint) - //{ - // rig_info.setIsRiggedTo(true); - //} - if (joint && rig_info && rig_info->isRiggedTo()) { LLViewerJointAttachment *as_joint_attach = dynamic_cast(joint); @@ -1574,7 +1569,7 @@ void LLVOAvatar::renderBones() } else { - if (jointIsRiggedTo(jointp->getName())) + if (jointIsRiggedTo(jointp)) { occ_color = RIGGED_COLOR_OCCLUDED; visible_color = RIGGED_COLOR_VISIBLE; @@ -2702,7 +2697,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) { ext[0].load3(mLastAnimExtents[0].mV); ext[1].load3(mLastAnimExtents[1].mV); - // AXON just do this once per frame + // Expensive. Just call this once per frame, in updateSpatialExtents(); //calculateSpatialExtents(ext[0], ext[1]); LLVector4a diff; diff.setSub(ext[1], mImpostorExtents[1]); @@ -5827,73 +5822,17 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) return false; } -// AXON update to use LLRiggingInfo -bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) +bool LLVOAvatar::jointIsRiggedTo(const LLJoint *joint) const { - LLJoint *joint = getJoint(joint_name); if (joint) { - LLJointRiggingInfoTab& tab = mJointRiggingInfoTab; + const LLJointRiggingInfoTab& tab = mJointRiggingInfoTab; S32 joint_num = joint->getJointNum(); if (joint_num < tab.size() && tab[joint_num].isRiggedTo()) { return true; } } - return false; -#if 0 - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && jointIsRiggedTo(joint_name, attached_object)) - { - return true; - } - } - } - return false; -#endif -} - -// AXON update to use LLRiggingInfo -bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo) -{ - // Process all children - LLViewerObject::const_child_list_t& children = vo->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); - it != children.end(); ++it) - { - LLViewerObject *childp = *it; - if (jointIsRiggedTo(joint_name,childp)) - { - return true; - } - } - - const LLVOVolume *vobj = dynamic_cast(vo); - if (!vobj) - { - return false; - } - - const LLMeshSkinInfo* pSkinData = vobj->getSkinInfo(); - - if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData ) - { - if (std::find(pSkinData->mJointNames.begin(), pSkinData->mJointNames.end(), joint_name) != - pSkinData->mJointNames.end()) - { - return true; - } - } - return false; } @@ -9554,10 +9493,9 @@ void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& } } -// AXON move to member -void getAssociatedVolumes(LLVOAvatar *av, std::vector& volumes) +void LLVOAvatar::getAssociatedVolumes(std::vector& volumes) { - for ( LLVOAvatar::attachment_map_t::iterator iter = av->mAttachmentPoints.begin(); iter != av->mAttachmentPoints.end(); ++iter ) + for ( LLVOAvatar::attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter ) { LLViewerJointAttachment* attachment = iter->second; LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end(); @@ -9584,7 +9522,7 @@ void getAssociatedVolumes(LLVOAvatar *av, std::vector& volumes) } } } - LLControlAvatar *control_av = dynamic_cast(av); + LLControlAvatar *control_av = dynamic_cast(this); if (control_av) { LLVOVolume *volp = control_av->mRootVolp; @@ -9612,7 +9550,7 @@ void LLVOAvatar::updateRiggingInfo() LL_DEBUGS("RigSpammish") << getFullname() << " updating rig tab" << LL_ENDL; mJointRiggingInfoTab.clear(); std::vector volumes; - getAssociatedVolumes(this, volumes); + getAssociatedVolumes(volumes); for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) { LLVOVolume *vol = *it; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index d80f0ad713..25c89f96d7 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -208,8 +208,7 @@ public: void addAttachmentOverridesForObject(LLViewerObject *vo, std::set* meshes_seen = NULL, bool recursive = true); void removeAttachmentOverridesForObject(const LLUUID& mesh_id); void removeAttachmentOverridesForObject(LLViewerObject *vo); - bool jointIsRiggedTo(const std::string& joint_name); - bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo); + bool jointIsRiggedTo(const LLJoint *joint) const; void clearAttachmentOverrides(); void rebuildAttachmentOverrides(); void updateAttachmentOverrides(); @@ -217,6 +216,8 @@ public: void getAttachmentOverrideNames(std::set& pos_names, std::set& scale_names) const; + void getAssociatedVolumes(std::vector& volumes); + // virtual void updateRiggingInfo(); -- cgit v1.3