@12ui/design 0.2.70 → 0.2.72
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 +5 -0
- package/SKILL.md +1 -1
- package/dist/cli-capabilities.d.ts +9 -0
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +10 -0
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-conversion-recovery-advice.d.ts +35 -0
- package/dist/cli-conversion-recovery-advice.d.ts.map +1 -0
- package/dist/cli-conversion-recovery-advice.js +72 -0
- package/dist/cli-conversion-recovery-advice.js.map +1 -0
- package/dist/cli-convert-command.d.ts.map +1 -1
- package/dist/cli-convert-command.js +153 -35
- package/dist/cli-convert-command.js.map +1 -1
- package/dist/cli-help/index.d.ts +93 -0
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-help/index.js +2 -0
- package/dist/cli-help/index.js.map +1 -1
- package/dist/cli-help/scene.d.ts +96 -0
- package/dist/cli-help/scene.d.ts.map +1 -0
- package/dist/cli-help/scene.js +162 -0
- package/dist/cli-help/scene.js.map +1 -0
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +6 -0
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-scene-command.d.ts +3 -0
- package/dist/cli-scene-command.d.ts.map +1 -0
- package/dist/cli-scene-command.js +292 -0
- package/dist/cli-scene-command.js.map +1 -0
- package/dist/cli-usage.d.ts +8 -0
- package/dist/cli-usage.d.ts.map +1 -1
- package/dist/cli-usage.js +26 -1
- package/dist/cli-usage.js.map +1 -1
- package/dist/conversion-client.d.ts +11 -0
- package/dist/conversion-client.d.ts.map +1 -1
- package/dist/conversion-client.js +11 -1
- package/dist/conversion-client.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +11 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/prototype-browsers.d.ts +8 -2
- package/dist/prototype-browsers.d.ts.map +1 -1
- package/dist/prototype-browsers.js +8 -3
- package/dist/prototype-browsers.js.map +1 -1
- package/dist/prototype-process.js +1 -1
- package/dist/prototype-process.js.map +1 -1
- package/dist/run-journal-commands.d.ts.map +1 -1
- package/dist/run-journal-commands.js +6 -0
- package/dist/run-journal-commands.js.map +1 -1
- package/dist/scene/camera-model.d.ts +48 -0
- package/dist/scene/camera-model.d.ts.map +1 -0
- package/dist/scene/camera-model.js +89 -0
- package/dist/scene/camera-model.js.map +1 -0
- package/dist/scene/camera-solve.d.ts +58 -0
- package/dist/scene/camera-solve.d.ts.map +1 -0
- package/dist/scene/camera-solve.js +288 -0
- package/dist/scene/camera-solve.js.map +1 -0
- package/dist/scene/capture-plan.d.ts +28 -0
- package/dist/scene/capture-plan.d.ts.map +1 -0
- package/dist/scene/capture-plan.js +79 -0
- package/dist/scene/capture-plan.js.map +1 -0
- package/dist/scene/capture.d.ts +21 -0
- package/dist/scene/capture.d.ts.map +1 -0
- package/dist/scene/capture.js +118 -0
- package/dist/scene/capture.js.map +1 -0
- package/dist/scene/image-colors.d.ts +25 -0
- package/dist/scene/image-colors.d.ts.map +1 -0
- package/dist/scene/image-colors.js +110 -0
- package/dist/scene/image-colors.js.map +1 -0
- package/dist/scene/image-rectify.d.ts +25 -0
- package/dist/scene/image-rectify.d.ts.map +1 -0
- package/dist/scene/image-rectify.js +82 -0
- package/dist/scene/image-rectify.js.map +1 -0
- package/dist/scene/image-sheet.d.ts +19 -0
- package/dist/scene/image-sheet.d.ts.map +1 -0
- package/dist/scene/image-sheet.js +118 -0
- package/dist/scene/image-sheet.js.map +1 -0
- package/dist/scene/least-squares.d.ts +31 -0
- package/dist/scene/least-squares.d.ts.map +1 -0
- package/dist/scene/least-squares.js +173 -0
- package/dist/scene/least-squares.js.map +1 -0
- package/dist/scene/numbers.d.ts +17 -0
- package/dist/scene/numbers.d.ts.map +1 -0
- package/dist/scene/numbers.js +39 -0
- package/dist/scene/numbers.js.map +1 -0
- package/dist/scene/placement.d.ts +43 -0
- package/dist/scene/placement.d.ts.map +1 -0
- package/dist/scene/placement.js +107 -0
- package/dist/scene/placement.js.map +1 -0
- package/dist/scene/raster.d.ts +18 -0
- package/dist/scene/raster.d.ts.map +1 -0
- package/dist/scene/raster.js +31 -0
- package/dist/scene/raster.js.map +1 -0
- package/dist/scene/scene-kit.d.ts +20 -0
- package/dist/scene/scene-kit.d.ts.map +1 -0
- package/dist/scene/scene-kit.js +74 -0
- package/dist/scene/scene-kit.js.map +1 -0
- package/dist/scene/scene-verbs.d.ts +4 -0
- package/dist/scene/scene-verbs.d.ts.map +1 -0
- package/dist/scene/scene-verbs.js +5 -0
- package/dist/scene/scene-verbs.js.map +1 -0
- package/dist/scene/seeded-random.d.ts +20 -0
- package/dist/scene/seeded-random.d.ts.map +1 -0
- package/dist/scene/seeded-random.js +42 -0
- package/dist/scene/seeded-random.js.map +1 -0
- package/dist/scene/spec-expression.d.ts +25 -0
- package/dist/scene/spec-expression.d.ts.map +1 -0
- package/dist/scene/spec-expression.js +234 -0
- package/dist/scene/spec-expression.js.map +1 -0
- package/dist/scene/static-server.d.ts +13 -0
- package/dist/scene/static-server.d.ts.map +1 -0
- package/dist/scene/static-server.js +99 -0
- package/dist/scene/static-server.js.map +1 -0
- package/open-design.json +2 -2
- package/package.json +3 -1
- package/scene-kit/starter/camera.js +10 -0
- package/scene-kit/starter/gobo.js +60 -0
- package/scene-kit/starter/index.html +23 -0
- package/scene-kit/starter/lib.js +84 -0
- package/scene-kit/starter/main.js +78 -0
- package/scene-kit/starter/scene.js +33 -0
- package/scene-kit/vendor/LICENSE +21 -0
- package/scene-kit/vendor/addons/geometries/RoundedBoxGeometry.js +216 -0
- package/scene-kit/vendor/addons/renderers/CSS3DRenderer.js +454 -0
- package/scene-kit/vendor/three.core.js +60586 -0
- package/scene-kit/vendor/three.module.js +19719 -0
- package/skills/12ui-design/SKILL.md +7 -1
- package/skills/12ui-design/scene.md +172 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box-constrained Levenberg-Marquardt with a numeric Jacobian, and a multistart
|
|
3
|
+
* around it. A line-for-line port of the proven Python solver
|
|
4
|
+
* (`solve_camera.py` lm/multistart): the same damping schedule, the same
|
|
5
|
+
* forward-difference step, the same clamping, so a spec solves to the same
|
|
6
|
+
* minimum in both.
|
|
7
|
+
*/
|
|
8
|
+
export class SingularMatrixError extends Error {
|
|
9
|
+
constructor() {
|
|
10
|
+
super('singular matrix');
|
|
11
|
+
this.name = 'SingularMatrixError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const clamp = (values, low, high) => {
|
|
15
|
+
const out = new Float64Array(values.length);
|
|
16
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
17
|
+
out[index] = Math.min(Math.max(values[index], low[index]), high[index]);
|
|
18
|
+
}
|
|
19
|
+
return out;
|
|
20
|
+
};
|
|
21
|
+
const sumOfSquares = (values) => {
|
|
22
|
+
let total = 0;
|
|
23
|
+
for (const value of values)
|
|
24
|
+
total += value * value;
|
|
25
|
+
return total;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Solves `matrix * x = rhs` by Gaussian elimination with partial pivoting.
|
|
29
|
+
* An exactly zero pivot is a singular system, as LAPACK reports it.
|
|
30
|
+
*/
|
|
31
|
+
export const solveLinearSystem = (matrix, rhs) => {
|
|
32
|
+
const size = rhs.length;
|
|
33
|
+
const a = matrix.map((row) => Float64Array.from(row));
|
|
34
|
+
const b = Float64Array.from(rhs);
|
|
35
|
+
for (let column = 0; column < size; column += 1) {
|
|
36
|
+
let pivotRow = column;
|
|
37
|
+
let pivotSize = Math.abs(a[column][column]);
|
|
38
|
+
for (let row = column + 1; row < size; row += 1) {
|
|
39
|
+
const candidate = Math.abs(a[row][column]);
|
|
40
|
+
if (candidate > pivotSize) {
|
|
41
|
+
pivotSize = candidate;
|
|
42
|
+
pivotRow = row;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (pivotSize === 0)
|
|
46
|
+
throw new SingularMatrixError();
|
|
47
|
+
if (pivotRow !== column) {
|
|
48
|
+
[a[column], a[pivotRow]] = [a[pivotRow], a[column]];
|
|
49
|
+
[b[column], b[pivotRow]] = [b[pivotRow], b[column]];
|
|
50
|
+
}
|
|
51
|
+
const pivot = a[column];
|
|
52
|
+
for (let row = column + 1; row < size; row += 1) {
|
|
53
|
+
const target = a[row];
|
|
54
|
+
const factor = target[column] / pivot[column];
|
|
55
|
+
if (factor === 0)
|
|
56
|
+
continue;
|
|
57
|
+
for (let k = column; k < size; k += 1)
|
|
58
|
+
target[k] -= factor * pivot[k];
|
|
59
|
+
b[row] -= factor * b[column];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const x = new Float64Array(size);
|
|
63
|
+
for (let row = size - 1; row >= 0; row -= 1) {
|
|
64
|
+
let total = b[row];
|
|
65
|
+
const current = a[row];
|
|
66
|
+
for (let k = row + 1; k < size; k += 1)
|
|
67
|
+
total -= current[k] * x[k];
|
|
68
|
+
x[row] = total / current[row];
|
|
69
|
+
}
|
|
70
|
+
return x;
|
|
71
|
+
};
|
|
72
|
+
export const levenbergMarquardt = (residuals, start, low, high, iterations = 60) => {
|
|
73
|
+
let p = clamp(start, low, high);
|
|
74
|
+
let lambda = 1e-2;
|
|
75
|
+
let r = residuals(p);
|
|
76
|
+
let cost = sumOfSquares(r);
|
|
77
|
+
const n = p.length;
|
|
78
|
+
for (let iteration = 0; iteration < iterations; iteration += 1) {
|
|
79
|
+
const m = r.length;
|
|
80
|
+
// Forward-difference Jacobian, column by column.
|
|
81
|
+
const jacobian = [];
|
|
82
|
+
for (let i = 0; i < n; i += 1) {
|
|
83
|
+
const step = 1e-6 * Math.max(1, Math.abs(p[i]));
|
|
84
|
+
const q = Float64Array.from(p);
|
|
85
|
+
q[i] += step;
|
|
86
|
+
const rq = residuals(q);
|
|
87
|
+
const column = new Float64Array(m);
|
|
88
|
+
for (let k = 0; k < m; k += 1)
|
|
89
|
+
column[k] = (rq[k] - r[k]) / step;
|
|
90
|
+
jacobian.push(column);
|
|
91
|
+
}
|
|
92
|
+
const normal = Array.from({ length: n }, () => new Float64Array(n));
|
|
93
|
+
const gradient = new Float64Array(n);
|
|
94
|
+
for (let i = 0; i < n; i += 1) {
|
|
95
|
+
const ci = jacobian[i];
|
|
96
|
+
let g = 0;
|
|
97
|
+
for (let k = 0; k < m; k += 1)
|
|
98
|
+
g += ci[k] * r[k];
|
|
99
|
+
gradient[i] = g;
|
|
100
|
+
for (let j = i; j < n; j += 1) {
|
|
101
|
+
const cj = jacobian[j];
|
|
102
|
+
let total = 0;
|
|
103
|
+
for (let k = 0; k < m; k += 1)
|
|
104
|
+
total += ci[k] * cj[k];
|
|
105
|
+
normal[i][j] = total;
|
|
106
|
+
normal[j][i] = total;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
let improved = false;
|
|
110
|
+
for (let attempt = 0; attempt < 12; attempt += 1) {
|
|
111
|
+
const damped = normal.map((row, i) => {
|
|
112
|
+
const copy = Float64Array.from(row);
|
|
113
|
+
copy[i] += lambda * (row[i] + 1e-9);
|
|
114
|
+
return copy;
|
|
115
|
+
});
|
|
116
|
+
let step;
|
|
117
|
+
try {
|
|
118
|
+
step = solveLinearSystem(damped, gradient.map((value) => -value));
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
if (error instanceof SingularMatrixError) {
|
|
122
|
+
lambda *= 10;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
const candidate = clamp(p.map((value, index) => value + step[index]), low, high);
|
|
128
|
+
const rq = residuals(candidate);
|
|
129
|
+
const cq = sumOfSquares(rq);
|
|
130
|
+
if (cq < cost) {
|
|
131
|
+
p = candidate;
|
|
132
|
+
r = rq;
|
|
133
|
+
cost = cq;
|
|
134
|
+
lambda = Math.max(lambda / 3, 1e-9);
|
|
135
|
+
improved = true;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
lambda *= 4;
|
|
139
|
+
}
|
|
140
|
+
if (!improved || cost < 1e-10)
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
return { parameters: p, cost };
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* Every start gets a short coarse run; the best `keep` are refined fully and
|
|
147
|
+
* the lowest cost wins. Ties keep the earlier start, as Python's stable sort did.
|
|
148
|
+
*/
|
|
149
|
+
export const multistart = (residuals, starts, low, high, { keep = 6, coarse = 25, refine = 200 } = {}) => {
|
|
150
|
+
const scored = starts.map((start, index) => ({
|
|
151
|
+
index,
|
|
152
|
+
...levenbergMarquardt(residuals, start, low, high, coarse),
|
|
153
|
+
}));
|
|
154
|
+
scored.sort((left, right) => (compareCost(left.cost, right.cost) || left.index - right.index));
|
|
155
|
+
let best = null;
|
|
156
|
+
for (const candidate of scored.slice(0, keep)) {
|
|
157
|
+
const refined = levenbergMarquardt(residuals, candidate.parameters, low, high, refine);
|
|
158
|
+
if (best === null || refined.cost < best.cost)
|
|
159
|
+
best = refined;
|
|
160
|
+
}
|
|
161
|
+
if (best === null)
|
|
162
|
+
throw new Error('multistart needs at least one start');
|
|
163
|
+
return best;
|
|
164
|
+
};
|
|
165
|
+
/** NaN sorts last, like a failed start should. */
|
|
166
|
+
const compareCost = (left, right) => {
|
|
167
|
+
if (Number.isNaN(left))
|
|
168
|
+
return Number.isNaN(right) ? 0 : 1;
|
|
169
|
+
if (Number.isNaN(right))
|
|
170
|
+
return -1;
|
|
171
|
+
return left - right;
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=least-squares.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"least-squares.js","sourceRoot":"","sources":["../../src/scene/least-squares.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,MAAM,KAAK,GAAG,CAAC,MAAyB,EAAE,GAAsB,EAAE,IAAuB,EAAgB,EAAE;IACzG,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAE,EAAE,GAAG,CAAC,KAAK,CAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,MAAoB,EAAU,EAAE;IACpD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC;IACnD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAA+B,EAAE,GAAiB,EAAgB,EAAE;IACpG,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;IACxB,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,QAAQ,GAAG,MAAM,CAAC;QACtB,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAE,CAAC,MAAM,CAAE,CAAC,CAAC;QAC9C,KAAK,IAAI,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAE,CAAC,MAAM,CAAE,CAAC,CAAC;YAC7C,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;gBAC1B,SAAS,GAAG,SAAS,CAAC;gBACtB,QAAQ,GAAG,GAAG,CAAC;YACjB,CAAC;QACH,CAAC;QACD,IAAI,SAAS,KAAK,CAAC;YAAE,MAAM,IAAI,mBAAmB,EAAE,CAAC;QACrD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,EAAE,CAAC,CAAC,MAAM,CAAE,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,EAAE,CAAC,CAAC,MAAM,CAAE,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAE,CAAC;QACzB,KAAK,IAAI,GAAG,GAAG,MAAM,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAE,CAAC;YACvB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAE,GAAG,KAAK,CAAC,MAAM,CAAE,CAAC;YAChD,IAAI,MAAM,KAAK,CAAC;gBAAE,SAAS;YAC3B,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAE,IAAI,MAAM,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACxE,CAAC,CAAC,GAAG,CAAE,IAAI,MAAM,GAAG,CAAC,CAAC,MAAM,CAAE,CAAC;QACjC,CAAC;IACH,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,KAAK,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAC5C,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,CAAE,CAAC;QACpB,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAE,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC;YAAE,KAAK,IAAI,OAAO,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACrE,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,OAAO,CAAC,GAAG,CAAE,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAIF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,SAAoB,EACpB,KAAwB,EACxB,GAAsB,EACtB,IAAuB,EACvB,UAAU,GAAG,EAAE,EACK,EAAE;IACtB,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,UAAU,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QACnB,iDAAiD;QACjD,MAAM,QAAQ,GAAmB,EAAE,CAAC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC,CAAE,IAAI,IAAI,CAAC;YACd,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;YACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC,GAAG,IAAI,CAAC;YACnE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;QACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;gBAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAE,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;YACnD,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;gBACxB,IAAI,KAAK,GAAG,CAAC,CAAC;gBACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;oBAAE,KAAK,IAAI,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC;gBACxD,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;gBACtB,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YACxB,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;gBACnC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACpC,IAAI,CAAC,CAAC,CAAE,IAAI,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,CAAE,GAAG,IAAI,CAAC,CAAC;gBACtC,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YACH,IAAI,IAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,IAAI,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACpE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;oBACzC,MAAM,IAAI,EAAE,CAAC;oBACb,SAAS;gBACX,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAClF,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;YAChC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;gBACd,CAAC,GAAG,SAAS,CAAC;gBACd,CAAC,GAAG,EAAE,CAAC;gBACP,IAAI,GAAG,EAAE,CAAC;gBACV,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;gBACpC,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM;YACR,CAAC;YACD,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;QACD,IAAI,CAAC,QAAQ,IAAI,IAAI,GAAG,KAAK;YAAE,MAAM;IACvC,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,SAAoB,EACpB,MAAoC,EACpC,GAAsB,EACtB,IAAuB,EACvB,EAAE,IAAI,GAAG,CAAC,EAAE,MAAM,GAAG,EAAE,EAAE,MAAM,GAAG,GAAG,KAA0D,EAAE,EAC7E,EAAE;IACtB,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3C,KAAK;QACL,GAAG,kBAAkB,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC;KAC3D,CAAC,CAAC,CAAC;IACJ,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC3B,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAC/D,CAAC,CAAC;IACH,IAAI,IAAI,GAA8B,IAAI,CAAC;IAC3C,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACvF,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI;YAAE,IAAI,GAAG,OAAO,CAAC;IAChE,CAAC;IACD,IAAI,IAAI,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC1E,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,kDAAkD;AAClD,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE;IAC1D,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC;IACnC,OAAO,IAAI,GAAG,KAAK,CAAC;AACtB,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** A malformed scene argument: a refusal, raised before any work starts. */
|
|
2
|
+
export declare class SceneArgumentError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
/** Round to `digits` decimals for JSON output (the Python helpers' `round`). */
|
|
6
|
+
export declare const roundTo: (value: number, digits: number) => number;
|
|
7
|
+
/** Fixed-point text, like Python's `f"{value:.Nf}"`. */
|
|
8
|
+
export declare const fixed: (value: number, digits: number) => string;
|
|
9
|
+
/** Parses "a,b" or "a,b,c" into numbers, naming the argument when it is malformed. */
|
|
10
|
+
export declare const parseNumberTuple: (text: string, count: number, what: string) => number[];
|
|
11
|
+
/** Parses a box "x0,y0,x1,y1" into integers (fractions truncate, as Python's int() did). */
|
|
12
|
+
export declare const parseBox: (text: string, what: string) => [number, number, number, number];
|
|
13
|
+
/** Splits a `;`-separated list, dropping empty entries. */
|
|
14
|
+
export declare const splitList: (text: string) => string[];
|
|
15
|
+
/** "WxH" into two positive integers. */
|
|
16
|
+
export declare const parseSize: (text: string, what: string) => [number, number];
|
|
17
|
+
//# sourceMappingURL=numbers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbers.d.ts","sourceRoot":"","sources":["../../src/scene/numbers.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,gFAAgF;AAChF,eAAO,MAAM,OAAO,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,MAGvD,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,MAA+B,CAAC;AAEtF,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,EAAE,MAAM,MAAM,KAAG,MAAM,EAOlF,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAGpF,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,KAAG,MAAM,EAAgE,CAAC;AAEhH,wCAAwC;AACxC,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,CAAC,MAAM,EAAE,MAAM,CAMrE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** A malformed scene argument: a refusal, raised before any work starts. */
|
|
2
|
+
export class SceneArgumentError extends Error {
|
|
3
|
+
constructor(message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = 'SceneArgumentError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
/** Round to `digits` decimals for JSON output (the Python helpers' `round`). */
|
|
9
|
+
export const roundTo = (value, digits) => {
|
|
10
|
+
const rounded = Number(value.toFixed(digits));
|
|
11
|
+
return Object.is(rounded, -0) ? 0 : rounded;
|
|
12
|
+
};
|
|
13
|
+
/** Fixed-point text, like Python's `f"{value:.Nf}"`. */
|
|
14
|
+
export const fixed = (value, digits) => value.toFixed(digits);
|
|
15
|
+
/** Parses "a,b" or "a,b,c" into numbers, naming the argument when it is malformed. */
|
|
16
|
+
export const parseNumberTuple = (text, count, what) => {
|
|
17
|
+
const parts = text.split(',').map((part) => part.trim());
|
|
18
|
+
const values = parts.map(Number);
|
|
19
|
+
if (parts.length !== count || parts.some((part) => part === '') || values.some((value) => !Number.isFinite(value))) {
|
|
20
|
+
throw new SceneArgumentError(`${what} must be ${count} comma-separated numbers, got "${text}"`);
|
|
21
|
+
}
|
|
22
|
+
return values;
|
|
23
|
+
};
|
|
24
|
+
/** Parses a box "x0,y0,x1,y1" into integers (fractions truncate, as Python's int() did). */
|
|
25
|
+
export const parseBox = (text, what) => {
|
|
26
|
+
const [x0, y0, x1, y1] = parseNumberTuple(text, 4, what).map(Math.trunc);
|
|
27
|
+
return [x0, y0, x1, y1];
|
|
28
|
+
};
|
|
29
|
+
/** Splits a `;`-separated list, dropping empty entries. */
|
|
30
|
+
export const splitList = (text) => text.split(';').map((part) => part.trim()).filter(Boolean);
|
|
31
|
+
/** "WxH" into two positive integers. */
|
|
32
|
+
export const parseSize = (text, what) => {
|
|
33
|
+
const match = /^(\d+)x(\d+)$/u.exec(text.trim());
|
|
34
|
+
if (!match || Number(match[1]) < 1 || Number(match[2]) < 1) {
|
|
35
|
+
throw new SceneArgumentError(`${what} must be <width>x<height> in pixels, got "${text}"`);
|
|
36
|
+
}
|
|
37
|
+
return [Number(match[1]), Number(match[2])];
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=numbers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numbers.js","sourceRoot":"","sources":["../../src/scene/numbers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type Camera, type ImageSize, type Vec3 } from './camera-model.js';
|
|
2
|
+
/**
|
|
3
|
+
* Placing objects through a solved camera: pixel rays onto a plane, world
|
|
4
|
+
* points back to pixels, and the pose of a rectangle from its four corners.
|
|
5
|
+
* Ports of `solve_camera.py ray|project|rect`, with the sized rectangle fixed:
|
|
6
|
+
* the Python helper crashed whenever both sides were known.
|
|
7
|
+
*/
|
|
8
|
+
export type RayLine = {
|
|
9
|
+
u: number;
|
|
10
|
+
v: number;
|
|
11
|
+
point: Vec3;
|
|
12
|
+
behind: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare const castRays: (camera: Camera, size: ImageSize, pixels: ReadonlyArray<[number, number]>, planeY: number) => RayLine[];
|
|
15
|
+
export declare const formatRayLine: (line: RayLine) => string;
|
|
16
|
+
export declare const formatProjectLine: (point: Vec3, u: number, v: number) => string;
|
|
17
|
+
export type RectPose = {
|
|
18
|
+
position: Vec3;
|
|
19
|
+
w: number;
|
|
20
|
+
h: number;
|
|
21
|
+
rotation: {
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
z: number;
|
|
25
|
+
order: 'YXZ';
|
|
26
|
+
};
|
|
27
|
+
rmsPx?: number;
|
|
28
|
+
note: string;
|
|
29
|
+
};
|
|
30
|
+
/** A rectangle lying flat on the plane y = planeY, any size. Corners TL;TR;BR;BL in pixels. */
|
|
31
|
+
export declare const rectOnPlane: (camera: Camera, size: ImageSize, corners: ReadonlyArray<[number, number]>, planeY: number) => {
|
|
32
|
+
pose: RectPose;
|
|
33
|
+
behind: boolean;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Free pose (position, lean, roll) of a rectangle whose width, height or both
|
|
37
|
+
* are known. With one side known the other is solved, less well determined.
|
|
38
|
+
*/
|
|
39
|
+
export declare const rectOfKnownSize: (camera: Camera, size: ImageSize, corners: ReadonlyArray<[number, number]>, known: {
|
|
40
|
+
width?: number;
|
|
41
|
+
height?: number;
|
|
42
|
+
}) => RectPose;
|
|
43
|
+
//# sourceMappingURL=placement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement.d.ts","sourceRoot":"","sources":["../../src/scene/placement.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,IAAI,EACV,MAAM,mBAAmB,CAAC;AAK3B;;;;;GAKG;AAEH,MAAM,MAAM,OAAO,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAC;AAE7E,eAAO,MAAM,QAAQ,GACnB,QAAQ,MAAM,EACd,MAAM,SAAS,EACf,QAAQ,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACvC,QAAQ,MAAM,KACb,OAAO,EAAiF,CAAC;AAE5F,eAAO,MAAM,aAAa,GAAI,MAAM,OAAO,KAAG,MAG7C,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,IAAI,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,MAErE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,EAAE,IAAI,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAYF,+FAA+F;AAC/F,eAAO,MAAM,WAAW,GACtB,QAAQ,MAAM,EACd,MAAM,SAAS,EACf,SAAS,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACxC,QAAQ,MAAM,KACb;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAoBnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,EACd,MAAM,SAAS,EACf,SAAS,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACxC,OAAO;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KACzC,QA+DF,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { planeHit, pixelRay, projectPoints, rotationMatrix, } from './camera-model.js';
|
|
2
|
+
import { multistart } from './least-squares.js';
|
|
3
|
+
import { fixed, roundTo, SceneArgumentError } from './numbers.js';
|
|
4
|
+
import { seededRandom } from './seeded-random.js';
|
|
5
|
+
export const castRays = (camera, size, pixels, planeY) => pixels.map(([u, v]) => ({ u, v, ...planeHit(camera, size, u, v, planeY) }));
|
|
6
|
+
export const formatRayLine = (line) => (`${fixed(line.u, 0)},${fixed(line.v, 0)} -> x=${fixed(line.point[0], 4)}`
|
|
7
|
+
+ ` y=${fixed(line.point[1], 4)} z=${fixed(line.point[2], 4)}`);
|
|
8
|
+
export const formatProjectLine = (point, u, v) => (`${fixed(point[0], 4)},${fixed(point[1], 4)},${fixed(point[2], 4)} -> px ${fixed(u, 1)},${fixed(v, 1)}`);
|
|
9
|
+
const FLAT_NOTE = 'mesh face is local xy facing +z; rotation.x=-pi/2 lays it flat facing up,'
|
|
10
|
+
+ ' local +y points away from the camera';
|
|
11
|
+
const AMBIGUITY_NOTE = 'rectangles seen from one view are ambiguous in lean versus depth; if it lands inside'
|
|
12
|
+
+ ' another object, constrain it with what you know (rests on a surface, leans on a wall)';
|
|
13
|
+
const SOLVED_SIDE_NOTE = 'one dimension was solved, so lean, roll and that dimension trade against each other;'
|
|
14
|
+
+ ' prefer --plane-y for anything lying flat. ';
|
|
15
|
+
const subtract = (a, b) => [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
|
|
16
|
+
const norm = (a) => Math.hypot(...a);
|
|
17
|
+
/** A rectangle lying flat on the plane y = planeY, any size. Corners TL;TR;BR;BL in pixels. */
|
|
18
|
+
export const rectOnPlane = (camera, size, corners, planeY) => {
|
|
19
|
+
const hits = corners.map(([u, v]) => planeHit(camera, size, u, v, planeY));
|
|
20
|
+
const P = hits.map((hit) => hit.point);
|
|
21
|
+
const centre = [0, 0, 0];
|
|
22
|
+
for (const point of P)
|
|
23
|
+
for (let axis = 0; axis < 3; axis += 1)
|
|
24
|
+
centre[axis] += point[axis] / P.length;
|
|
25
|
+
const top = subtract(P[1], P[0]);
|
|
26
|
+
const bottom = subtract(P[2], P[3]);
|
|
27
|
+
const width = (norm(top) + norm(bottom)) / 2;
|
|
28
|
+
const height = (norm(subtract(P[3], P[0])) + norm(subtract(P[2], P[1]))) / 2;
|
|
29
|
+
const yaw = Math.atan2(-(top[2] + bottom[2]), top[0] + bottom[0]);
|
|
30
|
+
return {
|
|
31
|
+
pose: {
|
|
32
|
+
position: [roundTo(centre[0], 4), roundTo(centre[1], 4), roundTo(centre[2], 4)],
|
|
33
|
+
w: roundTo(width, 4),
|
|
34
|
+
h: roundTo(height, 4),
|
|
35
|
+
rotation: { x: roundTo(-Math.PI / 2, 6), y: roundTo(yaw, 6), z: 0, order: 'YXZ' },
|
|
36
|
+
note: FLAT_NOTE,
|
|
37
|
+
},
|
|
38
|
+
behind: hits.some((hit) => hit.behind),
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Free pose (position, lean, roll) of a rectangle whose width, height or both
|
|
43
|
+
* are known. With one side known the other is solved, less well determined.
|
|
44
|
+
*/
|
|
45
|
+
export const rectOfKnownSize = (camera, size, corners, known) => {
|
|
46
|
+
const { width, height } = known;
|
|
47
|
+
if (width === undefined && height === undefined) {
|
|
48
|
+
throw new SceneArgumentError('rect needs --plane-y, or --width and/or --height');
|
|
49
|
+
}
|
|
50
|
+
const seed = Math.max(...[width, height].filter((value) => value !== undefined));
|
|
51
|
+
const solvedSide = width === undefined || height === undefined ? 1 : 0;
|
|
52
|
+
const centroid = corners.reduce((total, [u, v]) => [total[0] + u / corners.length, total[1] + v / corners.length], [0, 0]);
|
|
53
|
+
const ray = pixelRay(camera, size, centroid[0], centroid[1]);
|
|
54
|
+
const sides = (p) => [
|
|
55
|
+
width ?? p[6],
|
|
56
|
+
height ?? p[6],
|
|
57
|
+
];
|
|
58
|
+
const residuals = (p) => {
|
|
59
|
+
const [w, h] = sides(p);
|
|
60
|
+
const local = [[-w / 2, h / 2, 0], [w / 2, h / 2, 0], [w / 2, -h / 2, 0], [-w / 2, -h / 2, 0]];
|
|
61
|
+
// Euler YXZ with rotation.set(x = p[4], y = p[3], z = p[5]); lean is rotation.x.
|
|
62
|
+
const r = rotationMatrix(p[3], p[4], p[5]);
|
|
63
|
+
const world = local.map((point) => [
|
|
64
|
+
r[0][0] * point[0] + r[0][1] * point[1] + r[0][2] * point[2] + p[0],
|
|
65
|
+
r[1][0] * point[0] + r[1][1] * point[1] + r[1][2] * point[2] + p[1],
|
|
66
|
+
r[2][0] * point[0] + r[2][1] * point[1] + r[2][2] * point[2] + p[2],
|
|
67
|
+
]);
|
|
68
|
+
const projected = projectPoints(camera, world, size);
|
|
69
|
+
const out = new Float64Array(8);
|
|
70
|
+
projected.forEach((projection, index) => {
|
|
71
|
+
const penalty = Math.max(projection.depth + 0.01, 0) * 1e4;
|
|
72
|
+
out[2 * index] = projection.u - corners[index][0] + penalty;
|
|
73
|
+
out[2 * index + 1] = projection.v - corners[index][1] + penalty;
|
|
74
|
+
});
|
|
75
|
+
return out;
|
|
76
|
+
};
|
|
77
|
+
const random = seededRandom(2);
|
|
78
|
+
const starts = [];
|
|
79
|
+
for (let index = 0; index < 300; index += 1) {
|
|
80
|
+
const reach = random.uniform(0.2, 3) * seed * 3;
|
|
81
|
+
const start = [
|
|
82
|
+
camera.pos[0] + ray[0] * reach,
|
|
83
|
+
camera.pos[1] + ray[1] * reach,
|
|
84
|
+
camera.pos[2] + ray[2] * reach,
|
|
85
|
+
random.uniform(-1.2, 1.2),
|
|
86
|
+
random.uniform(-1.4, 1.4),
|
|
87
|
+
random.uniform(-0.6, 0.6),
|
|
88
|
+
];
|
|
89
|
+
if (solvedSide)
|
|
90
|
+
start.push(seed * random.uniform(0.5, 2));
|
|
91
|
+
starts.push(Float64Array.from(start));
|
|
92
|
+
}
|
|
93
|
+
const low = [-1e4, -1e4, -1e4, -4, -1.6, -3.2, ...(solvedSide ? [seed * 0.05] : [])];
|
|
94
|
+
const high = [1e4, 1e4, 1e4, 4, 1.6, 3.2, ...(solvedSide ? [seed * 20] : [])];
|
|
95
|
+
const best = multistart(residuals, starts, low, high);
|
|
96
|
+
const p = best.parameters;
|
|
97
|
+
const [w, h] = sides(p);
|
|
98
|
+
return {
|
|
99
|
+
position: [roundTo(p[0], 4), roundTo(p[1], 4), roundTo(p[2], 4)],
|
|
100
|
+
w: roundTo(w, 4),
|
|
101
|
+
h: roundTo(h, 4),
|
|
102
|
+
rotation: { x: roundTo(p[4], 6), y: roundTo(p[3], 6), z: roundTo(p[5], 6), order: 'YXZ' },
|
|
103
|
+
rmsPx: roundTo(Math.sqrt(best.cost / 8), 2),
|
|
104
|
+
note: (solvedSide ? SOLVED_SIDE_NOTE : '') + AMBIGUITY_NOTE,
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
//# sourceMappingURL=placement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placement.js","sourceRoot":"","sources":["../../src/scene/placement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 8-bit RGB pixels in memory: the one image shape every scene helper works on.
|
|
3
|
+
* Alpha is dropped without compositing, as the Python helpers' convert("RGB")
|
|
4
|
+
* did, and before any resize so a transparent edge never bleeds into colour.
|
|
5
|
+
*/
|
|
6
|
+
export type RgbImage = {
|
|
7
|
+
data: Buffer;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
};
|
|
11
|
+
export declare const readRgb: (file: string) => Promise<RgbImage>;
|
|
12
|
+
/** Lanczos resize to an exact size; the same size is returned untouched. */
|
|
13
|
+
export declare const resizeRgb: (image: RgbImage, width: number, height: number) => Promise<RgbImage>;
|
|
14
|
+
export declare const readRgbAt: (file: string, width: number, height: number) => Promise<RgbImage>;
|
|
15
|
+
/** PNG bytes of an in-memory image. */
|
|
16
|
+
export declare const encodePng: (image: RgbImage) => Promise<Buffer>;
|
|
17
|
+
export declare const writePng: (image: RgbImage, file: string) => Promise<void>;
|
|
18
|
+
//# sourceMappingURL=raster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster.d.ts","sourceRoot":"","sources":["../../src/scene/raster.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,eAAO,MAAM,OAAO,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,QAAQ,CAQ5D,CAAC;AAMF,4EAA4E;AAC5E,eAAO,MAAM,SAAS,GAAU,OAAO,QAAQ,EAAE,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,QAAQ,CAOhG,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,MAAM,MAAM,EAAE,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,QAAQ,CAE7F,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,SAAS,GAAU,OAAO,QAAQ,KAAG,OAAO,CAAC,MAAM,CAE/D,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAU,OAAO,QAAQ,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAE1E,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
export const readRgb = async (file) => {
|
|
3
|
+
const { data, info } = await sharp(file)
|
|
4
|
+
.removeAlpha()
|
|
5
|
+
.toColourspace('srgb')
|
|
6
|
+
.raw()
|
|
7
|
+
.toBuffer({ resolveWithObject: true });
|
|
8
|
+
if (info.channels !== 3)
|
|
9
|
+
throw new Error(`${file}: expected RGB pixels, decoded ${info.channels} channels`);
|
|
10
|
+
return { data, width: info.width, height: info.height };
|
|
11
|
+
};
|
|
12
|
+
const rawInput = (image) => ({
|
|
13
|
+
raw: { width: image.width, height: image.height, channels: 3 },
|
|
14
|
+
});
|
|
15
|
+
/** Lanczos resize to an exact size; the same size is returned untouched. */
|
|
16
|
+
export const resizeRgb = async (image, width, height) => {
|
|
17
|
+
if (image.width === width && image.height === height)
|
|
18
|
+
return image;
|
|
19
|
+
const { data, info } = await sharp(image.data, rawInput(image))
|
|
20
|
+
.resize(width, height, { fit: 'fill', kernel: 'lanczos3' })
|
|
21
|
+
.raw()
|
|
22
|
+
.toBuffer({ resolveWithObject: true });
|
|
23
|
+
return { data, width: info.width, height: info.height };
|
|
24
|
+
};
|
|
25
|
+
export const readRgbAt = async (file, width, height) => (resizeRgb(await readRgb(file), width, height));
|
|
26
|
+
/** PNG bytes of an in-memory image. */
|
|
27
|
+
export const encodePng = async (image) => (sharp(image.data, rawInput(image)).png().toBuffer());
|
|
28
|
+
export const writePng = async (image, file) => {
|
|
29
|
+
await sharp(image.data, rawInput(image)).png().toFile(file);
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=raster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster.js","sourceRoot":"","sources":["../../src/scene/raster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,IAAY,EAAqB,EAAE;IAC/D,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC;SACrC,WAAW,EAAE;SACb,aAAa,CAAC,MAAM,CAAC;SACrB,GAAG,EAAE;SACL,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,QAAQ,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,kCAAkC,IAAI,CAAC,QAAQ,WAAW,CAAC,CAAC;IAC5G,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,CAAC;IACrC,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAU,EAAE;CACxE,CAAC,CAAC;AAEH,4EAA4E;AAC5E,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,KAAe,EAAE,KAAa,EAAE,MAAc,EAAqB,EAAE;IACnG,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACnE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;SAC1D,GAAG,EAAE;SACL,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAAE,KAAa,EAAE,MAAc,EAAqB,EAAE,CAAC,CACjG,SAAS,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAC9C,CAAC;AAEF,uCAAuC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAE,KAAe,EAAmB,EAAE,CAAC,CACnE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CACpD,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,KAAe,EAAE,IAAY,EAAiB,EAAE;IAC7E,MAAM,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The starter harness and the pinned three.js that ship inside the package
|
|
3
|
+
* (`scene-kit/`), and the one operation on them: copy both into a new scene
|
|
4
|
+
* folder. The payload is stored once in the package, never in agent homes, and
|
|
5
|
+
* nothing is fetched: three.js r186 and its MIT licence are bundled.
|
|
6
|
+
*/
|
|
7
|
+
export declare const sceneKitRoot: () => string;
|
|
8
|
+
/** Every file `init` writes, as [kit source, path inside the scene folder]. */
|
|
9
|
+
export declare const sceneKitFiles: (kitRoot?: string) => Promise<Array<[string, string]>>;
|
|
10
|
+
export declare class SceneInitConflict extends Error {
|
|
11
|
+
readonly conflicts: readonly string[];
|
|
12
|
+
constructor(directory: string, conflicts: readonly string[]);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Copies the starter and the vendored three.js into `directory`. Refuses before
|
|
16
|
+
* writing anything when any destination file already exists; the folder itself
|
|
17
|
+
* may exist (it usually holds the source image).
|
|
18
|
+
*/
|
|
19
|
+
export declare const initSceneFolder: (directory: string, kitRoot?: string) => Promise<string[]>;
|
|
20
|
+
//# sourceMappingURL=scene-kit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-kit.d.ts","sourceRoot":"","sources":["../../src/scene/scene-kit.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AAEH,eAAO,MAAM,YAAY,QAAO,MAAqE,CAAC;AAsBtG,+EAA+E;AAC/E,eAAO,MAAM,aAAa,GAAU,gBAAwB,KAAG,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAO7F,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;gBAE1B,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE;CAS5D;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,WAAW,MAAM,EACjB,gBAAwB,KACvB,OAAO,CAAC,MAAM,EAAE,CAclB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { copyFile, mkdir, readdir, stat } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
/**
|
|
6
|
+
* The starter harness and the pinned three.js that ship inside the package
|
|
7
|
+
* (`scene-kit/`), and the one operation on them: copy both into a new scene
|
|
8
|
+
* folder. The payload is stored once in the package, never in agent homes, and
|
|
9
|
+
* nothing is fetched: three.js r186 and its MIT licence are bundled.
|
|
10
|
+
*/
|
|
11
|
+
export const sceneKitRoot = () => fileURLToPath(new URL('../../scene-kit/', import.meta.url));
|
|
12
|
+
const listFiles = async (root, relative = '') => {
|
|
13
|
+
const entries = await readdir(path.join(root, relative), { withFileTypes: true });
|
|
14
|
+
const nested = await Promise.all(entries.map(async (entry) => {
|
|
15
|
+
const child = path.join(relative, entry.name);
|
|
16
|
+
if (entry.isDirectory())
|
|
17
|
+
return listFiles(root, child);
|
|
18
|
+
return entry.isFile() ? [child] : [];
|
|
19
|
+
}));
|
|
20
|
+
return nested.flat().sort();
|
|
21
|
+
};
|
|
22
|
+
const exists = async (target) => {
|
|
23
|
+
try {
|
|
24
|
+
await stat(target);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error.code === 'ENOENT')
|
|
29
|
+
return false;
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
/** Every file `init` writes, as [kit source, path inside the scene folder]. */
|
|
34
|
+
export const sceneKitFiles = async (kitRoot = sceneKitRoot()) => {
|
|
35
|
+
const starter = await listFiles(path.join(kitRoot, 'starter'));
|
|
36
|
+
const vendor = await listFiles(path.join(kitRoot, 'vendor'));
|
|
37
|
+
return [
|
|
38
|
+
...starter.map((file) => [path.join(kitRoot, 'starter', file), file]),
|
|
39
|
+
...vendor.map((file) => [path.join(kitRoot, 'vendor', file), path.join('vendor', file)]),
|
|
40
|
+
];
|
|
41
|
+
};
|
|
42
|
+
export class SceneInitConflict extends Error {
|
|
43
|
+
conflicts;
|
|
44
|
+
constructor(directory, conflicts) {
|
|
45
|
+
super(`${directory} already has ${conflicts.length === 1 ? 'a file' : 'files'} the starter would write:`
|
|
46
|
+
+ ` ${conflicts.slice(0, 8).join(', ')}${conflicts.length > 8 ? ', ...' : ''}.`
|
|
47
|
+
+ ' Nothing was written. Choose a new folder, or move those files away first.');
|
|
48
|
+
this.name = 'SceneInitConflict';
|
|
49
|
+
this.conflicts = conflicts;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Copies the starter and the vendored three.js into `directory`. Refuses before
|
|
54
|
+
* writing anything when any destination file already exists; the folder itself
|
|
55
|
+
* may exist (it usually holds the source image).
|
|
56
|
+
*/
|
|
57
|
+
export const initSceneFolder = async (directory, kitRoot = sceneKitRoot()) => {
|
|
58
|
+
const target = path.resolve(directory);
|
|
59
|
+
const files = await sceneKitFiles(kitRoot);
|
|
60
|
+
const conflicts = [];
|
|
61
|
+
for (const [, relative] of files) {
|
|
62
|
+
if (await exists(path.join(target, relative)))
|
|
63
|
+
conflicts.push(relative);
|
|
64
|
+
}
|
|
65
|
+
if (conflicts.length > 0)
|
|
66
|
+
throw new SceneInitConflict(target, conflicts);
|
|
67
|
+
for (const [source, relative] of files) {
|
|
68
|
+
const destination = path.join(target, relative);
|
|
69
|
+
await mkdir(path.dirname(destination), { recursive: true });
|
|
70
|
+
await copyFile(source, destination, constants.COPYFILE_EXCL);
|
|
71
|
+
}
|
|
72
|
+
return files.map(([, relative]) => relative);
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=scene-kit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-kit.js","sourceRoot":"","sources":["../../src/scene/scene-kit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The `12ui scene` verbs, named once for the dispatcher and the capability record. */
|
|
2
|
+
export declare const SCENE_VERBS: readonly ["init", "solve", "ray", "project", "rect", "serve", "capture", "sheet", "blend", "colors", "rectify"];
|
|
3
|
+
export type SceneVerb = typeof SCENE_VERBS[number];
|
|
4
|
+
//# sourceMappingURL=scene-verbs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-verbs.d.ts","sourceRoot":"","sources":["../../src/scene/scene-verbs.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,eAAO,MAAM,WAAW,iHAEd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-verbs.js","sourceRoot":"","sources":["../../src/scene/scene-verbs.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS;CAC5F,CAAC"}
|