Introduce Scene Explorer feature#324
Conversation
A filterable LLFolderView scene-graph tree of the current region for environment builders and region administrators: Region -> linksets -> child prims (kept in link order), plus Avatars -> attachment-point folders -> attachments. Animesh objects list under their wearer; control and UI avatars are excluded. - ALObjectPropertiesCache: session cache of bulk ObjectProperties data, fed by a batched ObjectSelect/ObjectDeselect probe (throttled, deduped, retry-capped, skips the user's live selection); handlers forward to LLSelectMgr and in-flight tracking suppresses its node-less reply warning per-id - Idle-driven lifecycle: time-sliced discovery/widget build (~6ms/frame) and time-sliced filtering, so dense regions populate without stalls - Filters (persisted): text over name/desc/UUID, owner, scripted/light/ particles flags, radius (re-armed as the agent moves); sorts: distance/ name/land impact/triangles/type - Actions: focus (zoom-to-object), edit, inspect, teleport, copy id; configurable double-click activation; derendered objects excluded via ALDerenderList - fetchObjectCostsCoro: chunk GetObjectCost requests to the cap limit and retire pending ids if the coroutine is torn down mid-sequence Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Server load: - Add LLViewerObject::peekObjectCost/peekLinksetCost and use them in the reconcile refresh: getObjectCost() re-queues a GetObjectCost request whenever the cost is stale, and a failed fetch stays stale, so the periodic read was re-requesting failed/uncosted objects every 1.5s forever - Persist the object-properties cache across region crossings (entries are keyed by globally-unique UUID; wiping made every border hop re-probe the whole region) and bound growth with oldest-first eviction at 100k entries instead - Back the property-probe drain off to one batch per second while the backlog is large; keep the snappy cadence for normal regions UX: - Only drive the in-world selection while the Build or Inspect floater is visible: pushing a selection fires avatar look-at/point-at targeting and edit-mode side effects, which read as the camera and avatar reacting to every tree click while browsing - Mirror LLToolSelect's EditLinkedParts split when selecting: "Edit linked" on selects the individual prim, off selects the whole linkset even from a child row, keeping the build manipulators in sync - Double-click follows row expectation again: containers, multi-prim linksets and avatars expand/collapse; only childless single-prim roots activate like a leaf - Skip the camera zoom on default-action activation while Build or Inspect is open; double-click then means "retarget the selection" - Re-arm arrange alongside requestSortAll in reconcile: sorting only runs inside arrange(), so the periodic distance re-sort never actually reordered a quiet tree - Show "No matching objects" for zero-hit filters; pin sort combo and Avatars checkbox to the left so resizing no longer scatters them Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RLVa (stage 1): - Hide other avatars and their attachments under a nearby-agent restriction (self stays); re-evaluated per reconcile pass - Anonymize avatar row names per-agent via RlvStrings::getAnonym in the placeholder, the async name callback and a per-pass re-derivation, so @shownames flips apply promptly and search can't reveal real names - Gate Edit (button, activation) on RlvActions::canEdit and refuse non-editable objects in selectInWorld while Build is up, matching LLToolSelect's in-world refusal Derendered category (stage 2): - Synthetic TYPE_DERENDERED_OBJECT/_AVATAR rows under a lazily created category (exists only while entries exist and the toggle is on); excluded from the present-set sweep, the props fetch/retry and stale cached props; objects scoped to the current region, avatars listed region-less; stored posRegion drives distance display and teleport - syncDerendered runs per reconcile and on the ALDerenderList change signal; Derender / Derender Permanently / Restore context entries drive addSelection/removeObjects directly Detail pane + row presentation (stage 3): - Geometry-aware icons, on-demand rich hover tooltips, avatar rows show complexity + attachment count, category counts, per-selection action button gating, teleport to derendered positions - Received-items style expander bar hosting a collapsible detail panel (LLLayoutStack::collapsePanel; spacing gap above the bar is the drag area; user_resize on the preceding panels) - Type-specific native panels (object vs avatar) in a scroll container: form labels, owner/creator app-SLURLs (resolved clickable RLVa-aware names), read-only perm and flag checkboxes, heat-colored LI/render values, stable cost cells, muted loading placeholders so rows never reflow as replies arrive - Per-face material list in its own resizable section; asset ids gated like the build floater's copy checks (god account, library asset or full-perm inventory copy; memoized) with a friendly note otherwise; rebuilt only on selection change so scrolling isn't reset - ObjectProperties handler now unpacks the five permission masks into the props cache Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Inspect floater gains ten opt-in scene-builder columns (LI, ARC, physics, streaming, prim count, distance, scripts, light/glow, media, alpha/PBR) sourced from ALObjectProperties::fromObject so it and the explorer always agree; LI reads linkset total on roots and own contribution on children, and the cost setters now dirty the Inspect floater so async costs fill in. The explorer's static context menu becomes one superset toggleable menu serving both right-click and a new gear button, shown/hidden per row type imperatively (folder-view popups never evaluate on_visible/on_enable). Object rows stage the selection and reuse the global viewer handlers and their registered enable predicates; avatar rows act by id through LL/ALAvatarActions with parcel/estate admin entries hidden without the matching power. Adds tracker beacons, Show on Map, a Copy submenu, filter-by-owner (new OWNER_SPECIFIC mode), CSV results export, Ctrl+F, a view/sort hamburger replacing the sort combo and visibility checkboxes, a region-origin sort key, and Inspect/Beacon/TP bottom buttons. LLSliderCtrl now keeps its read-only value text pinned to the right edge on reshape, matching the editable variant. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full Region Coverage in the view menu asks the simulator for the 360 interest list while the explorer is open (applied on open, released on close); the agent-level mode re-applies itself across crossings, the release path never clobbers the 360 capture floater, and reconcile re-claims the mode if the capture floater restores it away. First enable shows a notice about the server load. Cost fetches become fully demand-driven: node builds peek instead of trigger (fillFromObject gains a fetch_costs switch, peekPhysicsCost added), with one-shot per-node demand from visible rows, the LI sort, and the detail pane. A per-reconcile visible-row scan keeps on-screen suffixes fresh and bumps those rows' property fetches into a priority lane drained ahead of the off-screen backlog. The position-keyed sorts re-arm only when the agent or an object actually moved and defer while the cursor is over the tree or a menu is open, and a status line reports build/fetch backlogs and a large-region note. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Selection now syncs both ways while Build or Inspect is open - and only then, so transient world selections never yank the tree while browsing. Multi-select feeds batch menu actions (Take Copy, Return, Derender, Restore), Enter activates rows, and Refresh re-arms fetch demand, re-requests visible rows, and time-slice re-fills local records so per-face flags catch up to edits. The filter bar adopts the inventory pattern: a search-type combo (name/description/owner/UUID/all over per-field pre-lowered strings), a visibility eye menu, and a sort/actions hamburger with Select All Results and a selection-sync toggle. A companion filters floater holds the full predicate set - type, all feature flags plus For Sale (sale info now unpacked from both ObjectProperties reply flavours) and payable, a region/parcel/radius scope, and land-impact/triangle thresholds - sharing persisted settings with the quick bar. Owners resolve once per unique id into row suffixes and searchable text with RLVa @shownames flips scrubbed or re-resolved per pass, the owner filter labels its target, and matches highlight in row names. The predicate core moves to alsceneexplorerpredicate as a pure, TUT-tested function (16 cases) with change-classification helpers backing a multi-generation filter: less-restrictive changes keep the visible set stable and more-restrictive ones re-stamp failing rows without re-evaluating. The model now requests a re-arrange when an item's filtered state changes - the framework has no other filter-to-arrange link, previously masked by the unconditional distance re-sort. Also adds a toolbar command and tooltip coverage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 48 minutes and 55 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds a new Scene Explorer floater providing a filterable tree view of scene objects with sorting, incremental predicate-based filtering, async server-property caching, and per-row context actions. Extends the Inspect floater with optional metric columns, refactors object-cost fetching to use chunked HTTP requests, and fixes a slider text-box layout positioning bug. ChangesScene Explorer Feature
Slider Text-Box Positioning Fix
Sequence Diagram(s)sequenceDiagram
participant Server
participant ALObjectPropertiesCache
participant LLSelectMgr
participant ALFloaterSceneExplorer
participant ALSceneExplorerFilter
participant ALSceneExplorerPredicate
Server->>ALObjectPropertiesCache: ObjectProperties (msg)
ALObjectPropertiesCache->>ALObjectPropertiesCache: parse ServerProps, evict oldest entries
ALObjectPropertiesCache->>LLSelectMgr: forward message
ALObjectPropertiesCache->>ALFloaterSceneExplorer: mChangeSignal fired
ALFloaterSceneExplorer->>ALSceneExplorerFilter: update Constraints (owner/flags/scope/search)
ALSceneExplorerFilter->>ALSceneExplorerFilter: setModified() — bump generation, classify restrictiveness
ALSceneExplorerFilter->>ALSceneExplorerPredicate: matches(ItemFacts, Constraints)
ALSceneExplorerPredicate-->>ALSceneExplorerFilter: pass/fail
ALSceneExplorerFilter->>ALFloaterSceneExplorer: setPassedFilter → requestArrange
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Suggested labels
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
indra/newview/llfloaterinspect.cpp (1)
63-65: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick winConsolidate metric bit values into named constants.
METRIC_COLUMNS_MASKandmColumnBitsduplicate raw bit literals, which can drift over time and silently desync column gating. Define the bit constants once and reuse them in both places.♻️ Suggested refactor
+namespace +{ +constexpr U32 COL_LAND_IMPACT = 1u << 10; +constexpr U32 COL_RENDERCOST = 1u << 11; +constexpr U32 COL_PHYSICSCOST = 1u << 12; +constexpr U32 COL_STREAMCOST = 1u << 13; +constexpr U32 COL_PRIMCOUNT = 1u << 14; +constexpr U32 COL_DISTANCE = 1u << 15; +constexpr U32 COL_SCRIPTS = 1u << 16; +constexpr U32 COL_LIGHTGLOW = 1u << 17; +constexpr U32 COL_MEDIA = 1u << 18; +constexpr U32 COL_ALPHAPBR = 1u << 19; +} + -static constexpr U32 METRIC_COLUMNS_MASK = 1024 | 2048 | 4096 | 8192 | 16384 | 32768 | 65536 | 131072 | 262144 | 524288; +static constexpr U32 METRIC_COLUMNS_MASK = + COL_LAND_IMPACT | COL_RENDERCOST | COL_PHYSICSCOST | COL_STREAMCOST | + COL_PRIMCOUNT | COL_DISTANCE | COL_SCRIPTS | COL_LIGHTGLOW | COL_MEDIA | COL_ALPHAPBR; ... - mColumnBits["land_impact"] = 1024; - mColumnBits["rendercost"] = 2048; - mColumnBits["physicscost"] = 4096; - mColumnBits["streamingcost"] = 8192; - mColumnBits["primcount"] = 16384; - mColumnBits["distance"] = 32768; - mColumnBits["scripts"] = 65536; - mColumnBits["lightglow"] = 131072; - mColumnBits["media"] = 262144; - mColumnBits["alphapbr"] = 524288; + mColumnBits["land_impact"] = COL_LAND_IMPACT; + mColumnBits["rendercost"] = COL_RENDERCOST; + mColumnBits["physicscost"] = COL_PHYSICSCOST; + mColumnBits["streamingcost"] = COL_STREAMCOST; + mColumnBits["primcount"] = COL_PRIMCOUNT; + mColumnBits["distance"] = COL_DISTANCE; + mColumnBits["scripts"] = COL_SCRIPTS; + mColumnBits["lightglow"] = COL_LIGHTGLOW; + mColumnBits["media"] = COL_MEDIA; + mColumnBits["alphapbr"] = COL_ALPHAPBR;Also applies to: 92-103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@indra/newview/llfloaterinspect.cpp` around lines 63 - 65, Extract the individual bit values (1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288) used in the METRIC_COLUMNS_MASK constant into named constant definitions (for example, METRIC_BIT_1, METRIC_BIT_2, etc., or more descriptively named based on their purpose). Then update METRIC_COLUMNS_MASK to be composed from these named constants using the bitwise OR operator. Additionally, locate the mColumnBits field definition (around lines 92-103) and update it to use the same named constants instead of repeating the raw bit literals. This eliminates duplication and ensures the two definitions stay in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@indra/newview/alfloatersceneexplorerfilters.cpp`:
- Around line 155-162: The onClickReset() method is not resetting the
ALSceneExplorerRadius setting along with the other filter settings
(ALSceneExplorerFlagFilter, ALSceneExplorerTypeFilter, ALSceneExplorerScope,
ALSceneExplorerMinLandImpact, and ALSceneExplorerMinTriangles), which leaves the
radius filter with a stale value when the user resets filters. Add a
gSavedSettings call to reset ALSceneExplorerRadius to its default value
(typically 0.f) in the onClickReset() method alongside the other setting resets.
In `@indra/newview/skins/default/xui/en/floater_scene_explorer_filters.xml`:
- Around line 355-364: The reset button's tool_tip in the
floater_scene_explorer_filters.xml file promises to clear every filter including
the explorer's quick bar, but the corresponding reset function implementation in
indra/newview/alfloatersceneexplorerfilters.cpp (Lines 155-168) only resets
advanced settings and refreshes filters without clearing the main floater's
search/owner quick-bar state or resetting the radius value. Update the reset
function to additionally clear the quick-bar search and owner fields, and reset
the radius value to its default state, so the implementation matches the UI's
promise of resetting all filters.
In `@indra/newview/skins/default/xui/en/notifications.xml`:
- Around line 13391-13394: The usetemplate element with name="okbutton" does not
support the ignore control, making the ignoretext attribute on line 13392
ineffective for the SceneExplorerFullRegion notification. Replace the
usetemplate name attribute from "okbutton" to a template that includes ignore
functionality, such as one that provides both an action button and ignore
capability. This will ensure the ignoretext value is properly honored and users
can actually use the "don't show again" feature for this notification.
---
Nitpick comments:
In `@indra/newview/llfloaterinspect.cpp`:
- Around line 63-65: Extract the individual bit values (1024, 2048, 4096, 8192,
16384, 32768, 65536, 131072, 262144, 524288) used in the METRIC_COLUMNS_MASK
constant into named constant definitions (for example, METRIC_BIT_1,
METRIC_BIT_2, etc., or more descriptively named based on their purpose). Then
update METRIC_COLUMNS_MASK to be composed from these named constants using the
bitwise OR operator. Additionally, locate the mColumnBits field definition
(around lines 92-103) and update it to use the same named constants instead of
repeating the raw bit literals. This eliminates duplication and ensures the two
definitions stay in sync.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 050ad1f7-1f52-4189-9f6b-aeee2a22201f
📒 Files selected for processing (33)
indra/llui/llsliderctrl.cppindra/newview/CMakeLists.txtindra/newview/alderenderlist.hindra/newview/alfloatersceneexplorer.cppindra/newview/alfloatersceneexplorer.hindra/newview/alfloatersceneexplorerfilters.cppindra/newview/alfloatersceneexplorerfilters.hindra/newview/alobjectproperties.cppindra/newview/alobjectproperties.hindra/newview/alsceneexplorermodel.cppindra/newview/alsceneexplorermodel.hindra/newview/alsceneexplorerpredicate.cppindra/newview/alsceneexplorerpredicate.hindra/newview/app_settings/commands.xmlindra/newview/app_settings/settings_alchemy.xmlindra/newview/llfloaterinspect.cppindra/newview/llselectmgr.cppindra/newview/llstartup.cppindra/newview/llviewerfloaterreg.cppindra/newview/llviewerobject.cppindra/newview/llviewerobject.hindra/newview/llviewerobjectlist.cppindra/newview/skins/default/xui/en/floater_inspect.xmlindra/newview/skins/default/xui/en/floater_scene_explorer.xmlindra/newview/skins/default/xui/en/floater_scene_explorer_filters.xmlindra/newview/skins/default/xui/en/menu_inspect_options.xmlindra/newview/skins/default/xui/en/menu_scene_explorer.xmlindra/newview/skins/default/xui/en/menu_scene_explorer_view.xmlindra/newview/skins/default/xui/en/menu_scene_explorer_visibility.xmlindra/newview/skins/default/xui/en/menu_viewer.xmlindra/newview/skins/default/xui/en/notifications.xmlindra/newview/skins/default/xui/en/strings.xmlindra/newview/tests/alsceneexplorerpredicate_test.cpp
- Reset All Filters now delegates to the explorer's canonical doResetFilters so it also clears the quick-bar search/owner state and restores radius to its default, matching the button's "clear every filter" tooltip. - SceneExplorerFullRegion notification uses the okignore template so its "don't show again" option actually works (okbutton has no ignore control). - Inspect metric column bits extracted to named COL_* constants shared by METRIC_COLUMNS_MASK and mColumnBits so they cannot drift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Description
Introduce Scene Explorer feature
Related Issues
Issue Link:
Checklist
Please ensure the following before requesting review:
Additional Notes