distark-render 1.0.0

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.
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Image Loading Module
3
+ * Handles loading images from MD5 hashes or URLs with caching support
4
+ */
5
+ /**
6
+ * ImageLoader class - Handles loading and caching images for character rigs
7
+ */
8
+ export class ImageLoader {
9
+ /**
10
+ * Creates a new ImageLoader instance
11
+ * @param baseHost - The base URL for the API (default: 'https://orchestrator.distark.com')
12
+ */
13
+ constructor(baseHost = 'https://orchestrator.distark.com') {
14
+ this.baseHost = baseHost;
15
+ this.imageCache = new Map();
16
+ }
17
+ /**
18
+ * Set the base host for image loading
19
+ * @param host - The base URL for the API
20
+ */
21
+ setBaseHost(host) {
22
+ this.baseHost = host;
23
+ }
24
+ /**
25
+ * Get the current base host
26
+ * @returns The current base host URL
27
+ */
28
+ getBaseHost() {
29
+ return this.baseHost;
30
+ }
31
+ /**
32
+ * Resolve an image source (hash or URL) to a full URL
33
+ * @param imageData - Image hash, URL, or data URL
34
+ * @returns Full URL or null if invalid
35
+ */
36
+ resolveImageSource(imageData) {
37
+ if (!imageData || typeof imageData !== 'string') {
38
+ return null;
39
+ }
40
+ // Check if it's an MD5 hash (32-character hex string)
41
+ const md5Regex = /^[a-f0-9]{32}$/i;
42
+ if (md5Regex.test(imageData)) {
43
+ return `${this.baseHost}/api/v1/artifacts/${imageData}`;
44
+ }
45
+ // Check if it's a truncated hash (ends with ...)
46
+ const truncatedHashRegex = /^[a-f0-9]{20,31}\.{3}$/i;
47
+ if (truncatedHashRegex.test(imageData)) {
48
+ const hash = imageData.replace(/\.{3}$/, '');
49
+ console.warn(`Truncated hash detected for ${imageData}, attempting to load with partial hash`);
50
+ return `${this.baseHost}/api/v1/artifacts/${hash}`;
51
+ }
52
+ // Return as-is for URLs and data URLs
53
+ if (imageData.startsWith('http://') ||
54
+ imageData.startsWith('https://') ||
55
+ imageData.startsWith('data:')) {
56
+ return imageData;
57
+ }
58
+ return null;
59
+ }
60
+ /**
61
+ * Load an image from a URL/hash and invoke callbacks
62
+ * @param key - Unique key for the image
63
+ * @param imageData - Image hash or URL
64
+ * @param onLoad - Callback when image loads successfully
65
+ * @param onError - Callback when image fails to load (optional)
66
+ */
67
+ loadImage(key, imageData, onLoad, onError) {
68
+ const imageUrl = this.resolveImageSource(imageData);
69
+ if (!imageUrl) {
70
+ console.warn(`Could not resolve image source for ${key}: ${imageData}`);
71
+ if (onError) {
72
+ onError(key, 'Invalid image source');
73
+ }
74
+ return;
75
+ }
76
+ console.log(`📥 Loading image for ${key} from: ${imageUrl.substring(0, 100)}...`);
77
+ const img = new Image();
78
+ img.crossOrigin = 'anonymous'; // Enable CORS
79
+ img.onload = () => {
80
+ console.log(`✓ Successfully loaded image for ${key} (${img.width}x${img.height})`);
81
+ if (onLoad) {
82
+ onLoad(key, img);
83
+ }
84
+ };
85
+ img.onerror = (err) => {
86
+ console.error(`✗ Failed to load image for ${key}`);
87
+ console.error(` URL: ${imageUrl}`);
88
+ console.error(` Error:`, err);
89
+ if (onError) {
90
+ onError(key, err);
91
+ }
92
+ };
93
+ img.src = imageUrl;
94
+ }
95
+ /**
96
+ * Load multiple images in parallel
97
+ * @param imagesToLoad - Array of {key, hash} objects
98
+ * @param onProgress - Optional callback for progress updates
99
+ * @returns Promise that resolves with loaded images map
100
+ */
101
+ async loadImages(imagesToLoad, onProgress) {
102
+ const loadedImages = {};
103
+ let loaded = 0;
104
+ let failed = 0;
105
+ const total = imagesToLoad.length;
106
+ const loadPromises = imagesToLoad.map(({ key, hash }) => {
107
+ return new Promise((resolve) => {
108
+ this.loadImage(key, hash, (loadedKey, img) => {
109
+ loadedImages[loadedKey] = img;
110
+ loaded++;
111
+ if (onProgress) {
112
+ onProgress(loaded, total, failed);
113
+ }
114
+ resolve();
115
+ }, () => {
116
+ failed++;
117
+ if (onProgress) {
118
+ onProgress(loaded, total, failed);
119
+ }
120
+ resolve();
121
+ });
122
+ });
123
+ });
124
+ await Promise.all(loadPromises);
125
+ return loadedImages;
126
+ }
127
+ /**
128
+ * Get the image cache
129
+ * @returns The image cache Map
130
+ */
131
+ getImageCache() {
132
+ return this.imageCache;
133
+ }
134
+ /**
135
+ * Clear the image cache
136
+ */
137
+ clearImageCache() {
138
+ this.imageCache.clear();
139
+ console.log('🗑️ Image cache cleared');
140
+ }
141
+ /**
142
+ * Get image from cache or return undefined
143
+ * @param key - Image key
144
+ */
145
+ getCachedImage(key) {
146
+ return this.imageCache.get(key);
147
+ }
148
+ /**
149
+ * Manually add image to cache
150
+ * @param key - Image key
151
+ * @param image - Image element
152
+ */
153
+ cacheImage(key, image) {
154
+ this.imageCache.set(key, image);
155
+ }
156
+ /**
157
+ * Load image with caching support
158
+ * Checks cache first, only loads if not cached
159
+ */
160
+ loadImageWithCache(key, imageData, onLoad, onError) {
161
+ // Check cache first
162
+ const cached = this.imageCache.get(key);
163
+ if (cached) {
164
+ console.log(`✓ Using cached image for ${key}`);
165
+ if (onLoad) {
166
+ onLoad(key, cached);
167
+ }
168
+ return;
169
+ }
170
+ // Not in cache, load it
171
+ this.loadImage(key, imageData, (loadedKey, img) => {
172
+ // Add to cache
173
+ this.imageCache.set(loadedKey, img);
174
+ console.log(`💾 Cached image for ${loadedKey}`);
175
+ if (onLoad) {
176
+ onLoad(loadedKey, img);
177
+ }
178
+ }, onError);
179
+ }
180
+ /**
181
+ * Load all images for a character rig and populate the cache
182
+ * @param rigData - Character rig data
183
+ * @param useCache - Whether to use existing cache (default: true)
184
+ * @param onProgress - Progress callback
185
+ * @returns Promise that resolves with the image cache as a plain object
186
+ */
187
+ async loadAllRigImages(rigData, useCache = true, onProgress) {
188
+ const imagesToLoad = [];
189
+ // Collect all image paths from imagePaths
190
+ if (rigData.imagePaths) {
191
+ for (const [key, hash] of Object.entries(rigData.imagePaths)) {
192
+ if (hash && typeof hash === 'string' && !hash.includes('[MEDIA_REMOVED]')) {
193
+ const imageKey = `imagePaths.${key}`;
194
+ // Skip if already in cache and useCache is true
195
+ if (!useCache || !this.imageCache.has(imageKey)) {
196
+ imagesToLoad.push({ key: imageKey, hash });
197
+ }
198
+ }
199
+ }
200
+ }
201
+ // Collect all eye images
202
+ if (rigData.eyes) {
203
+ for (const [key, value] of Object.entries(rigData.eyes)) {
204
+ if (typeof value === 'string' && !value.includes('[MEDIA_REMOVED]') &&
205
+ (key.includes('Image') || key.includes('Iris') || key.includes('Lid'))) {
206
+ const imageKey = `eyes.${key}`;
207
+ // Skip if already in cache and useCache is true
208
+ if (!useCache || !this.imageCache.has(imageKey)) {
209
+ imagesToLoad.push({ key: imageKey, hash: value });
210
+ }
211
+ }
212
+ }
213
+ }
214
+ console.log(`📦 Loading ${imagesToLoad.length} images for character rig...`);
215
+ let loaded = 0;
216
+ let failed = 0;
217
+ const total = imagesToLoad.length;
218
+ // If nothing to load, return cache immediately
219
+ if (total === 0) {
220
+ console.log('✓ All images already cached!');
221
+ const result = {};
222
+ this.imageCache.forEach((img, key) => {
223
+ result[key] = img;
224
+ });
225
+ console.log('📦 Image Cache:', result);
226
+ return result;
227
+ }
228
+ const loadPromises = imagesToLoad.map(({ key, hash }) => {
229
+ return new Promise((resolve) => {
230
+ this.loadImage(key, hash, (loadedKey, img) => {
231
+ this.imageCache.set(loadedKey, img);
232
+ loaded++;
233
+ if (onProgress) {
234
+ onProgress(loaded, total, failed);
235
+ }
236
+ resolve();
237
+ }, () => {
238
+ failed++;
239
+ if (onProgress) {
240
+ onProgress(loaded, total, failed);
241
+ }
242
+ resolve();
243
+ });
244
+ });
245
+ });
246
+ await Promise.all(loadPromises);
247
+ console.log(`✓ Loaded ${loaded}/${total} images (${failed} failed)`);
248
+ // Return cache as plain object
249
+ const result = {};
250
+ this.imageCache.forEach((img, key) => {
251
+ result[key] = img;
252
+ });
253
+ console.log('📦 Image Cache:', result);
254
+ return result;
255
+ }
256
+ }
257
+ // Export a default instance for backwards compatibility
258
+ export const defaultImageLoader = new ImageLoader();
259
+ //# sourceMappingURL=imageLoad.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imageLoad.js","sourceRoot":"","sources":["../../modules/imageLoad.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Mouth System Module
3
+ * Handles mouth animation based on audio volume, visemes, or manual control
4
+ *
5
+ * Note: This module does NOT handle rendering - it only manages state.
6
+ * The renderRig module handles actual rendering of mouth images.
7
+ */
8
+ /**
9
+ * Mouth shape types (viseme-based and general shapes)
10
+ */
11
+ export type MouthShape = 'closed' | 'slightly-open' | 'half-open' | 'ds' | 'open' | 'ee' | 'wide-open' | 'ah' | 'woo' | 'neutral';
12
+ /**
13
+ * Audio analysis data structure
14
+ */
15
+ export interface AudioAnalysisData {
16
+ analyser: AnalyserNode;
17
+ dataArray: Uint8Array<ArrayBuffer>;
18
+ audioElement: HTMLAudioElement;
19
+ }
20
+ /**
21
+ * Viseme mapping data (phoneme to mouth shape)
22
+ */
23
+ export interface VisemeData {
24
+ viseme: string;
25
+ timestamp: number;
26
+ }
27
+ /**
28
+ * Mouth animation mode
29
+ */
30
+ export type MouthAnimationMode = 'manual' | 'audio' | 'viseme';
31
+ /**
32
+ * Mouth data configuration
33
+ */
34
+ export interface MouthData {
35
+ mouthWidth?: number;
36
+ mouthHeight?: number;
37
+ mouthSize?: number;
38
+ mouthXCoor?: number;
39
+ mouthYCoor?: number;
40
+ [key: string]: number | undefined;
41
+ }
42
+ /**
43
+ * Mouth state
44
+ */
45
+ export interface MouthState {
46
+ currentMouthKey: MouthShape;
47
+ lastMouthChangeTime: number;
48
+ currentVolume: number;
49
+ mode: MouthAnimationMode;
50
+ }
51
+ /**
52
+ * Mouth configuration
53
+ */
54
+ export interface MouthConfig {
55
+ volumeThreshold?: number;
56
+ mouthChangeInterval?: number;
57
+ talkingMouths?: MouthShape[];
58
+ visemeMapping?: Record<string, MouthShape>;
59
+ }
60
+ /**
61
+ * MouthSystem class - Manages mouth animation state
62
+ */
63
+ export declare class MouthSystem {
64
+ private state;
65
+ private config;
66
+ private characterId;
67
+ private availableMouths;
68
+ /**
69
+ * Default viseme to mouth shape mapping
70
+ */
71
+ private static readonly DEFAULT_VISEME_MAPPING;
72
+ /**
73
+ * Default talking mouths (used for random audio-based animation)
74
+ */
75
+ private static readonly DEFAULT_TALKING_MOUTHS;
76
+ /**
77
+ * Creates a new MouthSystem instance
78
+ * @param characterId - Unique identifier for the character
79
+ * @param availableMouths - Set of available mouth shapes for this character
80
+ * @param config - Optional mouth configuration
81
+ */
82
+ constructor(characterId: string, availableMouths?: Set<MouthShape>, config?: MouthConfig);
83
+ /**
84
+ * Get current mouth state
85
+ */
86
+ getState(): MouthState;
87
+ /**
88
+ * Get current mouth shape
89
+ */
90
+ getCurrentMouth(): MouthShape;
91
+ /**
92
+ * Manually set mouth shape
93
+ */
94
+ setMouthShape(shape: MouthShape): void;
95
+ /**
96
+ * Set available mouth shapes
97
+ */
98
+ setAvailableMouths(mouths: MouthShape[]): void;
99
+ /**
100
+ * Update mouth animation based on audio volume
101
+ * @param currentTime - Current time in milliseconds
102
+ * @param audioData - Audio analysis data
103
+ */
104
+ updateFromAudio(currentTime: number, audioData: AudioAnalysisData): void;
105
+ /**
106
+ * Update mouth animation based on viseme data
107
+ * @param viseme - Viseme identifier (e.g., 'A', 'E', 'O')
108
+ */
109
+ updateFromViseme(viseme: string): void;
110
+ /**
111
+ * Reset mouth to neutral/closed state
112
+ */
113
+ reset(): void;
114
+ /**
115
+ * Get the image key for the current mouth shape
116
+ * This is used by renderRig to determine which image to render
117
+ *
118
+ * @returns The image key for the current mouth (e.g., 'imagePaths.mouth_open')
119
+ */
120
+ getCurrentMouthImageKey(): string;
121
+ /**
122
+ * Get all possible image key candidates for current mouth
123
+ * Used by renderRig to try multiple image name variations
124
+ */
125
+ getMouthImageKeyCandidates(): string[];
126
+ /**
127
+ * Get configuration
128
+ */
129
+ getConfig(): MouthConfig;
130
+ /**
131
+ * Update configuration
132
+ */
133
+ updateConfig(config: Partial<MouthConfig>): void;
134
+ /**
135
+ * Get debug information
136
+ */
137
+ getDebugInfo(): string;
138
+ }
139
+ /**
140
+ * Factory function to create mouth system
141
+ */
142
+ export declare function createMouthSystem(characterId: string, availableMouths?: MouthShape[], config?: MouthConfig): MouthSystem;
143
+ /**
144
+ * Helper: Extract available mouth shapes from rig data
145
+ */
146
+ export declare function extractMouthShapesFromRigData(rigData: any): MouthShape[];
147
+ //# sourceMappingURL=mouthSystem.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mouthSystem.d.ts","sourceRoot":"","sources":["../../modules/mouthSystem.ts"],"names":[],"mappings":"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"}