human2ai 0.1.2 → 0.1.4
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.en.md +36 -4
- package/README.md +44 -4
- package/dist/cli/main.js +47 -13
- package/dist/cli/main.js.map +1 -1
- package/dist/database/style-library-repository.d.ts +14 -1
- package/dist/database/style-library-repository.js +59 -0
- package/dist/database/style-library-repository.js.map +1 -1
- package/dist/domain/composition/analysis.d.ts +3 -0
- package/dist/domain/composition/analysis.js +5 -0
- package/dist/domain/composition/analysis.js.map +1 -1
- package/dist/domain/composition/draft.d.ts +2 -0
- package/dist/domain/composition/draft.js +126 -5
- package/dist/domain/composition/draft.js.map +1 -1
- package/dist/domain/composition/frame.d.ts +1 -0
- package/dist/domain/composition/frame.js +6 -0
- package/dist/domain/composition/frame.js.map +1 -1
- package/dist/domain/composition/geometry.d.ts +5 -1
- package/dist/domain/composition/geometry.js +40 -2
- package/dist/domain/composition/geometry.js.map +1 -1
- package/dist/domain/composition/index.d.ts +6 -3
- package/dist/domain/composition/index.js +6 -3
- package/dist/domain/composition/index.js.map +1 -1
- package/dist/domain/composition/planning-intersections.d.ts +20 -0
- package/dist/domain/composition/planning-intersections.js +119 -0
- package/dist/domain/composition/planning-intersections.js.map +1 -0
- package/dist/domain/composition/planning.d.ts +25 -0
- package/dist/domain/composition/planning.js +152 -0
- package/dist/domain/composition/planning.js.map +1 -0
- package/dist/domain/composition/refinement/engine.js +1 -0
- package/dist/domain/composition/refinement/engine.js.map +1 -1
- package/dist/domain/composition/render.js +14 -1
- package/dist/domain/composition/render.js.map +1 -1
- package/dist/domain/composition/states.js +6 -3
- package/dist/domain/composition/states.js.map +1 -1
- package/dist/domain/composition/types.d.ts +49 -1
- package/dist/domain/session/capabilities.js +1 -0
- package/dist/domain/session/capabilities.js.map +1 -1
- package/dist/domain/spatial/camera-box-sheet.d.ts +15 -0
- package/dist/domain/spatial/camera-box-sheet.js +24 -0
- package/dist/domain/spatial/camera-box-sheet.js.map +1 -0
- package/dist/domain/spatial/camera-box.d.ts +1 -1
- package/dist/domain/spatial/camera-box.js +6 -2
- package/dist/domain/spatial/camera-box.js.map +1 -1
- package/dist/domain/spatial/camera-render-key.d.ts +7 -0
- package/dist/domain/spatial/camera-render-key.js +63 -0
- package/dist/domain/spatial/camera-render-key.js.map +1 -0
- package/dist/domain/spatial/index.d.ts +1 -0
- package/dist/domain/spatial/index.js +1 -0
- package/dist/domain/spatial/index.js.map +1 -1
- package/dist/domain/spatial/lighting.js +3 -2
- package/dist/domain/spatial/lighting.js.map +1 -1
- package/dist/domain/spatial/model.d.ts +2 -0
- package/dist/domain/spatial/model.js +82 -27
- package/dist/domain/spatial/model.js.map +1 -1
- package/dist/domain/spatial/preview.d.ts +4 -0
- package/dist/domain/spatial/preview.js +23 -0
- package/dist/domain/spatial/preview.js.map +1 -0
- package/dist/domain/spatial/reference-lines.d.ts +12 -3
- package/dist/domain/spatial/reference-lines.js +37 -16
- package/dist/domain/spatial/reference-lines.js.map +1 -1
- package/dist/domain/spatial/render-inputs.d.ts +3 -0
- package/dist/domain/spatial/render-inputs.js +14 -0
- package/dist/domain/spatial/render-inputs.js.map +1 -0
- package/dist/domain/spatial/scene-cache.d.ts +13 -1
- package/dist/domain/spatial/scene-cache.js +90 -11
- package/dist/domain/spatial/scene-cache.js.map +1 -1
- package/dist/domain/spatial/scene-update.d.ts +6 -0
- package/dist/domain/spatial/scene-update.js +52 -0
- package/dist/domain/spatial/scene-update.js.map +1 -0
- package/dist/domain/spatial/scene.d.ts +3 -1
- package/dist/domain/spatial/scene.js +78 -20
- package/dist/domain/spatial/scene.js.map +1 -1
- package/dist/domain/spatial/types.d.ts +8 -0
- package/dist/domain/spatial/types.js.map +1 -1
- package/dist/domain/style/model-input.d.ts +3 -0
- package/dist/domain/style/model-input.js +36 -0
- package/dist/domain/style/model-input.js.map +1 -0
- package/dist/domain/style/types.d.ts +8 -1
- package/dist/domain/style/types.js +1 -1
- package/dist/domain/style/types.js.map +1 -1
- package/dist/domain/ui-sketch/clipboard.d.ts +12 -0
- package/dist/domain/ui-sketch/clipboard.js +55 -0
- package/dist/domain/ui-sketch/clipboard.js.map +1 -0
- package/dist/domain/ui-sketch/index.d.ts +1 -0
- package/dist/domain/ui-sketch/index.js +1 -0
- package/dist/domain/ui-sketch/index.js.map +1 -1
- package/dist/server/routes/spatial-sessions.js +39 -15
- package/dist/server/routes/spatial-sessions.js.map +1 -1
- package/dist/server/routes/style-library.js +39 -0
- package/dist/server/routes/style-library.js.map +1 -1
- package/dist/server/spatial-render-service.d.ts +21 -0
- package/dist/server/spatial-render-service.js +67 -0
- package/dist/server/spatial-render-service.js.map +1 -0
- package/dist/server/spatial-render-worker.d.ts +1 -0
- package/dist/server/spatial-render-worker.js +15 -0
- package/dist/server/spatial-render-worker.js.map +1 -0
- package/dist/server/spatial-render.d.ts +15 -3
- package/dist/server/spatial-render.js +47 -14
- package/dist/server/spatial-render.js.map +1 -1
- package/locales/en/common.json +94 -14
- package/migrations/0009_spatial_styles.sql +31 -0
- package/migrations/0010_style_preview_models.sql +8 -0
- package/package.json +1 -1
- package/schemas/composition-draft.schema.json +474 -1
- package/schemas/spatial-draft.schema.json +12 -0
- package/schemas/spatial-operations.schema.json +12 -0
- package/skills/human2ai/SKILL.md +23 -9
- package/skills/human2ai/references/composition.md +192 -1
- package/skills/human2ai/references/spatial-modeling.md +119 -0
- package/skills/human2ai/references/spatial.md +7 -2
- package/web/out/404/index.html +1 -1
- package/web/out/404.html +1 -1
- package/web/out/__next.__PAGE__.txt +7 -5
- package/web/out/__next._full.txt +7 -5
- package/web/out/__next._tree.txt +4 -2
- package/web/out/_next/static/chunks/101.6ef34adad3e9815b.js +1 -0
- package/web/out/_next/static/chunks/130-7e9e715a084569bb.js +1 -0
- package/web/out/_next/static/chunks/166-96a8c6ae1e9aed59.js +1 -0
- package/web/out/_next/static/chunks/218.7b89674409b344b8.js +1 -0
- package/web/out/_next/static/chunks/484.92b016222d6749f2.js +1 -0
- package/web/out/_next/static/chunks/{381-4a803b79da320e6e.js → 635-611c009924b842be.js} +54 -54
- package/web/out/_next/static/chunks/653-6dfb97fec9a2d91b.js +1 -0
- package/web/out/_next/static/chunks/678-32d3aa1859450d63.js +1 -0
- package/web/out/_next/static/chunks/83607670-fd2f339702a222e4.js +1 -0
- package/web/out/_next/static/chunks/app/_not-found/{page-59ce938ad0594022.js → page-b92817fdc4609975.js} +1 -1
- package/web/out/_next/static/chunks/app/composition/page-6c12ee8472715448.js +1 -0
- package/web/out/_next/static/chunks/app/{layout-6351ae607c4ee18d.js → layout-1dd9196cde94389c.js} +1 -1
- package/web/out/_next/static/chunks/app/page-741ecaf9ee8c3c07.js +1 -0
- package/web/out/_next/static/chunks/app/spatial/page-5ba0940650df6c7f.js +1 -0
- package/web/out/_next/static/chunks/app/styles/page-1ccfc2c5fbc1e646.js +1 -0
- package/web/out/_next/static/chunks/app/ui-sketch/page-ef4f2e531583e684.js +1 -0
- package/web/out/_next/static/chunks/{c3f2cda1-9e279dab137b7272.js → c3f2cda1-ef85a0897724e46b.js} +1 -1
- package/web/out/_next/static/chunks/main-app-cf37a257d91ce62e.js +1 -0
- package/web/out/_next/static/chunks/next/dist/client/components/builtin/global-error-33b4f58f02e82215.js +1 -0
- package/web/out/_next/static/chunks/webpack-d16ce1f994e98178.js +1 -0
- package/web/out/_next/static/css/06743b5635914999.css +5 -0
- package/web/out/_next/static/css/0b43ff4a0439c97e.css +1 -0
- package/web/out/_next/static/css/1f8501a43042a5a2.css +1 -0
- package/web/out/_next/static/css/39e8cace36461a15.css +1 -0
- package/web/out/_not-found/__next._full.txt +3 -3
- package/web/out/_not-found/__next._not-found.__PAGE__.txt +3 -3
- package/web/out/_not-found/__next._tree.txt +1 -1
- package/web/out/_not-found/index.html +1 -1
- package/web/out/_not-found/index.txt +3 -3
- package/web/out/composition/__next._full.txt +6 -5
- package/web/out/composition/__next._tree.txt +3 -2
- package/web/out/composition/__next.composition.__PAGE__.txt +6 -5
- package/web/out/composition/index.html +1 -1
- package/web/out/composition/index.txt +6 -5
- package/web/out/index.html +1 -1
- package/web/out/index.txt +7 -5
- package/web/out/spatial/__next._full.txt +6 -5
- package/web/out/spatial/__next._tree.txt +3 -2
- package/web/out/spatial/__next.spatial.__PAGE__.txt +6 -5
- package/web/out/spatial/index.html +1 -1
- package/web/out/spatial/index.txt +6 -5
- package/web/out/styles/__next._full.txt +6 -5
- package/web/out/styles/__next._tree.txt +3 -2
- package/web/out/styles/__next.styles.__PAGE__.txt +6 -5
- package/web/out/styles/index.html +1 -1
- package/web/out/styles/index.txt +6 -5
- package/web/out/ui-sketch/__next._full.txt +6 -5
- package/web/out/ui-sketch/__next._tree.txt +3 -2
- package/web/out/ui-sketch/__next.ui-sketch.__PAGE__.txt +6 -5
- package/web/out/ui-sketch/index.html +1 -1
- package/web/out/ui-sketch/index.txt +6 -5
- package/web/out/_next/static/chunks/130-f2627352fc1e1f49.js +0 -1
- package/web/out/_next/static/chunks/678-b0ea409290a64ff4.js +0 -1
- package/web/out/_next/static/chunks/728-ce64a38c9e8339e8.js +0 -1
- package/web/out/_next/static/chunks/83607670-bc1279370476e59f.js +0 -1
- package/web/out/_next/static/chunks/app/composition/page-b0a2f7370b949cf9.js +0 -1
- package/web/out/_next/static/chunks/app/page-a6fde4165eb4be1e.js +0 -1
- package/web/out/_next/static/chunks/app/spatial/page-2c3df91fd1d7d444.js +0 -1
- package/web/out/_next/static/chunks/app/styles/page-54b11f1945d64255.js +0 -1
- package/web/out/_next/static/chunks/app/ui-sketch/page-1abcd70a81ac7b30.js +0 -1
- package/web/out/_next/static/chunks/main-app-8946bf6a8c0dc843.js +0 -1
- package/web/out/_next/static/chunks/next/dist/client/components/builtin/global-error-5ac7248e26f2e308.js +0 -1
- package/web/out/_next/static/chunks/webpack-97ae63c0e0b2a512.js +0 -1
- package/web/out/_next/static/css/7bfa3a5c92836f5c.css +0 -5
- /package/web/out/_next/static/{1To86KpfZhDmNzmTIgEuy → n4UcxqMmr_2CBmSxBp52z}/_buildManifest.js +0 -0
- /package/web/out/_next/static/{1To86KpfZhDmNzmTIgEuy → n4UcxqMmr_2CBmSxBp52z}/_ssgManifest.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoxGeometry, Color, CylinderGeometry, DoubleSide, Group, Mesh, MeshLambertMaterial, LineSegments, OrthographicCamera, PerspectiveCamera, Quaternion, SphereGeometry, Vector3, } from "three";
|
|
1
|
+
import { BoxGeometry, Color, CylinderGeometry, DoubleSide, Group, InstancedMesh, Matrix4, Mesh, MeshLambertMaterial, LineSegments, OrthographicCamera, PerspectiveCamera, Quaternion, SphereGeometry, Vector3, } from "three";
|
|
2
2
|
import { createCharacterModel } from "./model.js";
|
|
3
3
|
import { jointWorldTransforms, quaternion, vector } from "./kinematics.js";
|
|
4
4
|
import { fingerPart } from "./hands.js";
|
|
@@ -27,25 +27,7 @@ export function createSpatialScene(draft, options = {}) {
|
|
|
27
27
|
scene.add(createCharacterModel(actor, options));
|
|
28
28
|
if (!options.showRig || actor.appearance === "geometric")
|
|
29
29
|
continue;
|
|
30
|
-
|
|
31
|
-
const overlay = (mesh) => {
|
|
32
|
-
mesh.material.depthTest = false;
|
|
33
|
-
mesh.renderOrder = 2;
|
|
34
|
-
};
|
|
35
|
-
for (const joint of actor.joints.filter(j => !j.terminal || Boolean(fingerPart(actor.bones.find(b => b.endJointId === j.id)?.modelPart ?? "")))) {
|
|
36
|
-
overlay(add(new SphereGeometry(joint.radius, 12, 8), "#e6a65c", world[joint.id].position, world[joint.id].rotation, { characterId: actor.id, jointId: joint.id, rig: "joint" }));
|
|
37
|
-
}
|
|
38
|
-
for (const bone of actor.bones) {
|
|
39
|
-
const finger = fingerPart(bone.modelPart);
|
|
40
|
-
if (finger?.segment === 0)
|
|
41
|
-
continue;
|
|
42
|
-
const start = world[bone.startJointId].position, end = world[bone.endJointId].position;
|
|
43
|
-
const direction = end.clone().sub(start), length = direction.length();
|
|
44
|
-
const data = { characterId: actor.id, boneId: bone.id, rig: "bone" };
|
|
45
|
-
const radius = actor.height * (finger ? .0018 : .009);
|
|
46
|
-
const mesh = add(new CylinderGeometry(radius, radius, length, 10), "#728aa1", start.clone().add(end).multiplyScalar(.5), new Quaternion().setFromUnitVectors(new Vector3(0, 1, 0), direction.normalize()), data);
|
|
47
|
-
overlay(mesh);
|
|
48
|
-
}
|
|
30
|
+
updateSpatialRig(scene, actor);
|
|
49
31
|
}
|
|
50
32
|
for (const object of draft.objects) {
|
|
51
33
|
const size = vector(object.size);
|
|
@@ -57,9 +39,85 @@ export function createSpatialScene(draft, options = {}) {
|
|
|
57
39
|
scene.updateMatrixWorld(true);
|
|
58
40
|
return scene;
|
|
59
41
|
}
|
|
42
|
+
/** Unit helper geometry survives pose/proportion changes; only transforms change. */
|
|
43
|
+
export function updateSpatialRig(scene, actor, batch = false) {
|
|
44
|
+
const parts = spatialRigParts(actor);
|
|
45
|
+
if (batch) {
|
|
46
|
+
const matrix = new Matrix4();
|
|
47
|
+
for (const rig of ["joint", "bone"]) {
|
|
48
|
+
const instances = parts.filter(part => part.data.rig === rig);
|
|
49
|
+
let mesh = scene.children.find(object => object instanceof InstancedMesh && object.userData.characterId === actor.id && object.userData.rig === rig);
|
|
50
|
+
if (mesh && mesh.count !== instances.length) {
|
|
51
|
+
scene.remove(mesh);
|
|
52
|
+
disposeSpatialScene(new Group().add(mesh));
|
|
53
|
+
mesh = undefined;
|
|
54
|
+
}
|
|
55
|
+
if (!mesh) {
|
|
56
|
+
mesh = new InstancedMesh(rigGeometry(rig), new MeshLambertMaterial({ side: DoubleSide, depthTest: false }), instances.length);
|
|
57
|
+
mesh.renderOrder = 2;
|
|
58
|
+
scene.add(mesh);
|
|
59
|
+
}
|
|
60
|
+
mesh.userData = { characterId: actor.id, rig, instances: instances.map(part => part.data) };
|
|
61
|
+
const color = new Color(rig === "joint" ? "#e6a65c" : "#728aa1");
|
|
62
|
+
instances.forEach((part, i) => {
|
|
63
|
+
mesh.setMatrixAt(i, matrix.compose(part.position, part.rotation, part.scale));
|
|
64
|
+
mesh.setColorAt(i, color);
|
|
65
|
+
});
|
|
66
|
+
mesh.instanceMatrix.needsUpdate = true;
|
|
67
|
+
if (mesh.instanceColor)
|
|
68
|
+
mesh.instanceColor.needsUpdate = true;
|
|
69
|
+
mesh.computeBoundingSphere();
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const existing = new Map(scene.children.filter(object => object.userData.rig && object.userData.characterId === actor.id)
|
|
74
|
+
.map(object => [`${object.userData.rig}/${object.userData.jointId ?? object.userData.boneId}`, object]));
|
|
75
|
+
const add = (rig, id) => {
|
|
76
|
+
const key = `${rig}/${id}`;
|
|
77
|
+
let mesh = existing.get(key);
|
|
78
|
+
existing.delete(key);
|
|
79
|
+
if (!mesh) {
|
|
80
|
+
mesh = new Mesh(rigGeometry(rig), new MeshLambertMaterial({ side: DoubleSide, depthTest: false }));
|
|
81
|
+
mesh.userData = { characterId: actor.id, rig, [rig === "joint" ? "jointId" : "boneId"]: id };
|
|
82
|
+
mesh.renderOrder = 2;
|
|
83
|
+
scene.add(mesh);
|
|
84
|
+
}
|
|
85
|
+
mesh.material.color.set(rig === "joint" ? "#e6a65c" : "#728aa1");
|
|
86
|
+
return mesh;
|
|
87
|
+
};
|
|
88
|
+
for (const part of parts) {
|
|
89
|
+
const mesh = add(part.data.rig, part.data.jointId ?? part.data.boneId);
|
|
90
|
+
mesh.position.copy(part.position);
|
|
91
|
+
mesh.quaternion.copy(part.rotation);
|
|
92
|
+
mesh.scale.copy(part.scale);
|
|
93
|
+
}
|
|
94
|
+
for (const mesh of existing.values()) {
|
|
95
|
+
scene.remove(mesh);
|
|
96
|
+
mesh.geometry.dispose();
|
|
97
|
+
mesh.material.dispose();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const rigGeometry = (rig) => rig === "joint" ? new SphereGeometry(1, 12, 8) : new CylinderGeometry(1, 1, 1, 10);
|
|
101
|
+
function spatialRigParts(actor) {
|
|
102
|
+
const world = jointWorldTransforms(actor), parts = [];
|
|
103
|
+
for (const joint of actor.joints.filter(j => !j.terminal || Boolean(fingerPart(actor.bones.find(b => b.endJointId === j.id)?.modelPart ?? "")))) {
|
|
104
|
+
parts.push({ data: { characterId: actor.id, rig: "joint", jointId: joint.id }, position: world[joint.id].position, rotation: world[joint.id].rotation, scale: new Vector3().setScalar(joint.radius) });
|
|
105
|
+
}
|
|
106
|
+
for (const bone of actor.bones) {
|
|
107
|
+
const finger = fingerPart(bone.modelPart);
|
|
108
|
+
if (finger?.segment === 0)
|
|
109
|
+
continue;
|
|
110
|
+
const start = world[bone.startJointId].position, end = world[bone.endJointId].position;
|
|
111
|
+
const direction = end.clone().sub(start), length = direction.length(), radius = actor.height * (finger ? .0018 : .009);
|
|
112
|
+
parts.push({ data: { characterId: actor.id, rig: "bone", boneId: bone.id }, position: start.clone().add(end).multiplyScalar(.5), rotation: new Quaternion().setFromUnitVectors(new Vector3(0, 1, 0), direction.normalize()), scale: new Vector3(radius, length, radius) });
|
|
113
|
+
}
|
|
114
|
+
return parts;
|
|
115
|
+
}
|
|
60
116
|
export function disposeSpatialScene(scene) {
|
|
61
117
|
scene.traverse(object => {
|
|
62
118
|
if (object instanceof Mesh || object instanceof LineSegments) {
|
|
119
|
+
if (object instanceof InstancedMesh)
|
|
120
|
+
object.dispose();
|
|
63
121
|
object.geometry.dispose();
|
|
64
122
|
for (const material of Array.isArray(object.material) ? object.material : [object.material])
|
|
65
123
|
material.dispose();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene.js","sourceRoot":"","sources":["../../../src/domain/spatial/scene.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAAE,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"scene.js","sourceRoot":"","sources":["../../../src/domain/spatial/scene.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,6 +37,8 @@ export interface SpatialBone {
|
|
|
37
37
|
export interface SpatialCharacter extends SpatialBodyShape {
|
|
38
38
|
id: string;
|
|
39
39
|
name: string;
|
|
40
|
+
/** User instructions for this entity; absent means no note. */
|
|
41
|
+
note?: string;
|
|
40
42
|
kind: "humanoid" | "custom";
|
|
41
43
|
position: Vec3;
|
|
42
44
|
rotation: Vec3;
|
|
@@ -56,6 +58,8 @@ export interface SpatialCharacter extends SpatialBodyShape {
|
|
|
56
58
|
export interface SpatialObject {
|
|
57
59
|
id: string;
|
|
58
60
|
name: string;
|
|
61
|
+
/** User instructions for this entity; absent means no note. */
|
|
62
|
+
note?: string;
|
|
59
63
|
kind: "box" | "sphere" | "plane";
|
|
60
64
|
position: Vec3;
|
|
61
65
|
rotation: Vec3;
|
|
@@ -65,6 +69,8 @@ export interface SpatialObject {
|
|
|
65
69
|
export interface SpatialCamera {
|
|
66
70
|
id: string;
|
|
67
71
|
name: string;
|
|
72
|
+
/** User instructions for this entity; absent means no note. */
|
|
73
|
+
note?: string;
|
|
68
74
|
position: Vec3;
|
|
69
75
|
target: Vec3;
|
|
70
76
|
projection: "perspective" | "orthographic";
|
|
@@ -87,6 +93,8 @@ export interface SpatialDraft {
|
|
|
87
93
|
export interface SpatialCameraBox {
|
|
88
94
|
id: string;
|
|
89
95
|
name: string;
|
|
96
|
+
/** User instructions for this entity; absent means no note. */
|
|
97
|
+
note?: string;
|
|
90
98
|
position: Vec3;
|
|
91
99
|
rotation: Vec3;
|
|
92
100
|
/** Cubic crop edge length in metres. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/spatial/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/spatial/types.ts"],"names":[],"mappings":"AAoGA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAU,CAAC;AAG9F,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAoBlC,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const MAX_STYLE_MODEL_BYTES = 10 * 1024 * 1024;
|
|
2
|
+
/** Accept a self-contained, static GLB example, never executable generator code. */
|
|
3
|
+
export function validStyleModel(data) {
|
|
4
|
+
if (!Buffer.isBuffer(data) || data.length < 28 || data.length > MAX_STYLE_MODEL_BYTES)
|
|
5
|
+
return false;
|
|
6
|
+
if (data.readUInt32LE(0) !== 0x46546c67 || data.readUInt32LE(4) !== 2 || data.readUInt32LE(8) !== data.length)
|
|
7
|
+
return false;
|
|
8
|
+
const jsonLength = data.readUInt32LE(12);
|
|
9
|
+
if (jsonLength % 4 || 20 + jsonLength > data.length || data.readUInt32LE(16) !== 0x4e4f534a)
|
|
10
|
+
return false;
|
|
11
|
+
try {
|
|
12
|
+
const document = JSON.parse(data.subarray(20, 20 + jsonLength).toString("utf8"));
|
|
13
|
+
if (document.asset?.version !== "2.0" || !document.scenes?.length || !document.nodes?.length || !document.meshes?.length)
|
|
14
|
+
return false;
|
|
15
|
+
// Textures and geometry must live in this file, with no decoder dependencies.
|
|
16
|
+
if (document.extensionsRequired?.some((name) => ["KHR_draco_mesh_compression", "EXT_meshopt_compression", "KHR_texture_basisu"].includes(name)))
|
|
17
|
+
return false;
|
|
18
|
+
if (JSON.stringify(document).includes('"uri":'))
|
|
19
|
+
return false;
|
|
20
|
+
const binaryOffset = 20 + jsonLength;
|
|
21
|
+
if (binaryOffset + 8 > data.length || data.readUInt32LE(binaryOffset + 4) !== 0x004e4942)
|
|
22
|
+
return false;
|
|
23
|
+
const binaryLength = data.readUInt32LE(binaryOffset);
|
|
24
|
+
if (binaryLength % 4 || binaryOffset + 8 + binaryLength !== data.length)
|
|
25
|
+
return false;
|
|
26
|
+
if (document.buffers?.length !== 1 || !Number.isInteger(document.buffers[0].byteLength) || document.buffers[0].byteLength <= 0 || document.buffers[0].byteLength > binaryLength)
|
|
27
|
+
return false;
|
|
28
|
+
return Array.isArray(document.bufferViews) && document.bufferViews.every((view) => (view.buffer === 0 && Number.isInteger(view.byteOffset ?? 0) && (view.byteOffset ?? 0) >= 0
|
|
29
|
+
&& Number.isInteger(view.byteLength) && view.byteLength > 0
|
|
30
|
+
&& (view.byteOffset ?? 0) + view.byteLength <= document.buffers[0].byteLength));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=model-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-input.js","sourceRoot":"","sources":["../../../src/domain/style/model-input.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD,oFAAoF;AACpF,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,GAAG,qBAAqB;QAAE,OAAO,KAAK,CAAC;IACpG,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC5H,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACzC,IAAI,UAAU,GAAG,CAAC,IAAI,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAC1G,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,UAAU,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACjF,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;YAAE,OAAO,KAAK,CAAC;QACvI,8EAA8E;QAC9E,IAAI,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,4BAA4B,EAAE,yBAAyB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACtK,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QAC9D,MAAM,YAAY,GAAG,EAAE,GAAG,UAAU,CAAC;QACrC,IAAI,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,CAAC,CAAC,KAAK,UAAU;YAAE,OAAO,KAAK,CAAC;QACvG,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACrD,IAAI,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,CAAC,GAAG,YAAY,KAAK,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACtF,IAAI,QAAQ,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,YAAY;YAAE,OAAO,KAAK,CAAC;QAC9L,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAiE,EAAE,EAAE,CAAC,CAC9I,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC;eACvF,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC;eACxD,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAC9E,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Session } from "../session/types.ts";
|
|
2
|
-
export declare const STYLE_CATEGORIES: readonly ["visual", "ui"];
|
|
2
|
+
export declare const STYLE_CATEGORIES: readonly ["visual", "ui", "spatial"];
|
|
3
3
|
export type StyleCategory = (typeof STYLE_CATEGORIES)[number];
|
|
4
4
|
export declare const STYLE_CREATOR_TYPES: readonly ["user", "agent"];
|
|
5
5
|
export type StyleCreatorType = (typeof STYLE_CREATOR_TYPES)[number];
|
|
@@ -22,10 +22,17 @@ export interface StyleEntry {
|
|
|
22
22
|
description: string;
|
|
23
23
|
promptSummary: string;
|
|
24
24
|
referenceImages: StyleReferenceImage[];
|
|
25
|
+
previewModel?: StylePreviewModel;
|
|
25
26
|
revision: number;
|
|
26
27
|
createdAt: string;
|
|
27
28
|
updatedAt: string;
|
|
28
29
|
}
|
|
30
|
+
export interface StylePreviewModel {
|
|
31
|
+
id: string;
|
|
32
|
+
originalFilename: string;
|
|
33
|
+
byteSize: number;
|
|
34
|
+
createdAt: string;
|
|
35
|
+
}
|
|
29
36
|
export interface SessionStyleState {
|
|
30
37
|
session: Session;
|
|
31
38
|
style: StyleEntry | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/style/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/domain/style/types.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAU,CAAC;AAGrE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAU,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { UiSketchDraft } from "./types.ts";
|
|
2
|
+
export type UiSketchClipboard = Pick<UiSketchDraft, "rectangles" | "texts" | "images" | "groups"> & {
|
|
3
|
+
layerOrder: string[];
|
|
4
|
+
};
|
|
5
|
+
export declare function copyUiSketchItems(draft: UiSketchDraft, itemIds: readonly string[]): UiSketchClipboard;
|
|
6
|
+
export declare function pasteUiSketchItems(input: UiSketchDraft, clipboard: UiSketchClipboard, offset: {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
}, stageId?: string): {
|
|
10
|
+
draft: UiSketchDraft;
|
|
11
|
+
ids: string[];
|
|
12
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { UI_SKETCH_START_STAGE_ID, uiSketchDraftForStage, updateUiSketchStageDraft } from "./draft.js";
|
|
2
|
+
import { uiSketchSelectionWithGroups } from "./groups.js";
|
|
3
|
+
import { uiSketchLayerOrder } from "./layers.js";
|
|
4
|
+
export function copyUiSketchItems(draft, itemIds) {
|
|
5
|
+
const selected = new Set(uiSketchSelectionWithGroups(draft, itemIds));
|
|
6
|
+
return structuredClone({
|
|
7
|
+
rectangles: draft.rectangles.filter((item) => selected.has(item.id)),
|
|
8
|
+
texts: draft.texts.filter((item) => selected.has(item.id)),
|
|
9
|
+
images: draft.images.filter((item) => selected.has(item.id)),
|
|
10
|
+
groups: draft.groups.filter((group) => group.itemIds.every((id) => selected.has(id))),
|
|
11
|
+
layerOrder: uiSketchLayerOrder(draft).filter((id) => selected.has(id)),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function pasteUiSketchItems(input, clipboard, offset, stageId = UI_SKETCH_START_STAGE_ID) {
|
|
15
|
+
if (clipboard.layerOrder.length === 0)
|
|
16
|
+
return { draft: input, ids: [] };
|
|
17
|
+
const draft = uiSketchDraftForStage(input, stageId);
|
|
18
|
+
const usedIds = new Set([
|
|
19
|
+
...draft.rectangles, ...draft.texts, ...draft.images, ...draft.groups,
|
|
20
|
+
...clipboard.rectangles, ...clipboard.texts, ...clipboard.images, ...clipboard.groups,
|
|
21
|
+
].map((item) => item.id));
|
|
22
|
+
const copiedIds = new Map();
|
|
23
|
+
function nextId(prefix) {
|
|
24
|
+
let index = 1;
|
|
25
|
+
while (usedIds.has(`${prefix}-${index}`))
|
|
26
|
+
index += 1;
|
|
27
|
+
const id = `${prefix}-${index}`;
|
|
28
|
+
usedIds.add(id);
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
function copyItems(items, prefix) {
|
|
32
|
+
return items.map((item) => {
|
|
33
|
+
const id = nextId(prefix);
|
|
34
|
+
copiedIds.set(item.id, id);
|
|
35
|
+
return {
|
|
36
|
+
...structuredClone(item),
|
|
37
|
+
id,
|
|
38
|
+
origin: "user",
|
|
39
|
+
x: item.x + offset.x,
|
|
40
|
+
y: item.y + offset.y,
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
draft.rectangles.push(...copyItems(clipboard.rectangles, "rectangle"));
|
|
45
|
+
draft.texts.push(...copyItems(clipboard.texts, "text"));
|
|
46
|
+
draft.images.push(...copyItems(clipboard.images, "image"));
|
|
47
|
+
draft.groups.push(...clipboard.groups.map((group) => ({
|
|
48
|
+
id: nextId("group"),
|
|
49
|
+
itemIds: group.itemIds.map((id) => copiedIds.get(id)),
|
|
50
|
+
})));
|
|
51
|
+
const ids = clipboard.layerOrder.map((id) => copiedIds.get(id));
|
|
52
|
+
draft.layerOrder = [...uiSketchLayerOrder(input), ...ids];
|
|
53
|
+
return { draft: updateUiSketchStageDraft(input, stageId, draft), ids };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=clipboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../../src/domain/ui-sketch/clipboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,4 +5,5 @@ export { standardizeUiSketchDraft, UI_LAYOUT_ALIGNMENT_TOLERANCE } from "./stand
|
|
|
5
5
|
export { groupUiSketchItems, ungroupUiSketchItems, uiSketchSelectionWithGroups, retainUiSketchGroups } from "./groups.ts";
|
|
6
6
|
export { uiSketchStateTabs, renameUiSketchState, deleteUiSketchState, reorderUiSketchStates } from "./states.ts";
|
|
7
7
|
export { uiSketchLayerOrder, reorderUiSketchLayers } from "./layers.ts";
|
|
8
|
+
export { copyUiSketchItems, pasteUiSketchItems, type UiSketchClipboard } from "./clipboard.ts";
|
|
8
9
|
export { renderUiSketchSvg } from "./render.ts";
|
|
@@ -4,5 +4,6 @@ export { standardizeUiSketchDraft, UI_LAYOUT_ALIGNMENT_TOLERANCE } from "./stand
|
|
|
4
4
|
export { groupUiSketchItems, ungroupUiSketchItems, uiSketchSelectionWithGroups, retainUiSketchGroups } from "./groups.js";
|
|
5
5
|
export { uiSketchStateTabs, renameUiSketchState, deleteUiSketchState, reorderUiSketchStates } from "./states.js";
|
|
6
6
|
export { uiSketchLayerOrder, reorderUiSketchLayers } from "./layers.js";
|
|
7
|
+
export { copyUiSketchItems, pasteUiSketchItems } from "./clipboard.js";
|
|
7
8
|
export { renderUiSketchSvg } from "./render.js";
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/ui-sketch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE1H,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEjH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/ui-sketch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE1H,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEjH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAA0B,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
import schema from "../../../schemas/spatial-draft.schema.json" with { type: "json" };
|
|
2
2
|
import { createSpatialDraft, SpatialConstraintError } from "../../domain/spatial/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { SpatialRenderService } from "../spatial-render-service.js";
|
|
4
|
+
import { SpatialCameraRenderKeys } from "../../domain/spatial/camera-render-key.js";
|
|
5
|
+
import { cameraBoxView } from "../../domain/spatial/camera-box.js";
|
|
4
6
|
import { SPATIAL_BOX_FACES, SPATIAL_RENDER_PASSES } from "../../domain/spatial/types.js";
|
|
7
|
+
import { parseSpatialBoxViews } from "../../domain/spatial/camera-box-sheet.js";
|
|
8
|
+
import en from "../../../locales/en/common.json" with { type: "json" };
|
|
5
9
|
import { registerDraftVersionRoutes, replyToDraftVersionError } from "./draft-version-routes.js";
|
|
6
10
|
export function registerSpatialSessionRoutes(server, repository) {
|
|
7
11
|
const { $schema: _dialect, ...fastifySchema } = schema;
|
|
8
12
|
server.addSchema(fastifySchema);
|
|
9
13
|
registerDraftVersionRoutes(server, { routePrefix: "/api/v1/sessions/:sessionId/spatial", draftSchema: { $ref: schema.$id }, repository });
|
|
10
14
|
const cache = new Map();
|
|
15
|
+
const inFlight = new Map();
|
|
16
|
+
const renderer = new SpatialRenderService(), renderKeys = new SpatialCameraRenderKeys();
|
|
17
|
+
server.addHook("onClose", () => renderer.close());
|
|
11
18
|
const cached = (key, render) => {
|
|
12
|
-
|
|
19
|
+
const image = cache.get(key);
|
|
20
|
+
if (image) {
|
|
21
|
+
cache.delete(key);
|
|
22
|
+
cache.set(key, image);
|
|
23
|
+
return Promise.resolve(image);
|
|
24
|
+
}
|
|
25
|
+
let pending = inFlight.get(key);
|
|
13
26
|
if (!pending) {
|
|
14
|
-
pending = render()
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
pending = render().then(image => {
|
|
28
|
+
cache.set(key, image);
|
|
29
|
+
if (cache.size > 24)
|
|
30
|
+
cache.delete(cache.keys().next().value);
|
|
31
|
+
return image;
|
|
32
|
+
}).finally(() => { inFlight.delete(key); });
|
|
33
|
+
inFlight.set(key, pending);
|
|
20
34
|
}
|
|
21
35
|
return pending;
|
|
22
36
|
};
|
|
@@ -44,8 +58,8 @@ export function registerSpatialSessionRoutes(server, repository) {
|
|
|
44
58
|
if (!camera)
|
|
45
59
|
return reply.code(404).send({ code: "SPATIAL_CAMERA_NOT_FOUND", message: "Camera not found" });
|
|
46
60
|
const pass = request.query.pass ?? "color";
|
|
47
|
-
const key = JSON.stringify([sessionId,
|
|
48
|
-
const pending = cached(key, () =>
|
|
61
|
+
const key = JSON.stringify([sessionId, cameraId, renderKeys.key(draft, camera, pass)]);
|
|
62
|
+
const pending = cached(key, () => renderer.render({ draft, camera, pass }));
|
|
49
63
|
return reply.header("cache-control", request.query.revision ? "private, max-age=31536000, immutable" : "no-cache")
|
|
50
64
|
.header("x-spatial-revision", version?.revision ?? 0).header("x-spatial-render-pass", pass).type("image/png").send(await pending);
|
|
51
65
|
}
|
|
@@ -56,18 +70,28 @@ export function registerSpatialSessionRoutes(server, repository) {
|
|
|
56
70
|
throw error;
|
|
57
71
|
}
|
|
58
72
|
});
|
|
59
|
-
server.get("/api/v1/sessions/:sessionId/spatial/camera-boxes/:boxId.png", { schema: { querystring: { type: "object", properties: { revision: { type: "integer", minimum: 1 }, pass: { type: "string", enum: [...SPATIAL_RENDER_PASSES] }, view: { type: "string", enum: ["sheet", ...SPATIAL_BOX_FACES] } } } } }, async (request, reply) => {
|
|
73
|
+
server.get("/api/v1/sessions/:sessionId/spatial/camera-boxes/:boxId.png", { schema: { querystring: { type: "object", properties: { revision: { type: "integer", minimum: 1 }, pass: { type: "string", enum: [...SPATIAL_RENDER_PASSES] }, view: { type: "string", enum: ["sheet", ...SPATIAL_BOX_FACES] }, views: { type: "string", minLength: 1, maxLength: 128 } } } } }, async (request, reply) => {
|
|
60
74
|
try {
|
|
75
|
+
if (request.query.view !== undefined && request.query.views !== undefined)
|
|
76
|
+
return reply.code(400).send({ code: "SPATIAL_INVALID", message: en.spatial.cameraBoxViewConflict });
|
|
77
|
+
const views = request.query.views === undefined ? undefined : parseSpatialBoxViews(request.query.views);
|
|
78
|
+
if (views === null)
|
|
79
|
+
return reply.code(400).send({ code: "SPATIAL_INVALID", message: en.spatial.cameraBoxViewsError });
|
|
61
80
|
const { sessionId, boxId } = request.params;
|
|
62
81
|
const version = request.query.revision ? repository.getDraftVersion(sessionId, request.query.revision) : repository.listDraftVersions(sessionId).at(-1);
|
|
63
82
|
const box = version?.draft.cameraBoxes?.find(box => box.id === boxId);
|
|
64
83
|
if (!box || !version)
|
|
65
84
|
return reply.code(404).send({ code: "SPATIAL_CAMERA_NOT_FOUND", message: "Camera box not found" });
|
|
66
|
-
const pass = request.query.pass ?? "color", view = request.query.view ?? "sheet";
|
|
67
|
-
const
|
|
68
|
-
const
|
|
85
|
+
const pass = request.query.pass ?? "color", view = views ?? request.query.view ?? "sheet";
|
|
86
|
+
const faces = typeof view === "string" ? view === "sheet" ? SPATIAL_BOX_FACES : [view] : view;
|
|
87
|
+
const key = JSON.stringify([sessionId, "camera-box", boxId, view, faces.map(face => {
|
|
88
|
+
const { source, camera } = cameraBoxView(box, face);
|
|
89
|
+
return renderKeys.key(version.draft, source, pass, camera);
|
|
90
|
+
})]);
|
|
91
|
+
const png = cached(key, () => renderer.render({ draft: version.draft, box, view, pass }));
|
|
69
92
|
return reply.header("cache-control", request.query.revision ? "private, max-age=31536000, immutable" : "no-cache")
|
|
70
|
-
.header("x-spatial-revision", version.revision).header("x-spatial-render-pass", pass).header("x-spatial-box-view", view
|
|
93
|
+
.header("x-spatial-revision", version.revision).header("x-spatial-render-pass", pass).header("x-spatial-box-view", typeof view === "string" ? view : "sheet")
|
|
94
|
+
.header("x-spatial-box-views", views?.join(",") ?? (view === "sheet" ? SPATIAL_BOX_FACES.join(",") : view)).type("image/png").send(await png);
|
|
71
95
|
}
|
|
72
96
|
catch (error) {
|
|
73
97
|
const handled = replyToDraftVersionError(reply, error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spatial-sessions.js","sourceRoot":"","sources":["../../../src/server/routes/spatial-sessions.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,4CAA4C,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAyB,MAAM,+BAA+B,CAAC;AAClH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"spatial-sessions.js","sourceRoot":"","sources":["../../../src/server/routes/spatial-sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -45,6 +45,14 @@ const referenceImageSchema = {
|
|
|
45
45
|
createdAt: { type: "string" },
|
|
46
46
|
},
|
|
47
47
|
};
|
|
48
|
+
const previewModelSchema = {
|
|
49
|
+
type: "object", additionalProperties: false,
|
|
50
|
+
required: ["id", "originalFilename", "byteSize", "createdAt"],
|
|
51
|
+
properties: {
|
|
52
|
+
id: { type: "string" }, originalFilename: { type: "string" },
|
|
53
|
+
byteSize: { type: "integer", minimum: 1 }, createdAt: { type: "string" },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
48
56
|
const styleSchema = {
|
|
49
57
|
type: "object",
|
|
50
58
|
additionalProperties: false,
|
|
@@ -68,6 +76,7 @@ const styleSchema = {
|
|
|
68
76
|
description: { type: "string" },
|
|
69
77
|
promptSummary: { type: "string" },
|
|
70
78
|
referenceImages: { type: "array", items: referenceImageSchema },
|
|
79
|
+
previewModel: previewModelSchema,
|
|
71
80
|
revision: { type: "integer", minimum: 1 },
|
|
72
81
|
createdAt: { type: "string" },
|
|
73
82
|
updatedAt: { type: "string" },
|
|
@@ -153,6 +162,10 @@ export function registerStyleLibraryRoutes(server, repository) {
|
|
|
153
162
|
properties: { url: { type: "string" } },
|
|
154
163
|
},
|
|
155
164
|
},
|
|
165
|
+
previewModel: {
|
|
166
|
+
type: "object", additionalProperties: false, required: ["url"],
|
|
167
|
+
properties: { url: { type: "string" } },
|
|
168
|
+
},
|
|
156
169
|
description: { type: "string" },
|
|
157
170
|
},
|
|
158
171
|
},
|
|
@@ -162,6 +175,7 @@ export function registerStyleLibraryRoutes(server, repository) {
|
|
|
162
175
|
}, async (request, reply) => execute(reply, 200, () => {
|
|
163
176
|
const style = repository.getStyle(request.params.styleId);
|
|
164
177
|
return {
|
|
178
|
+
...(style.previewModel ? { previewModel: { url: styleModelContentPath(style.id, style.previewModel.id) } } : {}),
|
|
165
179
|
referenceImages: style.referenceImages.map((reference) => ({
|
|
166
180
|
url: styleReferenceContentPath(style.id, reference.id),
|
|
167
181
|
})),
|
|
@@ -204,6 +218,28 @@ export function registerStyleLibraryRoutes(server, repository) {
|
|
|
204
218
|
response: { 400: errorSchema, 404: errorSchema, 409: errorSchema },
|
|
205
219
|
},
|
|
206
220
|
}, async (request, reply) => execute(reply, 204, () => (repository.deleteStyle(request.params.styleId, request.body))));
|
|
221
|
+
server.post("/api/v1/styles/:styleId/model", { schema: {
|
|
222
|
+
params: styleParamsSchema,
|
|
223
|
+
querystring: {
|
|
224
|
+
type: "object", additionalProperties: false, required: ["filename", "expectedRevision"],
|
|
225
|
+
properties: { filename: { type: "string", minLength: 1, maxLength: 255 }, expectedRevision: { type: "integer", minimum: 1 } },
|
|
226
|
+
},
|
|
227
|
+
response: { 200: styleSchema, 400: errorSchema, 404: errorSchema, 409: errorSchema },
|
|
228
|
+
} }, async (request, reply) => execute(reply, 200, () => repository.setPreviewModel(request.params.styleId, {
|
|
229
|
+
...request.query, data: request.body,
|
|
230
|
+
})));
|
|
231
|
+
server.delete("/api/v1/styles/:styleId/model", { schema: { params: styleParamsSchema, body: revisionBodySchema, response: { 200: styleSchema, 404: errorSchema, 409: errorSchema } } }, async (request, reply) => execute(reply, 200, () => repository.deletePreviewModel(request.params.styleId, request.body)));
|
|
232
|
+
server.get("/api/v1/styles/:styleId/models/:referenceId/content", { schema: { params: referenceParamsSchema, response: { 404: errorSchema } } }, async (request, reply) => {
|
|
233
|
+
try {
|
|
234
|
+
const { model, filePath } = repository.getPreviewModel(request.params.styleId, request.params.referenceId);
|
|
235
|
+
return reply.header("cache-control", "private, max-age=31536000, immutable")
|
|
236
|
+
.header("content-length", model.byteSize).header("x-content-type-options", "nosniff")
|
|
237
|
+
.type("model/gltf-binary").send(createReadStream(filePath));
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
return sendStyleError(reply, error);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
207
243
|
server.post("/api/v1/styles/:styleId/references", {
|
|
208
244
|
schema: {
|
|
209
245
|
params: styleParamsSchema,
|
|
@@ -305,4 +341,7 @@ function sendStyleError(reply, error) {
|
|
|
305
341
|
function styleReferenceContentPath(styleId, referenceId) {
|
|
306
342
|
return `/api/v1/styles/${encodeURIComponent(styleId)}/references/${encodeURIComponent(referenceId)}/content`;
|
|
307
343
|
}
|
|
344
|
+
function styleModelContentPath(styleId, modelId) {
|
|
345
|
+
return `/api/v1/styles/${encodeURIComponent(styleId)}/models/${encodeURIComponent(modelId)}/content`;
|
|
346
|
+
}
|
|
308
347
|
//# sourceMappingURL=style-library.js.map
|