u-space 0.0.31 → 0.0.32

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.
@@ -1,123 +1,127 @@
1
1
  # 快速上手 `u-space`
2
2
 
3
- `u-space` 是一个基于 Three.js 的 WebGPU 3D 引擎。本指南将向你展示如何搭建一个基础的 `u-space` 应用。
3
+ `u-space` 是一个基于 Three.js 的 WebGPU 3D 引擎。本指南使用 React、TypeScript 和 Vite 搭建一个基础应用。
4
4
 
5
- ## 安装
5
+ ## 创建项目
6
6
 
7
- 确保已将 `@types/three` 和 `three` 安装为对等依赖。如果你计划使用交互功能,还需要安装 `camera-controls`。
7
+ ### 1. 初始化 React + Vite
8
8
 
9
9
  ```bash
10
- pnpm install three camera-controls
10
+ pnpm create vite u-space-demo --template react-ts
11
+ cd u-space-demo
12
+ pnpm install
11
13
  ```
12
14
 
13
- ## 基础配置
15
+ ### 2. 安装 `u-space`
14
16
 
15
- 以下是一个最小示例,展示如何初始化 `u-space` 的 `Viewer` 并向场景中添加一个可交互对象。
17
+ ```bash
18
+ pnpm add u-space three camera-controls
19
+ pnpm add -D @types/three
20
+ ```
16
21
 
17
- ### 1. HTML 结构
22
+ Vite 会直接解析 npm 包及 `three/webgpu`,不需要额外配置模块映射。
18
23
 
19
- 创建一个容纳 3D 查看器的元素。
24
+ ## 编写场景组件
20
25
 
21
- ```html
22
- <!DOCTYPE html>
23
- <html lang="zh">
24
- <head>
25
- <meta charset="UTF-8" />
26
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
27
- <title>u-space App</title>
28
- </head>
29
- <body style="margin: 0">
30
- <div id="app" style="width: 100vw; height: 100vh"></div>
31
- <!-- 脚本放这里 -->
32
- </body>
33
- </html>
34
- ```
26
+ ### 1. 替换 `src/App.tsx`
35
27
 
36
- ### 2. Import Maps
28
+ 下面的组件会初始化 `Viewer`、添加一个可交互的立方体,并在 React 组件卸载时释放资源。
37
29
 
38
- 由于 `u-space` 依赖 Three.js 的 WebGPU 特性,建议配置 Import Map 以解析 Three.js 的 WebGPU 构建版本。
30
+ ```tsx
31
+ import { useEffect, useRef } from 'react';
32
+ import { BoxGeometry, Color, GridHelper, MeshBasicMaterial } from 'three/webgpu';
33
+ import { BaseMesh, Viewer } from 'u-space';
39
34
 
40
- ```html
41
- <script type="importmap">
42
- {
43
- "imports": {
44
- "three": "/node_modules/three/build/three.webgpu.js",
45
- "three/webgpu": "/node_modules/three/build/three.webgpu.js",
46
- "three/addons/": "/node_modules/three/examples/jsm/",
47
- "camera-controls": "/node_modules/camera-controls/dist/camera-controls.module.js",
48
- "u-space": "path/to/u-space/dist/index.js"
49
- }
50
- }
51
- </script>
52
- ```
35
+ export default function App() {
36
+ const containerRef = useRef<HTMLDivElement>(null);
37
+
38
+ useEffect(() => {
39
+ const container = containerRef.current;
40
+ if (!container) return;
41
+
42
+ let viewer: Viewer | undefined;
43
+ let cancelled = false;
44
+
45
+ async function setup() {
46
+ const nextViewer = new Viewer({
47
+ el: container,
48
+ rendererOptions: { forceWebGL: false },
49
+ });
50
+ await nextViewer.init();
51
+
52
+ // 兼容 React StrictMode 在开发环境中的重复挂载检查
53
+ if (cancelled) {
54
+ nextViewer.dispose();
55
+ return;
56
+ }
53
57
 
54
- ### 3. 初始化 Viewer 并添加对象
58
+ nextViewer.scene.background = new Color(0x666666);
59
+ nextViewer.scene.add(new GridHelper(10, 10));
55
60
 
56
- 初始化 `Viewer` 并向场景中添加一个基础 Three.js 对象。
61
+ const material = new MeshBasicMaterial({ color: 0xff0000 });
62
+ const box = new BaseMesh(new BoxGeometry(1, 1, 1), material);
63
+ box.position.set(0, 0.5, 0);
64
+ nextViewer.scene.add(box);
57
65
 
58
- ```html
59
- <script type="module">
60
- import { Color, GridHelper, Mesh, BoxGeometry, MeshBasicMaterial } from 'three/webgpu';
61
- import { Viewer } from 'u-space';
66
+ nextViewer.interactionManager.pointerMoveEventsEnabled = true;
62
67
 
63
- const app = document.getElementById('app');
68
+ box.addEventListener('click', ({ event }) => {
69
+ console.log('点击位置:', event.intersect?.point);
70
+ material.color.set(Math.random() * 0xffffff);
71
+ void nextViewer.render();
72
+ });
64
73
 
65
- // 初始化查看器
66
- const viewer = new Viewer({
67
- el: app,
68
- rendererOptions: { forceWebGL: false }, // 优先使用 WebGPU
69
- });
70
- await viewer.init();
74
+ box.addEventListener('pointerenter', () => {
75
+ document.body.style.cursor = 'pointer';
76
+ });
71
77
 
72
- // 设置背景颜色
73
- viewer.scene.background = new Color(0x666666);
78
+ box.addEventListener('pointerleave', () => {
79
+ document.body.style.cursor = 'default';
80
+ });
74
81
 
75
- // 添加网格辅助线
76
- const gridHelper = new GridHelper(10, 10);
77
- viewer.scene.add(gridHelper);
82
+ viewer = nextViewer;
83
+ void viewer.render();
84
+ }
85
+
86
+ void setup();
78
87
 
79
- // 添加一个立方体
80
- const geometry = new BoxGeometry(1, 1, 1);
81
- const material = new MeshBasicMaterial({ color: 0xff0000 });
82
- const box = new Mesh(geometry, material);
83
- box.position.set(0, 0.5, 0);
84
- viewer.scene.add(box);
88
+ return () => {
89
+ cancelled = true;
90
+ document.body.style.cursor = 'default';
91
+ viewer?.dispose();
92
+ };
93
+ }, []);
85
94
 
86
- // 渲染场景
87
- viewer.render();
88
- </script>
95
+ return <div ref={containerRef} className="viewer" />;
96
+ }
89
97
  ```
90
98
 
91
- ### 4. 启用交互
92
-
93
- `u-space` 内置了 `InteractionManager`,可以轻松为 3D 对象添加事件监听。
94
-
95
- ```javascript
96
- // 启用指针移动事件(pointerenter / pointerleave 需要此开关)
97
- viewer.interactionManager.pointerMoveEventsEnabled = true;
98
-
99
- // 添加点击事件
100
- box.addEventListener('click', (e) => {
101
- console.log('点击位置:', e.event.intersect.point);
102
- material.color.set(Math.random() * 0xffffff);
103
- viewer.render(); // 请求新一帧渲染
104
- });
105
-
106
- // 添加悬停事件
107
- box.addEventListener('pointerenter', (e) => {
108
- document.body.style.cursor = 'pointer';
109
- material.color.set(0x00ff00);
110
- viewer.render();
111
- });
112
-
113
- box.addEventListener('pointerleave', (e) => {
114
- document.body.style.cursor = 'default';
115
- material.color.set(0xff0000);
116
- viewer.render();
117
- });
99
+ `BaseMesh` 已包含 `u-space` 交互事件类型,因此可以直接监听 `click`、`pointerenter` 和 `pointerleave`。
100
+
101
+ ### 2. 替换 `src/index.css`
102
+
103
+ ```css
104
+ html,
105
+ body,
106
+ #root,
107
+ .viewer {
108
+ width: 100%;
109
+ height: 100%;
110
+ margin: 0;
111
+ }
112
+
113
+ body {
114
+ overflow: hidden;
115
+ }
116
+ ```
117
+
118
+ ### 3. 启动开发服务器
119
+
120
+ ```bash
121
+ pnpm dev
118
122
  ```
119
123
 
120
- 这样就完成了!你现在拥有一个基础的 `u-space` 应用。
124
+ 打开 Vite 输出的本地地址,即可看到并操作 `u-space` 场景。
121
125
 
122
126
  ## 版本信息
123
127
 
@@ -125,7 +129,7 @@ box.addEventListener('pointerleave', (e) => {
125
129
 
126
130
  ```typescript
127
131
  import { version } from 'u-space';
128
- console.log(version); // e.g. '0.0.31'
132
+ console.log(version); // e.g. '0.0.32'
129
133
 
130
134
  // 也可以通过全局变量访问
131
135
  console.log(window.__USPACE__.version);
package/docs/index.md CHANGED
@@ -41,7 +41,7 @@ features:
41
41
  | [Interactions](./api-interactions) | 交互管理:射线检测、鼠标/触摸事件、框选 |
42
42
  | [Managers](./api-managers) | 对象管理、场景管理、灯光管理 |
43
43
  | [Animations](./api-animations) | 补间动画:`tweenAnimation`、`Tween`、缓动模式 |
44
- | [Effects](./api-effects) | 视觉特效:高亮、呼吸、线框、淡入淡出、流动、流体(TSL) |
44
+ | [Effects](./api-effects) | 视觉特效:高亮、呼吸、线框、淡入淡出、流动、流体与可组合 Outline(TSL) |
45
45
  | [Tools](./api-tools) | 工具:测量(距离/面积/角度)、剖切(面/盒)、标注管理 |
46
46
 
47
47
  ### 插件
package/docs/mcp.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # u-space MCP
2
2
 
3
- `u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括实验性 `u-space/worker` OffscreenCanvas runtime、`OffscreenViewerHost`、top-level await `createWorkerViewer()`、Worker command/事件桥接、`ModelLoaderManager.setDecodeWorker()` + `u-space/worker/model-decoder` 嵌套静态模型解码、transferable/ACK backpressure、普通图片超过 WebGPU `8192` 上限时的解码前缩放、Three.js 原生静态场景矩阵策略及其与 `setEditableBatching()` 的组合;核心 `src/batches` 导出的 `ModelInstancedLayer` 与 `EditableGeometryBatchLayer`;`u-manager` 的 `UManagerLoader` 一体化加载入口、`SceneLoader` 语义去重、path-based model instancing 和 scene-specific editable batching adapter、Semantic/Facilities API,以及 atmosphere 和 fire 插件的 WebGPU 效果。
3
+ `u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括实验性 `u-space/worker` OffscreenCanvas runtime、`OffscreenViewerHost`、top-level await `createWorkerViewer()`、Worker command/事件桥接、`ModelLoaderManager.setDecodeWorker()` + `u-space/worker/model-decoder` 嵌套静态模型解码、transferable/ACK backpressure、普通图片超过 WebGPU `8192` 上限时的解码前缩放、Three.js 原生静态场景矩阵策略及其与 `setEditableBatching()` 的组合;核心 `src/batches` 导出的 `ModelInstancedLayer` 与 `EditableGeometryBatchLayer`;`TSLEffects.outline()` 可组合描边和 `InstanceObject` bounds proxy;`u-manager` 的 `UManagerLoader` 一体化加载入口、`SceneLoader` 语义去重、path-based model instancing 和 scene-specific editable batching adapter、Semantic/Facilities API,以及 atmosphere 和 fire 插件的 WebGPU 效果。
4
4
 
5
5
  ## 安装与启动
6
6
 
@@ -86,7 +86,7 @@ export const codingAgent = new Agent({
86
86
 
87
87
  ## 示例检索
88
88
 
89
- MCP 文档索引包含 `examples/test_umanager_loader.html`、`examples/test_umanager_dynamic_instances.html`、`examples/test_umanager2.html` 和 `examples/offscreen/test_umanager2_offscreen.html` 的说明。检索 `UManagerLoader example`、`test_umanager_loader` 或 `UManagerLoader 用法` 可以找到一体化加载示例;检索 `dynamic instances`、`getInstanceById` 或 `test_umanager_dynamic_instances` 可以找到运行时实例编辑示例;检索 `setEditableBatching`、`SceneEditableBatchLayer`、`SceneEditableBatchFallback`、`editable batching`、`materialize` 或 `test_umanager2` 可以找到大型静态场景合批及其与 `SceneInstancedLayer` fallback 的关系;检索 `OffscreenCanvas`、`OffscreenViewerHost`、`host.init`、`initialized`、`ready`、`createWorkerViewer`、`ModelLoaderManager.setDecodeWorker`、`model-decoder`、`decode Worker`、`transferable`、`ACK backpressure`、`ImageBitmapLoader`、`maxTextureDimension2D`、`oversized texture`、`top-level await`、`u-space/worker`、`Worker WebGPU` 或 `test_umanager2_offscreen` 可以找到 Worker 渲染、嵌套静态模型解码、生命周期、事件/command 桥接、超大贴图缩放、editable batching、pipeline 预热和主线程/GPU 性能边界。
89
+ MCP 文档索引包含 `examples/test_outline.html`、`examples/test_umanager_loader.html`、`examples/test_umanager_dynamic_instances.html`、`examples/test_umanager2.html` 和 `examples/offscreen/test_umanager2_offscreen.html` 的说明。检索 `TSLEffects.outline`、`outline effect`、`instanceBoundsProxy` 或 `test_outline` 可以找到描边 API 与交互示例;检索 `UManagerLoader example`、`test_umanager_loader` 或 `UManagerLoader 用法` 可以找到一体化加载示例;检索 `dynamic instances`、`getInstanceById` 或 `test_umanager_dynamic_instances` 可以找到运行时实例编辑示例;检索 `setEditableBatching`、`SceneEditableBatchLayer`、`SceneEditableBatchFallback`、`editable batching`、`materialize` 或 `test_umanager2` 可以找到大型静态场景合批及其与 `SceneInstancedLayer` fallback 的关系;检索 `OffscreenCanvas`、`OffscreenViewerHost`、`host.init`、`initialized`、`ready`、`createWorkerViewer`、`ModelLoaderManager.setDecodeWorker`、`model-decoder`、`decode Worker`、`transferable`、`ACK backpressure`、`ImageBitmapLoader`、`maxTextureDimension2D`、`oversized texture`、`top-level await`、`u-space/worker`、`Worker WebGPU` 或 `test_umanager2_offscreen` 可以找到 Worker 渲染、嵌套静态模型解码、生命周期、事件/command 桥接、超大贴图缩放、editable batching、pipeline 预热和主线程/GPU 性能边界。
90
90
 
91
91
  ## OffscreenCanvas Worker 检索范围
92
92
 
@@ -119,6 +119,17 @@ MCP 文档索引会同步 `docs/api-objects.md` 中的核心 `InstanceObject` AP
119
119
  | `FacilityInstancedLayer` | `SemanticGroup.facilityLayer` / `SemanticGroup.getDefaultFacilityLayer()`、`getInstances()`、`getInstanceById()`、`reserveBatch()`、`addInstance()` / `addInstances()`、`removeInstance()` / `removeInstances()`(支持单个 `instanceId` 字符串)、`removeBatch()`、`clearBatches()`、batch 创建条件、`setInstanceCulling()`、动态 Facilities batch、可选按相机视锥压缩 active instances、可选 `minScreenRadius` 屏幕尺寸裁剪、dirty-driven instance buffer 同步和 raycast hit remap。 |
120
120
  | `Facilities` | `SemanticLoader` 解析、`FloorMesh.getFacilityById()`、`FacilityInstanceObject.setInstanceOpacity()`、普通 `Model` fallback wrapper 与 scene-level instancing 的一致 API;`SemanticGroup` / `BuildingGroup` / `FloorMesh` 查询使用对象语义 ID、实例 `instanceId` 或显式别名,不扫描 `userData` ID。 |
121
121
 
122
+ ## Effects 检索范围
123
+
124
+ MCP 文档索引会同步 `docs/api-effects.md` 中的 `MaterialEffects` / `TSLEffects` API,以及 `docs/examples-guide.md` 中的 Outline 示例。客户端可以直接检索以下关键词:
125
+
126
+ | 关键词 / API | 可检索内容 |
127
+ | :----------- | :--------- |
128
+ | `TSLEffects.outline` / `TSLOutlineEffect` | 通过 `RenderPipeline.addOutputEffect()` 接入描边、`setSelectedObjects()` 替换选择、`update()` 动态调参,以及 `removeOutputEffect()` 后 `dispose()` 的完整生命周期。 |
129
+ | `TSLOutlineOptions` | 可见/隐藏边缘颜色、强度、厚度、Glow、降采样比例,以及 `instanceBoundsProxy`、padding 和最小尺寸默认值。 |
130
+ | `InstanceObject outline` / `instanceBoundsProxy` | 优先使用实例的实际渲染对象或逻辑对象渲染子树;都不存在时由世界包围盒创建不可见代理,并随 dirty callback 更新。 |
131
+ | `test_outline` | Box、Sphere 与核心 `InstanceObject` 的交互选择、实时参数调整和 output-effect 资源释放示例。 |
132
+
122
133
  ## fire 检索范围
123
134
 
124
135
  MCP 文档索引会同步 `docs/api-plugin-fire.md` 中的 FireEffect API、参数和示例。客户端可以直接检索以下关键词:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u-space",
3
- "version": "0.0.31",
3
+ "version": "0.0.32",
4
4
  "type": "module",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "module": "dist/index.js",