s3m-three 0.4.22 → 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 +52 -35
- package/dist/browser/s3m-three.iife.js +47 -30
- 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/DatasetManager.d.ts +13 -0
- package/dist/render/DatasetManager.d.ts.map +1 -1
- package/dist/render/DatasetManager.js +20 -0
- package/dist/render/DatasetManager.js.map +1 -1
- package/dist/render/GeometryBuilder.d.ts +11 -0
- package/dist/render/GeometryBuilder.d.ts.map +1 -1
- package/dist/render/GeometryBuilder.js +2 -1
- package/dist/render/GeometryBuilder.js.map +1 -1
- package/dist/render/S3MViewer.d.ts +159 -5
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +331 -13
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/StyleMaterial.d.ts +10 -1
- package/dist/render/StyleMaterial.d.ts.map +1 -1
- package/dist/render/StyleMaterial.js +9 -1
- package/dist/render/StyleMaterial.js.map +1 -1
- package/dist/render/TextureFactory.d.ts +23 -1
- package/dist/render/TextureFactory.d.ts.map +1 -1
- package/dist/render/TextureFactory.js +32 -8
- package/dist/render/TextureFactory.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/LightRig.d.ts +21 -7
- package/dist/render/viewer/LightRig.d.ts.map +1 -1
- package/dist/render/viewer/LightRig.js +11 -13
- package/dist/render/viewer/LightRig.js.map +1 -1
- 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/dist/render/viewer/types.d.ts +12 -0
- package/dist/render/viewer/types.d.ts.map +1 -1
- package/dist/render/viewer/types.js.map +1 -1
- package/dist/tileset/S3MTileset.d.ts +19 -0
- package/dist/tileset/S3MTileset.d.ts.map +1 -1
- package/dist/tileset/S3MTileset.js +16 -0
- package/dist/tileset/S3MTileset.js.map +1 -1
- package/docs/API.md +124 -3
- 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/DatasetManager.ts +21 -0
- package/src/render/GeometryBuilder.ts +13 -1
- package/src/render/S3MViewer.ts +401 -14
- package/src/render/StyleMaterial.ts +16 -2
- package/src/render/TextureFactory.ts +50 -8
- package/src/render/analysis/DepthPass.ts +278 -0
- package/src/render/viewer/LightRig.ts +23 -13
- package/src/render/viewer/PickService.ts +47 -0
- package/src/render/viewer/types.ts +12 -0
- package/src/tileset/S3MTileset.ts +24 -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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"}
|