three-base 2.0.175 → 2.0.181
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/MktMesh/MktMesh.d.ts +44 -3
- package/MktMesh/MktMesh.js +162 -6
- package/MktMesh/MktMesh.ts +170 -5
- package/MktMesh/boxLine2.d.ts +42 -0
- package/MktMesh/boxLine2.js +185 -0
- package/MktMesh/boxLine2.ts +222 -0
- package/MktMesh/imagePlane.d.ts +60 -0
- package/MktMesh/imagePlane.js +159 -0
- package/MktMesh/imagePlane.ts +204 -0
- package/MktMesh/imageTileLoader.d.ts +19 -0
- package/MktMesh/imageTileLoader.js +55 -0
- package/MktMesh/imageTileLoader.ts +64 -0
- package/MktMesh/modelSlot.d.ts +123 -0
- package/MktMesh/modelSlot.js +339 -0
- package/MktMesh/modelSlot.ts +383 -0
- package/MktMesh/panoSlotRoster.js +1 -1
- package/MktMesh/panoSlotRoster.ts +1 -1
- package/MktMesh/types.d.ts +10 -0
- package/MktMesh/types.ts +10 -0
- package/package.json +21 -1
package/MktMesh/MktMesh.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { BufferGeometry, Camera, Matrix4, Mesh, ShaderMaterial, Texture, Vector3
|
|
|
2
2
|
import { type PanoTexMode } from "./mktShader";
|
|
3
3
|
import { type PanoStitcher } from "./panoTileStitcher";
|
|
4
4
|
import type { MktMeshData, MktTextureInfo, WallPoint, WallSide } from "./types";
|
|
5
|
+
import { ImagePlane, type ImagePlaneData } from "./imagePlane";
|
|
6
|
+
import { ModelSlot, type ModelSlotData } from "./modelSlot";
|
|
5
7
|
export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
6
8
|
/** 纹理列表(每个纹理的 url + 世界矩阵) */
|
|
7
9
|
textures: MktTextureInfo[];
|
|
@@ -119,6 +121,18 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
119
121
|
* 必须与基类喂纹理处用同一个值,否则标记与地址不同源 ⇒ 整图被按 1/2 横向铺满球面(10-06 晚起纵向不分块,四槽时代是 1/4)。 */
|
|
120
122
|
get panoTexMode(): PanoTexMode;
|
|
121
123
|
private _tmpV3;
|
|
124
|
+
/**
|
|
125
|
+
* 图片平面层(⭐ 10-26 旨入库):对象挂在**本 MktMesh 的子树**里,⛔ 不是场景根
|
|
126
|
+
* ⇒ 移动/旋转/缩放这个展品时,墙 + 全景 + 平面图 + 模型一起走。
|
|
127
|
+
*/
|
|
128
|
+
imagePlanes: ImagePlane[];
|
|
129
|
+
/** 模型槽层(同一棵子树,口径同上) */
|
|
130
|
+
models: ModelSlot[];
|
|
131
|
+
/**
|
|
132
|
+
* 那 4 张瓦片的下载/解码缓存。⭐ 与全景 `_texCache` 同一条旨(10-02「纹理都缓存在对象里面,执行 dispose 时才销毁」)
|
|
133
|
+
* ⇒ 切工程**不**清它,回来那一圈直接命中缓存、不闪缺图灰;只随本对象 `dispose()` 释放。
|
|
134
|
+
*/
|
|
135
|
+
private _imgTileLoader;
|
|
122
136
|
constructor(opts?: {
|
|
123
137
|
wallHeight?: number;
|
|
124
138
|
wallClosed?: boolean;
|
|
@@ -295,12 +309,39 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
295
309
|
projectName: string;
|
|
296
310
|
/** 注入项目名(导出 json 前调一次即可;导入时无须调——还原靠落盘地址自身的首段) */
|
|
297
311
|
setProjectName(name: string): void;
|
|
312
|
+
/** 单颗图片平面入层(编辑态双击落点用):进数组 + 挂进本对象子树 */
|
|
313
|
+
addImagePlane(ip: ImagePlane): ImagePlane;
|
|
314
|
+
/** 摘掉一颗并释放它自己的几何/材质;那 4 张瓦片纹理归 `_imgTileLoader` 管 ⇒ ⛔ 不在这里 dispose */
|
|
315
|
+
removeImagePlane(ip: ImagePlane): void;
|
|
316
|
+
/** 单颗模型槽入层(编辑态双击落点、以及「复制模型」用) */
|
|
317
|
+
addModel(ms: ModelSlot): ModelSlot;
|
|
318
|
+
/** 摘掉一槽并释放(子树里的几何/材质/贴图由 `ModelSlot.dispose` 自己收尾) */
|
|
319
|
+
removeModel(ms: ModelSlot): void;
|
|
320
|
+
/**
|
|
321
|
+
* 整层重建图片平面(`importData` 与预览那一路)。
|
|
322
|
+
* ⚠️ 进来的地址必须是**已补回域名**的绝对形态:补域名只有 `importData` 那一处(与 `textures` 同一把 `assetUrl` 尺),
|
|
323
|
+
* ⛔ 本方法里不许再补一遍,也⛔ 不许在调用方各自补。
|
|
324
|
+
*/
|
|
325
|
+
setImagePlanes(datas: ImagePlaneData[]): void;
|
|
326
|
+
/**
|
|
327
|
+
* 整层重建模型槽(`importData` 与预览那一路),地址口径的要求同 `setImagePlanes`。
|
|
328
|
+
* ⚠️ GLB 逐只**异步取、不 await**(十几只串一条队会把载入卡死),每只落地那一刻各回调一次 `onEachLoad`:
|
|
329
|
+
* 预览每帧真画 ⇒ 不传;编辑器是按需渲染 ⇒ 传一个「标脏」的钩子,否则模型挂上来屏幕不动。
|
|
330
|
+
*/
|
|
331
|
+
setModels(datas: ModelSlotData[], onEachLoad?: () => void): void;
|
|
332
|
+
/**
|
|
333
|
+
* 每帧把各颗平面那 4 张瓦片的纹理直采绑到材质(⭐ 10-22 晚旨:不走拼合器 RT)。
|
|
334
|
+
* 库里的**唯一驱动点**:持有渲染循环的那一方(编辑态 / 预览 / 下游)每帧调一次,⛔ 不许在调用方再抄一份循环。
|
|
335
|
+
* 还没下载完/缺格的那一格绑 null ⇒ 片元画缺图灰(皇上 10-26 收回默认图那条旨:「不要默认图, 没有加到位的时候 就显示深灰色」)。
|
|
336
|
+
*/
|
|
337
|
+
feedImagePlaneTiles(): void;
|
|
298
338
|
/** 导出数据:墙点位 + 墙高 + 是否闭合 + 纹理数组(url + 矩阵)
|
|
299
339
|
* @param projName 项目名(可选,优先于 `setProjectName` 注入的那个)——图片地址落成 `{项目名}/xxx.jpg` */
|
|
300
340
|
exportData(projName?: string): MktMeshData;
|
|
301
341
|
/** 导入数据:重建墙体几何与纹理列表,并激活第一个纹理
|
|
302
|
-
* @param projName 项目名(可选)——用于把落盘的 `{项目名}/x_0.jpg` 还原回真身OSS 地址
|
|
303
|
-
|
|
304
|
-
|
|
342
|
+
* @param projName 项目名(可选)——用于把落盘的 `{项目名}/x_0.jpg` 还原回真身OSS 地址
|
|
343
|
+
* @param onModelLoad 每只 GLB 落地时回调一次(可选)——按需渲染的宿主(编辑器)拿它标脏;每帧真画的预览不传 */
|
|
344
|
+
importData(data: MktMeshData, projName?: string, onModelLoad?: () => void): void;
|
|
345
|
+
/** 释放 GPU 资源:瓦片缓存(**只有这里**清,皇上旨 2026-10-02)、拼合器、平面图/模型两层、几何、材质 */
|
|
305
346
|
dispose(): this;
|
|
306
347
|
}
|
package/MktMesh/MktMesh.js
CHANGED
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
* `panoSlotRoster.ts`;皇上旨 2026-10-03 起预览/发布与编辑器共用同一份算法 ⇒ 两边装同一批全景)。
|
|
17
17
|
* ⭐ 皇上旨 2026-10-07 第二十一道旨:锚点 = 外部控制器的中心点(`setRosterCenter` 注入),没注入才回落相机位置;
|
|
18
18
|
* 中心变化或名册里有空格被补上人时加载新瓦片 → 设置 shader 的 8 个全景槽 panorama + textureMatrix;
|
|
19
|
-
* 4. exportData / importData 支持导入导出(墙点位 +
|
|
19
|
+
* 4. exportData / importData 支持导入导出(墙点位 + 纹理数组 + ⭐ 10-26 旨起的平面图 / 模型两层)。
|
|
20
20
|
* 5. ⚠️ 铁律:激活纹理(墙面上正在绘制的全景)的旋转/位置变化,必须立即同步到
|
|
21
21
|
* shader 的 textureMatrix uniform(见 setTexture),否则平面纹理不跟着全景球转。
|
|
22
22
|
*
|
|
23
23
|
* 说明:所有实例共享同一份 material(单一 panorama uniform),
|
|
24
24
|
* 同一时刻只激活名册 0 号槽(中心)那一个纹理(全局共享单激活方案)。
|
|
25
25
|
*/
|
|
26
|
-
import { BufferGeometry, BackSide, Float32BufferAttribute, Matrix4, Mesh, Shape, ShapeGeometry, SRGBColorSpace, Vector3, } from "three";
|
|
26
|
+
import { BufferGeometry, BackSide, Float32BufferAttribute, Matrix4, Mesh, Shape, ShapeGeometry, SRGBColorSpace, Vector3, Vector4, } from "three";
|
|
27
27
|
import { createPlaceholderTexture, isPanoTexMode, mktPanoTiledFlag, mktPanoTexUrls, isRtStitchKey, rtStitchKeyParts, RT_STITCH_KEY_PREFIX, RT_STITCH_SLOT_COUNT } from "./mktShader";
|
|
28
28
|
import { MKT_PANO_MAX_SLOTS } from "./mktMappingShader";
|
|
29
29
|
import { createMktFloorMappingShaderMaterial } from "./mktMappingShader";
|
|
@@ -45,6 +45,12 @@ import { subdivideCapTriangles, WALL_CAP_MAX_EDGE_M } from "./wallCapTessellate"
|
|
|
45
45
|
// ⭐ 皇上旨 2026-10-08「json 里面的图片的地址,把域名去掉,只保留相对的根路径」:
|
|
46
46
|
// 导出时剥域名(`exportData`)、导入时补回来(`importData`)——**各只有这一处**,⛔ 不许在别处另剥/另补。
|
|
47
47
|
import { stripAssetHost, absAssetUrl } from "./assetUrl";
|
|
48
|
+
// ⭐ 皇上旨 2026-10-26「按这个方案,把图片平面和模型一起搬进库里」:这两层(含每帧喂瓦片那条编排)
|
|
49
|
+
// 原先各住在本站两个渲染器里一份 ⇒ 下游直接用包里的 `MktMesh` 时,存档里的 `images`/`models` 两键没人读。
|
|
50
|
+
// 入库之后它们挂在 `MktMesh` **自己的子树**下,与墙同一棵变换 ⇒ 预览那三根 transform 滑杆搬得动整份展品。
|
|
51
|
+
import { ImagePlane } from "./imagePlane";
|
|
52
|
+
import { ModelSlot } from "./modelSlot";
|
|
53
|
+
import { ImagePlaneTileLoader } from "./imageTileLoader";
|
|
48
54
|
export default class MktMesh extends Mesh {
|
|
49
55
|
/** 纹理列表(每个纹理的 url + 世界矩阵) */
|
|
50
56
|
textures = [];
|
|
@@ -172,6 +178,18 @@ export default class MktMesh extends Mesh {
|
|
|
172
178
|
}
|
|
173
179
|
// 复用临时对象(避免每帧 new,降低 GC 压力)
|
|
174
180
|
_tmpV3 = new Vector3();
|
|
181
|
+
/**
|
|
182
|
+
* 图片平面层(⭐ 10-26 旨入库):对象挂在**本 MktMesh 的子树**里,⛔ 不是场景根
|
|
183
|
+
* ⇒ 移动/旋转/缩放这个展品时,墙 + 全景 + 平面图 + 模型一起走。
|
|
184
|
+
*/
|
|
185
|
+
imagePlanes = [];
|
|
186
|
+
/** 模型槽层(同一棵子树,口径同上) */
|
|
187
|
+
models = [];
|
|
188
|
+
/**
|
|
189
|
+
* 那 4 张瓦片的下载/解码缓存。⭐ 与全景 `_texCache` 同一条旨(10-02「纹理都缓存在对象里面,执行 dispose 时才销毁」)
|
|
190
|
+
* ⇒ 切工程**不**清它,回来那一圈直接命中缓存、不闪缺图灰;只随本对象 `dispose()` 释放。
|
|
191
|
+
*/
|
|
192
|
+
_imgTileLoader = new ImagePlaneTileLoader();
|
|
175
193
|
constructor(opts = {}) {
|
|
176
194
|
// 发布/预览态墙:**固定**用「全景序号直取」着色器(皇上旨 2026-09-29:mktmesh 就只有按照 attribute
|
|
177
195
|
// 配置来显示全景这一种固定的 shader——每帧由 feedFaceMapping 按 panoFaceMapping 把被引用的全景
|
|
@@ -1008,6 +1026,105 @@ export default class MktMesh extends Mesh {
|
|
|
1008
1026
|
setProjectName(name) {
|
|
1009
1027
|
this.projectName = typeof name === "string" ? name : "";
|
|
1010
1028
|
}
|
|
1029
|
+
// ───────────── 平面图 / 模型两层(⭐ 皇上旨 2026-10-26「把图片平面和模型一起搬进库里」) ─────────────
|
|
1030
|
+
/** 单颗图片平面入层(编辑态双击落点用):进数组 + 挂进本对象子树 */
|
|
1031
|
+
addImagePlane(ip) {
|
|
1032
|
+
this.imagePlanes.push(ip);
|
|
1033
|
+
this.add(ip);
|
|
1034
|
+
return ip;
|
|
1035
|
+
}
|
|
1036
|
+
/** 摘掉一颗并释放它自己的几何/材质;那 4 张瓦片纹理归 `_imgTileLoader` 管 ⇒ ⛔ 不在这里 dispose */
|
|
1037
|
+
removeImagePlane(ip) {
|
|
1038
|
+
const i = this.imagePlanes.indexOf(ip);
|
|
1039
|
+
if (i >= 0)
|
|
1040
|
+
this.imagePlanes.splice(i, 1);
|
|
1041
|
+
this.remove(ip);
|
|
1042
|
+
ip.dispose();
|
|
1043
|
+
}
|
|
1044
|
+
/** 单颗模型槽入层(编辑态双击落点、以及「复制模型」用) */
|
|
1045
|
+
addModel(ms) {
|
|
1046
|
+
this.models.push(ms);
|
|
1047
|
+
this.add(ms);
|
|
1048
|
+
return ms;
|
|
1049
|
+
}
|
|
1050
|
+
/** 摘掉一槽并释放(子树里的几何/材质/贴图由 `ModelSlot.dispose` 自己收尾) */
|
|
1051
|
+
removeModel(ms) {
|
|
1052
|
+
const i = this.models.indexOf(ms);
|
|
1053
|
+
if (i >= 0)
|
|
1054
|
+
this.models.splice(i, 1);
|
|
1055
|
+
this.remove(ms);
|
|
1056
|
+
ms.dispose();
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* 整层重建图片平面(`importData` 与预览那一路)。
|
|
1060
|
+
* ⚠️ 进来的地址必须是**已补回域名**的绝对形态:补域名只有 `importData` 那一处(与 `textures` 同一把 `assetUrl` 尺),
|
|
1061
|
+
* ⛔ 本方法里不许再补一遍,也⛔ 不许在调用方各自补。
|
|
1062
|
+
*/
|
|
1063
|
+
setImagePlanes(datas) {
|
|
1064
|
+
for (const ip of this.imagePlanes) {
|
|
1065
|
+
this.remove(ip);
|
|
1066
|
+
ip.dispose();
|
|
1067
|
+
}
|
|
1068
|
+
this.imagePlanes = [];
|
|
1069
|
+
for (const d of datas) {
|
|
1070
|
+
const ip = new ImagePlane(d.name);
|
|
1071
|
+
ip.applyData(d);
|
|
1072
|
+
this.imagePlanes.push(ip);
|
|
1073
|
+
this.add(ip);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* 整层重建模型槽(`importData` 与预览那一路),地址口径的要求同 `setImagePlanes`。
|
|
1078
|
+
* ⚠️ GLB 逐只**异步取、不 await**(十几只串一条队会把载入卡死),每只落地那一刻各回调一次 `onEachLoad`:
|
|
1079
|
+
* 预览每帧真画 ⇒ 不传;编辑器是按需渲染 ⇒ 传一个「标脏」的钩子,否则模型挂上来屏幕不动。
|
|
1080
|
+
*/
|
|
1081
|
+
setModels(datas, onEachLoad) {
|
|
1082
|
+
for (const ms of this.models) {
|
|
1083
|
+
this.remove(ms);
|
|
1084
|
+
ms.dispose();
|
|
1085
|
+
}
|
|
1086
|
+
this.models = [];
|
|
1087
|
+
for (const d of datas) {
|
|
1088
|
+
const ms = new ModelSlot(d.name);
|
|
1089
|
+
ms.applyData(d);
|
|
1090
|
+
this.models.push(ms);
|
|
1091
|
+
this.add(ms);
|
|
1092
|
+
if (d.url)
|
|
1093
|
+
void ms.setModelUrl(d.url).then(() => onEachLoad && onEachLoad());
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* 每帧把各颗平面那 4 张瓦片的纹理直采绑到材质(⭐ 10-22 晚旨:不走拼合器 RT)。
|
|
1098
|
+
* 库里的**唯一驱动点**:持有渲染循环的那一方(编辑态 / 预览 / 下游)每帧调一次,⛔ 不许在调用方再抄一份循环。
|
|
1099
|
+
* 还没下载完/缺格的那一格绑 null ⇒ 片元画缺图灰(皇上 10-26 收回默认图那条旨:「不要默认图, 没有加到位的时候 就显示深灰色」)。
|
|
1100
|
+
*/
|
|
1101
|
+
feedImagePlaneTiles() {
|
|
1102
|
+
if (!this.imagePlanes.length)
|
|
1103
|
+
return;
|
|
1104
|
+
const zero = new Vector4(0, 0, 1, 1);
|
|
1105
|
+
for (const ip of this.imagePlanes) {
|
|
1106
|
+
const tiles = ip.tiles;
|
|
1107
|
+
// ⛔ 旧存档 16 条地址(> 满批 4)直接不收 ⇒ 整张缺图灰,按 10-20 口径重传即可;空 tiles 同样
|
|
1108
|
+
if (!tiles || tiles.length !== 4) {
|
|
1109
|
+
ip.setTileTextures([null, null, null, null], [zero.clone(), zero.clone(), zero.clone(), zero.clone()]);
|
|
1110
|
+
continue;
|
|
1111
|
+
}
|
|
1112
|
+
const texs = [null, null, null, null];
|
|
1113
|
+
const insets = [zero.clone(), zero.clone(), zero.clone(), zero.clone()];
|
|
1114
|
+
for (let i = 0; i < 4; i++) {
|
|
1115
|
+
const url = tiles[i];
|
|
1116
|
+
if (!url)
|
|
1117
|
+
continue;
|
|
1118
|
+
this._imgTileLoader.preload(url);
|
|
1119
|
+
const e = this._imgTileLoader.get(url);
|
|
1120
|
+
if (!e || !e.tex)
|
|
1121
|
+
continue;
|
|
1122
|
+
texs[i] = e.tex;
|
|
1123
|
+
insets[i] = this._imgTileLoader.inset(e, i);
|
|
1124
|
+
}
|
|
1125
|
+
ip.setTileTextures(texs, insets);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1011
1128
|
/** 导出数据:墙点位 + 墙高 + 是否闭合 + 纹理数组(url + 矩阵)
|
|
1012
1129
|
* @param projName 项目名(可选,优先于 `setProjectName` 注入的那个)——图片地址落成 `{项目名}/xxx.jpg` */
|
|
1013
1130
|
exportData(projName) {
|
|
@@ -1030,11 +1147,29 @@ export default class MktMesh extends Mesh {
|
|
|
1030
1147
|
tiles: (t.tiles && t.tiles.length ? t.tiles.map((u) => stripAssetHost(u, pn)) : []),
|
|
1031
1148
|
matrix: t.matrix.toArray(),
|
|
1032
1149
|
})),
|
|
1150
|
+
// ⭐ 10-26 旨入库:这两层的地址与 `textures` 共用上面那一条剥域名口径(⛔ 不是另起一把尺),
|
|
1151
|
+
// 其余字段(位置/旋转/宽高/瓦片数/落点面/原始包围盒)由各自的 `toData()` 逐字存。
|
|
1152
|
+
images: this.imagePlanes.map((ip) => {
|
|
1153
|
+
const d = ip.toData();
|
|
1154
|
+
return {
|
|
1155
|
+
...d,
|
|
1156
|
+
url: d.url ? stripAssetHost(d.url, pn) : "",
|
|
1157
|
+
tiles: d.tiles.length ? d.tiles.map((u) => stripAssetHost(u, pn)) : [],
|
|
1158
|
+
};
|
|
1159
|
+
}),
|
|
1160
|
+
models: this.models.map((ms) => {
|
|
1161
|
+
const d = ms.toData();
|
|
1162
|
+
return { ...d, url: d.url ? stripAssetHost(d.url, pn) : "" };
|
|
1163
|
+
}),
|
|
1033
1164
|
};
|
|
1034
1165
|
}
|
|
1035
1166
|
/** 导入数据:重建墙体几何与纹理列表,并激活第一个纹理
|
|
1036
|
-
* @param projName 项目名(可选)——用于把落盘的 `{项目名}/x_0.jpg` 还原回真身OSS 地址
|
|
1037
|
-
|
|
1167
|
+
* @param projName 项目名(可选)——用于把落盘的 `{项目名}/x_0.jpg` 还原回真身OSS 地址
|
|
1168
|
+
* @param onModelLoad 每只 GLB 落地时回调一次(可选)——按需渲染的宿主(编辑器)拿它标脏;每帧真画的预览不传 */
|
|
1169
|
+
importData(data, projName, onModelLoad) {
|
|
1170
|
+
// ⭐ 10-08 旨的「补回域名」那颗项目名,10-26 旨之后全景/平面图/模型**三层共用同一个**(原来在 textures 的
|
|
1171
|
+
// map 里就地取,下面那两层也要用 ⇒ 提到方法开头,⛔ 不是第二处口径)。
|
|
1172
|
+
const pn = typeof projName === "string" && projName ? projName : this.projectName;
|
|
1038
1173
|
this.setWallPoints(data.wallPoints ?? [], {
|
|
1039
1174
|
closed: data.wallClosed,
|
|
1040
1175
|
height: data.wallHeight,
|
|
@@ -1049,7 +1184,6 @@ export default class MktMesh extends Mesh {
|
|
|
1049
1184
|
// (`/three-base_upload/…`)不必重存也能正常加载,不会被拼成 `https://host/https://host/…`
|
|
1050
1185
|
// · 19:53 旨后还要把 `{项目名}/x_0.jpg` **还原**成真身 OSS 地址(顶掉的上传目录要补回来),
|
|
1051
1186
|
// 否则 json 里的地址指不回原图(图片裂)。`pn` 取入参、回落 `setProjectName` 注入的那个。
|
|
1052
|
-
const pn = typeof projName === "string" && projName ? projName : this.projectName;
|
|
1053
1187
|
const urlAbs = absAssetUrl(t.url, pn);
|
|
1054
1188
|
return {
|
|
1055
1189
|
url: urlAbs,
|
|
@@ -1073,9 +1207,18 @@ export default class MktMesh extends Mesh {
|
|
|
1073
1207
|
this.panoFaceMapping[f] = imported[f];
|
|
1074
1208
|
this.rebuildPanoIndexAttribute();
|
|
1075
1209
|
}
|
|
1210
|
+
// ⭐ 10-26 旨「把图片平面和模型一起搬进库里」的另一半:这两层也从**同一份 JSON** 里读,
|
|
1211
|
+
// 地址在这一处补回域名(与上面 textures 同一条尺)⇒ 下游只调 `importData(整串)` 就全画出来。
|
|
1212
|
+
// 旧存档没有这两个键 ⇒ 空数组 = 整层清空,与「墙 + 全景」那套逐字同口径。
|
|
1213
|
+
this.setImagePlanes((data.images ?? []).map((d) => ({
|
|
1214
|
+
...d,
|
|
1215
|
+
url: d.url ? absAssetUrl(d.url, pn) : "",
|
|
1216
|
+
tiles: (d.tiles ?? []).map((u) => absAssetUrl(u, pn)),
|
|
1217
|
+
})));
|
|
1218
|
+
this.setModels((data.models ?? []).map((d) => ({ ...d, url: d.url ? absAssetUrl(d.url, pn) : "" })), onModelLoad);
|
|
1076
1219
|
}
|
|
1077
1220
|
// ───────────────────────── 释放 ─────────────────────────
|
|
1078
|
-
/** 释放 GPU 资源:瓦片缓存(**只有这里**清,皇上旨 2026-10-02
|
|
1221
|
+
/** 释放 GPU 资源:瓦片缓存(**只有这里**清,皇上旨 2026-10-02)、拼合器、平面图/模型两层、几何、材质 */
|
|
1079
1222
|
dispose() {
|
|
1080
1223
|
// ⚠️ rt 虚拟键从不进 `_texCache`(拼合槽纹理由 `_stitcher` 自己持有并释放),这里清的都是本类下载的 Texture。
|
|
1081
1224
|
// ⭐ 甲(2026-10-05):`releasePanoTexture` 除 `dispose()` 外还要 `ImageBitmap.close()` —— 位图的原生内存
|
|
@@ -1086,6 +1229,19 @@ export default class MktMesh extends Mesh {
|
|
|
1086
1229
|
this._texUploaded = new WeakSet(); // WeakSet 无 clear ⇒ 整只换掉
|
|
1087
1230
|
this._uploadQueued.clear(); // 排队项即便回调仍触发,也会因 `!this._uploadQueued.delete(tex)` 早退
|
|
1088
1231
|
this._ossSizeDepKeys.clear();
|
|
1232
|
+
// ⭐ 10-26 旨入库的两层:子对象逐个 dispose,平面那 4 张瓦片的缓存**只在这里**整批清
|
|
1233
|
+
// (与上面 `_texCache` 同一条旨 ⇒ 切工程不重建这一份、也就不会闪缺图灰)。
|
|
1234
|
+
for (const ip of this.imagePlanes) {
|
|
1235
|
+
this.remove(ip);
|
|
1236
|
+
ip.dispose();
|
|
1237
|
+
}
|
|
1238
|
+
this.imagePlanes = [];
|
|
1239
|
+
for (const ms of this.models) {
|
|
1240
|
+
this.remove(ms);
|
|
1241
|
+
ms.dispose();
|
|
1242
|
+
}
|
|
1243
|
+
this.models = [];
|
|
1244
|
+
this._imgTileLoader.clear();
|
|
1089
1245
|
this._stitcher.dispose();
|
|
1090
1246
|
this._glRenderer = null;
|
|
1091
1247
|
if (this._placeholder)
|
package/MktMesh/MktMesh.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* `panoSlotRoster.ts`;皇上旨 2026-10-03 起预览/发布与编辑器共用同一份算法 ⇒ 两边装同一批全景)。
|
|
17
17
|
* ⭐ 皇上旨 2026-10-07 第二十一道旨:锚点 = 外部控制器的中心点(`setRosterCenter` 注入),没注入才回落相机位置;
|
|
18
18
|
* 中心变化或名册里有空格被补上人时加载新瓦片 → 设置 shader 的 8 个全景槽 panorama + textureMatrix;
|
|
19
|
-
* 4. exportData / importData 支持导入导出(墙点位 +
|
|
19
|
+
* 4. exportData / importData 支持导入导出(墙点位 + 纹理数组 + ⭐ 10-26 旨起的平面图 / 模型两层)。
|
|
20
20
|
* 5. ⚠️ 铁律:激活纹理(墙面上正在绘制的全景)的旋转/位置变化,必须立即同步到
|
|
21
21
|
* shader 的 textureMatrix uniform(见 setTexture),否则平面纹理不跟着全景球转。
|
|
22
22
|
*
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
SRGBColorSpace,
|
|
40
40
|
Texture,
|
|
41
41
|
Vector3,
|
|
42
|
+
Vector4,
|
|
42
43
|
} from "three";
|
|
43
44
|
import type { WebGLRenderer } from "three";
|
|
44
45
|
import { createPlaceholderTexture, isPanoTexMode, mktPanoTiledFlag, mktPanoTexUrls, isRtStitchKey, rtStitchKeyParts, RT_STITCH_KEY_PREFIX, RT_STITCH_SLOT_COUNT, type PanoTexMode } from "./mktShader";
|
|
@@ -64,6 +65,12 @@ import { subdivideCapTriangles, WALL_CAP_MAX_EDGE_M } from "./wallCapTessellate"
|
|
|
64
65
|
// ⭐ 皇上旨 2026-10-08「json 里面的图片的地址,把域名去掉,只保留相对的根路径」:
|
|
65
66
|
// 导出时剥域名(`exportData`)、导入时补回来(`importData`)——**各只有这一处**,⛔ 不许在别处另剥/另补。
|
|
66
67
|
import { stripAssetHost, absAssetUrl } from "./assetUrl";
|
|
68
|
+
// ⭐ 皇上旨 2026-10-26「按这个方案,把图片平面和模型一起搬进库里」:这两层(含每帧喂瓦片那条编排)
|
|
69
|
+
// 原先各住在本站两个渲染器里一份 ⇒ 下游直接用包里的 `MktMesh` 时,存档里的 `images`/`models` 两键没人读。
|
|
70
|
+
// 入库之后它们挂在 `MktMesh` **自己的子树**下,与墙同一棵变换 ⇒ 预览那三根 transform 滑杆搬得动整份展品。
|
|
71
|
+
import { ImagePlane, type ImagePlaneData } from "./imagePlane";
|
|
72
|
+
import { ModelSlot, type ModelSlotData } from "./modelSlot";
|
|
73
|
+
import { ImagePlaneTileLoader } from "./imageTileLoader";
|
|
67
74
|
|
|
68
75
|
export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
69
76
|
/** 纹理列表(每个纹理的 url + 世界矩阵) */
|
|
@@ -197,6 +204,19 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
197
204
|
// 复用临时对象(避免每帧 new,降低 GC 压力)
|
|
198
205
|
private _tmpV3: Vector3 = new Vector3();
|
|
199
206
|
|
|
207
|
+
/**
|
|
208
|
+
* 图片平面层(⭐ 10-26 旨入库):对象挂在**本 MktMesh 的子树**里,⛔ 不是场景根
|
|
209
|
+
* ⇒ 移动/旋转/缩放这个展品时,墙 + 全景 + 平面图 + 模型一起走。
|
|
210
|
+
*/
|
|
211
|
+
imagePlanes: ImagePlane[] = [];
|
|
212
|
+
/** 模型槽层(同一棵子树,口径同上) */
|
|
213
|
+
models: ModelSlot[] = [];
|
|
214
|
+
/**
|
|
215
|
+
* 那 4 张瓦片的下载/解码缓存。⭐ 与全景 `_texCache` 同一条旨(10-02「纹理都缓存在对象里面,执行 dispose 时才销毁」)
|
|
216
|
+
* ⇒ 切工程**不**清它,回来那一圈直接命中缓存、不闪缺图灰;只随本对象 `dispose()` 释放。
|
|
217
|
+
*/
|
|
218
|
+
private _imgTileLoader = new ImagePlaneTileLoader();
|
|
219
|
+
|
|
200
220
|
constructor(opts: { wallHeight?: number; wallClosed?: boolean } = {}) {
|
|
201
221
|
// 发布/预览态墙:**固定**用「全景序号直取」着色器(皇上旨 2026-09-29:mktmesh 就只有按照 attribute
|
|
202
222
|
// 配置来显示全景这一种固定的 shader——每帧由 feedFaceMapping 按 panoFaceMapping 把被引用的全景
|
|
@@ -1035,6 +1055,107 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
1035
1055
|
this.projectName = typeof name === "string" ? name : "";
|
|
1036
1056
|
}
|
|
1037
1057
|
|
|
1058
|
+
// ───────────── 平面图 / 模型两层(⭐ 皇上旨 2026-10-26「把图片平面和模型一起搬进库里」) ─────────────
|
|
1059
|
+
|
|
1060
|
+
/** 单颗图片平面入层(编辑态双击落点用):进数组 + 挂进本对象子树 */
|
|
1061
|
+
addImagePlane(ip: ImagePlane): ImagePlane {
|
|
1062
|
+
this.imagePlanes.push(ip);
|
|
1063
|
+
this.add(ip);
|
|
1064
|
+
return ip;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/** 摘掉一颗并释放它自己的几何/材质;那 4 张瓦片纹理归 `_imgTileLoader` 管 ⇒ ⛔ 不在这里 dispose */
|
|
1068
|
+
removeImagePlane(ip: ImagePlane): void {
|
|
1069
|
+
const i = this.imagePlanes.indexOf(ip);
|
|
1070
|
+
if (i >= 0) this.imagePlanes.splice(i, 1);
|
|
1071
|
+
this.remove(ip);
|
|
1072
|
+
ip.dispose();
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/** 单颗模型槽入层(编辑态双击落点、以及「复制模型」用) */
|
|
1076
|
+
addModel(ms: ModelSlot): ModelSlot {
|
|
1077
|
+
this.models.push(ms);
|
|
1078
|
+
this.add(ms);
|
|
1079
|
+
return ms;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
/** 摘掉一槽并释放(子树里的几何/材质/贴图由 `ModelSlot.dispose` 自己收尾) */
|
|
1083
|
+
removeModel(ms: ModelSlot): void {
|
|
1084
|
+
const i = this.models.indexOf(ms);
|
|
1085
|
+
if (i >= 0) this.models.splice(i, 1);
|
|
1086
|
+
this.remove(ms);
|
|
1087
|
+
ms.dispose();
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* 整层重建图片平面(`importData` 与预览那一路)。
|
|
1092
|
+
* ⚠️ 进来的地址必须是**已补回域名**的绝对形态:补域名只有 `importData` 那一处(与 `textures` 同一把 `assetUrl` 尺),
|
|
1093
|
+
* ⛔ 本方法里不许再补一遍,也⛔ 不许在调用方各自补。
|
|
1094
|
+
*/
|
|
1095
|
+
setImagePlanes(datas: ImagePlaneData[]): void {
|
|
1096
|
+
for (const ip of this.imagePlanes) {
|
|
1097
|
+
this.remove(ip);
|
|
1098
|
+
ip.dispose();
|
|
1099
|
+
}
|
|
1100
|
+
this.imagePlanes = [];
|
|
1101
|
+
for (const d of datas) {
|
|
1102
|
+
const ip = new ImagePlane(d.name);
|
|
1103
|
+
ip.applyData(d);
|
|
1104
|
+
this.imagePlanes.push(ip);
|
|
1105
|
+
this.add(ip);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* 整层重建模型槽(`importData` 与预览那一路),地址口径的要求同 `setImagePlanes`。
|
|
1111
|
+
* ⚠️ GLB 逐只**异步取、不 await**(十几只串一条队会把载入卡死),每只落地那一刻各回调一次 `onEachLoad`:
|
|
1112
|
+
* 预览每帧真画 ⇒ 不传;编辑器是按需渲染 ⇒ 传一个「标脏」的钩子,否则模型挂上来屏幕不动。
|
|
1113
|
+
*/
|
|
1114
|
+
setModels(datas: ModelSlotData[], onEachLoad?: () => void): void {
|
|
1115
|
+
for (const ms of this.models) {
|
|
1116
|
+
this.remove(ms);
|
|
1117
|
+
ms.dispose();
|
|
1118
|
+
}
|
|
1119
|
+
this.models = [];
|
|
1120
|
+
for (const d of datas) {
|
|
1121
|
+
const ms = new ModelSlot(d.name);
|
|
1122
|
+
ms.applyData(d);
|
|
1123
|
+
this.models.push(ms);
|
|
1124
|
+
this.add(ms);
|
|
1125
|
+
if (d.url) void ms.setModelUrl(d.url).then(() => onEachLoad && onEachLoad());
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/**
|
|
1130
|
+
* 每帧把各颗平面那 4 张瓦片的纹理直采绑到材质(⭐ 10-22 晚旨:不走拼合器 RT)。
|
|
1131
|
+
* 库里的**唯一驱动点**:持有渲染循环的那一方(编辑态 / 预览 / 下游)每帧调一次,⛔ 不许在调用方再抄一份循环。
|
|
1132
|
+
* 还没下载完/缺格的那一格绑 null ⇒ 片元画缺图灰(皇上 10-26 收回默认图那条旨:「不要默认图, 没有加到位的时候 就显示深灰色」)。
|
|
1133
|
+
*/
|
|
1134
|
+
feedImagePlaneTiles(): void {
|
|
1135
|
+
if (!this.imagePlanes.length) return;
|
|
1136
|
+
const zero = new Vector4(0, 0, 1, 1);
|
|
1137
|
+
for (const ip of this.imagePlanes) {
|
|
1138
|
+
const tiles = ip.tiles;
|
|
1139
|
+
// ⛔ 旧存档 16 条地址(> 满批 4)直接不收 ⇒ 整张缺图灰,按 10-20 口径重传即可;空 tiles 同样
|
|
1140
|
+
if (!tiles || tiles.length !== 4) {
|
|
1141
|
+
ip.setTileTextures([null, null, null, null], [zero.clone(), zero.clone(), zero.clone(), zero.clone()]);
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
const texs: (Texture | null)[] = [null, null, null, null];
|
|
1145
|
+
const insets: Vector4[] = [zero.clone(), zero.clone(), zero.clone(), zero.clone()];
|
|
1146
|
+
for (let i = 0; i < 4; i++) {
|
|
1147
|
+
const url = tiles[i];
|
|
1148
|
+
if (!url) continue;
|
|
1149
|
+
this._imgTileLoader.preload(url);
|
|
1150
|
+
const e = this._imgTileLoader.get(url);
|
|
1151
|
+
if (!e || !e.tex) continue;
|
|
1152
|
+
texs[i] = e.tex;
|
|
1153
|
+
insets[i] = this._imgTileLoader.inset(e, i);
|
|
1154
|
+
}
|
|
1155
|
+
ip.setTileTextures(texs, insets);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1038
1159
|
/** 导出数据:墙点位 + 墙高 + 是否闭合 + 纹理数组(url + 矩阵)
|
|
1039
1160
|
* @param projName 项目名(可选,优先于 `setProjectName` 注入的那个)——图片地址落成 `{项目名}/xxx.jpg` */
|
|
1040
1161
|
exportData(projName?: string): MktMeshData {
|
|
@@ -1057,12 +1178,30 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
1057
1178
|
tiles: (t.tiles && t.tiles.length ? t.tiles.map((u) => stripAssetHost(u, pn)) : []) as string[],
|
|
1058
1179
|
matrix: t.matrix.toArray(),
|
|
1059
1180
|
})),
|
|
1181
|
+
// ⭐ 10-26 旨入库:这两层的地址与 `textures` 共用上面那一条剥域名口径(⛔ 不是另起一把尺),
|
|
1182
|
+
// 其余字段(位置/旋转/宽高/瓦片数/落点面/原始包围盒)由各自的 `toData()` 逐字存。
|
|
1183
|
+
images: this.imagePlanes.map((ip) => {
|
|
1184
|
+
const d = ip.toData();
|
|
1185
|
+
return {
|
|
1186
|
+
...d,
|
|
1187
|
+
url: d.url ? stripAssetHost(d.url, pn) : "",
|
|
1188
|
+
tiles: d.tiles.length ? d.tiles.map((u) => stripAssetHost(u, pn)) : [],
|
|
1189
|
+
};
|
|
1190
|
+
}),
|
|
1191
|
+
models: this.models.map((ms) => {
|
|
1192
|
+
const d = ms.toData();
|
|
1193
|
+
return { ...d, url: d.url ? stripAssetHost(d.url, pn) : "" };
|
|
1194
|
+
}),
|
|
1060
1195
|
};
|
|
1061
1196
|
}
|
|
1062
1197
|
|
|
1063
1198
|
/** 导入数据:重建墙体几何与纹理列表,并激活第一个纹理
|
|
1064
|
-
* @param projName 项目名(可选)——用于把落盘的 `{项目名}/x_0.jpg` 还原回真身OSS 地址
|
|
1065
|
-
|
|
1199
|
+
* @param projName 项目名(可选)——用于把落盘的 `{项目名}/x_0.jpg` 还原回真身OSS 地址
|
|
1200
|
+
* @param onModelLoad 每只 GLB 落地时回调一次(可选)——按需渲染的宿主(编辑器)拿它标脏;每帧真画的预览不传 */
|
|
1201
|
+
importData(data: MktMeshData, projName?: string, onModelLoad?: () => void): void {
|
|
1202
|
+
// ⭐ 10-08 旨的「补回域名」那颗项目名,10-26 旨之后全景/平面图/模型**三层共用同一个**(原来在 textures 的
|
|
1203
|
+
// map 里就地取,下面那两层也要用 ⇒ 提到方法开头,⛔ 不是第二处口径)。
|
|
1204
|
+
const pn = typeof projName === "string" && projName ? projName : this.projectName;
|
|
1066
1205
|
this.setWallPoints(data.wallPoints ?? [], {
|
|
1067
1206
|
closed: data.wallClosed,
|
|
1068
1207
|
height: data.wallHeight,
|
|
@@ -1078,7 +1217,6 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
1078
1217
|
// (`/three-base_upload/…`)不必重存也能正常加载,不会被拼成 `https://host/https://host/…`
|
|
1079
1218
|
// · 19:53 旨后还要把 `{项目名}/x_0.jpg` **还原**成真身 OSS 地址(顶掉的上传目录要补回来),
|
|
1080
1219
|
// 否则 json 里的地址指不回原图(图片裂)。`pn` 取入参、回落 `setProjectName` 注入的那个。
|
|
1081
|
-
const pn = typeof projName === "string" && projName ? projName : this.projectName;
|
|
1082
1220
|
const urlAbs = absAssetUrl(t.url as string, pn);
|
|
1083
1221
|
return {
|
|
1084
1222
|
url: urlAbs,
|
|
@@ -1102,11 +1240,25 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
1102
1240
|
for (let f = 0; f < restore; f++) this.panoFaceMapping[f] = imported[f];
|
|
1103
1241
|
this.rebuildPanoIndexAttribute();
|
|
1104
1242
|
}
|
|
1243
|
+
// ⭐ 10-26 旨「把图片平面和模型一起搬进库里」的另一半:这两层也从**同一份 JSON** 里读,
|
|
1244
|
+
// 地址在这一处补回域名(与上面 textures 同一条尺)⇒ 下游只调 `importData(整串)` 就全画出来。
|
|
1245
|
+
// 旧存档没有这两个键 ⇒ 空数组 = 整层清空,与「墙 + 全景」那套逐字同口径。
|
|
1246
|
+
this.setImagePlanes(
|
|
1247
|
+
(data.images ?? []).map((d) => ({
|
|
1248
|
+
...d,
|
|
1249
|
+
url: d.url ? absAssetUrl(d.url, pn) : "",
|
|
1250
|
+
tiles: (d.tiles ?? []).map((u) => absAssetUrl(u, pn)),
|
|
1251
|
+
}))
|
|
1252
|
+
);
|
|
1253
|
+
this.setModels(
|
|
1254
|
+
(data.models ?? []).map((d) => ({ ...d, url: d.url ? absAssetUrl(d.url, pn) : "" })),
|
|
1255
|
+
onModelLoad
|
|
1256
|
+
);
|
|
1105
1257
|
}
|
|
1106
1258
|
|
|
1107
1259
|
// ───────────────────────── 释放 ─────────────────────────
|
|
1108
1260
|
|
|
1109
|
-
/** 释放 GPU 资源:瓦片缓存(**只有这里**清,皇上旨 2026-10-02
|
|
1261
|
+
/** 释放 GPU 资源:瓦片缓存(**只有这里**清,皇上旨 2026-10-02)、拼合器、平面图/模型两层、几何、材质 */
|
|
1110
1262
|
dispose(): this {
|
|
1111
1263
|
// ⚠️ rt 虚拟键从不进 `_texCache`(拼合槽纹理由 `_stitcher` 自己持有并释放),这里清的都是本类下载的 Texture。
|
|
1112
1264
|
// ⭐ 甲(2026-10-05):`releasePanoTexture` 除 `dispose()` 外还要 `ImageBitmap.close()` —— 位图的原生内存
|
|
@@ -1116,6 +1268,19 @@ export default class MktMesh extends Mesh<BufferGeometry, ShaderMaterial> {
|
|
|
1116
1268
|
this._texUploaded = new WeakSet(); // WeakSet 无 clear ⇒ 整只换掉
|
|
1117
1269
|
this._uploadQueued.clear(); // 排队项即便回调仍触发,也会因 `!this._uploadQueued.delete(tex)` 早退
|
|
1118
1270
|
this._ossSizeDepKeys.clear();
|
|
1271
|
+
// ⭐ 10-26 旨入库的两层:子对象逐个 dispose,平面那 4 张瓦片的缓存**只在这里**整批清
|
|
1272
|
+
// (与上面 `_texCache` 同一条旨 ⇒ 切工程不重建这一份、也就不会闪缺图灰)。
|
|
1273
|
+
for (const ip of this.imagePlanes) {
|
|
1274
|
+
this.remove(ip);
|
|
1275
|
+
ip.dispose();
|
|
1276
|
+
}
|
|
1277
|
+
this.imagePlanes = [];
|
|
1278
|
+
for (const ms of this.models) {
|
|
1279
|
+
this.remove(ms);
|
|
1280
|
+
ms.dispose();
|
|
1281
|
+
}
|
|
1282
|
+
this.models = [];
|
|
1283
|
+
this._imgTileLoader.clear();
|
|
1119
1284
|
this._stitcher.dispose();
|
|
1120
1285
|
this._glRenderer = null;
|
|
1121
1286
|
if (this._placeholder) this._placeholder.dispose();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { BoxGeometry, BufferGeometry, Camera, Group, Material, Mesh, MeshBasicMaterial, NormalBufferAttributes, Raycaster, Scene, Vector3, WebGLRenderer } from "three";
|
|
2
|
+
import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
|
|
3
|
+
import { LineSegments2 } from "three/examples/jsm/lines/LineSegments2.js";
|
|
4
|
+
export default class BoxLine2 extends Mesh {
|
|
5
|
+
constructor();
|
|
6
|
+
/** 控制台识别用(本仓约定:对象要能被认出来是谁的哪一份) */
|
|
7
|
+
type: string;
|
|
8
|
+
frustumCulled: boolean;
|
|
9
|
+
size: Vector3;
|
|
10
|
+
T1: Vector3;
|
|
11
|
+
T2: Vector3;
|
|
12
|
+
T3: Vector3;
|
|
13
|
+
T4: Vector3;
|
|
14
|
+
B1: Vector3;
|
|
15
|
+
B2: Vector3;
|
|
16
|
+
B3: Vector3;
|
|
17
|
+
B4: Vector3;
|
|
18
|
+
frontLineMaterial: LineMaterial;
|
|
19
|
+
backLineMaterial: LineMaterial;
|
|
20
|
+
createLine(name: string): LineSegments2;
|
|
21
|
+
T1_line: LineSegments2;
|
|
22
|
+
T2_line: LineSegments2;
|
|
23
|
+
T3_line: LineSegments2;
|
|
24
|
+
T4_line: LineSegments2;
|
|
25
|
+
M1_line: LineSegments2;
|
|
26
|
+
M2_line: LineSegments2;
|
|
27
|
+
M3_line: LineSegments2;
|
|
28
|
+
M4_line: LineSegments2;
|
|
29
|
+
B1_line: LineSegments2;
|
|
30
|
+
B2_line: LineSegments2;
|
|
31
|
+
B3_line: LineSegments2;
|
|
32
|
+
B4_line: LineSegments2;
|
|
33
|
+
/** 射线靶子(比框小一圈):`alphaTest: 1.1` ⇒ 一个像素都不画,只给下面的遮挡判据打 */
|
|
34
|
+
boxMesh: Mesh<BoxGeometry, MeshBasicMaterial, import("three").Object3DEventMap>;
|
|
35
|
+
/** 代理盒单边内缩量:米级盒子照参考实现减 0.1;薄一片/占位方块那种小尺寸钳到自身的一半,⛔ 不出负数 */
|
|
36
|
+
private _insetSize;
|
|
37
|
+
setSize(v: Vector3): void;
|
|
38
|
+
raycaster: Raycaster;
|
|
39
|
+
onBeforeRender: (renderer: WebGLRenderer, _scene: Scene, camera: Camera, _geometry: BufferGeometry<NormalBufferAttributes>, _material: Material, _group: Group) => void;
|
|
40
|
+
/** 释放:12 份线段几何 + 代理盒几何 + 两份 LineMaterial + 代理盒材质(模型槽删除/换框时调用) */
|
|
41
|
+
dispose(): void;
|
|
42
|
+
}
|