diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llcontrolavatar.cpp | 78 | ||||
-rw-r--r-- | indra/newview/llcontrolavatar.h | 2 | ||||
-rw-r--r-- | indra/newview/llskinningutil.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 11 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 1 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 40 |
6 files changed, 88 insertions, 45 deletions
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 5a1add258c..8291df7705 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -34,6 +34,10 @@ #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), @@ -64,6 +68,41 @@ 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) @@ -92,12 +131,47 @@ void LLControlAvatar::matchVolumeTransform() } else { - setPositionAgent(mRootVolp->getRenderPosition()); + + LLVector3 vol_pos = mRootVolp->getRenderPosition(); + LLVector3 pos_box_offset; + pos_box_offset.clear(); + + // Fix up position if needed to prevent visual encroachment + if (box_valid_and_non_zero(getLastAnimExtents())) // wait for state to settle down + { + const F32 MAX_LEGAL_OFFSET = 2.0; + + // The goal here is to ensure that the extent of the avatar's + // bounding box does not wander too far from the + // official position of the corresponding volume. We + // do this by tracking the distance and applying a + // correction to the control avatar position if + // needed. + LLVector3 uncorrected_extents[2]; + uncorrected_extents[0] = getLastAnimExtents()[0] - mPositionConstraintFixup; + uncorrected_extents[1] = getLastAnimExtents()[1] - mPositionConstraintFixup; + pos_box_offset = point_to_box_offset(vol_pos, uncorrected_extents); + F32 offset_dist = pos_box_offset.length(); + if (offset_dist > MAX_LEGAL_OFFSET) + { + 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; + } + + mPositionConstraintFixup = pos_box_offset; + + setPositionAgent(vol_pos + mPositionConstraintFixup); LLQuaternion obj_rot = mRootVolp->getRotation(); LLQuaternion result_rot = obj_rot; setRotation(result_rot); mRoot->setWorldRotation(result_rot); - mRoot->setPosition(mRootVolp->getRenderPosition()); + mRoot->setPosition(vol_pos + mPositionConstraintFixup); } } } diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index 02244769b9..c72dc03efc 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -80,6 +80,8 @@ public: bool mMarkedForDeath; + LLVector3 mPositionConstraintFixup; + }; typedef std::map<LLUUID, S32> signaled_animation_map_t; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 8a499f77cd..db9877f302 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -204,7 +204,6 @@ void LLSkinningUtil::getPerVertexSkinMatrix( llassert(valid_weights); } -// AXON need to remember this has been done void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) { if (!skin->mJointNumsInitialized) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7a138b26a4..6896632597 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1296,14 +1296,16 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); - LLVector4a buffer(0.0); + LLVector4a buffer(0.1); LLVector4a pos; - pos.load3(getRenderPosition().mV); + pos.load3(mPelvisp->getWorldPosition().mV); newMin.setSub(pos, buffer); newMax.setAdd(pos, buffer); - //stretch bounding box by joint positions - if (box_detail>=1) + //stretch bounding box by joint positions. No point doing this for + //control avs, where the polymeshes aren't maintained or + //displayed. + if (box_detail>=1 && !isControlAvatar()) { for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) { @@ -1316,6 +1318,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) } } + // AXON shouldn't this section be after all the detail levels? LLVector4a center, size; center.setAdd(newMin, newMax); center.mul(0.5f); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 42b04ef870..d80f0ad713 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -525,6 +525,7 @@ public: static void updateImpostors(); LLRenderTarget mImpostor; BOOL mNeedsImpostorUpdate; + const LLVector3* getLastAnimExtents() const { return mLastAnimExtents; } private: LLVector3 mImpostorOffset; LLVector2 mImpostorDim; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3387f718df..7f353ea8aa 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3604,44 +3604,9 @@ void LLVOVolume::updateRiggingInfo() if (skin && avatar && volume) { LL_DEBUGS("RigSpammish") << "starting, vovol " << this << " lod " << getLOD() << " last " << mLastRiggingInfoLOD << LL_ENDL; - // AXON SPAM - for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) + if (getLOD()>mLastRiggingInfoLOD || getLOD()==3) { - 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 + // Rigging info may need update mJointRiggingInfoTab.clear(); for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) { @@ -3656,7 +3621,6 @@ void LLVOVolume::updateRiggingInfo() mLastRiggingInfoLOD = getLOD(); LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " << this << " lod " << mLastRiggingInfoLOD - << " any faces rebuilt? " << any_face_needs_rebuild << LL_ENDL; } } |