diff options
Diffstat (limited to 'indra/llcharacter/lljoint.cpp')
-rw-r--r-- | indra/llcharacter/lljoint.cpp | 469 |
1 files changed, 423 insertions, 46 deletions
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 8fa08a2a6c..a3d5679f65 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -32,6 +32,8 @@ #include "lljoint.h" #include "llmath.h" +#include "llcallstack.h" +#include <boost/algorithm/string.hpp> S32 LLJoint::sNumUpdates = 0; S32 LLJoint::sNumTouches = 0; @@ -42,7 +44,7 @@ bool attachment_map_iter_compare_key(const T& a, const T& b) return a.first < b.first; } -bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const +bool LLVector3OverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const { pos = LLVector3(0,0,0); mesh_id = LLUUID(); @@ -60,7 +62,7 @@ bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const return found; } -void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const +void LLVector3OverrideMap::showJointVector3Overrides( std::ostringstream& os ) const { map_type::const_iterator max_it = std::max_element(m_map.begin(), m_map.end(), @@ -73,23 +75,23 @@ void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const } } -U32 LLPosOverrideMap::count() const +U32 LLVector3OverrideMap::count() const { return m_map.size(); } -void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) +void LLVector3OverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) { m_map[mesh_id] = pos; } -bool LLPosOverrideMap::remove(const LLUUID& mesh_id) +bool LLVector3OverrideMap::remove(const LLUUID& mesh_id) { U32 remove_count = m_map.erase(mesh_id); return (remove_count > 0); } -void LLPosOverrideMap::clear() +void LLVector3OverrideMap::clear() { m_map.clear(); } @@ -108,6 +110,8 @@ void LLJoint::init() mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; mUpdateXform = TRUE; + mSupport = SUPPORT_BASE; + mEnd = LLVector3(0.0f, 0.0f, 0.0f); } LLJoint::LLJoint() : @@ -124,13 +128,12 @@ LLJoint::LLJoint(S32 joint_num) : touch(); } - //----------------------------------------------------------------------------- // LLJoint() // Class Constructor //----------------------------------------------------------------------------- LLJoint::LLJoint(const std::string &name, LLJoint *parent) : - mJointNum(0) + mJointNum(-2) { init(); mUpdateXform = FALSE; @@ -170,6 +173,27 @@ void LLJoint::setup(const std::string &name, LLJoint *parent) } //----------------------------------------------------------------------------- +// setSupport() +//----------------------------------------------------------------------------- +void LLJoint::setSupport(const std::string& support_name) +{ + if (support_name == "extended") + { + setSupport(SUPPORT_EXTENDED); + } + else if (support_name == "base") + { + setSupport(SUPPORT_BASE); + } + else + { + LL_WARNS() << "unknown support string " << support_name << LL_ENDL; + setSupport(SUPPORT_BASE); + } +} + + +//----------------------------------------------------------------------------- // touch() // Sets all dirty flags for all children, recursively. //----------------------------------------------------------------------------- @@ -195,6 +219,18 @@ void LLJoint::touch(U32 flags) } //----------------------------------------------------------------------------- +// setJointNum() +//----------------------------------------------------------------------------- +void LLJoint::setJointNum(S32 joint_num) +{ + mJointNum = joint_num; + if (mJointNum + 2 >= LL_CHARACTER_MAX_ANIMATED_JOINTS) + { + LL_INFOS() << "LL_CHARACTER_MAX_ANIMATED_JOINTS needs to be increased" << LL_ENDL; + LL_ERRS() << "joint_num " << joint_num << " + 2 is too large for " << LL_CHARACTER_MAX_ANIMATED_JOINTS << LL_ENDL; + } +} +//----------------------------------------------------------------------------- // getRoot() //----------------------------------------------------------------------------- LLJoint *LLJoint::getRoot() @@ -290,43 +326,119 @@ const LLVector3& LLJoint::getPosition() bool do_debug_joint(const std::string& name) { - return false; + if (std::find(LLJoint::s_debugJointNames.begin(), LLJoint::s_debugJointNames.end(),name) != LLJoint::s_debugJointNames.end()) + { + return true; + } + return false; } //-------------------------------------------------------------------- // setPosition() //-------------------------------------------------------------------- -void LLJoint::setPosition( const LLVector3& pos ) +void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment_overrides ) { - if (pos != getPosition()) + LLVector3 pos(requested_pos); + + LLVector3 active_override; + LLUUID mesh_id; + if (apply_attachment_overrides && m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override)) + { + if (pos != active_override && do_debug_joint(getName())) + { + LLScopedContextString str("setPosition"); + LL_DEBUGS("Avatar") << " joint " << getName() << " requested_pos " << requested_pos + << " overriden by attachment " << active_override << LL_ENDL; + } + pos = active_override; + } + if ((pos != getPosition()) && do_debug_joint(getName())) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; - } + LLScopedContextString str("setPosition"); + LLCallStack cs; + LLContextStatus con_status; + LL_DEBUGS("Avatar") << " joint " << getName() << " set pos " << pos << LL_ENDL; + LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << "====================" << LL_ENDL; + LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } - mXform.setPosition(pos); - touch(MATRIX_DIRTY | POSITION_DIRTY); + if (pos != getPosition()) + { + mXform.setPosition(pos); + touch(MATRIX_DIRTY | POSITION_DIRTY); + } +} + +void LLJoint::setDefaultPosition( const LLVector3& pos ) +{ + mDefaultPosition = pos; +} + +const LLVector3& LLJoint::getDefaultPosition() const +{ + return mDefaultPosition; +} + +void LLJoint::setDefaultScale( const LLVector3& scale ) +{ + mDefaultScale = scale; +} + +const LLVector3& LLJoint::getDefaultScale() const +{ + return mDefaultScale; } void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) { std::ostringstream os; os << joint.m_posBeforeOverrides; - joint.m_attachmentOverrides.showJointPosOverrides(os); + joint.m_attachmentPosOverrides.showJointVector3Overrides(os); + LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; +} + +void showJointScaleOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) +{ + std::ostringstream os; + os << joint.m_scaleBeforeOverrides; + joint.m_attachmentScaleOverrides.showJointVector3Overrides(os); LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; } +bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const +{ + LLVector3 diff = pos - getDefaultPosition(); + const F32 max_joint_pos_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset; +} + +bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const +{ + LLVector3 diff = scale - getDefaultScale(); + const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm + return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; +} + //-------------------------------------------------------------------- // addAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } - if (!m_attachmentOverrides.count()) + // BENTO + // Not clear pelvis overrides are meaningful/useful. + //if (mName == "mPelvis") + //{ + // return; + //} + + LLVector3 before_pos; + LLUUID before_mesh_id; + bool has_active_override_before = hasAttachmentPosOverride( before_pos, before_mesh_id ); + if (!m_attachmentPosOverrides.count()) { if (do_debug_joint(getName())) { @@ -334,32 +446,50 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh } m_posBeforeOverrides = getPosition(); } - m_attachmentOverrides.add(mesh_id,pos); - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; - } - updatePos(av_info); + m_attachmentPosOverrides.add(mesh_id,pos); + LLVector3 after_pos; + LLUUID after_mesh_id; + hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_before || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentPosOverride for mesh " << mesh_id << " pos " << pos << LL_ENDL; + } + updatePos(av_info); + } } //-------------------------------------------------------------------- // removeAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info ) +void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info, bool& active_override_changed ) { + active_override_changed = false; if (mesh_id.isNull()) { return; } - if (m_attachmentOverrides.remove(mesh_id)) + LLVector3 before_pos; + LLUUID before_mesh_id; + hasAttachmentPosOverride( before_pos, before_mesh_id ); + if (m_attachmentPosOverrides.remove(mesh_id)) { - if (do_debug_joint(getName())) - { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() - << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; - showJointPosOverrides(*this, "remove", av_info); - } - updatePos(av_info); + LLVector3 after_pos; + LLUUID after_mesh_id; + bool has_active_override_after = hasAttachmentPosOverride(after_pos, after_mesh_id); + if (!has_active_override_after || (after_pos != before_pos)) + { + active_override_changed = true; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentPosOverride for " << mesh_id << LL_ENDL; + showJointPosOverrides(*this, "remove", av_info); + } + updatePos(av_info); + } } } @@ -368,7 +498,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str //-------------------------------------------------------------------- bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const { - return m_attachmentOverrides.findActiveOverride(mesh_id,pos); + return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos); } //-------------------------------------------------------------------- @@ -376,11 +506,81 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const //-------------------------------------------------------------------- void LLJoint::clearAttachmentPosOverrides() { - if (m_attachmentOverrides.count()) + if (m_attachmentPosOverrides.count()) { - m_attachmentOverrides.clear(); + m_attachmentPosOverrides.clear(); setPosition(m_posBeforeOverrides); - setId( LLUUID::null ); + } +} + +//-------------------------------------------------------------------- +// getAllAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::getAllAttachmentPosOverrides(S32& num_pos_overrides, + std::set<LLVector3>& distinct_pos_overrides) +{ + num_pos_overrides = m_attachmentPosOverrides.count(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + for (; it != m_attachmentPosOverrides.getMap().end(); ++it) + { + distinct_pos_overrides.insert(it->second); + } +} + +//-------------------------------------------------------------------- +// getAllAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::getAllAttachmentScaleOverrides(S32& num_scale_overrides, + std::set<LLVector3>& distinct_scale_overrides) +{ + num_scale_overrides = m_attachmentScaleOverrides.count(); + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) + { + distinct_scale_overrides.insert(it->second); + } +} + +//-------------------------------------------------------------------- +// showAttachmentPosOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const +{ + LLVector3 active_override; + bool has_active_override; + LLUUID mesh_id; + has_active_override = m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override); + U32 count = m_attachmentPosOverrides.count(); + if (count==1) + { + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " has single attachment pos override " << highlight << "" << it->second << " default " << mDefaultPosition << LL_ENDL; + } + else if (count>1) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment pos overrides" << LL_ENDL; + std::set<LLVector3> distinct_offsets; + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); + for (; it != m_attachmentPosOverrides.getMap().end(); ++it) + { + distinct_offsets.insert(it->second); + } + if (distinct_offsets.size()>1) + { + LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; + } + std::set<LLVector3>::iterator dit = distinct_offsets.begin(); + for ( ; dit != distinct_offsets.end(); ++dit) + { + std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; + LL_DEBUGS("Avatar") << " POS " << highlight << "" << (*dit) << " default " << mDefaultPosition << LL_ENDL; + } } } @@ -391,20 +591,178 @@ void LLJoint::updatePos(const std::string& av_info) { LLVector3 pos, found_pos; LLUUID mesh_id; - if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos)) + if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos)) { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentPosOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; + } pos = found_pos; } else { - LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + } pos = m_posBeforeOverrides; } setPosition(pos); } //-------------------------------------------------------------------- +// updateScale() +//-------------------------------------------------------------------- +void LLJoint::updateScale(const std::string& av_info) +{ + LLVector3 scale, found_scale; + LLUUID mesh_id; + if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner of " << m_attachmentScaleOverrides.count() << " is mesh " << mesh_id << " scale " << found_scale << LL_ENDL; + } + scale = found_scale; + } + else + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner is scaleBeforeOverrides " << m_scaleBeforeOverrides << LL_ENDL; + } + scale = m_scaleBeforeOverrides; + } + setScale(scale); +} + +//-------------------------------------------------------------------- +// addAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ) +{ + if (mesh_id.isNull()) + { + return; + } + if (!m_attachmentScaleOverrides.count()) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL; + } + m_scaleBeforeOverrides = getScale(); + } + m_attachmentScaleOverrides.add(mesh_id,scale); + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL; + } + updateScale(av_info); +} + +//-------------------------------------------------------------------- +// removeAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ) +{ + if (mesh_id.isNull()) + { + return; + } + if (m_attachmentScaleOverrides.remove(mesh_id)) + { + if (do_debug_joint(getName())) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL; + showJointScaleOverrides(*this, "remove", av_info); + } + updateScale(av_info); + } +} + +//-------------------------------------------------------------------- + // hasAttachmentScaleOverride() + //-------------------------------------------------------------------- +bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const +{ + return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale); +} + +//-------------------------------------------------------------------- +// clearAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::clearAttachmentScaleOverrides() +{ + if (m_attachmentScaleOverrides.count()) + { + m_attachmentScaleOverrides.clear(); + setScale(m_scaleBeforeOverrides); + } +} + +//-------------------------------------------------------------------- +// showAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const +{ + LLVector3 active_override; + bool has_active_override; + LLUUID mesh_id; + has_active_override = m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override); + U32 count = m_attachmentScaleOverrides.count(); + if (count==1) + { + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() + << " has single attachment scale override " << highlight << "" << it->second << " default " << mDefaultScale << LL_ENDL; + } + else if (count>1) + { + LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment scale overrides" << LL_ENDL; + std::set<LLVector3> distinct_offsets; + LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); + for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) + { + distinct_offsets.insert(it->second); + } + if (distinct_offsets.size()>1) + { + LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; + } + else + { + LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; + } + std::set<LLVector3>::iterator dit = distinct_offsets.begin(); + for ( ; dit != distinct_offsets.end(); ++dit) + { + std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; + LL_DEBUGS("Avatar") << " POS " << highlight << "" << (*dit) << " default " << mDefaultScale << LL_ENDL; + } + } +} + +// init static +LLJoint::debug_joint_name_t LLJoint::s_debugJointNames = debug_joint_name_t(); + +//-------------------------------------------------------------------- +// setDebugJointNames +//-------------------------------------------------------------------- +void LLJoint::setDebugJointNames(const debug_joint_name_t& names) +{ + s_debugJointNames = names; +} +void LLJoint::setDebugJointNames(const std::string& names_string) +{ + debug_joint_name_t names; + boost::split(names, names_string, boost::is_any_of(" :,")); + setDebugJointNames(names); +} + +//-------------------------------------------------------------------- // getWorldPosition() //-------------------------------------------------------------------- LLVector3 LLJoint::getWorldPosition() @@ -529,13 +887,32 @@ const LLVector3& LLJoint::getScale() //-------------------------------------------------------------------- // setScale() //-------------------------------------------------------------------- -void LLJoint::setScale( const LLVector3& scale ) +void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_overrides ) { -// if (mXform.getScale() != scale) + LLVector3 scale(requested_scale); + LLUUID mesh_id; + LLVector3 active_override; + if (apply_attachment_overrides && m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override)) + { + if (scale != active_override && do_debug_joint(getName())) + { + LLScopedContextString str("setScale"); + LL_DEBUGS("Avatar") << " joint " << getName() << " requested_scale " << requested_scale + << " overriden by attachment " << active_override << LL_ENDL; + } + scale = active_override; + } + if ((mXform.getScale() != scale) && do_debug_joint(getName())) { - mXform.setScale(scale); - touch(); + LLScopedContextString str("setScale"); + LLCallStack cs; + LLContextStatus con_status; + LL_DEBUGS("Avatar") << " joint " << getName() << " set scale " << scale << LL_ENDL; + LL_DEBUGS("Avatar") << "CONTEXT:\n" << "====================\n" << con_status << LL_ENDL; + LL_DEBUGS("Avatar") << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; } + mXform.setScale(scale); + touch(); } |