From 03282e3618da2280184b2363f86d45783e22329b Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Thu, 12 Mar 2020 03:34:16 -0400 Subject: [PATCH] War on dynamic_cast<LLVOVolume> edition! --- indra/newview/llcontrolavatar.cpp | 2 +- indra/newview/llfloatertools.cpp | 4 +- indra/newview/llpanelprimmediacontrols.cpp | 15 ++++--- indra/newview/llselectmgr.cpp | 6 +-- indra/newview/llspatialpartition.cpp | 6 +-- indra/newview/llviewermessage.cpp | 2 +- indra/newview/llviewerobject.cpp | 13 +++++- indra/newview/llviewerobject.h | 2 + indra/newview/llviewerwindow.cpp | 3 +- indra/newview/llvoavatar.cpp | 46 +++++++++++----------- indra/newview/llvovolume.cpp | 15 ++++--- indra/newview/llvovolume.h | 1 + 12 files changed, 68 insertions(+), 47 deletions(-) diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index f57c4495afa..1f4abdd8edd 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -501,7 +501,7 @@ void LLControlAvatar::getAnimatedVolumes(std::vector<LLVOVolume*>& volumes) iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; - LLVOVolume *child_volp = dynamic_cast<LLVOVolume*>(childp); + LLVOVolume *child_volp = childp ? childp->asVolume() : nullptr; if (child_volp && child_volp->isAnimatedObject()) { volumes.push_back(child_volp); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 0429749e11d..96acc5b4249 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -1251,8 +1251,8 @@ void LLFloaterTools::getMediaState() for ( ; iter != end; ++iter) { LLSelectNode* node = *iter; - LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject()); - if (NULL != object) + LLVOVolume* object = node ? node->getObject()->asVolume() : nullptr; + if (nullptr != object) { if (!object->permModify()) { diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 6e61584d33f..32fb33f734c 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -319,11 +319,12 @@ void LLPanelPrimMediaControls::updateShape() bool hasPermsControl = true; bool mini_controls = false; LLMediaEntry *media_data = objectp->getTE(mTargetObjectFace)->getMediaData(); - if (media_data && NULL != dynamic_cast<LLVOVolume*>(objectp)) + LLVOVolume *vol = objectp ? objectp->asVolume() : nullptr; + if (media_data && vol) { // Don't show the media controls if we do not have permissions - enabled = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL); - hasPermsControl = dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL); + enabled = vol->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL); + hasPermsControl = vol->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL); mini_controls = (LLMediaEntry::MINI == media_data->getControls()); } const bool is_hud = objectp->isHUDAttachment(); @@ -805,12 +806,16 @@ void LLPanelPrimMediaControls::draw() // draw control background UI image LLViewerObject* objectp = getTargetObject(); - LLMediaEntry *media_data(0); + LLMediaEntry *media_data = nullptr; + LLVOVolume* volumep = nullptr; if( objectp ) + { media_data = objectp->getTE(mTargetObjectFace)->getMediaData(); + volumep = objectp->asVolume(); + } - if( !dynamic_cast<LLVOVolume*>(objectp) || !media_data || dynamic_cast<LLVOVolume*>(objectp)->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL) ) + if( !volumep || !media_data || volumep->hasMediaPermission(media_data, LLVOVolume::MEDIA_PERM_CONTROL) ) mBackgroundImage->draw( controls_bg_area, UI_VERTEX_COLOR % alpha); // draw volume slider background UI image diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index f93a81fb569..dce448cd53d 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -2088,7 +2088,7 @@ void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) else { // Add/update media object->setTEMediaFlags(te, mMediaFlags); - LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); + LLVOVolume *vo = object->asVolume(); llassert(NULL != vo); if (NULL != vo) { @@ -2114,7 +2114,7 @@ void LLSelectMgr::selectionSetMedia(U8 media_type, const LLSD &media_data) if (object->permModify()) { object->sendTEUpdate(); - LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object); + LLVOVolume *vo = object->asVolume(); llassert(NULL != vo); // It's okay to skip this object if hasMedia() is false... // the sendTEUpdate() above would remove all media data if it were @@ -7537,7 +7537,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost() ++child_iter) { LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); + LLVOVolume *child = child_obj ? child_obj->asVolume() : nullptr; if (child) { cost += child->getRenderCost(textures); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d651761f4af..1917a5a3e4f 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -2033,7 +2033,7 @@ void renderComplexityDisplay(LLDrawable* drawablep) return; } - LLVOVolume *voVol = dynamic_cast<LLVOVolume*>(vobj); + LLVOVolume *voVol = vobj->asVolume();; if (!voVol) { @@ -2052,8 +2052,8 @@ void renderComplexityDisplay(LLDrawable* drawablep) LLViewerObject::const_child_list_t children = voVol->getChildren(); for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter) { - const LLViewerObject *child = *iter; - const LLVOVolume *child_volume = dynamic_cast<const LLVOVolume*>(child); + LLViewerObject *child = *iter; + LLVOVolume* child_volume = child ? child->asVolume() : nullptr; if (child_volume) { cost += child_volume->getRenderCost(textures); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index f86d7b131b0..194fc5a9a76 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4428,7 +4428,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data) return; } - LLVOVolume *volp = dynamic_cast<LLVOVolume*>(objp); + LLVOVolume *volp = objp->asVolume(); if (!volp) { LL_DEBUGS("AnimatedObjectsNotify") << "Received animation state for non-volume object " << uuid << LL_ENDL; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f1108f9ca5a..336261eb4f0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3151,7 +3151,7 @@ void LLViewerObject::linkControlAvatar() { if (!getControlAvatar() && isRootEdit()) { - LLVOVolume *volp = dynamic_cast<LLVOVolume*>(this); + LLVOVolume *volp = asVolume(); if (!volp) { LL_WARNS() << "called with null or non-volume object" << LL_ENDL; @@ -3972,7 +3972,9 @@ F32 LLViewerObject::recursiveGetScaledSurfaceArea() const ++child_iter) { LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); + if(!child_obj) continue; + + LLVOVolume *child = child_obj->asVolume(); if (child && child->getVolume()) { const LLVector3& scale = child->getScale(); @@ -5692,11 +5694,18 @@ bool LLViewerObject::isOwnerInMuteList(LLUUID id) return muted; } +// virtual LLVOAvatar* LLViewerObject::asAvatar() { return NULL; } +// virtual +LLVOVolume* LLViewerObject::asVolume() +{ + return nullptr; +} + // 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 diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 809ad995d32..1ded01ee292 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -61,6 +61,7 @@ class LLPipeline; class LLTextureEntry; class LLVOAvatar; class LLVOInventoryListener; +class LLVOVolume; class LLViewerInventoryItem; class LLViewerObject; class LLViewerObjectMedia; @@ -138,6 +139,7 @@ class LLViewerObject BOOL isParticleSource() const; virtual LLVOAvatar* asAvatar(); + virtual LLVOVolume* asVolume(); LLVOAvatar* getAvatarAncestor(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 81ddbcd220e..ff2723b5fe0 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1192,7 +1192,8 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi LL_DEBUGS() << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << LL_ENDL; - LLVOVolume *obj = dynamic_cast<LLVOVolume*>(static_cast<LLViewerObject*>(pick_info.getObject())); + LLViewerObject* vobjp = static_cast<LLViewerObject*>(pick_info.getObject()); + LLVOVolume *obj = vobjp ? vobjp->asVolume() : nullptr; if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty()) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f20b082d8c7..126e8de893b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1382,15 +1382,15 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) ++attachment_iter) { // Don't we need to look at children of attached_object as well? - const LLViewerObject* attached_object = attachment_iter->get(); + LLViewerObject* attached_object = attachment_iter->get(); if (attached_object && !attached_object->isHUDAttachment()) { - const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object); + const LLVOVolume *vol = attached_object->asVolume(); if (vol && vol->isAnimatedObject()) { // Animated objects already have a bounding box in their control av, use that. // Could lag by a frame if there's no guarantee on order of processing for avatars. - LLControlAvatar *cav = vol->getControlAvatar(); + const LLControlAvatar *cav = vol->getControlAvatar(); if (cav) { LLVector4a cav_min; @@ -1409,7 +1409,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LLDrawable* drawable = attached_object->mDrawable; if (drawable && !drawable->isState(LLDrawable::RIGGED)) { - LLSpatialBridge* bridge = drawable->getSpatialBridge(); + const LLSpatialBridge* bridge = drawable->getSpatialBridge(); if (bridge) { const LLVector4a* ext = bridge->getSpatialExtents(); @@ -6235,7 +6235,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL } } - LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo); + LLVOVolume *vobj = vo->asVolume(); bool pelvisGotSet = false; if (!vobj) @@ -7632,12 +7632,12 @@ void LLVOAvatar::rebuildAttachments() { for (LLViewerObject* pAttachObj : kvpAttachPt.second->mAttachedObjects) { - if (LLVOVolume* pAttachVol = (pAttachObj->isMesh()) ? dynamic_cast<LLVOVolume*>(pAttachObj) : nullptr) + if (LLVOVolume* pAttachVol = (pAttachObj->isMesh()) ? pAttachObj->asVolume() : nullptr) { pAttachVol->forceLOD(3); for (LLViewerObject* pChildObj : pAttachObj->getChildren()) { - if (LLVOVolume* pChildVol = (pChildObj->isMesh()) ? dynamic_cast<LLVOVolume*>(pChildObj) : nullptr) + if (LLVOVolume* pChildVol = (pChildObj->isMesh()) ? pChildObj->asVolume() : nullptr) pAttachVol->forceLOD(3); } } @@ -9978,11 +9978,12 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes) LLViewerJointAttachment* attachment = iter->second; 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) + for (LLViewerObject* attached_object : attachment->mAttachedObjects) { - LLViewerObject* attached_object = attach_iter->get(); - LLVOVolume *volume = dynamic_cast<LLVOVolume*>(attached_object); + if (!attached_object) + continue; + + LLVOVolume *volume = attached_object->asVolume(); if (volume) { volumes.push_back(volume); @@ -9995,11 +9996,12 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes) } } LLViewerObject::const_child_list_t& children = attached_object->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); - it != children.end(); ++it) + for (LLViewerObject* childp : children) { - LLViewerObject *childp = *it; - LLVOVolume *volume = dynamic_cast<LLVOVolume*>(childp); + if (!childp) + continue; + + LLVOVolume *volume = childp->asVolume(); if (volume) { volumes.push_back(volume); @@ -10016,11 +10018,9 @@ void LLVOAvatar::getAssociatedVolumes(std::vector<LLVOVolume*>& volumes) { volumes.push_back(volp); LLViewerObject::const_child_list_t& children = volp->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); - it != children.end(); ++it) + for (LLViewerObject* childp : children) { - LLViewerObject *childp = *it; - LLVOVolume *volume = dynamic_cast<LLVOVolume*>(childp); + LLVOVolume *volume = childp ? childp->asVolume() : nullptr; if (volume) { volumes.push_back(volume); @@ -10345,7 +10345,7 @@ void LLVOAvatar::accountRenderComplexityForObject( ++child_iter) { LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); + LLVOVolume *child = child_obj ? child_obj->asVolume() : nullptr; if (child) { attachment_children_cost += child->getRenderCost(textures); @@ -10396,11 +10396,9 @@ void LLVOAvatar::accountRenderComplexityForObject( hud_object_complexity.objectsCount++; LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) + for (LLViewerObject* childp : child_list) { - LLViewerObject* childp = *iter; - const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); + const LLVOVolume* chld_volume = childp ? childp->asVolume() : nullptr; if (chld_volume) { // get cost and individual textures diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a78c248c33e..c30d74f62fa 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -267,6 +267,11 @@ LLVOVolume::~LLVOVolume() } } +LLVOVolume* LLVOVolume::asVolume() +{ + return this; +} + void LLVOVolume::markDead() { if (!mDead) @@ -1324,7 +1329,7 @@ std::string get_debug_object_lod_text(LLVOVolume *rootp) iter != child_list.end(); ++iter) { LLViewerObject *childp = *iter; - LLVOVolume *volp = dynamic_cast<LLVOVolume*>(childp); + LLVOVolume *volp = childp ? childp->asVolume() : nullptr; if (volp) { lod_string += llformat("%d",volp->getLOD()); @@ -3674,8 +3679,6 @@ bool LLVOVolume::isAnimatedObject() const // virtual void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent) { - LLVOVolume *old_volp = dynamic_cast<LLVOVolume*>(old_parent); - if (new_parent && !new_parent->isAvatar()) { if (mControlAvatar.notNull()) @@ -3687,7 +3690,9 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare av->markForDeath(); } } - if (old_volp && old_volp->isAnimatedObject()) + + LLVOVolume *old_volp = old_parent ? old_parent->asVolume() : nullptr; + if (old_volp && old_volp->isAnimatedObject()) { if (old_volp->getControlAvatar()) { @@ -5442,7 +5447,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (bridge) { vobj = bridge->mDrawable->getVObj(); - vol_obj = dynamic_cast<LLVOVolume*>(vobj); + vol_obj = vobj ? vobj->asVolume() : nullptr; } if (vol_obj) { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d9f40de9449..e42a0081628 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -115,6 +115,7 @@ class LLVOVolume : public LLViewerObject public: LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); + LLVOVolume* asVolume(); /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); -- GitLab