|
@@ -0,0 +1,179 @@
|
|
|
+import * as THREE from 'three';
|
|
|
+export const ThreeCubeDetailClass = {
|
|
|
+ constructor(options) {
|
|
|
+ this.webgl = options.webgl;
|
|
|
+ this.view = options.view;
|
|
|
+ this.points = options.points;
|
|
|
+ this.mesh = null;
|
|
|
+ this.edges = null;
|
|
|
+ this._camera = null;
|
|
|
+ },
|
|
|
+ initialize(){
|
|
|
+ this.renderer = new THREE.WebGLRenderer({
|
|
|
+ context:this.gl,
|
|
|
+ premultipliedAlpha:false
|
|
|
+ })
|
|
|
+ this.renderer.setPixelRatio(window.devicePixelRatio);
|
|
|
+ this.renderer.setViewport(0,0,this.view.width,this.view.height);
|
|
|
+
|
|
|
+ this.renderer.autoClear = false;
|
|
|
+ this.renderer.autoClearDepth = false;
|
|
|
+ this.renderer.autoClearColor = false;
|
|
|
+ let originalSetRenderTarget = this.renderer.setRenderTarget.bind(this.renderer);
|
|
|
+ this.renderer.setRenderTarget = function (target) {
|
|
|
+ originalSetRenderTarget(target);
|
|
|
+ if (target == null) {
|
|
|
+ context.bindRenderTarget();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ this.scene = new THREE.Scene();
|
|
|
+ let cam = this.camera;
|
|
|
+ this._camera = new THREE.PerspectiveCamera(cam.fovY, cam.aspect, 0.1, 1000000000);
|
|
|
+
|
|
|
+ const axesHelper = new THREE.AxesHelper(1);
|
|
|
+ axesHelper.position.copy(1000000, 100000, 100000);
|
|
|
+ this.scene.add(axesHelper);
|
|
|
+ let grid = new THREE.GridHelper(30, 10, 0xf0f0f0, 0xffffff);
|
|
|
+ this.scene.add(grid);
|
|
|
+
|
|
|
+ this.createInstancedMesh();
|
|
|
+
|
|
|
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
|
|
|
+ this.scene.add(ambientLight);
|
|
|
+
|
|
|
+ const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
|
|
|
+ directionalLight.position.set(10, 10, 10);
|
|
|
+ this.scene.add(directionalLight);
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+ createInstancedMesh() {
|
|
|
+
|
|
|
+ const boxGeometry = new THREE.BoxGeometry(this.size.z, this.size.x, this.size.y);
|
|
|
+ boxGeometry.computeVertexNormals();
|
|
|
+
|
|
|
+
|
|
|
+ const material = new THREE.MeshPhongMaterial({
|
|
|
+ transparent: true,
|
|
|
+ opacity: 0.1,
|
|
|
+ depthTest: true,
|
|
|
+ side: THREE.DoubleSide,
|
|
|
+ depthWrite: false,
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ material.onBeforeCompile = (shader) => {
|
|
|
+ shader.vertexShader = `
|
|
|
+ attribute vec3 instanceColor;
|
|
|
+ varying vec3 vColor;
|
|
|
+ ` + shader.vertexShader;
|
|
|
+
|
|
|
+ shader.vertexShader = shader.vertexShader.replace(
|
|
|
+ `#include <begin_vertex>`,
|
|
|
+ `
|
|
|
+ #include <begin_vertex>
|
|
|
+ vColor = instanceColor;
|
|
|
+ `
|
|
|
+ );
|
|
|
+ shader.fragmentShader = `
|
|
|
+ varying vec3 vColor;
|
|
|
+ ` + shader.fragmentShader;
|
|
|
+
|
|
|
+ shader.fragmentShader = shader.fragmentShader.replace(
|
|
|
+ `#include <dithering_fragment>`,
|
|
|
+ `
|
|
|
+ #include <dithering_fragment>
|
|
|
+ gl_FragColor.rgb = vColor;
|
|
|
+ `
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ this.mesh = new THREE.InstancedMesh(boxGeometry, material, this.points.length);
|
|
|
+
|
|
|
+
|
|
|
+ const edgesGeometry = new THREE.EdgesGeometry(boxGeometry);
|
|
|
+ const edgesGroup = new THREE.Group();
|
|
|
+
|
|
|
+ const dummy = new THREE.Object3D();
|
|
|
+ const instanceColors = new Float32Array(this.points.length * 3);
|
|
|
+
|
|
|
+
|
|
|
+ for (let i = 0; i < this.points.length; i++) {
|
|
|
+ const worldX = this.points[i].x;
|
|
|
+ const worldY = this.points[i].y;
|
|
|
+ const worldZ = this.points[i].z;
|
|
|
+ const renderPos = [];
|
|
|
+
|
|
|
+
|
|
|
+ this.webgl.toRenderCoordinates(
|
|
|
+ this.view,
|
|
|
+ [worldX, worldY, worldZ],
|
|
|
+ 0,
|
|
|
+ this.view.spatialReference,
|
|
|
+ renderPos,
|
|
|
+ 0,
|
|
|
+ 1
|
|
|
+ );
|
|
|
+
|
|
|
+
|
|
|
+ dummy.position.set(renderPos[0], renderPos[1], renderPos[2]);
|
|
|
+ dummy.updateMatrix();
|
|
|
+
|
|
|
+
|
|
|
+ this.mesh.setMatrixAt(i, dummy.matrix);
|
|
|
+
|
|
|
+
|
|
|
+ const color = this.points[i].color;
|
|
|
+ instanceColors[i * 3] = 1;
|
|
|
+ instanceColors[i * 3 + 1] = 0;
|
|
|
+ instanceColors[i * 3 + 2] = 0;
|
|
|
+
|
|
|
+
|
|
|
+ const glowMaterial = new THREE.LineBasicMaterial({
|
|
|
+ color: new THREE.Color(1, 0, 0),
|
|
|
+ linewidth: 2,
|
|
|
+ transparent: true,
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ const edgeLine = new THREE.LineSegments(edgesGeometry, glowMaterial);
|
|
|
+ edgeLine.position.copy(dummy.position);
|
|
|
+ edgeLine.rotation.copy(dummy.rotation);
|
|
|
+ edgeLine.scale.copy(dummy.scale);
|
|
|
+ edgesGroup.add(edgeLine);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ boxGeometry.setAttribute('instanceColor', new THREE.InstancedBufferAttribute(instanceColors, 3));
|
|
|
+ boxGeometry.attributes.instanceColor.needsUpdate = true;
|
|
|
+ this.mesh.instanceMatrix.needsUpdate = true;
|
|
|
+
|
|
|
+
|
|
|
+ this.scene.add(this.mesh);
|
|
|
+ this.scene.add(edgesGroup);
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ render(){
|
|
|
+ let cam = this.camera;
|
|
|
+
|
|
|
+ this._camera.position.set(cam.eye[0], cam.eye[1], cam.eye[2]);
|
|
|
+ this._camera.up.set(cam.up[0], cam.up[1], cam.up[2]);
|
|
|
+ this._camera.lookAt(new THREE.Vector3(cam.center[0], cam.center[1], cam.center[2]));
|
|
|
+
|
|
|
+ this._camera.projectionMatrix.fromArray(cam.projectionMatrix);
|
|
|
+
|
|
|
+ this.renderer.state.reset();
|
|
|
+
|
|
|
+ this.bindRenderTarget();
|
|
|
+ this.renderer.render(this.scene, this._camera);
|
|
|
+
|
|
|
+ this.requestRender();
|
|
|
+
|
|
|
+
|
|
|
+ this.resetWebGLState();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|