@shapediver/viewer.rendering-engine.camera-engine 3.3.4 → 3.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -10
- package/src/implementation/CameraEngine.ts +0 -386
- package/src/implementation/camera/AbstractCamera.ts +0 -324
- package/src/implementation/camera/OrthographicCamera.ts +0 -282
- package/src/implementation/camera/PerspectiveCamera.ts +0 -250
- package/src/implementation/controls/AbstractCameraControls.ts +0 -660
- package/src/implementation/controls/CameraControlsEventDistribution.ts +0 -289
- package/src/implementation/controls/CameraControlsLogic.ts +0 -534
- package/src/implementation/controls/OrthographicCameraControls.ts +0 -36
- package/src/implementation/controls/PerspectiveCameraControls.ts +0 -37
- package/src/implementation/interpolation/CameraInterpolationManager.ts +0 -149
- package/src/implementation/interpolation/interpolationMethods/CameraCylindricalInterpolation.ts +0 -83
- package/src/implementation/interpolation/interpolationMethods/CameraLinearInterpolation.ts +0 -41
- package/src/implementation/interpolation/interpolationMethods/CameraMultipleInterpolation.ts +0 -61
- package/src/implementation/interpolation/interpolationMethods/CameraOrthographicInterpolation.ts +0 -41
- package/src/implementation/interpolation/interpolationMethods/CameraSphericalInterpolation.ts +0 -65
- package/src/index.ts +0 -28
- package/src/interfaces/ICameraEngine.ts +0 -33
- package/src/interfaces/camera/ICamera.ts +0 -88
- package/src/interfaces/camera/IOrthographicCamera.ts +0 -36
- package/src/interfaces/camera/IPerspectiveCamera.ts +0 -18
- package/src/interfaces/controls/ICameraControls.ts +0 -80
- package/src/interfaces/controls/ICameraControlsEventDistribution.ts +0 -11
- package/src/interfaces/controls/ICameraControlsLogic.ts +0 -15
- package/src/interfaces/interpolation/ICameraInterpolation.ts +0 -9
- package/tsconfig.json +0 -17
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import { AbstractCamera } from './AbstractCamera';
|
|
2
|
-
import { Box, IBox, Plane } from '@shapediver/viewer.shared.math';
|
|
3
|
-
import { CAMERA_TYPE } from '../../interfaces/ICameraEngine';
|
|
4
|
-
import { ICameraControls } from '../../interfaces/controls/ICameraControls';
|
|
5
|
-
import { IPerspectiveCamera } from '../../interfaces/camera/IPerspectiveCamera';
|
|
6
|
-
import { IPerspectiveCameraSettings } from '@shapediver/viewer.settings';
|
|
7
|
-
import { IRenderingEngine } from '@shapediver/viewer.rendering-engine.rendering-engine';
|
|
8
|
-
import { ITree, Tree } from '@shapediver/viewer.shared.node-tree';
|
|
9
|
-
import {
|
|
10
|
-
mat4,
|
|
11
|
-
quat,
|
|
12
|
-
vec2,
|
|
13
|
-
vec3
|
|
14
|
-
} from 'gl-matrix';
|
|
15
|
-
import { PerspectiveCameraControls } from '../controls/PerspectiveCameraControls';
|
|
16
|
-
import {
|
|
17
|
-
Converter,
|
|
18
|
-
DomEventEngine,
|
|
19
|
-
SettingsEngine,
|
|
20
|
-
ShapeDiverViewerCameraError,
|
|
21
|
-
} from '@shapediver/viewer.shared.services';
|
|
22
|
-
|
|
23
|
-
export class PerspectiveCamera extends AbstractCamera implements IPerspectiveCamera {
|
|
24
|
-
// #region Properties (6)
|
|
25
|
-
|
|
26
|
-
readonly #converter: Converter = Converter.instance;
|
|
27
|
-
readonly #tree: ITree = Tree.instance;
|
|
28
|
-
|
|
29
|
-
#aspect: number | undefined;
|
|
30
|
-
#domEventEngine?: DomEventEngine;
|
|
31
|
-
#fov: number = 60;
|
|
32
|
-
|
|
33
|
-
protected _controls: ICameraControls;
|
|
34
|
-
|
|
35
|
-
// #endregion Properties (6)
|
|
36
|
-
|
|
37
|
-
// #region Constructors (1)
|
|
38
|
-
|
|
39
|
-
constructor(id: string, version?: string, initialAspect?: number, isDefault: boolean = false) {
|
|
40
|
-
super(id, CAMERA_TYPE.PERSPECTIVE, version, isDefault);
|
|
41
|
-
this.#aspect = initialAspect;
|
|
42
|
-
this._controls = new PerspectiveCameraControls(this, true);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// #endregion Constructors (1)
|
|
46
|
-
|
|
47
|
-
// #region Public Getters And Setters (6)
|
|
48
|
-
|
|
49
|
-
public get aspect(): number | undefined {
|
|
50
|
-
return this.#aspect;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public set aspect(value: number | undefined) {
|
|
54
|
-
this.#aspect = value;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
public get controls(): ICameraControls {
|
|
58
|
-
return this._controls;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public set controls(value: ICameraControls) {
|
|
62
|
-
this._controls = value;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public get fov(): number {
|
|
66
|
-
return this.#fov;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
public set fov(value: number) {
|
|
70
|
-
this.#fov = value;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// #endregion Public Getters And Setters (6)
|
|
74
|
-
|
|
75
|
-
// #region Public Methods (6)
|
|
76
|
-
|
|
77
|
-
public applySettings(settingsEngine: SettingsEngine) {
|
|
78
|
-
const cameraSetting = <IPerspectiveCameraSettings>settingsEngine.camera.cameras[this.id];
|
|
79
|
-
if (cameraSetting) {
|
|
80
|
-
this.name = cameraSetting.name;
|
|
81
|
-
this.autoAdjust = cameraSetting.autoAdjust;
|
|
82
|
-
this.cameraMovementDuration = cameraSetting.cameraMovementDuration;
|
|
83
|
-
this.enableCameraControls = cameraSetting.enableCameraControls;
|
|
84
|
-
this.revertAtMouseUp = cameraSetting.revertAtMouseUp;
|
|
85
|
-
this.revertAtMouseUpDuration = cameraSetting.revertAtMouseUpDuration;
|
|
86
|
-
this.sceneRotation = vec2.fromValues(cameraSetting.sceneRotation.x, cameraSetting.sceneRotation.y);
|
|
87
|
-
this.zoomExtentsFactor = cameraSetting.zoomExtentsFactor;
|
|
88
|
-
|
|
89
|
-
const position = this.#converter.toVec3(cameraSetting.position);
|
|
90
|
-
const target = this.#converter.toVec3(cameraSetting.target);
|
|
91
|
-
this.defaultPosition = vec3.clone(position);
|
|
92
|
-
this.defaultTarget = vec3.clone(target);
|
|
93
|
-
|
|
94
|
-
this.position = position;
|
|
95
|
-
this.target = target;
|
|
96
|
-
this.fov = cameraSetting.fov;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (this.position[0] === this.target[0] && this.position[1] === this.target[1] && this.position[2] === this.target[2]) {
|
|
100
|
-
if (this._viewportId) {
|
|
101
|
-
this._stateEngine.viewportEngines[this._viewportId]?.boundingBoxCreated.then(async () => {
|
|
102
|
-
await this.zoomTo(undefined, { duration: 0 });
|
|
103
|
-
this.defaultPosition = vec3.clone(this._controls.position);
|
|
104
|
-
this.defaultTarget = vec3.clone(this._controls.target);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
(<PerspectiveCameraControls>this._controls).applySettings(settingsEngine);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
public assignViewer(renderingEngine: IRenderingEngine): void {
|
|
112
|
-
if (renderingEngine.closed)
|
|
113
|
-
throw new ShapeDiverViewerCameraError(`OrthographicCamera(${this.id}).assignViewer: Viewer with id ${renderingEngine.id} not found.`);
|
|
114
|
-
|
|
115
|
-
this.assignViewerInternal(renderingEngine.id);
|
|
116
|
-
this._controls.assignViewer(renderingEngine.id, renderingEngine.canvas);
|
|
117
|
-
|
|
118
|
-
if (this.domEventListenerToken && this.#domEventEngine)
|
|
119
|
-
this.#domEventEngine.removeDomEventListener(this.domEventListenerToken);
|
|
120
|
-
|
|
121
|
-
this.#domEventEngine = renderingEngine.domEventEngine;
|
|
122
|
-
this.domEventListenerToken = this.#domEventEngine.addDomEventListener((<PerspectiveCameraControls>this._controls).cameraControlsEventDistribution);
|
|
123
|
-
|
|
124
|
-
this.boundingBox = this.#tree.root.boundingBox.clone();
|
|
125
|
-
|
|
126
|
-
this._stateEngine.viewportEngines[renderingEngine.id]?.boundingBoxCreated.then(async () => {
|
|
127
|
-
if (this.position[0] === this.target[0] && this.position[1] === this.target[1] && this.position[2] === this.target[2])
|
|
128
|
-
await this.zoomTo(undefined, { duration: 0 });
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
public calculateZoomTo(zoomTarget?: Box, startingPosition: vec3 = this.position, startingTarget: vec3 = this.target): { position: vec3, target: vec3 } {
|
|
133
|
-
let box: IBox;
|
|
134
|
-
|
|
135
|
-
// Part 1 - calculate the bounding box that we should zoom to
|
|
136
|
-
if (!zoomTarget) {
|
|
137
|
-
// complete scene
|
|
138
|
-
box = this._boundingBox.clone();
|
|
139
|
-
} else {
|
|
140
|
-
// specified Box
|
|
141
|
-
box = zoomTarget.clone();
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (box.isEmpty()) return { position: vec3.create(), target: vec3.create() };
|
|
145
|
-
|
|
146
|
-
const samePosition = startingPosition[0] === startingTarget[0] && startingPosition[1] === startingTarget[1] && startingPosition[2] === startingTarget[2];
|
|
147
|
-
const target = vec3.fromValues((box.max[0] + box.min[0]) / 2, (box.max[1] + box.min[1]) / 2, (box.max[2] + box.min[2]) / 2);
|
|
148
|
-
|
|
149
|
-
// if the camera position and the target are the same, we set a corner position
|
|
150
|
-
if (startingPosition[0] === startingTarget[0] && startingPosition[1] === startingTarget[1] && startingPosition[2] === startingTarget[2])
|
|
151
|
-
startingPosition = vec3.fromValues(target[0], target[1] - 7.5, target[2] + 5);
|
|
152
|
-
|
|
153
|
-
// extend box by the factor
|
|
154
|
-
const boxDir = vec3.subtract(vec3.create(), box.max, target);
|
|
155
|
-
vec3.multiply(boxDir, boxDir, samePosition ? vec3.fromValues(2, 2, 2) : vec3.fromValues(this.zoomExtentsFactor, this.zoomExtentsFactor, this.zoomExtentsFactor));
|
|
156
|
-
box = new Box(vec3.subtract(vec3.create(), target, boxDir), vec3.add(vec3.create(), target, boxDir));
|
|
157
|
-
|
|
158
|
-
const direction = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), target, startingPosition));
|
|
159
|
-
|
|
160
|
-
const cross = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), vec3.fromValues(0, 0, 1), direction));
|
|
161
|
-
const up = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), cross, direction));
|
|
162
|
-
|
|
163
|
-
let position = vec3.add(vec3.create(), target, vec3.multiply(vec3.create(), direction, vec3.fromValues(-0.00000001, -0.00000001, -0.00000001)));
|
|
164
|
-
|
|
165
|
-
const points = [];
|
|
166
|
-
points.push(vec3.fromValues(box.min[0], box.min[1], box.min[2]));
|
|
167
|
-
points.push(vec3.fromValues(box.min[0], box.min[1], box.max[2]));
|
|
168
|
-
points.push(vec3.fromValues(box.min[0], box.max[1], box.min[2]));
|
|
169
|
-
points.push(vec3.fromValues(box.min[0], box.max[1], box.max[2]));
|
|
170
|
-
points.push(vec3.fromValues(box.max[0], box.min[1], box.min[2]));
|
|
171
|
-
points.push(vec3.fromValues(box.max[0], box.min[1], box.max[2]));
|
|
172
|
-
points.push(vec3.fromValues(box.max[0], box.max[1], box.min[2]));
|
|
173
|
-
points.push(vec3.fromValues(box.max[0], box.max[1], box.max[2]));
|
|
174
|
-
|
|
175
|
-
const fovDown = vec3.normalize(vec3.create(), vec3.transformQuat(vec3.create(), direction, quat.setAxisAngle(quat.create(), cross, (this.fov / 2) * (Math.PI / 180))));
|
|
176
|
-
const fovUp = vec3.normalize(vec3.create(), vec3.transformQuat(vec3.create(), direction, quat.setAxisAngle(quat.create(), cross, -(this.fov / 2) * (Math.PI / 180))));
|
|
177
|
-
|
|
178
|
-
const aspect = samePosition ? 1.5 : this.aspect || 1.5;
|
|
179
|
-
const hFoV = 2 * Math.atan(Math.tan(this.fov * Math.PI / 180 / 2) * aspect);
|
|
180
|
-
const fovRight = vec3.normalize(vec3.create(), vec3.transformQuat(vec3.create(), direction, quat.setAxisAngle(quat.create(), up, hFoV / 2)));
|
|
181
|
-
const fovLeft = vec3.normalize(vec3.create(), vec3.transformQuat(vec3.create(), direction, quat.setAxisAngle(quat.create(), up, -hFoV / 2)));
|
|
182
|
-
|
|
183
|
-
const planeCross = new Plane(vec3.clone(cross), 0);
|
|
184
|
-
planeCross.setFromNormalAndCoplanarPoint(vec3.clone(cross), vec3.clone(target));
|
|
185
|
-
|
|
186
|
-
const planeUp = new Plane(vec3.fromValues(0, 0, 1), 0);
|
|
187
|
-
planeUp.setFromNormalAndCoplanarPoint(vec3.clone(up), vec3.clone(target));
|
|
188
|
-
|
|
189
|
-
let distanceCamera = 0.0;
|
|
190
|
-
for (let i = 0; i < points.length; i++) {
|
|
191
|
-
let projected = planeCross.clampPoint(points[i]);
|
|
192
|
-
let toP = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), projected, position));
|
|
193
|
-
|
|
194
|
-
if (vec3.dot(direction, fovDown) > vec3.dot(direction, toP)) {
|
|
195
|
-
const currentDir = vec3.multiply(vec3.create(), vec3.dot(fovDown, toP) > vec3.dot(fovUp, toP) ? fovDown : fovUp, vec3.fromValues(-1, -1, -1));
|
|
196
|
-
const distance = planeUp.intersect(projected, currentDir);
|
|
197
|
-
if (distance) {
|
|
198
|
-
const cameraPoint = vec3.add(vec3.create(), vec3.multiply(vec3.create(), currentDir, vec3.fromValues(distance, distance, distance)), projected);
|
|
199
|
-
distanceCamera = Math.max(distanceCamera, vec3.distance(target, cameraPoint));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
projected = planeUp.clampPoint(points[i]);
|
|
204
|
-
toP = vec3.normalize(vec3.create(), vec3.subtract(vec3.create(), projected, position));
|
|
205
|
-
|
|
206
|
-
if (vec3.dot(direction, fovRight) > vec3.dot(direction, toP)) {
|
|
207
|
-
const currentDir = vec3.multiply(vec3.create(), vec3.dot(fovRight, toP) > vec3.dot(fovLeft, toP) ? fovRight : fovLeft, vec3.fromValues(-1, -1, -1));
|
|
208
|
-
const distance = planeCross.intersect(projected, currentDir);
|
|
209
|
-
if (distance) {
|
|
210
|
-
const cameraPoint = vec3.add(vec3.create(), vec3.multiply(vec3.create(), currentDir, vec3.fromValues(distance, distance, distance)), projected);
|
|
211
|
-
distanceCamera = Math.max(distanceCamera, vec3.distance(target, cameraPoint));
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
position = vec3.add(vec3.create(), target, vec3.multiply(vec3.create(), direction, vec3.fromValues(-distanceCamera, -distanceCamera, -distanceCamera)));
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
position, target
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
public clone(): IPerspectiveCamera {
|
|
224
|
-
return new PerspectiveCamera(this.id, this.version, this.aspect);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
public project(pos: vec3, position = this.position, target = this.target): vec2 {
|
|
228
|
-
const m = mat4.targetTo(mat4.create(), position, target, vec3.fromValues(0, 0, 1));
|
|
229
|
-
const aspect = this.aspect || 1.5;
|
|
230
|
-
const p = mat4.perspective(mat4.create(), this.fov / (180 / Math.PI), aspect, this.near, this.far);
|
|
231
|
-
let inverse = mat4.invert(mat4.create(), m);
|
|
232
|
-
if (!inverse) inverse = mat4.create();
|
|
233
|
-
vec3.transformMat4(pos, pos, inverse);
|
|
234
|
-
vec3.transformMat4(pos, pos, p);
|
|
235
|
-
return vec2.fromValues(pos[0], pos[1]);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
public unproject(pos: vec3, position = this.position, target = this.target): vec3 {
|
|
239
|
-
const m = mat4.targetTo(mat4.create(), position, target, vec3.fromValues(0, 0, 1));
|
|
240
|
-
const aspect = this.aspect || 1.5;
|
|
241
|
-
const p = mat4.perspective(mat4.create(), this.fov / (180 / Math.PI), aspect, this.near, this.far);
|
|
242
|
-
let inverse = mat4.invert(mat4.create(), p);
|
|
243
|
-
if (!inverse) inverse = mat4.create();
|
|
244
|
-
vec3.transformMat4(pos, pos, inverse);
|
|
245
|
-
vec3.transformMat4(pos, pos, m);
|
|
246
|
-
return vec3.clone(pos);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// #endregion Public Methods (6)
|
|
250
|
-
}
|