RepliCAD

Форк
0
/
ProjectionCamera.ts 
114 строк · 3.0 Кб
1
import type { gp_Ax2 } from "replicad-opencascadejs";
2
import { asDir, asPnt, makeAx2, Point, Vector } from "../geom";
3
import type { BoundingBox } from "../geom";
4
import { WrappingObj } from "../register";
5
export type CubeFace = "front" | "back" | "top" | "bottom" | "left" | "right";
6
export type ProjectionPlane =
7
  | "XY"
8
  | "XZ"
9
  | "YZ"
10
  | "YX"
11
  | "ZX"
12
  | "ZY"
13
  | "front"
14
  | "back"
15
  | "top"
16
  | "bottom"
17
  | "left"
18
  | "right";
19

20
const PROJECTION_PLANES: Record<ProjectionPlane, { dir: Point; xAxis: Point }> =
21
  {
22
    XY: { dir: [0, 0, 1], xAxis: [1, 0, 0] },
23
    XZ: { dir: [0, -1, 0], xAxis: [1, 0, 0] },
24
    YZ: { dir: [1, 0, 0], xAxis: [0, 1, 0] },
25
    YX: { dir: [0, 0, -1], xAxis: [0, 1, 0] },
26
    ZX: { dir: [0, 1, 0], xAxis: [0, 0, 1] },
27
    ZY: { dir: [-1, 0, 0], xAxis: [0, 0, 1] },
28

29
    front: { dir: [0, -1, 0], xAxis: [1, 0, 0] },
30
    back: { dir: [0, 1, 0], xAxis: [-1, 0, 0] },
31
    right: { dir: [-1, 0, 0], xAxis: [0, -1, 0] },
32
    left: { dir: [1, 0, 0], xAxis: [0, 1, 0] },
33
    bottom: { dir: [0, 0, 1], xAxis: [1, 0, 0] },
34
    top: { dir: [0, 0, -1], xAxis: [1, 0, 0] },
35
  };
36

37
export function isProjectionPlane(plane: unknown): plane is ProjectionPlane {
38
  return typeof plane === "string" && plane in PROJECTION_PLANES;
39
}
40

41
export function lookFromPlane(projectionPlane: ProjectionPlane) {
42
  const { dir, xAxis } = PROJECTION_PLANES[projectionPlane];
43
  return new ProjectionCamera([0, 0, 0], dir, xAxis);
44
}
45

46
function defaultXDir(direction: Point) {
47
  const dir = new Vector(direction);
48
  let yAxis: Point = new Vector([0, 0, 1]);
49
  let xAxis: Point = yAxis.cross(dir);
50
  if (xAxis.Length === 0) {
51
    yAxis = new Vector([0, 1, 0]);
52
    xAxis = yAxis.cross(dir);
53
  }
54
  return xAxis.normalize();
55
}
56

57
export class ProjectionCamera extends WrappingObj<gp_Ax2> {
58
  constructor(
59
    position: Point = [0, 0, 0],
60
    direction: Point = [0, 0, 1],
61
    xAxis?: Point
62
  ) {
63
    const xDir = xAxis ? new Vector(xAxis) : defaultXDir(direction);
64
    const ax2 = makeAx2(position, direction, xDir);
65
    super(ax2);
66
  }
67

68
  get position() {
69
    return new Vector(this.wrapped.Location());
70
  }
71

72
  get direction() {
73
    return new Vector(this.wrapped.Direction());
74
  }
75

76
  get xAxis() {
77
    return new Vector(this.wrapped.XDirection());
78
  }
79

80
  get yAxis() {
81
    return new Vector(this.wrapped.YDirection());
82
  }
83

84
  autoAxes() {
85
    const xAxis = defaultXDir(this.direction);
86
    this.wrapped.SetXDirection(asDir(xAxis));
87
  }
88

89
  setPosition(position: Point) {
90
    this.wrapped.SetLocation(asPnt(position));
91
    return this;
92
  }
93

94
  setXAxis(xAxis: Point) {
95
    this.wrapped.SetYDirection(asDir(xAxis));
96
    return this;
97
  }
98

99
  setYAxis(yAxis: Point) {
100
    this.wrapped.SetYDirection(asDir(yAxis));
101
    return this;
102
  }
103

104
  lookAt(shape: { boundingBox: BoundingBox } | Point) {
105
    const lootAtPoint = new Vector(
106
      "boundingBox" in shape ? shape.boundingBox.center : shape
107
    );
108
    const direction = this.position.sub(lootAtPoint).normalized();
109

110
    this.wrapped.SetDirection(direction.toDir());
111
    this.autoAxes();
112
    return this;
113
  }
114
}
115

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.