s3m-three 0.0.0-stage → 0.1.0

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.
Files changed (128) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +57 -2
  3. package/dist/core/AttributeQuery.d.ts +97 -0
  4. package/dist/core/AttributeQuery.d.ts.map +1 -0
  5. package/dist/core/AttributeQuery.js +221 -0
  6. package/dist/core/AttributeQuery.js.map +1 -0
  7. package/dist/core/BinaryReader.d.ts +38 -0
  8. package/dist/core/BinaryReader.d.ts.map +1 -0
  9. package/dist/core/BinaryReader.js +88 -0
  10. package/dist/core/BinaryReader.js.map +1 -0
  11. package/dist/core/CRNDecode.d.ts +13 -0
  12. package/dist/core/CRNDecode.d.ts.map +1 -0
  13. package/dist/core/CRNDecode.js +84 -0
  14. package/dist/core/CRNDecode.js.map +1 -0
  15. package/dist/core/DXTTextureDecode.d.ts +21 -0
  16. package/dist/core/DXTTextureDecode.d.ts.map +1 -0
  17. package/dist/core/DXTTextureDecode.js +236 -0
  18. package/dist/core/DXTTextureDecode.js.map +1 -0
  19. package/dist/core/FeatureInfo.d.ts +45 -0
  20. package/dist/core/FeatureInfo.d.ts.map +1 -0
  21. package/dist/core/FeatureInfo.js +125 -0
  22. package/dist/core/FeatureInfo.js.map +1 -0
  23. package/dist/core/MeshOpt.d.ts +88 -0
  24. package/dist/core/MeshOpt.d.ts.map +1 -0
  25. package/dist/core/MeshOpt.js +336 -0
  26. package/dist/core/MeshOpt.js.map +1 -0
  27. package/dist/core/S3MBParser.d.ts +27 -0
  28. package/dist/core/S3MBParser.d.ts.map +1 -0
  29. package/dist/core/S3MBParser.js +503 -0
  30. package/dist/core/S3MBParser.js.map +1 -0
  31. package/dist/core/TextureFormat.d.ts +44 -0
  32. package/dist/core/TextureFormat.d.ts.map +1 -0
  33. package/dist/core/TextureFormat.js +97 -0
  34. package/dist/core/TextureFormat.js.map +1 -0
  35. package/dist/core/types.d.ts +235 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +2 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/index.d.ts +43 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +32 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/render/CoordinateHelper.d.ts +90 -0
  44. package/dist/render/CoordinateHelper.d.ts.map +1 -0
  45. package/dist/render/CoordinateHelper.js +85 -0
  46. package/dist/render/CoordinateHelper.js.map +1 -0
  47. package/dist/render/DatasetManager.d.ts +109 -0
  48. package/dist/render/DatasetManager.d.ts.map +1 -0
  49. package/dist/render/DatasetManager.js +229 -0
  50. package/dist/render/DatasetManager.js.map +1 -0
  51. package/dist/render/EdgeLines.d.ts +69 -0
  52. package/dist/render/EdgeLines.d.ts.map +1 -0
  53. package/dist/render/EdgeLines.js +293 -0
  54. package/dist/render/EdgeLines.js.map +1 -0
  55. package/dist/render/FeatureStyleManager.d.ts +159 -0
  56. package/dist/render/FeatureStyleManager.d.ts.map +1 -0
  57. package/dist/render/FeatureStyleManager.js +629 -0
  58. package/dist/render/FeatureStyleManager.js.map +1 -0
  59. package/dist/render/GeoAdapter.d.ts +56 -0
  60. package/dist/render/GeoAdapter.d.ts.map +1 -0
  61. package/dist/render/GeoAdapter.js +49 -0
  62. package/dist/render/GeoAdapter.js.map +1 -0
  63. package/dist/render/GeometryBuilder.d.ts +56 -0
  64. package/dist/render/GeometryBuilder.d.ts.map +1 -0
  65. package/dist/render/GeometryBuilder.js +694 -0
  66. package/dist/render/GeometryBuilder.js.map +1 -0
  67. package/dist/render/GroundManager.d.ts +61 -0
  68. package/dist/render/GroundManager.d.ts.map +1 -0
  69. package/dist/render/GroundManager.js +221 -0
  70. package/dist/render/GroundManager.js.map +1 -0
  71. package/dist/render/OrthoProjection.d.ts +84 -0
  72. package/dist/render/OrthoProjection.d.ts.map +1 -0
  73. package/dist/render/OrthoProjection.js +141 -0
  74. package/dist/render/OrthoProjection.js.map +1 -0
  75. package/dist/render/Picker.d.ts +43 -0
  76. package/dist/render/Picker.d.ts.map +1 -0
  77. package/dist/render/Picker.js +266 -0
  78. package/dist/render/Picker.js.map +1 -0
  79. package/dist/render/S3MLayer.d.ts +457 -0
  80. package/dist/render/S3MLayer.d.ts.map +1 -0
  81. package/dist/render/S3MLayer.js +1860 -0
  82. package/dist/render/S3MLayer.js.map +1 -0
  83. package/dist/render/S3MViewer.d.ts +390 -0
  84. package/dist/render/S3MViewer.d.ts.map +1 -0
  85. package/dist/render/S3MViewer.js +1713 -0
  86. package/dist/render/S3MViewer.js.map +1 -0
  87. package/dist/render/StyleMaterial.d.ts +164 -0
  88. package/dist/render/StyleMaterial.d.ts.map +1 -0
  89. package/dist/render/StyleMaterial.js +481 -0
  90. package/dist/render/StyleMaterial.js.map +1 -0
  91. package/dist/render/TextureFactory.d.ts +33 -0
  92. package/dist/render/TextureFactory.d.ts.map +1 -0
  93. package/dist/render/TextureFactory.js +117 -0
  94. package/dist/render/TextureFactory.js.map +1 -0
  95. package/dist/tileset/S3MTileset.d.ts +129 -0
  96. package/dist/tileset/S3MTileset.d.ts.map +1 -0
  97. package/dist/tileset/S3MTileset.js +479 -0
  98. package/dist/tileset/S3MTileset.js.map +1 -0
  99. package/dist/vendor/crunch_decoder.module.js +1140 -0
  100. package/dist/vendor/meshopt_decoder.module.js +118 -0
  101. package/docs/API.md +744 -0
  102. package/package.json +67 -4
  103. package/src/core/AttributeQuery.ts +268 -0
  104. package/src/core/BinaryReader.ts +116 -0
  105. package/src/core/CRNDecode.ts +107 -0
  106. package/src/core/DXTTextureDecode.ts +260 -0
  107. package/src/core/FeatureInfo.ts +150 -0
  108. package/src/core/MeshOpt.ts +401 -0
  109. package/src/core/S3MBParser.ts +590 -0
  110. package/src/core/TextureFormat.ts +103 -0
  111. package/src/core/types.ts +222 -0
  112. package/src/index.ts +134 -0
  113. package/src/render/DatasetManager.ts +301 -0
  114. package/src/render/EdgeLines.ts +343 -0
  115. package/src/render/FeatureStyleManager.ts +773 -0
  116. package/src/render/GeoAdapter.ts +72 -0
  117. package/src/render/GeometryBuilder.ts +840 -0
  118. package/src/render/GroundManager.ts +245 -0
  119. package/src/render/OrthoProjection.ts +189 -0
  120. package/src/render/Picker.ts +293 -0
  121. package/src/render/S3MViewer.ts +1980 -0
  122. package/src/render/StyleMaterial.ts +602 -0
  123. package/src/render/TextureFactory.ts +134 -0
  124. package/src/tileset/S3MTileset.ts +552 -0
  125. package/src/vendor/crunch_decoder.module.d.ts +27 -0
  126. package/src/vendor/crunch_decoder.module.js +1140 -0
  127. package/src/vendor/meshopt_decoder.module.d.ts +31 -0
  128. package/src/vendor/meshopt_decoder.module.js +118 -0
@@ -0,0 +1,88 @@
1
+ export class BinaryReader {
2
+ buffer;
3
+ base;
4
+ view;
5
+ offset;
6
+ _decoder = new TextDecoder('utf-8');
7
+ constructor(buffer, byteOffset = 0, byteLength) {
8
+ this.buffer = buffer;
9
+ this.base = byteOffset;
10
+ this.view = new DataView(buffer, byteOffset, byteLength === undefined ? buffer.byteLength - byteOffset : byteLength);
11
+ this.offset = 0;
12
+ }
13
+ get remaining() {
14
+ return this.view.byteLength - this.offset;
15
+ }
16
+ u8() {
17
+ const v = this.view.getUint8(this.offset);
18
+ this.offset += 1;
19
+ return v;
20
+ }
21
+ u16() {
22
+ const v = this.view.getUint16(this.offset, true);
23
+ this.offset += 2;
24
+ return v;
25
+ }
26
+ u32() {
27
+ const v = this.view.getUint32(this.offset, true);
28
+ this.offset += 4;
29
+ return v;
30
+ }
31
+ i32() {
32
+ const v = this.view.getInt32(this.offset, true);
33
+ this.offset += 4;
34
+ return v;
35
+ }
36
+ f32() {
37
+ const v = this.view.getFloat32(this.offset, true);
38
+ this.offset += 4;
39
+ return v;
40
+ }
41
+ f64() {
42
+ const v = this.view.getFloat64(this.offset, true);
43
+ this.offset += 8;
44
+ return v;
45
+ }
46
+ /** 返回原始字节视图(不拷贝,生命周期绑定底层 buffer) */
47
+ bytes(n) {
48
+ const a = new Uint8Array(this.buffer, this.base + this.offset, n);
49
+ this.offset += n;
50
+ return a;
51
+ }
52
+ /** 返回拷贝,用于纹理等需要脱离源 buffer 的数据 */
53
+ bytesCopy(n) {
54
+ const a = new Uint8Array(this.buffer, this.base + this.offset, n);
55
+ this.offset += n;
56
+ return a.slice();
57
+ }
58
+ string() {
59
+ const len = this.u32();
60
+ const a = new Uint8Array(this.buffer, this.base + this.offset, len);
61
+ this.offset += len;
62
+ return this._decoder.decode(a);
63
+ }
64
+ skip(n) {
65
+ this.offset += n;
66
+ }
67
+ /**
68
+ * 4 字节对齐。rel 是对齐基准在流中的偏移,默认 0(即整个流起点)。
69
+ * 纹理流用的是「纹理流起点」而不是文件起点,所以要显式传。
70
+ */
71
+ align4(rel = 0) {
72
+ const m = (this.offset - rel) % 4;
73
+ if (m !== 0)
74
+ this.skip(4 - m);
75
+ }
76
+ vec3f64() {
77
+ return { x: this.f64(), y: this.f64(), z: this.f64() };
78
+ }
79
+ boundingBox() {
80
+ return {
81
+ center: this.vec3f64(),
82
+ xExtent: this.vec3f64(),
83
+ yExtent: this.vec3f64(),
84
+ zExtent: this.vec3f64(),
85
+ };
86
+ }
87
+ }
88
+ //# sourceMappingURL=BinaryReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BinaryReader.js","sourceRoot":"","sources":["../../src/core/BinaryReader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface CRNResult {
2
+ width: number;
3
+ height: number;
4
+ /** CRN 里打包的 mip 层数(我们只取第 0 层,其余交给 three 生成) */
5
+ levels: number;
6
+ /** 1 / 3 / 5 */
7
+ dxtFormat: 1 | 3 | 5;
8
+ /** 第 0 层的 DXT 块数据 */
9
+ data: Uint8Array;
10
+ }
11
+ /** 解一个 CRN 块。失败时抛错(调用方负责降级成「无贴图」)。 */
12
+ export declare function transcodeCRN(src: Uint8Array): Promise<CRNResult>;
13
+ //# sourceMappingURL=CRNDecode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CRNDecode.d.ts","sourceRoot":"","sources":["../../src/core/CRNDecode.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB;IAChB,SAAS,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,qBAAqB;IACrB,IAAI,EAAE,UAAU,CAAC;CAClB;AA2CD,sCAAsC;AACtC,wBAAsB,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAyCtE"}
@@ -0,0 +1,84 @@
1
+ let modulePromise = null;
2
+ /**
3
+ * wasm 是否真的可用。
4
+ *
5
+ * 注意:胶水在实例化开始前就把 `Module.asm` 赋成了空对象,所以「asm 存在」不等于
6
+ * 「就绪」——必须看导出表里有没有东西,否则 `_malloc` 会在内部对一个 undefined 调 apply。
7
+ */
8
+ function isReady(m) {
9
+ return !!m.asm && Object.keys(m.asm).length > 0;
10
+ }
11
+ /** wasm 只在真的遇到 CRN 纹理时才加载(内联在 vendor 里,不发额外请求) */
12
+ async function getCrunch() {
13
+ if (!modulePromise) {
14
+ modulePromise = (async () => {
15
+ const mod = await import('../vendor/crunch_decoder.module.js');
16
+ const m = mod.default;
17
+ if (!isReady(m)) {
18
+ await new Promise((resolve) => {
19
+ m.onRuntimeInitialized = () => resolve();
20
+ const tick = () => {
21
+ if (isReady(m))
22
+ resolve();
23
+ else
24
+ setTimeout(tick, 8);
25
+ };
26
+ tick();
27
+ });
28
+ }
29
+ return m;
30
+ })();
31
+ }
32
+ return modulePromise;
33
+ }
34
+ /** CRN 文件头魔数 'Hx';S3M 的纹理裸块没有容器头,但 crunch 负载自己保留了这两个字节 */
35
+ const CRN_MAGIC = [0x48, 0x78];
36
+ function hasMagic(src) {
37
+ return src.length >= 2 && src[0] === CRN_MAGIC[0] && src[1] === CRN_MAGIC[1];
38
+ }
39
+ /** 解一个 CRN 块。失败时抛错(调用方负责降级成「无贴图」)。 */
40
+ export async function transcodeCRN(src) {
41
+ const srcSize = src.byteLength;
42
+ if (!srcSize)
43
+ throw new Error('[s3m] CRN 数据为空');
44
+ // 先验魔数:压缩方式标成 CRN 但数据其实不是(见过 DXT 被误标)时,
45
+ // crunch 会拿垃圾头解出一个尺寸「看着合理」的块,越早拦越好;也省掉一次 wasm 加载
46
+ if (!hasMagic(src))
47
+ throw new Error('[s3m] 数据没有 CRN 头(Hx),不是 crunch 负载');
48
+ const crunch = await getCrunch();
49
+ const srcPtr = crunch._malloc(srcSize);
50
+ if (!srcPtr)
51
+ throw new Error('[s3m] crunch 分配源数据失败');
52
+ try {
53
+ // 注意:malloc 可能触发堆扩容,HEAPU8 会换成新视图,所以每次都重新取
54
+ crunch.HEAPU8.set(src, srcPtr);
55
+ const fmt = crunch._crn_get_dxt_format(srcPtr, srcSize);
56
+ const dxtFormat = fmt === 0 ? 1 : fmt === 1 ? 3 : fmt === 2 ? 5 : 0;
57
+ if (!dxtFormat)
58
+ throw new Error(`[s3m] 不是可识别的 CRN 数据(dxtFormat=${fmt})`);
59
+ const width = crunch._crn_get_width(srcPtr, srcSize);
60
+ const height = crunch._crn_get_height(srcPtr, srcSize);
61
+ const levels = crunch._crn_get_levels(srcPtr, srcSize);
62
+ if (!(width > 0) || !(height > 0)) {
63
+ throw new Error(`[s3m] CRN 尺寸异常:${width}×${height}`);
64
+ }
65
+ // 只解第 0 层:DXT1 每 4×4 块 8 字节,DXT3/5 是 16 字节
66
+ const blockSize = dxtFormat === 1 ? 8 : 16;
67
+ const dstSize = Math.max(1, width >> 2) * Math.max(1, height >> 2) * blockSize;
68
+ const dstPtr = crunch._malloc(dstSize);
69
+ if (!dstPtr)
70
+ throw new Error('[s3m] crunch 分配输出缓冲失败');
71
+ try {
72
+ crunch._crn_decompress(srcPtr, srcSize, dstPtr, dstSize, 0, 1);
73
+ const data = new Uint8Array(crunch.HEAPU8.subarray(dstPtr, dstPtr + dstSize));
74
+ return { width, height, levels, dxtFormat: dxtFormat, data };
75
+ }
76
+ finally {
77
+ crunch._free(dstPtr);
78
+ }
79
+ }
80
+ finally {
81
+ crunch._free(srcPtr);
82
+ }
83
+ }
84
+ //# sourceMappingURL=CRNDecode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CRNDecode.js","sourceRoot":"","sources":["../../src/core/CRNDecode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * DXT1 / DXT3 / DXT5 纹理解码(squish 算法的 JS 移植)
3
+ *
4
+ * 来源:SuperMap iClient3D S3M SDK(Apache-2.0)。
5
+ * 迁移到 TS 时做了两件事,算法本身未改:
6
+ * 1. 补齐类型;
7
+ * 2. 修掉 `DecompressAlphaDxt3` 里把 `block` 误写成未定义全局 `bytes` 的笔误
8
+ * (DXT3 纹理此前会直接 ReferenceError)。
9
+ */
10
+ declare const DXTTextureDecode: {
11
+ /**
12
+ * @param out 输出缓冲,长度须为 width*height*4
13
+ * @param width 像素宽
14
+ * @param height 像素高
15
+ * @param block 压缩块
16
+ * @param format S3M pixelFormat(>11 或 5 走 DXT5,其余走 DXT1)
17
+ */
18
+ decode(out: Uint8Array, width: number, height: number, block: Uint8Array, format: number): void;
19
+ };
20
+ export default DXTTextureDecode;
21
+ //# sourceMappingURL=DXTTextureDecode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DXTTextureDecode.d.ts","sourceRoot":"","sources":["../../src/core/DXTTextureDecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoOH,QAAA,MAAM,gBAAgB;IACpB;;;;;;OAMG;gBACS,UAAU,SAAS,MAAM,UAAU,MAAM,SAAS,UAAU,UAAU,MAAM,GAAG,IAAI;CAahG,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * DXT1 / DXT3 / DXT5 纹理解码(squish 算法的 JS 移植)
3
+ *
4
+ * 来源:SuperMap iClient3D S3M SDK(Apache-2.0)。
5
+ * 迁移到 TS 时做了两件事,算法本身未改:
6
+ * 1. 补齐类型;
7
+ * 2. 修掉 `DecompressAlphaDxt3` 里把 `block` 误写成未定义全局 `bytes` 的笔误
8
+ * (DXT3 纹理此前会直接 ReferenceError)。
9
+ */
10
+ const kDxt1 = 1 << 0;
11
+ const kDxt3 = 1 << 1;
12
+ const kDxt5 = 1 << 2;
13
+ const krgb565 = 1 << 5;
14
+ function Unpack565(packed0, packed1, colour, offset) {
15
+ const value = packed0 | (packed1 << 8);
16
+ const red = (value >> 11) & 0x1f;
17
+ const green = (value >> 5) & 0x3f;
18
+ const blue = value & 0x1f;
19
+ colour[offset + 0] = (red << 3) | (red >> 2);
20
+ colour[offset + 1] = (green << 2) | (green >> 4);
21
+ colour[offset + 2] = (blue << 3) | (blue >> 2);
22
+ colour[offset + 3] = 255;
23
+ return value;
24
+ }
25
+ function DecompressColour(rgba, block, nOffset, isDxt1) {
26
+ const codes = new Uint8Array(16);
27
+ const a = Unpack565(block[nOffset + 0], block[nOffset + 1], codes, 0);
28
+ const b = Unpack565(block[nOffset + 2], block[nOffset + 3], codes, 4);
29
+ for (let i = 0; i < 3; i++) {
30
+ const c = codes[i];
31
+ const d = codes[4 + i];
32
+ if (isDxt1 && a <= b) {
33
+ codes[8 + i] = (c + d) / 2;
34
+ codes[12 + i] = 0;
35
+ }
36
+ else {
37
+ codes[8 + i] = (2 * c + d) / 3;
38
+ codes[12 + i] = (c + 2 * d) / 3;
39
+ }
40
+ }
41
+ codes[8 + 3] = 255;
42
+ codes[12 + 3] = isDxt1 && a <= b ? 0 : 255;
43
+ const indices = new Uint8Array(16);
44
+ for (let i = 0; i < 4; ++i) {
45
+ const packed = block[nOffset + 4 + i];
46
+ indices[4 * i + 0] = packed & 0x3;
47
+ indices[4 * i + 1] = (packed >> 2) & 0x3;
48
+ indices[4 * i + 2] = (packed >> 4) & 0x3;
49
+ indices[4 * i + 3] = (packed >> 6) & 0x3;
50
+ }
51
+ for (let i = 0; i < 16; ++i) {
52
+ const offset = 4 * indices[i];
53
+ for (let j = 0; j < 4; ++j)
54
+ rgba[4 * i + j] = codes[offset + j];
55
+ }
56
+ }
57
+ function DecompressAlphaDxt3(rgba, block, nOffset) {
58
+ // unpack the alpha values pairwise
59
+ for (let i = 0; i < 8; ++i) {
60
+ // quantise down to 4 bits
61
+ const quant = block[nOffset + i];
62
+ // unpack the values
63
+ const lo = quant & 0x0f;
64
+ const hi = quant & 0xf0;
65
+ // convert back up to bytes
66
+ rgba[8 * i + 3] = lo | (lo << 4);
67
+ rgba[8 * i + 7] = hi | (hi >> 4);
68
+ }
69
+ }
70
+ function DecompressAlphaDxt5(rgba, block, start) {
71
+ const alpha0 = block[start + 0];
72
+ const alpha1 = block[start + 1];
73
+ const codes = new Uint8Array(8);
74
+ codes[0] = alpha0;
75
+ codes[1] = alpha1;
76
+ if (alpha0 <= alpha1) {
77
+ // use 5-alpha codebook
78
+ for (let i = 1; i < 5; ++i)
79
+ codes[1 + i] = ((5 - i) * alpha0 + i * alpha1) / 5;
80
+ codes[6] = 0;
81
+ codes[7] = 255;
82
+ }
83
+ else {
84
+ // use 7-alpha codebook
85
+ for (let i = 1; i < 7; ++i)
86
+ codes[1 + i] = ((7 - i) * alpha0 + i * alpha1) / 7;
87
+ }
88
+ const indices = new Uint8Array(16);
89
+ let nOffset = start + 2;
90
+ let nBegin = 0;
91
+ for (let i = 0; i < 2; ++i) {
92
+ // grab 3 bytes
93
+ let value = 0;
94
+ for (let j = 0; j < 3; ++j) {
95
+ const byte = block[nOffset++];
96
+ value |= byte << (8 * j);
97
+ }
98
+ // unpack 8 3-bit values from it
99
+ for (let j = 0; j < 8; ++j) {
100
+ const index = (value >> (3 * j)) & 0x7;
101
+ indices[nBegin++] = index;
102
+ }
103
+ }
104
+ for (let i = 0; i < 16; ++i)
105
+ rgba[4 * i + 3] = codes[indices[i]];
106
+ }
107
+ function Decompress(rgba, block, nOffset, flags) {
108
+ let nOffset2 = 0;
109
+ if ((flags & (kDxt3 | kDxt5)) !== 0)
110
+ nOffset2 = 8;
111
+ DecompressColour(rgba, block, nOffset + nOffset2, (flags & kDxt1) !== 0);
112
+ if ((flags & kDxt3) !== 0) {
113
+ DecompressAlphaDxt3(rgba, block, nOffset);
114
+ }
115
+ else if ((flags & kDxt5) !== 0) {
116
+ DecompressAlphaDxt5(rgba, block, nOffset);
117
+ }
118
+ }
119
+ /** 把 block 视为 uint16 数组:DXT1 的 565 快路径需要按 16 位读 */
120
+ function asU16(view) {
121
+ const start = view.byteOffset & ~1;
122
+ const len = (view.byteLength + (view.byteOffset & 1)) >> 1;
123
+ return new Uint16Array(view.buffer, start, len);
124
+ }
125
+ function DecompressImage565(rgb565, width, height, blocks) {
126
+ const c = new Uint16Array(4);
127
+ const dst = rgb565;
128
+ let m = 0;
129
+ let dstI = 0;
130
+ let i = 0;
131
+ let r0 = 0;
132
+ let g0 = 0;
133
+ let b0 = 0;
134
+ let r1 = 0;
135
+ let g1 = 0;
136
+ let b1 = 0;
137
+ const blockWidth = width / 4;
138
+ const blockHeight = height / 4;
139
+ for (let blockY = 0; blockY < blockHeight; blockY++) {
140
+ for (let blockX = 0; blockX < blockWidth; blockX++) {
141
+ i = 4 * ((blockHeight - blockY) * blockWidth + blockX);
142
+ c[0] = blocks[i];
143
+ c[1] = blocks[i + 1];
144
+ r0 = c[0] & 0x1f;
145
+ g0 = c[0] & 0x7e0;
146
+ b0 = c[0] & 0xf800;
147
+ r1 = c[1] & 0x1f;
148
+ g1 = c[1] & 0x7e0;
149
+ b1 = c[1] & 0xf800;
150
+ // Interpolate between c0 and c1 to get c2 and c3.
151
+ // 1/3 用 3/8 近似、2/3 用 5/8 近似 —— 这也是多数 GPU 硬件解码器的做法
152
+ c[2] = ((5 * r0 + 3 * r1) >> 3) | (((5 * g0 + 3 * g1) >> 3) & 0x7e0) | (((5 * b0 + 3 * b1) >> 3) & 0xf800);
153
+ c[3] = ((5 * r1 + 3 * r0) >> 3) | (((5 * g1 + 3 * g0) >> 3) & 0x7e0) | (((5 * b1 + 3 * b0) >> 3) & 0xf800);
154
+ m = blocks[i + 2];
155
+ dstI = blockY * 4 * width + blockX * 4;
156
+ dst[dstI] = c[m & 0x3];
157
+ dst[dstI + 1] = c[(m >> 2) & 0x3];
158
+ dst[dstI + 2] = c[(m >> 4) & 0x3];
159
+ dst[dstI + 3] = c[(m >> 6) & 0x3];
160
+ dstI += width;
161
+ dst[dstI] = c[(m >> 8) & 0x3];
162
+ dst[dstI + 1] = c[(m >> 10) & 0x3];
163
+ dst[dstI + 2] = c[(m >> 12) & 0x3];
164
+ dst[dstI + 3] = c[(m >> 14) & 0x3];
165
+ m = blocks[i + 3];
166
+ dstI += width;
167
+ dst[dstI] = c[m & 0x3];
168
+ dst[dstI + 1] = c[(m >> 2) & 0x3];
169
+ dst[dstI + 2] = c[(m >> 4) & 0x3];
170
+ dst[dstI + 3] = c[(m >> 6) & 0x3];
171
+ dstI += width;
172
+ dst[dstI] = c[(m >> 8) & 0x3];
173
+ dst[dstI + 1] = c[(m >> 10) & 0x3];
174
+ dst[dstI + 2] = c[(m >> 12) & 0x3];
175
+ dst[dstI + 3] = c[(m >> 14) & 0x3];
176
+ }
177
+ }
178
+ return dst;
179
+ }
180
+ /**
181
+ * 解压整张 DXT 图。
182
+ *
183
+ * 解出的像素按 `{ r1,g1,b1,a1, ... , rn,gn,bn,an }`(n = width*height)连续写入 `rgba`。
184
+ */
185
+ function DecompressImage(rgba, width, height, blocks, flags) {
186
+ const bytesPerBlock = (flags & kDxt1) !== 0 ? 8 : 16;
187
+ let nOffset = 0;
188
+ for (let y = 0; y < height; y += 4) {
189
+ for (let x = 0; x < width; x += 4) {
190
+ const targetRgba = new Uint8Array(4 * 16);
191
+ Decompress(targetRgba, blocks, nOffset, flags);
192
+ let nOffsetTarget = 0;
193
+ for (let py = 0; py < 4; ++py) {
194
+ for (let px = 0; px < 4; ++px) {
195
+ const sx = x + px;
196
+ const sy = y + py;
197
+ if (sx < width && sy < height) {
198
+ // flip Y
199
+ let nBegin = 4 * (width * (height - sy) + sx);
200
+ for (let i = 0; i < 4; ++i)
201
+ rgba[nBegin++] = targetRgba[nOffsetTarget++];
202
+ }
203
+ else {
204
+ nOffsetTarget += 4;
205
+ }
206
+ }
207
+ }
208
+ // advance
209
+ nOffset += bytesPerBlock;
210
+ }
211
+ }
212
+ }
213
+ const DXTTextureDecode = {
214
+ /**
215
+ * @param out 输出缓冲,长度须为 width*height*4
216
+ * @param width 像素宽
217
+ * @param height 像素高
218
+ * @param block 压缩块
219
+ * @param format S3M pixelFormat(>11 或 5 走 DXT5,其余走 DXT1)
220
+ */
221
+ decode(out, width, height, block, format) {
222
+ if (out == null || block == null || height === 0 || width === 0)
223
+ return;
224
+ // 有 alpha 通道 → RGBA,否则走 rgb565
225
+ // S3MPixelFormat.BGR -> 11 / LUMINANCE_ALPHA -> 5
226
+ const flags = format > 11 || format === 5 ? kDxt5 : kDxt1 | krgb565;
227
+ if (flags & kDxt1 && flags & krgb565) {
228
+ DecompressImage565(asU16(out), width, height, asU16(block));
229
+ }
230
+ else {
231
+ DecompressImage(out, width, height, block, flags);
232
+ }
233
+ },
234
+ };
235
+ export default DXTTextureDecode;
236
+ //# sourceMappingURL=DXTTextureDecode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DXTTextureDecode.js","sourceRoot":"","sources":["../../src/core/DXTTextureDecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;AAEvB,SAAS,SAAS,CAAC,OAAe,EAAE,OAAe,EAAE,MAAkB,EAAE,MAAc;IACrF,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IAEvC,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAClC,MAAM,IAAI,GAAG,KAAK,GAAG,IAAI,CAAC;IAE1B,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IACjD,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;IAC/C,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IAEzB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAgB,EAAE,KAAiB,EAAE,OAAe,EAAE,MAAe;IAC7F,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAEjC,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACtE,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAEtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEvB,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3B,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAC/B,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;IACnB,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAE3C,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAEtC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,GAAG,CAAC;QAClC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;QACzC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;QACzC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAgB,EAAE,KAAiB,EAAE,OAAe;IAC/E,mCAAmC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3B,0BAA0B;QAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QAEjC,oBAAoB;QACpB,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC;QAExB,2BAA2B;QAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAgB,EAAE,KAAiB,EAAE,KAAa;IAC7E,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAEhC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAEhC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAClB,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAClB,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QACrB,uBAAuB;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/E,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACb,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACjB,CAAC;SAAM,CAAC;QACN,uBAAuB;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC;IACxB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC3B,eAAe;QACf,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9B,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3B,CAAC;QAED,gCAAgC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YACvC,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC;QAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,UAAU,CAAC,IAAgB,EAAE,KAAiB,EAAE,OAAe,EAAE,KAAa;IACrF,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC;QAAE,QAAQ,GAAG,CAAC,CAAC;IAElD,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAEzE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;SAAM,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,mDAAmD;AACnD,SAAS,KAAK,CAAC,IAAgB;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAmB,EAAE,KAAa,EAAE,MAAc,EAAE,MAAmB;IACjG,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAC;IACnB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IAEX,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC;IAC7B,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC;IAC/B,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;QACpD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC;YACnD,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,GAAG,MAAM,CAAC,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACrB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACjB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAClB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;YACnB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACjB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAClB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;YACnB,kDAAkD;YAClD,kDAAkD;YAClD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAC3G,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;YAC3G,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClB,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YACvB,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClC,IAAI,IAAI,KAAK,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9B,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;YACnC,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClB,IAAI,IAAI,KAAK,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YACvB,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAClC,IAAI,IAAI,KAAK,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9B,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;YACnC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,IAAgB,EAAE,KAAa,EAAE,MAAc,EAAE,MAAkB,EAAE,KAAa;IACzG,MAAM,aAAa,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAErD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1C,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAE/C,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;gBAC9B,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;oBAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;oBAClB,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;oBAClB,IAAI,EAAE,GAAG,KAAK,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC;wBAC9B,SAAS;wBACT,IAAI,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;wBAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;4BAAE,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;oBAC3E,CAAC;yBAAM,CAAC;wBACN,aAAa,IAAI,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,UAAU;YACV,OAAO,IAAI,aAAa,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG;IACvB;;;;;;OAMG;IACH,MAAM,CAAC,GAAe,EAAE,KAAa,EAAE,MAAc,EAAE,KAAiB,EAAE,MAAc;QACtF,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO;QAExE,+BAA+B;QAC/B,kDAAkD;QAClD,MAAM,KAAK,GAAG,MAAM,GAAG,EAAE,IAAI,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC;QAEpE,IAAI,KAAK,GAAG,KAAK,IAAI,KAAK,GAAG,OAAO,EAAE,CAAC;YACrC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,eAAe,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;CACF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * 单体属性提取
3
+ *
4
+ * S3M 的 `pickInfo` 是「SMID → batchId + 顶点区间」的映射,本身不带业务属性
5
+ * (OSGB 转 S3M 的数据通常没有属性表)。所以这里做两件事:
6
+ * 1. 反查 SMID —— 这是和 iServer 侧数据对齐的唯一标识;
7
+ * 2. 从几何直接算出可信的派生属性(高度、基底高程、外接盒、三角面数、楼层估算)。
8
+ *
9
+ * 派生属性是「算出来的」而不是「查出来的」,所以每一项都标注了计算口径,
10
+ * 避免使用者误以为是业务数据。
11
+ */
12
+ import type { BufferGeometry } from 'three';
13
+ import type { FeatureAttributes, GeoPackageEntry, PickEntry, PickSegment, SegmentBox } from './types.js';
14
+ /** 楼层估算用的默认层高(米) */
15
+ export declare const DEFAULT_FLOOR_HEIGHT = 3.2;
16
+ /**
17
+ * 单体的控制位。
18
+ *
19
+ * 顶点区间型单体用 `batchId`(写进 `aBatchId`),实例化型用 `instanceBatchId`
20
+ * (写进 `aInstanceBatchId`)。两者都走「每网格一张状态纹理」,所以对上层是同一个概念。
21
+ */
22
+ export declare function pickEntryId(entry?: PickEntry | null): number;
23
+ /** 实例化几何里「实例序号 → 单体」的反查表 */
24
+ export interface InstanceFeature {
25
+ smid: number;
26
+ /** 控制位(状态纹理下标) */
27
+ batchId: number;
28
+ }
29
+ export declare function buildInstanceLookup(pickInfo?: Record<number, PickEntry> | null): Map<number, InstanceFeature>;
30
+ export declare function resolveFeature(geo: GeoPackageEntry | undefined, batchId: number): {
31
+ smid: number | null;
32
+ segments: PickSegment[];
33
+ };
34
+ /**
35
+ * 统计单体顶点区间包围盒 + 该单体自身的三角面数。
36
+ */
37
+ export declare function measureSegments(geometry: BufferGeometry | undefined, segments: PickSegment[]): SegmentBox | null;
38
+ /** 组装给 UI 展示的属性对象 */
39
+ export declare function buildAttributes(args: {
40
+ smid: number | null;
41
+ box: SegmentBox | null;
42
+ triangles: number;
43
+ floorHeight?: number;
44
+ }): FeatureAttributes;
45
+ //# sourceMappingURL=FeatureInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeatureInfo.d.ts","sourceRoot":"","sources":["../../src/core/FeatureInfo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEzG,oBAAoB;AACpB,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAK5D;AAED,4BAA4B;AAC5B,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,IAAI,GAC1C,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAW9B;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,GAAG,SAAS,EAChC,OAAO,EAAE,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;CAAE,CAUlD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,UAAU,GAAG,IAAI,CA+ChH;AAED,qBAAqB;AACrB,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,iBAAiB,CAmBpB"}
@@ -0,0 +1,125 @@
1
+ /** 楼层估算用的默认层高(米) */
2
+ export const DEFAULT_FLOOR_HEIGHT = 3.2;
3
+ /**
4
+ * 单体的控制位。
5
+ *
6
+ * 顶点区间型单体用 `batchId`(写进 `aBatchId`),实例化型用 `instanceBatchId`
7
+ * (写进 `aInstanceBatchId`)。两者都走「每网格一张状态纹理」,所以对上层是同一个概念。
8
+ */
9
+ export function pickEntryId(entry) {
10
+ if (!entry)
11
+ return -1;
12
+ if (entry.batchId != null)
13
+ return entry.batchId;
14
+ if (entry.instanceBatchId != null)
15
+ return entry.instanceBatchId;
16
+ return -1;
17
+ }
18
+ export function buildInstanceLookup(pickInfo) {
19
+ const map = new Map();
20
+ if (!pickInfo)
21
+ return map;
22
+ for (const [key, entry] of Object.entries(pickInfo)) {
23
+ if (!entry?.instanceIds?.length)
24
+ continue;
25
+ const smid = Number(key);
26
+ if (!Number.isFinite(smid))
27
+ continue;
28
+ const batchId = pickEntryId(entry);
29
+ for (const instanceIndex of entry.instanceIds)
30
+ map.set(instanceIndex, { smid, batchId });
31
+ }
32
+ return map;
33
+ }
34
+ export function resolveFeature(geo, batchId) {
35
+ const pickInfo = geo?.pickInfo;
36
+ if (!pickInfo || batchId < 0)
37
+ return { smid: null, segments: [] };
38
+ for (const [id, entry] of Object.entries(pickInfo)) {
39
+ if (pickEntryId(entry) === batchId) {
40
+ return { smid: Number(id), segments: entry.segments ?? [] };
41
+ }
42
+ }
43
+ return { smid: null, segments: [] };
44
+ }
45
+ /**
46
+ * 统计单体顶点区间包围盒 + 该单体自身的三角面数。
47
+ */
48
+ export function measureSegments(geometry, segments) {
49
+ const pos = geometry?.getAttribute('position');
50
+ if (!pos || !segments.length)
51
+ return null;
52
+ let minX = Infinity;
53
+ let minY = Infinity;
54
+ let minZ = Infinity;
55
+ let maxX = -Infinity;
56
+ let maxY = -Infinity;
57
+ let maxZ = -Infinity;
58
+ let count = 0;
59
+ for (const seg of segments) {
60
+ const end = Math.min(seg.vertexOffset + seg.vertexCount, pos.count);
61
+ for (let i = seg.vertexOffset; i < end; i++) {
62
+ const x = pos.getX(i);
63
+ const y = pos.getY(i);
64
+ const z = pos.getZ(i);
65
+ if (x < minX)
66
+ minX = x;
67
+ if (x > maxX)
68
+ maxX = x;
69
+ if (y < minY)
70
+ minY = y;
71
+ if (y > maxY)
72
+ maxY = y;
73
+ if (z < minZ)
74
+ minZ = z;
75
+ if (z > maxZ)
76
+ maxZ = z;
77
+ count++;
78
+ }
79
+ }
80
+ if (!count)
81
+ return null;
82
+ // 单体三角面数:索引三元组的三个顶点都落在本单体区间内才算,
83
+ // 直接用整个网格的 index.count 会把整片街区都算进去。
84
+ let triangles = 0;
85
+ const index = geometry.index;
86
+ if (index) {
87
+ const mask = new Uint8Array(pos.count);
88
+ for (const seg of segments) {
89
+ const end = Math.min(seg.vertexOffset + seg.vertexCount, pos.count);
90
+ mask.fill(1, seg.vertexOffset, end);
91
+ }
92
+ const arr = index.array;
93
+ for (let i = 0; i < arr.length; i += 3) {
94
+ if (mask[arr[i]] && mask[arr[i + 1]] && mask[arr[i + 2]])
95
+ triangles++;
96
+ }
97
+ }
98
+ return { minX, minY, minZ, maxX, maxY, maxZ, count, triangles };
99
+ }
100
+ /** 组装给 UI 展示的属性对象 */
101
+ export function buildAttributes(args) {
102
+ const { smid, box, triangles, floorHeight = DEFAULT_FLOOR_HEIGHT } = args;
103
+ if (!box)
104
+ return { smid, triangles };
105
+ const height = box.maxZ - box.minZ;
106
+ return {
107
+ smid,
108
+ height: round(height, 1),
109
+ baseElevation: round(box.minZ, 1),
110
+ size: [round(box.maxX - box.minX, 1), round(box.maxY - box.minY, 1)],
111
+ bboxArea: round((box.maxX - box.minX) * (box.maxY - box.minY), 1),
112
+ floors: Math.max(1, Math.round(height / floorHeight)),
113
+ triangles: box.triangles ?? triangles,
114
+ vertices: box.count,
115
+ bbox: [
116
+ [round(box.minX, 1), round(box.minY, 1), round(box.minZ, 1)],
117
+ [round(box.maxX, 1), round(box.maxY, 1), round(box.maxZ, 1)],
118
+ ],
119
+ };
120
+ }
121
+ function round(v, d) {
122
+ const p = 10 ** d;
123
+ return Math.round(v * p) / p;
124
+ }
125
+ //# sourceMappingURL=FeatureInfo.js.map