From 5610444d6450d5eb2e203be527116fe01d2d436a Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 19 Jul 2017 22:21:08 +0100 Subject: SL-714 - fixes to get wireframes to display consistently when right-clicking on animated objects. --- indra/newview/lldrawable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index f956023358..61ebf947dd 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -550,7 +550,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled) if (isState(ACTIVE) && !isState(ACTIVE_CHILD) && !mVObjp->isAttachment() && - !mVObjp->isFlexible()) + !mVObjp->isFlexible() && + !mVObjp->isAnimatedObject()) { clearState(ACTIVE | ANIMATED_CHILD); -- cgit v1.3 From 30880e062afa0671b166f161ae7c109bfd37d38f Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 21 Jul 2017 20:01:40 +0100 Subject: SL-751, SL-691 - test lsl scripts update, better syncing between skeleton and drawable --- indra/newview/lldrawable.cpp | 6 ++++ indra/newview/llviewerobject.cpp | 4 --- scripts/testing/lsl/axon_test_region_driver.lsl | 8 ++--- .../lsl/move_in_circle_using_llSetRegionPos.lsl | 39 +++++++++++----------- 4 files changed, 29 insertions(+), 28 deletions(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 61ebf947dd..8001486b53 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -50,6 +50,7 @@ #include "llviewerobjectlist.h" #include "llviewerwindow.h" #include "llvocache.h" +#include "llcontrolavatar.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f; @@ -697,6 +698,11 @@ F32 LLDrawable::updateXform(BOOL undamped) mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!) mXform.updateMatrix(); + if (mVObjp && mVObjp->isRootEdit() && mVObjp->getControlAvatar()) + { + mVObjp->getControlAvatar()->matchVolumeTransform(); + } + if (mSpatialBridge) { gPipeline.markMoved(mSpatialBridge, FALSE); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cb9f9e0455..e2fbac023a 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4062,10 +4062,6 @@ void LLViewerObject::setPosition(const LLVector3 &pos, BOOL damped) // position caches need to be up to date on root objects updatePositionCaches(); } - if (getControlAvatar() && isRootEdit()) - { - getControlAvatar()->matchVolumeTransform(); - } } void LLViewerObject::setPositionGlobal(const LLVector3d &pos_global, BOOL damped) diff --git a/scripts/testing/lsl/axon_test_region_driver.lsl b/scripts/testing/lsl/axon_test_region_driver.lsl index dfcbb9871a..dcf146a9cf 100644 --- a/scripts/testing/lsl/axon_test_region_driver.lsl +++ b/scripts/testing/lsl/axon_test_region_driver.lsl @@ -1,4 +1,4 @@ -list buttons = ["anim start", "anim stop", " ", "verbose on", "verbose off", " "]; +list buttons = ["anim start", "anim stop", "step", "verbose on", "verbose off", " "]; string dialogInfo = "\nPlease make a choice."; key ToucherID; @@ -20,7 +20,7 @@ default llListenRemove(listenHandle); listenHandle = llListen(dialogChannel, "", ToucherID, ""); llDialog(ToucherID, dialogInfo, buttons, dialogChannel); - llSetTimerEvent(60.0); // Here we set a time limit for responses + //llSetTimerEvent(60.0); // Here we set a time limit for responses } listen(integer channel, string name, key id, string message) @@ -35,7 +35,7 @@ default // stop timer since the menu was clicked llSetTimerEvent(0); - llOwnerSay("Sending message " + message + " on channel " + (string)commandChannel); + //llOwnerSay("Sending message " + message + " on channel " + (string)commandChannel); llRegionSay(commandChannel, message); } @@ -45,7 +45,7 @@ default llSetTimerEvent(0); llListenRemove(listenHandle); - llWhisper(0, "Sorry. You snooze; you lose."); + //llWhisper(0, "Sorry. You snooze; you lose."); } } diff --git a/scripts/testing/lsl/move_in_circle_using_llSetRegionPos.lsl b/scripts/testing/lsl/move_in_circle_using_llSetRegionPos.lsl index 5303b6f4f5..fa12ab0588 100644 --- a/scripts/testing/lsl/move_in_circle_using_llSetRegionPos.lsl +++ b/scripts/testing/lsl/move_in_circle_using_llSetRegionPos.lsl @@ -1,6 +1,6 @@ integer listenHandle; integer verbose; -integer num_steps = 50; +integer num_steps = 12; float circle_time = 5.0; integer circle_step; vector circle_pos; @@ -14,12 +14,21 @@ start_circle(vector center, float radius) circle_radius = radius; circle_step = 0; llSetTimerEvent(circle_time/num_steps); + llTargetOmega(<0.0, 0.0, 1.0>, TWO_PI/circle_time, 1.0); } stop_circle() { llSetTimerEvent(0); - llSetRegionPos(circle_center); + llTargetOmega(<0.0, 0.0, 1.0>, TWO_PI/circle_time, 0.0); + integer i; + for (i=0; i<10; i++) + { + vector new_pos = circle_center; + new_pos.x += llFrand(0.01); + llSetRegionPos(new_pos); + llSleep(0.1); + } } next_circle() @@ -32,34 +41,19 @@ next_circle() circle_step = (circle_step+1)%num_steps; } -circle_path(vector center, float radius) -{ - integer i; - integer num_steps = 50; - float circle_time = 5.0; // seconds - for (i=0; i); - llSleep(circle_time/num_steps); - } -} - default { state_entry() { - llSay(0, "Hello, Avatar!"); + //llSay(0, "Hello, Avatar!"); listenHandle = llListen(-2001,"","",""); verbose = 0; + circle_center = llGetPos(); } listen(integer channel, string name, key id, string message) { - llOwnerSay("got message " + name + " " + (string) id + " " + message); + //llOwnerSay("got message " + name + " " + (string) id + " " + message); list words = llParseString2List(message,[" "],[]); string command = llList2String(words,0); string option = llList2String(words,1); @@ -85,6 +79,11 @@ default verbose = 0; } } + if (command=="step") + { + llSetTimerEvent(0); + next_circle(); + } } timer() -- cgit v1.3 From 2aa890da0bd8b42493745daa736c5ed9451bbf91 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 8 Sep 2017 16:05:49 +0100 Subject: SL-718 - better support for transforms of animated attachments --- indra/newview/llcontrolavatar.cpp | 46 ++++++++++++++++++++++------ indra/newview/lldrawable.cpp | 5 --- indra/newview/llviewerobject.cpp | 9 ++++-- indra/newview/llviewerobjectlist.cpp | 6 ++-- indra/newview/llvoavatar.cpp | 59 +++++++++++++++++++++++++----------- indra/newview/llvoavatar.h | 2 +- 6 files changed, 89 insertions(+), 38 deletions(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index d458e2951b..172816b3e3 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -50,6 +50,8 @@ LLControlAvatar::~LLControlAvatar() void LLControlAvatar::matchVolumeTransform() { +#if 0 + // AXON - should we be using bind_shape? { LLVolume *volume = mRootVolp->getVolume(); if (volume) @@ -63,16 +65,40 @@ void LLControlAvatar::matchVolumeTransform() } } } - - setPositionAgent(mRootVolp->getRenderPosition()); - //slamPosition(); - - LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1)); - LLQuaternion obj_rot = mRootVolp->getRotation(); - LLQuaternion result_rot = fix_axes_rot * obj_rot; - setRotation(result_rot); - mRoot->setWorldRotation(result_rot); - mRoot->setPosition(mRootVolp->getRenderPosition()); +#endif + + + if (mRootVolp) + { + if (mRootVolp->isAttachment()) + { + LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor(); + if (attached_av) + { + LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp); + setPositionAgent(mRootVolp->getRenderPosition()); + LLVector3 pos = attach->getParent()->getWorldPosition(); + mRoot->setWorldPosition(pos); + mRoot->setRotation(attach->getParent()->getWorldRotation()); + } + else + { + LL_WARNS_ONCE() << "can't find attached av!" << LL_ENDL; + } + } + else + { + setPositionAgent(mRootVolp->getRenderPosition()); + //slamPosition(); + + LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1)); + LLQuaternion obj_rot = mRootVolp->getRotation(); + LLQuaternion result_rot = fix_axes_rot * obj_rot; + setRotation(result_rot); + mRoot->setWorldRotation(result_rot); + mRoot->setPosition(mRootVolp->getRenderPosition()); + } + } } void LLControlAvatar::setGlobalScale(F32 scale) diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8001486b53..6799c3f862 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -698,11 +698,6 @@ F32 LLDrawable::updateXform(BOOL undamped) mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!) mXform.updateMatrix(); - if (mVObjp && mVObjp->isRootEdit() && mVObjp->getControlAvatar()) - { - mVObjp->getControlAvatar()->matchVolumeTransform(); - } - if (mSpatialBridge) { gPipeline.markMoved(mSpatialBridge, FALSE); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e2fbac023a..34e7bc0fad 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5188,10 +5188,15 @@ LLVOAvatar* LLViewerObject::asAvatar() return NULL; } -// If this object is directly or indirectly parented by an avatar, return it. +// If this object is directly or indirectly parented by an avatar, +// return it. Normally getAvatar() is the correct function to call; +// it will give the avatar used for skinning. The exception is with +// animated objects that are also attachments; in that case, +// getAvatar() will return the control avatar, used for skinning, and +// getAvatarAncestor will return the avatar to which the object is +// attached. LLVOAvatar* LLViewerObject::getAvatarAncestor() { - LL_ERRS("AXON") << "this method has been targetted for termination. Use getAvatar()." << LL_ENDL; LLViewerObject *pobj = (LLViewerObject*) getParent(); while (pobj) { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 1f99119d82..63e6560d98 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -862,8 +862,8 @@ void LLViewerObjectList::update(LLAgent &agent) { if (idle_count >= idle_list.size()) { - idle_list.push_back( objectp ); - } + idle_list.push_back( objectp ); + } else { idle_list[idle_count] = objectp; @@ -900,7 +900,7 @@ void LLViewerObjectList::update(LLAgent &agent) { objectp = *idle_iter; llassert(objectp->isActive()); - objectp->idleUpdate(agent, frame_time); + objectp->idleUpdate(agent, frame_time); } //update flexible objects diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index eab5206828..34ca69d6e0 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -110,6 +110,8 @@ #include "llcallstack.h" #include "llrendersphere.h" +#include + extern F32 SPEED_ADJUST_MAX; extern F32 SPEED_ADJUST_MAX_SEC; extern F32 ANIM_SPEED_MAX; @@ -3518,6 +3520,17 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } BOOL visible = isVisible(); + bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing + bool is_attachment = false; + if (is_control_avatar) + { + LLControlAvatar *cav = dynamic_cast(this); + is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects + } + + LLScopedContextString str("updateCharacter " + getFullname() + " is_control_avatar " + + boost::lexical_cast(is_control_avatar) + + " is_attachment " + boost::lexical_cast(is_attachment)); // For fading out the names above heads, only let the timer // run if we're visible. @@ -3532,21 +3545,25 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) bool visually_muted = isVisuallyMuted(); // AXON FIXME this expression is a crawling horror - if (mDrawable.notNull() && visible && (!isSelf() || visually_muted) && - !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) + if (mDrawable.notNull() + && visible + && (!isSelf() || visually_muted) // AXON would the self ever be visually muted? + && !mIsDummy + && sUseImpostors + && !mNeedsAnimUpdate + && !sFreezeCounter) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; size.setSub(ext[1],ext[0]); F32 mag = size.getLength3().getF32()*0.5f; - F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); if (visually_muted) { // visually muted avatars update at 16 hz mUpdatePeriod = 16; } - else if ( ! shouldImpostor() + else if (! shouldImpostor() || mDrawable->mDistanceWRTCamera < 1.f + mag) { // first 25% of max visible avatars are not impostored // also, don't impostor avatars whose bounding box may be penetrating the @@ -3590,7 +3607,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // change animation time quanta based on avatar render load // AXON how should control avs be handled here? - bool is_pure_dummy = mIsDummy && !isControlAvatar(); + bool is_pure_dummy = mIsDummy && !is_control_avatar; if (!isSelf() && !is_pure_dummy) { F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f); @@ -3602,6 +3619,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) stopMotion(ANIM_AGENT_WALK_ADJUST); removeAnimationData("Walk Speed"); } + // AXON: see SL-763 - playback with altered time step does not + // appear to work correctly, odd behavior for distant avatars. mMotionController.setTimeStep(time_step); // LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL; } @@ -3698,23 +3717,28 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) { root_pos += LLVector3d(getHoverOffset()); } - - LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); - - - if (newPosition != mRoot->getXform()->getWorldPosition()) - { - mRoot->touch(); - // SL-315 - mRoot->setWorldPosition( newPosition ); // regular update - } + LLControlAvatar *cav = dynamic_cast(this); + if (cav) + { + cav->matchVolumeTransform(); + } + else + { + LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); + if (newPosition != mRoot->getXform()->getWorldPosition()) + { + mRoot->touch(); + // SL-315 + mRoot->setWorldPosition( newPosition ); // regular update + } + } //-------------------------------------------------------------------- // Propagate viewer object rotation to root of avatar //-------------------------------------------------------------------- - // AXON - also skip for control avatars - if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) + // AXON - also skip for control avatars? Rotation fixups for avatars in motion, some may be relevant. + if (!is_control_avatar && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) { LLQuaternion iQ; LLVector3 upDir( 0.0f, 0.0f, 1.0f ); @@ -3868,6 +3892,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } else if (mDrawable.notNull()) { + // Sitting on an object - mRoot is slaved to mDrawable orientation. LLVector3 pos = mDrawable->getPosition(); pos += getHoverOffset() * mDrawable->getRotation(); // SL-315 diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 8b22024e0a..acecc6118c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -749,9 +749,9 @@ public: static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); /*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const; LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const; + LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); protected: - LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); void lazyAttach(); void rebuildRiggedAttachments( void ); -- 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/newview/lldrawable.cpp') 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 9be476e3bb4cde7b086581931ed39ac137207ffe Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 9 Jul 2018 22:30:50 +0100 Subject: MAINT-7926, MAINT-8400 - fixes related to bounding box and LOD calculations for rigged meshes in animated objects --- indra/newview/llcontrolavatar.cpp | 13 ++++++++++++- indra/newview/lldrawable.cpp | 20 ++++++++++++++++++++ indra/newview/llskinningutil.cpp | 25 ++++++++++++++++++++++--- indra/newview/llvoavatar.cpp | 6 +++--- indra/newview/llvovolume.cpp | 28 ++++++++++++++++++++++++++-- indra/newview/llvovolume.h | 3 +++ 6 files changed, 86 insertions(+), 9 deletions(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 88152d2dc6..93b178e0e9 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -316,7 +316,10 @@ void LLControlAvatar::updateDebugText() F32 est_tris = 0.f; F32 est_streaming_tris = 0.f; F32 streaming_cost = 0.f; - + std::string cam_dist_string = ""; + S32 cam_dist_count = 0; + F32 lod_radius = mRootVolp->mLODRadius; + for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) { @@ -351,6 +354,7 @@ void LLControlAvatar::updateDebugText() { // Rigged/animatable mesh type_string += "R"; + lod_radius = volp->mLODRadius; } else if (volp->isMesh()) { @@ -362,6 +366,12 @@ void LLControlAvatar::updateDebugText() // Any other prim type_string += "P"; } + if (cam_dist_count < 4) + { + cam_dist_string += LLStringOps::getReadableNumber(volp->mLODDistance) + "/" + + LLStringOps::getReadableNumber(volp->mLODAdjustedDistance) + " "; + cam_dist_count++; + } } else { @@ -376,6 +386,7 @@ 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())); + addDebugText(llformat("lod_radius %s dists %s", LLStringOps::getReadableNumber(lod_radius).c_str(),cam_dist_string.c_str())); if (mPositionConstraintFixup.length() > 0.0f) { addDebugText(llformat("pos fix (%.1f %.1f %.1f)", diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 22ed54913a..6d9c2c5eb8 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -32,6 +32,7 @@ #include "material_codes.h" // viewer includes +#include "llagent.h" #include "llcriticaldamp.h" #include "llface.h" #include "lllightconstants.h" @@ -900,6 +901,25 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) } } } + + // MAINT-7926 Handle volumes in an animated object as a special case + if (volume->getAvatar() && volume->getAvatar()->isControlAvatar()) + { + const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents(); + LLVector3d cam_pos = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); + LLVector3 cam_region_pos = LLVector3(cam_pos - volume->getRegion()->getOriginGlobal()); + + LLVector3 cam_to_box_offset = point_to_box_offset(cam_region_pos, av_box); + //LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname() + // << " pos (ignored) " << pos + // << " cam pos " << cam_pos + // << " cam region pos " << cam_region_pos + // << " box " << av_box[0] << "," << av_box[1] << LL_ENDL; + mDistanceWRTCamera = ll_round(cam_to_box_offset.magVec(), 0.01f); + mVObjp->updateLOD(); + return; + } + } else { diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 0878cee1a3..1f39097a98 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -241,11 +241,29 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a for (S32 i=0; i 0.0f) + { + for (U32 k=0; k<4; ++k) + { + wght[k] /= scale; + } + } for (U32 k=0; k<4; ++k) { - S32 joint_index = llfloor(w[k]); - if (w[k]-joint_index > 0.0f) + S32 joint_index = idx[k]; + if (wght[k] > 0.0f) { S32 joint_num = skin->mJointNums[joint_index]; if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) @@ -263,6 +281,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a matMul(bind_shape, inv_bind, mat); LLVector4a pos_joint_space; mat.affineTransform(pos, pos_joint_space); + pos_joint_space.mul(wght[k]); LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); update_min_max(extents[0], extents[1], pos_joint_space); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9b8af204cf..1ed105f8d4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1316,10 +1316,10 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) newMin = pos; newMax = pos; - //stretch bounding box by joint positions. No point doing this for + //stretch bounding box by joint positions. Doing this for //control avs, where the polymeshes aren't maintained or - //displayed. - if (box_detail>=1 && !isControlAvatar()) + //displayed, can give inaccurate boxes due to joints stuck at (0,0,0). + if ((box_detail>=1) && !isControlAvatar()) { for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7f353ea8aa..6bcbebb546 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -108,6 +108,10 @@ static LLTrace::BlockTimerStatHandle FTM_VOLUME_TEXTURES("Volume Textures"); extern BOOL gGLDebugLoggingEnabled; +#if LL_MSVC +#pragma optimize("", off) +#endif + // Implementation class of LLMediaDataClientObject. See llmediadataclient.h class LLMediaDataClientObjectImpl : public LLMediaDataClientObject { @@ -219,6 +223,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mFaceMappingChanged = FALSE; mLOD = MIN_LOD; + mLODDistance = 0.0f; + mLODAdjustedDistance = 0.0f; + mLODRadius = 0.0f; mTextureAnimp = NULL; mVolumeChanged = FALSE; mVObjRadius = LLVector3(1,1,0.5f).length(); @@ -1293,7 +1300,19 @@ BOOL LLVOVolume::calcLOD() } distance = avatar->mDrawable->mDistanceWRTCamera; - radius = avatar->getBinRadius(); + if (avatar->isControlAvatar()) + { + // MAINT-7926 Handle volumes in an animated object as a special case + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec() * 0.5f; + //LL_DEBUGS("DynamicBox") << avatar->getFullname() << " diag " << diag << " radius " << radius << LL_ENDL; + } + else + { + // Note this isn't really a radius, so distance calcs are off by factor of 2 + radius = avatar->getBinRadius(); + } if (distance <= 0.f || radius <= 0.f) { LL_DEBUGS("CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL; @@ -1313,7 +1332,10 @@ BOOL LLVOVolume::calcLOD() //hold onto unmodified distance for debugging //F32 debug_distance = distance; - + + mLODDistance = distance; + mLODRadius = radius; + distance *= sDistanceFactor; F32 rampDist = LLVOVolume::sLODFactor * 2; @@ -1335,6 +1357,8 @@ BOOL LLVOVolume::calcLOD() lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); } + mLODAdjustedDistance = distance; + cur_detail = computeLODDetail(ll_round(distance, 0.01f), ll_round(radius, 0.01f), lod_factor); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT) && mDrawable->getFace(0)) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 446d4a3d37..0882fc095d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -380,6 +380,9 @@ public: LLViewerTextureAnim *mTextureAnimp; U8 mTexAnimMode; + F32 mLODDistance; + F32 mLODAdjustedDistance; + F32 mLODRadius; private: friend class LLDrawable; friend class LLFace; -- cgit v1.3 From 447aadc37b56190893bbd4e2f527a4683844024b Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 31 Jul 2018 21:57:42 +0100 Subject: SL-937 - use dynamic box for rigged mesh attached to normal avatar as well. Still has a 2x error in the radius calc, but gets radius using the dynamic box. --- indra/newview/lldrawable.cpp | 5 ++++- indra/newview/llvovolume.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 6d9c2c5eb8..6f48b8a968 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -902,8 +902,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) } } + // MAINT-7926 Handle volumes in an animated object as a special case - if (volume->getAvatar() && volume->getAvatar()->isControlAvatar()) + // SL-937: add dynamic box handling for rigged mesh on regular avatars. + //if (volume->getAvatar() && volume->getAvatar()->isControlAvatar()) + if (volume->getAvatar()) { const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents(); LLVector3d cam_pos = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 61d82ec1cf..01b70088ab 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1296,6 +1296,8 @@ BOOL LLVOVolume::calcLOD() } distance = avatar->mDrawable->mDistanceWRTCamera; + + if (avatar->isControlAvatar()) { // MAINT-7926 Handle volumes in an animated object as a special case @@ -1306,8 +1308,16 @@ BOOL LLVOVolume::calcLOD() } else { + // Volume in a rigged mesh attached to a regular avatar. +#if 0 // Note this isn't really a radius, so distance calcs are off by factor of 2 radius = avatar->getBinRadius(); +#else + // SL-937: add dynamic box handling for rigged mesh on regular avatars. + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec(); // preserve old BinRadius behavior - 2x off +#endif } if (distance <= 0.f || radius <= 0.f) { -- cgit v1.3 From 301821337bf692d9f8d56230dc620efa74fcd275 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 19 Sep 2018 15:53:44 +0100 Subject: SL-9680, SL-9673 - set attachment distance floor at 0.01 to avoid triggering divide-by-zero prevention logic. Force HUD attachments to always be full detail. --- indra/newview/lldrawable.cpp | 14 ++++++++------ indra/newview/llvovolume.cpp | 24 +++++++++++++++--------- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 6f48b8a968..55db721ccf 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -913,12 +913,14 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLVector3 cam_region_pos = LLVector3(cam_pos - volume->getRegion()->getOriginGlobal()); LLVector3 cam_to_box_offset = point_to_box_offset(cam_region_pos, av_box); - //LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname() - // << " pos (ignored) " << pos - // << " cam pos " << cam_pos - // << " cam region pos " << cam_region_pos - // << " box " << av_box[0] << "," << av_box[1] << LL_ENDL; - mDistanceWRTCamera = ll_round(cam_to_box_offset.magVec(), 0.01f); + mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f)); + LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname() + << " pos (ignored) " << pos + << " cam pos " << cam_pos + << " cam region pos " << cam_region_pos + << " box " << av_box[0] << "," << av_box[1] + << " -> dist " << mDistanceWRTCamera + << LL_ENDL; mVObjp->updateLOD(); return; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8de97c711d..913460b3d1 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1344,24 +1344,22 @@ BOOL LLVOVolume::calcLOD() const LLVector3* box = avatar->getLastAnimExtents(); LLVector3 diag = box[1] - box[0]; radius = diag.magVec() * 0.5f; - //LL_DEBUGS("DynamicBox") << avatar->getFullname() << " diag " << diag << " radius " << radius << LL_ENDL; + LL_DEBUGS("DynamicBox") << avatar->getFullname() << " diag " << diag << " radius " << radius << LL_ENDL; } else { // Volume in a rigged mesh attached to a regular avatar. -#if 0 // Note this isn't really a radius, so distance calcs are off by factor of 2 - radius = avatar->getBinRadius(); -#else + //radius = avatar->getBinRadius(); // SL-937: add dynamic box handling for rigged mesh on regular avatars. const LLVector3* box = avatar->getLastAnimExtents(); LLVector3 diag = box[1] - box[0]; radius = diag.magVec(); // preserve old BinRadius behavior - 2x off -#endif + LL_DEBUGS("DynamicBox") << avatar->getFullname() << " diag " << diag << " radius " << radius << LL_ENDL; } if (distance <= 0.f || radius <= 0.f) { - LL_DEBUGS("CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL; + LL_DEBUGS("DynamicBox","CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL; return FALSE; } } @@ -1371,7 +1369,7 @@ BOOL LLVOVolume::calcLOD() radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length(); if (distance <= 0.f || radius <= 0.f) { - LL_DEBUGS("CalcLOD") << "non-avatar distance/radius uninitialized, skipping" << LL_ENDL; + LL_DEBUGS("DynamicBox","CalcLOD") << "non-avatar distance/radius uninitialized, skipping" << LL_ENDL; return FALSE; } } @@ -1414,7 +1412,15 @@ BOOL LLVOVolume::calcLOD() mLODAdjustedDistance = distance; - cur_detail = computeLODDetail(ll_round(distance, 0.01f), ll_round(radius, 0.01f), lod_factor); + if (isHUDAttachment()) + { + // HUDs always show at highest detail + cur_detail = 3; + } + else + { + cur_detail = computeLODDetail(ll_round(distance, 0.01f), ll_round(radius, 0.01f), lod_factor); + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT) && mDrawable->getFace(0)) { @@ -1434,7 +1440,7 @@ BOOL LLVOVolume::calcLOD() if (cur_detail != mLOD) { - LL_DEBUGS("CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD + LL_DEBUGS("DynamicBox","CalcLOD") << "new LOD " << cur_detail << " change from " << mLOD << " distance " << distance << " radius " << radius << " rampDist " << rampDist << " drawable rigged? " << (mDrawable ? (S32) mDrawable->isState(LLDrawable::RIGGED) : (S32) -1) << " mRiggedVolume " << (void*)getRiggedVolume() -- cgit v1.3 From 4d4255c27b45ed5e32fe7c4870e2ce3ed10cb140 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 27 Sep 2018 19:34:41 +0100 Subject: SL-1350 - keep control avatar rotation synced to corresponding root drawable --- indra/newview/llcontrolavatar.cpp | 11 ++++++++++- indra/newview/lldrawable.cpp | 5 ++++- indra/newview/llvoavatar.cpp | 3 ++- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'indra/newview/lldrawable.cpp') diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 0efed8ab7c..a620f2abe9 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -175,7 +175,16 @@ void LLControlAvatar::matchVolumeTransform() // complexity info and such line up better. Should defer // this until avatars also get fixed. - LLQuaternion obj_rot = mRootVolp->getRotation(); + LLQuaternion obj_rot; + if (mRootVolp->mDrawable) + { + obj_rot = mRootVolp->mDrawable->getRotation(); + } + else + { + obj_rot = mRootVolp->getRotation(); + } + LLMatrix3 bind_mat; LLQuaternion bind_rot; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 55db721ccf..8c6cbc020b 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -52,7 +52,6 @@ #include "llviewerwindow.h" #include "llvocache.h" #include "llcontrolavatar.h" -#include "llcallstack.h" #include "lldrawpoolavatar.h" const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f; @@ -730,6 +729,10 @@ F32 LLDrawable::updateXform(BOOL undamped) mXform.setRotation(target_rot); mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!) mXform.updateMatrix(); + if (isRoot() && mVObjp->isAnimatedObject() && mVObjp->getControlAvatar()) + { + mVObjp->getControlAvatar()->matchVolumeTransform(); + } if (mSpatialBridge) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index dba99c7e98..1f72aed5b4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4168,7 +4168,8 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w LLControlAvatar *cav = dynamic_cast(this); if (cav) { - cav->matchVolumeTransform(); + // SL-1350: Moved to LLDrawable::updateXform() + //cav->matchVolumeTransform(); } else { -- cgit v1.3