summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llcontrolavatar.cpp78
-rw-r--r--indra/newview/llcontrolavatar.h2
-rw-r--r--indra/newview/llskinningutil.cpp1
-rw-r--r--indra/newview/llvoavatar.cpp11
-rw-r--r--indra/newview/llvoavatar.h1
-rw-r--r--indra/newview/llvovolume.cpp40
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;
}
}