# 应用App

 [App](https://vjmap.com/map3d/api/classes/App.html)是基于`vjmap3d`开发出的3d应用，他作为 vjmap3d 的核心，主要负责管理场景渲染, 事件交互等。

 ## 应用模块

  `App`类本身基本上没有什么方法和属性，他是由以下应用模块 [Module](./module.md)功能组合而成。

> 📌 模块成员是 **mixin 注入**：模块唤醒时经 `applyMixinsTo(app, [...])` 把成员挂到 `app` 上。`App.defaultModules`（即下表全部模块，含 `StatModule`/`CameraModule`）**不论是否传对应选项都会注入**——只有用 `options.modules` 自定义模块列表去掉某模块时，对应 `app.*` 才不存在。getter 的值可能是 `undefined`（如未设 `stat.show` 时 `app.showStat === undefined`），但 `app.showStat = true` 照常生效；判断模块是否存在请用 `app.getModule(vjmap3d.StatModule)`，不要用 `typeof app.showStat`。

|应用模块名|描述|选项参数名|
|:---|:---|:---|
|[WebGLRendererModule](https://vjmap.com/map3d/api/classes/WebGLRendererModule.html)|渲染引擎模块|render|
|[CameraModule](https://vjmap.com/map3d/api/classes/CameraModule.html)|相机模块|camera|
|[OrbitControlModule](https://vjmap.com/map3d/api/classes/OrbitControlModule.html)|轨道控制器模块|control|
|[SceneModule](https://vjmap.com/map3d/api/classes/SceneModule.html)|场景模块|scene|
|[PostProcessModule](https://vjmap.com/map3d/api/classes/PostProcessModule.html)|后期处理模块|postProcess|
|[CoordSystemModule](https://vjmap.com/map3d/api/classes/CoordSystemModule.html)|坐标转换模块|coordSystem|
|[EntityManagerModule](https://vjmap.com/map3d/api/classes/EntityManagerModule.html)|实体管理模块||
|[EntityQueryModule](https://vjmap.com/map3d/api/classes/EntityQueryModule.html)|实体查询模块||
|[InputModule](https://vjmap.com/map3d/api/classes/InputModule.html)|鼠标键盘输入模块|input|
|[PickModule](https://vjmap.com/map3d/api/classes/PickModule.html)|拾取交互模块||
|[UiModule](https://vjmap.com/map3d/api/classes/UiModule.html)|UI界面模块|ui|
|[RectCollideModule](https://vjmap.com/map3d/api/classes/RectCollideModule.html)|矩形碰撞检测模块|rectCollide|
|[ToolStateModule](https://vjmap.com/map3d/api/classes/ToolStateModule.html)|工具交互模块|toolState|
|[CommandModule](https://vjmap.com/map3d/api/classes/CommandModule.html)|命令模块|command|
|[StatModule](https://vjmap.com/map3d/api/classes/StatModule.html)|性能统计模块|stat|
|[ParticleRenderModule](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html)|粒子效果模块|particle|
|[PhysicsManagerModule](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html)|物理引擎模块|physics|
|[EntityOutlineModule](https://vjmap.com/map3d/api/classes/EntityOutlineModule.html)|实体描边模块|entityOutline|
|[CSS2DRendererModule](https://vjmap.com/map3d/api/classes/CSS2DRendererModule.html)|css2d渲染引擎模块|css2dRender|
|[CSS3DRendererModule](https://vjmap.com/map3d/api/classes/CSS3DRendererModule.html)|css3d渲染引擎模块|css3dRender|

<mapFrame>
<pre>
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
let app = new vjmap3d.App(svc, {
    container: "map", // 容器id
    scene: {
        gridHelper: { visible: true } // 是否显示坐标网格
    }
})
const ui = await app.getConfigPane();
let cfg = app.uiConfig
ui.appendChild(cfg)
</pre>
</mapFrame>

::: tip 提示
默认情况下，按 Ctrl + Shift + U 可弹出或关闭属性面板
:::

 ## 信号事件

 `App` 常用的信号事件如下：
|事件名|描述|
|:---|:---|
|onSelectedChange|物体选择信息改变事件|
|onEntitySelected|实体设置选择|
|onEntityUnSelected|实体取消选择|
|onBloomedChange|实体辉光改变|
|onEntityBloomed|实体设置辉光|
|onEntityUnBloomed|实体取消辉光|
|onOutlineChange|实体描边改变|
|onEntityOutline|实体设置描边|
|onEntityUnOutline|实体取消描边|
|onMouseUp|鼠标抬起|
|onMouseMove|鼠标移动|
|onMouseDown|鼠标按下|
|onMousePreClick|鼠标按下之前|
|onMouseClick|鼠标单击|
|onMouseDblClick|鼠标双击|
|onMouseOver|鼠标指针穿过被选元素或其子元素，均会触发事件|
|onMouseOut|鼠标指针离开被选元素或其子元素则触发事件|
|onMouseEnter|鼠标指针穿过被选元素时才触发事件|
|onMouseLeave|鼠标指针离开被选元素时才触发事件|
|onContextMenu|上下文菜单事件|
|onPointerDown|指针按下(PC和移动端)|
|onPointerMove|指针移动(PC和移动端)|
|onPointerUp|指针抬起(PC和移动端)|
|onPointerDownUp|指针直接按下松开，没有拖动|
|onPointerCancel|指针取消|
|onMouseWheel|鼠标滚轮|
|onKeyDown|键盘按下|
|onKeyUp|键盘抬起|
|onAppBeforeUpdate|每帧更新前运行|
|onAppUpdate|每帧更新|
|onAppAfterUpdate|每帧更新后运行|
|onAppBeforeRender|每帧渲染前运行|
|onAppRender|每帧渲染|
|onAppAfterRender|每帧渲染后运行|

> 📌 帧信号的派发机制：`callModules("onAppUpdate")` 是**三通道扇出**——同一调用同时派发 `moduleManager.callModules`（模块方法）、`app.dispatch("onAppUpdate")`（`app.on` 监听）和 `app.signal.onAppUpdate.dispatch`（signal `.add` 回调）。三条通道等价可用。注意 RAF 节流：页面不可见/无变化时帧率骤降（同一段 400ms 窗口回调 0~9 次），自动化验证勿按固定帧率断言，单帧确定性回调用 `app.onNextFrame(cb)`。
|onAppBeforeAddEntity|实体增加前回调|
|onAppAddEntity|实体增加回调|
|onAppBeforeRemoveObject|object3d对象移除前回调|
|onAppRemoveObject|object3d对象移除回调|
|onAppBeforeRemoveEntity|实体移除前回调|
|onAppRemoveEntity|实体移除回调|
|onContainerSizeChange|窗口大小变化事件|
|onCameraControl|相机控件事件|
|onCameraUpdate|相机更新事件|
|onCameraChange|相机变化事件，当相机对象变化或远近裁剪面变化时触发|
|contextMenuPreOpen|上下文菜单即将打开|
|contextMenuOpened|上下文菜单已打开|
|contextMenuNoContent|上下文菜单打开无内容|
|contextMenuCancel|上下文菜单取消|
|onCustomEvent|自定义事件|
|onAddScene|新增场景|
|onActiveScene|把场景置为当前|
|onRemoveScene|移除场景|

示例： 响应点击事件，弹出信息
```js
app.signal.onMouseClick.add(e => app.logInfo("您点击了下!", "success" , 1000))
```

<mapFrame>
<pre>
let svc = new vjmap3d.Service(env.serviceUrl, env.accessToken);
        let app = new vjmap3d.App(svc, {
            container: "map", // 容器id
            // 渲染参数
            scene: {
                gridHelper: { visible: true } // 是否显示坐标网格
            },
            camera: {  // 相机设置
                viewHelper: { enable: true } // 是否显示视角指示器
            }
        })
        //
        app.signal.onMouseClick.add(e => app.logInfo("您点击了下!", "success" , 1000))
</pre>
</mapFrame>

## 模块中常用方法属性

### [WebGLRendererModule](https://vjmap.com/map3d/api/classes/WebGLRendererModule.html)

渲染引擎模块。模块参数 `render` 中可通过 `engine` 选择渲染引擎：`"webgl"`（默认，`WebGLRenderer`）或 `"webgpu"`（`WebGPURenderer`，可配 `forceWebGL: true` 强制 WebGL2 后端，**v2.0.0 起提供**，旧版 `1.0.23` 仅 `webgl`）。浏览器不支持 WebGPU 时由 three 的 `WebGPURenderer` 自动降级为 WebGL2 后端（仍属 `webgpu` 引擎：`app.renderer.isWebGPURenderer === true`、仍只认 TSL/NodeMaterial）；只有 `three/webgpu`/`three/tsl` 动态加载失败、渲染器 `init()` 抛错或地图图层（map2d）模式时才回退到 `webgl` 引擎，详见 [WebGPU 渲染引擎](../advance/webgpu.md)。

|方法名|描述|
|:---|:---|
|[renderer](https://vjmap.com/map3d/api/classes/WebGLRendererModule.html#renderer)|渲染器（`webgl` 引擎时为 `WebGLRenderer`，`webgpu` 引擎时为 `WebGPURenderer`，可用 `isWebGPURenderer` 判断）|
|[isMapMode](https://vjmap.com/map3d/api/classes/WebGLRendererModule.html#isMapMode)|2d地图模式(为true时表示基于vjmap,3d做为一个图层)|
|[getScreenshot](https://vjmap.com/map3d/api/classes/WebGLRendererModule.html#getScreenshot)|获取渲染截图（返 `Blob`；**参数名是 `mine` 不是 `mime`**——`getScreenshot({mine:"image/png"})`，历史拼写；**参数对象不可省略**：无参调用时内部读 `params.download` 抛 TypeError、Promise reject，至少写 `app.getScreenshot({})`）|
|[commonUniforms](https://vjmap.com/map3d/api/classes/WebGLRendererModule.html#commonUniforms)|通用的uniforms参数|

::: tip whenReady
`webgpu` 引擎的渲染器为异步初始化：创建 `App` 后如需立即访问 `app.renderer`，应先 `await app.whenReady()`（`webgl` 引擎下立即返回）。注意 `whenReady` 自 v2.0.0 起提供——旧版 `1.0.23` 的 dist 中无此方法，需跨版本兼容时写 `await app.whenReady?.()`。
:::

### [CSS2DRendererModule](https://vjmap.com/map3d/api/classes/CSS2DRendererModule.html)

css2d渲染引擎模块

|方法名|描述|
|:---|:---|
|[css2dRenderer](https://vjmap.com/map3d/api/classes/CSS2DRendererModule.html#css2dRenderer)|2d渲染器|
|[getMarker2Ds](https://vjmap.com/map3d/api/classes/CSS2DRendererModule.html#getMarker2Ds)|获取所有的marker2d|
|[getPopup2Ds](https://vjmap.com/map3d/api/classes/CSS2DRendererModule.html#getPopup2Ds)|获取所有的popup2d|
|[popup2d](https://vjmap.com/map3d/api/classes/CSS2DRendererModule.html#popup2d)|全局的popup对象|
 
### [CSS3DRendererModule](https://vjmap.com/map3d/api/classes/CSS3DRendererModule.html)

css3d渲染引擎模块

|方法名|描述|
|:---|:---|
|[css3dRenderer](https://vjmap.com/map3d/api/classes/CSS3DRendererModule.html#css3dRenderer)|css3d渲染器|
|[css3dOccludeRenderer](https://vjmap.com/map3d/api/classes/CSS3DRendererModule.html#css3dOccludeRenderer)|能遮挡的css3d渲染器|
|[setCss3dObjectCanOcclude](https://vjmap.com/map3d/api/classes/CSS3DRendererModule.html#setCss3dObjectCanOcclude)|设置3d物体能否被场景遮挡|

### [SceneModule](https://vjmap.com/map3d/api/classes/SceneModule.html)

场景模块

|方法名|描述|
|:---|:---|
|[addScene](https://vjmap.com/map3d/api/classes/SceneModule.html#addScene)|增加场景|
|[activeScene](https://vjmap.com/map3d/api/classes/SceneModule.html#activeScene)|切换场景|
|[removeScene](https://vjmap.com/map3d/api/classes/SceneModule.html#removeScene)|移除场景|
|[initScene](https://vjmap.com/map3d/api/classes/SceneModule.html#initScene)|初始化场景|
|[clearScenes](https://vjmap.com/map3d/api/classes/SceneModule.html#clearScenes)|清空所有场景|
|[sceneEntity](https://vjmap.com/map3d/api/classes/SceneModule.html#sceneEntity)|场景实体|
|[addDefaultLights](https://vjmap.com/map3d/api/classes/SceneModule.html#addDefaultLights)|增加缺省灯光|
|[getSceneStatData](https://vjmap.com/map3d/api/classes/SceneModule.html#getSceneStatData)|获取场景的统计数据|
|[envConfig](https://vjmap.com/map3d/api/classes/SceneModule.html#envConfig)|环境变量|
|[setEnvConfig](https://vjmap.com/map3d/api/classes/SceneModule.html#setEnvConfig)|设置环境变量|
|[setBackgroundEnvironment](https://vjmap.com/map3d/api/classes/SceneModule.html#setBackgroundEnvironment)|设置场景背景及环境参数|
|[setFocus](https://vjmap.com/map3d/api/classes/SceneModule.html#setFocus)|获取焦点|
|[loadResources](https://vjmap.com/map3d/api/classes/SceneModule.html#loadResources)|加载资源数组|
|[getLoadedResources](https://vjmap.com/map3d/api/classes/SceneModule.html#getLoadedResources)|获取通过loadResources已加载的资源|

### [EntityManagerModule](https://vjmap.com/map3d/api/classes/EntityManagerModule.html)

实体管理模块

|方法名|描述|
|:---|:---|
|[getEntities](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getEntities)|获取所有实体|
|[getRayQueryEntities](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getRayQueryEntities)|获取可以射线查询的实体|
|[addSelectedEntity](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#addSelectedEntity)|增加选择实体|
|[removeSelectEntity](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#removeSelectEntity)|移除选择实体|
|[getSelectObjects](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getSelectObjects)|获取选择实体|
|[getSelectObjectsRef](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getSelectObjectsRef)|获取选择实体响应式对象|
|[addBloomEntity](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#addBloomEntity)|增加辉光实体|
|[removeBloomEntity](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#removeBloomEntity)|移除辉光实体|
|[getBloomObjects](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getBloomObjects)|获取辉光实体|
|[getBloomObjectsRef](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getBloomObjectsRef)|获取辉光实体响应式对象|
|[addOutlineEntity](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#addOutlineEntity)|增加描边实体|
|[removeOutlineEntity](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#removeOutlineEntity)|移除描边实体|
|[getOutlineObjects](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getOutlineObjects)|获取描边实体|
|[getOutlineObjectsRef](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#getOutlineObjectsRef)|获取描边响应式对象|
|[setSelectBoomRefreshFlag](https://vjmap.com/map3d/api/classes/EntityManagerModule.html#setSelectBoomRefreshFlag)|设置辉光刷新标识|

### [StatModule](https://vjmap.com/map3d/api/classes/StatModule.html)

性能统计模块

|方法名|描述|
|:---|:---|
|[showStat](https://vjmap.com/map3d/api/classes/StatModule.html#showStat)|是否显示性能统计|

### [CameraModule](https://vjmap.com/map3d/api/classes/CameraModule.html)

相机模块

|方法名|描述|
|:---|:---|
|[viewHelperEnable](https://vjmap.com/map3d/api/classes/CameraModule.html#viewHelperEnable)|是否显示视角显示器|
|[setCameraLookAt](https://vjmap.com/map3d/api/classes/CameraModule.html#setCameraLookAt)|设置相机朝向|
|[enableCameraControl](https://vjmap.com/map3d/api/classes/App.html#enableCameraControl)|是否启用相机控制器|
|[enableCameraControlRef](https://vjmap.com/map3d/api/classes/App.html#enableCameraControlRef)|相机控制器响应式对象|
|[enableWheelWhenCtrlDisabled](https://vjmap.com/map3d/api/classes/App.html#enableWheelWhenCtrlDisabled)|当相机禁止时还允许滚轮进行缩放操作|
  
### [CoordSystemModule](https://vjmap.com/map3d/api/classes/CoordSystemModule.html)

坐标转换模块

|方法名|描述|
|:---|:---|
|[unproject](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#unproject)|屏幕坐标转世界坐标（屏幕坐标为**浏览器视口 client 坐标**，如 `event.clientX/clientY`，内部会减去容器 left/top；限定求交实体用 `{ include: [...], exclude: [...] }`——直接传数组会被当成普通对象忽略、退化为全场景求交）|
|[unprojectAsync](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#unprojectAsync)|屏幕坐标转世界坐标（同 unproject 函数，不同的地方是他支持通过后期处理的深度进行转换，是异步执行的；`webgl` 引擎下未显式 `postProcess: { enable: true }` 时 `getDepth` 恒为 `undefined`，`"depth"` 方式随之退化为场景射线求交）|
|[project](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#project)|世界坐标转屏幕坐标|
|[screenToNdc](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#screenToNdc)|屏幕坐标转NDC坐标|
|[ndcToScreen](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#ndcToScreen)|NDC坐标转屏幕坐标|
|[centerOrigin](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#centerOrigin)|设置的中心点坐标|
|[scaleOrigin](https://vjmap.com/map3d/api/classes/CoordSystemModule.html#scaleOrigin)|开始缩放比例，x,y,z方向都同比例缩放，默认1|

> ⚠️ 屏幕位置无实体命中时 `unproject` / `unprojectAsync` 返回形态**不一致**——`unproject` 返回 `null`，而 `unprojectAsync` 返回一个 `x/y/z` 全为 `undefined` 的 Vector3（不是 null）。判空须用 `v == null || v.x == null` 之类写法兼容两者。

### [PickModule](https://vjmap.com/map3d/api/classes/PickModule.html)

拾取交互模块

|方法名|描述|
|:---|:---|
|[isFreeStatus](https://vjmap.com/map3d/api/classes/PickModule.html#isFreeStatus)|当前应该是否处于自由状态|
|[isFreeStatusRef](https://vjmap.com/map3d/api/classes/PickModule.html#isFreeStatusRef)|自由状态响应式对象|
|[pickPoint](https://vjmap.com/map3d/api/classes/PickModule.html#pickPoint)|拾取一个点|
|[pickEntity](https://vjmap.com/map3d/api/classes/PickModule.html#pickEntity)|拾取实体|
|[drawSelectBox](https://vjmap.com/map3d/api/classes/PickModule.html#drawSelectBox)|绘制一个选择框|
|[actionDrawPoint](https://vjmap.com/map3d/api/classes/PickModule.html#actionDrawPoint)|绘制一个点，获取点坐标|
|[actionDrawLineSting](https://vjmap.com/map3d/api/classes/PickModule.html#actionDrawLineSting)|绘制一条线，获取线坐标|
|[actionDrawPolygon](https://vjmap.com/map3d/api/classes/PickModule.html#actionDrawPolygon)|绘制一个多边形，获取多边形坐标|
|[actionDrawEdit](https://vjmap.com/map3d/api/classes/PickModule.html#actionDrawEdit)|编辑绘制的对象|
|[actionPickSelect](https://vjmap.com/map3d/api/classes/PickModule.html#actionPickSelect)|选中一个实体对象|
|[getDrawLayer](https://vjmap.com/map3d/api/classes/PickModule.html#getDrawLayer)|通过图层名称获取当前绘图层的实体|
  
### [InputModule](https://vjmap.com/map3d/api/classes/InputModule.html)

鼠标键盘输入模块

|方法名|描述|
|:---|:---|
|[addPointerEventsObject](https://vjmap.com/map3d/api/classes/InputModule.html#addPointerEventsObject)|增加有事件响应的实体|
|[removePointerEventsObject](https://vjmap.com/map3d/api/classes/InputModule.html#removePointerEventsObject)|移除有事件响应的实体|
|[Input](https://vjmap.com/map3d/api/classes/InputModule.html#Input)|当前输入参数|
|[setMenu](https://vjmap.com/map3d/api/classes/InputModule.html#setMenu)|设置地图右键上下文菜单|
 
### [EntityQueryModule](https://vjmap.com/map3d/api/classes/EntityQueryModule.html)

实体查询模块

|方法名|描述|
|:---|:---|
|[queryEntitiesByCamera](https://vjmap.com/map3d/api/classes/EntityQueryModule.html#queryEntitiesByCamera)|通过相机查询实体|
|[queryEntitiesByRaycast](https://vjmap.com/map3d/api/classes/EntityQueryModule.html#queryEntitiesByRaycast)|通过射线查询实体|
|[queryEntitiesByScreenPos](https://vjmap.com/map3d/api/classes/EntityQueryModule.html#queryEntitiesByScreenPos)|通过屏幕像素坐标查询实体|
|[queryEntitiesByBox](https://vjmap.com/map3d/api/classes/EntityQueryModule.html#queryEntitiesByBox)|通过框选查询实体|
|[getRayByScreenPos](https://vjmap.com/map3d/api/classes/EntityQueryModule.html#getRayByScreenPos)|通过屏幕坐标获取射线|
|[getQueryRaycaster](https://vjmap.com/map3d/api/classes/EntityQueryModule.html#getQueryRaycaster)|获取查询的射线对象|

### [PostProcessModule](https://vjmap.com/map3d/api/classes/PostProcessModule.html)

后期处理模块。`webgpu` 引擎下由 WebGPU 后处理模块自动接管，下列方法在 `App` 上保持同名可用（`composer` 返回的是兼容对象而非 pmndrs 的 `EffectComposer`，其 `passes` 恒为空数组；`bloomEffect` 只有 `selection`/`intensity`/`luminanceThreshold`，`outlineEffect`/`selectedEffect` 只有 `selection`/`edgeStrength`/`visibleEdgeColor`/`hiddenEdgeColor`/`pulseSpeed`；部分 `postProcess` 参数被忽略），详见 [后期处理](../postprocessing/postprocessing.md)。

|方法名|描述|
|:---|:---|
|[composer](https://vjmap.com/map3d/api/classes/PostProcessModule.html#composer)|效果合成器|
|[isComposerEnable](https://vjmap.com/map3d/api/classes/PostProcessModule.html#isComposerEnable)|效果合成器是否可用|
|[setComposerEnable](https://vjmap.com/map3d/api/classes/PostProcessModule.html#setComposerEnable)|设置效果合成器是否可用|
|[addEffectRenderPass](https://vjmap.com/map3d/api/classes/PostProcessModule.html#addEffectRenderPass)|给效果合成器增加渲染通道|
|[removeEffectRenderPass](https://vjmap.com/map3d/api/classes/PostProcessModule.html#removeEffectRenderPass)|给效果合成器移除渲染通道|
|[refreshEffectRenderPass](https://vjmap.com/map3d/api/classes/PostProcessModule.html#refreshEffectRenderPass)|刷新渲染通道（⚠️ composer 内同时存在 **UV 变换类效果**与**卷积类效果**（如 GlitchEffect）时调用抛 `Effects that transform UVs are incompatible with convolution`——内部 addRenderPass/setEffectRenderPassOrder 也走此路径，手动调用前先确认效果组合兼容）|
|[getDepth](https://vjmap.com/map3d/api/classes/PostProcessModule.html#getDepth)|根据屏幕坐标获取深度值|
|[outlineEffect](https://vjmap.com/map3d/api/classes/PostProcessModule.html#outlineEffect)|OutlineEffect|
|[bloomEffect](https://vjmap.com/map3d/api/classes/PostProcessModule.html#bloomEffect)|bloomEffect|
|[selectedEffect](https://vjmap.com/map3d/api/classes/PostProcessModule.html#selectedEffect)|selectedEffect|
|[isPostProcessIdle](https://vjmap.com/map3d/api/classes/App.html#isPostProcessIdle)|⚠️ 仅类型声明（后期处理是否空闲），运行时 `undefined`，勿用|

### [RectCollideModule](https://vjmap.com/map3d/api/classes/RectCollideModule.html)

矩形碰撞检测模块

|方法名|描述|
|:---|:---|
|[addCollideRectObject](https://vjmap.com/map3d/api/classes/RectCollideModule.html#addCollideRectObject)|增加碰撞检测的对象|
|[removeCollideRectObject](https://vjmap.com/map3d/api/classes/RectCollideModule.html#removeCollideRectObject)|移除碰撞检测的对象|
|[updateCollideRect](https://vjmap.com/map3d/api/classes/RectCollideModule.html#updateCollideRect)|更新碰撞检测|
|[setCollideRectDirty](https://vjmap.com/map3d/api/classes/RectCollideModule.html#setCollideRectDirty)|设置更新碰撞检测为脏数据，使其重新检测|

### [ToolStateModule](https://vjmap.com/map3d/api/classes/ToolStateModule.html)

工具交互模块

|方法名|描述|
|:---|:---|
|[rootState](https://vjmap.com/map3d/api/classes/ToolStateModule.html#rootState)|根状态|
|[getStatePath](https://vjmap.com/map3d/api/classes/ToolStateModule.html#getStatePath)|获取状态路径|
|[stateIsIn](https://vjmap.com/map3d/api/classes/ToolStateModule.html#stateIsIn)|stateIsIn|
|[stateInAny](https://vjmap.com/map3d/api/classes/ToolStateModule.html#stateInAny)|stateInAny|
|[setCurrentTool](https://vjmap.com/map3d/api/classes/ToolStateModule.html#setCurrentTool)|设置当前工具|
|[getCurrentTool](https://vjmap.com/map3d/api/classes/ToolStateModule.html#getCurrentTool)|获取当前工具|
|[getCurrentToolId](https://vjmap.com/map3d/api/classes/ToolStateModule.html#getCurrentToolId)|获取当前工具id|
|[getStateDescendant](https://vjmap.com/map3d/api/classes/ToolStateModule.html#getStateDescendant)|getStateDescendant|
|[addTool](https://vjmap.com/map3d/api/classes/ToolStateModule.html#addTool)|增加工具|
|[removeTool](https://vjmap.com/map3d/api/classes/ToolStateModule.html#removeTool)|移除工具|
|[isInActiveTool](https://vjmap.com/map3d/api/classes/ToolStateModule.html#isInActiveTool)|判断当前是否有工具处于运行中|
|[isInteracting](https://vjmap.com/map3d/api/classes/ToolStateModule.html#isInteracting)|是否正在交互|
|[transformObject](https://vjmap.com/map3d/api/classes/ToolStateModule.html#transformObject)|对一个物体进行变换控制器操作|

### [CommandModule](https://vjmap.com/map3d/api/classes/CommandModule.html)

命令模块

|方法名|描述|
|:---|:---|
|[commandHistory](https://vjmap.com/map3d/api/classes/CommandModule.html#commandHistory)|命令历史记录|
|[clearCommands](https://vjmap.com/map3d/api/classes/CommandModule.html#clearCommands)|清空命令|
|[executeCommand](https://vjmap.com/map3d/api/classes/CommandModule.html#executeCommand)|执行命令，自动执行。⚠️ 无入参校验——`executeCommand(null)` 抛 `Cannot set properties of null (setting 'app')`，务必传 `ICommand` 实例|
|[executeAllCommands](https://vjmap.com/map3d/api/classes/CommandModule.html#executeAllCommands)|执行所有命令，自动执行|
|[executeManyCommands](https://vjmap.com/map3d/api/classes/CommandModule.html#executeManyCommands)|执行多个命令，自动执行|
|[addCommand](https://vjmap.com/map3d/api/classes/CommandModule.html#addCommand)|增加命令，不会自动执行|
|[addAllCommands](https://vjmap.com/map3d/api/classes/CommandModule.html#addAllCommands)|增加全部命令——⚠️ 实现会包成 `MultiCmdsCommand` 入栈并**立即执行**每个子命令（子命令的 `autoExecute=false` 被忽略），且子命令不会注入 `app`（依赖 `this.app` 的自定义命令会抛错，`executeAllCommands`/`executeManyCommands` 同）；只入栈不执行请逐个 `addCommand`|
|[addManyCommands](https://vjmap.com/map3d/api/classes/CommandModule.html#addManyCommands)|增加多个命令——⚠️ 同 `addAllCommands`：会立即执行各子命令，只入栈不执行请逐个 `addCommand`|
|[undo](https://vjmap.com/map3d/api/classes/CommandModule.html#undo)|撤销|
|[redo](https://vjmap.com/map3d/api/classes/CommandModule.html#redo)|还原|

### [UiModule](https://vjmap.com/map3d/api/classes/UiModule.html)

UI界面模块

|方法名|描述|
|:---|:---|
|[addControl](https://vjmap.com/map3d/api/classes/UiModule.html#addControl)|增加控件|
|[removeControl](https://vjmap.com/map3d/api/classes/UiModule.html#removeControl)|移除控件|
|[hasControl](https://vjmap.com/map3d/api/classes/UiModule.html#hasControl)|是否有控件|
|[setCursor](https://vjmap.com/map3d/api/classes/UiModule.html#setCursor)|设置光标|
|[getConfigPane](https://vjmap.com/map3d/api/classes/UiModule.html#getConfigPane)|获取配置面板|
|[logInfo](https://vjmap.com/map3d/api/classes/UiModule.html#logInfo)|信息弹窗提示|

### [ParticleRenderModule](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html)

粒子效果模块

|方法名|描述|
|:---|:---|
|[particleRenderer](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#particleRenderer)|粒子渲染器|
|[addParticleSystem](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#addParticleSystem)|增加粒子系统|
|[addParticle](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#addParticle)|增加粒子|
|[loadParticle](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#loadParticle)|从文件加载粒子场景|
|[loadParticleFromJson](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#loadParticleFromJson)|从JSON字符串中加载粒子场景|
|[loadParticleFromRes](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#loadParticleFromRes)|从资源加载粒子场景|
|[removeParticle](https://vjmap.com/map3d/api/classes/ParticleRenderModule.html#removeParticle)|移除粒子系统|

### [PhysicsManagerModule](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html)

物理引擎模块

|方法名|描述|
|:---|:---|
|[physicsEnable](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#physicsEnable)|是否能用物理引擎|
|[physicsWorld](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#physicsWorld)|得到物理引擎世界对象|
|[physicsEngine](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#physicsEngine)|得到物理引擎对象|
|[enablePhysicsEngine](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#enablePhysicsEngine)|启动物体引擎|
|[addPhysicsBody](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#addPhysicsBody)|增加物理刚体|
|[removePhysicsObject](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#removePhysicsObject)|通过实体或对象移除物理刚体|
|[addPhysicsGround](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#addPhysicsGround)|增加一个物理地面|
|[setPhysicsDebugger](https://vjmap.com/map3d/api/classes/PhysicsManagerModule.html#setPhysicsDebugger)|设置物理引擎调试|

## 生命周期补充

- `app.destroy()`：`AppBase` 上的方法，**仅停止渲染循环**并置 `app.destroyed === true`，**不移除模块**、不释放渲染器/canvas/window resize 监听。彻底销毁用 `app.dispose()`（先 `removeAllModules()` 再 `destroy()`，会 `renderer.dispose()` 并移除 canvas）。
- **App 没有 `resize` 方法**——画布尺寸只在 **window 的 `resize` 事件**（防抖）时按容器 `clientWidth/clientHeight` 更新，不监听容器元素本身（没有 ResizeObserver）。容器因布局变化（侧栏折叠、隐藏的 tab 变为显示）而 window 尺寸未变时不会自适应，需手动 `window.dispatchEvent(new Event('resize'))`。
- `app.clearScenes()`：清空所有场景但不销毁 app。
- `app.toJSON()`（d.ts 存在但文档未列）：对正常 `new App()` 实例直接调用抛 `Cannot convert undefined or null to object`——序列化依赖的内部状态未就绪时不可用，调用前需自行 try/catch。
