distark-render 1.0.0 → 1.0.1
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/README.md +0 -2
- package/dist/modules/adapters/p5Renderer.d.ts +71 -0
- package/dist/modules/adapters/p5Renderer.d.ts.map +1 -0
- package/dist/modules/adapters/p5Renderer.js +145 -0
- package/dist/modules/adapters/p5Renderer.js.map +1 -0
- package/dist/modules/adapters/skiaRenderer.d.ts +84 -0
- package/dist/modules/adapters/skiaRenderer.d.ts.map +1 -0
- package/dist/modules/adapters/skiaRenderer.js +251 -0
- package/dist/modules/adapters/skiaRenderer.js.map +1 -0
- package/dist/modules/eyeSystem.d.ts.map +1 -1
- package/dist/modules/eyeSystem.js +0 -10
- package/dist/modules/eyeSystem.js.map +1 -1
- package/dist/modules/imageLoad.d.ts +4 -1
- package/dist/modules/imageLoad.d.ts.map +1 -1
- package/dist/modules/imageLoad.js +49 -19
- package/dist/modules/imageLoad.js.map +1 -1
- package/dist/modules/renderRig.d.ts +1 -1
- package/dist/modules/renderRig.d.ts.map +1 -1
- package/dist/modules/renderRig.js +61 -36
- package/dist/modules/renderRig.js.map +1 -1
- package/dist/test-skia.d.ts +4 -7
- package/dist/test-skia.d.ts.map +1 -1
- package/dist/test-skia.js +23 -169
- package/dist/test-skia.js.map +1 -1
- package/package.json +18 -2
package/README.md
CHANGED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* p5.js Renderer - Pre-built adapter for p5.js
|
|
3
|
+
* Reduces setup from ~80 lines to ~3 lines
|
|
4
|
+
*/
|
|
5
|
+
import { ImageLoader } from '../imageLoad.js';
|
|
6
|
+
import { CharacterRigRenderer } from '../renderRig.js';
|
|
7
|
+
import type { RigData, RenderOptions, RigRenderData } from '../../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* p5-specific image loader
|
|
10
|
+
* Extends ImageLoader to use p5.loadImage instead of browser Image API
|
|
11
|
+
*/
|
|
12
|
+
export declare class P5ImageLoader extends ImageLoader {
|
|
13
|
+
private p5;
|
|
14
|
+
constructor(p5Instance: any, baseHost?: string);
|
|
15
|
+
/**
|
|
16
|
+
* Override to use p5.loadImage
|
|
17
|
+
* Inherits all caching, URL resolution, and batch loading from base class
|
|
18
|
+
*/
|
|
19
|
+
loadImage(key: string, imageData: string, onLoad?: (key: string, img: any) => void, onError?: (key: string, error: Event | string) => void): void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* p5.js Renderer - Complete rendering solution for p5.js
|
|
23
|
+
*
|
|
24
|
+
* Usage:
|
|
25
|
+
* const renderer = new P5Renderer(p);
|
|
26
|
+
* await renderer.loadImages(rigData);
|
|
27
|
+
* renderer.render(rigData, { width: 800, height: 800 });
|
|
28
|
+
*
|
|
29
|
+
* Advanced Usage (full p5 control):
|
|
30
|
+
* const renderData = renderer.compute(rigData, options);
|
|
31
|
+
* // Modify renderData.objects as needed
|
|
32
|
+
* renderer.renderObjects(renderData.objects);
|
|
33
|
+
*/
|
|
34
|
+
export declare class P5Renderer extends CharacterRigRenderer {
|
|
35
|
+
private p5;
|
|
36
|
+
private loadedImages;
|
|
37
|
+
private isReady;
|
|
38
|
+
constructor(p5Instance: any, baseHost?: string);
|
|
39
|
+
/**
|
|
40
|
+
* Load all images for a character rig
|
|
41
|
+
* Must be called before renderRig()
|
|
42
|
+
*/
|
|
43
|
+
loadImages(rigData: RigData): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Compute rig render data (for advanced control)
|
|
46
|
+
* Returns the computed transforms that you can modify before rendering
|
|
47
|
+
*/
|
|
48
|
+
compute(rigData: RigData, options?: Partial<RenderOptions>): RigRenderData;
|
|
49
|
+
/**
|
|
50
|
+
* Render objects to p5 canvas
|
|
51
|
+
* Can be used with modified render data for custom effects
|
|
52
|
+
*/
|
|
53
|
+
renderObjects(objects: any[], showPivots?: boolean, pivotPoints?: any[]): void;
|
|
54
|
+
/**
|
|
55
|
+
* Simple one-line render (compute + renderObjects)
|
|
56
|
+
*
|
|
57
|
+
* @param rigData - Character rig data
|
|
58
|
+
* @param options - Render options (width, height, camera offset)
|
|
59
|
+
* @param showPivots - Whether to show pivot points for debugging
|
|
60
|
+
*/
|
|
61
|
+
renderRig(rigData: RigData, options?: Partial<RenderOptions>, showPivots?: boolean): void;
|
|
62
|
+
/**
|
|
63
|
+
* Check if images are loaded and ready to render
|
|
64
|
+
*/
|
|
65
|
+
ready(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Get loaded images (for custom rendering)
|
|
68
|
+
*/
|
|
69
|
+
getLoadedImages(): Record<string, any>;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=p5Renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"p5Renderer.d.ts","sourceRoot":"","sources":["../../../modules/adapters/p5Renderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE5E;;;GAGG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC1C,OAAO,CAAC,EAAE,CAAM;gBAEJ,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM;IAK9C;;;OAGG;IACH,SAAS,CACL,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,EACxC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,KAAK,IAAI,GACvD,IAAI;CA6BV;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,UAAW,SAAQ,oBAAoB;IAChD,OAAO,CAAC,EAAE,CAAM;IAChB,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,OAAO,CAAkB;gBAErB,UAAU,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM;IAM9C;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa;IAe1E;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,UAAU,GAAE,OAAe,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IA6BrF;;;;;;OAMG;IACH,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,UAAU,GAAE,OAAe,GAAG,IAAI;IAKhG;;OAEG;IACH,KAAK,IAAI,OAAO;IAIhB;;OAEG;IACH,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGzC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* p5.js Renderer - Pre-built adapter for p5.js
|
|
3
|
+
* Reduces setup from ~80 lines to ~3 lines
|
|
4
|
+
*/
|
|
5
|
+
import { ImageLoader } from '../imageLoad.js';
|
|
6
|
+
import { CharacterRigRenderer } from '../renderRig.js';
|
|
7
|
+
/**
|
|
8
|
+
* p5-specific image loader
|
|
9
|
+
* Extends ImageLoader to use p5.loadImage instead of browser Image API
|
|
10
|
+
*/
|
|
11
|
+
export class P5ImageLoader extends ImageLoader {
|
|
12
|
+
constructor(p5Instance, baseHost) {
|
|
13
|
+
super(baseHost);
|
|
14
|
+
this.p5 = p5Instance;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Override to use p5.loadImage
|
|
18
|
+
* Inherits all caching, URL resolution, and batch loading from base class
|
|
19
|
+
*/
|
|
20
|
+
loadImage(key, imageData, onLoad, onError) {
|
|
21
|
+
const imageUrl = this.resolveImageSource(imageData);
|
|
22
|
+
if (!imageUrl) {
|
|
23
|
+
console.warn(`Could not resolve image source for ${key}: ${imageData}`);
|
|
24
|
+
if (onError)
|
|
25
|
+
onError(key, 'Invalid image source');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Check cache first (from base class)
|
|
29
|
+
const cached = this.getCachedImage(key);
|
|
30
|
+
if (cached) {
|
|
31
|
+
if (onLoad)
|
|
32
|
+
onLoad(key, cached);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// Use p5.loadImage
|
|
36
|
+
this.p5.loadImage(imageUrl, (img) => {
|
|
37
|
+
this.cacheImage(key, img);
|
|
38
|
+
if (onLoad)
|
|
39
|
+
onLoad(key, img);
|
|
40
|
+
}, (err) => {
|
|
41
|
+
console.error(`Failed to load ${key}:`, err);
|
|
42
|
+
if (onError)
|
|
43
|
+
onError(key, err);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* p5.js Renderer - Complete rendering solution for p5.js
|
|
49
|
+
*
|
|
50
|
+
* Usage:
|
|
51
|
+
* const renderer = new P5Renderer(p);
|
|
52
|
+
* await renderer.loadImages(rigData);
|
|
53
|
+
* renderer.render(rigData, { width: 800, height: 800 });
|
|
54
|
+
*
|
|
55
|
+
* Advanced Usage (full p5 control):
|
|
56
|
+
* const renderData = renderer.compute(rigData, options);
|
|
57
|
+
* // Modify renderData.objects as needed
|
|
58
|
+
* renderer.renderObjects(renderData.objects);
|
|
59
|
+
*/
|
|
60
|
+
export class P5Renderer extends CharacterRigRenderer {
|
|
61
|
+
constructor(p5Instance, baseHost) {
|
|
62
|
+
const imageLoader = new P5ImageLoader(p5Instance, baseHost);
|
|
63
|
+
super(imageLoader);
|
|
64
|
+
this.loadedImages = {};
|
|
65
|
+
this.isReady = false;
|
|
66
|
+
this.p5 = p5Instance;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Load all images for a character rig
|
|
70
|
+
* Must be called before renderRig()
|
|
71
|
+
*/
|
|
72
|
+
async loadImages(rigData) {
|
|
73
|
+
this.loadedImages = await this.imageLoader.loadAllRigImages(rigData, true);
|
|
74
|
+
this.isReady = true;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compute rig render data (for advanced control)
|
|
78
|
+
* Returns the computed transforms that you can modify before rendering
|
|
79
|
+
*/
|
|
80
|
+
compute(rigData, options) {
|
|
81
|
+
if (!this.isReady) {
|
|
82
|
+
throw new Error('Images not loaded. Call loadImages() first.');
|
|
83
|
+
}
|
|
84
|
+
const renderOptions = {
|
|
85
|
+
canvasWidth: options?.canvasWidth ?? this.p5.width,
|
|
86
|
+
canvasHeight: options?.canvasHeight ?? this.p5.height,
|
|
87
|
+
cameraOffset: options?.cameraOffset ?? { x: 0, y: 0 },
|
|
88
|
+
loadedImages: this.loadedImages
|
|
89
|
+
};
|
|
90
|
+
return this.computeCharacterRigData(rigData, renderOptions);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Render objects to p5 canvas
|
|
94
|
+
* Can be used with modified render data for custom effects
|
|
95
|
+
*/
|
|
96
|
+
renderObjects(objects, showPivots = false, pivotPoints) {
|
|
97
|
+
objects.forEach(obj => {
|
|
98
|
+
if (!obj.imageData)
|
|
99
|
+
return;
|
|
100
|
+
this.p5.push();
|
|
101
|
+
this.p5.translate(obj.x, obj.y);
|
|
102
|
+
this.p5.rotate(obj.rotation);
|
|
103
|
+
this.p5.scale(obj.scaleX, obj.scaleY);
|
|
104
|
+
const drawX = -obj.width * obj.anchorX;
|
|
105
|
+
const drawY = -obj.height * obj.anchorY;
|
|
106
|
+
this.p5.image(obj.imageData, drawX, drawY, obj.width, obj.height);
|
|
107
|
+
this.p5.pop();
|
|
108
|
+
});
|
|
109
|
+
// Draw pivot points if requested
|
|
110
|
+
if (showPivots && pivotPoints) {
|
|
111
|
+
pivotPoints.forEach((pivot) => {
|
|
112
|
+
this.p5.push();
|
|
113
|
+
this.p5.fill(0, 150, 255, 230);
|
|
114
|
+
this.p5.stroke(0);
|
|
115
|
+
this.p5.strokeWeight(1);
|
|
116
|
+
this.p5.circle(pivot.x, pivot.y, 8);
|
|
117
|
+
this.p5.pop();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Simple one-line render (compute + renderObjects)
|
|
123
|
+
*
|
|
124
|
+
* @param rigData - Character rig data
|
|
125
|
+
* @param options - Render options (width, height, camera offset)
|
|
126
|
+
* @param showPivots - Whether to show pivot points for debugging
|
|
127
|
+
*/
|
|
128
|
+
renderRig(rigData, options, showPivots = false) {
|
|
129
|
+
const renderData = this.compute(rigData, options);
|
|
130
|
+
this.renderObjects(renderData.objects, showPivots, renderData.pivotPoints);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if images are loaded and ready to render
|
|
134
|
+
*/
|
|
135
|
+
ready() {
|
|
136
|
+
return this.isReady;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get loaded images (for custom rendering)
|
|
140
|
+
*/
|
|
141
|
+
getLoadedImages() {
|
|
142
|
+
return this.loadedImages;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=p5Renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"p5Renderer.js","sourceRoot":"","sources":["../../../modules/adapters/p5Renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skia Canvas Renderer - Pre-built adapter for Node.js/Skia
|
|
3
|
+
* Reduces setup from ~75 lines to ~4 lines
|
|
4
|
+
*/
|
|
5
|
+
import { ImageLoader } from '../imageLoad.js';
|
|
6
|
+
import { CharacterRigRenderer } from '../renderRig.js';
|
|
7
|
+
import type { RigData, RenderOptions, RigRenderData } from '../../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Skia-specific image loader
|
|
10
|
+
* Handles async image loading for Node.js canvas
|
|
11
|
+
*/
|
|
12
|
+
export declare class SkiaImageLoader extends ImageLoader {
|
|
13
|
+
constructor(baseHost?: string);
|
|
14
|
+
/**
|
|
15
|
+
* Async image loading for Skia Canvas
|
|
16
|
+
* Note: This requires the @napi-rs/canvas package's loadImage function
|
|
17
|
+
*/
|
|
18
|
+
loadImageAsync(key: string, imageData: string): Promise<any>;
|
|
19
|
+
loadAllRigImagesAsync(rigData: RigData): Promise<Record<string, any>>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Skia Canvas Renderer - Complete rendering solution for Node.js
|
|
23
|
+
*
|
|
24
|
+
* Simple Usage:
|
|
25
|
+
* const renderer = new SkiaRenderer();
|
|
26
|
+
* await renderer.renderToFile('output.png', rigData, { width: 800, height: 800 });
|
|
27
|
+
*
|
|
28
|
+
* Advanced Usage:
|
|
29
|
+
* const renderer = new SkiaRenderer();
|
|
30
|
+
* await renderer.loadImages(rigData);
|
|
31
|
+
* const canvas = renderer.createCanvas(800, 800);
|
|
32
|
+
* renderer.render(canvas, rigData);
|
|
33
|
+
* await canvas.saveAs('output.png');
|
|
34
|
+
*/
|
|
35
|
+
export declare class SkiaRenderer extends CharacterRigRenderer {
|
|
36
|
+
private loadedImages;
|
|
37
|
+
private isReady;
|
|
38
|
+
constructor(baseHost?: string);
|
|
39
|
+
/**
|
|
40
|
+
* Load all images for a character rig
|
|
41
|
+
*/
|
|
42
|
+
loadImages(rigData: RigData): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Create a Skia canvas
|
|
45
|
+
*/
|
|
46
|
+
createCanvas(width: number, height: number): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Compute rig render data (for advanced control)
|
|
49
|
+
*/
|
|
50
|
+
compute(rigData: RigData, options?: Partial<RenderOptions>): RigRenderData;
|
|
51
|
+
/**
|
|
52
|
+
* Render objects to canvas context
|
|
53
|
+
* Use this to render pre-computed and modified render data
|
|
54
|
+
*/
|
|
55
|
+
renderObjects(ctx: any, objects: any[], showPivots?: boolean, pivotPoints?: any[]): void;
|
|
56
|
+
/**
|
|
57
|
+
* Render to a canvas (Skia Canvas 2D API)
|
|
58
|
+
* Computes render data and renders it
|
|
59
|
+
*/
|
|
60
|
+
renderToCanvas(canvas: any, rigData: RigData, options?: Partial<RenderOptions>, showPivots?: boolean): void;
|
|
61
|
+
/**
|
|
62
|
+
* One-liner: Render directly to file
|
|
63
|
+
*
|
|
64
|
+
* @param outputPath - Path to save PNG file
|
|
65
|
+
* @param rigData - Character rig data
|
|
66
|
+
* @param options - Render options (width, height, camera offset)
|
|
67
|
+
*/
|
|
68
|
+
renderToFile(outputPath: string, rigData: RigData, options?: Partial<RenderOptions> & {
|
|
69
|
+
showPivots?: boolean;
|
|
70
|
+
}): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Render to buffer (for streaming, HTTP responses, etc.)
|
|
73
|
+
*/
|
|
74
|
+
renderToBuffer(rigData: RigData, options?: Partial<RenderOptions>, format?: 'png' | 'jpeg'): Promise<Buffer>;
|
|
75
|
+
/**
|
|
76
|
+
* Check if images are loaded
|
|
77
|
+
*/
|
|
78
|
+
ready(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Get loaded images (for custom rendering)
|
|
81
|
+
*/
|
|
82
|
+
getLoadedImages(): Record<string, any>;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=skiaRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skiaRenderer.d.ts","sourceRoot":"","sources":["../../../modules/adapters/skiaRenderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE5E;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,WAAW;gBAChC,QAAQ,CAAC,EAAE,MAAM;IAI7B;;;OAGG;IACG,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IA+B5D,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAqD9E;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAa,SAAQ,oBAAoB;IAClD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,OAAO,CAAkB;gBAErB,QAAQ,CAAC,EAAE,MAAM;IAK7B;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjD;;OAEG;IACG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAa/D;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;IAe9E;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,UAAU,GAAE,OAAe,EAAE,WAAW,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IAgC/F;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EAAE,UAAU,GAAE,OAAe,GAAG,IAAI;IAgBlH;;;;;;OAMG;IACG,YAAY,CACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAC5D,OAAO,CAAC,IAAI,CAAC;IAoBhB;;OAEG;IACG,cAAc,CAChB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EAChC,MAAM,GAAE,KAAK,GAAG,MAAc,GAC/B,OAAO,CAAC,MAAM,CAAC;IAclB;;OAEG;IACH,KAAK,IAAI,OAAO;IAIhB;;OAEG;IACH,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CAGzC"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skia Canvas Renderer - Pre-built adapter for Node.js/Skia
|
|
3
|
+
* Reduces setup from ~75 lines to ~4 lines
|
|
4
|
+
*/
|
|
5
|
+
import { ImageLoader } from '../imageLoad.js';
|
|
6
|
+
import { CharacterRigRenderer } from '../renderRig.js';
|
|
7
|
+
/**
|
|
8
|
+
* Skia-specific image loader
|
|
9
|
+
* Handles async image loading for Node.js canvas
|
|
10
|
+
*/
|
|
11
|
+
export class SkiaImageLoader extends ImageLoader {
|
|
12
|
+
constructor(baseHost) {
|
|
13
|
+
super(baseHost);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Async image loading for Skia Canvas
|
|
17
|
+
* Note: This requires the @napi-rs/canvas package's loadImage function
|
|
18
|
+
*/
|
|
19
|
+
async loadImageAsync(key, imageData) {
|
|
20
|
+
const imageUrl = this.resolveImageSource(imageData);
|
|
21
|
+
if (!imageUrl) {
|
|
22
|
+
throw new Error(`Could not resolve image source for ${key}: ${imageData}`);
|
|
23
|
+
}
|
|
24
|
+
// Check cache first
|
|
25
|
+
const cached = this.getCachedImage(key);
|
|
26
|
+
if (cached) {
|
|
27
|
+
return cached;
|
|
28
|
+
}
|
|
29
|
+
// Dynamic import to avoid browser compatibility issues
|
|
30
|
+
let loadImage;
|
|
31
|
+
try {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
33
|
+
// @ts-ignore - Optional dependency
|
|
34
|
+
const module = await import('@napi-rs/canvas');
|
|
35
|
+
loadImage = module.loadImage;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Fallback to skia-canvas if @napi-rs/canvas is not available
|
|
39
|
+
const module = await import('skia-canvas');
|
|
40
|
+
loadImage = module.loadImage;
|
|
41
|
+
}
|
|
42
|
+
const img = await loadImage(imageUrl);
|
|
43
|
+
this.cacheImage(key, img);
|
|
44
|
+
return img;
|
|
45
|
+
}
|
|
46
|
+
async loadAllRigImagesAsync(rigData) {
|
|
47
|
+
const imagesToLoad = [];
|
|
48
|
+
// Collect all unique image paths from imagePaths
|
|
49
|
+
// CHANGED: We now ONLY track the actual path/hash, not semantic keys
|
|
50
|
+
if (rigData.imagePaths) {
|
|
51
|
+
for (const [, hash] of Object.entries(rigData.imagePaths)) {
|
|
52
|
+
if (hash && typeof hash === 'string' && !hash.includes('[MEDIA_REMOVED]')) {
|
|
53
|
+
// Only add if not already in list (deduplicate)
|
|
54
|
+
if (!imagesToLoad.find(item => item.hash === hash)) {
|
|
55
|
+
imagesToLoad.push({ hash });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Collect all eye images
|
|
61
|
+
if (rigData.eyes) {
|
|
62
|
+
for (const [eyeKey, value] of Object.entries(rigData.eyes)) {
|
|
63
|
+
if (typeof value === 'string' && !value.includes('[MEDIA_REMOVED]') &&
|
|
64
|
+
(eyeKey.includes('Image') || eyeKey.includes('Iris') || eyeKey.includes('Lid'))) {
|
|
65
|
+
// Only add if not already in list (deduplicate)
|
|
66
|
+
if (!imagesToLoad.find(item => item.hash === value)) {
|
|
67
|
+
imagesToLoad.push({ hash: value });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
console.log(`📦 Loading ${imagesToLoad.length} images for character rig...`);
|
|
73
|
+
const loadedImages = {};
|
|
74
|
+
let loaded = 0;
|
|
75
|
+
let failed = 0;
|
|
76
|
+
// Load all images in parallel
|
|
77
|
+
await Promise.all(imagesToLoad.map(async ({ hash }) => {
|
|
78
|
+
// CRITICAL: Use the actual path/hash as the cache key!
|
|
79
|
+
const img = await this.loadImageAsync(hash, hash);
|
|
80
|
+
if (img) {
|
|
81
|
+
loadedImages[hash] = img; // Cache by actual path, not semantic key!
|
|
82
|
+
loaded++;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
failed++;
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
console.log(`✓ Loaded ${loaded}/${imagesToLoad.length} images (${failed} failed)`);
|
|
89
|
+
console.log('📦 Image Cache (indexed by actual paths):', Object.keys(loadedImages).map(k => k.substring(0, 50)));
|
|
90
|
+
return loadedImages;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Skia Canvas Renderer - Complete rendering solution for Node.js
|
|
95
|
+
*
|
|
96
|
+
* Simple Usage:
|
|
97
|
+
* const renderer = new SkiaRenderer();
|
|
98
|
+
* await renderer.renderToFile('output.png', rigData, { width: 800, height: 800 });
|
|
99
|
+
*
|
|
100
|
+
* Advanced Usage:
|
|
101
|
+
* const renderer = new SkiaRenderer();
|
|
102
|
+
* await renderer.loadImages(rigData);
|
|
103
|
+
* const canvas = renderer.createCanvas(800, 800);
|
|
104
|
+
* renderer.render(canvas, rigData);
|
|
105
|
+
* await canvas.saveAs('output.png');
|
|
106
|
+
*/
|
|
107
|
+
export class SkiaRenderer extends CharacterRigRenderer {
|
|
108
|
+
constructor(baseHost) {
|
|
109
|
+
const imageLoader = new SkiaImageLoader(baseHost);
|
|
110
|
+
super(imageLoader);
|
|
111
|
+
this.loadedImages = {};
|
|
112
|
+
this.isReady = false;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Load all images for a character rig
|
|
116
|
+
*/
|
|
117
|
+
async loadImages(rigData) {
|
|
118
|
+
const loader = this.getImageLoader();
|
|
119
|
+
this.loadedImages = await loader.loadAllRigImagesAsync(rigData);
|
|
120
|
+
this.isReady = true;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create a Skia canvas
|
|
124
|
+
*/
|
|
125
|
+
async createCanvas(width, height) {
|
|
126
|
+
try {
|
|
127
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
128
|
+
// @ts-ignore - Optional dependency
|
|
129
|
+
const module = await import('@napi-rs/canvas');
|
|
130
|
+
return module.createCanvas(width, height);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Fallback to skia-canvas
|
|
134
|
+
const module = await import('skia-canvas');
|
|
135
|
+
return module.Canvas ? new module.Canvas(width, height) : module.createCanvas(width, height);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Compute rig render data (for advanced control)
|
|
140
|
+
*/
|
|
141
|
+
compute(rigData, options = {}) {
|
|
142
|
+
if (!this.isReady) {
|
|
143
|
+
throw new Error('Images not loaded. Call loadImages() first.');
|
|
144
|
+
}
|
|
145
|
+
const renderOptions = {
|
|
146
|
+
canvasWidth: options.canvasWidth ?? 800,
|
|
147
|
+
canvasHeight: options.canvasHeight ?? 800,
|
|
148
|
+
cameraOffset: options.cameraOffset ?? { x: 0, y: 0 },
|
|
149
|
+
loadedImages: this.loadedImages
|
|
150
|
+
};
|
|
151
|
+
return this.computeCharacterRigData(rigData, renderOptions);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Render objects to canvas context
|
|
155
|
+
* Use this to render pre-computed and modified render data
|
|
156
|
+
*/
|
|
157
|
+
renderObjects(ctx, objects, showPivots = false, pivotPoints) {
|
|
158
|
+
objects.forEach(obj => {
|
|
159
|
+
if (!obj.imageData)
|
|
160
|
+
return;
|
|
161
|
+
ctx.save();
|
|
162
|
+
ctx.translate(obj.x, obj.y);
|
|
163
|
+
ctx.rotate(obj.rotation);
|
|
164
|
+
ctx.scale(obj.scaleX, obj.scaleY);
|
|
165
|
+
const drawX = -obj.width * obj.anchorX;
|
|
166
|
+
const drawY = -obj.height * obj.anchorY;
|
|
167
|
+
ctx.drawImage(obj.imageData, drawX, drawY, obj.width, obj.height);
|
|
168
|
+
ctx.restore();
|
|
169
|
+
});
|
|
170
|
+
// Draw pivot points if requested
|
|
171
|
+
if (showPivots && pivotPoints) {
|
|
172
|
+
pivotPoints.forEach(pivot => {
|
|
173
|
+
ctx.save();
|
|
174
|
+
ctx.fillStyle = 'rgba(0, 150, 255, 0.9)';
|
|
175
|
+
ctx.strokeStyle = '#000';
|
|
176
|
+
ctx.lineWidth = 1;
|
|
177
|
+
ctx.beginPath();
|
|
178
|
+
ctx.arc(pivot.x, pivot.y, 4, 0, Math.PI * 2);
|
|
179
|
+
ctx.fill();
|
|
180
|
+
ctx.stroke();
|
|
181
|
+
ctx.restore();
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Render to a canvas (Skia Canvas 2D API)
|
|
187
|
+
* Computes render data and renders it
|
|
188
|
+
*/
|
|
189
|
+
renderToCanvas(canvas, rigData, options, showPivots = false) {
|
|
190
|
+
const ctx = canvas.getContext('2d');
|
|
191
|
+
const renderData = this.compute(rigData, {
|
|
192
|
+
...options,
|
|
193
|
+
canvasWidth: canvas.width,
|
|
194
|
+
canvasHeight: canvas.height
|
|
195
|
+
});
|
|
196
|
+
// Clear canvas
|
|
197
|
+
ctx.fillStyle = '#f0f0f0';
|
|
198
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
199
|
+
// Render using renderObjects
|
|
200
|
+
this.renderObjects(ctx, renderData.objects, showPivots, renderData.pivotPoints);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* One-liner: Render directly to file
|
|
204
|
+
*
|
|
205
|
+
* @param outputPath - Path to save PNG file
|
|
206
|
+
* @param rigData - Character rig data
|
|
207
|
+
* @param options - Render options (width, height, camera offset)
|
|
208
|
+
*/
|
|
209
|
+
async renderToFile(outputPath, rigData, options) {
|
|
210
|
+
// Load images if not already loaded
|
|
211
|
+
if (!this.isReady) {
|
|
212
|
+
await this.loadImages(rigData);
|
|
213
|
+
}
|
|
214
|
+
// Create canvas
|
|
215
|
+
const width = options?.canvasWidth ?? 800;
|
|
216
|
+
const height = options?.canvasHeight ?? 800;
|
|
217
|
+
const canvas = await this.createCanvas(width, height);
|
|
218
|
+
// Render
|
|
219
|
+
this.renderToCanvas(canvas, rigData, options, options?.showPivots);
|
|
220
|
+
// Save to file
|
|
221
|
+
const fs = await import('fs/promises');
|
|
222
|
+
const buffer = await canvas.toBuffer('image/png');
|
|
223
|
+
await fs.writeFile(outputPath, buffer);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Render to buffer (for streaming, HTTP responses, etc.)
|
|
227
|
+
*/
|
|
228
|
+
async renderToBuffer(rigData, options, format = 'png') {
|
|
229
|
+
if (!this.isReady) {
|
|
230
|
+
await this.loadImages(rigData);
|
|
231
|
+
}
|
|
232
|
+
const width = options?.canvasWidth ?? 800;
|
|
233
|
+
const height = options?.canvasHeight ?? 800;
|
|
234
|
+
const canvas = await this.createCanvas(width, height);
|
|
235
|
+
this.renderToCanvas(canvas, rigData, options);
|
|
236
|
+
return await canvas.toBuffer(`image/${format}`);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Check if images are loaded
|
|
240
|
+
*/
|
|
241
|
+
ready() {
|
|
242
|
+
return this.isReady;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get loaded images (for custom rendering)
|
|
246
|
+
*/
|
|
247
|
+
getLoadedImages() {
|
|
248
|
+
return this.loadedImages;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=skiaRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skiaRenderer.js","sourceRoot":"","sources":["../../../modules/adapters/skiaRenderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eyeSystem.d.ts","sourceRoot":"","sources":["../../modules/eyeSystem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,OAAO,EACP,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACX,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,qBAAa,SAAS;IAClB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAWzC;IAEF;;;;OAIG;gBACS,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAwBjD;;OAEG;IACH,QAAQ,IAAI,QAAQ;IAIpB;;OAEG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQtC;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"eyeSystem.d.ts","sourceRoot":"","sources":["../../modules/eyeSystem.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACR,OAAO,EACP,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACX,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,qBAAa,SAAS;IAClB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAWzC;IAEF;;;;OAIG;gBACS,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAwBjD;;OAEG;IACH,QAAQ,IAAI,QAAQ;IAIpB;;OAEG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQtC;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAuCzC;;;;OAIG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAsCzE;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAiB9C;;;;OAIG;IACH,4BAA4B,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,GAAE,QAAyB,GAAG,YAAY;IAoBxG;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAMzB;;;;;;OAMG;IACH,MAAM,CACF,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,OAAe,EAC1B,oBAAoB,CAAC,EAAE,QAAQ,EAC/B,YAAY,GAAE,QAAyB,GACxC,IAAI;IA0CP;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM;IAejD;;OAEG;IACH,gBAAgB,IAAI;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,KAAK,EAAE,QAAQ,CAAA;KAAE;IAOvD;;OAEG;IACH,cAAc,IAAI,WAAW;IAI7B;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI5C;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIxC;;OAEG;IACH,UAAU,IAAI,IAAI;IAMlB;;OAEG;IACH,YAAY,IAAI,MAAM;CAQzB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAEhF"}
|
|
@@ -62,11 +62,8 @@ export class EyeSystem {
|
|
|
62
62
|
// Initialize blink timing if needed
|
|
63
63
|
if (this.state.eyeLidLastUpdatedTime === null) {
|
|
64
64
|
this.state.eyeLidLastUpdatedTime = currentTime - this.state.eyeLidUpdateInterval + this.state.nextBlinkOffset;
|
|
65
|
-
console.log(`🔧 [${this.characterId}] Blink timing initialized - eyeLidLastUpdatedTime: ${this.state.eyeLidLastUpdatedTime.toFixed(2)}s, interval: ${this.state.eyeLidUpdateInterval.toFixed(2)}s`);
|
|
66
65
|
}
|
|
67
66
|
const timeSinceBlink = currentTime - this.state.eyeLidLastUpdatedTime;
|
|
68
|
-
const oldState = this.state.currentEyeLidState;
|
|
69
|
-
console.log(`⏱️ [${this.characterId}] updateBlinking - currentTime: ${currentTime.toFixed(2)}s, timeSinceBlink: ${timeSinceBlink.toFixed(2)}s, interval: ${this.state.eyeLidUpdateInterval.toFixed(2)}s, currentState: ${this.state.currentEyeLidState}`);
|
|
70
67
|
// Check if it's time to start a new blink
|
|
71
68
|
if (timeSinceBlink >= this.state.eyeLidUpdateInterval) {
|
|
72
69
|
this.state.currentEyeLidCount = 1; // Start blinking
|
|
@@ -99,10 +96,6 @@ export class EyeSystem {
|
|
|
99
96
|
else {
|
|
100
97
|
this.state.currentEyeLidState = 'open';
|
|
101
98
|
}
|
|
102
|
-
// Log when eyelid state changes
|
|
103
|
-
if (oldState !== this.state.currentEyeLidState) {
|
|
104
|
-
console.log(`👁️ [${this.characterId}] Eyelid: ${oldState} → ${this.state.currentEyeLidState}`);
|
|
105
|
-
}
|
|
106
99
|
}
|
|
107
100
|
/**
|
|
108
101
|
* Update eye gaze direction
|
|
@@ -202,14 +195,11 @@ export class EyeSystem {
|
|
|
202
195
|
* @param characterPos - This character's position
|
|
203
196
|
*/
|
|
204
197
|
update(currentTime, isPlaying = false, speakingCharacterPos, characterPos = { x: 0, y: 0 }) {
|
|
205
|
-
console.log(`🔍 [${this.characterId}] EyeSystem.update called - time: ${currentTime.toFixed(2)}s, isPlaying: ${isPlaying}`);
|
|
206
198
|
// Handle timeline reset
|
|
207
199
|
if (currentTime < 0.1 || this.detectReset(currentTime)) {
|
|
208
|
-
console.log(`🔄 [${this.characterId}] Timeline reset detected, resetting timing`);
|
|
209
200
|
this.resetTiming(currentTime);
|
|
210
201
|
}
|
|
211
202
|
// Always update blinking (works even when paused)
|
|
212
|
-
console.log(`👁️ [${this.characterId}] Calling updateBlinking...`);
|
|
213
203
|
this.updateBlinking(currentTime);
|
|
214
204
|
// Eye movement only when playing
|
|
215
205
|
if (!isPlaying) {
|