From 486896581c675404245acfa37229125c3db0eac8 Mon Sep 17 00:00:00 2001 From: Arno Kaimbacher Date: Wed, 17 Feb 2021 18:15:15 +0100 Subject: [PATCH] - add slicing box - new files: material.js, Picking.js, PlaneGeometry.js, Selection.js, SelectionBoxFace.js, SelectionBoxLine.js, shader.js, uniforms.js - changed files: main.js --- src/js/clip/Picking.js | 218 ++++++++++++++++++++++++++++++++ src/js/clip/PlaneGeometry.js | 25 ++++ src/js/clip/Selection.js | 159 +++++++++++++++++++++++ src/js/clip/SelectionBoxFace.js | 20 ++- src/js/clip/SelectionBoxLine.js | 37 ++++++ src/js/clip/material.js | 31 +++++ src/js/clip/shader.js | 45 +++++++ src/js/clip/uniforms.js | 17 +++ src/js/main.js | 50 +++++++- 9 files changed, 594 insertions(+), 8 deletions(-) create mode 100644 src/js/clip/Picking.js create mode 100644 src/js/clip/PlaneGeometry.js create mode 100644 src/js/clip/Selection.js create mode 100644 src/js/clip/SelectionBoxLine.js create mode 100644 src/js/clip/material.js create mode 100644 src/js/clip/shader.js create mode 100644 src/js/clip/uniforms.js diff --git a/src/js/clip/Picking.js b/src/js/clip/Picking.js new file mode 100644 index 0000000..b261e31 --- /dev/null +++ b/src/js/clip/Picking.js @@ -0,0 +1,218 @@ +import { Vector2 } from 'three/src/math/Vector2'; +import { Vector3 } from 'three/src/math/Vector3'; +import { Raycaster } from 'three/src/core/Raycaster'; +import { PlaneGeometry } from 'three/src/geometries/PlaneGeometry'; +import { Mesh } from 'three/src/objects/Mesh'; +import * as material from '../clip/material'; +import * as domEvent from '../core/domEvent'; +import * as browser from '../core/browser'; + +export class Picking { + + simulation; + intersected; + mouse; + ray; + normals; + plane; + touchCapable = false; + isDraging = false; + + constructor(size, center, simulation) { + this.size = size; + this.center = center; + + if (browser.touch && browser.mobile) { + this.touchCapable = true; + } + + this.simulation = simulation; + this.intersected = null; + this.mouse = new Vector2(); + this.ray = new Raycaster(); + this.normals = { + x1: new Vector3(-1, 0, 0), + x2: new Vector3(1, 0, 0), + y1: new Vector3(0, -1, 0), + y2: new Vector3(0, 1, 0), + z1: new Vector3(0, 0, -1), + z2: new Vector3(0, 0, 1) + }; + let planeGeometry = new PlaneGeometry(this.size, this.size, 4, 4); + this.plane = new Mesh(planeGeometry, material.Invisible); + simulation.scene.add(this.plane); + + this.domElement = simulation.renderer.domElement; + + if (this.touchCapable) { + domEvent.on(this.domElement, 'mousemove', this.mouseMove, this); + domEvent.on(this.domElement, 'touchstart', this.beginDrag, this); + } else { + domEvent.on(this.domElement, 'mousemove', this.mouseMove, this); + domEvent.on(this.domElement, 'mousedown', this.beginDrag, this); + } + } + + _getOffset(element) { + if (!element.getClientRects().length) { + return { top: 0, left: 0 }; + } + + let rect = element.getBoundingClientRect(); + let win = element.ownerDocument.defaultView; + return ( + { + top: rect.top + win.pageYOffset, + left: rect.left + win.pageXOffset + }); + } + + _getCanvasPoint(event) { + let canvasOffset = this._getOffset(this.simulation.renderer.domElement); + let eventX = (event.clientX !== undefined) ? event.clientX : (event.touches && event.touches[0].clientX); + let eventY = (event.clientY !== undefined) ? event.clientY : (event.touches && event.touches[0].clientY); + let xClickedOnCanvas = eventX - canvasOffset.left; + let yClickedonCanvas = eventY - canvasOffset.top; + return { + x: xClickedOnCanvas, + y: yClickedonCanvas + } + } + + mouseMove(event) { + if (this.isDraging == true) { + return; + } + let point = this._getCanvasPoint(event); + let width = this.simulation.renderer.domElement.clientWidth; + let height = this.simulation.renderer.domElement.clientHeight; + let x = (point.x / width) * 2 - 1; + let y = -(point.y / height) * 2 + 1; + this.mouse.set(x, y); + + this.ray.setFromCamera(this.mouse, this.simulation.camera); + let intersects = this.ray.intersectObjects(this.simulation.selection.selectables); + + if (intersects.length > 0) { + let candidate = intersects[0].object; + + if (this.intersected !== candidate) { + if (this.intersected !== null) { + this.intersected.guardian.rayOut(); + } + candidate.guardian.rayOver(); + this.intersected = candidate; + this.simulation.renderer.domElement.style.cursor = 'pointer'; + // this.simulation.throttledRender(); + this.simulation.animate(); + } + + } else if (this.intersected !== null) { + // cursor is not selecting the box + this.intersected.guardian.rayOut(); + this.intersected = null; + this.simulation.renderer.domElement.style.cursor = 'auto'; + // this.simulation.throttledRender(); + this.simulation.animate(); + } + } + + beginDrag(event) { + // this.mouse.setToNormalizedDeviceCoordinates(event, window); + let point = this._getCanvasPoint(event); + let width = this.simulation.renderer.domElement.clientWidth; + let height = this.simulation.renderer.domElement.clientHeight; + let x = (point.x / width) * 2 - 1; + let y = -(point.y / height) * 2 + 1; + this.mouse.set(x, y); + + this.ray.setFromCamera(this.mouse, this.simulation.camera); + let intersects = this.ray.intersectObjects(this.simulation.selection.selectables); + + if (intersects.length > 0) { + this.isDraging = true; + event.preventDefault(); + event.stopPropagation(); + this.simulation.map.enabled = false; + var intersectionPoint = intersects[0].point; + var axis = intersects[0].object.axis; + + if (axis === 'x1' || axis === 'x2') { + // intersectionPoint.setX(0); + intersectionPoint.setX(this.center.x); + } else if (axis === 'y1' || axis === 'y2') { + // intersectionPoint.setY(0); + intersectionPoint.setY(this.center.y); + } else if (axis === 'z1' || axis === 'z2') { + // intersectionPoint.setZ(0); + intersectionPoint.setZ(this.center.z); + } + this.plane.position.copy(intersectionPoint); + + let newNormal = this.simulation.camera.position.clone().sub( + this.simulation.camera.position.clone().projectOnVector(this.normals[axis]) + ); + this.plane.lookAt(newNormal.add(intersectionPoint)); + this.simulation.renderer.domElement.style.cursor = 'grab'; + // simulation.throttledRender(); + this.simulation.animate(); + + let continueDrag = function (event) { + event.preventDefault(); + event.stopPropagation(); + // this.mouse.setToNormalizedDeviceCoordinates(event, window); + let point = this._getCanvasPoint(event); + let width = this.simulation.renderer.domElement.clientWidth; + let height = this.simulation.renderer.domElement.clientHeight; + let x = (point.x / width) * 2 - 1; + let y = -(point.y / height) * 2 + 1; + this.mouse.set(x, y); + + this.ray.setFromCamera(this.mouse, this.simulation.camera); + let intersects = this.ray.intersectObject(this.plane); + if (intersects.length > 0) { + let value; + if (axis === 'x1' || axis === 'x2') { + value = intersects[0].point.x; + } else if (axis === 'y1' || axis === 'y2') { + value = intersects[0].point.y; + } else if (axis === 'z1' || axis === 'z2') { + value = intersects[0].point.z; + } + this.simulation.selection.setValue(axis, value); + // this.simulation.selection.setValue('x1', 4452960); + // this.simulation.throttledRender(); + this.simulation.animate(); + } + + }; + + let endDrag = function (event) { + this.isDraging = false; + this.simulation.map.enabled = true; + this.simulation.renderer.domElement.style.cursor = 'pointer'; + domEvent.off(this.domElement, "mousemove", continueDrag, this); + domEvent.off(this.domElement, "touchmove", continueDrag, this); + + domEvent.off(this.domElement, "mouseup", endDrag, this); + domEvent.off(this.domElement, 'mouseleave', endDrag, this); + domEvent.off(this.domElement, 'touchend', endDrag, this); + domEvent.off(this.domElement, 'touchcancel', endDrag, this); + domEvent.off(this.domElement, 'touchleave', endDrag, this); + }; + + if (this.touchCapable) { + domEvent.on(this.domElement, 'touchmove', continueDrag, this); + domEvent.on(this.domElement, 'touchend', endDrag, this); + domEvent.on(this.domElement, 'touchcancel', endDrag, this); + domEvent.on(this.domElement, 'touchleave', endDrag, this); + } else { + domEvent.on(this.domElement, 'mousemove', continueDrag, this); + domEvent.on(this.domElement, 'mouseup', endDrag, this); + domEvent.on(this.domElement, 'mouseleave', endDrag, this); + } + } + } + + +} \ No newline at end of file diff --git a/src/js/clip/PlaneGeometry.js b/src/js/clip/PlaneGeometry.js new file mode 100644 index 0000000..8cd1455 --- /dev/null +++ b/src/js/clip/PlaneGeometry.js @@ -0,0 +1,25 @@ +import { BufferGeometry } from 'three/src/core/BufferGeometry'; +import { Uint16BufferAttribute } from 'three/src/core/BufferAttribute'; + +export class PlaneGeometry extends BufferGeometry { + + vertices = []; + + constructor(v0, v1, v2, v3) { + super(); + this.vertices.push(v0, v1, v2, v3); + this.setFromPoints(this.vertices); + + let indexArray = [0, 1, 2, 0, 2, 3]; + let indices = new Uint16BufferAttribute(indexArray, 1);//.setDynamic(true); + this.setIndex(indices); + + this.computeVertexNormals(); + + } + update() { + this.setFromPoints(this.vertices); + this.attributes.position.needsUpdate = true; + this.computeBoundingSphere(); + } +} \ No newline at end of file diff --git a/src/js/clip/Selection.js b/src/js/clip/Selection.js new file mode 100644 index 0000000..bab7601 --- /dev/null +++ b/src/js/clip/Selection.js @@ -0,0 +1,159 @@ +import { BoxGeometry } from 'three/src/geometries/BoxGeometry'; +import { Mesh } from 'three/src/objects/Mesh'; +import * as material from './material'; +import { Vector3 } from 'three/src/math/Vector3'; +import { Object3D } from 'three/src/core/Object3D'; +import { uniforms } from "./uniforms"; +import { SelectionBoxFace } from './SelectionBoxFace'; +import { SelectionBoxLine } from './SelectionBoxLine'; + +export class Selection { + limitLow; + limitHigh; + box; + boxMesh; + vertices; + touchMeshes; displayMeshes; meshGeometries; selectables; + faces; + + constructor(low, high) { + this.limitLow = low; + this.limitHigh = high; + this.limit = { + x1: low.x, + y1: low.y, + x2: high.x, + y2: high.y + } + + this.box = new BoxGeometry(1, 1, 1); + this.boxMesh = new Mesh(this.box, material.capMaterial); + + this.vertices = [ + new Vector3(), new Vector3(), + new Vector3(), new Vector3(), + new Vector3(), new Vector3(), + new Vector3(), new Vector3() + ]; + this.updateVertices(); + + let v = this.vertices; + + this.touchMeshes = new Object3D(); + this.displayMeshes = new Object3D(); + this.meshGeometries = []; + this.lineGeometries = []; + this.selectables = []; + + this.faces = []; + var f = this.faces; + this.faces.push(new SelectionBoxFace('y1', v[0], v[1], v[5], v[4], this)); + this.faces.push(new SelectionBoxFace('z1', v[0], v[2], v[3], v[1], this)); + this.faces.push(new SelectionBoxFace('x1', v[0], v[4], v[6], v[2], this)); + this.faces.push(new SelectionBoxFace('x2', v[7], v[5], v[1], v[3], this)); + this.faces.push(new SelectionBoxFace('y2', v[7], v[3], v[2], v[6], this)); + this.faces.push(new SelectionBoxFace('z2', v[7], v[6], v[4], v[5], this)); + + this.boxLines = []; + this.boxLines.push(new SelectionBoxLine(v[0], v[1], f[0], f[1], this)); + this.boxLines.push(new SelectionBoxLine(v[0], v[2], f[1], f[2], this)); + this.boxLines.push(new SelectionBoxLine(v[0], v[4], f[0], f[2], this)); + this.boxLines.push(new SelectionBoxLine(v[1], v[3], f[1], f[3], this)); + this.boxLines.push(new SelectionBoxLine(v[1], v[5], f[0], f[3], this)); + this.boxLines.push(new SelectionBoxLine(v[2], v[3], f[1], f[4], this)); + this.boxLines.push(new SelectionBoxLine(v[2], v[6], f[2], f[4], this)); + this.boxLines.push(new SelectionBoxLine(v[3], v[7], f[3], f[4], this)); + this.boxLines.push(new SelectionBoxLine(v[4], v[5], f[0], f[5], this)); + this.boxLines.push(new SelectionBoxLine(v[4], v[6], f[2], f[5], this)); + this.boxLines.push(new SelectionBoxLine(v[5], v[7], f[3], f[5], this)); + this.boxLines.push(new SelectionBoxLine(v[6], v[7], f[4], f[5], this)); + + this.setBox(); + this.setUniforms(); + + } + + updateVertices() { + this.vertices[0].set(this.limitLow.x, this.limitLow.y, this.limitLow.z); + this.vertices[1].set(this.limitHigh.x, this.limitLow.y, this.limitLow.z); + this.vertices[2].set(this.limitLow.x, this.limitHigh.y, this.limitLow.z); + this.vertices[3].set(this.limitHigh.x, this.limitHigh.y, this.limitLow.z); + this.vertices[4].set(this.limitLow.x, this.limitLow.y, this.limitHigh.z); + this.vertices[5].set(this.limitHigh.x, this.limitLow.y, this.limitHigh.z); + this.vertices[6].set(this.limitLow.x, this.limitHigh.y, this.limitHigh.z); + this.vertices[7].set(this.limitHigh.x, this.limitHigh.y, this.limitHigh.z); + } + + updateGeometries() { + // for (var i = 0; i < this.meshGeometries.length; i++) { + // // this.meshGeometries[i].verticesNeedUpdate = true; + // // this.meshGeometries[i].getAttribute('position').needsUpdate = true; + // this.meshGeometries[i].attributes.position.needsUpdate = true; + // this.meshGeometries[i].index.needsUpdate = true; + // this.meshGeometries[i].computeBoundingSphere(); + // this.meshGeometries[i].computeBoundingBox(); + // } + for (let i = 0; i < this.faces.length; i++) { + this.faces[i].update(); + } + + // for (var i = 0; i < this.lineGeometries.length; i++) { + // // this.lineGeometries[i].verticesNeedUpdate = true; + // // this.meshGeometries[i].getAttribute('position').needsUpdate = true; + // this.lineGeometries[i].attributes.position.needsUpdate = true; + // this.lineGeometries[i].index.needsUpdate = true; + // this.lineGeometries[i].computeBoundingSphere(); + // this.lineGeometries[i].computeBoundingBox(); + // } + for (let i = 0; i < this.boxLines.length; i++) { + this.boxLines[i].update(); + } + } + + setBox() { + let width = new Vector3(); + width.subVectors(this.limitHigh, this.limitLow); + + this.boxMesh.scale.copy(width); + width.multiplyScalar(0.5).add(this.limitLow); + this.boxMesh.position.copy(width); + } + + setUniforms() { + let unif = uniforms.clipping; + unif.clippingLow.value.copy(this.limitLow); + unif.clippingHigh.value.copy(this.limitHigh); + } + + setValue(axis, value) { + let buffer = 1000; + let limit = 14000; + + if (axis === 'x1') { + // this.limitLow.x = Math.max(-limit, Math.min(this.limitHigh.x - buffer, value)); + this.limitLow.x = Math.max(this.limit.x1, Math.min(this.limitHigh.x - buffer, value)); + } else if (axis === 'x2') { + // this.limitHigh.x = Math.max(this.limitLow.x + buffer, Math.min(limit, value)); + this.limitHigh.x = Math.max(this.limitLow.x + buffer, Math.min(this.limit.x2, value)); + } else if (axis === 'y1') { + // this.limitLow.y = Math.max(-limit, Math.min(this.limitHigh.y - buffer, value)); + this.limitLow.y = Math.max(this.limit.y1, Math.min(this.limitHigh.y - buffer, value)); + } else if (axis === 'y2') { + // this.limitHigh.y = Math.max(this.limitLow.y + buffer, Math.min(limit, value)); + this.limitHigh.y = Math.max(this.limitLow.y + buffer, Math.min(this.limit.y2, value)); + } else if (axis === 'z1') { + this.limitLow.z = Math.max(-limit, Math.min(this.limitHigh.z - buffer, value)); + } else if (axis === 'z2') { + this.limitHigh.z = Math.max(this.limitLow.z + buffer, Math.min(limit, value)); + } + + this.setBox(); + this.setUniforms(); + + this.updateVertices(); + this.updateGeometries(); + } + + + +} \ No newline at end of file diff --git a/src/js/clip/SelectionBoxFace.js b/src/js/clip/SelectionBoxFace.js index 0d65f59..98a5edb 100644 --- a/src/js/clip/SelectionBoxFace.js +++ b/src/js/clip/SelectionBoxFace.js @@ -1,28 +1,34 @@ import { Mesh } from 'three/src/objects/Mesh'; +import { PlaneGeometry } from './PlaneGeometry'; +import * as material from './material'; export class SelectionBoxFace { constructor(axis, v0, v1, v2, v3, selection) { - let frontFaceGeometry = new PlaneGeometry(v0, v1, v2, v3); - frontFaceGeometry.dynamic = true; + let frontFaceGeometry = this.fontFaceGeometry = new PlaneGeometry(v0, v1, v2, v3); + // frontFaceGeometry.dynamic = true; selection.meshGeometries.push(frontFaceGeometry); - let frontFaceMesh = new Mesh(frontFaceGeometry, MATERIAL.Invisible); + let frontFaceMesh = new Mesh(frontFaceGeometry, material.Invisible); frontFaceMesh.axis = axis; frontFaceMesh.guardian = this; selection.touchMeshes.add(frontFaceMesh); selection.selectables.push(frontFaceMesh); - let backFaceGeometry = new PlaneGeometry(v3, v2, v1, v0); - backFaceGeometry.dynamic = true; + let backFaceGeometry = this.backFaceGeometry = new PlaneGeometry(v3, v2, v1, v0); + // backFaceGeometry.dynamic = true; selection.meshGeometries.push(backFaceGeometry); - let backFaceMesh = new Mesh(backFaceGeometry, MATERIAL.BoxBackFace); + let backFaceMesh = new Mesh(backFaceGeometry, material.BoxBackFace); selection.displayMeshes.add(backFaceMesh); this.lines = new Array(); + } + update() { + this.fontFaceGeometry.update(); + this.backFaceGeometry.update(); } rayOver() { @@ -39,4 +45,4 @@ export class SelectionBoxFace { } } -} \ No newline at end of file +} diff --git a/src/js/clip/SelectionBoxLine.js b/src/js/clip/SelectionBoxLine.js new file mode 100644 index 0000000..21bb903 --- /dev/null +++ b/src/js/clip/SelectionBoxLine.js @@ -0,0 +1,37 @@ +import { LineSegments } from 'three/src/objects/LineSegments'; +// import { Float32BufferAttribute } from 'three/src/core/BufferAttribute'; +import * as material from './material'; +import { BufferGeometry } from 'three/src/core/BufferGeometry'; + +export class SelectionBoxLine { + + // material; + + constructor(v0, v1, f0, f1, selection) { + // var lineGeometry = new THREE.Geometry(); + // lineGeometry.vertices.push(v0, v1); + // lineGeometry.computeLineDistances(); + // lineGeometry.dynamic = true; + + let vertices = this.vertices = [v0, v1]; + let lineGeometry = this.lineGeometry = new BufferGeometry().setFromPoints(vertices); + selection.lineGeometries.push(lineGeometry); + lineGeometry.attributes.position.needsUpdate = true; + + this.line = new LineSegments(lineGeometry, material.BoxWireframe); + selection.displayMeshes.add(this.line); + + f0.lines.push(this); + f1.lines.push(this); + } + + update() { + this.lineGeometry.setFromPoints(this.vertices); + this.lineGeometry.attributes.position.needsUpdate = true; + this.lineGeometry.computeBoundingSphere(); + } + + setHighlight(b) { + this.line.material = b ? material.BoxWireActive : material.BoxWireframe; + } +} \ No newline at end of file diff --git a/src/js/clip/material.js b/src/js/clip/material.js new file mode 100644 index 0000000..644bbdf --- /dev/null +++ b/src/js/clip/material.js @@ -0,0 +1,31 @@ +import { MeshBasicMaterial } from 'three/src/materials/MeshBasicMaterial'; +import { LineBasicMaterial } from 'three/src/materials/LineBasicMaterial'; +import { ShaderMaterial } from 'three/src/materials/ShaderMaterial'; +import { uniforms } from "./uniforms"; +import { shader } from './shader'; +import { DoubleSide } from 'three/src/constants'; + +let capMaterial = new ShaderMaterial({ + uniforms: uniforms.caps, + vertexShader: shader.vertex, + fragmentShader: shader.fragment +}); + +let BoxBackFace = new MeshBasicMaterial({ color: 0xEEDDCC, transparent: true }); +let BoxWireframe = new LineBasicMaterial({ color: 0x000000, linewidth: 2 }); +// yellow select color +let BoxWireActive = new LineBasicMaterial({ color: 0xffff00, linewidth: 4, side: DoubleSide }); + +let Invisible = new ShaderMaterial({ + vertexShader: shader.invisibleVertexShader, + fragmentShader: shader.invisibleFragmentShader, + side: DoubleSide +}); + +export { + capMaterial, + BoxBackFace, + BoxWireframe, + BoxWireActive, + Invisible +} diff --git a/src/js/clip/shader.js b/src/js/clip/shader.js new file mode 100644 index 0000000..b52836e --- /dev/null +++ b/src/js/clip/shader.js @@ -0,0 +1,45 @@ + + +let shader = { + + vertex: '\ + uniform vec3 color;\ + varying vec3 pixelNormal;\ + \ + void main() {\ + \ + pixelNormal = normal;\ + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\ + \ + }', + + fragment: '\ + uniform vec3 color;\ + varying vec3 pixelNormal;\ + \ + void main( void ) {\ + \ + float shade = (\ + 3.0 * pow ( abs ( pixelNormal.y ), 2.0 )\ + + 2.0 * pow ( abs ( pixelNormal.z ), 2.0 )\ + + 1.0 * pow ( abs ( pixelNormal.x ), 2.0 )\ + ) / 3.0;\ + \ + gl_FragColor = vec4( color * shade, 1.0 );\ + \ + }', + + invisibleVertexShader: '\ + void main() {\ + vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\ + gl_Position = projectionMatrix * mvPosition;\ + }', + + invisibleFragmentShader: '\ + void main( void ) {\ + gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\ + discard;\ + }' + +} +export { shader }; \ No newline at end of file diff --git a/src/js/clip/uniforms.js b/src/js/clip/uniforms.js new file mode 100644 index 0000000..62b1ffe --- /dev/null +++ b/src/js/clip/uniforms.js @@ -0,0 +1,17 @@ +import { Vector3 } from 'three/src/math/Vector3'; +import { Color } from 'three/src/math/Color'; + +let uniforms = { + + clipping: { + color: { type: "c", value: new Color(0x3d9ecb) }, + clippingLow: { type: "v3", value: new Vector3(0, 0, 0) }, + clippingHigh: { type: "v3", value: new Vector3(0, 0, 0) } + }, + + caps: { + color: { type: "c", value: new Color(0xf83610) } + } + +}; +export { uniforms }; \ No newline at end of file diff --git a/src/js/main.js b/src/js/main.js index 307b7d3..a3edd2e 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -22,6 +22,9 @@ import * as util from './core/utilities'; import * as browser from './core/browser'; import * as domUtil from './core/domUtil'; import { MobileDialog } from "./controls/MobileDialog"; +import { Picking } from './clip/Picking'; + +import { Selection } from './clip/Selection'; import '../css/page.scss'; /* style loader will import it */ @@ -33,7 +36,8 @@ class Application { this.wireframeMode = false; this.canvas; this._canvasImageUrl; - this.downloadButton + this.downloadButton; + this.showCaps = true; this.objects = []; @@ -90,6 +94,7 @@ class Application { this.renderer = new WebGLRenderer({ alpha: true, antialias: true, preserveDrawingBuffer: true }); this.renderer.setPixelRatio(window.devicePixelRatio); this.renderer.setSize(this.width, this.height); + this.renderer.autoClear = false; this.renderer.setClearColor(0x000000, 0.0); // second param is opacity, 0 => transparent // enable clipping @@ -100,6 +105,9 @@ class Application { /* Scene: that will hold all our elements such as objects, cameras and lights. */ this.scene = new Scene(); + this.capsScene = new Scene(); + this.backStencil = new Scene(); + this.frontStencil = new Scene(); this._buildDefaultLights(this.scene); //app.scene.autoUpdate = false; //// show axes in the screen @@ -160,6 +168,14 @@ class Application { // create map // let map = this.map = new Map(x, y, z, size, center, this.camera, this.scene, this.container, 'https://geusegdi01.geus.dk/meta3d/rpc/model_meta?modelid=20'); + this.selection = new Selection( + // new Vector3(-7, -14, -14), + // new Vector3(14, 9, 3) + new Vector3(x.min, y.min, z.min), + new Vector3(x.max, y.max, z.max) + ); + new Picking(size, center, this); + let map = this.map = await Map.build(x, y, z, center, this.camera, this.scene, this.container, 'https://geusegdi01.geus.dk/meta3d/rpc/model_meta_all?modelid=20'); this.mapTitle = document.querySelector('#map-title'); this.mapTitle.innerHTML += map.title; @@ -226,6 +242,16 @@ class Application { //slice on x and y axes: // this.slicer = new SlicerControl({ parentDiv: 'slicer-control' }).addTo(this.map); + // this.selection = new Selection( + // // new Vector3(-7, -14, -14), + // // new Vector3(14, 9, 3) + // new Vector3(x.min, y.min, z.min), + // new Vector3(x.max, y.max, z.max) + // ); + this.capsScene.add(this.selection.boxMesh); + this.scene.add(this.selection.displayMeshes); + this.scene.add(this.selection.touchMeshes); + // domEvent.on(window, 'resize', this.onWindowResize, this); // domEvent.on(window, 'keydown', this.keydown, this); this.start(); @@ -311,6 +337,28 @@ class Application { } animate() { + this.renderer.clear(); + + let gl = this.renderer.context; + // if (this.showCaps) { + + // this.renderer.state.setStencilTest(true); + + // this.renderer.state.setStencilFunc(gl.ALWAYS, 1, 0xff); + // this.renderer.state.setStencilOp(gl.KEEP, gl.KEEP, gl.INCR); + // // this.renderer.render(this.backStencil, this.camera); + + // this.renderer.state.setStencilFunc(gl.ALWAYS, 1, 0xff); + // this.renderer.state.setStencilOp(gl.KEEP, gl.KEEP, gl.DECR); + // // this.renderer.render(this.frontStencil, this.camera); + + // this.renderer.state.setStencilFunc(gl.EQUAL, 1, 0xff); + // this.renderer.state.setStencilOp(gl.KEEP, gl.KEEP, gl.KEEP); + // this.renderer.render(this.capsScene, this.camera); + + // this.renderer.state.setStencilTest(false); + + // } this.renderer.render(this.scene, this.camera); this.northArrow.animate(); this.gridlayer.animate();