- 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
This commit is contained in:
parent
8b4ace6763
commit
486896581c
218
src/js/clip/Picking.js
Normal file
218
src/js/clip/Picking.js
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
25
src/js/clip/PlaneGeometry.js
Normal file
25
src/js/clip/PlaneGeometry.js
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
159
src/js/clip/Selection.js
Normal file
159
src/js/clip/Selection.js
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,28 +1,34 @@
|
||||||
import { Mesh } from 'three/src/objects/Mesh';
|
import { Mesh } from 'three/src/objects/Mesh';
|
||||||
|
import { PlaneGeometry } from './PlaneGeometry';
|
||||||
|
import * as material from './material';
|
||||||
|
|
||||||
export class SelectionBoxFace {
|
export class SelectionBoxFace {
|
||||||
|
|
||||||
constructor(axis, v0, v1, v2, v3, selection) {
|
constructor(axis, v0, v1, v2, v3, selection) {
|
||||||
|
|
||||||
let frontFaceGeometry = new PlaneGeometry(v0, v1, v2, v3);
|
let frontFaceGeometry = this.fontFaceGeometry = new PlaneGeometry(v0, v1, v2, v3);
|
||||||
frontFaceGeometry.dynamic = true;
|
// frontFaceGeometry.dynamic = true;
|
||||||
selection.meshGeometries.push(frontFaceGeometry);
|
selection.meshGeometries.push(frontFaceGeometry);
|
||||||
|
|
||||||
let frontFaceMesh = new Mesh(frontFaceGeometry, MATERIAL.Invisible);
|
let frontFaceMesh = new Mesh(frontFaceGeometry, material.Invisible);
|
||||||
frontFaceMesh.axis = axis;
|
frontFaceMesh.axis = axis;
|
||||||
frontFaceMesh.guardian = this;
|
frontFaceMesh.guardian = this;
|
||||||
selection.touchMeshes.add(frontFaceMesh);
|
selection.touchMeshes.add(frontFaceMesh);
|
||||||
selection.selectables.push(frontFaceMesh);
|
selection.selectables.push(frontFaceMesh);
|
||||||
|
|
||||||
let backFaceGeometry = new PlaneGeometry(v3, v2, v1, v0);
|
let backFaceGeometry = this.backFaceGeometry = new PlaneGeometry(v3, v2, v1, v0);
|
||||||
backFaceGeometry.dynamic = true;
|
// backFaceGeometry.dynamic = true;
|
||||||
selection.meshGeometries.push(backFaceGeometry);
|
selection.meshGeometries.push(backFaceGeometry);
|
||||||
|
|
||||||
let backFaceMesh = new Mesh(backFaceGeometry, MATERIAL.BoxBackFace);
|
let backFaceMesh = new Mesh(backFaceGeometry, material.BoxBackFace);
|
||||||
selection.displayMeshes.add(backFaceMesh);
|
selection.displayMeshes.add(backFaceMesh);
|
||||||
|
|
||||||
this.lines = new Array();
|
this.lines = new Array();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.fontFaceGeometry.update();
|
||||||
|
this.backFaceGeometry.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
rayOver() {
|
rayOver() {
|
||||||
|
|
37
src/js/clip/SelectionBoxLine.js
Normal file
37
src/js/clip/SelectionBoxLine.js
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
31
src/js/clip/material.js
Normal file
31
src/js/clip/material.js
Normal file
|
@ -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
|
||||||
|
}
|
45
src/js/clip/shader.js
Normal file
45
src/js/clip/shader.js
Normal file
|
@ -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 };
|
17
src/js/clip/uniforms.js
Normal file
17
src/js/clip/uniforms.js
Normal file
|
@ -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 };
|
|
@ -22,6 +22,9 @@ import * as util from './core/utilities';
|
||||||
import * as browser from './core/browser';
|
import * as browser from './core/browser';
|
||||||
import * as domUtil from './core/domUtil';
|
import * as domUtil from './core/domUtil';
|
||||||
import { MobileDialog } from "./controls/MobileDialog";
|
import { MobileDialog } from "./controls/MobileDialog";
|
||||||
|
import { Picking } from './clip/Picking';
|
||||||
|
|
||||||
|
import { Selection } from './clip/Selection';
|
||||||
|
|
||||||
import '../css/page.scss'; /* style loader will import it */
|
import '../css/page.scss'; /* style loader will import it */
|
||||||
|
|
||||||
|
@ -33,7 +36,8 @@ class Application {
|
||||||
this.wireframeMode = false;
|
this.wireframeMode = false;
|
||||||
this.canvas;
|
this.canvas;
|
||||||
this._canvasImageUrl;
|
this._canvasImageUrl;
|
||||||
this.downloadButton
|
this.downloadButton;
|
||||||
|
this.showCaps = true;
|
||||||
|
|
||||||
this.objects = [];
|
this.objects = [];
|
||||||
|
|
||||||
|
@ -90,6 +94,7 @@ class Application {
|
||||||
this.renderer = new WebGLRenderer({ alpha: true, antialias: true, preserveDrawingBuffer: true });
|
this.renderer = new WebGLRenderer({ alpha: true, antialias: true, preserveDrawingBuffer: true });
|
||||||
this.renderer.setPixelRatio(window.devicePixelRatio);
|
this.renderer.setPixelRatio(window.devicePixelRatio);
|
||||||
this.renderer.setSize(this.width, this.height);
|
this.renderer.setSize(this.width, this.height);
|
||||||
|
this.renderer.autoClear = false;
|
||||||
this.renderer.setClearColor(0x000000, 0.0); // second param is opacity, 0 => transparent
|
this.renderer.setClearColor(0x000000, 0.0); // second param is opacity, 0 => transparent
|
||||||
|
|
||||||
// enable clipping
|
// enable clipping
|
||||||
|
@ -100,6 +105,9 @@ class Application {
|
||||||
|
|
||||||
/* Scene: that will hold all our elements such as objects, cameras and lights. */
|
/* Scene: that will hold all our elements such as objects, cameras and lights. */
|
||||||
this.scene = new Scene();
|
this.scene = new Scene();
|
||||||
|
this.capsScene = new Scene();
|
||||||
|
this.backStencil = new Scene();
|
||||||
|
this.frontStencil = new Scene();
|
||||||
this._buildDefaultLights(this.scene);
|
this._buildDefaultLights(this.scene);
|
||||||
//app.scene.autoUpdate = false;
|
//app.scene.autoUpdate = false;
|
||||||
//// show axes in the screen
|
//// show axes in the screen
|
||||||
|
@ -160,6 +168,14 @@ class Application {
|
||||||
// create map
|
// 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');
|
// 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');
|
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 = document.querySelector('#map-title');
|
||||||
this.mapTitle.innerHTML += map.title;
|
this.mapTitle.innerHTML += map.title;
|
||||||
|
@ -226,6 +242,16 @@ class Application {
|
||||||
//slice on x and y axes:
|
//slice on x and y axes:
|
||||||
// this.slicer = new SlicerControl({ parentDiv: 'slicer-control' }).addTo(this.map);
|
// 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, 'resize', this.onWindowResize, this);
|
||||||
// domEvent.on(window, 'keydown', this.keydown, this);
|
// domEvent.on(window, 'keydown', this.keydown, this);
|
||||||
this.start();
|
this.start();
|
||||||
|
@ -311,6 +337,28 @@ class Application {
|
||||||
}
|
}
|
||||||
|
|
||||||
animate() {
|
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.renderer.render(this.scene, this.camera);
|
||||||
this.northArrow.animate();
|
this.northArrow.animate();
|
||||||
this.gridlayer.animate();
|
this.gridlayer.animate();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user