bill 1 year ago
parent
commit
069b14b1ee
3 changed files with 124 additions and 6 deletions
  1. 107 0
      src/app/liantong/index.ts
  2. 12 3
      src/board/packages/container.ts
  3. 5 3
      src/board/plugins/camera-plugin.ts

+ 107 - 0
src/app/liantong/index.ts

@@ -1,4 +1,12 @@
 import {
 import {
+  Euler,
+  MathUtils,
+  Matrix4,
+  OrthographicCamera,
+  Quaternion,
+  Vector3,
+} from "three";
+import {
   CameraQueryPlugin,
   CameraQueryPlugin,
   EditPoi,
   EditPoi,
   EditWholeLine,
   EditWholeLine,
@@ -32,9 +40,54 @@ export type CopyProps = {
   dire?: number[];
   dire?: number[];
 };
 };
 
 
+const temp = {
+  rooms: [
+    {
+      id: "0",
+      points: [
+        { x: -4.158378227724868, y: -1.9303326184126997, id: "2" },
+        { x: -0.8163098137566145, y: -2.4105148617989434, id: "3" },
+        { x: -0.7586879445502657, y: 0.3169202806349194, id: "4" },
+        { x: -3.826915381847119, y: 0.3766487888964334, id: "5" },
+        { x: -15.327417208888889, y: -12.36848245920904, id: "6" },
+        { x: -9.104255334603174, y: -12.36848245920904, id: "7" },
+        { x: -9.104255334603174, y: -9.671413113728732, id: "8" },
+        { x: -0.941157197037036, y: -9.671413113728732, id: "9" },
+        { x: -0.9411571970370356, y: -7.098550909158703, id: "10" },
+        { x: -8.681694960423279, y: -7.098550909158701, id: "11" },
+        { x: -15.327417208888885, y: -14.869918864249149, id: "12" },
+        { x: -9.008218885925924, y: -14.869918864249149, id: "13" },
+        { x: -9.008218885925924, y: -10.44256591441262, id: "14" },
+        { x: -1.2484738328042297, y: -10.44256591441262, id: "15" },
+      ],
+      polygons: [
+        { id: "2", lineIds: ["2", "3", "4", "5"] },
+        { id: "3", lineIds: ["6", "7", "8", "9", "10"] },
+        { id: "4", lineIds: ["11", "12", "13"] },
+      ],
+      lines: [
+        { id: "2", pointIds: ["2", "3"] },
+        { id: "3", pointIds: ["3", "4"] },
+        { id: "4", pointIds: ["4", "5"] },
+        { id: "5", pointIds: ["5", "2"] },
+        { id: "6", pointIds: ["6", "7"] },
+        { id: "7", pointIds: ["7", "8"] },
+        { id: "8", pointIds: ["8", "9"] },
+        { id: "9", pointIds: ["9", "10"] },
+        { id: "10", pointIds: ["10", "11"] },
+        { id: "11", pointIds: ["12", "13"] },
+        { id: "12", pointIds: ["13", "14"] },
+        { id: "13", pointIds: ["14", "15"] },
+      ],
+    },
+  ],
+  pois: [],
+};
+
 export const createBoard = (
 export const createBoard = (
   props: { dom?: HTMLDivElement; store?: Store } = {}
   props: { dom?: HTMLDivElement; store?: Store } = {}
 ) => {
 ) => {
+  props.store = temp;
   const data = props.store || {
   const data = props.store || {
     rooms: [{ id: "0", points: [], polygons: [], lines: [] }],
     rooms: [{ id: "0", points: [], polygons: [], lines: [] }],
     pois: [],
     pois: [],
@@ -50,6 +103,7 @@ export const createBoard = (
     }
     }
   });
   });
 
 
+  // const prevMat:
   return {
   return {
     ...board,
     ...board,
     bus,
     bus,
@@ -66,6 +120,59 @@ export const createBoard = (
         poi.shape.hide();
         poi.shape.hide();
       });
       });
     },
     },
+    setCamera(camera: OrthographicCamera) {
+      // -1 - 1转到屏幕
+      // const bound = board.bound.bound;
+      // const realWidth = bound[2] - bound[0];
+      // const realHeight = bound[3] - bound[1];
+
+      // let cameraDir = new Vector3(0, 0, -1).applyQuaternion(camera.quaternion);
+      // let rad = Math.atan2(cameraDir.x, cameraDir.z); //向下看时绕y轴旋转角度
+
+      // let scaleMat = new Matrix4().makeScale(realWidth, realHeight, 1);
+      // let posMat = new Matrix4().makeTranslation(
+      //   camera.position.x,
+      //   camera.position.z,
+      //   0
+      // );
+      // let rotMat = new Matrix4().makeRotationZ(rad); //3d场景里y朝上
+
+      // let tStageMat = scaleMat.premultiply(rotMat).premultiply(posMat);
+
+      // const cameraMat = tStageMat.toArray();
+      // board.bound.setCameraMat(cameraMat);
+
+      board.bound.bus.off("cameraChange");
+
+      // -1 - 1转到屏幕
+      const bound = board.bound.bound;
+      const realWidth = bound[2] - bound[0];
+      const realHeight = bound[3] - bound[1];
+      const lastMat = new Matrix4().makeRotationX(Math.PI / 2);
+      let prevMat = new Matrix4()
+        .multiply(new Matrix4().makeScale(1, -1, 1))
+        .multiply(new Matrix4().scale(new Vector3(realWidth, realHeight, 1)))
+        .multiply(new Matrix4().makeScale(0.5, 0.5, 0.5))
+        .multiply(camera.projectionMatrix);
+
+      const temp = new Matrix4()
+        .multiply(lastMat)
+        .multiply(camera.matrix.clone())
+        .invert();
+
+      const tStageMat = prevMat.clone().multiply(temp);
+      board.bound.setCameraMat(tStageMat.toArray());
+
+      board.bound.bus.on("cameraChange", () => {
+        const cameraMat = board.bound.cameraMat
+          .clone()
+          .premultiply(prevMat.clone().invert())
+          .invert()
+          .premultiply(lastMat.clone().invert());
+
+        cameraMat.decompose(camera.position, camera.quaternion, camera.scale);
+      });
+    },
     showPois() {
     showPois() {
       const pois = board.tree.entrys.pois as Entity[];
       const pois = board.tree.entrys.pois as Entity[];
       pois.forEach((poi) => {
       pois.forEach((poi) => {

+ 12 - 3
src/board/packages/container.ts

@@ -238,13 +238,22 @@ export class Container<
 
 
     mat.decompose(translate, quaternion, scale);
     mat.decompose(translate, quaternion, scale);
     // 将四元数转换为欧拉角
     // 将四元数转换为欧拉角
-    const euler = new Euler().setFromQuaternion(quaternion, "XYZ");
+    const ag = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"] as const;
+    let euler = new Euler();
+    for (let i = 0; i < ag.length; i++) {
+      euler.setFromQuaternion(quaternion, ag[i]);
+      const a = Math.abs(MathUtils.radToDeg(euler.z) % 90);
+      if (Math.abs(a) < 5) {
+        break;
+      }
+    }
+    euler.setFromQuaternion(quaternion, "XYZ");
     // 提取绕Z轴的旋转,即二维旋转角度
     // 提取绕Z轴的旋转,即二维旋转角度
     const rotationZ = euler.z; // 在Three.js中,角度是以弧度表示的
     const rotationZ = euler.z; // 在Three.js中,角度是以弧度表示的
-
+    console.log(MathUtils.radToDeg(euler.z));
     // 更新Konva Stage的位置和缩放
     // 更新Konva Stage的位置和缩放
-    this.stage.position({ x: translate.x, y: translate.y });
     this.stage.scale({ x: scale.x, y: scale.y });
     this.stage.scale({ x: scale.x, y: scale.y });
+    this.stage.position({ x: translate.x, y: translate.y });
     this.stage.rotation(MathUtils.radToDeg(rotationZ));
     this.stage.rotation(MathUtils.radToDeg(rotationZ));
     this.redraw();
     this.redraw();
 
 

+ 5 - 3
src/board/plugins/camera-plugin.ts

@@ -162,6 +162,7 @@ export class CameraQueryPlugin {
     this.setBound(bound, padding);
     this.setBound(bound, padding);
   }
   }
 
 
+  realBound: number[];
   setBound(bound: number[], padding?: number | number[]) {
   setBound(bound: number[], padding?: number | number[]) {
     padding = !Array.isArray(padding) ? [padding || 0, padding || 0] : padding;
     padding = !Array.isArray(padding) ? [padding || 0, padding || 0] : padding;
     if (padding.length === 1) {
     if (padding.length === 1) {
@@ -187,12 +188,13 @@ export class CameraQueryPlugin {
     const scaleY = effectiveHeight / realHeight;
     const scaleY = effectiveHeight / realHeight;
     const scale = Math.min(scaleX, scaleY); // 选择较小的比例以保持内容比例
     const scale = Math.min(scaleX, scaleY); // 选择较小的比例以保持内容比例
 
 
-    const offsetX = (screenWidth - realWidth * scale) / 2 - bound[0] * scale;
-    const offsetY = (screenHeight - realHeight * scale) / 2 - bound[1] * scale;
+    const offsetX = (screenWidth - realWidth * scaleX) / 2 - bound[0] * scaleX;
+    const offsetY =
+      (screenHeight - realHeight * scaleY) / 2 - bound[1] * scaleY;
 
 
     // 创建矩阵并应用缩放
     // 创建矩阵并应用缩放
     const matrix = new Matrix4()
     const matrix = new Matrix4()
-      .scale(new Vector3(scale, scale, 1))
+      .scale(new Vector3(scaleX, scaleY, 1))
       .setPosition(offsetX, offsetY, 0);
       .setPosition(offsetX, offsetY, 0);
 
 
     this.bound = bound;
     this.bound = bound;