fix(viewer-lib): Handles WEB-2475. Shaded view mode no longer eats up cpu time on large streams (#3849)

- FilteringExtension now emits the filtering state changed event when reseting the filtering state
- BasitPass no longer applies the per vertex color indices each frame
- ViewModes extension now listens for filtering state changes and have any active BasitPass reset it's color indices on a filtering reset event. Not great, not terrible but it avoids us having to double cache the per vertex color indices.
This commit is contained in:
Alexandru Popovici
2025-01-20 14:12:14 +02:00
committed by GitHub
parent 7d23f5a04c
commit a75b89dd67
4 changed files with 38 additions and 4 deletions
+2 -1
View File
@@ -113,7 +113,7 @@ const getStream = () => {
// prettier-ignore
// 'https://app.speckle.systems/streams/da9e320dad/commits/5388ef24b8?c=%5B-7.66134,10.82932,6.41935,-0.07739,-13.88552,1.8697,0,1%5D'
// Revit sample house (good for bim-like stuff with many display meshes)
'https://app.speckle.systems/streams/da9e320dad/commits/5388ef24b8'
// 'https://app.speckle.systems/streams/da9e320dad/commits/5388ef24b8'
// 'https://latest.speckle.systems/streams/c1faab5c62/commits/ab1a1ab2b6'
// 'https://app.speckle.systems/streams/da9e320dad/commits/5388ef24b8'
// 'https://latest.speckle.systems/streams/58b5648c4d/commits/60371ecb2d'
@@ -469,6 +469,7 @@ const getStream = () => {
// 'https://app.speckle.systems/projects/e89b61b65c/models/2a0995f124'
// 'https://latest.speckle.systems/projects/3fe1880c36/models/65bb4287a8'
'https://latest.speckle.systems/projects/db06488e1c/models/21f3930771'
)
}
@@ -417,7 +417,9 @@ export class FilteringExtension extends Extension {
this.UserspaceColorState = null
this.StateKey = undefined
this.Renderer.resetMaterials()
this.CurrentFilteringState = {}
this.viewer.requestRender(UpdateFlags.RENDER_RESET | UpdateFlags.SHADOWS)
this.emit(ViewerEvent.FilteringStateSet, this.CurrentFilteringState)
return null
}
@@ -1,4 +1,6 @@
import { UpdateFlags } from '../../IViewer.js'
import { IViewer, UpdateFlags, ViewerEvent } from '../../IViewer.js'
import { BasitPass } from '../pipeline/Passes/BasitPass.js'
import { GPass } from '../pipeline/Passes/GPass.js'
import { ArcticViewPipeline } from '../pipeline/Pipelines/ArcticViewPipeline.js'
import { BasitPipeline } from '../pipeline/Pipelines/BasitViewPipeline.js'
import { DefaultPipeline } from '../pipeline/Pipelines/DefaultPipeline.js'
@@ -9,6 +11,7 @@ import { MRTShadedViewPipeline } from '../pipeline/Pipelines/MRT/MRTShadedViewPi
import { PenViewPipeline } from '../pipeline/Pipelines/PenViewPipeline.js'
import { ShadedViewPipeline } from '../pipeline/Pipelines/ShadedViewPipeline.js'
import { Extension } from './Extension.js'
import { FilteringExtension, FilteringState } from './FilteringExtension.js'
export enum ViewMode {
DEFAULT,
@@ -28,6 +31,34 @@ export interface ViewModeEventPayload {
}
export class ViewModes extends Extension {
public get inject() {
return [FilteringExtension]
}
public constructor(
viewer: IViewer,
protected filteringExtension: FilteringExtension
) {
super(viewer)
/** Not a super fan of this, but it avoids us caching another set of per vertex color indices */
if (filteringExtension)
filteringExtension.on(ViewerEvent.FilteringStateSet, (arg: FilteringState) => {
/** If no texture colored filters are present */
if (
(!arg.colorGroups || !arg.colorGroups.length) &&
(!arg.userColorGroups || !arg.userColorGroups.length)
) {
/** If any basit pass exists, set it's required color indices */
this.viewer
.getRenderer()
.pipeline.getPass('BASIT')
.forEach((pass: GPass) => {
;(pass as BasitPass).applyColorIndices()
})
}
})
}
public on<T extends ViewModeEvent>(
eventType: T,
listener: (arg: ViewModeEventPayload[T]) => void
@@ -33,6 +33,7 @@ export class BasitPass extends BaseGPass {
this.tree = tree
this.speckleRenderer = renderer
this.buildMaterials()
this.applyColorIndices()
}
public get displayName(): string {
@@ -82,7 +83,7 @@ export class BasitPass extends BaseGPass {
}
}
protected applyColorIndices() {
public applyColorIndices() {
for (const item in this.materialMap) {
const batch = this.materialMap[item][0]
const colorMap = this.materialMap[item][1]
@@ -131,7 +132,6 @@ export class BasitPass extends BaseGPass {
): boolean {
if (!camera || !scene) return false
this.applyColorIndices()
this.overrideMaterials()
if (this.onBeforeRender) this.onBeforeRender()