From 0e9843aba88e33c05c55bcff36b891baf71e8ea9 Mon Sep 17 00:00:00 2001 From: AlexandruPopovici Date: Tue, 9 Aug 2022 14:11:30 +0300 Subject: [PATCH] #828 Implemented automatic draw range setting after autocompleting draw ranges. This will make sure that hidden objects will not have their shadows draw, as well as you cannot pick hidden objects. Additionally I also made hidden lines not pickable --- .../viewer/src/modules/SpeckleRenderer.ts | 37 ++++++++++++++----- .../viewer/src/modules/batching/Batcher.ts | 5 ++- .../viewer/src/modules/batching/LineBatch.ts | 4 +- .../viewer/src/modules/batching/MeshBatch.ts | 10 +++++ packages/viewer/src/modules/tree/WorldTree.ts | 10 ++--- 5 files changed, 47 insertions(+), 19 deletions(-) diff --git a/packages/viewer/src/modules/SpeckleRenderer.ts b/packages/viewer/src/modules/SpeckleRenderer.ts index ff2949fda..ded070c6c 100644 --- a/packages/viewer/src/modules/SpeckleRenderer.ts +++ b/packages/viewer/src/modules/SpeckleRenderer.ts @@ -205,6 +205,7 @@ export default class SpeckleRenderer { public endFilter() { this.batcher.autoFillDrawRanges(this.filterBatchRecording) + this.renderer.shadowMap.needsUpdate = true } public updateClippingPlanes(planes: Plane[]) { @@ -315,6 +316,7 @@ export default class SpeckleRenderer { ) if (!result) { this.batcher.resetBatchesDrawRanges() + this.renderer.shadowMap.needsUpdate = true return } @@ -323,12 +325,20 @@ export default class SpeckleRenderer { result.object.uuid, result.faceIndex !== undefined ? result.faceIndex : result.index ) + /** Batch rejected picking. This only happens with hidden lines */ + if (!rv) { + this.batcher.resetBatchesDrawRanges() + this.renderer.shadowMap.needsUpdate = true + return + } + const hitId = rv.renderData.id // const hitNode = WorldTree.getInstance().findId(hitId) this.batcher.resetBatchesDrawRanges() this.batcher.isolateRenderView(hitId) + this.renderer.shadowMap.needsUpdate = true /** In case the above call has breaking bugs, just use this instead */ // this.batcher.autoFillDrawRanges( // this.batcher.setObjectsFilterMaterial([hitNode.model.id], { @@ -355,17 +365,24 @@ export default class SpeckleRenderer { result.object.uuid, result.faceIndex !== undefined ? result.faceIndex : result.index ) - const transformedBox = new Box3().copy(rv.aabb) - transformedBox.applyMatrix4(result.object.matrixWorld) - this.zoomToBox(transformedBox, 1.2, true) + if (rv) { + const transformedBox = new Box3().copy(rv.aabb) + transformedBox.applyMatrix4(result.object.matrixWorld) + this.zoomToBox(transformedBox, 1.2, true) + this.viewer.needsRender = true + this.viewer.emit( + 'object-doubleclicked', + result ? rv.renderData.id : null, + result ? result.point : null + ) + } else { + if (this.viewer.sectionBox.display.visible) { + this.zoomToBox(this.viewer.sectionBox.cube, 1.2, true) + } else { + this.zoomExtents() + } + } } - - this.viewer.needsRender = true - this.viewer.emit( - 'object-doubleclicked', - result ? rv.renderData.id : null, - result ? result.point : null - ) } /** Taken from InteractionsHandler. Will revisit in the future */ diff --git a/packages/viewer/src/modules/batching/Batcher.ts b/packages/viewer/src/modules/batching/Batcher.ts index b59e3ee82..93acb268a 100644 --- a/packages/viewer/src/modules/batching/Batcher.ts +++ b/packages/viewer/src/modules/batching/Batcher.ts @@ -5,7 +5,7 @@ import { WorldTree } from '../tree/WorldTree' import LineBatch from './LineBatch' import Materials from '../materials/Materials' import { NodeRenderView } from '../tree/NodeRenderView' -import { Batch, BatchUpdateRange, GeometryType } from './Batch' +import { Batch, BatchUpdateRange, GeometryType, HideAllBatchUpdateRange } from './Batch' import PointBatch from './PointBatch' import { FilterMaterialType } from '../FilteringManager' import { WebGLRenderer } from 'three' @@ -199,6 +199,7 @@ export default class Batcher { FilterMaterialType.HIDDEN ) }) + this.batches[k].setVisibleRange(HideAllBatchUpdateRange) } else { const drawRanges = [] for (let i = 0; i < this.batches[k].renderViews.length; i++) { @@ -208,7 +209,7 @@ export default class Batcher { count: this.batches[k].renderViews[i].batchCount, material: this.materials.getFilterMaterial( this.batches[k].renderViews[i], - FilterMaterialType.HIDDEN + FilterMaterialType.GHOST ) }) } diff --git a/packages/viewer/src/modules/batching/LineBatch.ts b/packages/viewer/src/modules/batching/LineBatch.ts index 2af45b61f..d76f0dd7e 100644 --- a/packages/viewer/src/modules/batching/LineBatch.ts +++ b/packages/viewer/src/modules/batching/LineBatch.ts @@ -170,7 +170,9 @@ export default class LineBatch implements Batch { for (let k = 0; k < this.renderViews.length; k++) { if ( index >= this.renderViews[k].batchStart && - index < this.renderViews[k].batchEnd + index < this.renderViews[k].batchEnd && + /** A bit cheaty, but ok for now */ + this.colorBuffer.array[index * this.colorBuffer.stride + 3] !== 0 ) { return this.renderViews[k] } diff --git a/packages/viewer/src/modules/batching/MeshBatch.ts b/packages/viewer/src/modules/batching/MeshBatch.ts index 7ddaeb2e4..799a08066 100644 --- a/packages/viewer/src/modules/batching/MeshBatch.ts +++ b/packages/viewer/src/modules/batching/MeshBatch.ts @@ -245,6 +245,16 @@ export default class MeshBatch implements Batch { } this.geometry.setIndex(targetIBO) this.geometry.index.needsUpdate = true + + const hiddenGroup = this.geometry.groups.find((value) => { + return this.mesh.material[value.materialIndex].visible === false + }) + if (hiddenGroup) { + this.setVisibleRange({ + offset: 0, + count: hiddenGroup.start + }) + } } /** This is the initial basic way of dealing with auto-completing draw groups diff --git a/packages/viewer/src/modules/tree/WorldTree.ts b/packages/viewer/src/modules/tree/WorldTree.ts index 5c432ef58..e0c48372a 100644 --- a/packages/viewer/src/modules/tree/WorldTree.ts +++ b/packages/viewer/src/modules/tree/WorldTree.ts @@ -15,6 +15,7 @@ export interface NodeData { export class WorldTree { private static instance: WorldTree private static renderTreeInstances: { [id: string]: RenderTree } = {} + private readonly supressWarnings = true private constructor() { this.tree = new TreeModel() @@ -40,9 +41,6 @@ export class WorldTree { console.error(`WorldTree not initialised`) return null } - if (!subtreeId) { - console.warn(`No subtree provided, using Root`) - } const id = subtreeId ? subtreeId : WorldTree.getInstance().root.model.id if (!WorldTree.renderTreeInstances[id]) { @@ -83,14 +81,14 @@ export class WorldTree { } public findAll(predicate: SearchPredicate, node?: TreeNode): Array { - if (!node) { + if (!node && !this.supressWarnings) { console.warn(`Root will be used for searching. You might not want that`) } return (node ? node : this.root).all(predicate) } public findId(id: string, node?: TreeNode) { - if (!node) { + if (!node && !this.supressWarnings) { console.warn(`Root will be used for searching. You might not want that`) } return (node ? node : this.root).first((_node: TreeNode) => { @@ -103,7 +101,7 @@ export class WorldTree { } public walk(predicate: SearchPredicate, node?: TreeNode): void { - if (!node) { + if (!node && !this.supressWarnings) { console.warn(`Root will be used for searching. You might not want that`) } this._root.walk(predicate)