diff --git a/packages/viewer/src/modules/Batch.ts b/packages/viewer/src/modules/Batch.ts index e7127f9e7..8fd8b680a 100644 --- a/packages/viewer/src/modules/Batch.ts +++ b/packages/viewer/src/modules/Batch.ts @@ -24,7 +24,7 @@ export default class Batch { private id: string private renderViews: NodeRenderView[] private geometry: BufferGeometry | LineSegmentsGeometry - private material: Material + public batchMaterial: Material public mesh: Mesh | Line | Line2 public constructor(id: string, renderViews: NodeRenderView[]) { @@ -32,13 +32,20 @@ export default class Batch { this.renderViews = renderViews } - public setMaterial(material: Material) { - this.material = material + public setBatchMaterial(material: Material) { + this.batchMaterial = material + } - this.mesh - this.material - this.renderViews - this.geometry + public setMaterial(material: Material | Material[]) { + this.mesh.material = material + } + + public addDrawGroup(start: number, count: number, materialIndex: number) { + this.geometry.addGroup(start, count, materialIndex) + } + + public clearDrawGroups() { + this.geometry.clearGroups() } public buildBatch(type: GeometryType) { @@ -56,8 +63,8 @@ export default class Batch { public getRenderView(index: number): NodeRenderView { for (let k = 0; k < this.renderViews.length; k++) { if ( - index >= this.renderViews[k].batchStart && - index < this.renderViews[k].batchEnd + index * 3 >= this.renderViews[k].batchStart && + index * 3 < this.renderViews[k].batchEnd ) { return this.renderViews[k] } @@ -92,7 +99,7 @@ export default class Batch { arrayOffset += geometry.attributes.INDEX.length } this.makeMeshGeometry(indices, position) - this.mesh = new Mesh(this.geometry, this.material) + this.mesh = new Mesh(this.geometry, this.batchMaterial) } private buildLineBatch() { @@ -138,12 +145,12 @@ export default class Batch { if (Geometry.THICK_LINES) { this.mesh = new LineSegments2( this.geometry as LineSegmentsGeometry, - this.material as SpeckleLineMaterial + this.batchMaterial as SpeckleLineMaterial ) ;(this.mesh as LineSegments2).computeLineDistances() this.mesh.scale.set(1, 1, 1) } else { - this.mesh = new Line(this.geometry, this.material) + this.mesh = new Line(this.geometry, this.batchMaterial) } } diff --git a/packages/viewer/src/modules/Batcher.ts b/packages/viewer/src/modules/Batcher.ts index 3f91c66ac..32df73e1c 100644 --- a/packages/viewer/src/modules/Batcher.ts +++ b/packages/viewer/src/modules/Batcher.ts @@ -3,6 +3,7 @@ import Batch, { GeometryType } from './Batch' import { SpeckleType } from './converter/GeometryConverter' import { WorldTree } from './converter/WorldTree' import Materials from './materials/Materials' +import { NodeRenderView } from './NodeRenderView' export default class Batcher { private materials: Materials @@ -49,7 +50,7 @@ export default class Batcher { const batchID = generateUUID() this.batches[batchID] = new Batch(batchID, batch) - this.batches[batchID].setMaterial(material) + this.batches[batchID].setBatchMaterial(material) this.batches[batchID].buildBatch(batchType) console.warn(batch) } @@ -58,4 +59,20 @@ export default class Batcher { public getRenderView(batchId: string, index: number) { return this.batches[batchId].getRenderView(index) } + + public resetBatchesDrawGroups() { + for (const k in this.batches) { + this.batches[k].clearDrawGroups() + this.batches[k].mesh.material = this.batches[k].batchMaterial + } + } + + public selectRenderView(renderView: NodeRenderView) { + const batch = this.batches[renderView.batchId] + batch.setMaterial([batch.batchMaterial, this.materials.meshHighlightMaterial]) + batch.clearDrawGroups() + batch.addDrawGroup(0, renderView.batchStart, 0) + batch.addDrawGroup(renderView.batchStart, renderView.batchCount, 1) + batch.addDrawGroup(renderView.batchEnd, Infinity, 0) + } } diff --git a/packages/viewer/src/modules/Intersections.ts b/packages/viewer/src/modules/Intersections.ts index 5d9415696..fe6345dcf 100644 --- a/packages/viewer/src/modules/Intersections.ts +++ b/packages/viewer/src/modules/Intersections.ts @@ -4,6 +4,7 @@ import Batcher from './Batcher' export class Intersections { private scene: Scene private batcher: Batcher + private lastTimeCall = 0 public constructor(scene: Scene, batcher: Batcher) { this.scene = scene @@ -12,11 +13,19 @@ export class Intersections { } public intersectScene(raycaster: Raycaster) { + if (performance.now() - this.lastTimeCall < 100) return + this.lastTimeCall = performance.now() const target = this.scene.getObjectByName('ContentGroup') const results = raycaster.intersectObjects(target.children) + if (!results.length) { + this.batcher.resetBatchesDrawGroups() + return + } + results.sort((value) => value.distance) - // console.log( - // this.batcher.getRenderView(results[0].object.uuid, results[0].faceIndex) - // ) + // console.log(results[0].faceIndex) + const rv = this.batcher.getRenderView(results[0].object.uuid, results[0].faceIndex) + // console.log(rv.renderData) + this.batcher.selectRenderView(rv) } } diff --git a/packages/viewer/src/modules/NodeRenderView.ts b/packages/viewer/src/modules/NodeRenderView.ts index dbd44373a..d9b697673 100644 --- a/packages/viewer/src/modules/NodeRenderView.ts +++ b/packages/viewer/src/modules/NodeRenderView.ts @@ -67,6 +67,14 @@ export class NodeRenderView { return this._batchIndexStart + this._batchIndexCount } + public get batchCount() { + return this._batchIndexCount + } + + public get batchId() { + return this._batchId + } + public get needsSegmentConversion() { return ( this._renderData.speckleType === SpeckleType.Curve || diff --git a/packages/viewer/src/modules/materials/Materials.ts b/packages/viewer/src/modules/materials/Materials.ts index db7d84d41..2d59c0a5c 100644 --- a/packages/viewer/src/modules/materials/Materials.ts +++ b/packages/viewer/src/modules/materials/Materials.ts @@ -8,6 +8,7 @@ import SpeckleStandardMaterial from './SpeckleStandardMaterial' export default class Materials { private readonly materialMap: { [hash: number]: Material } = {} + public meshHighlightMaterial: Material = null public static renderMaterialFromNode(node: TreeNode): RenderMaterial { if (!node) return null @@ -48,6 +49,17 @@ export default class Materials { } public createDefaultMaterials() { + this.meshHighlightMaterial = new SpeckleStandardMaterial( + { + color: 0x7f7fff, + emissive: 0x0, + roughness: 1, + metalness: 0, + side: DoubleSide // TBD + // clippingPlanes: this.viewer.sectionBox.planes + }, + ['USE_RTE'] + ) this.materialMap[NodeRenderView.NullRenderMaterialHash] = new SpeckleStandardMaterial( {