@spatialwalk/avatarkit 1.0.0-beta.44 → 1.0.0-beta.46
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/CHANGELOG.md +24 -0
- package/README.md +3 -1
- package/dist/{StreamingAudioPlayer-rs7ZcwVo.js → StreamingAudioPlayer-BlY4b-HD.js} +1 -1
- package/dist/avatar_core_wasm.wasm +0 -0
- package/dist/core/Avatar.d.ts +1 -0
- package/dist/core/AvatarController.d.ts +1 -0
- package/dist/core/AvatarView.d.ts +2 -1
- package/dist/{index-CEqzEo-H.js → index-DJMm01Eu.js} +55 -4
- package/dist/index.js +1 -1
- package/package.json +13 -12
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.0.0-beta.46] - 2025-12-29
|
|
9
|
+
|
|
10
|
+
### 🐛 Bugfix
|
|
11
|
+
- Expose `getCharacterMeta()` method in `Avatar` class as public API
|
|
12
|
+
|
|
13
|
+
## [1.0.0-beta.45] - 2025-12-29
|
|
14
|
+
|
|
15
|
+
### ✨ New Features
|
|
16
|
+
- **Immediate Rendering on Pause** - When playback is paused, updating post-processing parameters or camera configuration will immediately re-render the current frame:
|
|
17
|
+
- Post-processing parameters (rotation, neck pose, jaw pose, eye blink, etc.) now apply immediately when updated during pause
|
|
18
|
+
- Camera configuration (position, target, FOV, etc.) now applies immediately when updated during pause
|
|
19
|
+
- During normal playback, these updates still apply on the next frame as before
|
|
20
|
+
|
|
21
|
+
### 🔄 API Changes
|
|
22
|
+
|
|
23
|
+
### 🔄 API Changes
|
|
24
|
+
- **AvatarView Ready Promise Replaced with Callback** - Replaced `ready: Promise<void>` property with `onFirstRendering?: () => void` callback for better async handling:
|
|
25
|
+
- Removed `ready` Promise property
|
|
26
|
+
- Added `onFirstRendering` optional callback that is called when the first frame is rendered
|
|
27
|
+
- Callback-based approach is more idiomatic and easier to use than Promise-based approach
|
|
28
|
+
|
|
29
|
+
### 🗑️ Removed
|
|
30
|
+
- **Removed unused `seek()` method** - Removed unused and buggy `seek()` method from `StreamingAudioPlayer`
|
|
31
|
+
|
|
8
32
|
## [1.0.0-beta.44] - 2025-12-29
|
|
9
33
|
|
|
10
34
|
### 🔧 Performance Improvements
|
package/README.md
CHANGED
|
@@ -309,7 +309,9 @@ const container = document.getElementById('avatar-container')
|
|
|
309
309
|
const avatarView = new AvatarView(avatar, container)
|
|
310
310
|
|
|
311
311
|
// Wait for first frame to render
|
|
312
|
-
|
|
312
|
+
avatarView.onFirstRendering = () => {
|
|
313
|
+
// First frame rendered
|
|
314
|
+
}
|
|
313
315
|
|
|
314
316
|
// Get or set avatar transform (position and scale)
|
|
315
317
|
// Get current transform
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { A as APP_CONFIG, e as errorToMessage, l as logEvent, a as logger } from "./index-
|
|
4
|
+
import { A as APP_CONFIG, e as errorToMessage, l as logEvent, a as logger } from "./index-DJMm01Eu.js";
|
|
5
5
|
class StreamingAudioPlayer {
|
|
6
6
|
constructor(options) {
|
|
7
7
|
__publicField(this, "audioContext", null);
|
|
File without changes
|
package/dist/core/Avatar.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export declare class AvatarController {
|
|
|
53
53
|
private resetConversationIdState;
|
|
54
54
|
private getEffectiveConversationId;
|
|
55
55
|
setPostProcessingConfig(config: PostProcessingConfig | null): void;
|
|
56
|
+
private rerenderCurrentFrame;
|
|
56
57
|
setVolume(volume: number): void;
|
|
57
58
|
getVolume(): number;
|
|
58
59
|
private startStreamingPlaybackInternal;
|
|
@@ -3,7 +3,7 @@ import { AvatarController } from './AvatarController';
|
|
|
3
3
|
export declare class AvatarView {
|
|
4
4
|
private readonly avatarController;
|
|
5
5
|
private readonly avatar;
|
|
6
|
-
|
|
6
|
+
onFirstRendering?: () => void;
|
|
7
7
|
private canvas;
|
|
8
8
|
private renderSystem;
|
|
9
9
|
private isInitialized;
|
|
@@ -56,6 +56,7 @@ export declare class AvatarView {
|
|
|
56
56
|
private startRealtimeRendering;
|
|
57
57
|
private stopRealtimeRendering;
|
|
58
58
|
dispose(): void;
|
|
59
|
+
private rerenderCurrentFrameWithNewCamera;
|
|
59
60
|
private handleResize;
|
|
60
61
|
get transform(): {
|
|
61
62
|
x: number;
|
|
@@ -7573,7 +7573,7 @@ const _AnimationPlayer = class _AnimationPlayer {
|
|
|
7573
7573
|
if (this.streamingPlayer) {
|
|
7574
7574
|
return;
|
|
7575
7575
|
}
|
|
7576
|
-
const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-
|
|
7576
|
+
const { StreamingAudioPlayer } = await import("./StreamingAudioPlayer-BlY4b-HD.js");
|
|
7577
7577
|
const { AvatarSDK: AvatarSDK2 } = await Promise.resolve().then(() => AvatarSDK$1);
|
|
7578
7578
|
const audioFormat = AvatarSDK2.getAudioFormat();
|
|
7579
7579
|
this.streamingPlayer = new StreamingAudioPlayer({
|
|
@@ -8963,7 +8963,7 @@ class AvatarSDK {
|
|
|
8963
8963
|
}
|
|
8964
8964
|
__publicField(AvatarSDK, "_isInitialized", false);
|
|
8965
8965
|
__publicField(AvatarSDK, "_configuration", null);
|
|
8966
|
-
__publicField(AvatarSDK, "_version", "1.0.0-beta.
|
|
8966
|
+
__publicField(AvatarSDK, "_version", "1.0.0-beta.46");
|
|
8967
8967
|
__publicField(AvatarSDK, "_avatarCore", null);
|
|
8968
8968
|
__publicField(AvatarSDK, "_dynamicSdkConfig", null);
|
|
8969
8969
|
const AvatarSDK$1 = Object.freeze(Object.defineProperty({
|
|
@@ -11091,6 +11091,44 @@ class AvatarController {
|
|
|
11091
11091
|
}
|
|
11092
11092
|
setPostProcessingConfig(config) {
|
|
11093
11093
|
this.postProcessingConfig = config;
|
|
11094
|
+
if (this.currentState === AvatarState.paused && this.isPlaying) {
|
|
11095
|
+
this.rerenderCurrentFrame();
|
|
11096
|
+
}
|
|
11097
|
+
}
|
|
11098
|
+
async rerenderCurrentFrameIfPaused() {
|
|
11099
|
+
if (this.currentState !== AvatarState.paused || !this.renderCallback) {
|
|
11100
|
+
return;
|
|
11101
|
+
}
|
|
11102
|
+
const frameIndex = this.lastRenderedFrameIndex;
|
|
11103
|
+
if (frameIndex < 0) {
|
|
11104
|
+
return;
|
|
11105
|
+
}
|
|
11106
|
+
let arrayIndex = frameIndex - this.keyframesOffset;
|
|
11107
|
+
if (arrayIndex < 0 || arrayIndex >= this.currentKeyframes.length) {
|
|
11108
|
+
if (this.currentKeyframes.length === 0) {
|
|
11109
|
+
return;
|
|
11110
|
+
}
|
|
11111
|
+
arrayIndex = Math.max(0, Math.min(this.currentKeyframes.length - 1, arrayIndex));
|
|
11112
|
+
}
|
|
11113
|
+
try {
|
|
11114
|
+
const currentFrame = this.currentKeyframes[arrayIndex];
|
|
11115
|
+
let wasmParams = convertProtoFlameToWasmParams(currentFrame);
|
|
11116
|
+
if (this.postProcessingConfig) {
|
|
11117
|
+
wasmParams = this.applyPostProcessingToParams(wasmParams);
|
|
11118
|
+
}
|
|
11119
|
+
const avatarCore = AvatarSDK.getAvatarCore();
|
|
11120
|
+
if (avatarCore) {
|
|
11121
|
+
const splatData = await avatarCore.computeFrameFlatFromParams(wasmParams, this.characterHandle ?? void 0);
|
|
11122
|
+
if (splatData) {
|
|
11123
|
+
this.renderCallback(splatData, frameIndex);
|
|
11124
|
+
}
|
|
11125
|
+
}
|
|
11126
|
+
} catch (error) {
|
|
11127
|
+
logger.error("[AvatarController] Failed to rerender current frame:", error instanceof Error ? error.message : String(error));
|
|
11128
|
+
}
|
|
11129
|
+
}
|
|
11130
|
+
async rerenderCurrentFrame() {
|
|
11131
|
+
await this.rerenderCurrentFrameIfPaused();
|
|
11094
11132
|
}
|
|
11095
11133
|
onTransitionComplete() {
|
|
11096
11134
|
var _a;
|
|
@@ -13477,7 +13515,7 @@ class AvatarView {
|
|
|
13477
13515
|
constructor(avatar, container) {
|
|
13478
13516
|
__publicField(this, "avatarController");
|
|
13479
13517
|
__publicField(this, "avatar");
|
|
13480
|
-
__publicField(this, "
|
|
13518
|
+
__publicField(this, "onFirstRendering");
|
|
13481
13519
|
__publicField(this, "canvas");
|
|
13482
13520
|
__publicField(this, "renderSystem", null);
|
|
13483
13521
|
__publicField(this, "isInitialized", false);
|
|
@@ -13513,7 +13551,9 @@ class AvatarView {
|
|
|
13513
13551
|
this.renderRealtimeFrame(splatData, frameIndex);
|
|
13514
13552
|
});
|
|
13515
13553
|
this.canvas = this.createCanvas(container);
|
|
13516
|
-
this.
|
|
13554
|
+
this.initializeView(avatar).catch((error) => {
|
|
13555
|
+
logger.error("[AvatarView] Initialization failed:", error instanceof Error ? error.message : String(error));
|
|
13556
|
+
});
|
|
13517
13557
|
this.setupControllerEventListeners();
|
|
13518
13558
|
}
|
|
13519
13559
|
alignFlamePair(from, to2) {
|
|
@@ -13749,6 +13789,7 @@ class AvatarView {
|
|
|
13749
13789
|
return derivedCamera;
|
|
13750
13790
|
}
|
|
13751
13791
|
async renderFirstFrame() {
|
|
13792
|
+
var _a;
|
|
13752
13793
|
if (!this.renderSystem) {
|
|
13753
13794
|
throw new Error("Render system not initialized");
|
|
13754
13795
|
}
|
|
@@ -13771,6 +13812,7 @@ class AvatarView {
|
|
|
13771
13812
|
this.renderSystem.renderFrame();
|
|
13772
13813
|
if (APP_CONFIG.debug)
|
|
13773
13814
|
logger.log("[AvatarView] First frame rendered successfully");
|
|
13815
|
+
(_a = this.onFirstRendering) == null ? void 0 : _a.call(this);
|
|
13774
13816
|
} else {
|
|
13775
13817
|
throw new Error("Failed to compute first frame splat data");
|
|
13776
13818
|
}
|
|
@@ -14143,7 +14185,16 @@ class AvatarView {
|
|
|
14143
14185
|
this.renderSystem.updateCamera(cameraConfig);
|
|
14144
14186
|
if (APP_CONFIG.debug)
|
|
14145
14187
|
logger.log("[AvatarView] Applied new camera config to render system");
|
|
14188
|
+
if (this.avatarController.state === AvatarState.paused && this.renderingState === "speaking") {
|
|
14189
|
+
this.rerenderCurrentFrameWithNewCamera();
|
|
14190
|
+
}
|
|
14191
|
+
}
|
|
14192
|
+
}
|
|
14193
|
+
async rerenderCurrentFrameWithNewCamera() {
|
|
14194
|
+
if (this.avatarController.state !== AvatarState.paused || this.renderingState !== "speaking" || !this.renderSystem) {
|
|
14195
|
+
return;
|
|
14146
14196
|
}
|
|
14197
|
+
await this.avatarController.rerenderCurrentFrameIfPaused();
|
|
14147
14198
|
}
|
|
14148
14199
|
handleResize() {
|
|
14149
14200
|
if (this.renderSystem) {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spatialwalk/avatarkit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.46",
|
|
5
|
+
"packageManager": "pnpm@10.18.2",
|
|
5
6
|
"description": "SPAvatar SDK - 3D Gaussian Splatting Avatar Rendering SDK",
|
|
6
7
|
"author": "SPAvatar Team",
|
|
7
8
|
"license": "MIT",
|
|
@@ -31,6 +32,16 @@
|
|
|
31
32
|
"CHANGELOG.md",
|
|
32
33
|
"dist"
|
|
33
34
|
],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "SDK_BUILD=true vite build --mode library",
|
|
37
|
+
"dev": "vite build --mode library --watch",
|
|
38
|
+
"clean": "rm -rf dist",
|
|
39
|
+
"typecheck": "tsc --noEmit",
|
|
40
|
+
"test": "cd tests && pnpm test",
|
|
41
|
+
"test:watch": "cd tests && pnpm run test:watch",
|
|
42
|
+
"test:e2e": "cd tests && pnpm run test:e2e",
|
|
43
|
+
"test:perf": "cd tests && pnpm run test:perf"
|
|
44
|
+
},
|
|
34
45
|
"peerDependencies": {
|
|
35
46
|
"@webgpu/types": "*"
|
|
36
47
|
},
|
|
@@ -47,15 +58,5 @@
|
|
|
47
58
|
"typescript": "^5.0.0",
|
|
48
59
|
"vite": "^5.0.0",
|
|
49
60
|
"vite-plugin-dts": "^4.5.4"
|
|
50
|
-
},
|
|
51
|
-
"scripts": {
|
|
52
|
-
"build": "SDK_BUILD=true vite build --mode library",
|
|
53
|
-
"dev": "vite build --mode library --watch",
|
|
54
|
-
"clean": "rm -rf dist",
|
|
55
|
-
"typecheck": "tsc --noEmit",
|
|
56
|
-
"test": "cd tests && pnpm test",
|
|
57
|
-
"test:watch": "cd tests && pnpm run test:watch",
|
|
58
|
-
"test:e2e": "cd tests && pnpm run test:e2e",
|
|
59
|
-
"test:perf": "cd tests && pnpm run test:perf"
|
|
60
61
|
}
|
|
61
|
-
}
|
|
62
|
+
}
|