@math.gl/culling 3.6.0-alpha.5 → 3.6.0-alpha.8
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/dist/es5/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
- package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
- package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
- package/dist/es5/lib/perspective-frustum.js +63 -58
- package/dist/es5/lib/perspective-frustum.js.map +1 -1
- package/dist/es5/lib/perspective-off-center-frustum.js +51 -51
- package/dist/es5/lib/perspective-off-center-frustum.js.map +1 -1
- package/dist/es5/lib/plane.js.map +1 -1
- package/dist/esm/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
- package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
- package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
- package/dist/esm/lib/perspective-frustum.js +60 -55
- package/dist/esm/lib/perspective-frustum.js.map +1 -1
- package/dist/esm/lib/perspective-off-center-frustum.js +48 -46
- package/dist/esm/lib/perspective-off-center-frustum.js.map +1 -1
- package/dist/esm/lib/plane.js.map +1 -1
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +1 -1
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +2 -2
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -1
- package/dist/lib/perspective-frustum.d.ts +52 -40
- package/dist/lib/perspective-frustum.d.ts.map +1 -1
- package/dist/lib/perspective-frustum.js +81 -96
- package/dist/lib/perspective-off-center-frustum.d.ts +74 -38
- package/dist/lib/perspective-off-center-frustum.d.ts.map +1 -1
- package/dist/lib/perspective-off-center-frustum.js +64 -99
- package/dist/lib/plane.d.ts +8 -8
- package/dist/lib/plane.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/lib/algorithms/compute-eigen-decomposition.ts +3 -3
- package/src/lib/bounding-volumes/axis-aligned-bounding-box.ts +2 -2
- package/src/lib/bounding-volumes/oriented-bounding-box.ts +2 -2
- package/src/lib/perspective-frustum.ts +115 -118
- package/src/lib/perspective-off-center-frustum.ts +137 -131
- package/src/lib/plane.ts +11 -8
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
// - It has not been fully adapted to math.gl conventions
|
|
6
6
|
// - Documentation has not been ported
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {Vector3, Matrix4, assert} from '@math.gl/core';
|
|
8
|
+
import {Vector3, Vector2, Matrix4, assert, NumericArray} from '@math.gl/core';
|
|
11
9
|
import CullingVolume from './culling-volume';
|
|
12
10
|
import Plane from './plane';
|
|
13
11
|
|
|
@@ -17,20 +15,60 @@ const scratchPlaneNearCenter = new Vector3();
|
|
|
17
15
|
const scratchPlaneFarCenter = new Vector3();
|
|
18
16
|
const scratchPlaneNormal = new Vector3();
|
|
19
17
|
|
|
18
|
+
type PerspectiveOffCenterFrustumOptions = {
|
|
19
|
+
left?: number;
|
|
20
|
+
right?: number;
|
|
21
|
+
top?: number;
|
|
22
|
+
bottom?: number;
|
|
23
|
+
near?: number;
|
|
24
|
+
far?: number;
|
|
25
|
+
};
|
|
26
|
+
|
|
20
27
|
export default class PerspectiveOffCenterFrustum {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Defines the left clipping plane.
|
|
30
|
+
* @type {Number}
|
|
31
|
+
* @default undefined
|
|
32
|
+
*/
|
|
33
|
+
left?: number;
|
|
34
|
+
private _left?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Defines the right clipping plane.
|
|
37
|
+
* @type {Number}
|
|
38
|
+
* @default undefined
|
|
39
|
+
*/
|
|
40
|
+
right?: number;
|
|
41
|
+
private _right?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Defines the top clipping plane.
|
|
44
|
+
* @type {Number}
|
|
45
|
+
* @default undefined
|
|
46
|
+
*/
|
|
47
|
+
top?: number;
|
|
48
|
+
private _top?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Defines the bottom clipping plane.
|
|
51
|
+
* @type {Number}
|
|
52
|
+
* @default undefined
|
|
53
|
+
*/
|
|
54
|
+
bottom?: number;
|
|
55
|
+
private _bottom?: number;
|
|
56
|
+
/**
|
|
57
|
+
* The distance of the near plane.
|
|
58
|
+
* @type {Number}
|
|
59
|
+
* @default 1.0
|
|
60
|
+
*/
|
|
61
|
+
near: number;
|
|
62
|
+
private _near: number;
|
|
63
|
+
/**
|
|
64
|
+
* The distance of the far plane.
|
|
65
|
+
* @type {Number}
|
|
66
|
+
* @default 500000000.0
|
|
67
|
+
*/
|
|
68
|
+
far: number;
|
|
69
|
+
private _far: number;
|
|
70
|
+
|
|
71
|
+
private _cullingVolume = new CullingVolume([
|
|
34
72
|
new Plane(),
|
|
35
73
|
new Plane(),
|
|
36
74
|
new Plane(),
|
|
@@ -38,8 +76,8 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
38
76
|
new Plane(),
|
|
39
77
|
new Plane()
|
|
40
78
|
]);
|
|
41
|
-
_perspectiveMatrix = new Matrix4();
|
|
42
|
-
_infinitePerspective = new Matrix4();
|
|
79
|
+
private _perspectiveMatrix = new Matrix4();
|
|
80
|
+
private _infinitePerspective = new Matrix4();
|
|
43
81
|
|
|
44
82
|
/**
|
|
45
83
|
* The viewing frustum is defined by 6 planes.
|
|
@@ -48,15 +86,6 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
48
86
|
* plane from the origin/camera position.
|
|
49
87
|
*
|
|
50
88
|
* @alias PerspectiveOffCenterFrustum
|
|
51
|
-
* @constructor
|
|
52
|
-
*
|
|
53
|
-
* @param {Object} [options] An object with the following properties:
|
|
54
|
-
* @param {Number} [options.left] The left clipping plane distance.
|
|
55
|
-
* @param {Number} [options.right] The right clipping plane distance.
|
|
56
|
-
* @param {Number} [options.top] The top clipping plane distance.
|
|
57
|
-
* @param {Number} [options.bottom] The bottom clipping plane distance.
|
|
58
|
-
* @param {Number} [options.near=1.0] The near clipping plane distance.
|
|
59
|
-
* @param {Number} [options.far=500000000.0] The far clipping plane distance.
|
|
60
89
|
*
|
|
61
90
|
* @example
|
|
62
91
|
* const frustum = new PerspectiveOffCenterFrustum({
|
|
@@ -70,63 +99,33 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
70
99
|
*
|
|
71
100
|
* @see PerspectiveFrustum
|
|
72
101
|
*/
|
|
73
|
-
constructor(options:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Defines the left clipping plane.
|
|
78
|
-
* @type {Number}
|
|
79
|
-
* @default undefined
|
|
80
|
-
*/
|
|
102
|
+
constructor(options: PerspectiveOffCenterFrustumOptions = {}) {
|
|
103
|
+
const {near = 1.0, far = 500000000.0} = options;
|
|
104
|
+
|
|
81
105
|
this.left = options.left;
|
|
82
106
|
this._left = undefined;
|
|
83
107
|
|
|
84
|
-
/**
|
|
85
|
-
* Defines the right clipping plane.
|
|
86
|
-
* @type {Number}
|
|
87
|
-
* @default undefined
|
|
88
|
-
*/
|
|
89
108
|
this.right = options.right;
|
|
90
109
|
this._right = undefined;
|
|
91
110
|
|
|
92
|
-
/**
|
|
93
|
-
* Defines the top clipping plane.
|
|
94
|
-
* @type {Number}
|
|
95
|
-
* @default undefined
|
|
96
|
-
*/
|
|
97
111
|
this.top = options.top;
|
|
98
112
|
this._top = undefined;
|
|
99
113
|
|
|
100
|
-
/**
|
|
101
|
-
* Defines the bottom clipping plane.
|
|
102
|
-
* @type {Number}
|
|
103
|
-
* @default undefined
|
|
104
|
-
*/
|
|
105
114
|
this.bottom = options.bottom;
|
|
106
115
|
this._bottom = undefined;
|
|
107
116
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.near = options.near;
|
|
114
|
-
this._near = this.near;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* The distance of the far plane.
|
|
118
|
-
* @type {Number}
|
|
119
|
-
* @default 500000000.0
|
|
120
|
-
*/
|
|
121
|
-
this.far = options.far;
|
|
122
|
-
this._far = this.far;
|
|
117
|
+
this.near = near;
|
|
118
|
+
this._near = near;
|
|
119
|
+
|
|
120
|
+
this.far = far;
|
|
121
|
+
this._far = far;
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
/**
|
|
126
125
|
* Returns a duplicate of a PerspectiveOffCenterFrustum instance.
|
|
127
126
|
* @returns {PerspectiveOffCenterFrustum} A new PerspectiveFrustum instance.
|
|
128
127
|
* */
|
|
129
|
-
clone() {
|
|
128
|
+
clone(): PerspectiveOffCenterFrustum {
|
|
130
129
|
return new PerspectiveOffCenterFrustum({
|
|
131
130
|
right: this.right,
|
|
132
131
|
left: this.left,
|
|
@@ -141,10 +140,9 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
141
140
|
* Compares the provided PerspectiveOffCenterFrustum componentwise and returns
|
|
142
141
|
* <code>true</code> if they are equal, <code>false</code> otherwise.
|
|
143
142
|
*
|
|
144
|
-
* @param {PerspectiveOffCenterFrustum} [other] The right hand side PerspectiveOffCenterFrustum.
|
|
145
143
|
* @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
|
|
146
144
|
*/
|
|
147
|
-
equals(other) {
|
|
145
|
+
equals(other: PerspectiveOffCenterFrustum): boolean {
|
|
148
146
|
return (
|
|
149
147
|
other &&
|
|
150
148
|
other instanceof PerspectiveOffCenterFrustum &&
|
|
@@ -164,8 +162,8 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
164
162
|
*
|
|
165
163
|
* @see PerspectiveOffCenterFrustum#infiniteProjectionMatrix
|
|
166
164
|
*/
|
|
167
|
-
get projectionMatrix() {
|
|
168
|
-
|
|
165
|
+
get projectionMatrix(): Matrix4 {
|
|
166
|
+
this._update();
|
|
169
167
|
return this._perspectiveMatrix;
|
|
170
168
|
}
|
|
171
169
|
|
|
@@ -176,17 +174,13 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
176
174
|
*
|
|
177
175
|
* @see PerspectiveOffCenterFrustum#projectionMatrix
|
|
178
176
|
*/
|
|
179
|
-
get infiniteProjectionMatrix() {
|
|
180
|
-
|
|
177
|
+
get infiniteProjectionMatrix(): Matrix4 {
|
|
178
|
+
this._update();
|
|
181
179
|
return this._infinitePerspective;
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
/**
|
|
185
183
|
* Creates a culling volume for this frustum.
|
|
186
|
-
*
|
|
187
|
-
* @param {Vector3} position The eye position.
|
|
188
|
-
* @param {Vector3} direction The view direction.
|
|
189
|
-
* @param {Vector3} up The up direction.
|
|
190
184
|
* @returns {CullingVolume} A culling volume at the given position and orientation.
|
|
191
185
|
*
|
|
192
186
|
* @example
|
|
@@ -195,7 +189,14 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
195
189
|
* const intersect = cullingVolume.computeVisibility(boundingVolume);
|
|
196
190
|
*/
|
|
197
191
|
// eslint-disable-next-line complexity, max-statements
|
|
198
|
-
computeCullingVolume(
|
|
192
|
+
computeCullingVolume(
|
|
193
|
+
/** A Vector3 defines the eye position. */
|
|
194
|
+
position: Readonly<NumericArray>,
|
|
195
|
+
/** A Vector3 defines the view direction. */
|
|
196
|
+
direction: Readonly<NumericArray>,
|
|
197
|
+
/** A Vector3 defines the up direction. */
|
|
198
|
+
up: Readonly<NumericArray>
|
|
199
|
+
): CullingVolume {
|
|
199
200
|
assert(position, 'position is required.');
|
|
200
201
|
assert(direction, 'direction is required.');
|
|
201
202
|
assert(up, 'up is required.');
|
|
@@ -265,10 +266,6 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
265
266
|
/**
|
|
266
267
|
* Returns the pixel's width and height in meters.
|
|
267
268
|
*
|
|
268
|
-
* @param {Number} drawingBufferWidth The width of the drawing buffer.
|
|
269
|
-
* @param {Number} drawingBufferHeight The height of the drawing buffer.
|
|
270
|
-
* @param {Number} distance The distance to the near plane in meters.
|
|
271
|
-
* @param {Vector2} result The object onto which to store the result.
|
|
272
269
|
* @returns {Vector2} The modified result parameter or a new instance of {@link Vector2} with the pixel's width and height in the x and y properties, respectively.
|
|
273
270
|
*
|
|
274
271
|
* @exception {DeveloperError} drawingBufferWidth must be greater than zero.
|
|
@@ -290,8 +287,17 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
290
287
|
* const distance = Vector3.magnitude(toCenterProj);
|
|
291
288
|
* const pixelSize = camera.frustum.getPixelDimensions(scene.drawingBufferWidth, scene.drawingBufferHeight, distance, new Vector2());
|
|
292
289
|
*/
|
|
293
|
-
getPixelDimensions(
|
|
294
|
-
|
|
290
|
+
getPixelDimensions(
|
|
291
|
+
/** The width of the drawing buffer. */
|
|
292
|
+
drawingBufferWidth: number,
|
|
293
|
+
/** The height of the drawing buffer. */
|
|
294
|
+
drawingBufferHeight: number,
|
|
295
|
+
/** The distance to the near plane in meters. */
|
|
296
|
+
distance: number,
|
|
297
|
+
/** The object onto which to store the result. */
|
|
298
|
+
result: Vector2
|
|
299
|
+
): Vector2 {
|
|
300
|
+
this._update();
|
|
295
301
|
|
|
296
302
|
assert(Number.isFinite(drawingBufferWidth) && Number.isFinite(drawingBufferHeight));
|
|
297
303
|
// 'Both drawingBufferWidth and drawingBufferHeight are required.'
|
|
@@ -314,56 +320,56 @@ export default class PerspectiveOffCenterFrustum {
|
|
|
314
320
|
result.y = pixelHeight;
|
|
315
321
|
return result;
|
|
316
322
|
}
|
|
317
|
-
}
|
|
318
323
|
|
|
319
|
-
// eslint-disable-next-line complexity, max-statements
|
|
320
|
-
|
|
321
|
-
assert(
|
|
322
|
-
Number.isFinite(frustum.right) &&
|
|
323
|
-
Number.isFinite(frustum.left) &&
|
|
324
|
-
Number.isFinite(frustum.top) &&
|
|
325
|
-
Number.isFinite(frustum.bottom) &&
|
|
326
|
-
Number.isFinite(frustum.near) &&
|
|
327
|
-
Number.isFinite(frustum.far)
|
|
328
|
-
);
|
|
329
|
-
// throw new DeveloperError('right, left, top, bottom, near, or far parameters are not set.');
|
|
330
|
-
|
|
331
|
-
const {top, bottom, right, left, near, far} = frustum;
|
|
332
|
-
|
|
333
|
-
if (
|
|
334
|
-
top !== frustum._top ||
|
|
335
|
-
bottom !== frustum._bottom ||
|
|
336
|
-
left !== frustum._left ||
|
|
337
|
-
right !== frustum._right ||
|
|
338
|
-
near !== frustum._near ||
|
|
339
|
-
far !== frustum._far
|
|
340
|
-
) {
|
|
324
|
+
// eslint-disable-next-line complexity, max-statements
|
|
325
|
+
private _update() {
|
|
341
326
|
assert(
|
|
342
|
-
|
|
343
|
-
|
|
327
|
+
Number.isFinite(this.right) &&
|
|
328
|
+
Number.isFinite(this.left) &&
|
|
329
|
+
Number.isFinite(this.top) &&
|
|
330
|
+
Number.isFinite(this.bottom) &&
|
|
331
|
+
Number.isFinite(this.near) &&
|
|
332
|
+
Number.isFinite(this.far)
|
|
344
333
|
);
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
top
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
334
|
+
// throw new DeveloperError('right, left, top, bottom, near, or far parameters are not set.');
|
|
335
|
+
|
|
336
|
+
const {top, bottom, right, left, near, far} = this;
|
|
337
|
+
|
|
338
|
+
if (
|
|
339
|
+
top !== this._top ||
|
|
340
|
+
bottom !== this._bottom ||
|
|
341
|
+
left !== this._left ||
|
|
342
|
+
right !== this._right ||
|
|
343
|
+
near !== this._near ||
|
|
344
|
+
far !== this._far
|
|
345
|
+
) {
|
|
346
|
+
assert(
|
|
347
|
+
this.near > 0 && this.near < this.far,
|
|
348
|
+
'near must be greater than zero and less than far.'
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
this._left = left;
|
|
352
|
+
this._right = right;
|
|
353
|
+
this._top = top;
|
|
354
|
+
this._bottom = bottom;
|
|
355
|
+
this._near = near;
|
|
356
|
+
this._far = far;
|
|
357
|
+
this._perspectiveMatrix = new Matrix4().frustum({
|
|
358
|
+
left,
|
|
359
|
+
right,
|
|
360
|
+
bottom,
|
|
361
|
+
top,
|
|
362
|
+
near,
|
|
363
|
+
far
|
|
364
|
+
});
|
|
365
|
+
this._infinitePerspective = new Matrix4().frustum({
|
|
366
|
+
left,
|
|
367
|
+
right,
|
|
368
|
+
bottom,
|
|
369
|
+
top,
|
|
370
|
+
near,
|
|
371
|
+
far: Infinity
|
|
372
|
+
});
|
|
373
|
+
}
|
|
368
374
|
}
|
|
369
375
|
}
|
package/src/lib/plane.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
3
3
|
|
|
4
4
|
/* eslint-disable */
|
|
5
|
-
import {Vector3, equals, assert} from '@math.gl/core';
|
|
5
|
+
import {Vector3, equals, assert, NumericArray} from '@math.gl/core';
|
|
6
6
|
|
|
7
7
|
const scratchPosition = new Vector3();
|
|
8
8
|
const scratchNormal = new Vector3();
|
|
@@ -12,14 +12,14 @@ export default class Plane {
|
|
|
12
12
|
readonly normal: Vector3;
|
|
13
13
|
distance: number;
|
|
14
14
|
|
|
15
|
-
constructor(normal:
|
|
15
|
+
constructor(normal: Readonly<NumericArray> = [0, 0, 1], distance: number = 0) {
|
|
16
16
|
this.normal = new Vector3();
|
|
17
17
|
this.distance = -0;
|
|
18
18
|
this.fromNormalDistance(normal, distance);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** Creates a plane from a normal and a distance from the origin. */
|
|
22
|
-
fromNormalDistance(normal:
|
|
22
|
+
fromNormalDistance(normal: Readonly<NumericArray>, distance: number): this {
|
|
23
23
|
assert(Number.isFinite(distance));
|
|
24
24
|
this.normal.from(normal).normalize();
|
|
25
25
|
this.distance = distance;
|
|
@@ -27,7 +27,7 @@ export default class Plane {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/** Creates a plane from a normal and a point on the plane. */
|
|
30
|
-
fromPointNormal(point:
|
|
30
|
+
fromPointNormal(point: Readonly<NumericArray>, normal: Readonly<NumericArray>): this {
|
|
31
31
|
point = scratchPosition.from(point);
|
|
32
32
|
this.normal.from(normal).normalize();
|
|
33
33
|
const distance = -this.normal.dot(point);
|
|
@@ -56,20 +56,23 @@ export default class Plane {
|
|
|
56
56
|
/** Computes the signed shortest distance of a point to a plane.
|
|
57
57
|
* The sign of the distance determines which side of the plane the point is on.
|
|
58
58
|
*/
|
|
59
|
-
getPointDistance(point:
|
|
59
|
+
getPointDistance(point: Readonly<NumericArray>): number {
|
|
60
60
|
return this.normal.dot(point) + this.distance;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/** Transforms the plane by the given transformation matrix. */
|
|
64
|
-
transform(matrix4:
|
|
64
|
+
transform(matrix4: Readonly<NumericArray>): this {
|
|
65
65
|
const normal = scratchNormal.copy(this.normal).transformAsVector(matrix4).normalize();
|
|
66
66
|
const point = this.normal.scale(-this.distance).transform(matrix4);
|
|
67
67
|
return this.fromPointNormal(point, normal);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/** Projects a point onto the plane. */
|
|
71
|
-
projectPointOntoPlane(point:
|
|
72
|
-
projectPointOntoPlane(
|
|
71
|
+
projectPointOntoPlane(point: Readonly<NumericArray>, result: Vector3): Vector3;
|
|
72
|
+
projectPointOntoPlane(
|
|
73
|
+
point: Readonly<NumericArray>,
|
|
74
|
+
result?: readonly number[]
|
|
75
|
+
): readonly number[];
|
|
73
76
|
|
|
74
77
|
projectPointOntoPlane(point, result = [0, 0, 0]) {
|
|
75
78
|
point = scratchPosition.from(point);
|