s3m-three 0.4.23 → 0.4.24
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/analysis/clipping.d.ts +63 -0
- package/dist/analysis/clipping.d.ts.map +1 -0
- package/dist/analysis/clipping.js +69 -0
- package/dist/analysis/clipping.js.map +1 -0
- package/dist/analysis/depth.d.ts +55 -0
- package/dist/analysis/depth.d.ts.map +1 -0
- package/dist/analysis/depth.js +99 -0
- package/dist/analysis/depth.js.map +1 -0
- package/dist/analysis/index.d.ts +21 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +17 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/lineOfSight.d.ts +60 -0
- package/dist/analysis/lineOfSight.d.ts.map +1 -0
- package/dist/analysis/lineOfSight.js +56 -0
- package/dist/analysis/lineOfSight.js.map +1 -0
- package/dist/analysis/measure.d.ts +56 -0
- package/dist/analysis/measure.d.ts.map +1 -0
- package/dist/analysis/measure.js +95 -0
- package/dist/analysis/measure.js.map +1 -0
- package/dist/analysis/skyline.d.ts +55 -0
- package/dist/analysis/skyline.d.ts.map +1 -0
- package/dist/analysis/skyline.js +78 -0
- package/dist/analysis/skyline.js.map +1 -0
- package/dist/analysis/viewshed.d.ts +48 -0
- package/dist/analysis/viewshed.d.ts.map +1 -0
- package/dist/analysis/viewshed.js +115 -0
- package/dist/analysis/viewshed.js.map +1 -0
- package/dist/browser/s3m-three.iife.ext-three.js +20 -3
- package/dist/browser/s3m-three.iife.js +20 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/render/S3MViewer.d.ts +106 -0
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +174 -1
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/analysis/DepthPass.d.ts +78 -0
- package/dist/render/analysis/DepthPass.d.ts.map +1 -0
- package/dist/render/analysis/DepthPass.js +209 -0
- package/dist/render/analysis/DepthPass.js.map +1 -0
- package/dist/render/viewer/PickService.d.ts +15 -0
- package/dist/render/viewer/PickService.d.ts.map +1 -1
- package/dist/render/viewer/PickService.js +41 -0
- package/dist/render/viewer/PickService.js.map +1 -1
- package/docs/API.md +100 -0
- package/package.json +1 -1
- package/src/analysis/clipping.ts +135 -0
- package/src/analysis/depth.ts +126 -0
- package/src/analysis/index.ts +47 -0
- package/src/analysis/lineOfSight.ts +110 -0
- package/src/analysis/measure.ts +119 -0
- package/src/analysis/skyline.ts +125 -0
- package/src/analysis/viewshed.ts +160 -0
- package/src/index.ts +5 -0
- package/src/render/S3MViewer.ts +233 -2
- package/src/render/analysis/DepthPass.ts +278 -0
- package/src/render/viewer/PickService.ts +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure.js","sourceRoot":"","sources":["../../src/analysis/measure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Vec3 } from './measure.js';
|
|
2
|
+
export interface SkylineArgs {
|
|
3
|
+
/** RGBA8 深度图(three 的 RGBADepthPacking) */
|
|
4
|
+
rgba: ArrayLike<number>;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
/** 视图投影矩阵的逆(列主序,与 `THREE.Matrix4.elements` 同序) */
|
|
8
|
+
inverseViewProj: ArrayLike<number>;
|
|
9
|
+
/** 相机在场景 ENU 里的位置 */
|
|
10
|
+
cameraPos: Vec3;
|
|
11
|
+
/**
|
|
12
|
+
* 背景判定阈值:深度 >= 它的像素视为天空(默认 0.9999)。
|
|
13
|
+
* 用 0.9999 而不是 1:远处地平线可能因为精度落在 0.99999 上。
|
|
14
|
+
*/
|
|
15
|
+
skyDepth?: number;
|
|
16
|
+
/** 每隔多少列取一次(默认 1,即逐列) */
|
|
17
|
+
step?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface SkylineResult {
|
|
20
|
+
/** 方位角(度,0 = 正北,顺时针),长度 = ceil(width / step) */
|
|
21
|
+
azimuths: Float32Array;
|
|
22
|
+
/** 对应列的仰角(度,0 = 水平) */
|
|
23
|
+
elevations: Float32Array;
|
|
24
|
+
/** 整条天际线的最大仰角(度) */
|
|
25
|
+
maxElevation: number;
|
|
26
|
+
/** 最小仰角(度);全是天空时为 0 */
|
|
27
|
+
minElevation: number;
|
|
28
|
+
/** 没有几何、直通天空的列占比(0~1)—— 开敞度的最粗口径 */
|
|
29
|
+
openRatio: number;
|
|
30
|
+
/**
|
|
31
|
+
* 每列天际线在**屏幕上的位置**(归一化 0~1,左上角为原点),
|
|
32
|
+
* 布局是 `[x0, y0, x1, y1, …]`,长度 = `cols * 2`。
|
|
33
|
+
*
|
|
34
|
+
* 这是画「地图上的天际线」最直接的输入:深度图本来就是屏幕空间的东西,
|
|
35
|
+
* 换算成角度只是为了给人看,换算回去还会多一次投影误差。
|
|
36
|
+
* 归一化是为了让调用方按自己的画布尺寸缩放(捕获分辨率可以比画布小)。
|
|
37
|
+
*/
|
|
38
|
+
screen: Float32Array;
|
|
39
|
+
/**
|
|
40
|
+
* 每列是否有几何(1 = 有,0 = 纯天空)。
|
|
41
|
+
*
|
|
42
|
+
* 画线时要在这里断开:把纯天空的列也连进去,线会横穿天空,
|
|
43
|
+
* 看起来像天际线突然掉到画面底部。
|
|
44
|
+
*/
|
|
45
|
+
hasGeometry: Uint8Array;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 逐列取「最上面的几何像素」,反投影成世界坐标后换算成仰角,
|
|
49
|
+
* 同时记下该像素的归一化屏幕位置(给「在地图上描线」用)。
|
|
50
|
+
*
|
|
51
|
+
* 没有几何的列记 0°(地平线)并计入 `openRatio`,而不是记 -90°:
|
|
52
|
+
* 天际线曲线在地平线处收口,画图时不会突然掉到画面底部。
|
|
53
|
+
*/
|
|
54
|
+
export declare function skylineFromDepth(args: SkylineArgs): SkylineResult;
|
|
55
|
+
//# sourceMappingURL=skyline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skyline.d.ts","sourceRoot":"","sources":["../../src/analysis/skyline.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,eAAe,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,qBAAqB;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,QAAQ,EAAE,YAAY,CAAC;IACvB,uBAAuB;IACvB,UAAU,EAAE,YAAY,CAAC;IACzB,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;OAOG;IACH,MAAM,EAAE,YAAY,CAAC;IACrB;;;;;OAKG;IACH,WAAW,EAAE,UAAU,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,aAAa,CA0DjE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 天际线:从一张「从相机看出去」的深度图,按列抽出天际线曲线。
|
|
3
|
+
*
|
|
4
|
+
* 为什么是「按列」:天际线在屏幕上就是每列最上面那个几何像素的轮廓。
|
|
5
|
+
* 所以不需要额外的几何体 —— 一次深度 pass + 一次逐列扫描就够了,
|
|
6
|
+
* 结果直接是一串(方位角,仰角),画成 2D 曲线比生成 3D 多边形便宜得多。
|
|
7
|
+
*
|
|
8
|
+
* 只做数学,不碰 WebGL:深度图由 `render/analysis/DepthPass` 产出。
|
|
9
|
+
*/
|
|
10
|
+
import { azimuthElevation, pixelToNdc, unpackRGBADepth, unprojectNdc } from './depth.js';
|
|
11
|
+
/**
|
|
12
|
+
* 逐列取「最上面的几何像素」,反投影成世界坐标后换算成仰角,
|
|
13
|
+
* 同时记下该像素的归一化屏幕位置(给「在地图上描线」用)。
|
|
14
|
+
*
|
|
15
|
+
* 没有几何的列记 0°(地平线)并计入 `openRatio`,而不是记 -90°:
|
|
16
|
+
* 天际线曲线在地平线处收口,画图时不会突然掉到画面底部。
|
|
17
|
+
*/
|
|
18
|
+
export function skylineFromDepth(args) {
|
|
19
|
+
const { rgba, width, height, inverseViewProj, cameraPos } = args;
|
|
20
|
+
const skyDepth = args.skyDepth ?? 0.9999;
|
|
21
|
+
const step = Math.max(1, Math.floor(args.step ?? 1));
|
|
22
|
+
const cols = Math.ceil(width / step);
|
|
23
|
+
const azimuths = new Float32Array(cols);
|
|
24
|
+
const elevations = new Float32Array(cols);
|
|
25
|
+
const screen = new Float32Array(cols * 2);
|
|
26
|
+
const hasGeometry = new Uint8Array(cols);
|
|
27
|
+
let maxElevation = -90;
|
|
28
|
+
let minElevation = 90;
|
|
29
|
+
let open = 0;
|
|
30
|
+
for (let c = 0; c < cols; c++) {
|
|
31
|
+
const x = Math.min(width - 1, c * step);
|
|
32
|
+
let found = false;
|
|
33
|
+
for (let y = 0; y < height; y++) {
|
|
34
|
+
const off = (y * width + x) * 4;
|
|
35
|
+
const depth = unpackRGBADepth(rgba, off);
|
|
36
|
+
if (depth >= skyDepth)
|
|
37
|
+
continue;
|
|
38
|
+
const [ndcX, ndcY] = pixelToNdc(x, y, width, height);
|
|
39
|
+
const p = unprojectNdc(ndcX, ndcY, depth, inverseViewProj);
|
|
40
|
+
const { azimuth, elevation } = azimuthElevation(cameraPos, p);
|
|
41
|
+
azimuths[c] = azimuth;
|
|
42
|
+
elevations[c] = elevation;
|
|
43
|
+
// 像素中心归一化:与捕获图同尺度,调用方乘自己的画布尺寸即可
|
|
44
|
+
screen[c * 2] = (x + 0.5) / width;
|
|
45
|
+
screen[c * 2 + 1] = (y + 0.5) / height;
|
|
46
|
+
hasGeometry[c] = 1;
|
|
47
|
+
if (elevation > maxElevation)
|
|
48
|
+
maxElevation = elevation;
|
|
49
|
+
if (elevation < minElevation)
|
|
50
|
+
minElevation = elevation;
|
|
51
|
+
found = true;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
if (!found) {
|
|
55
|
+
// 这一列没有几何:天际线落在水平线上
|
|
56
|
+
open++;
|
|
57
|
+
azimuths[c] = 0;
|
|
58
|
+
elevations[c] = 0;
|
|
59
|
+
screen[c * 2] = (x + 0.5) / width;
|
|
60
|
+
screen[c * 2 + 1] = 1; // 贴到画面底部,画线时按 hasGeometry 断开
|
|
61
|
+
hasGeometry[c] = 0;
|
|
62
|
+
if (0 > maxElevation)
|
|
63
|
+
maxElevation = 0;
|
|
64
|
+
if (0 < minElevation)
|
|
65
|
+
minElevation = 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
azimuths,
|
|
70
|
+
elevations,
|
|
71
|
+
maxElevation,
|
|
72
|
+
minElevation,
|
|
73
|
+
openRatio: cols > 0 ? open / cols : 0,
|
|
74
|
+
screen,
|
|
75
|
+
hasGeometry,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=skyline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skyline.js","sourceRoot":"","sources":["../../src/analysis/skyline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Vec3 } from './measure.js';
|
|
2
|
+
export interface ViewshedOptions {
|
|
3
|
+
/** 分析半径(米) */
|
|
4
|
+
radius: number;
|
|
5
|
+
/** 栅格边长(格数,默认 96;96² = 9216 个采样点,CPU 侧约 1~3 ms) */
|
|
6
|
+
grid?: number;
|
|
7
|
+
/**
|
|
8
|
+
* 遮挡容差(米,默认 0.5)。
|
|
9
|
+
*
|
|
10
|
+
* 采样点到观察点的距离要**小于等于**该方向上的遮挡距离才算可见;
|
|
11
|
+
* 留一点容差是为了吸收深度图的离散化误差与地面自身的起伏。
|
|
12
|
+
*/
|
|
13
|
+
bias?: number;
|
|
14
|
+
/** 地面高程(场景 ENU 的 z,默认 0) */
|
|
15
|
+
groundZ?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ViewshedResult {
|
|
18
|
+
/**
|
|
19
|
+
* `grid × grid` 的可见性,行优先(`y * grid + x`):
|
|
20
|
+
* `1` = 可见,`0` = 被遮挡,`-1` = 超出半径或没有数据。
|
|
21
|
+
*/
|
|
22
|
+
raster: Float32Array;
|
|
23
|
+
grid: number;
|
|
24
|
+
/** 栅格左下角(场景 ENU 米) */
|
|
25
|
+
minX: number;
|
|
26
|
+
minY: number;
|
|
27
|
+
/** 每格边长(米) */
|
|
28
|
+
cellSize: number;
|
|
29
|
+
/** 有效格子里可见的比例(0~1) */
|
|
30
|
+
visibleRatio: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @param origin 观察点(场景 ENU 米,已含眼高)
|
|
34
|
+
* @param sampleDistance 沿单位方向取「最近的遮挡距离」;该方向没有几何时返回 `Infinity`
|
|
35
|
+
*/
|
|
36
|
+
export declare function computeViewshed(origin: Vec3, sampleDistance: (dir: Vec3) => number, opts: ViewshedOptions): ViewshedResult;
|
|
37
|
+
/**
|
|
38
|
+
* 从 6 面立方体深度图构造 `sampleDistance`。
|
|
39
|
+
*
|
|
40
|
+
* 立方体每个面是 `size × size` 的 RGBA8,存的是 `距离 / maxDist` 的打包值
|
|
41
|
+
* (打包方式同 three 的 `packDepthToRGBA`,与 `RGBADepthPacking` 一致)。
|
|
42
|
+
* 采样用最近邻 —— 可视域本身是栅格化的,插值不会让结果更准。
|
|
43
|
+
*
|
|
44
|
+
* 面序与 three 的 `WebGLCubeRenderTarget` / `CubeCamera` 一致:
|
|
45
|
+
* `+x, -x, +y, -y, +z, -z`。
|
|
46
|
+
*/
|
|
47
|
+
export declare function makeCubeDistanceSampler(faces: readonly (ArrayLike<number> | null | undefined)[], size: number, maxDist: number): (dir: Vec3) => number;
|
|
48
|
+
//# sourceMappingURL=viewshed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewshed.d.ts","sourceRoot":"","sources":["../../src/analysis/viewshed.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,WAAW,eAAe;IAC9B,cAAc;IACd,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,EACZ,cAAc,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,EACrC,IAAI,EAAE,eAAe,GACpB,cAAc,CA8ChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,EACxD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,CAAC,GAAG,EAAE,IAAI,KAAK,MAAM,CAwCvB"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 360° 可视域:地面栅格版。
|
|
3
|
+
*
|
|
4
|
+
* 思路与「从观察点做阴影贴图」一致,但**判定在 CPU 上做**:
|
|
5
|
+
* GPU 只负责产出一个 `方向 → 最近遮挡距离` 的采样函数(6 面立方体深度图),
|
|
6
|
+
* 这里拿它在观察点周围的地面网格上逐格比较距离。
|
|
7
|
+
*
|
|
8
|
+
* 为什么不在片元里逐像素判定(建筑立面着色版):
|
|
9
|
+
* 那要把立方体深度注入到每种材质(pbr / lambert / 棱线 / 点云 / 泼溅)的 shader 里,
|
|
10
|
+
* 成本和风险高一个量级;地面栅格版能覆盖绝大多数规划类需求,且结果可以直接
|
|
11
|
+
* 当成一张贴图/热力图叠在地面上。
|
|
12
|
+
*
|
|
13
|
+
* 纯数学,不碰 WebGL:采样函数由 `render/analysis/DepthPass` 提供,单测里用假的。
|
|
14
|
+
*/
|
|
15
|
+
import { unpackRGBADepth } from './depth.js';
|
|
16
|
+
/**
|
|
17
|
+
* @param origin 观察点(场景 ENU 米,已含眼高)
|
|
18
|
+
* @param sampleDistance 沿单位方向取「最近的遮挡距离」;该方向没有几何时返回 `Infinity`
|
|
19
|
+
*/
|
|
20
|
+
export function computeViewshed(origin, sampleDistance, opts) {
|
|
21
|
+
const radius = Math.max(1e-3, opts.radius);
|
|
22
|
+
const grid = Math.max(2, Math.floor(opts.grid ?? 96));
|
|
23
|
+
const bias = Math.max(0, opts.bias ?? 0.5);
|
|
24
|
+
const groundZ = opts.groundZ ?? 0;
|
|
25
|
+
const cellSize = (radius * 2) / grid;
|
|
26
|
+
const minX = origin[0] - radius;
|
|
27
|
+
const minY = origin[1] - radius;
|
|
28
|
+
const raster = new Float32Array(grid * grid);
|
|
29
|
+
let visible = 0;
|
|
30
|
+
let counted = 0;
|
|
31
|
+
for (let iy = 0; iy < grid; iy++) {
|
|
32
|
+
const wy = minY + (iy + 0.5) * cellSize;
|
|
33
|
+
for (let ix = 0; ix < grid; ix++) {
|
|
34
|
+
const wx = minX + (ix + 0.5) * cellSize;
|
|
35
|
+
const dx = wx - origin[0];
|
|
36
|
+
const dy = wy - origin[1];
|
|
37
|
+
const dz = groundZ - origin[2];
|
|
38
|
+
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
39
|
+
const idx = iy * grid + ix;
|
|
40
|
+
if (dist > radius || dist < 1e-6) {
|
|
41
|
+
raster[idx] = -1;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const dir = [dx / dist, dy / dist, dz / dist];
|
|
45
|
+
const blockedAt = sampleDistance(dir);
|
|
46
|
+
const ok = dist <= blockedAt + bias;
|
|
47
|
+
raster[idx] = ok ? 1 : 0;
|
|
48
|
+
counted++;
|
|
49
|
+
if (ok)
|
|
50
|
+
visible++;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
raster,
|
|
55
|
+
grid,
|
|
56
|
+
minX,
|
|
57
|
+
minY,
|
|
58
|
+
cellSize,
|
|
59
|
+
visibleRatio: counted > 0 ? visible / counted : 0,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 从 6 面立方体深度图构造 `sampleDistance`。
|
|
64
|
+
*
|
|
65
|
+
* 立方体每个面是 `size × size` 的 RGBA8,存的是 `距离 / maxDist` 的打包值
|
|
66
|
+
* (打包方式同 three 的 `packDepthToRGBA`,与 `RGBADepthPacking` 一致)。
|
|
67
|
+
* 采样用最近邻 —— 可视域本身是栅格化的,插值不会让结果更准。
|
|
68
|
+
*
|
|
69
|
+
* 面序与 three 的 `WebGLCubeRenderTarget` / `CubeCamera` 一致:
|
|
70
|
+
* `+x, -x, +y, -y, +z, -z`。
|
|
71
|
+
*/
|
|
72
|
+
export function makeCubeDistanceSampler(faces, size, maxDist) {
|
|
73
|
+
return (dir) => {
|
|
74
|
+
const [x, y, z] = dir;
|
|
75
|
+
const ax = Math.abs(x);
|
|
76
|
+
const ay = Math.abs(y);
|
|
77
|
+
const az = Math.abs(z);
|
|
78
|
+
// 主轴决定落在哪个面:|x| 最大 → ±x 面,依此类推
|
|
79
|
+
let faceIndex;
|
|
80
|
+
let u;
|
|
81
|
+
let v;
|
|
82
|
+
if (ax >= ay && ax >= az) {
|
|
83
|
+
faceIndex = x >= 0 ? 0 : 1;
|
|
84
|
+
const d = ax;
|
|
85
|
+
// three 的立方体面约定:+x 面 u = -z/d, v = -y/d
|
|
86
|
+
u = x >= 0 ? -z / d : z / d;
|
|
87
|
+
v = -y / d;
|
|
88
|
+
}
|
|
89
|
+
else if (ay >= az) {
|
|
90
|
+
faceIndex = y >= 0 ? 2 : 3;
|
|
91
|
+
const d = ay;
|
|
92
|
+
u = x / d;
|
|
93
|
+
v = y >= 0 ? z / d : -z / d;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
faceIndex = z >= 0 ? 4 : 5;
|
|
97
|
+
const d = az;
|
|
98
|
+
// 面朝向相反时 u 轴也翻向,否则 -z 面会左右镜像(可视域会镜像到错误一侧)
|
|
99
|
+
u = z >= 0 ? x / d : -x / d;
|
|
100
|
+
v = -y / d;
|
|
101
|
+
}
|
|
102
|
+
const face = faces[faceIndex];
|
|
103
|
+
if (!face)
|
|
104
|
+
return Infinity;
|
|
105
|
+
const px = Math.min(size - 1, Math.max(0, Math.floor(((u + 1) / 2) * size)));
|
|
106
|
+
const py = Math.min(size - 1, Math.max(0, Math.floor(((v + 1) / 2) * size)));
|
|
107
|
+
const d = unpackRGBADepth(face, (py * size + px) * 4);
|
|
108
|
+
// 打包值是归一化距离:1 = 远平面(该方向没有几何)。three 的 pack 对 v>=1
|
|
109
|
+
// 直接返回全白,解包正好是 1.0,所以阈值取 0.9999 就够。
|
|
110
|
+
if (d >= 0.9999)
|
|
111
|
+
return Infinity;
|
|
112
|
+
return d * maxDist;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=viewshed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewshed.js","sourceRoot":"","sources":["../../src/analysis/viewshed.ts"],"names":[],"mappings":"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"}
|