three-base 2.0.142 → 2.0.145
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/DirectionalLight.d.ts +6 -6
- package/DirectionalLight.js +68 -68
- package/EventMap.d.ts +103 -103
- package/EventMap.js +17 -17
- package/EventMesh.d.ts +18 -18
- package/EventMesh.js +59 -59
- package/ExtrudeMesh.d.ts +112 -112
- package/ExtrudeMesh.js +342 -342
- package/FPScontrol.d.ts +511 -511
- package/FPScontrol.js +1799 -1799
- package/FPScontrol.ts +1855 -1855
- package/Fire/Fire.d.ts +28 -28
- package/Fire/Fire.js +80 -80
- package/Fire/FireGeometry.d.ts +9 -9
- package/Fire/FireGeometry.js +40 -40
- package/Fire/FireMaterial.d.ts +28 -28
- package/Fire/FireMaterial.js +32 -32
- package/Fire/index.d.ts +2 -2
- package/Fire/index.js +2 -2
- package/GLTFDracoLoader.d.ts +71 -71
- package/GLTFDracoLoader.js +266 -266
- package/GLTFDracoLoader.ts +1 -1
- package/Grass/Grass.d.ts +8 -8
- package/Grass/Grass.js +38 -38
- package/Grass/index.d.ts +2 -2
- package/Grass/index.js +2 -2
- package/Ground1/Ground1.d.ts +10 -10
- package/Ground1/Ground1.js +71 -71
- package/Ground1/index.d.ts +1 -1
- package/Ground1/index.js +1 -1
- package/MeshBase.d.ts +36 -36
- package/MeshBase.js +247 -247
- package/Mirror.d.ts +25 -25
- package/Mirror.js +143 -143
- package/MktMesh/MktMesh.d.ts +301 -291
- package/MktMesh/MktMesh.js +1064 -1045
- package/MktMesh/MktMesh.ts +32 -11
- package/MktMesh/assetUrl.d.ts +59 -35
- package/MktMesh/assetUrl.js +154 -69
- package/MktMesh/assetUrl.ts +155 -69
- package/MktMesh/mktMappingShader.d.ts +12 -12
- package/MktMesh/mktMappingShader.js +138 -138
- package/MktMesh/mktMappingShader.ts +139 -139
- package/MktMesh/mktShader.d.ts +263 -263
- package/MktMesh/mktShader.js +1236 -1236
- package/MktMesh/mktShader.ts +1344 -1344
- package/MktMesh/panoBitmapTexture.d.ts +25 -25
- package/MktMesh/panoBitmapTexture.js +52 -52
- package/MktMesh/panoBitmapTexture.ts +54 -54
- package/MktMesh/panoSlotBind.d.ts +29 -29
- package/MktMesh/panoSlotBind.js +106 -106
- package/MktMesh/panoSlotBind.ts +153 -153
- package/MktMesh/panoSlotRoster.d.ts +22 -22
- package/MktMesh/panoSlotRoster.js +169 -169
- package/MktMesh/panoSlotRoster.ts +168 -168
- package/MktMesh/panoTileStitcher.d.ts +119 -119
- package/MktMesh/panoTileStitcher.js +529 -529
- package/MktMesh/panoTileStitcher.ts +616 -616
- package/MktMesh/types.d.ts +75 -75
- package/MktMesh/types.js +1 -1
- package/MktMesh/wallCapTessellate.d.ts +33 -33
- package/MktMesh/wallCapTessellate.js +97 -97
- package/MktMesh/wallCapTessellate.ts +68 -68
- package/PipeMesh/PathGeometry.d.ts +44 -44
- package/PipeMesh/PathGeometry.js +307 -307
- package/PipeMesh/PathPoint.d.ts +17 -17
- package/PipeMesh/PathPoint.js +31 -31
- package/PipeMesh/PathPointList.d.ts +31 -31
- package/PipeMesh/PathPointList.js +209 -209
- package/PipeMesh/PathTubeGeometry.d.ts +25 -25
- package/PipeMesh/PathTubeGeometry.js +130 -130
- package/PipeMesh/PipeMesh.d.ts +25 -25
- package/PipeMesh/PipeMesh.js +63 -63
- package/PipeMesh/index.d.ts +1 -1
- package/PipeMesh/index.js +1 -1
- package/PlaneModal1/PlaneModal1.d.ts +34 -34
- package/PlaneModal1/PlaneModal1.js +109 -109
- package/PlaneModal1/index.d.ts +1 -1
- package/PlaneModal1/index.js +1 -1
- package/PlaneText.d.ts +27 -27
- package/PlaneText.js +35 -35
- package/PlaneWithHtml.d.ts +13 -13
- package/PlaneWithHtml.js +64 -64
- package/PointLight/PointLight.d.ts +13 -13
- package/PointLight/PointLight.js +64 -64
- package/PointLight/index.d.ts +1 -1
- package/PointLight/index.js +1 -1
- package/Sky/Sky.d.ts +9 -9
- package/Sky/Sky.js +22 -22
- package/Sky/index.d.ts +1 -1
- package/Sky/index.js +1 -1
- package/SpotLight.d.ts +6 -6
- package/SpotLight.js +72 -72
- package/SpriteModal1/SpriteModal1.d.ts +33 -33
- package/SpriteModal1/SpriteModal1.js +116 -116
- package/SpriteModal1/index.d.ts +1 -1
- package/SpriteModal1/index.js +1 -1
- package/SpriteText.d.ts +46 -46
- package/SpriteText.js +176 -176
- package/SpriteText2.d.ts +48 -48
- package/SpriteText2.js +223 -223
- package/SpriteText3.d.ts +86 -86
- package/SpriteText3.js +517 -517
- package/SpriteText3.ts +599 -599
- package/SpriteWithHtml.d.ts +9 -9
- package/SpriteWithHtml.js +44 -44
- package/Text3D/Text3D.d.ts +20 -20
- package/Text3D/Text3D.js +58 -58
- package/Text3D/fontController.d.ts +60 -60
- package/Text3D/fontController.js +166 -166
- package/Text3D/index.d.ts +1 -1
- package/Text3D/index.js +1 -1
- package/ThreeBase.d.ts +248 -248
- package/ThreeBase.js +1202 -1202
- package/ThreeBase.ts +1314 -1314
- package/ThreeMouse.d.ts +53 -54
- package/ThreeMouse.js +453 -453
- package/Transition.d.ts +45 -45
- package/Transition.js +209 -209
- package/Water/Water.d.ts +5 -5
- package/Water/Water.js +44 -44
- package/Water/index.d.ts +2 -2
- package/Water/index.js +2 -2
- package/WaterFlow/FloatingDuck.d.ts +88 -88
- package/WaterFlow/FloatingDuck.js +307 -307
- package/WaterFlow/FloatingDuck.ts +445 -445
- package/WaterFlow/GPUFluidSimulation.d.ts +56 -56
- package/WaterFlow/GPUFluidSimulation.js +781 -781
- package/WaterFlow/GPUFluidSimulation.ts +827 -827
- package/WaterFlow/ReservoirSystem.d.ts +106 -106
- package/WaterFlow/ReservoirSystem.js +611 -611
- package/WaterFlow/ReservoirSystem.ts +754 -754
- package/WaterFlow/SPHField.d.ts +35 -35
- package/WaterFlow/SPHField.js +203 -203
- package/WaterFlow/SPHField.ts +228 -228
- package/WaterFlow/ScreenSpaceFluidPass.d.ts +69 -69
- package/WaterFlow/ScreenSpaceFluidPass.js +728 -728
- package/WaterFlow/ScreenSpaceFluidPass.ts +789 -789
- package/WaterFlow/ShallowWaterSurface.d.ts +45 -45
- package/WaterFlow/ShallowWaterSurface.js +438 -438
- package/WaterFlow/ShallowWaterSurface.ts +510 -510
- package/WaterFlow/WaterFlow.d.ts +87 -87
- package/WaterFlow/WaterFlow.js +171 -171
- package/WaterFlow/WaterFlow.ts +219 -219
- package/WaterFlow/types.d.ts +161 -161
- package/WaterFlow/types.js +1 -1
- package/WaterFlow/types.ts +189 -189
- package/WaterFlow/waterFlowPass.d.ts +3 -3
- package/WaterFlow/waterFlowPass.js +20 -20
- package/WaterFlow/waterFlowPass.ts +40 -40
- package/collisionOBB.d.ts +42 -42
- package/collisionOBB.js +112 -112
- package/collisionOBB.ts +108 -108
- package/declare.d.ts +25 -25
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/instanced/InstancedBatch.d.ts +57 -57
- package/instanced/InstancedBatch.js +348 -348
- package/instanced/InstancedBatch.ts +406 -406
- package/instanced/InstancedChild.d.ts +174 -174
- package/instanced/InstancedChild.js +264 -264
- package/instanced/InstancedChild.ts +327 -327
- package/instanced/InstancedGroup.d.ts +43 -43
- package/instanced/InstancedGroup.js +126 -126
- package/instanced/InstancedGroup.ts +137 -137
- package/instanced/InstancedMeshBase.d.ts +38 -38
- package/instanced/InstancedMeshBase.js +282 -282
- package/instanced/InstancedTemplate.d.ts +46 -46
- package/instanced/InstancedTemplate.js +125 -125
- package/keyControls.d.ts +29 -30
- package/keyControls.js +101 -101
- package/lensflare/LensFlare.d.ts +39 -39
- package/lensflare/LensFlare.js +284 -284
- package/package.json +6 -1
- package/pass/bloom_pass.d.ts +2 -2
- package/pass/bloom_pass.js +174 -174
- package/pass/cover_pass.d.ts +2 -2
- package/pass/cover_pass.js +108 -108
- package/pass/debugDepthState.d.ts +20 -20
- package/pass/debugDepthState.js +9 -9
- package/pass/debugDepthState.ts +22 -22
- package/pass/depthTestBias.d.ts +12 -12
- package/pass/depthTestBias.js +12 -12
- package/pass/depthTestBias.ts +12 -12
- package/pass/effectUserData.d.ts +27 -27
- package/pass/effectUserData.js +1 -1
- package/pass/effectUserData.ts +46 -46
- package/pass/frosted_glass_pass.d.ts +2 -2
- package/pass/frosted_glass_pass.js +150 -150
- package/pass/fsQuad.d.ts +9 -9
- package/pass/fsQuad.js +28 -28
- package/pass/glow_pass.d.ts +2 -2
- package/pass/glow_pass.js +350 -350
- package/pass/screen_bloom_pass.d.ts +11 -11
- package/pass/screen_bloom_pass.js +136 -136
- package/pass/ssao_pass.d.ts +88 -88
- package/pass/ssao_pass.js +799 -799
- package/pass/ssao_pass.ts +918 -918
- package/pass/stroke_pass.d.ts +2 -2
- package/pass/stroke_pass.js +267 -267
- package/shaders/FXAAShaderMaterial.d.ts +3 -3
- package/shaders/FXAAShaderMaterial.js +20 -20
- package/shaders/baseDepthVisShader.d.ts +11 -11
- package/shaders/baseDepthVisShader.js +36 -36
- package/shaders/baseDepthVisShader.ts +36 -36
- package/shaders/baseTextureToRenderShader.d.ts +2 -2
- package/shaders/baseTextureToRenderShader.js +19 -19
- package/shaders/copyShader.d.ts +3 -3
- package/shaders/copyShader.js +13 -13
- package/shaders/debugDepthCompareShader.d.ts +14 -14
- package/shaders/debugDepthCompareShader.js +49 -49
- package/shaders/debugDepthCompareShader.ts +50 -50
- package/shaders/debugDepthJudgeShader.d.ts +18 -18
- package/shaders/debugDepthJudgeShader.js +52 -52
- package/shaders/debugDepthJudgeShader.ts +54 -54
- package/shaders/debugExcludedShader.d.ts +13 -13
- package/shaders/debugExcludedShader.js +46 -46
- package/shaders/debugExcludedShader.ts +48 -48
- package/spriteTextBg.d.ts +1 -1
- package/spriteTextBg.js +20 -20
- package/spriteTextBg.ts +20 -20
- package/threeLoader.d.ts +35 -35
- package/threeLoader.js +518 -518
- package/threeUtils.d.ts +53 -53
- package/threeUtils.js +329 -329
- package/types.d.ts +2 -2
- package/types.js +6 -6
package/MktMesh/panoSlotBind.ts
CHANGED
|
@@ -1,153 +1,153 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @Author: xiaosihan
|
|
3
|
-
* @Date: 2026-10-03
|
|
4
|
-
* @Description: 「一个点槽(同一个全景点的 `RT_STITCH_SLOT_COUNT` 张瓦片)如何换绑进 shader」的**唯一**策略实现
|
|
5
|
-
* (皇上旨 2026-10-03「整套搬进库(彻底同源)」)。
|
|
6
|
-
*
|
|
7
|
-
* ⭐ 2026-10-06 晚皇上旨「每个全景纹理由**左右 2 个 RT** 组成」⇒ 一个点槽的张数从 4 降到 **2**,
|
|
8
|
-
* 同屏全景数从 4 涨到 **8**。本文件里所有「几张」一律由 `RT_STITCH_SLOT_COUNT` 派生,
|
|
9
|
-
* ⛔ 不许再出现字面量 4(槽数再变会漏改 —— 这正是当年两侧分家的老毛病)。
|
|
10
|
-
*
|
|
11
|
-
* 来历:这套判据原先只活在编辑态 `mktMeshEditRenderer._bindSlotTiles`(皇上旨 09-24「一张一张替换上去,别 4 张一起换」
|
|
12
|
-
* + 09-25「未就绪整槽沿用上一批」+ 09-25「绝不让一张已显示的全景因为正在补第 3 格瓦片而整体退出」)。
|
|
13
|
-
* 库侧(预览 / 发布态 `MktMesh.feedFaceMapping`)走的是另一套「齐活才写、矩阵无条件 copy」⇒ ① 换景点会闪一帧灰,
|
|
14
|
-
* ② 图与投影矩阵可能来自**不同批**(旧图配新矩阵)。皇上看的是线上观感,两侧必须同一份代码,故整条搬进来。
|
|
15
|
-
*
|
|
16
|
-
* ⛔ 本文件是这个问题的**第一份也是唯一一份**实现:编辑器与库都只许「委托一行」并把各自的取图口注入进来。
|
|
17
|
-
* 出现第二份 = 两侧又会分家(护栏里有反钉)。
|
|
18
|
-
*
|
|
19
|
-
* 依赖注入的原因:编辑器与库的纹理来源不同(编辑器有自己的 `_floorTexCache` + `threeUtils` 上传队列;
|
|
20
|
-
* 库读自身那份),但「什么时候可以换、换要换几个、没换成该怎么办」这个**决策**必须完全一致 ⇒
|
|
21
|
-
* 决策留在本文件,取货与占位纹理由 `deps` 交进来。
|
|
22
|
-
*/
|
|
23
|
-
import type { ShaderMaterial, Texture } from "three";
|
|
24
|
-
import { RT_STITCH_SLOT_COUNT, setMktPanoTiled } from "./mktShader";
|
|
25
|
-
|
|
26
|
-
/** 取一张「已解码**且**已上传 GPU」的瓦片;未就绪要**当场**自行起载 / 排上传,然后返回 null。
|
|
27
|
-
* ⚠️ 语义硬约束(皇上旨 09-25「队列里的代码就是把加载好的纹理设进 shader 这一句」):
|
|
28
|
-
* 本回调**不许**做同步的重活(解码、上传、绑定判断都不许在 render 里现场发生),只负责「发起 + 报告就绪」。 */
|
|
29
|
-
export interface PanoSlotBindDeps {
|
|
30
|
-
peek(key: string, original: boolean): Texture | null;
|
|
31
|
-
/** 整槽口径(**只**给跨形态翻转那一次用):同一个点的 `RT_STITCH_SLOT_COUNT` 张一起要,缺的返回 null。
|
|
32
|
-
* 编辑器实现 = `_peekSlotGen`(带 `proxy:` 过渡档墓碑分支),库实现 = 逐张 `peek`;
|
|
33
|
-
* 「判不齐就整档不换」这个**决定**仍然只在本文件里下。 */
|
|
34
|
-
peekSlot(tiles: string[], original: boolean): (Texture | null)[];
|
|
35
|
-
/** 该槽从没成功绑过任何图时用来垫 sampler 的 1×1 占位(⛔ 空 sampler 会报错) */
|
|
36
|
-
placeholder: Texture;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 「panoramas[i] 这一格认的是哪张瓦片地址」——逐张换绑的**账本**,按材质实例分 WeakMap 键。
|
|
41
|
-
* 放模块级 ⇒ 编辑器与库**共一本账**(两侧材质是不同实例,天然不串味);材质重建后自动从空账开始。
|
|
42
|
-
*/
|
|
43
|
-
const slotTileKeys = new WeakMap<ShaderMaterial, string[]>();
|
|
44
|
-
|
|
45
|
-
/** 取(必要时建)某材质的逐格地址账本;`len` = `panoramas.length`(= 点数 × `RT_STITCH_SLOT_COUNT`)。 */
|
|
46
|
-
export function panoSlotTileKeys(mat: ShaderMaterial, len: number): string[] {
|
|
47
|
-
let keys = slotTileKeys.get(mat);
|
|
48
|
-
if (!keys) {
|
|
49
|
-
keys = new Array(len).fill("");
|
|
50
|
-
slotTileKeys.set(mat, keys);
|
|
51
|
-
}
|
|
52
|
-
return keys;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 把一个「点槽」的 `RT_STITCH_SLOT_COUNT` 张瓦片换绑进 `panoramas[base .. base + RT_STITCH_SLOT_COUNT - 1]`。
|
|
57
|
-
*
|
|
58
|
-
* 返回 true = 本槽这一帧的图与点位**配好了**(调用方据此写投影矩阵);false = 沿用上一批(调用方矩阵也别动)。
|
|
59
|
-
*
|
|
60
|
-
* ⚠️ 只有一条例外必须整槽同帧:`uPanoTiled` 是**按槽一个标记**(每点一个数,不是每张一个),
|
|
61
|
-
* 它告诉着色器「这几个槽装的是左右两张拼合槽(1) 还是一张整图(0)」。跨形态那一次(瓦片 ↔ 整片、
|
|
62
|
-
* 或某点压根没切过片)若逐张换,中间几帧会拿整图按半幅采(或反之)⇒ 瞬间拉伸错位。
|
|
63
|
-
* 所以「目标形态 ≠ 本槽现有形态」时走整档判齐口径。
|
|
64
|
-
* ⚠️ 同形态内也分两条路(09-25 治本):**整槽换人**(有格正贴着另一批的真图 ⇒ 全部同帧换,判不齐一张都不动)与
|
|
65
|
-
* **逐张补格**(本槽空着或同一批地址还缺的格 ⇒ 到一张补一张)。
|
|
66
|
-
* 「这一格认的是哪张地址」记在 `panoSlotTileKeys`,换人不成就连账本都不改,下一帧重试。
|
|
67
|
-
*/
|
|
68
|
-
export function panoSlotBind(
|
|
69
|
-
mat: ShaderMaterial,
|
|
70
|
-
panos: Texture[],
|
|
71
|
-
base: number,
|
|
72
|
-
tiles: string[],
|
|
73
|
-
tiled: boolean,
|
|
74
|
-
slot: number | undefined,
|
|
75
|
-
deps: PanoSlotBindDeps,
|
|
76
|
-
): boolean {
|
|
77
|
-
// 单全景材质的 uPanoTiled 是标量(写的时候忽略槽位);融合/映射材质是每点一个的数组 ⇒ 读法两样,判定同一个。
|
|
78
|
-
const uv = mat.uniforms.uPanoTiled?.value as number | ArrayLike<number> | undefined;
|
|
79
|
-
const curTiled = uv === undefined ? tiled
|
|
80
|
-
: (typeof uv === "number" ? uv > 0.5 : (uv[slot ?? 0] as number) > 0.5);
|
|
81
|
-
|
|
82
|
-
if (curTiled !== tiled) {
|
|
83
|
-
// ── 跨形态:整槽判齐、一次写入、同一帧翻标记(见上面 ⚠️)──
|
|
84
|
-
// ⭐ 09-28 旨「瓦片纹理不需要添加 oss 的参数」后,过渡缩图档与原图档下载的是**同一张图**,
|
|
85
|
-
// 「原图没齐先上缩图」的兜底只剩双下载 ⇒ 整条删除;判不齐就沿用上一批。
|
|
86
|
-
const ready = deps.peekSlot(tiles, tiled);
|
|
87
|
-
// ⛔ 判齐用「本点槽数」派生(不许写 `ready[0] && ready[1] && ready[2] && ready[3]`)
|
|
88
|
-
const all = ready.length >= RT_STITCH_SLOT_COUNT && ready.slice(0, RT_STITCH_SLOT_COUNT).every((t) => !!t);
|
|
89
|
-
if (all) {
|
|
90
|
-
const keys = panoSlotTileKeys(mat, panos.length);
|
|
91
|
-
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
92
|
-
panos[base + k] = ready[k] as Texture;
|
|
93
|
-
keys[base + k] = tiles[k];
|
|
94
|
-
}
|
|
95
|
-
// ⚠️ 纹理与形态标记必须同一帧落地(分叉过一次 = 整片形态按瓦片 UV 采整图 ⇒ 半幅拉伸)
|
|
96
|
-
setMktPanoTiled(mat, tiled ? 1 : 0, slot);
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
// 整档还没齐:本槽沿用上一批(sampler 读到 undefined 会报错,所以压根没绑过才填占位)
|
|
100
|
-
if (!panos[base]) {
|
|
101
|
-
const keys = panoSlotTileKeys(mat, panos.length);
|
|
102
|
-
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
103
|
-
panos[base + k] = deps.placeholder;
|
|
104
|
-
keys[base + k] = tiles[k];
|
|
105
|
-
}
|
|
106
|
-
setMktPanoTiled(mat, tiled ? 1 : 0, slot); // 占位是 1×1 素色,两种采法无差别,直接把标记对准目标
|
|
107
|
-
}
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ── 同形态 ──
|
|
112
|
-
const keys = panoSlotTileKeys(mat, panos.length);
|
|
113
|
-
// ⭐ 换人(皇上旨 09-25「绝不让一张已显示的全景因为正在补第 3 格瓦片而整体退出」):
|
|
114
|
-
// 只要**有任何一格正贴着别的批次的真图**,本槽这次就是「整槽换人」⇒ 整槽所有张必须同帧落地,
|
|
115
|
-
// 判不齐就一张都不动(连账本也不动 ⇒ 下一帧照判「要换」继续重试,缺的那几张的下载/上传已由 `deps.peek` 当场发起)。
|
|
116
|
-
// 否则旧全景的第 1 张会配新全景的投影矩阵、且权重照给 ⇒ 墙上的图一会儿这张一会儿那张(正是他报的现象)。
|
|
117
|
-
let swapping = false;
|
|
118
|
-
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
119
|
-
const cur = panos[base + k];
|
|
120
|
-
if (cur && cur !== deps.placeholder && keys[base + k] !== tiles[k]) {
|
|
121
|
-
swapping = true;
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (swapping) {
|
|
126
|
-
const got: (Texture | null)[] = [];
|
|
127
|
-
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
128
|
-
// ⭐ 09-28 旨后不再退缩图档(过渡档去参 = 同一张原图,兜底只剩双下载)
|
|
129
|
-
got.push(deps.peek(tiles[k], tiled));
|
|
130
|
-
}
|
|
131
|
-
if (!got.every((t) => !!t)) return false; // 沿用上一批:图 + 矩阵 + 账本一概留着
|
|
132
|
-
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
133
|
-
panos[base + k] = got[k] as Texture;
|
|
134
|
-
keys[base + k] = tiles[k];
|
|
135
|
-
}
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ── 逐张补格(皇上的口径):走到这里说明本槽没有任何一格贴着别的批次的真图
|
|
140
|
-
// ⇒ 不是「首次那几帧」(整槽都是 1×1 占位),就是「同一批地址里还缺的格」。
|
|
141
|
-
// 两种都各判各的、到一张补一张,缺的格露的是素色占位而非另一张全景 ⇒ 无需攒齐。──
|
|
142
|
-
let bound = false;
|
|
143
|
-
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
144
|
-
const i = base + k;
|
|
145
|
-
// ⭐ 09-28 旨后不再退缩图档(过渡档去参 = 同一张原图,兜底只剩双下载)
|
|
146
|
-
const tex = deps.peek(tiles[k], tiled);
|
|
147
|
-
if (!tex) continue; // 还在路上(缺的这张已由 deps.peek 当场发起下载 / 排上传)
|
|
148
|
-
keys[i] = tiles[k];
|
|
149
|
-
if (panos[i] !== tex) panos[i] = tex;
|
|
150
|
-
bound = true;
|
|
151
|
-
}
|
|
152
|
-
return bound;
|
|
153
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* @Author: xiaosihan
|
|
3
|
+
* @Date: 2026-10-03
|
|
4
|
+
* @Description: 「一个点槽(同一个全景点的 `RT_STITCH_SLOT_COUNT` 张瓦片)如何换绑进 shader」的**唯一**策略实现
|
|
5
|
+
* (皇上旨 2026-10-03「整套搬进库(彻底同源)」)。
|
|
6
|
+
*
|
|
7
|
+
* ⭐ 2026-10-06 晚皇上旨「每个全景纹理由**左右 2 个 RT** 组成」⇒ 一个点槽的张数从 4 降到 **2**,
|
|
8
|
+
* 同屏全景数从 4 涨到 **8**。本文件里所有「几张」一律由 `RT_STITCH_SLOT_COUNT` 派生,
|
|
9
|
+
* ⛔ 不许再出现字面量 4(槽数再变会漏改 —— 这正是当年两侧分家的老毛病)。
|
|
10
|
+
*
|
|
11
|
+
* 来历:这套判据原先只活在编辑态 `mktMeshEditRenderer._bindSlotTiles`(皇上旨 09-24「一张一张替换上去,别 4 张一起换」
|
|
12
|
+
* + 09-25「未就绪整槽沿用上一批」+ 09-25「绝不让一张已显示的全景因为正在补第 3 格瓦片而整体退出」)。
|
|
13
|
+
* 库侧(预览 / 发布态 `MktMesh.feedFaceMapping`)走的是另一套「齐活才写、矩阵无条件 copy」⇒ ① 换景点会闪一帧灰,
|
|
14
|
+
* ② 图与投影矩阵可能来自**不同批**(旧图配新矩阵)。皇上看的是线上观感,两侧必须同一份代码,故整条搬进来。
|
|
15
|
+
*
|
|
16
|
+
* ⛔ 本文件是这个问题的**第一份也是唯一一份**实现:编辑器与库都只许「委托一行」并把各自的取图口注入进来。
|
|
17
|
+
* 出现第二份 = 两侧又会分家(护栏里有反钉)。
|
|
18
|
+
*
|
|
19
|
+
* 依赖注入的原因:编辑器与库的纹理来源不同(编辑器有自己的 `_floorTexCache` + `threeUtils` 上传队列;
|
|
20
|
+
* 库读自身那份),但「什么时候可以换、换要换几个、没换成该怎么办」这个**决策**必须完全一致 ⇒
|
|
21
|
+
* 决策留在本文件,取货与占位纹理由 `deps` 交进来。
|
|
22
|
+
*/
|
|
23
|
+
import type { ShaderMaterial, Texture } from "three";
|
|
24
|
+
import { RT_STITCH_SLOT_COUNT, setMktPanoTiled } from "./mktShader";
|
|
25
|
+
|
|
26
|
+
/** 取一张「已解码**且**已上传 GPU」的瓦片;未就绪要**当场**自行起载 / 排上传,然后返回 null。
|
|
27
|
+
* ⚠️ 语义硬约束(皇上旨 09-25「队列里的代码就是把加载好的纹理设进 shader 这一句」):
|
|
28
|
+
* 本回调**不许**做同步的重活(解码、上传、绑定判断都不许在 render 里现场发生),只负责「发起 + 报告就绪」。 */
|
|
29
|
+
export interface PanoSlotBindDeps {
|
|
30
|
+
peek(key: string, original: boolean): Texture | null;
|
|
31
|
+
/** 整槽口径(**只**给跨形态翻转那一次用):同一个点的 `RT_STITCH_SLOT_COUNT` 张一起要,缺的返回 null。
|
|
32
|
+
* 编辑器实现 = `_peekSlotGen`(带 `proxy:` 过渡档墓碑分支),库实现 = 逐张 `peek`;
|
|
33
|
+
* 「判不齐就整档不换」这个**决定**仍然只在本文件里下。 */
|
|
34
|
+
peekSlot(tiles: string[], original: boolean): (Texture | null)[];
|
|
35
|
+
/** 该槽从没成功绑过任何图时用来垫 sampler 的 1×1 占位(⛔ 空 sampler 会报错) */
|
|
36
|
+
placeholder: Texture;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 「panoramas[i] 这一格认的是哪张瓦片地址」——逐张换绑的**账本**,按材质实例分 WeakMap 键。
|
|
41
|
+
* 放模块级 ⇒ 编辑器与库**共一本账**(两侧材质是不同实例,天然不串味);材质重建后自动从空账开始。
|
|
42
|
+
*/
|
|
43
|
+
const slotTileKeys = new WeakMap<ShaderMaterial, string[]>();
|
|
44
|
+
|
|
45
|
+
/** 取(必要时建)某材质的逐格地址账本;`len` = `panoramas.length`(= 点数 × `RT_STITCH_SLOT_COUNT`)。 */
|
|
46
|
+
export function panoSlotTileKeys(mat: ShaderMaterial, len: number): string[] {
|
|
47
|
+
let keys = slotTileKeys.get(mat);
|
|
48
|
+
if (!keys) {
|
|
49
|
+
keys = new Array(len).fill("");
|
|
50
|
+
slotTileKeys.set(mat, keys);
|
|
51
|
+
}
|
|
52
|
+
return keys;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 把一个「点槽」的 `RT_STITCH_SLOT_COUNT` 张瓦片换绑进 `panoramas[base .. base + RT_STITCH_SLOT_COUNT - 1]`。
|
|
57
|
+
*
|
|
58
|
+
* 返回 true = 本槽这一帧的图与点位**配好了**(调用方据此写投影矩阵);false = 沿用上一批(调用方矩阵也别动)。
|
|
59
|
+
*
|
|
60
|
+
* ⚠️ 只有一条例外必须整槽同帧:`uPanoTiled` 是**按槽一个标记**(每点一个数,不是每张一个),
|
|
61
|
+
* 它告诉着色器「这几个槽装的是左右两张拼合槽(1) 还是一张整图(0)」。跨形态那一次(瓦片 ↔ 整片、
|
|
62
|
+
* 或某点压根没切过片)若逐张换,中间几帧会拿整图按半幅采(或反之)⇒ 瞬间拉伸错位。
|
|
63
|
+
* 所以「目标形态 ≠ 本槽现有形态」时走整档判齐口径。
|
|
64
|
+
* ⚠️ 同形态内也分两条路(09-25 治本):**整槽换人**(有格正贴着另一批的真图 ⇒ 全部同帧换,判不齐一张都不动)与
|
|
65
|
+
* **逐张补格**(本槽空着或同一批地址还缺的格 ⇒ 到一张补一张)。
|
|
66
|
+
* 「这一格认的是哪张地址」记在 `panoSlotTileKeys`,换人不成就连账本都不改,下一帧重试。
|
|
67
|
+
*/
|
|
68
|
+
export function panoSlotBind(
|
|
69
|
+
mat: ShaderMaterial,
|
|
70
|
+
panos: Texture[],
|
|
71
|
+
base: number,
|
|
72
|
+
tiles: string[],
|
|
73
|
+
tiled: boolean,
|
|
74
|
+
slot: number | undefined,
|
|
75
|
+
deps: PanoSlotBindDeps,
|
|
76
|
+
): boolean {
|
|
77
|
+
// 单全景材质的 uPanoTiled 是标量(写的时候忽略槽位);融合/映射材质是每点一个的数组 ⇒ 读法两样,判定同一个。
|
|
78
|
+
const uv = mat.uniforms.uPanoTiled?.value as number | ArrayLike<number> | undefined;
|
|
79
|
+
const curTiled = uv === undefined ? tiled
|
|
80
|
+
: (typeof uv === "number" ? uv > 0.5 : (uv[slot ?? 0] as number) > 0.5);
|
|
81
|
+
|
|
82
|
+
if (curTiled !== tiled) {
|
|
83
|
+
// ── 跨形态:整槽判齐、一次写入、同一帧翻标记(见上面 ⚠️)──
|
|
84
|
+
// ⭐ 09-28 旨「瓦片纹理不需要添加 oss 的参数」后,过渡缩图档与原图档下载的是**同一张图**,
|
|
85
|
+
// 「原图没齐先上缩图」的兜底只剩双下载 ⇒ 整条删除;判不齐就沿用上一批。
|
|
86
|
+
const ready = deps.peekSlot(tiles, tiled);
|
|
87
|
+
// ⛔ 判齐用「本点槽数」派生(不许写 `ready[0] && ready[1] && ready[2] && ready[3]`)
|
|
88
|
+
const all = ready.length >= RT_STITCH_SLOT_COUNT && ready.slice(0, RT_STITCH_SLOT_COUNT).every((t) => !!t);
|
|
89
|
+
if (all) {
|
|
90
|
+
const keys = panoSlotTileKeys(mat, panos.length);
|
|
91
|
+
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
92
|
+
panos[base + k] = ready[k] as Texture;
|
|
93
|
+
keys[base + k] = tiles[k];
|
|
94
|
+
}
|
|
95
|
+
// ⚠️ 纹理与形态标记必须同一帧落地(分叉过一次 = 整片形态按瓦片 UV 采整图 ⇒ 半幅拉伸)
|
|
96
|
+
setMktPanoTiled(mat, tiled ? 1 : 0, slot);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// 整档还没齐:本槽沿用上一批(sampler 读到 undefined 会报错,所以压根没绑过才填占位)
|
|
100
|
+
if (!panos[base]) {
|
|
101
|
+
const keys = panoSlotTileKeys(mat, panos.length);
|
|
102
|
+
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
103
|
+
panos[base + k] = deps.placeholder;
|
|
104
|
+
keys[base + k] = tiles[k];
|
|
105
|
+
}
|
|
106
|
+
setMktPanoTiled(mat, tiled ? 1 : 0, slot); // 占位是 1×1 素色,两种采法无差别,直接把标记对准目标
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ── 同形态 ──
|
|
112
|
+
const keys = panoSlotTileKeys(mat, panos.length);
|
|
113
|
+
// ⭐ 换人(皇上旨 09-25「绝不让一张已显示的全景因为正在补第 3 格瓦片而整体退出」):
|
|
114
|
+
// 只要**有任何一格正贴着别的批次的真图**,本槽这次就是「整槽换人」⇒ 整槽所有张必须同帧落地,
|
|
115
|
+
// 判不齐就一张都不动(连账本也不动 ⇒ 下一帧照判「要换」继续重试,缺的那几张的下载/上传已由 `deps.peek` 当场发起)。
|
|
116
|
+
// 否则旧全景的第 1 张会配新全景的投影矩阵、且权重照给 ⇒ 墙上的图一会儿这张一会儿那张(正是他报的现象)。
|
|
117
|
+
let swapping = false;
|
|
118
|
+
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
119
|
+
const cur = panos[base + k];
|
|
120
|
+
if (cur && cur !== deps.placeholder && keys[base + k] !== tiles[k]) {
|
|
121
|
+
swapping = true;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (swapping) {
|
|
126
|
+
const got: (Texture | null)[] = [];
|
|
127
|
+
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
128
|
+
// ⭐ 09-28 旨后不再退缩图档(过渡档去参 = 同一张原图,兜底只剩双下载)
|
|
129
|
+
got.push(deps.peek(tiles[k], tiled));
|
|
130
|
+
}
|
|
131
|
+
if (!got.every((t) => !!t)) return false; // 沿用上一批:图 + 矩阵 + 账本一概留着
|
|
132
|
+
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
133
|
+
panos[base + k] = got[k] as Texture;
|
|
134
|
+
keys[base + k] = tiles[k];
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ── 逐张补格(皇上的口径):走到这里说明本槽没有任何一格贴着别的批次的真图
|
|
140
|
+
// ⇒ 不是「首次那几帧」(整槽都是 1×1 占位),就是「同一批地址里还缺的格」。
|
|
141
|
+
// 两种都各判各的、到一张补一张,缺的格露的是素色占位而非另一张全景 ⇒ 无需攒齐。──
|
|
142
|
+
let bound = false;
|
|
143
|
+
for (let k = 0; k < RT_STITCH_SLOT_COUNT; k++) {
|
|
144
|
+
const i = base + k;
|
|
145
|
+
// ⭐ 09-28 旨后不再退缩图档(过渡档去参 = 同一张原图,兜底只剩双下载)
|
|
146
|
+
const tex = deps.peek(tiles[k], tiled);
|
|
147
|
+
if (!tex) continue; // 还在路上(缺的这张已由 deps.peek 当场发起下载 / 排上传)
|
|
148
|
+
keys[i] = tiles[k];
|
|
149
|
+
if (panos[i] !== tex) panos[i] = tex;
|
|
150
|
+
bound = true;
|
|
151
|
+
}
|
|
152
|
+
return bound;
|
|
153
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
/** ⭐ 槽位「中心死区」(米):离**锚点**(控制器中心点;发布页未注入时 = 相机位置)水平距离最近的那张是中心;挑战者必须比现任中心**近出这么多**才抢得走。
|
|
2
|
-
* 没有死区 ⇒ 锚点停在两点的等距带附近每帧换中心 ⇒ 换中心 = 整组邻居重排 = 一整组瓦片重绑(正是 09-24/25 报的「切全景卡一下」)。
|
|
3
|
-
* 定义在此是因为编辑态与库侧共用(全项目**只此一处**,两侧都 import 它)。 */
|
|
4
|
-
export declare const PANO_SLOT_SWAP_MARGIN_M = 0.5;
|
|
5
|
-
/** 一个候选:`t` 是全景点对象(存引用不存下标 —— 删点会让下标整体前移,引用不会认错人),`d` 是它到**锚点**的水平距离(锚点由调用方决定,本函数不认识它) */
|
|
6
|
-
export interface PanoRosterCand<T> {
|
|
7
|
-
t: T;
|
|
8
|
-
d: number;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* 算出下一帧的槽位名册(**不修改传进来的 roster**,返回新数组)。
|
|
12
|
-
* @param roster 当前名册(0 号槽 = 上一帧的中心),长度可以小于 maxSlots(内部按 undefined 补齐)
|
|
13
|
-
* @param dists 本帧全部全景点及其到**锚点**的距离(锚点 = 调用方那把尺子的端点;⭐ 10-07 第二十一道旨后 = 控制器中心点),**数组顺序 = 全景列表顺序**(下标就是旨意里说的「几号全景」)
|
|
14
|
-
* @param maxSlots shader 的槽位上限(= `MKT_PANO_MAX_SLOTS`;⭐ 2026-10-06 晚旨后是 **8**:8 点 × 每个全景
|
|
15
|
-
* 左右 2 张 RT = 16 sampler 仍是 GLSL 物理上限。⛔ 本函数不许假设它恒等于 4)
|
|
16
|
-
* @param margin 抢中心的死区(米,= `PANO_SLOT_SWAP_MARGIN_M`)
|
|
17
|
-
* @returns 长度恒 = maxSlots 的新名册:**0 号槽 = 中心**,其余槽 = 列表里按序号一层层往外扩的那些
|
|
18
|
-
* (同一层先取离锚点更近那侧)。⭐ 10-07 旨「尽可能填满」⇒ 越界的序号不占格、外扩继续往有货那侧走,
|
|
19
|
-
* 所以**填几格 = min(项目全景总数, maxSlots)**;只有列表里的人不够时才留空(= `undefined`)。
|
|
20
|
-
* 中心没换人 ⇒ 在册的一格都不动,只把**空格**补上。
|
|
21
|
-
*/
|
|
22
|
-
export declare function panoSlotRosterStep<T>(roster: (T | undefined)[], dists: PanoRosterCand<T>[], maxSlots: number, margin: number): (T | undefined)[];
|
|
1
|
+
/** ⭐ 槽位「中心死区」(米):离**锚点**(控制器中心点;发布页未注入时 = 相机位置)水平距离最近的那张是中心;挑战者必须比现任中心**近出这么多**才抢得走。
|
|
2
|
+
* 没有死区 ⇒ 锚点停在两点的等距带附近每帧换中心 ⇒ 换中心 = 整组邻居重排 = 一整组瓦片重绑(正是 09-24/25 报的「切全景卡一下」)。
|
|
3
|
+
* 定义在此是因为编辑态与库侧共用(全项目**只此一处**,两侧都 import 它)。 */
|
|
4
|
+
export declare const PANO_SLOT_SWAP_MARGIN_M = 0.5;
|
|
5
|
+
/** 一个候选:`t` 是全景点对象(存引用不存下标 —— 删点会让下标整体前移,引用不会认错人),`d` 是它到**锚点**的水平距离(锚点由调用方决定,本函数不认识它) */
|
|
6
|
+
export interface PanoRosterCand<T> {
|
|
7
|
+
t: T;
|
|
8
|
+
d: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 算出下一帧的槽位名册(**不修改传进来的 roster**,返回新数组)。
|
|
12
|
+
* @param roster 当前名册(0 号槽 = 上一帧的中心),长度可以小于 maxSlots(内部按 undefined 补齐)
|
|
13
|
+
* @param dists 本帧全部全景点及其到**锚点**的距离(锚点 = 调用方那把尺子的端点;⭐ 10-07 第二十一道旨后 = 控制器中心点),**数组顺序 = 全景列表顺序**(下标就是旨意里说的「几号全景」)
|
|
14
|
+
* @param maxSlots shader 的槽位上限(= `MKT_PANO_MAX_SLOTS`;⭐ 2026-10-06 晚旨后是 **8**:8 点 × 每个全景
|
|
15
|
+
* 左右 2 张 RT = 16 sampler 仍是 GLSL 物理上限。⛔ 本函数不许假设它恒等于 4)
|
|
16
|
+
* @param margin 抢中心的死区(米,= `PANO_SLOT_SWAP_MARGIN_M`)
|
|
17
|
+
* @returns 长度恒 = maxSlots 的新名册:**0 号槽 = 中心**,其余槽 = 列表里按序号一层层往外扩的那些
|
|
18
|
+
* (同一层先取离锚点更近那侧)。⭐ 10-07 旨「尽可能填满」⇒ 越界的序号不占格、外扩继续往有货那侧走,
|
|
19
|
+
* 所以**填几格 = min(项目全景总数, maxSlots)**;只有列表里的人不够时才留空(= `undefined`)。
|
|
20
|
+
* 中心没换人 ⇒ 在册的一格都不动,只把**空格**补上。
|
|
21
|
+
*/
|
|
22
|
+
export declare function panoSlotRosterStep<T>(roster: (T | undefined)[], dists: PanoRosterCand<T>[], maxSlots: number, margin: number): (T | undefined)[];
|