|
@@ -1,119 +1,832 @@
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+import {ViewerBase} from "../custom/viewer/viewerBase.js"
|
|
import * as THREE from "../../libs/three.js/build/three.module.js";
|
|
import * as THREE from "../../libs/three.js/build/three.module.js";
|
|
|
|
+import Viewport from "../custom/viewer/Viewport.js"
|
|
|
|
+
|
|
|
|
+import {ExtendView} from "./ExtendView.js"
|
|
|
|
+import {LineDraw/* , MeshDraw */} from "../custom/utils/DrawUtil.js";
|
|
|
|
+import {InputHandler} from "../navigation/InputHandlerNew.js";
|
|
|
|
+
|
|
|
|
+import {CameraMode } from "../defines.js"
|
|
|
|
+
|
|
|
|
+import SplitScreen from "../custom/utils/SplitScreen.js";
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+//import {FirstPersonControls} from '../navigation/FirstPersonControlsNew.js'
|
|
|
|
+
|
|
|
|
+import {OrbitControls} from "../navigation/OrbitControlsNew.js";
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+let splitScreen = new SplitScreen()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+const Colors = {
|
|
|
|
+ black : '#161A1A',
|
|
|
|
+ blue: '#00F',
|
|
|
|
+ gray: '#878585' ,
|
|
|
|
+ white:'#ffffff'
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+let navCubeViewer
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class base{
|
|
|
|
+ constructor(){
|
|
|
|
+ this.faceDefaultColor = Colors.black//14936556,
|
|
|
|
+ this.wireframeDefaultColor = 13421772,
|
|
|
|
+ this.faceHighlightColor = 12255212,
|
|
|
|
+ this.wireframeHighlightColor = 3330982
|
|
|
|
+ }
|
|
|
|
|
|
-export class NavigationCube extends THREE.Object3D {
|
|
|
|
-
|
|
|
|
- constructor(viewer){
|
|
|
|
- super();
|
|
|
|
-
|
|
|
|
- this.viewer = viewer;
|
|
|
|
-
|
|
|
|
- let createPlaneMaterial = (img) => {
|
|
|
|
- let material = new THREE.MeshBasicMaterial( {
|
|
|
|
- depthTest: true,
|
|
|
|
- depthWrite: true,
|
|
|
|
- side: THREE.DoubleSide
|
|
|
|
- });
|
|
|
|
- new THREE.TextureLoader().load(
|
|
|
|
- exports.resourcePath + '/textures/navigation/' + img,
|
|
|
|
- function(texture) {
|
|
|
|
- texture.anisotropy = viewer.renderer.capabilities.getMaxAnisotropy();
|
|
|
|
- material.map = texture;
|
|
|
|
- material.needsUpdate = true;
|
|
|
|
- });
|
|
|
|
- return material;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- let planeGeometry = new THREE.PlaneGeometry(1, 1);
|
|
|
|
-
|
|
|
|
- this.front = new THREE.Mesh(planeGeometry, createPlaneMaterial('F.png'));
|
|
|
|
- this.front.position.y = -0.5;
|
|
|
|
- this.front.rotation.x = Math.PI / 2.0;
|
|
|
|
- this.front.updateMatrixWorld();
|
|
|
|
- this.front.name = "F";
|
|
|
|
- this.add(this.front);
|
|
|
|
-
|
|
|
|
- this.back = new THREE.Mesh(planeGeometry, createPlaneMaterial('B.png'));
|
|
|
|
- this.back.position.y = 0.5;
|
|
|
|
- this.back.rotation.x = Math.PI / 2.0;
|
|
|
|
- this.back.updateMatrixWorld();
|
|
|
|
- this.back.name = "B";
|
|
|
|
- this.add(this.back);
|
|
|
|
-
|
|
|
|
- this.left = new THREE.Mesh(planeGeometry, createPlaneMaterial('L.png'));
|
|
|
|
- this.left.position.x = -0.5;
|
|
|
|
- this.left.rotation.y = Math.PI / 2.0;
|
|
|
|
- this.left.updateMatrixWorld();
|
|
|
|
- this.left.name = "L";
|
|
|
|
- this.add(this.left);
|
|
|
|
-
|
|
|
|
- this.right = new THREE.Mesh(planeGeometry, createPlaneMaterial('R.png'));
|
|
|
|
- this.right.position.x = 0.5;
|
|
|
|
- this.right.rotation.y = Math.PI / 2.0;
|
|
|
|
- this.right.updateMatrixWorld();
|
|
|
|
- this.right.name = "R";
|
|
|
|
- this.add(this.right);
|
|
|
|
-
|
|
|
|
- this.bottom = new THREE.Mesh(planeGeometry, createPlaneMaterial('D.png'));
|
|
|
|
- this.bottom.position.z = -0.5;
|
|
|
|
- this.bottom.updateMatrixWorld();
|
|
|
|
- this.bottom.name = "D";
|
|
|
|
- this.add(this.bottom);
|
|
|
|
-
|
|
|
|
- this.top = new THREE.Mesh(planeGeometry, createPlaneMaterial('U.png'));
|
|
|
|
- this.top.position.z = 0.5;
|
|
|
|
- this.top.updateMatrixWorld();
|
|
|
|
- this.top.name = "U";
|
|
|
|
- this.add(this.top);
|
|
|
|
-
|
|
|
|
- this.width = 150; // in px
|
|
|
|
-
|
|
|
|
- this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, -1, 1);
|
|
|
|
- this.camera.position.copy(new THREE.Vector3(0, 0, 0));
|
|
|
|
- this.camera.lookAt(new THREE.Vector3(0, 1, 0));
|
|
|
|
- this.camera.updateMatrixWorld();
|
|
|
|
- this.camera.rotation.order = "ZXY";
|
|
|
|
-
|
|
|
|
- let onMouseDown = (event) => {
|
|
|
|
- if (!this.visible) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this.pickedFace = null;
|
|
|
|
- let mouse = new THREE.Vector2();
|
|
|
|
- mouse.x = event.clientX - (window.innerWidth - this.width);
|
|
|
|
- mouse.y = event.clientY;
|
|
|
|
-
|
|
|
|
- if(mouse.x < 0 || mouse.y > this.width) return;
|
|
|
|
-
|
|
|
|
- mouse.x = (mouse.x / this.width) * 2 - 1;
|
|
|
|
- mouse.y = -(mouse.y / this.width) * 2 + 1;
|
|
|
|
-
|
|
|
|
- let raycaster = new THREE.Raycaster();
|
|
|
|
- raycaster.setFromCamera(mouse, this.camera);
|
|
|
|
- raycaster.ray.origin.sub(this.camera.getWorldDirection(new THREE.Vector3()));
|
|
|
|
-
|
|
|
|
- let intersects = raycaster.intersectObjects(this.children);
|
|
|
|
-
|
|
|
|
- let minDistance = 1000;
|
|
|
|
- for (let i = 0; i < intersects.length; i++) {
|
|
|
|
- if(intersects[i].distance < minDistance) {
|
|
|
|
- this.pickedFace = intersects[i].object.name;
|
|
|
|
- minDistance = intersects[i].distance;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(this.pickedFace) {
|
|
|
|
- this.viewer.setView(this.pickedFace);
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- this.viewer.renderer.domElement.addEventListener('mousedown', onMouseDown, false);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- update(rotation) {
|
|
|
|
- this.camera.rotation.copy(rotation);
|
|
|
|
- this.visible && this.camera.updateMatrixWorld();
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ createMesh(e) {
|
|
|
|
+ for (var t = new THREE.BufferGeometry, i = e.length - 2, n = new Uint32Array(3 * i), o = 0, s = 1; s <= i; s++)
|
|
|
|
+ n[o++] = 0,
|
|
|
|
+ n[o++] = s,
|
|
|
|
+ n[o++] = s + 1;
|
|
|
|
+ var r = new THREE.MeshBasicMaterial({
|
|
|
|
+ color: this.faceDefaultColor,
|
|
|
|
+ side: THREE.DoubleSide
|
|
|
|
+ })
|
|
|
|
+ , a = new Float32Array(3 * e.length);
|
|
|
|
+ t.setAttribute("position", new THREE.BufferAttribute(a,3).copyVector3sArray(e)),
|
|
|
|
+ t.setIndex(new THREE.BufferAttribute(n,1));
|
|
|
|
+ var l = new THREE.Mesh(t,r);
|
|
|
|
+ return l.componentId = this.componentId,
|
|
|
|
+ l
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ createWireframe(e, lineWidth) {
|
|
|
|
+ /* for (var t = new THREE.LineGeometry, i = [], n = 0; n < e.length; n++) {
|
|
|
|
+ var o = e[n];
|
|
|
|
+ i.push(o.x, o.y, o.z)
|
|
|
|
+ }
|
|
|
|
+ t.setPositions(i);
|
|
|
|
+ var s = new THREE.LineMaterial({
|
|
|
|
+ color: this.wireframeDefaultColor,
|
|
|
|
+ linewidth: 1
|
|
|
|
+ });
|
|
|
|
+ s.resolution.set(160, 160);
|
|
|
|
+ var r = new THREE.Line2(t,s);
|
|
|
|
+ return r.componentId = this.componentId,
|
|
|
|
+ r */
|
|
|
|
+
|
|
|
|
+ let line = LineDraw.createFatLine(e,{
|
|
|
|
+ color: Colors.gray ,
|
|
|
|
+ lineWidth ,
|
|
|
|
+ viewer: navCubeViewer,
|
|
|
|
+ depthTest:true, depthWrite:true,
|
|
|
|
+ //transparent:true
|
|
|
|
+ });
|
|
|
|
+ line.renderOrder = 3;
|
|
|
|
+ return line
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getMesh() {
|
|
|
|
+ return this.mesh
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getWireframe() {
|
|
|
|
+ return this.wireframeMesh
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ transparent(e) {
|
|
|
|
+ e.material && (e.material.transparent = !0,
|
|
|
|
+ e.material.opacity = 0)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ opaque(e) {
|
|
|
|
+ e.material && (e.material.transparent = !1,
|
|
|
|
+ e.material.opacity = 1)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getId() {
|
|
|
|
+ return this.componentId
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class Edge extends base{
|
|
|
|
+ constructor(t, i, n) {
|
|
|
|
+ super()
|
|
|
|
+
|
|
|
|
+ this.highlightWidth = 3,
|
|
|
|
+ this.width = 15,
|
|
|
|
+ this.vertices = t,
|
|
|
|
+ this.indices = i,
|
|
|
|
+ this.componentId = n,
|
|
|
|
+ this.highlightWireframeMesh = null,
|
|
|
|
+ this.testWireframe = null,
|
|
|
|
+ this.build()
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ build() {
|
|
|
|
+ var e = this.indices[0]
|
|
|
|
+ , t = this.indices[1]
|
|
|
|
+ , i = this.vertices[e]
|
|
|
|
+ , n = this.vertices[t]
|
|
|
|
+ , o = i.clone().add(n).multiplyScalar(.5).clone().multiplyScalar(-1)
|
|
|
|
+ , s = o.clone().normalize()
|
|
|
|
+ , r = []
|
|
|
|
+ , a = n.clone().sub(i).normalize()
|
|
|
|
+ , l = i.clone().add(a.clone().multiplyScalar(20))
|
|
|
|
+ , h = i.clone().add(a.clone().multiplyScalar(80))
|
|
|
|
+ , c = [];
|
|
|
|
+ if (0 !== o.x) {
|
|
|
|
+ var d = o.x > 0 ? this.width : -this.width;
|
|
|
|
+ c.push((new THREE.Vector3).setX(d).add(s))
|
|
|
|
+ }
|
|
|
|
+ if (0 !== o.y) {
|
|
|
|
+ var u = o.y > 0 ? this.width : -this.width;
|
|
|
|
+ c.push((new THREE.Vector3).setY(u).add(s))
|
|
|
|
+ }
|
|
|
|
+ if (0 !== o.z) {
|
|
|
|
+ var g = o.z > 0 ? this.width : -this.width;
|
|
|
|
+ c.push((new THREE.Vector3).setZ(g).add(s))
|
|
|
|
+ }
|
|
|
|
+ 2 === c.length && (r.push(l.clone().add(s)),
|
|
|
|
+ r.push(l.clone().add(c[0])),
|
|
|
|
+ r.push(h.clone().add(c[0])),
|
|
|
|
+ r.push(h.clone().add(s)),
|
|
|
|
+ r.push(h.clone().add(c[1])),
|
|
|
|
+ r.push(l.clone().add(c[1]))),
|
|
|
|
+ this.mesh = this.createMesh(r)
|
|
|
|
+ this.transparent(this.mesh)
|
|
|
|
+ //this.wireframeMesh = this.createWireframe([l, h]),
|
|
|
|
+ //this.highlightWireframeMesh = this.createHighlightWireframe([l.sub(s), h.sub(s)])
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ createHighlightWireframe(e) {
|
|
|
|
+ for (var t = [], i = 0; i < e.length; i++) {
|
|
|
|
+ var n = e[i];
|
|
|
|
+ t.push(n.x, n.y, n.z)
|
|
|
|
+ }
|
|
|
|
+ var o = new THREE.LineGeometry;
|
|
|
|
+ o.setPositions(t);
|
|
|
|
+ var s = new THREE.LineMaterial({
|
|
|
|
+ color: this.wireframeHighlightColor,
|
|
|
|
+ linewidth: this.highlightWidth,
|
|
|
|
+ dashed: !1
|
|
|
|
+ });
|
|
|
|
+ s.resolution.set(160, 160);
|
|
|
|
+ var r = new THREE.Line2(o,s);
|
|
|
|
+ return r.computeLineDistances(),
|
|
|
|
+ r.scale.set(1, 1, 1),
|
|
|
|
+ r.visible = !1,
|
|
|
|
+ r.renderOrder = 100,
|
|
|
|
+ r
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getTestWireframe() {
|
|
|
|
+ return this.testWireframe
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getHighlightWireframeMesh() {
|
|
|
|
+ return this.highlightWireframeMesh
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ highlight() {
|
|
|
|
+ this.highlightWireframeMesh.visible = !0,
|
|
|
|
+ this.highlightWireframeMesh.renderOrder = 100
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cancelHighlight() {
|
|
|
|
+ this.highlightWireframeMesh.visible = !1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class Corner extends base{
|
|
|
|
+ constructor(t, i) {
|
|
|
|
+ super()
|
|
|
|
+ this.length = 20,
|
|
|
|
+ this.vertex = t,
|
|
|
|
+ this.cornerFace = null,
|
|
|
|
+ this.cornerWireframe = null,
|
|
|
|
+ this.componentId = i,
|
|
|
|
+ this.cornerVertices = null,
|
|
|
|
+ this.build()
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ build() {
|
|
|
|
+ var e = []
|
|
|
|
+ , t = this.vertex.clone()
|
|
|
|
+ , i = t.clone().multiplyScalar(-1);
|
|
|
|
+ e.push(t);
|
|
|
|
+ var n = this.vertex.clone()
|
|
|
|
+ , o = i.x > 0 ? this.length : -this.length;
|
|
|
|
+ n.x += o,
|
|
|
|
+ e.push(n);
|
|
|
|
+ var s = this.vertex.clone()
|
|
|
|
+ , r = i.y > 0 ? this.length : -this.length;
|
|
|
|
+ s.y += r,
|
|
|
|
+ e.push(s);
|
|
|
|
+ var a = this.vertex.clone()
|
|
|
|
+ , l = i.z > 0 ? this.length : -this.length;
|
|
|
|
+ a.z += l,
|
|
|
|
+ e.push(a),
|
|
|
|
+ this.cornerVertices = e
|
|
|
|
+ this.mesh = this.createMesh([n, s, a])
|
|
|
|
+ this.wireframeMesh = this.createWireframe([n, s, a, n], 2),
|
|
|
|
+ this.buildCornerFace()
|
|
|
|
+ this.buildCornerWireframe()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ highlight() {
|
|
|
|
+ this.wireframeMesh.material.color.setHex(this.wireframeHighlightColor),
|
|
|
|
+ this.wireframeMesh.renderOrder = 100,
|
|
|
|
+ this.mesh.material.color.setHex(this.faceHighlightColor),
|
|
|
|
+ this.cornerFace.material.color.setHex(this.faceHighlightColor),
|
|
|
|
+ this.cornerFace.material.transparent = !0,
|
|
|
|
+ this.cornerFace.material.opacity = .5,
|
|
|
|
+ this.cornerWireframe.material.color.setHex(this.wireframeHighlightColor),
|
|
|
|
+ this.cornerWireframe.visible = !0
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cancelHighlight() {
|
|
|
|
+ this.wireframeMesh.material.color.setHex(this.wireframeDefaultColor),
|
|
|
|
+ this.wireframeMesh.renderOrder = 0,
|
|
|
|
+ this.mesh.material.color.setHex(this.faceDefaultColor),
|
|
|
|
+ this.transparent(this.cornerFace),
|
|
|
|
+ this.cornerWireframe.visible = !1
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ buildCornerFace() {
|
|
|
|
+ if (!this.cornerFace) {
|
|
|
|
+ var e = this.cornerVertices;
|
|
|
|
+ e.push(e[1]),
|
|
|
|
+ this.cornerFace = this.createMesh(e),
|
|
|
|
+ this.transparent(this.cornerFace)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getCornerFace() {
|
|
|
|
+ return this.cornerFace
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getCornerWireframe() {
|
|
|
|
+ return this.cornerWireframe
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ buildCornerWireframe() {
|
|
|
|
+ if (!this.cornerWireframe) {
|
|
|
|
+ for (var e = [], t = 1; t < this.cornerVertices.length; t++) {
|
|
|
|
+ var i = this.cornerVertices[0]
|
|
|
|
+ , n = this.cornerVertices[t];
|
|
|
|
+ e.push(i, n)
|
|
|
|
+ }
|
|
|
|
+ this.cornerWireframe = this.createWireframe(e),
|
|
|
|
+ this.cornerWireframe.visible = !1
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class Face extends base{
|
|
|
|
+ constructor(t, i, n, o){
|
|
|
|
+
|
|
|
|
+ super()
|
|
|
|
+
|
|
|
|
+ this.length = 60
|
|
|
|
+ this.vertices = t,
|
|
|
|
+ this.indices = i,
|
|
|
|
+ this.componentId = n,
|
|
|
|
+ this.vertexUvs = null,
|
|
|
|
+ this.texture = o,
|
|
|
|
+ this.highlightMesh = null,
|
|
|
|
+ this.wireframeMesh = null,
|
|
|
|
+ this.vertexUvs = [],
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(0,.2)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(0,.8)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(.2,1)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(.8,1)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(1,.8)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(1,.2)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(.8,0)),
|
|
|
|
+ this.vertexUvs.push(new THREE.Vector2(.2,0)),
|
|
|
|
+ this.build()
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ build() {
|
|
|
|
+ for (var e = [], t = null, i = null, n = 0, o = this.indices.length; n < o; n++) {
|
|
|
|
+ var s = this.indices[n]
|
|
|
|
+ , r = this.indices[n + 1];
|
|
|
|
+ t = this.vertices[s],
|
|
|
|
+ i = this.vertices[r],
|
|
|
|
+ n === o - 1 && (i = this.vertices[this.indices[0]]);
|
|
|
|
+ var a = i.clone().sub(t).normalize()
|
|
|
|
+ , l = t.clone().add(i).multiplyScalar(.5);
|
|
|
|
+ e.push(l.clone().sub(a.clone().multiplyScalar(this.length / 2))),
|
|
|
|
+ e.push(l.clone().add(a.clone().multiplyScalar(this.length / 2)))
|
|
|
|
+ }
|
|
|
|
+ this.createTexturedMesh(e);
|
|
|
|
+ for (var h = new THREE.Box3, c = 0; c < this.indices.length; c++) {
|
|
|
|
+ var d = this.indices[c];
|
|
|
|
+ h.expandByPoint(this.vertices[d])
|
|
|
|
+ }
|
|
|
|
+ for (var u = h.getCenter(new THREE.Vector3).normalize(), g = [], p = 0; p < e.length; p++) {
|
|
|
|
+ var m = e[p];
|
|
|
|
+ g.push(m.clone().add(u))
|
|
|
|
+ }
|
|
|
|
+ this.highlightMesh = this.createMesh(g)
|
|
|
|
+ this.highlightMesh.visible = !1
|
|
|
|
+ this.highlightMesh.isHighlightMesh = !0
|
|
|
|
+ g.push(g[0])
|
|
|
|
+ this.wireframeMesh = this.createWireframe(g, 1)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ highlight() {
|
|
|
|
+ this.highlightMesh.visible = !0
|
|
|
|
+ this.highlightMesh.material.color.setHex(this.faceHighlightColor)
|
|
|
|
+ this.highlightMesh.material.transparent = !0
|
|
|
|
+ this.highlightMesh.material.opacity = .5
|
|
|
|
+ //this.wireframeMesh.material.color.setHex(this.wireframeHighlightColor)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cancelHighlight() {
|
|
|
|
+ this.highlightMesh.visible = !1
|
|
|
|
+ //this.wireframeMesh.material.color.setHex(this.wireframeDefaultColor)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ createTexturedMesh(e) {
|
|
|
|
+ for (var t = e.length - 2, i = new Uint32Array(3 * t), n = 0, o = 1; o <= t; o++)
|
|
|
|
+ i[n++] = 0,
|
|
|
|
+ i[n++] = o,
|
|
|
|
+ i[n++] = o + 1;
|
|
|
|
+ var s = new THREE.BufferGeometry
|
|
|
|
+ , r = new Float32Array(3 * e.length)
|
|
|
|
+ , a = new Float32Array(2 * this.vertexUvs.length);
|
|
|
|
+ s.setAttribute("position", new THREE.BufferAttribute(r,3).copyVector3sArray(e)),
|
|
|
|
+ s.setAttribute("uv", new THREE.BufferAttribute(a,2).copyVector2sArray(this.vertexUvs)),
|
|
|
|
+ s.setIndex(new THREE.BufferAttribute(i,1));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ var l = new THREE.ShaderMaterial({
|
|
|
|
+ side: THREE.DoubleSide,
|
|
|
|
+ transparent: !1,
|
|
|
|
+ uniforms:{
|
|
|
|
+ faceColor: {type:'v3', value: new THREE.Color(Colors.black) } ,
|
|
|
|
+ textColor: {type:'v3', value: new THREE.Color(Colors.white) } ,
|
|
|
|
+ map: {type: 't', value: this.texture },
|
|
|
|
+ },
|
|
|
|
+ vertexShader:`
|
|
|
|
+ varying vec2 vUv;
|
|
|
|
+ void main() {
|
|
|
|
+ vUv = uv;
|
|
|
|
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
|
|
+ }`,
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ fragmentShader:`
|
|
|
|
+ varying vec2 vUv;
|
|
|
|
+ uniform vec3 faceColor;
|
|
|
|
+ uniform vec3 textColor;
|
|
|
|
+ uniform sampler2D map;
|
|
|
|
+ void main() {
|
|
|
|
+ //从图上实测
|
|
|
|
+ const float mapFaceColorR = 0.85;
|
|
|
|
+ const float mapTextColotR = 0.45;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ vec4 texColor = texture2D(map, vUv);
|
|
|
|
+ if(texColor.r > mapFaceColorR){
|
|
|
|
+ gl_FragColor = vec4(faceColor, texColor.a);
|
|
|
|
+ }else if(texColor.r<mapTextColotR){
|
|
|
|
+ gl_FragColor = vec4(textColor, texColor.a);
|
|
|
|
+ }else{//抗锯齿 过渡
|
|
|
|
+ float faceRatio = (texColor.r - mapTextColotR) / (mapFaceColorR - mapTextColotR);
|
|
|
|
+ gl_FragColor = vec4( mix(textColor, faceColor, faceRatio), texColor.a);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ `
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ this.mesh = new THREE.Mesh(s,l),
|
|
|
|
+ this.mesh.componentId = this.componentId
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getHighlightMesh() {
|
|
|
|
+ return this.highlightMesh
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ buildVertexUvs(e) {
|
|
|
|
+ var t = []
|
|
|
|
+ , i = (new THREE.Box3).setFromPoints(e)
|
|
|
|
+ , n = i.min
|
|
|
|
+ , o = new THREE.Vector2;
|
|
|
|
+ i.getSize(o);
|
|
|
|
+ for (var s = 0 == o.x ? "x" : 0 == o.y ? "y" : "z", r = 0; r < e.length; r++) {
|
|
|
|
+ var a = e[r]
|
|
|
|
+ , l = (o.x + o.y + o.z) / 2
|
|
|
|
+ , h = a.clone().sub(n).multiplyScalar(1 / l)
|
|
|
|
+ , c = new THREE.Vector2(h.x,h.y);
|
|
|
|
+ "x" == s ? c = new THREE.Vector2(h.y,h.z) : "y" == s && (c = new THREE.Vector2(h.x,h.z)),
|
|
|
|
+ t.push(c)
|
|
|
|
+ }
|
|
|
|
+ return t
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class NavigationCube{
|
|
|
|
+ constructor(scene, length){
|
|
|
|
+ this.scene = scene
|
|
|
|
+ this.length = length
|
|
|
|
+ this.initialize()
|
|
|
|
+
|
|
|
|
+ /*this.callback = t
|
|
|
|
+ this.buildEdges() */
|
|
|
|
+ this.buildCorners()
|
|
|
|
+ this.buildFaces()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ initialize(){
|
|
|
|
+ this.enumViewMode = {
|
|
|
|
+ "2673": "Top", //数字是面的faceIndex组合
|
|
|
|
+ "4015": "Bottom",
|
|
|
|
+ "0231": "Front",
|
|
|
|
+ "5764": "Back",
|
|
|
|
+ "1375": "Right",
|
|
|
|
+ "4620": "Left",
|
|
|
|
+ 3: "RoofSouthEast",
|
|
|
|
+ 2: "RoofSouthWest",
|
|
|
|
+ 7: "RoofNorthEast",
|
|
|
|
+ 6: "RoofNorthWest",
|
|
|
|
+ 1: "BottomSouthEast",
|
|
|
|
+ 0: "BottomSouthWest",
|
|
|
|
+ 4: "BottomNorthWest",
|
|
|
|
+ 5: "BottomNorthEast",
|
|
|
|
+ 32: "RoofFront",
|
|
|
|
+ 76: "RoofBack",
|
|
|
|
+ 37: "RoofRight",
|
|
|
|
+ 26: "RoofLeft",
|
|
|
|
+ "01": "BottomFront",
|
|
|
|
+ 45: "BottomBack",
|
|
|
|
+ 15: "BottomRight",
|
|
|
|
+ "04": "BottomLeft",
|
|
|
|
+ 13: "SouthEast",
|
|
|
|
+ 20: "SouthWest",
|
|
|
|
+ 57: "NorthEast",
|
|
|
|
+ 64: "NorthWest"
|
|
|
|
+ }
|
|
|
|
+ this.vertices = [],
|
|
|
|
+ this.vertexIds = [],
|
|
|
|
+ this.edgeIds = [],
|
|
|
|
+ this.edgeIndices = [],
|
|
|
|
+ this.faceIds = [],
|
|
|
|
+ this.faceIndices = [],
|
|
|
|
+ this.componentList = []
|
|
|
|
+
|
|
|
|
+ var e = this.length;
|
|
|
|
+ //立方体八个点
|
|
|
|
+ this.vertices.push(new THREE.Vector3(-e / 2,-e / 2,e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(e / 2,-e / 2,e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(-e / 2,e / 2,e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(e / 2,e / 2,e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(-e / 2,-e / 2,-e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(e / 2,-e / 2,-e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(-e / 2,e / 2,-e / 2)),
|
|
|
|
+ this.vertices.push(new THREE.Vector3(e / 2,e / 2,-e / 2));
|
|
|
|
+ for (var t = 0; t < 8; t++)
|
|
|
|
+ this.vertexIds.push(t + "");
|
|
|
|
+ //12条边
|
|
|
|
+ this.edgeIndices.push([0, 1], [1, 3], [3, 2], [2, 0]),
|
|
|
|
+ this.edgeIndices.push([0, 4], [1, 5], [2, 6], [3, 7]),
|
|
|
|
+ this.edgeIndices.push([4, 5], [5, 7], [7, 6], [6, 4]);
|
|
|
|
+ for (t = 0; t < 12; t++) {
|
|
|
|
+ var i = this.edgeIndices[t];
|
|
|
|
+ this.edgeIds.push(i[0] + "" + i[1])
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //6个面,每个面2个三角形
|
|
|
|
+ this.faceIndices.push([0, 2, 3, 1]),
|
|
|
|
+ this.faceIndices.push([4, 0, 1, 5]),
|
|
|
|
+ this.faceIndices.push([4, 6, 2, 0]),
|
|
|
|
+ this.faceIndices.push([2, 6, 7, 3]),
|
|
|
|
+ this.faceIndices.push([1, 3, 7, 5]),
|
|
|
|
+ this.faceIndices.push([5, 7, 6, 4]);
|
|
|
|
+
|
|
|
|
+ for (t = 0; t < 6; t++) {
|
|
|
|
+ var n = this.faceIndices[t];
|
|
|
|
+ this.faceIds.push(n[0] + "" + n[1] + n[2] + n[3])
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ buildFaces() {
|
|
|
|
+ const directions = {
|
|
|
|
+ Top : new THREE.Vector3(0,0,-1),
|
|
|
|
+ Bottom : new THREE.Vector3(0,0,1),
|
|
|
|
+ Left : new THREE.Vector3(1,0,0),
|
|
|
|
+ Right : new THREE.Vector3(-1,0,0),
|
|
|
|
+ Front : new THREE.Vector3(0,1,0),
|
|
|
|
+ Back : new THREE.Vector3(0,-1,0),
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ let texturesLoaded = 0
|
|
|
|
+ let create = (n)=>{
|
|
|
|
+ let name = this.enumViewMode[this.faceIds[n]]
|
|
|
|
+ var url = Potree.resourcePath+'/textures/navigation/' + name + ".png"
|
|
|
|
+ , r = new THREE.TextureLoader;
|
|
|
|
+ r.setCrossOrigin("anonymous");
|
|
|
|
+ r.load(url, (tex)=> {
|
|
|
|
+ var face = new Face(e,t[n], this.faceIds[n], tex);
|
|
|
|
+ this.componentList.push(face)
|
|
|
|
+ let faceMesh = face.getMesh()
|
|
|
|
+ this.scene.add(faceMesh)
|
|
|
|
+ this.scene.add(face.getWireframe())
|
|
|
|
+ /* this.scene.add(face.getHighlightMesh()) */
|
|
|
|
+ //6 == ++texturesLoaded && a.callback && a.callback()
|
|
|
|
+
|
|
|
|
+ //不过平板无hover事件
|
|
|
|
+ faceMesh.addEventListener('mouseover', (e)=>{
|
|
|
|
+ if(this.changingView)return
|
|
|
|
+ faceMesh.material.uniforms.faceColor.value.set(Colors.blue)
|
|
|
|
+ //console.log('变', name)
|
|
|
|
+ navCubeViewer.dispatchEvent('content_changed')
|
|
|
|
+ });
|
|
|
|
+ faceMesh.addEventListener('mouseleave', (e)=>{
|
|
|
|
+ if(this.changingView)return
|
|
|
|
+ faceMesh.material.uniforms.faceColor.value.set(Colors.black)
|
|
|
|
+ //console.log('回', name)
|
|
|
|
+ navCubeViewer.dispatchEvent('content_changed')
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ faceMesh.addEventListener('click', (e)=>{
|
|
|
|
+ this.changingView = true
|
|
|
|
+ faceMesh.material.uniforms.faceColor.value.set(Colors.blue)
|
|
|
|
+ /*
|
|
|
|
+ this.changingView = true
|
|
|
|
+ let viewStart = viewer.scene.view.clone();
|
|
|
|
+ viewer["set"+name+'View']()
|
|
|
|
+ let viewEnd = viewer.scene.view.clone();
|
|
|
|
+ viewer.scene.view.copy(viewStart) //先变回来,以渐变
|
|
|
|
+
|
|
|
|
+ let duration = 4000
|
|
|
|
+ viewer.scene.view.setView({
|
|
|
|
+ position: viewEnd.position ,
|
|
|
|
+ quaternion:new THREE.Quaternion().setFromEuler(viewEnd.rotation),
|
|
|
|
+ duration,
|
|
|
|
+ callback: ()=>{
|
|
|
|
+ this.changingView = false
|
|
|
|
+ faceMesh.material.uniforms.faceColor.value.set(Colors.black)
|
|
|
|
+ console.log('回2', name)
|
|
|
|
+ navCubeViewer.dispatchEvent('content_changed')
|
|
|
|
+ },onUpdate: (e)=>{
|
|
|
|
+ console.log(e, viewer.scene.view.position.toArray(), viewer.scene.view.rotation.toArray())
|
|
|
|
+ }
|
|
|
|
+ }) */
|
|
|
|
+ if(viewer.mainViewport.camera != viewer.scene.cameraO){
|
|
|
|
+ viewer.scene.cameraO.position.copy(viewer.mainViewport.camera.position)
|
|
|
|
+ viewer.scene.cameraO.quaternion.copy(viewer.mainViewport.camera.quaternion)
|
|
|
|
+ viewer.mainViewport.camera = viewer.scene.cameraO
|
|
|
|
+ viewer.setCameraMode(CameraMode.ORTHOGRAPHIC)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ viewer.focusOnObject(viewer.bound, 'boundingBox', 1000, {dir:directions[name].clone()}).promise.done(()=>{
|
|
|
|
+ this.changingView = false
|
|
|
|
+ faceMesh.material.uniforms.faceColor.value.set(Colors.black)
|
|
|
|
+ //console.log('回2', name)
|
|
|
|
+ navCubeViewer.dispatchEvent('content_changed')
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ for (var e = this.vertices, t = this.faceIndices, s = 0; s < 6; s++){
|
|
|
|
+ create(s)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ buildEdges() {
|
|
|
|
+ for (var e = this.vertices, t = this.edgeIndices, i = this.edgeIds, n = 0; n < 12; n++) {
|
|
|
|
+ var o = new Edge(e,t[n],i[n]);
|
|
|
|
+ this.componentList.push(o),
|
|
|
|
+ this.scene.add(o.getMesh()),
|
|
|
|
+ this.scene.add(o.getWireframe()),
|
|
|
|
+ this.scene.add(o.getHighlightWireframeMesh())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ buildCorners() {
|
|
|
|
+ for (var e = this.vertices, t = this.vertexIds, i = 0; i < 8; i++) {
|
|
|
|
+ var n = new Corner(e[i],t[i]);
|
|
|
|
+ this.componentList.push(n)
|
|
|
|
+ this.scene.add(n.getMesh())
|
|
|
|
+ this.scene.add(n.getWireframe()),
|
|
|
|
+ this.scene.add(n.getCornerFace())
|
|
|
|
+ this.scene.add(n.getCornerWireframe())
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getComponent(e) {
|
|
|
|
+ for (var t = 0; t < this.componentList.length; t++) {
|
|
|
|
+ var i = this.componentList[t];
|
|
|
|
+ if (i.getId() == e)
|
|
|
|
+ return i
|
|
|
|
+ }
|
|
|
|
+ return null
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ getMeshes() {
|
|
|
|
+ for (var e = [], t = this.scene.children, i = 0; i < t.length; i++) {
|
|
|
|
+ var n = t[i];
|
|
|
|
+ "Mesh" === n.type && !0 !== n.isHighlightMesh && e.push(n)
|
|
|
|
+ }
|
|
|
|
+ return e
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ destroy() {
|
|
|
|
+ this.scene = null,
|
|
|
|
+ this.vertices = null,
|
|
|
|
+ this.vertexIds = null,
|
|
|
|
+ this.edgeIds = null,
|
|
|
|
+ this.edgeIndices = null,
|
|
|
|
+ this.faceIds = null,
|
|
|
|
+ this.faceIndices = null,
|
|
|
|
+ this.componentList = null,
|
|
|
|
+ this.enumViewMode = null
|
|
|
|
+ }
|
|
|
|
+ , */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+class NavCubeViewer extends ViewerBase{
|
|
|
|
+ constructor(domElement, listenViewport){
|
|
|
|
+ super(domElement, {name:'navCube', antialias:true/* , preserveDrawingBuffer:true */} )
|
|
|
|
+
|
|
|
|
+ navCubeViewer = this
|
|
|
|
+ this.scene = new THREE.Scene
|
|
|
|
+ this.scene.rotation.x = Math.PI/2 //Yup->Zup
|
|
|
|
+
|
|
|
|
+ this.listenViewport = listenViewport
|
|
|
|
+
|
|
|
|
+ let w = 200
|
|
|
|
+ this.camera = new THREE.OrthographicCamera(-w/2,w/2,w/2,-w/2 , 1, w*4);
|
|
|
|
+ this.camera.zoom = (domElement.clientWidth || 300) / w * 1.267//zoom越大视野越小
|
|
|
|
+ this.camera.updateProjectionMatrix()
|
|
|
|
+ this.view = new ExtendView();
|
|
|
|
+ /* this.view.position.set(0,0,0);
|
|
|
|
+ this.view.lookAt(0,0,0) */
|
|
|
|
+ this.viewports = [new Viewport( this.view, this.camera, {
|
|
|
|
+ left:0, bottom:0, width:1, height: 1, name:'navCube'
|
|
|
|
+ }) ]
|
|
|
|
+
|
|
|
|
+ this.cube = new NavigationCube(this.scene, w/2 )
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ viewer.addEventListener('camera_changed', e => {
|
|
|
|
+ if (e.viewport == listenViewport && (/* e.changeInfo.positionChanged || */e.changeInfo.quaternionChanged)) {
|
|
|
|
+ this.updateCamera()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ this.controls = new OrbitControls(this, this.viewports[0]);
|
|
|
|
+ this.controls.setEnable(true)
|
|
|
|
+ this.controls.setScene(true)
|
|
|
|
+ this.view.radius = this.cube.length * 3//相机距离
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //事件
|
|
|
|
+ this.inputHandler = new InputHandler(this, this.scene);
|
|
|
|
+ this.inputHandler.name = 'navCube'
|
|
|
|
+ //this.inputHandler.addInputListener(this.controls);
|
|
|
|
+ this.inputHandler.registerInteractiveScene(this.scene);//interactiveScenes
|
|
|
|
+ this.viewports[0].interactiveScenes = this.inputHandler.interactiveScenes;//供viewer的inputHandler使用
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ viewer.addEventListener('allLoaded',()=>{
|
|
|
|
+ let viewportProps = [{
|
|
|
|
+ left:0, bottom:0,
|
|
|
|
+ width:1, height:1,
|
|
|
|
+ name : "MainView",
|
|
|
|
+ //axis:["y","z"],
|
|
|
|
+ //direction : new THREE.Vector3(1,0,0),
|
|
|
|
+ active: true,
|
|
|
|
+ //相机位置在x轴负向 右下角屏
|
|
|
|
+ viewContainsPoints:[new THREE.Vector3(0,0,0)],
|
|
|
|
+ margin:{x:300, y:250} ,
|
|
|
|
+ } ]
|
|
|
|
+ splitScreen.splitStart(viewportProps)
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ render(){
|
|
|
|
+ this.renderer.render(this.scene, this.camera)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ update(delta){
|
|
|
|
+ this.updateScreenSize()
|
|
|
|
+ this.controls.update(delta)
|
|
|
|
+ this.view.applyToCamera(this.camera)
|
|
|
|
+
|
|
|
|
+ let changed = this.cameraChanged()
|
|
|
|
+ if(changed || this.needRender){
|
|
|
|
+ this.needRender = false
|
|
|
|
+ this.render()
|
|
|
|
+ this.applyToMainView()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ updateCamera(){
|
|
|
|
+ let view = this.listenViewport.view
|
|
|
|
+ this.view.quaternion = view.quaternion //this.view.rotation = view.rotation
|
|
|
|
+ var dir = view.direction; //相机朝向
|
|
|
|
+ this.view.position.copy(dir.multiplyScalar(this.view.radius).negate()) //相机绕着指南针中心(000)转动
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ applyToMainView(){
|
|
|
|
+ let view = this.listenViewport.view
|
|
|
|
+ view.quaternion = this.view.quaternion
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pushHomeBtn(){
|
|
|
|
+ if(viewer.mainViewport.camera == viewer.scene.cameraO){
|
|
|
|
+ //viewer.scene.cameraP.position.copy(viewer.mainViewport.camera.position)
|
|
|
|
+ //viewer.scene.cameraP.quaternion.copy(viewer.mainViewport.camera.quaternion)
|
|
|
|
+ viewer.mainViewport.camera = viewer.scene.cameraP
|
|
|
|
+ viewer.setCameraMode(CameraMode.PERSPECTIVE)
|
|
|
|
+
|
|
|
|
+ //假设保持到目前中心的视角范围不变
|
|
|
|
+ let view = viewer.mainViewport.view
|
|
|
|
+ splitScreen.setShiftTarget(viewer.mainViewport, viewer.bound.center)
|
|
|
|
+ viewer.mainViewport.targetPlane.setFromNormalAndCoplanarPoint( view.direction.clone(), viewer.bound.center )
|
|
|
|
+ viewer.mainViewport.targetPlane.projectPoint(view.position, viewer.mainViewport.shiftTarget )
|
|
|
|
+
|
|
|
|
+ let halfHeight = viewer.scene.cameraO.top/viewer.scene.cameraO.zoom
|
|
|
|
+ let dis = halfHeight / Math.tan( THREE.Math.degToRad(viewer.scene.cameraP.fov/2))
|
|
|
|
+
|
|
|
|
+ view.position.copy(viewer.mainViewport.shiftTarget).sub(view.direction.clone().multiplyScalar(dis));
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ rotateSideCamera(angle){
|
|
|
|
+ splitScreen.rotateSideCamera(viewer.mainViewport,angle)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+export {NavCubeViewer}
|