u-space 0.0.3 → 0.0.5

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.
@@ -3342,16 +3342,27 @@ function requireWhichTypedArray() {
3342
3342
  var O = r(E);
3343
3343
  S = p(O, Symbol.toStringTag);
3344
3344
  }
3345
- s["$" + m] = b(S.get);
3345
+ if (S && S.get) {
3346
+ var C = b(S.get);
3347
+ s[
3348
+ /** @type {`$${import('.').TypedArrayName}`} */
3349
+ "$" + m
3350
+ ] = C;
3351
+ }
3346
3352
  }
3347
3353
  }) : h(n, function(m) {
3348
3354
  var A = new t[m](), E = A.slice || A.set;
3349
- E && (s[
3350
- /** @type {`$${import('.').TypedArrayName}`} */
3351
- "$" + m
3352
- ] = /** @type {import('./types').BoundSlice | import('./types').BoundSet} */
3353
- // @ts-expect-error TODO FIXME
3354
- b(E));
3355
+ if (E) {
3356
+ var S = (
3357
+ /** @type {import('./types').BoundSlice | import('./types').BoundSet} */
3358
+ // @ts-expect-error TODO FIXME
3359
+ b(E)
3360
+ );
3361
+ s[
3362
+ /** @type {`$${import('.').TypedArrayName}`} */
3363
+ "$" + m
3364
+ ] = S;
3365
+ }
3355
3366
  });
3356
3367
  var l = function(A) {
3357
3368
  var E = !1;
@@ -4591,43 +4602,11 @@ function require_stream_duplex$1() {
4591
4602
  }
4592
4603
  }), _stream_duplex$1;
4593
4604
  }
4594
- var string_decoder = {}, safeBuffer = { exports: {} }, hasRequiredSafeBuffer;
4595
- function requireSafeBuffer() {
4596
- return hasRequiredSafeBuffer || (hasRequiredSafeBuffer = 1, (function(h, d) {
4597
- var b = requireDist(), u = b.Buffer;
4598
- function p(f, o) {
4599
- for (var t in f)
4600
- o[t] = f[t];
4601
- }
4602
- u.from && u.alloc && u.allocUnsafe && u.allocUnsafeSlow ? h.exports = b : (p(b, d), d.Buffer = r);
4603
- function r(f, o, t) {
4604
- return u(f, o, t);
4605
- }
4606
- p(u, r), r.from = function(f, o, t) {
4607
- if (typeof f == "number")
4608
- throw new TypeError("Argument must not be a number");
4609
- return u(f, o, t);
4610
- }, r.alloc = function(f, o, t) {
4611
- if (typeof f != "number")
4612
- throw new TypeError("Argument must be a number");
4613
- var n = u(f);
4614
- return o !== void 0 ? typeof t == "string" ? n.fill(o, t) : n.fill(o) : n.fill(0), n;
4615
- }, r.allocUnsafe = function(f) {
4616
- if (typeof f != "number")
4617
- throw new TypeError("Argument must be a number");
4618
- return u(f);
4619
- }, r.allocUnsafeSlow = function(f) {
4620
- if (typeof f != "number")
4621
- throw new TypeError("Argument must be a number");
4622
- return b.SlowBuffer(f);
4623
- };
4624
- })(safeBuffer, safeBuffer.exports)), safeBuffer.exports;
4625
- }
4626
- var hasRequiredString_decoder;
4605
+ var string_decoder = {}, hasRequiredString_decoder;
4627
4606
  function requireString_decoder() {
4628
4607
  if (hasRequiredString_decoder) return string_decoder;
4629
4608
  hasRequiredString_decoder = 1;
4630
- var h = requireSafeBuffer().Buffer, d = h.isEncoding || function(E) {
4609
+ var h = requireSafeBuffer$1().Buffer, d = h.isEncoding || function(E) {
4631
4610
  switch (E = "" + E, E && E.toLowerCase()) {
4632
4611
  case "hex":
4633
4612
  case "utf8":
@@ -5688,6 +5667,38 @@ var streamBrowser, hasRequiredStreamBrowser;
5688
5667
  function requireStreamBrowser() {
5689
5668
  return hasRequiredStreamBrowser || (hasRequiredStreamBrowser = 1, streamBrowser = requireEvents().EventEmitter), streamBrowser;
5690
5669
  }
5670
+ var safeBuffer = { exports: {} }, hasRequiredSafeBuffer;
5671
+ function requireSafeBuffer() {
5672
+ return hasRequiredSafeBuffer || (hasRequiredSafeBuffer = 1, (function(h, d) {
5673
+ var b = requireDist(), u = b.Buffer;
5674
+ function p(f, o) {
5675
+ for (var t in f)
5676
+ o[t] = f[t];
5677
+ }
5678
+ u.from && u.alloc && u.allocUnsafe && u.allocUnsafeSlow ? h.exports = b : (p(b, d), d.Buffer = r);
5679
+ function r(f, o, t) {
5680
+ return u(f, o, t);
5681
+ }
5682
+ p(u, r), r.from = function(f, o, t) {
5683
+ if (typeof f == "number")
5684
+ throw new TypeError("Argument must not be a number");
5685
+ return u(f, o, t);
5686
+ }, r.alloc = function(f, o, t) {
5687
+ if (typeof f != "number")
5688
+ throw new TypeError("Argument must be a number");
5689
+ var n = u(f);
5690
+ return o !== void 0 ? typeof t == "string" ? n.fill(o, t) : n.fill(o) : n.fill(0), n;
5691
+ }, r.allocUnsafe = function(f) {
5692
+ if (typeof f != "number")
5693
+ throw new TypeError("Argument must be a number");
5694
+ return u(f);
5695
+ }, r.allocUnsafeSlow = function(f) {
5696
+ if (typeof f != "number")
5697
+ throw new TypeError("Argument must be a number");
5698
+ return b.SlowBuffer(f);
5699
+ };
5700
+ })(safeBuffer, safeBuffer.exports)), safeBuffer.exports;
5701
+ }
5691
5702
  var util = {}, hasRequiredUtil;
5692
5703
  function requireUtil() {
5693
5704
  if (hasRequiredUtil) return util;
@@ -9898,7 +9909,7 @@ function requireBn$1() {
9898
9909
  var _ = 67108863 ^ 67108863 >>> g << g;
9899
9910
  this.words[this.length - 1] &= _;
9900
9911
  }
9901
- return this.strip();
9912
+ return this.length === 0 && (this.words[0] = 0, this.length = 1), this.strip();
9902
9913
  }, r.prototype.maskn = function(v) {
9903
9914
  return this.clone().imaskn(v);
9904
9915
  }, r.prototype.iaddn = function(v) {
@@ -11279,7 +11290,7 @@ function requireBn() {
11279
11290
  var q = 67108863 ^ 67108863 >>> _ << _;
11280
11291
  this.words[this.length - 1] &= q;
11281
11292
  }
11282
- return this._strip();
11293
+ return this.length === 0 && (this.words[0] = 0, this.length = 1), this._strip();
11283
11294
  }, r.prototype.maskn = function(c) {
11284
11295
  return this.clone().imaskn(c);
11285
11296
  }, r.prototype.iaddn = function(c) {
@@ -1,4 +1,4 @@
1
- import { type Object3D } from 'three/webgpu';
1
+ import { type Object3D, AnimationMixer, type AnimationAction, type AnimationClip } from 'three/webgpu';
2
2
  import { type InteractionEventMap } from '../interactions';
3
3
  import { BaseGroup } from './BaseGroup';
4
4
  export interface ModelParameters {
@@ -6,12 +6,25 @@ export interface ModelParameters {
6
6
  cache?: boolean;
7
7
  persistent?: boolean;
8
8
  }
9
+ export interface PlayAnimationOptions {
10
+ loop?: boolean;
11
+ repetitions?: number;
12
+ timeScale?: number;
13
+ clampWhenFinished?: boolean;
14
+ }
9
15
  export declare class Model extends BaseGroup<InteractionEventMap> {
10
16
  readonly isModel = true;
11
17
  type: string;
12
18
  private static memoryCache;
19
+ mixer: AnimationMixer | null;
20
+ animations: AnimationClip[];
21
+ private actions;
13
22
  constructor();
14
23
  loadAsync(parameters: ModelParameters): Promise<Object3D<import("three").Object3DEventMap> | null>;
24
+ playAnimation(nameOrIndex?: string | number, options?: PlayAnimationOptions): AnimationAction | null;
25
+ playAllAnimations(options?: PlayAnimationOptions): AnimationAction[];
26
+ stopAnimation(nameOrIndex?: string | number): void;
27
+ updateAnimation(delta: number): void;
15
28
  static clearMemoryCache(): void;
16
29
  static clearPersistentCache(): Promise<void>;
17
30
  }
@@ -21,11 +21,15 @@ export interface PoiParameters {
21
21
  borderRadius?: number;
22
22
  /** Text position relative to the icon */
23
23
  textPosition?: 'top' | 'bottom' | 'left' | 'right';
24
+ /** Scale factor for mapping canvas pixels to world units */
25
+ scaleFactor?: number;
24
26
  }
25
27
  export declare class Poi extends BaseSprite<InteractionEventMap> {
26
28
  readonly isPoi = true;
27
29
  type: string;
28
30
  parameters: Required<PoiParameters>;
31
+ private _canvas;
32
+ private _lastParametersJSON;
29
33
  constructor(parameters?: PoiParameters);
30
34
  /**
31
35
  * Update the POI with new parameters
@@ -14,15 +14,19 @@ export interface ViewerOptions {
14
14
  export interface ViewerEventMap {
15
15
  beforeControlsUpdate: {
16
16
  time: number;
17
+ delta: number;
17
18
  };
18
19
  afterControlsUpdate: {
19
20
  time: number;
21
+ delta: number;
20
22
  };
21
23
  beforeRender: {
22
24
  time: number;
25
+ delta: number;
23
26
  };
24
27
  afterRender: {
25
28
  time: number;
29
+ delta: number;
26
30
  };
27
31
  cameraChange: {
28
32
  camera: PerspectiveCamera | OrthographicCamera;
@@ -66,6 +66,64 @@ const model3 = new Model();
66
66
  model3.loadAsync({ url: 'model.glb', cache: true, persistent: true });
67
67
  ```
68
68
 
69
+ ### 动画
70
+
71
+ `Model` 在加载含内置动画的模型(如 glTF/FBX)后,会自动初始化 `AnimationMixer` 并收集 `AnimationClip`。
72
+
73
+ **属性:**
74
+
75
+ | 属性 | 类型 | 说明 |
76
+ | :----------- | :-------------------------- | :----------------------------------------- |
77
+ | `mixer` | `AnimationMixer \| null` | 动画混合器,加载含动画模型后自动创建。 |
78
+ | `animations` | `AnimationClip[]` | 模型内置的动画片段列表。 |
79
+
80
+ #### `playAnimation(nameOrIndex?, options?)`
81
+
82
+ 播放指定动画。不传参时播放第一个动画。
83
+
84
+ ```typescript
85
+ // 按名称播放
86
+ model.playAnimation('Walk');
87
+
88
+ // 按索引播放
89
+ model.playAnimation(0);
90
+
91
+ // 带选项
92
+ model.playAnimation('Run', {
93
+ loop: true, // 是否循环(默认 true)
94
+ repetitions: 3, // 循环次数(默认 Infinity)
95
+ timeScale: 1.5, // 播放速度(默认 1)
96
+ clampWhenFinished: true, // 播放结束后停留在最后一帧(默认 false)
97
+ });
98
+ ```
99
+
100
+ #### `playAllAnimations(options?)`
101
+
102
+ 播放模型所有内置动画。参数同 `playAnimation`。
103
+
104
+ ```typescript
105
+ model.playAllAnimations({ timeScale: 2 });
106
+ ```
107
+
108
+ #### `stopAnimation(nameOrIndex?)`
109
+
110
+ 停止指定动画。不传参时停止所有动画。
111
+
112
+ ```typescript
113
+ model.stopAnimation('Walk'); // 停止指定动画
114
+ model.stopAnimation(); // 停止所有动画
115
+ ```
116
+
117
+ #### `updateAnimation(delta)`
118
+
119
+ 推进动画时间,需在渲染循环中调用。`delta` 为帧间隔时间(秒),可从 Viewer 事件的 `delta` 属性获取。
120
+
121
+ ```typescript
122
+ viewer.addEventListener('beforeRender', (e) => {
123
+ model.updateAnimation(e.delta);
124
+ });
125
+ ```
126
+
69
127
  ### 清除缓存
70
128
 
71
129
  可通过 `Model` 类的静态方法手动清除内部缓存:
@@ -158,8 +158,10 @@ viewer.dispose();
158
158
 
159
159
  Viewer 继承自 `EventDispatcher`,会触发以下事件:
160
160
 
161
- - `beforeControlsUpdate`:在 `CameraControls` 更新之前触发,提供 `{ time: number }`。
162
- - `afterControlsUpdate`:在 `CameraControls` 更新之后触发,提供 `{ time: number }`。
163
- - `beforeRender`:在 `renderer.render` 调用之前立即触发,提供 `{ time: number }`。
164
- - `afterRender`:在 `renderer.render` 完成之后立即触发,提供 `{ time: number }`。
161
+ - `beforeControlsUpdate`:在 `CameraControls` 更新之前触发,提供 `{ time: number; delta: number }`。
162
+ - `afterControlsUpdate`:在 `CameraControls` 更新之后触发,提供 `{ time: number; delta: number }`。
163
+ - `beforeRender`:在 `renderer.render` 调用之前立即触发,提供 `{ time: number; delta: number }`。
164
+ - `afterRender`:在 `renderer.render` 完成之后立即触发,提供 `{ time: number; delta: number }`。
165
165
  - `cameraChange`:调用 `setCamera` 时触发,提供 `{ camera: Camera }`。
166
+
167
+ 其中 `delta` 为上一帧到当前帧的时间间隔(秒),可用于动画更新等场景。
@@ -46,3 +46,17 @@
46
46
  - 流式传输结构化场景布局,解析场景描述(`SceneLoader`、`TopologiesLoader`)。
47
47
  - 使用相机动画(`VisionsLoader` 和 `VisionsParser`)在场景中编排预定义的飞行路径。
48
48
  - 获取复杂的节点材质,并自定义 WebGPU 专属的 TSL(Three Shading Language)节点,如 `TSLEffects.fluid()`。
49
+
50
+ ## 5. `test_model_animation.html`:模型内置动画
51
+
52
+ [在线演示](https://u-space-phi.vercel.app/examples/test_model_animation.html)
53
+
54
+ 该示例演示了如何加载含内置动画的 glTF 模型,并通过 `Model` 类的动画 API 控制播放。
55
+
56
+ ### 核心要点:
57
+
58
+ - 使用 `Model.loadAsync()` 加载带动画的 `.glb` 文件,动画片段自动初始化。
59
+ - 使用 `viewer.frameloop = 'always'` 开启持续渲染以驱动动画。
60
+ - 监听 `beforeRender` 事件,通过 `model.updateAnimation(e.delta)` 推进动画时间。
61
+ - 使用 `model.playAnimation(name)` 按名称播放单个动画,`model.playAllAnimations()` 播放全部。
62
+ - 使用 `model.stopAnimation()` 停止动画播放。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u-space",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "types": "dist/src/index.d.ts",
6
6
  "module": "dist/index.js",