distark-render 1.1.5 → 1.1.6

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,204 +0,0 @@
1
- /**
2
- * Visual End-to-End Test: Part Hiding via hiddenValues
3
- *
4
- * Scenario
5
- * --------
6
- * A character rig has a rightHand limb whose image is solid RED (RGB 255,0,0).
7
- * Every other part has no image assigned, so only the rightHand can produce red pixels.
8
- *
9
- * Test 1 – Baseline (rightHand visible)
10
- * hiddenValues: {}
11
- * Expected: red pixels ARE present in the rendered canvas.
12
- * Purpose: Proves the test setup is valid (image pipeline works).
13
- *
14
- * Test 2 – Hidden (rightHand hidden)
15
- * hiddenValues: { rightHand: true }
16
- * Expected: ZERO red pixels in the rendered canvas.
17
- * This is the RED → GREEN test:
18
- * RED: renderRig.ts ignores hiddenValues → rightHand drawn → red pixels found → FAIL
19
- * GREEN: renderRig.ts respects hiddenValues → rightHand excluded → no red pixels → PASS
20
- *
21
- * Hand position trace (default rotations = 0, canvas 800×600)
22
- * ─────────────────────────────────────────────────────────────
23
- * character centre : (400, 400) [W/2, H/2+100]
24
- * shoulder pivot : (450, 400) [+50, 0]
25
- * rightUpperArm centre : (450, 360) [−40 along Y]
26
- * elbow pivot : (450, 320) [−80 upper arm height]
27
- * rightForearm centre : (450, 285) [−35 along Y]
28
- * wrist pivot : (450, 250) [−70 forearm height]
29
- * rightHand centre : (450, 210) [−40 along Y]
30
- * rightHand draw rect : x∈[410,490], y∈[170,250] ← well within canvas
31
- */
32
- import { CharacterRigRenderer } from '../modules/renderRig.js';
33
- import { writeFile, mkdir } from 'fs/promises';
34
- // ─── Constants ────────────────────────────────────────────────────────────────
35
- const CANVAS_W = 800;
36
- const CANVAS_H = 600;
37
- /** Image key used in loadedImages for the red rightHand canvas. */
38
- const RED_HAND_KEY = 'test://red-right-hand';
39
- let _createCanvas = null;
40
- async function getCreateCanvas() {
41
- if (_createCanvas)
42
- return _createCanvas;
43
- try {
44
- // @ts-ignore – optional peer dep
45
- const m = await import('@napi-rs/canvas'); // eslint-disable-line @typescript-eslint/no-explicit-any
46
- _createCanvas = m.createCanvas;
47
- }
48
- catch {
49
- // @ts-ignore – optional peer dep
50
- const m = await import('skia-canvas'); // eslint-disable-line @typescript-eslint/no-explicit-any
51
- _createCanvas = (m.createCanvas ?? ((w, h) => new m.Canvas(w, h)));
52
- }
53
- return _createCanvas;
54
- }
55
- // ─── Pixel helpers ────────────────────────────────────────────────────────────
56
- /**
57
- * Count pixels that are "clearly red": r>200, g<50, b<50, not transparent.
58
- * The threshold tolerates minor sub-pixel anti-aliasing.
59
- */
60
- function countRedPixels(data) {
61
- let n = 0;
62
- for (let i = 0; i < data.length; i += 4) {
63
- if (data[i] > 200 && data[i + 1] < 50 && data[i + 2] < 50 && data[i + 3] > 0)
64
- n++;
65
- }
66
- return n;
67
- }
68
- // ─── Rig factory ──────────────────────────────────────────────────────────────
69
- /**
70
- * Build a minimal RigData where ONLY rightHand has an image (solid red).
71
- * All other image slots are empty so only rightHand can produce red pixels.
72
- *
73
- * @param hidden - when true, sets hiddenValues: { rightHand: true }
74
- */
75
- function makeTestRig(hidden) {
76
- return {
77
- id: 'hidden-parts-test',
78
- imagePaths: {
79
- rightHand: RED_HAND_KEY, // only rightHand has an image
80
- },
81
- rotationValues: {},
82
- selfRotationValues: {},
83
- dimensionValues: {
84
- rightUpperArm: { width: 30, height: 80 },
85
- rightForearm: { width: 25, height: 70 },
86
- rightHand: { width: 80, height: 80 },
87
- },
88
- pivotPoints: {
89
- 'torso_rightUpperArm': { x: 50, y: 0 },
90
- 'rightUpperArm_rightForearm': { x: 0, y: 0 },
91
- 'rightForearm_rightHand': { x: 0, y: 0 },
92
- },
93
- zIndexValues: {},
94
- hiddenValues: hidden ? { rightHand: true } : {},
95
- jointOffset: {},
96
- eyes: {},
97
- };
98
- }
99
- // ─── Render helper ────────────────────────────────────────────────────────────
100
- /**
101
- * Render `rigData` onto a fresh canvas and return the canvas.
102
- * Saves a debug PNG to test-outputs/.
103
- */
104
- async function renderRig(createCanvas, rigData, redHandCanvas, label) {
105
- const canvas = createCanvas(CANVAS_W, CANVAS_H);
106
- const ctx = canvas.getContext('2d');
107
- // Fill background with distark_render's default grey
108
- ctx.fillStyle = '#f0f0f0';
109
- ctx.fillRect(0, 0, CANVAS_W, CANVAS_H);
110
- const loadedImages = {
111
- [RED_HAND_KEY]: redHandCanvas,
112
- };
113
- const renderer = new CharacterRigRenderer();
114
- const renderOptions = {
115
- canvasWidth: CANVAS_W,
116
- canvasHeight: CANVAS_H,
117
- loadedImages: loadedImages,
118
- };
119
- const { objects } = renderer.computeCharacterRigData(rigData, renderOptions);
120
- for (const obj of objects) {
121
- if (!obj.imageData)
122
- continue;
123
- ctx.save();
124
- ctx.translate(obj.x, obj.y);
125
- ctx.rotate(obj.rotation);
126
- ctx.scale(obj.scaleX, obj.scaleY);
127
- ctx.drawImage(obj.imageData, -obj.width * obj.anchorX, -obj.height * obj.anchorY, obj.width, obj.height);
128
- ctx.restore();
129
- }
130
- // Persist debug PNG
131
- await mkdir('test-outputs', { recursive: true });
132
- const buf = await canvas.toBuffer('image/png');
133
- await writeFile(`test-outputs/hidden-parts-${label}.png`, buf);
134
- console.log(` 📷 Saved test-outputs/hidden-parts-${label}.png`);
135
- return canvas;
136
- }
137
- // ─── Main ─────────────────────────────────────────────────────────────────────
138
- async function main() {
139
- console.log('\n🧪 Hidden Parts — Visual E2E Test');
140
- console.log('='.repeat(54));
141
- console.log('Character: rightHand limb → solid RED image (255,0,0)');
142
- console.log('All other parts: no image assigned');
143
- console.log('Test: hiddenValues.rightHand=true must produce ZERO red pixels\n');
144
- const createCanvas = await getCreateCanvas();
145
- // Build a solid-red 80×80 canvas that represents the rightHand image
146
- const redHandCanvas = createCanvas(80, 80);
147
- const rctx = redHandCanvas.getContext('2d');
148
- rctx.fillStyle = 'rgb(255,0,0)';
149
- rctx.fillRect(0, 0, 80, 80);
150
- let passed = 0;
151
- let failed = 0;
152
- // ── Test 1: Baseline — rightHand IS visible ─────────────────────────────
153
- console.log('[1/2] Baseline — no hiddenValues (rightHand should be visible)');
154
- {
155
- const rig = makeTestRig(false);
156
- const canvas = await renderRig(createCanvas, rig, redHandCanvas, 'baseline');
157
- const ctx = canvas.getContext('2d');
158
- const { data } = ctx.getImageData(0, 0, CANVAS_W, CANVAS_H);
159
- const redCount = countRedPixels(data);
160
- if (redCount > 0) {
161
- console.log(` ✅ PASS — ${redCount} red pixels found; rightHand rendered correctly`);
162
- passed++;
163
- }
164
- else {
165
- console.log(' ❌ FAIL — 0 red pixels; rightHand image never drawn (broken test setup)');
166
- failed++;
167
- }
168
- }
169
- // ── Test 2: Hidden — rightHand must NOT appear ──────────────────────────
170
- console.log('\n[2/2] Hidden — hiddenValues: { rightHand: true }');
171
- {
172
- const rig = makeTestRig(true);
173
- const canvas = await renderRig(createCanvas, rig, redHandCanvas, 'hidden');
174
- const ctx = canvas.getContext('2d');
175
- const { data } = ctx.getImageData(0, 0, CANVAS_W, CANVAS_H);
176
- const redCount = countRedPixels(data);
177
- if (redCount === 0) {
178
- console.log(' ✅ PASS — 0 red pixels; rightHand correctly excluded from render');
179
- passed++;
180
- }
181
- else {
182
- console.log(` ❌ FAIL — ${redCount} red pixels found; ` +
183
- 'rightHand rendered despite hiddenValues.rightHand = true\n' +
184
- ' └─ Fix: ensure computeCharacterRigData() skips parts where hiddenValues[part] === true');
185
- failed++;
186
- }
187
- }
188
- // ── Summary ─────────────────────────────────────────────────────────────
189
- console.log('\n' + '='.repeat(54));
190
- console.log(`📊 Results: ${passed}/2 passed`);
191
- if (failed === 0) {
192
- console.log('✅ All hidden-parts tests PASSED\n');
193
- process.exit(0);
194
- }
195
- else {
196
- console.log('❌ Hidden-parts test(s) FAILED\n');
197
- process.exit(1);
198
- }
199
- }
200
- main().catch(err => {
201
- console.error('Fatal error:', err);
202
- process.exit(1);
203
- });
204
- //# sourceMappingURL=test-hidden-parts.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-hidden-parts.js","sourceRoot":"","sources":["../../tests/test-hidden-parts.ts"],"names":[],"mappings":"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"}