@instruktlabs/kiln 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +19 -0
- package/.claude-plugin/plugin.json +30 -0
- package/.codex-plugin/plugin.json +37 -0
- package/.mcp.json +10 -0
- package/CHANGELOG.md +2579 -0
- package/CONTRIBUTING.md +130 -0
- package/LICENSE +21 -0
- package/README.md +443 -2
- package/THIRD_PARTY_NOTICES.md +62 -0
- package/dist/agent-providers.mjs +310 -0
- package/dist/agent-run.mjs +40433 -0
- package/dist/build.json +215 -0
- package/dist/cli.mjs +48027 -0
- package/dist/evaluator-worker.mjs +27572 -0
- package/dist/mcp-engine.mjs +43537 -0
- package/dist/mcp-server.mjs +2388 -0
- package/dist/viewer/app.js +4281 -0
- package/dist/viewer/chat.html +4409 -0
- package/dist/viewer/index.html +51 -0
- package/dist/viewer/style.css +51 -0
- package/docs/architecture.md +77 -0
- package/docs/cameras.md +181 -0
- package/docs/chatgpt.md +48 -0
- package/docs/collections.md +195 -0
- package/docs/community-exporter.md +95 -0
- package/docs/engine-handoff.md +221 -0
- package/docs/examples.md +171 -0
- package/docs/export-profiles.md +223 -0
- package/docs/extending.md +43 -0
- package/docs/geometry.md +505 -0
- package/docs/google.md +121 -0
- package/docs/harnesses.md +372 -0
- package/docs/install.md +542 -0
- package/docs/material-library.md +133 -0
- package/docs/migration.md +809 -0
- package/docs/programs.md +123 -0
- package/docs/projects-and-live-review.md +94 -0
- package/docs/rendering.md +250 -0
- package/docs/runtime.md +223 -0
- package/docs/sdk.md +137 -0
- package/docs/tools.md +1874 -0
- package/lib/_types/render-service/src/build-identity.d.mts +24 -0
- package/lib/_types/render-service/src/instance.d.mts +47 -0
- package/lib/agent/call-budget.d.ts +55 -0
- package/lib/agent/call-budget.js +52 -0
- package/lib/agent/compaction.d.ts +83 -0
- package/lib/agent/compaction.js +124 -0
- package/lib/agent/concurrency.d.ts +8 -0
- package/lib/agent/concurrency.js +24 -0
- package/lib/agent/diff.d.ts +23 -0
- package/lib/agent/diff.js +124 -0
- package/lib/agent/generate.d.ts +192 -0
- package/lib/agent/generate.js +240 -0
- package/lib/agent/hooks.d.ts +91 -0
- package/lib/agent/hooks.js +158 -0
- package/lib/agent/index.d.ts +42 -0
- package/lib/agent/index.js +30 -0
- package/lib/agent/native-prompt.d.ts +15 -0
- package/lib/agent/native-prompt.js +29 -0
- package/lib/agent/native-workflow.d.ts +4 -0
- package/lib/agent/native-workflow.js +30 -0
- package/lib/agent/providers.d.ts +188 -0
- package/lib/agent/providers.js +392 -0
- package/lib/agent/run.d.ts +72 -0
- package/lib/agent/run.js +245 -0
- package/lib/agent/skill-resources.d.ts +9 -0
- package/lib/agent/skill-resources.js +178 -0
- package/lib/agent/split-tool-result-images.d.ts +33 -0
- package/lib/agent/split-tool-result-images.js +47 -0
- package/lib/agent/stream-start.d.ts +30 -0
- package/lib/agent/stream-start.js +32 -0
- package/lib/agent/tools.d.ts +12 -0
- package/lib/agent/tools.js +77 -0
- package/lib/agent/view-render-timeout.d.ts +40 -0
- package/lib/agent/view-render-timeout.js +71 -0
- package/lib/animation-cubic.d.ts +12 -0
- package/lib/animation-cubic.js +44 -0
- package/lib/animation-spline.d.ts +50 -0
- package/lib/animation-spline.js +168 -0
- package/lib/architecture.d.ts +146 -0
- package/lib/architecture.js +498 -0
- package/lib/arena/adaptive.d.ts +38 -0
- package/lib/arena/adaptive.js +87 -0
- package/lib/arena/bradley-terry.d.ts +63 -0
- package/lib/arena/bradley-terry.js +165 -0
- package/lib/arena/index.d.ts +15 -0
- package/lib/arena/index.js +13 -0
- package/lib/assembly-transform.d.ts +7 -0
- package/lib/assembly-transform.js +21 -0
- package/lib/assembly.d.ts +105 -0
- package/lib/assembly.js +587 -0
- package/lib/asset-catalog.d.ts +13 -0
- package/lib/asset-catalog.js +21 -0
- package/lib/asset-export.d.ts +41 -0
- package/lib/asset-export.js +106 -0
- package/lib/asset-materials-node.d.ts +5 -0
- package/lib/asset-materials-node.js +56 -0
- package/lib/asset-widget.d.ts +10 -0
- package/lib/asset-widget.js +23 -0
- package/lib/assets-node.d.ts +33 -0
- package/lib/assets-node.js +348 -0
- package/lib/assets-resources.d.ts +33 -0
- package/lib/assets-resources.js +109 -0
- package/lib/assets.d.ts +91 -0
- package/lib/assets.js +205 -0
- package/lib/atomic-directory.d.ts +9 -0
- package/lib/atomic-directory.js +31 -0
- package/lib/authoring-style.d.ts +3 -0
- package/lib/authoring-style.js +42 -0
- package/lib/build-cache-node.d.ts +12 -0
- package/lib/build-cache-node.js +87 -0
- package/lib/build-cache.d.ts +24 -0
- package/lib/build-cache.js +229 -0
- package/lib/character.d.ts +132 -0
- package/lib/character.js +612 -0
- package/lib/cli-render-mode.d.ts +31 -0
- package/lib/cli-render-mode.js +204 -0
- package/lib/community-exporter.d.ts +13 -0
- package/lib/community-exporter.js +237 -0
- package/lib/composer/agent/compaction.d.ts +72 -0
- package/lib/composer/agent/compaction.js +103 -0
- package/lib/composer/agent/index.d.ts +25 -0
- package/lib/composer/agent/index.js +19 -0
- package/lib/composer/agent/prompt.d.ts +25 -0
- package/lib/composer/agent/prompt.js +100 -0
- package/lib/composer/agent/run.d.ts +91 -0
- package/lib/composer/agent/run.js +212 -0
- package/lib/composer/agent/tools.d.ts +75 -0
- package/lib/composer/agent/tools.js +643 -0
- package/lib/composer/agent/world-run.d.ts +50 -0
- package/lib/composer/agent/world-run.js +295 -0
- package/lib/composer/agent/world-tools.d.ts +20 -0
- package/lib/composer/agent/world-tools.js +311 -0
- package/lib/composer/collision.d.ts +109 -0
- package/lib/composer/collision.js +339 -0
- package/lib/composer/contract-utils.d.ts +6 -0
- package/lib/composer/contract-utils.js +48 -0
- package/lib/composer/dsl.d.ts +52 -0
- package/lib/composer/dsl.js +147 -0
- package/lib/composer/ground.d.ts +22 -0
- package/lib/composer/ground.js +9 -0
- package/lib/composer/index.d.ts +19 -0
- package/lib/composer/index.js +19 -0
- package/lib/composer/layout.d.ts +106 -0
- package/lib/composer/layout.js +216 -0
- package/lib/composer/model.d.ts +298 -0
- package/lib/composer/model.js +441 -0
- package/lib/composer/overlap.d.ts +89 -0
- package/lib/composer/overlap.js +139 -0
- package/lib/composer/presentation.d.ts +123 -0
- package/lib/composer/presentation.js +256 -0
- package/lib/composer/reachability.d.ts +78 -0
- package/lib/composer/reachability.js +303 -0
- package/lib/composer/render-port.d.ts +293 -0
- package/lib/composer/render-port.js +172 -0
- package/lib/composer/terrain-runtime.d.ts +73 -0
- package/lib/composer/terrain-runtime.js +328 -0
- package/lib/composer/terrain.d.ts +43 -0
- package/lib/composer/terrain.js +49 -0
- package/lib/composer/world-document.d.ts +722 -0
- package/lib/composer/world-document.js +857 -0
- package/lib/composer/world-integration.d.ts +78 -0
- package/lib/composer/world-integration.js +452 -0
- package/lib/composer/world-package.d.ts +312 -0
- package/lib/composer/world-package.js +209 -0
- package/lib/contracts/asset.d.ts +270 -0
- package/lib/contracts/asset.js +1616 -0
- package/lib/contracts/breadth.d.ts +197 -0
- package/lib/contracts/breadth.js +631 -0
- package/lib/contracts/environment.d.ts +13 -0
- package/lib/contracts/environment.js +67 -0
- package/lib/contracts/index.d.ts +5 -0
- package/lib/contracts/index.js +5 -0
- package/lib/contracts/integration.d.ts +94 -0
- package/lib/contracts/integration.js +10 -0
- package/lib/contracts/requirements-migration.d.ts +61 -0
- package/lib/contracts/requirements-migration.js +401 -0
- package/lib/contracts/requirements.d.ts +815 -0
- package/lib/contracts/requirements.js +266 -0
- package/lib/contracts/semantic.d.ts +124 -0
- package/lib/contracts/semantic.js +421 -0
- package/lib/deform.d.ts +31 -0
- package/lib/deform.js +137 -0
- package/lib/deformation-normals.d.ts +3 -0
- package/lib/deformation-normals.js +72 -0
- package/lib/discovery/articulation-recipes.d.ts +6 -0
- package/lib/discovery/articulation-recipes.js +184 -0
- package/lib/discovery/catalog-schema.d.ts +175 -0
- package/lib/discovery/catalog-schema.js +118 -0
- package/lib/discovery/catalog.d.ts +25 -0
- package/lib/discovery/catalog.js +84 -0
- package/lib/discovery/construction-recipes.d.ts +7 -0
- package/lib/discovery/construction-recipes.js +236 -0
- package/lib/discovery/helper-contracts.d.ts +19 -0
- package/lib/discovery/helper-contracts.js +1940 -0
- package/lib/discovery/helper-specs.d.ts +40 -0
- package/lib/discovery/helper-specs.js +800 -0
- package/lib/discovery/index.d.ts +9 -0
- package/lib/discovery/index.js +20 -0
- package/lib/discovery/intents.d.ts +3 -0
- package/lib/discovery/intents.js +117 -0
- package/lib/discovery/lexical-index.d.ts +5 -0
- package/lib/discovery/lexical-index.js +67 -0
- package/lib/discovery/query-schema.d.ts +35 -0
- package/lib/discovery/query-schema.js +66 -0
- package/lib/discovery/recipes.d.ts +6 -0
- package/lib/discovery/recipes.js +191 -0
- package/lib/discovery/service.d.ts +57 -0
- package/lib/discovery/service.js +234 -0
- package/lib/discovery/shapes.d.ts +6 -0
- package/lib/discovery/shapes.js +65 -0
- package/lib/discovery/structural-recipes.d.ts +6 -0
- package/lib/discovery/structural-recipes.js +193 -0
- package/lib/discovery/surface-recipes.d.ts +7 -0
- package/lib/discovery/surface-recipes.js +124 -0
- package/lib/draw-diagnostics.d.ts +57 -0
- package/lib/draw-diagnostics.js +239 -0
- package/lib/edit-buffer.d.ts +86 -0
- package/lib/edit-buffer.js +99 -0
- package/lib/engine-identity.d.ts +44 -0
- package/lib/engine-identity.js +41 -0
- package/lib/evaluator/authoring-diagnostic.d.ts +38 -0
- package/lib/evaluator/authoring-diagnostic.js +128 -0
- package/lib/evaluator/handler.d.ts +14 -0
- package/lib/evaluator/handler.js +86 -0
- package/lib/evaluator/index.d.ts +4 -0
- package/lib/evaluator/index.js +4 -0
- package/lib/evaluator/isolation.d.ts +45 -0
- package/lib/evaluator/isolation.js +362 -0
- package/lib/evaluator/probe-invariants.d.ts +2 -0
- package/lib/evaluator/probe-invariants.js +7 -0
- package/lib/evaluator/probe-worker.d.ts +1 -0
- package/lib/evaluator/probe-worker.js +134 -0
- package/lib/evaluator/protocol.d.ts +105 -0
- package/lib/evaluator/protocol.js +512 -0
- package/lib/evaluator/source-check.d.ts +7 -0
- package/lib/evaluator/source-check.js +57 -0
- package/lib/evaluator/subprocess.d.ts +26 -0
- package/lib/evaluator/subprocess.js +212 -0
- package/lib/evaluator/transport-worker.d.mts +1 -0
- package/lib/evaluator/transport-worker.mjs +3 -0
- package/lib/evaluator/worker-urls.d.ts +6 -0
- package/lib/evaluator/worker-urls.js +12 -0
- package/lib/evaluator/worker.d.ts +1 -0
- package/lib/evaluator/worker.js +26 -0
- package/lib/exporter-node.d.ts +16 -0
- package/lib/exporter-node.js +58 -0
- package/lib/gears.d.ts +68 -0
- package/lib/gears.js +259 -0
- package/lib/geometry-budget.d.ts +15 -0
- package/lib/geometry-budget.js +36 -0
- package/lib/geometry-catalog.d.ts +5 -0
- package/lib/geometry-catalog.js +161 -0
- package/lib/geometry-export.d.ts +11 -0
- package/lib/geometry-export.js +160 -0
- package/lib/geometry.d.ts +46 -0
- package/lib/geometry.js +311 -0
- package/lib/gltf-io.d.ts +38 -0
- package/lib/gltf-io.js +95 -0
- package/lib/implicit.d.ts +20 -0
- package/lib/implicit.js +58 -0
- package/lib/index-policy.d.ts +13 -0
- package/lib/index-policy.js +41 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +5 -0
- package/lib/inspect.d.ts +76 -0
- package/lib/inspect.js +206 -0
- package/lib/kit.d.ts +90 -0
- package/lib/kit.js +459 -0
- package/lib/live-review-node.d.ts +70 -0
- package/lib/live-review-node.js +961 -0
- package/lib/live-review.d.ts +65 -0
- package/lib/live-review.js +1 -0
- package/lib/local-runtime.d.ts +25 -0
- package/lib/local-runtime.js +272 -0
- package/lib/lod-export.d.ts +39 -0
- package/lib/lod-export.js +102 -0
- package/lib/lod.d.ts +56 -0
- package/lib/lod.js +138 -0
- package/lib/material-library-node.d.ts +56 -0
- package/lib/material-library-node.js +402 -0
- package/lib/material-library.d.ts +731 -0
- package/lib/material-library.js +425 -0
- package/lib/material-metrics.d.ts +72 -0
- package/lib/material-metrics.js +276 -0
- package/lib/material-presets.d.ts +29 -0
- package/lib/material-presets.js +181 -0
- package/lib/material-recipe-prompt.d.ts +23 -0
- package/lib/material-recipe-prompt.js +72 -0
- package/lib/material-recipe-runtime.d.ts +31 -0
- package/lib/material-recipe-runtime.js +91 -0
- package/lib/material-recipes.d.ts +131 -0
- package/lib/material-recipes.js +543 -0
- package/lib/material-resources.d.ts +181 -0
- package/lib/material-resources.js +416 -0
- package/lib/material-texture-library.generated.d.ts +1311 -0
- package/lib/material-texture-library.generated.js +11308 -0
- package/lib/metrics.d.ts +98 -0
- package/lib/metrics.js +210 -0
- package/lib/node-visibility.d.ts +31 -0
- package/lib/node-visibility.js +105 -0
- package/lib/open-shell.d.ts +21 -0
- package/lib/open-shell.js +83 -0
- package/lib/ops.d.ts +197 -0
- package/lib/ops.js +630 -0
- package/lib/palette-snap.d.ts +74 -0
- package/lib/palette-snap.js +151 -0
- package/lib/palette.d.ts +75 -0
- package/lib/palette.js +273 -0
- package/lib/portable-material-runtime.d.ts +14 -0
- package/lib/portable-material-runtime.js +81 -0
- package/lib/primitives.d.ts +483 -0
- package/lib/primitives.js +1553 -0
- package/lib/procedural-material-v2.d.ts +189 -0
- package/lib/procedural-material-v2.js +452 -0
- package/lib/procedural-texture.d.ts +90 -0
- package/lib/procedural-texture.js +306 -0
- package/lib/profile.d.ts +190 -0
- package/lib/profile.js +366 -0
- package/lib/program-store-node.d.ts +14 -0
- package/lib/program-store-node.js +137 -0
- package/lib/program-store.d.ts +43 -0
- package/lib/program-store.js +89 -0
- package/lib/project-bundle-node.d.ts +15 -0
- package/lib/project-bundle-node.js +175 -0
- package/lib/project-bundle.d.ts +65 -0
- package/lib/project-bundle.js +322 -0
- package/lib/projects-node.d.ts +17 -0
- package/lib/projects-node.js +227 -0
- package/lib/projects.d.ts +312 -0
- package/lib/projects.js +216 -0
- package/lib/prompt-api.d.ts +32 -0
- package/lib/prompt-api.js +223 -0
- package/lib/qa/architecture-corpus.d.ts +31 -0
- package/lib/qa/architecture-corpus.js +438 -0
- package/lib/qa/architecture-repairs.d.ts +17 -0
- package/lib/qa/architecture-repairs.js +73 -0
- package/lib/qa/architecture.d.ts +56 -0
- package/lib/qa/architecture.js +985 -0
- package/lib/qa/benchmark-fixtures.d.ts +42 -0
- package/lib/qa/benchmark-fixtures.js +191 -0
- package/lib/qa/breadth-corpus.d.ts +17 -0
- package/lib/qa/breadth-corpus.js +125 -0
- package/lib/qa/breadth-evidence.d.ts +18 -0
- package/lib/qa/breadth-evidence.js +514 -0
- package/lib/qa/breadth-final.d.ts +46 -0
- package/lib/qa/breadth-final.js +359 -0
- package/lib/qa/breadth.d.ts +66 -0
- package/lib/qa/breadth.js +539 -0
- package/lib/qa/character-advisory.d.ts +7 -0
- package/lib/qa/character-advisory.js +488 -0
- package/lib/qa/character-repairs.d.ts +11 -0
- package/lib/qa/character-repairs.js +68 -0
- package/lib/qa/character-vehicle-corpus.d.ts +32 -0
- package/lib/qa/character-vehicle-corpus.js +525 -0
- package/lib/qa/character.d.ts +66 -0
- package/lib/qa/character.js +712 -0
- package/lib/qa/corpus.d.ts +185 -0
- package/lib/qa/corpus.js +396 -0
- package/lib/qa/environment.d.ts +44 -0
- package/lib/qa/environment.js +725 -0
- package/lib/qa/geometry-relations.d.ts +94 -0
- package/lib/qa/geometry-relations.js +552 -0
- package/lib/qa/gltf.d.ts +29 -0
- package/lib/qa/gltf.js +66 -0
- package/lib/qa/index.d.ts +32 -0
- package/lib/qa/index.js +34 -0
- package/lib/qa/lod.d.ts +14 -0
- package/lib/qa/lod.js +25 -0
- package/lib/qa/material.d.ts +5 -0
- package/lib/qa/material.js +223 -0
- package/lib/qa/part-connectivity.d.ts +73 -0
- package/lib/qa/part-connectivity.js +216 -0
- package/lib/qa/prop-environment-prompt.d.ts +6 -0
- package/lib/qa/prop-environment-prompt.js +43 -0
- package/lib/qa/prop-helper-policy.d.ts +37 -0
- package/lib/qa/prop-helper-policy.js +65 -0
- package/lib/qa/prop.d.ts +44 -0
- package/lib/qa/prop.js +702 -0
- package/lib/qa/reference-comparison.d.ts +183 -0
- package/lib/qa/reference-comparison.js +420 -0
- package/lib/qa/registry.d.ts +159 -0
- package/lib/qa/registry.js +406 -0
- package/lib/qa/requirements-applicability.d.ts +33 -0
- package/lib/qa/requirements-applicability.js +189 -0
- package/lib/qa/requirements-report.d.ts +38 -0
- package/lib/qa/requirements-report.js +202 -0
- package/lib/qa/requirements-run.d.ts +20 -0
- package/lib/qa/requirements-run.js +370 -0
- package/lib/qa/run.d.ts +54 -0
- package/lib/qa/run.js +240 -0
- package/lib/qa/self-intersection.d.ts +157 -0
- package/lib/qa/self-intersection.js +633 -0
- package/lib/qa/sweep.d.ts +4 -0
- package/lib/qa/sweep.js +65 -0
- package/lib/qa/types.d.ts +90 -0
- package/lib/qa/types.js +81 -0
- package/lib/qa/universal.d.ts +14 -0
- package/lib/qa/universal.js +398 -0
- package/lib/qa/vegetation-corpus.d.ts +18 -0
- package/lib/qa/vegetation-corpus.js +304 -0
- package/lib/qa/vegetation.d.ts +133 -0
- package/lib/qa/vegetation.js +933 -0
- package/lib/qa/vehicle-advisory.d.ts +8 -0
- package/lib/qa/vehicle-advisory.js +395 -0
- package/lib/qa/vehicle.d.ts +19 -0
- package/lib/qa/vehicle.js +594 -0
- package/lib/rebuild-options.d.ts +31 -0
- package/lib/rebuild-options.js +13 -0
- package/lib/render-capabilities.d.ts +25 -0
- package/lib/render-capabilities.js +100 -0
- package/lib/render-service-client.d.ts +59 -0
- package/lib/render-service-client.js +194 -0
- package/lib/render-service-host.d.ts +44 -0
- package/lib/render-service-host.js +236 -0
- package/lib/render-service-windows.d.ts +12 -0
- package/lib/render-service-windows.js +72 -0
- package/lib/render.d.ts +565 -0
- package/lib/render.js +1978 -0
- package/lib/requirements-assets.d.ts +6 -0
- package/lib/requirements-assets.js +33 -0
- package/lib/requirements-context.d.ts +1658 -0
- package/lib/requirements-context.js +126 -0
- package/lib/requirements-identity.d.ts +3 -0
- package/lib/requirements-identity.js +38 -0
- package/lib/requirements-json.d.ts +12 -0
- package/lib/requirements-json.js +58 -0
- package/lib/requirements-store.d.ts +42 -0
- package/lib/requirements-store.js +86 -0
- package/lib/requirements.d.ts +4 -0
- package/lib/requirements.js +4 -0
- package/lib/revision-comparison.d.ts +85 -0
- package/lib/revision-comparison.js +334 -0
- package/lib/rig-export.d.ts +5 -0
- package/lib/rig-export.js +19 -0
- package/lib/rigid-merge.d.ts +90 -0
- package/lib/rigid-merge.js +585 -0
- package/lib/runtime-identity.d.ts +20 -0
- package/lib/runtime-identity.js +193 -0
- package/lib/solids.d.ts +29 -0
- package/lib/solids.js +523 -0
- package/lib/source-bindings.d.ts +6 -0
- package/lib/source-bindings.js +96 -0
- package/lib/source-runtime-checks.d.ts +14 -0
- package/lib/source-runtime-checks.js +169 -0
- package/lib/sweep-analysis.d.ts +22 -0
- package/lib/sweep-analysis.js +109 -0
- package/lib/sweep.d.ts +34 -0
- package/lib/sweep.js +347 -0
- package/lib/texture-bake.d.ts +125 -0
- package/lib/texture-bake.js +395 -0
- package/lib/texture-contract.d.ts +3 -0
- package/lib/texture-contract.js +10 -0
- package/lib/texture-resolver.d.ts +22 -0
- package/lib/texture-resolver.js +28 -0
- package/lib/textures.d.ts +90 -0
- package/lib/textures.js +240 -0
- package/lib/tools/actions.d.ts +35 -0
- package/lib/tools/actions.js +69 -0
- package/lib/tools/capture-input.d.ts +373 -0
- package/lib/tools/capture-input.js +193 -0
- package/lib/tools/discovery.d.ts +3 -0
- package/lib/tools/discovery.js +177 -0
- package/lib/tools/materials.d.ts +29 -0
- package/lib/tools/materials.js +168 -0
- package/lib/tools/preview-fidelity.d.ts +6 -0
- package/lib/tools/preview-fidelity.js +23 -0
- package/lib/tools/program-artifacts.d.ts +30 -0
- package/lib/tools/program-artifacts.js +76 -0
- package/lib/tools/programs.d.ts +9 -0
- package/lib/tools/programs.js +151 -0
- package/lib/tools/projects.d.ts +27 -0
- package/lib/tools/projects.js +98 -0
- package/lib/tools/registry.d.ts +792 -0
- package/lib/tools/registry.js +2123 -0
- package/lib/tools/review-detail.d.ts +106 -0
- package/lib/tools/review-detail.js +740 -0
- package/lib/tools/review.d.ts +40 -0
- package/lib/tools/review.js +230 -0
- package/lib/tools/skill-resource.d.ts +8 -0
- package/lib/tools/skill-resource.js +1 -0
- package/lib/tools/workspace.d.ts +8 -0
- package/lib/tools/workspace.js +87 -0
- package/lib/user-data-extras.d.ts +40 -0
- package/lib/user-data-extras.js +158 -0
- package/lib/user-data-validation.d.ts +18 -0
- package/lib/user-data-validation.js +201 -0
- package/lib/uv-project.d.ts +14 -0
- package/lib/uv-project.js +145 -0
- package/lib/uv-shapes.d.ts +11 -0
- package/lib/uv-shapes.js +48 -0
- package/lib/uv.d.ts +39 -0
- package/lib/uv.js +216 -0
- package/lib/validation.d.ts +90 -0
- package/lib/validation.js +1099 -0
- package/lib/vehicle.d.ts +128 -0
- package/lib/vehicle.js +487 -0
- package/lib/views/annotate.d.ts +41 -0
- package/lib/views/annotate.js +131 -0
- package/lib/views/architecture.d.ts +22 -0
- package/lib/views/architecture.js +55 -0
- package/lib/views/background.d.ts +54 -0
- package/lib/views/background.js +65 -0
- package/lib/views/camera-capture.d.ts +15 -0
- package/lib/views/camera-capture.js +101 -0
- package/lib/views/camera.d.ts +106 -0
- package/lib/views/camera.js +488 -0
- package/lib/views/capture-cache.d.ts +48 -0
- package/lib/views/capture-cache.js +239 -0
- package/lib/views/capture-limits.d.ts +19 -0
- package/lib/views/capture-limits.js +61 -0
- package/lib/views/capture.d.ts +124 -0
- package/lib/views/capture.js +210 -0
- package/lib/views/character-capture.d.ts +20 -0
- package/lib/views/character-capture.js +180 -0
- package/lib/views/character.d.ts +64 -0
- package/lib/views/character.js +176 -0
- package/lib/views/diagnostic.d.ts +90 -0
- package/lib/views/diagnostic.js +627 -0
- package/lib/views/evidence-history.d.ts +13 -0
- package/lib/views/evidence-history.js +131 -0
- package/lib/views/glb.d.ts +36 -0
- package/lib/views/glb.js +524 -0
- package/lib/views/grid.d.ts +46 -0
- package/lib/views/grid.js +81 -0
- package/lib/views/index.d.ts +257 -0
- package/lib/views/index.js +624 -0
- package/lib/views/inspect.d.ts +110 -0
- package/lib/views/inspect.js +195 -0
- package/lib/views/lod.d.ts +30 -0
- package/lib/views/lod.js +79 -0
- package/lib/views/measurement.d.ts +47 -0
- package/lib/views/measurement.js +60 -0
- package/lib/views/part-placement.d.ts +25 -0
- package/lib/views/part-placement.js +26 -0
- package/lib/views/png.d.ts +23 -0
- package/lib/views/png.js +162 -0
- package/lib/views/port.d.ts +74 -0
- package/lib/views/port.js +250 -0
- package/lib/views/pose.d.ts +113 -0
- package/lib/views/pose.js +433 -0
- package/lib/views/raster.d.ts +164 -0
- package/lib/views/raster.js +508 -0
- package/lib/views/renderer-id.d.ts +11 -0
- package/lib/views/renderer-id.js +29 -0
- package/lib/views/scene-raster.d.ts +41 -0
- package/lib/views/scene-raster.js +84 -0
- package/lib/views/surface-distance.d.ts +51 -0
- package/lib/views/surface-distance.js +343 -0
- package/lib/views/vehicle.d.ts +57 -0
- package/lib/views/vehicle.js +288 -0
- package/lib/wall-panels.d.ts +38 -0
- package/lib/wall-panels.js +99 -0
- package/lib/widget-transfer.d.ts +12 -0
- package/lib/widget-transfer.js +117 -0
- package/lib/workspace-location.d.ts +6 -0
- package/lib/workspace-location.js +16 -0
- package/lib/workspace-node.d.ts +15 -0
- package/lib/workspace-node.js +74 -0
- package/lib/workspace.d.ts +26 -0
- package/lib/workspace.js +22 -0
- package/lib/written-nodes.d.ts +10 -0
- package/lib/written-nodes.js +32 -0
- package/package.json +385 -4
- package/plugin.json +16 -0
- package/plugins/kiln-engine/.claude-plugin/plugin.json +18 -0
- package/plugins/kiln-engine/LICENSE +21 -0
- package/plugins/kiln-engine/README.md +25 -0
- package/plugins/kiln-engine/package-provenance.json +15 -0
- package/plugins/kiln-engine/plugin.json +38 -0
- package/plugins/kiln-engine/runtime.json +4 -0
- package/plugins/kiln-engine/scripts/setup-workspace.mjs +337 -0
- package/plugins/kiln-engine/skills/kiln-setup-workspace/SKILL.md +108 -0
- package/plugins/kiln-engine/skills/kiln-setup-workspace/references/plugin-install.md +66 -0
- package/render-service/README.md +139 -0
- package/render-service/package-lock.json +72 -0
- package/render-service/package.json +22 -0
- package/render-service/src/backdrops.mjs +26 -0
- package/render-service/src/bind-policy.mjs +80 -0
- package/render-service/src/build-identity.mjs +83 -0
- package/render-service/src/cache-identity.mjs +65 -0
- package/render-service/src/contract.mjs +494 -0
- package/render-service/src/display-output.mjs +18 -0
- package/render-service/src/display-transform.mjs +192 -0
- package/render-service/src/framing.mjs +114 -0
- package/render-service/src/glb-input.mjs +259 -0
- package/render-service/src/gpu.mjs +101 -0
- package/render-service/src/health-contract.mjs +40 -0
- package/render-service/src/instance.mjs +146 -0
- package/render-service/src/node-visibility.mjs +49 -0
- package/render-service/src/png-input.mjs +77 -0
- package/render-service/src/presentation-presets.mjs +216 -0
- package/render-service/src/readback.mjs +16 -0
- package/render-service/src/register-hooks.mjs +2 -0
- package/render-service/src/render-queue.mjs +144 -0
- package/render-service/src/renderer.mjs +473 -0
- package/render-service/src/request-limits.mjs +72 -0
- package/render-service/src/review-tone-mapping.mjs +55 -0
- package/render-service/src/server.mjs +387 -0
- package/render-service/src/three-alias-hooks.mjs +6 -0
- package/scripts/create-workspace.mjs +808 -0
- package/scripts/package-plugin.mjs +67 -0
- package/skills/kiln-author-asset/SKILL.md +104 -0
- package/skills/kiln-author-asset/references/camera-cli.md +33 -0
- package/skills/kiln-author-asset/references/camera-recipes.md +73 -0
- package/skills/kiln-author-asset/references/export-profiles.md +216 -0
- package/skills/kiln-author-asset/references/geometry-recipes.md +329 -0
- package/skills/kiln-author-asset/references/program-contract.md +44 -0
- package/skills/kiln-author-asset/references/projects-and-materials.md +158 -0
- package/skills/kiln-author-asset/references/reusable-frame.kiln.js +32 -0
- package/skills/kiln-batch-dispatch/SKILL.md +22 -0
- package/skills/kiln-batch-dispatch/references/clean-room-evaluation.md +35 -0
- package/skills/kiln-compose-scene/SKILL.md +38 -0
- package/skills/kiln-compose-scene/references/composition-api.md +29 -0
- package/skills/kiln-compose-scene/references/runtime-scenes.md +363 -0
- package/skills/kiln-qa-asset/SKILL.md +99 -0
- package/skills/kiln-qa-asset/references/engine-handoff.md +246 -0
- package/skills/kiln-qa-asset/references/integration-checks.md +96 -0
- package/skills/kiln-refine-asset/SKILL.md +136 -0
- package/skills/kiln-refine-asset/references/revision-and-views.md +205 -0
- package/skills/kiln-refine-asset/references/revision-cli.md +39 -0
- package/skills/kiln-setup-workspace/SKILL.md +108 -0
- package/skills/kiln-setup-workspace/references/plugin-install.md +66 -0
- package/src/agent/call-budget.ts +106 -0
- package/src/agent/compaction.ts +197 -0
- package/src/agent/concurrency.ts +30 -0
- package/src/agent/diff.ts +141 -0
- package/src/agent/generate.ts +448 -0
- package/src/agent/hooks.ts +204 -0
- package/src/agent/index.ts +114 -0
- package/src/agent/native-prompt.ts +51 -0
- package/src/agent/native-workflow.ts +33 -0
- package/src/agent/providers.ts +529 -0
- package/src/agent/run.ts +356 -0
- package/src/agent/skill-resources.ts +198 -0
- package/src/agent/split-tool-result-images.ts +80 -0
- package/src/agent/stream-start.ts +61 -0
- package/src/agent/tools.ts +113 -0
- package/src/agent/view-render-timeout.ts +110 -0
- package/src/animation-cli.ts +251 -0
- package/src/animation-cubic.ts +57 -0
- package/src/animation-spline.ts +183 -0
- package/src/architecture.ts +871 -0
- package/src/arena/adaptive.ts +119 -0
- package/src/arena/bradley-terry.ts +221 -0
- package/src/arena/index.ts +21 -0
- package/src/assembly-transform.ts +34 -0
- package/src/assembly.ts +762 -0
- package/src/asset-catalog.ts +30 -0
- package/src/asset-cli.ts +505 -0
- package/src/asset-export.ts +141 -0
- package/src/asset-materials-node.ts +78 -0
- package/src/asset-viewer.ts +160 -0
- package/src/asset-widget-uri.ts +9 -0
- package/src/asset-widget.ts +38 -0
- package/src/assets-node.ts +412 -0
- package/src/assets-resources.ts +137 -0
- package/src/assets.ts +252 -0
- package/src/atomic-directory.ts +45 -0
- package/src/authoring-style.ts +49 -0
- package/src/breadth-prompt.ts +79 -0
- package/src/build-cache-node.ts +99 -0
- package/src/build-cache.ts +253 -0
- package/src/character.ts +776 -0
- package/src/cli-json.ts +29 -0
- package/src/cli-output.ts +135 -0
- package/src/cli-render-mode.ts +270 -0
- package/src/cli.ts +809 -0
- package/src/community-exporter.ts +268 -0
- package/src/composer/agent/compaction.ts +146 -0
- package/src/composer/agent/index.ts +41 -0
- package/src/composer/agent/prompt.ts +126 -0
- package/src/composer/agent/run.ts +317 -0
- package/src/composer/agent/tools.ts +847 -0
- package/src/composer/agent/world-run.ts +421 -0
- package/src/composer/agent/world-tools.ts +411 -0
- package/src/composer/collision.ts +448 -0
- package/src/composer/contract-utils.ts +52 -0
- package/src/composer/dsl.ts +196 -0
- package/src/composer/ground.ts +27 -0
- package/src/composer/index.ts +19 -0
- package/src/composer/layout.ts +357 -0
- package/src/composer/model.ts +688 -0
- package/src/composer/overlap.ts +220 -0
- package/src/composer/presentation.ts +309 -0
- package/src/composer/reachability.ts +407 -0
- package/src/composer/render-port.ts +516 -0
- package/src/composer/terrain-runtime.ts +415 -0
- package/src/composer/terrain.ts +53 -0
- package/src/composer/world-document.ts +1019 -0
- package/src/composer/world-integration.ts +589 -0
- package/src/composer/world-package.ts +255 -0
- package/src/contracts/asset.ts +2030 -0
- package/src/contracts/breadth.ts +888 -0
- package/src/contracts/environment.ts +81 -0
- package/src/contracts/index.ts +5 -0
- package/src/contracts/integration.ts +100 -0
- package/src/contracts/requirements-migration.ts +536 -0
- package/src/contracts/requirements.ts +357 -0
- package/src/contracts/semantic.ts +544 -0
- package/src/deform.ts +215 -0
- package/src/deformation-normals.ts +84 -0
- package/src/direct-entry.ts +28 -0
- package/src/discovery/articulation-recipes.ts +190 -0
- package/src/discovery/catalog-schema.ts +125 -0
- package/src/discovery/catalog.ts +88 -0
- package/src/discovery/construction-recipes.ts +243 -0
- package/src/discovery/helper-contracts.ts +2388 -0
- package/src/discovery/helper-specs.ts +1046 -0
- package/src/discovery/index.ts +36 -0
- package/src/discovery/intents.ts +120 -0
- package/src/discovery/lexical-index.ts +72 -0
- package/src/discovery/query-schema.ts +71 -0
- package/src/discovery/recipes.ts +215 -0
- package/src/discovery/service.ts +329 -0
- package/src/discovery/shapes.ts +120 -0
- package/src/discovery/structural-recipes.ts +199 -0
- package/src/discovery/surface-recipes.ts +130 -0
- package/src/discovery-cli.ts +106 -0
- package/src/draw-diagnostics.ts +313 -0
- package/src/edit-buffer.ts +134 -0
- package/src/edit-cli.ts +125 -0
- package/src/engine-identity.ts +50 -0
- package/src/evaluator/authoring-diagnostic.ts +168 -0
- package/src/evaluator/handler.ts +114 -0
- package/src/evaluator/index.ts +50 -0
- package/src/evaluator/isolation.ts +454 -0
- package/src/evaluator/probe-invariants.ts +9 -0
- package/src/evaluator/probe-worker.ts +158 -0
- package/src/evaluator/protocol.ts +701 -0
- package/src/evaluator/source-check.ts +64 -0
- package/src/evaluator/subprocess.ts +294 -0
- package/src/evaluator/transport-worker.mjs +8 -0
- package/src/evaluator/worker-urls.ts +16 -0
- package/src/evaluator/worker.ts +26 -0
- package/src/experiments/geometry-acceptance.ts +278 -0
- package/src/experiments/geometry-frontier.ts +181 -0
- package/src/experiments/program-aliases.ts +96 -0
- package/src/experiments/run-w6-material-vegetation.ts +7 -0
- package/src/experiments/run-w7-vegetation-lod.ts +6 -0
- package/src/experiments/w6-material-vegetation.ts +772 -0
- package/src/experiments/w7-vegetation-lod.ts +335 -0
- package/src/exporter-node.ts +68 -0
- package/src/gears.ts +334 -0
- package/src/generated/mcp-manifest.json +2050 -0
- package/src/geometry-budget.ts +50 -0
- package/src/geometry-catalog.ts +215 -0
- package/src/geometry-export.ts +193 -0
- package/src/geometry.ts +379 -0
- package/src/gltf-io.ts +129 -0
- package/src/gltf-validator-shims.d.ts +12 -0
- package/src/implicit.ts +106 -0
- package/src/index-policy.ts +52 -0
- package/src/index.ts +5 -0
- package/src/inspect-cli.ts +198 -0
- package/src/inspect.ts +290 -0
- package/src/kit.ts +547 -0
- package/src/live-review-node.ts +1011 -0
- package/src/live-review.ts +55 -0
- package/src/local-runtime.ts +336 -0
- package/src/lod-export.ts +120 -0
- package/src/lod.ts +192 -0
- package/src/loopback.ts +6 -0
- package/src/material-library-node.ts +488 -0
- package/src/material-library.ts +481 -0
- package/src/material-metrics.ts +392 -0
- package/src/material-presets.ts +207 -0
- package/src/material-recipe-prompt.ts +99 -0
- package/src/material-recipe-runtime.ts +162 -0
- package/src/material-recipes.ts +748 -0
- package/src/material-resources.ts +640 -0
- package/src/material-texture-library.generated.ts +11408 -0
- package/src/mcp-core.ts +437 -0
- package/src/mcp-engine.ts +383 -0
- package/src/mcp-manifest.ts +104 -0
- package/src/mcp-server.ts +118 -0
- package/src/metrics.ts +277 -0
- package/src/migration-cli.ts +105 -0
- package/src/migration-rebuild.ts +265 -0
- package/src/node-visibility.ts +116 -0
- package/src/open-shell.ts +104 -0
- package/src/ops.ts +751 -0
- package/src/palette-snap.ts +209 -0
- package/src/palette.ts +307 -0
- package/src/portable-material-runtime.ts +109 -0
- package/src/primitives.ts +2299 -0
- package/src/procedural-material-v2.ts +720 -0
- package/src/procedural-texture.ts +427 -0
- package/src/profile.ts +485 -0
- package/src/program-store-node.ts +138 -0
- package/src/program-store.ts +116 -0
- package/src/project-bundle-node.ts +220 -0
- package/src/project-bundle.ts +392 -0
- package/src/project-cli.ts +248 -0
- package/src/projects-node.ts +270 -0
- package/src/projects.ts +274 -0
- package/src/prompt-api.ts +231 -0
- package/src/qa/architecture-corpus.ts +828 -0
- package/src/qa/architecture-repairs.ts +92 -0
- package/src/qa/architecture.ts +1358 -0
- package/src/qa/benchmark-fixtures.ts +441 -0
- package/src/qa/breadth-corpus.ts +168 -0
- package/src/qa/breadth-evidence.ts +595 -0
- package/src/qa/breadth-final.ts +453 -0
- package/src/qa/breadth.ts +690 -0
- package/src/qa/character-advisory.ts +596 -0
- package/src/qa/character-repairs.ts +185 -0
- package/src/qa/character-vehicle-corpus.ts +802 -0
- package/src/qa/character.ts +998 -0
- package/src/qa/corpus.ts +499 -0
- package/src/qa/environment.ts +903 -0
- package/src/qa/geometry-relations.ts +843 -0
- package/src/qa/gltf.ts +103 -0
- package/src/qa/index.ts +34 -0
- package/src/qa/lod.ts +28 -0
- package/src/qa/material.ts +302 -0
- package/src/qa/part-connectivity.ts +252 -0
- package/src/qa/prop-environment-prompt.ts +58 -0
- package/src/qa/prop-helper-policy.ts +118 -0
- package/src/qa/prop.ts +828 -0
- package/src/qa/reference-comparison.ts +495 -0
- package/src/qa/registry.ts +604 -0
- package/src/qa/requirements-applicability.ts +241 -0
- package/src/qa/requirements-report.ts +280 -0
- package/src/qa/requirements-run.ts +470 -0
- package/src/qa/run.ts +329 -0
- package/src/qa/self-intersection.ts +741 -0
- package/src/qa/sweep.ts +68 -0
- package/src/qa/types.ts +187 -0
- package/src/qa/universal.ts +506 -0
- package/src/qa/vegetation-corpus.ts +404 -0
- package/src/qa/vegetation.ts +1174 -0
- package/src/qa/vehicle-advisory.ts +468 -0
- package/src/qa/vehicle.ts +756 -0
- package/src/rebuild-options.ts +16 -0
- package/src/render-capabilities.ts +140 -0
- package/src/render-service-client.ts +297 -0
- package/src/render-service-host.ts +278 -0
- package/src/render-service-windows.ts +80 -0
- package/src/render.ts +2748 -0
- package/src/requirements-assets.ts +53 -0
- package/src/requirements-context.ts +170 -0
- package/src/requirements-file.ts +10 -0
- package/src/requirements-identity.ts +43 -0
- package/src/requirements-json.ts +65 -0
- package/src/requirements-store.ts +150 -0
- package/src/requirements.ts +4 -0
- package/src/review-cli.ts +81 -0
- package/src/revision-comparison.ts +425 -0
- package/src/rig-export.ts +29 -0
- package/src/rigid-merge.ts +691 -0
- package/src/runtime-identity.ts +207 -0
- package/src/runtime-support.mjs +20 -0
- package/src/service-cli.ts +210 -0
- package/src/solids.ts +650 -0
- package/src/source-bindings.ts +90 -0
- package/src/source-runtime-checks.ts +189 -0
- package/src/sweep-analysis.ts +168 -0
- package/src/sweep.ts +482 -0
- package/src/texture-bake.ts +526 -0
- package/src/texture-contract.ts +12 -0
- package/src/texture-resolver.ts +61 -0
- package/src/textures.ts +345 -0
- package/src/tools/actions.ts +124 -0
- package/src/tools/capture-input.ts +233 -0
- package/src/tools/discovery.ts +194 -0
- package/src/tools/materials.ts +206 -0
- package/src/tools/preview-fidelity.ts +31 -0
- package/src/tools/program-artifacts.ts +107 -0
- package/src/tools/programs.ts +190 -0
- package/src/tools/projects.ts +141 -0
- package/src/tools/registry.ts +3111 -0
- package/src/tools/review-detail.ts +788 -0
- package/src/tools/review.ts +269 -0
- package/src/tools/skill-resource.ts +9 -0
- package/src/tools/workspace.ts +112 -0
- package/src/user-data-extras.ts +181 -0
- package/src/user-data-validation.ts +211 -0
- package/src/uv-project.ts +185 -0
- package/src/uv-shapes.ts +63 -0
- package/src/uv.ts +301 -0
- package/src/validation.ts +1257 -0
- package/src/vegetation-prompt.ts +109 -0
- package/src/vehicle.ts +742 -0
- package/src/viewer/app.ts +666 -0
- package/src/viewer/attribution.ts +17 -0
- package/src/viewer/camera-state.ts +45 -0
- package/src/viewer/chat-app.ts +221 -0
- package/src/viewer/chat-download.ts +53 -0
- package/src/viewer/dashboard.ts +59 -0
- package/src/viewer/deep-link.ts +34 -0
- package/src/viewer/dom.ts +63 -0
- package/src/viewer/framing.ts +55 -0
- package/src/viewer/library-state.ts +34 -0
- package/src/viewer/live-panel.ts +742 -0
- package/src/viewer/live-state.ts +99 -0
- package/src/viewer/load-guard.ts +10 -0
- package/src/viewer/lod-control.ts +98 -0
- package/src/viewer/lod.ts +172 -0
- package/src/viewer/material-preset-form.ts +34 -0
- package/src/viewer/materials-panel.ts +335 -0
- package/src/viewer/membership-panel.ts +122 -0
- package/src/viewer/navigation.ts +9 -0
- package/src/viewer/performance-control.ts +75 -0
- package/src/viewer/performance.ts +61 -0
- package/src/viewer/project-editor.ts +37 -0
- package/src/viewer/project-membership.ts +20 -0
- package/src/viewer/projects-panel.ts +374 -0
- package/src/viewer/scene.ts +426 -0
- package/src/viewer/visibility.ts +73 -0
- package/src/views/annotate.ts +138 -0
- package/src/views/architecture.ts +77 -0
- package/src/views/background.ts +87 -0
- package/src/views/camera-capture.ts +143 -0
- package/src/views/camera.ts +622 -0
- package/src/views/capture-cache.ts +272 -0
- package/src/views/capture-limits.ts +73 -0
- package/src/views/capture.ts +300 -0
- package/src/views/character-capture.ts +279 -0
- package/src/views/character.ts +267 -0
- package/src/views/diagnostic.ts +853 -0
- package/src/views/evidence-history.ts +166 -0
- package/src/views/glb.ts +747 -0
- package/src/views/grid.ts +118 -0
- package/src/views/index.ts +1071 -0
- package/src/views/inspect.ts +296 -0
- package/src/views/lod.ts +117 -0
- package/src/views/measurement.ts +69 -0
- package/src/views/part-placement.ts +50 -0
- package/src/views/png.ts +175 -0
- package/src/views/port.ts +335 -0
- package/src/views/pose.ts +541 -0
- package/src/views/raster.ts +627 -0
- package/src/views/renderer-id.ts +31 -0
- package/src/views/scene-raster.ts +139 -0
- package/src/views/surface-distance.ts +403 -0
- package/src/views/vehicle.ts +431 -0
- package/src/wall-panels.ts +127 -0
- package/src/widget-transfer.ts +115 -0
- package/src/workspace-cli.ts +41 -0
- package/src/workspace-http.ts +219 -0
- package/src/workspace-location.ts +20 -0
- package/src/workspace-node.ts +91 -0
- package/src/workspace.ts +43 -0
- package/src/written-nodes.ts +39 -0
- package/src/xatlasjs-shims.d.ts +16 -0
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure-CPU orthographic rasterizer for Kiln scene graphs.
|
|
3
|
+
*
|
|
4
|
+
* Why this exists: the agent loop needs to SEE its asset (kiln_screenshot)
|
|
5
|
+
* but no GPU/browser renderer is available everywhere the loop runs — the
|
|
6
|
+
* kiln-studio agent-runtime container ships without a browser
|
|
7
|
+
* (PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1) and Playwright is unsupported under
|
|
8
|
+
* Bun on Windows (see imposter/bake.ts). headless-gl is WebGL1-only while
|
|
9
|
+
* three >= r163 requires WebGL2. So: a dependency-free scanline z-buffer
|
|
10
|
+
* rasterizer over the executed scene. Flat lambert, base color only — enough
|
|
11
|
+
* fidelity for silhouette / proportion / orientation / contact QA, which is
|
|
12
|
+
* what the vision loop checks.
|
|
13
|
+
*
|
|
14
|
+
* Scene access is strictly duck-typed (`.isMesh`, `matrixWorld.elements`,
|
|
15
|
+
* position attribute arrays) because sandbox-created objects live in a
|
|
16
|
+
* different module realm — see executeKilnCode in ../render.ts.
|
|
17
|
+
*
|
|
18
|
+
* Lighting matches scripts/visual-audit.ts: key directional light from
|
|
19
|
+
* [1.5, 2, 1] at 1.1 plus 0.25 ambient. Back-face culling is strict (like
|
|
20
|
+
* the offline audit grid) so inverted winding shows up as missing faces.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { resolveBackdrop, type BackdropId } from './background';
|
|
24
|
+
|
|
25
|
+
export interface ViewSpec {
|
|
26
|
+
name: string;
|
|
27
|
+
/** Direction from model center toward the camera (kiln frame: +X fwd, +Y up, +Z right). */
|
|
28
|
+
dir: [number, number, number];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Same six views as the offline audit grid (scripts/visual-audit.ts). */
|
|
32
|
+
export const SIX_VIEWS: ViewSpec[] = [
|
|
33
|
+
{ name: 'Front', dir: [1, 0, 0] },
|
|
34
|
+
{ name: 'Right', dir: [0, 0, 1] },
|
|
35
|
+
{ name: 'Back', dir: [-1, 0, 0] },
|
|
36
|
+
{ name: 'Left', dir: [0, 0, -1] },
|
|
37
|
+
{ name: 'Top', dir: [0, 1, 0.0001] },
|
|
38
|
+
{ name: '3/4', dir: [0.7, 0.5, 0.7] },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* H-33 arm: the same grid with the single 3/4 swapped to the opposite-rear
|
|
43
|
+
* azimuth, so features the front-quarter cell always occludes (rear fascia,
|
|
44
|
+
* tail geometry, the back of a spoiler) get one perspective cell.
|
|
45
|
+
*/
|
|
46
|
+
export const SIX_VIEWS_REAR_QUARTER: ViewSpec[] = [
|
|
47
|
+
...SIX_VIEWS.slice(0, 5),
|
|
48
|
+
{ name: '3/4 Rear', dir: [-0.7, 0.5, -0.7] },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Elevation clamp for orbit cameras. The rasterizer already swaps its up-hint
|
|
53
|
+
* past |y| > 0.99 so a true pole does not degenerate, but an exactly-vertical
|
|
54
|
+
* camera makes the framing basis spin freely with azimuth — two calls that
|
|
55
|
+
* differ only in azimuth would return differently-rotated top views. Clamping
|
|
56
|
+
* short of the pole keeps azimuth meaningful all the way up.
|
|
57
|
+
*/
|
|
58
|
+
export const MIN_ELEVATION_DEG = -89;
|
|
59
|
+
export const MAX_ELEVATION_DEG = 89;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Object-relative orbit angles to a camera direction in the kiln frame
|
|
63
|
+
* (+X forward, +Y up, +Z right).
|
|
64
|
+
*
|
|
65
|
+
* Azimuth sweeps from the front (+X) toward the right (+Z), so it reproduces
|
|
66
|
+
* the named grid cameras exactly: 0 = Front, 90 = Right, 180 = Back,
|
|
67
|
+
* 270 = Left, and (45, 26.79) is the shipped 3/4 direction. Azimuth wraps
|
|
68
|
+
* naturally; elevation is clamped to {@link MIN_ELEVATION_DEG}..{@link MAX_ELEVATION_DEG}.
|
|
69
|
+
*/
|
|
70
|
+
export function orbitDir(azimuthDeg: number, elevationDeg: number): [number, number, number] {
|
|
71
|
+
const el =
|
|
72
|
+
(Math.min(MAX_ELEVATION_DEG, Math.max(MIN_ELEVATION_DEG, elevationDeg)) * Math.PI) / 180;
|
|
73
|
+
const az = (azimuthDeg * Math.PI) / 180;
|
|
74
|
+
const cosEl = Math.cos(el);
|
|
75
|
+
return [cosEl * Math.cos(az), Math.sin(el), cosEl * Math.sin(az)];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Exact inverse of {@link orbitDir}: recover orbit angles from a direction.
|
|
80
|
+
*
|
|
81
|
+
* Used so the named cameras can report where they are in the same coordinates
|
|
82
|
+
* the model steers with, without a second hand-maintained table that could
|
|
83
|
+
* drift from the direction vectors above. Azimuth comes back in [0, 360).
|
|
84
|
+
*/
|
|
85
|
+
export function orbitAnglesOf(dir: [number, number, number]): {
|
|
86
|
+
azimuthDeg: number;
|
|
87
|
+
elevationDeg: number;
|
|
88
|
+
} {
|
|
89
|
+
const [x, y, z] = normalize(dir);
|
|
90
|
+
const azimuthDeg = ((((Math.atan2(z, x) * 180) / Math.PI) % 360) + 360) % 360;
|
|
91
|
+
return {
|
|
92
|
+
azimuthDeg: +azimuthDeg.toFixed(2),
|
|
93
|
+
elevationDeg: +((Math.asin(Math.min(1, Math.max(-1, y))) * 180) / Math.PI).toFixed(2),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Named six-view grid variants (H-33). 'default' keeps the shipped front-quarter grid. */
|
|
98
|
+
export type ViewGridVariant = 'default' | 'rear-quarter';
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Resolve a grid-variant name (typically the `KILN_GRID_VARIANT` env) to its
|
|
102
|
+
* view set. Unknown / unset names fall back to {@link SIX_VIEWS} so a stale or
|
|
103
|
+
* mistyped env can never change what the agent sees.
|
|
104
|
+
*/
|
|
105
|
+
export function resolveGridViews(variant?: string): ViewSpec[] {
|
|
106
|
+
return variant?.trim().toLowerCase() === 'rear-quarter' ? SIX_VIEWS_REAR_QUARTER : SIX_VIEWS;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export interface RasterOptions {
|
|
110
|
+
/** Square output size in pixels per view. Default 256. */
|
|
111
|
+
size?: number;
|
|
112
|
+
/** Cull triangles facing away from the camera. Default true (reveals winding bugs). */
|
|
113
|
+
backfaceCull?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Fixed world-space AABB to frame the camera to, instead of the scene's own
|
|
116
|
+
* bounds. Used by the animation grid so every sampled frame shares one framing —
|
|
117
|
+
* otherwise per-frame auto-framing re-centers the model and HIDES root travel
|
|
118
|
+
* (a sideways/forward-sliding walk would look stationary). The scene's own
|
|
119
|
+
* geometry is still drawn; only the camera center/zoom come from this box.
|
|
120
|
+
*/
|
|
121
|
+
frameBounds?: { min: [number, number, number]; max: [number, number, number] };
|
|
122
|
+
/** Named backdrop to clear to. Omit for the default; see `views/background.ts`. */
|
|
123
|
+
backdrop?: BackdropId;
|
|
124
|
+
}
|
|
125
|
+
const AMBIENT = 0.25;
|
|
126
|
+
const KEY_INTENSITY = 1.1;
|
|
127
|
+
const KEY_DIR = normalize([1.5, 2, 1]);
|
|
128
|
+
|
|
129
|
+
type Vec3 = [number, number, number];
|
|
130
|
+
|
|
131
|
+
function normalize(v: number[]): Vec3 {
|
|
132
|
+
const len = Math.hypot(v[0]!, v[1]!, v[2]!) || 1;
|
|
133
|
+
return [v[0]! / len, v[1]! / len, v[2]! / len];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function cross(a: Vec3, b: Vec3): Vec3 {
|
|
137
|
+
return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function dot(a: Vec3, b: Vec3): number {
|
|
141
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Minimal duck-typed views of the Three.js objects we read. */
|
|
145
|
+
interface DuckAttribute {
|
|
146
|
+
array: ArrayLike<number>;
|
|
147
|
+
itemSize: number;
|
|
148
|
+
count: number;
|
|
149
|
+
}
|
|
150
|
+
interface DuckGeometry {
|
|
151
|
+
getAttribute(name: string): DuckAttribute | undefined;
|
|
152
|
+
index: DuckAttribute | null;
|
|
153
|
+
/** Three.js geometry groups: ranges of the index (or position) buffer drawn
|
|
154
|
+
* with `materialIndex` when the mesh carries a material ARRAY. */
|
|
155
|
+
groups?: Array<{ start: number; count: number; materialIndex?: number }>;
|
|
156
|
+
}
|
|
157
|
+
interface DuckMaterial {
|
|
158
|
+
color?: { r: number; g: number; b: number };
|
|
159
|
+
/** Effective glTF base-color alpha after OPAQUE/MASK/BLEND handling. */
|
|
160
|
+
opacity?: number;
|
|
161
|
+
doubleSided?: boolean;
|
|
162
|
+
visible?: boolean;
|
|
163
|
+
}
|
|
164
|
+
interface DuckMesh {
|
|
165
|
+
isMesh?: boolean;
|
|
166
|
+
visible?: boolean;
|
|
167
|
+
geometry?: DuckGeometry;
|
|
168
|
+
material?: DuckMaterial | DuckMaterial[];
|
|
169
|
+
matrixWorld?: { elements: ArrayLike<number> };
|
|
170
|
+
}
|
|
171
|
+
interface DuckObject3D {
|
|
172
|
+
visible?: boolean;
|
|
173
|
+
children?: DuckObject3D[];
|
|
174
|
+
updateMatrixWorld?(force?: boolean): void;
|
|
175
|
+
traverse?(cb: (obj: unknown) => void): void;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
interface Tri {
|
|
179
|
+
// World-space vertices, flattened [x0,y0,z0, x1,y1,z1, x2,y2,z2]
|
|
180
|
+
v: Float64Array;
|
|
181
|
+
color: [number, number, number];
|
|
182
|
+
alpha: number;
|
|
183
|
+
doubleSided: boolean;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Opaque triangles first in scene order, then translucent ones farthest-first,
|
|
188
|
+
* as a GPU renderer composites them. Drawn in scene order, a translucent pane
|
|
189
|
+
* listed before the parts behind it wrote its depth first and hid them, so a
|
|
190
|
+
* glazed opening read as empty. `distance` grows away from the viewer; ties keep
|
|
191
|
+
* scene order, so the result stays deterministic.
|
|
192
|
+
*/
|
|
193
|
+
export function compositingOrder<T extends { v: ArrayLike<number>; alpha: number }>(
|
|
194
|
+
tris: readonly T[],
|
|
195
|
+
distance: (x: number, y: number, z: number) => number,
|
|
196
|
+
): T[] {
|
|
197
|
+
const opaque: T[] = [];
|
|
198
|
+
const translucent: Array<{ tri: T; key: number; index: number }> = [];
|
|
199
|
+
for (const [index, tri] of tris.entries()) {
|
|
200
|
+
if (tri.alpha >= 1) {
|
|
201
|
+
opaque.push(tri);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const v = tri.v;
|
|
205
|
+
const key = distance(
|
|
206
|
+
(v[0]! + v[3]! + v[6]!) / 3,
|
|
207
|
+
(v[1]! + v[4]! + v[7]!) / 3,
|
|
208
|
+
(v[2]! + v[5]! + v[8]!) / 3,
|
|
209
|
+
);
|
|
210
|
+
translucent.push({ tri, key, index });
|
|
211
|
+
}
|
|
212
|
+
translucent.sort((a, b) => b.key - a.key || a.index - b.index);
|
|
213
|
+
return [...opaque, ...translucent.map((entry) => entry.tri)];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Visit every object under `root` that draws. Three's rule: a node with `visible = false`
|
|
218
|
+
* hides its subtree. The start node counts as shown, so a named part (an isolated subject, a
|
|
219
|
+
* measured part) keeps its geometry while the whole scene leaves hidden parts out. A duck root
|
|
220
|
+
* without `children` (the flat scene read from GLB bytes) is walked with `traverse`, each
|
|
221
|
+
* object by its own flag.
|
|
222
|
+
*/
|
|
223
|
+
function forEachDrawn(root: DuckObject3D, visit: (obj: DuckObject3D) => void): void {
|
|
224
|
+
if (!Array.isArray(root.children)) {
|
|
225
|
+
root.traverse?.((obj) => {
|
|
226
|
+
const node = obj as DuckObject3D;
|
|
227
|
+
if (node === root || node.visible !== false) visit(node);
|
|
228
|
+
});
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const walk = (obj: DuckObject3D, start: boolean) => {
|
|
232
|
+
if (!start && obj.visible === false) return;
|
|
233
|
+
visit(obj);
|
|
234
|
+
for (const child of obj.children ?? []) walk(child, false);
|
|
235
|
+
};
|
|
236
|
+
walk(root, true);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Collect world-space triangles + base colors from a (possibly cross-realm) scene. */
|
|
240
|
+
export function collectTriangles(root: DuckObject3D): {
|
|
241
|
+
tris: Tri[];
|
|
242
|
+
bbox: { min: Vec3; max: Vec3 };
|
|
243
|
+
} {
|
|
244
|
+
root.updateMatrixWorld?.(true);
|
|
245
|
+
|
|
246
|
+
const tris: Tri[] = [];
|
|
247
|
+
const min: Vec3 = [Infinity, Infinity, Infinity];
|
|
248
|
+
const max: Vec3 = [-Infinity, -Infinity, -Infinity];
|
|
249
|
+
|
|
250
|
+
const drawMesh = (obj: unknown) => {
|
|
251
|
+
const mesh = obj as DuckMesh;
|
|
252
|
+
if (!mesh.isMesh) return;
|
|
253
|
+
const geo = mesh.geometry;
|
|
254
|
+
const pos = geo?.getAttribute?.('position');
|
|
255
|
+
if (!geo || !pos || pos.itemSize !== 3) return;
|
|
256
|
+
|
|
257
|
+
const mats = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
258
|
+
const colorOf = (mat: DuckMaterial | undefined): [number, number, number] => {
|
|
259
|
+
const c = mat?.color;
|
|
260
|
+
return c ? [clamp01(c.r), clamp01(c.g), clamp01(c.b)] : [0.7, 0.7, 0.7];
|
|
261
|
+
};
|
|
262
|
+
// Per-group material resolution: a multi-material mesh draws each geometry
|
|
263
|
+
// group (a start/count range over the index — or position — buffer) with its
|
|
264
|
+
// own `materialIndex`. Colors are already per-triangle here, so resolve the
|
|
265
|
+
// group covering each triangle's first buffer position; meshes without
|
|
266
|
+
// groups (the common single-material case) keep the flat first material.
|
|
267
|
+
const groups = mats.length > 1 && geo.groups?.length ? geo.groups : undefined;
|
|
268
|
+
const materialAt = (bufferPos: number): DuckMaterial | undefined => {
|
|
269
|
+
if (!groups) return mats[0];
|
|
270
|
+
for (const g of groups) {
|
|
271
|
+
if (bufferPos >= g.start && bufferPos < g.start + g.count) {
|
|
272
|
+
return mats[g.materialIndex ?? 0];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return mats[0];
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const m = mesh.matrixWorld?.elements;
|
|
279
|
+
if (!m) return;
|
|
280
|
+
|
|
281
|
+
const arr = pos.array;
|
|
282
|
+
const world = new Float64Array(pos.count * 3);
|
|
283
|
+
for (let i = 0; i < pos.count; i++) {
|
|
284
|
+
const x = arr[i * 3]!;
|
|
285
|
+
const y = arr[i * 3 + 1]!;
|
|
286
|
+
const z = arr[i * 3 + 2]!;
|
|
287
|
+
const wx = m[0]! * x + m[4]! * y + m[8]! * z + m[12]!;
|
|
288
|
+
const wy = m[1]! * x + m[5]! * y + m[9]! * z + m[13]!;
|
|
289
|
+
const wz = m[2]! * x + m[6]! * y + m[10]! * z + m[14]!;
|
|
290
|
+
world[i * 3] = wx;
|
|
291
|
+
world[i * 3 + 1] = wy;
|
|
292
|
+
world[i * 3 + 2] = wz;
|
|
293
|
+
if (wx < min[0]) min[0] = wx;
|
|
294
|
+
if (wy < min[1]) min[1] = wy;
|
|
295
|
+
if (wz < min[2]) min[2] = wz;
|
|
296
|
+
if (wx > max[0]) max[0] = wx;
|
|
297
|
+
if (wy > max[1]) max[1] = wy;
|
|
298
|
+
if (wz > max[2]) max[2] = wz;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const pushTri = (a: number, b: number, c2: number, material: DuckMaterial | undefined) => {
|
|
302
|
+
const v = new Float64Array(9);
|
|
303
|
+
v[0] = world[a * 3]!;
|
|
304
|
+
v[1] = world[a * 3 + 1]!;
|
|
305
|
+
v[2] = world[a * 3 + 2]!;
|
|
306
|
+
v[3] = world[b * 3]!;
|
|
307
|
+
v[4] = world[b * 3 + 1]!;
|
|
308
|
+
v[5] = world[b * 3 + 2]!;
|
|
309
|
+
v[6] = world[c2 * 3]!;
|
|
310
|
+
v[7] = world[c2 * 3 + 1]!;
|
|
311
|
+
v[8] = world[c2 * 3 + 2]!;
|
|
312
|
+
tris.push({
|
|
313
|
+
v,
|
|
314
|
+
color: colorOf(material),
|
|
315
|
+
alpha: clamp01(material?.opacity ?? 1),
|
|
316
|
+
doubleSided: material?.doubleSided === true,
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// Geometry groups address the index buffer for indexed geometry and the
|
|
321
|
+
// position buffer otherwise, so `i` (the triangle's first buffer slot) is
|
|
322
|
+
// the group-lookup key in both branches.
|
|
323
|
+
const index = geo.index;
|
|
324
|
+
if (index) {
|
|
325
|
+
const ia = index.array;
|
|
326
|
+
for (let i = 0; i + 2 < index.count; i += 3) {
|
|
327
|
+
pushTri(ia[i]!, ia[i + 1]!, ia[i + 2]!, materialAt(i));
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
for (let i = 0; i + 2 < pos.count; i += 3) {
|
|
331
|
+
pushTri(i, i + 1, i + 2, materialAt(i));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
forEachDrawn(root, drawMesh);
|
|
336
|
+
|
|
337
|
+
if (!Number.isFinite(min[0])) {
|
|
338
|
+
return { tris, bbox: { min: [0, 0, 0], max: [0, 0, 0] } };
|
|
339
|
+
}
|
|
340
|
+
return { tris, bbox: { min, max } };
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function clamp01(n: number): number {
|
|
344
|
+
return n < 0 ? 0 : n > 1 ? 1 : n;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Linear -> sRGB encode (the renderer's output transform). Material colors read
|
|
349
|
+
* off the scene are linear-sRGB (Three.js color management converts hex strings
|
|
350
|
+
* on construction), and lighting math happens in linear space — without this
|
|
351
|
+
* encode the views come out far darker than the Three.js-rendered audit grids.
|
|
352
|
+
*/
|
|
353
|
+
function linearToSrgb(c: number): number {
|
|
354
|
+
const v = clamp01(c);
|
|
355
|
+
return v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Render one orthographic view of the scene to an RGB pixel buffer
|
|
360
|
+
* (size*size*3 bytes, row-major from the top-left).
|
|
361
|
+
*/
|
|
362
|
+
export function rasterizeView(
|
|
363
|
+
root: unknown,
|
|
364
|
+
dir: [number, number, number],
|
|
365
|
+
opts: RasterOptions = {},
|
|
366
|
+
): Uint8Array {
|
|
367
|
+
const size = opts.size ?? 256;
|
|
368
|
+
const cull = opts.backfaceCull ?? true;
|
|
369
|
+
const BG = resolveBackdrop(opts.backdrop).rgb;
|
|
370
|
+
const { tris, bbox } = collectTriangles(root as DuckObject3D);
|
|
371
|
+
|
|
372
|
+
const out = new Uint8Array(size * size * 3);
|
|
373
|
+
for (let i = 0; i < size * size; i++) {
|
|
374
|
+
out[i * 3] = BG[0];
|
|
375
|
+
out[i * 3 + 1] = BG[1];
|
|
376
|
+
out[i * 3 + 2] = BG[2];
|
|
377
|
+
}
|
|
378
|
+
if (tris.length === 0) return out;
|
|
379
|
+
|
|
380
|
+
// Camera basis: z points from target toward the camera (three.js convention).
|
|
381
|
+
const z = normalize(dir);
|
|
382
|
+
const upHint: Vec3 = Math.abs(z[1]) > 0.99 ? [0, 0, -1] : [0, 1, 0];
|
|
383
|
+
const x = normalize(cross(upHint, z));
|
|
384
|
+
const y = cross(z, x);
|
|
385
|
+
|
|
386
|
+
// Framing box: a caller-supplied fixed AABB (animation grid — keeps the camera
|
|
387
|
+
// steady so root travel is visible) or the scene's own bounds (static views).
|
|
388
|
+
const frameMin = opts.frameBounds ? opts.frameBounds.min : bbox.min;
|
|
389
|
+
const frameMax = opts.frameBounds ? opts.frameBounds.max : bbox.max;
|
|
390
|
+
const center: Vec3 = [
|
|
391
|
+
(frameMin[0] + frameMax[0]) / 2,
|
|
392
|
+
(frameMin[1] + frameMax[1]) / 2,
|
|
393
|
+
(frameMin[2] + frameMax[2]) / 2,
|
|
394
|
+
];
|
|
395
|
+
|
|
396
|
+
// Project the 8 framing-box corners to find the framing extent for this view.
|
|
397
|
+
let ext = 1e-6;
|
|
398
|
+
for (let ci = 0; ci < 8; ci++) {
|
|
399
|
+
const px = (ci & 1 ? frameMax[0] : frameMin[0]) - center[0];
|
|
400
|
+
const py = (ci & 2 ? frameMax[1] : frameMin[1]) - center[1];
|
|
401
|
+
const pz = (ci & 4 ? frameMax[2] : frameMin[2]) - center[2];
|
|
402
|
+
const p: Vec3 = [px, py, pz];
|
|
403
|
+
ext = Math.max(ext, Math.abs(dot(p, x)), Math.abs(dot(p, y)));
|
|
404
|
+
}
|
|
405
|
+
const scale = (size * 0.45) / ext; // 90% of the half-size — small margin
|
|
406
|
+
const half = size / 2;
|
|
407
|
+
|
|
408
|
+
const zbuf = new Float64Array(size * size).fill(-Infinity);
|
|
409
|
+
|
|
410
|
+
const sx = new Float64Array(3);
|
|
411
|
+
const sy = new Float64Array(3);
|
|
412
|
+
const sz = new Float64Array(3);
|
|
413
|
+
|
|
414
|
+
// Orthographic: distance from the viewer runs against the view axis `z`.
|
|
415
|
+
const ordered = compositingOrder(
|
|
416
|
+
tris,
|
|
417
|
+
(px, py, pz) => -((px - center[0]) * z[0] + (py - center[1]) * z[1] + (pz - center[2]) * z[2]),
|
|
418
|
+
);
|
|
419
|
+
for (const tri of ordered) {
|
|
420
|
+
// World-space face normal (flat shading; robust under non-uniform scale).
|
|
421
|
+
const e1: Vec3 = [tri.v[3]! - tri.v[0]!, tri.v[4]! - tri.v[1]!, tri.v[5]! - tri.v[2]!];
|
|
422
|
+
const e2: Vec3 = [tri.v[6]! - tri.v[0]!, tri.v[7]! - tri.v[1]!, tri.v[8]! - tri.v[2]!];
|
|
423
|
+
const n = cross(e1, e2);
|
|
424
|
+
const nLen = Math.hypot(n[0], n[1], n[2]);
|
|
425
|
+
if (nLen < 1e-12) continue;
|
|
426
|
+
const N: Vec3 = [n[0] / nLen, n[1] / nLen, n[2] / nLen];
|
|
427
|
+
|
|
428
|
+
const facing = dot(N, z);
|
|
429
|
+
if (cull && facing <= 0 && !tri.doubleSided) continue;
|
|
430
|
+
if (tri.alpha <= 0) continue;
|
|
431
|
+
|
|
432
|
+
// Project to screen space.
|
|
433
|
+
for (let i = 0; i < 3; i++) {
|
|
434
|
+
const px = tri.v[i * 3]! - center[0];
|
|
435
|
+
const py = tri.v[i * 3 + 1]! - center[1];
|
|
436
|
+
const pz = tri.v[i * 3 + 2]! - center[2];
|
|
437
|
+
const p: Vec3 = [px, py, pz];
|
|
438
|
+
sx[i] = half + dot(p, x) * scale;
|
|
439
|
+
sy[i] = half - dot(p, y) * scale;
|
|
440
|
+
sz[i] = dot(p, z);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Flat lambert with the audit-grid light rig, in linear space, then the
|
|
444
|
+
// sRGB output transform (matching what a Three.js renderer would write).
|
|
445
|
+
const lambert = Math.max(0, dot(N, KEY_DIR));
|
|
446
|
+
const lit = Math.min(1, AMBIENT + KEY_INTENSITY * lambert);
|
|
447
|
+
const r = Math.round(linearToSrgb(tri.color[0] * lit) * 255);
|
|
448
|
+
const g = Math.round(linearToSrgb(tri.color[1] * lit) * 255);
|
|
449
|
+
const b = Math.round(linearToSrgb(tri.color[2] * lit) * 255);
|
|
450
|
+
|
|
451
|
+
// Rasterize via edge functions.
|
|
452
|
+
const minX = Math.max(0, Math.floor(Math.min(sx[0]!, sx[1]!, sx[2]!)));
|
|
453
|
+
const maxX = Math.min(size - 1, Math.ceil(Math.max(sx[0]!, sx[1]!, sx[2]!)));
|
|
454
|
+
const minY = Math.max(0, Math.floor(Math.min(sy[0]!, sy[1]!, sy[2]!)));
|
|
455
|
+
const maxY = Math.min(size - 1, Math.ceil(Math.max(sy[0]!, sy[1]!, sy[2]!)));
|
|
456
|
+
if (minX > maxX || minY > maxY) continue;
|
|
457
|
+
|
|
458
|
+
const ax = sx[0]!,
|
|
459
|
+
ay = sy[0]!,
|
|
460
|
+
bx2 = sx[1]!,
|
|
461
|
+
by = sy[1]!,
|
|
462
|
+
cx = sx[2]!,
|
|
463
|
+
cy = sy[2]!;
|
|
464
|
+
const area = (bx2 - ax) * (cy - ay) - (by - ay) * (cx - ax);
|
|
465
|
+
if (Math.abs(area) < 1e-9) continue;
|
|
466
|
+
const invArea = 1 / area;
|
|
467
|
+
|
|
468
|
+
for (let py = minY; py <= maxY; py++) {
|
|
469
|
+
for (let px = minX; px <= maxX; px++) {
|
|
470
|
+
const cxp = px + 0.5;
|
|
471
|
+
const cyp = py + 0.5;
|
|
472
|
+
const w0 = ((bx2 - ax) * (cyp - ay) - (by - ay) * (cxp - ax)) * invArea;
|
|
473
|
+
const w1 = ((cx - bx2) * (cyp - by) - (cy - by) * (cxp - bx2)) * invArea;
|
|
474
|
+
const w2 = 1 - w0 - w1;
|
|
475
|
+
// Accept either winding on screen (back-face culling already happened
|
|
476
|
+
// in world space) — check all barycentrics share the area's sign space.
|
|
477
|
+
if (w0 < 0 || w1 < 0 || w2 < 0) continue;
|
|
478
|
+
// Barycentric weights map: w0 → vertex C, w1 → vertex A, w2 → vertex B
|
|
479
|
+
// for this edge-function arrangement; depth interpolation just needs a
|
|
480
|
+
// consistent convex combination, so order doesn't matter for QA views.
|
|
481
|
+
const depth = w1 * sz[0]! + w2 * sz[1]! + w0 * sz[2]!;
|
|
482
|
+
const pi = py * size + px;
|
|
483
|
+
if (depth <= zbuf[pi]!) continue;
|
|
484
|
+
zbuf[pi] = depth;
|
|
485
|
+
if (tri.alpha >= 1) {
|
|
486
|
+
out[pi * 3] = r;
|
|
487
|
+
out[pi * 3 + 1] = g;
|
|
488
|
+
out[pi * 3 + 2] = b;
|
|
489
|
+
} else {
|
|
490
|
+
const inverse = 1 - tri.alpha;
|
|
491
|
+
out[pi * 3] = Math.round(r * tri.alpha + out[pi * 3]! * inverse);
|
|
492
|
+
out[pi * 3 + 1] = Math.round(g * tri.alpha + out[pi * 3 + 1]! * inverse);
|
|
493
|
+
out[pi * 3 + 2] = Math.round(b * tri.alpha + out[pi * 3 + 2]! * inverse);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return out;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/** World-space AABB of a (possibly sandbox-created) scene's drawable geometry.
|
|
503
|
+
* Reuses the rasterizer's own triangle collection so the box matches exactly what
|
|
504
|
+
* gets drawn. Empty scenes report a zero box. Used by the animation grid to union
|
|
505
|
+
* bounds across posed frames into one steady camera framing. */
|
|
506
|
+
export function measureBounds(root: unknown): {
|
|
507
|
+
min: [number, number, number];
|
|
508
|
+
max: [number, number, number];
|
|
509
|
+
} {
|
|
510
|
+
const { bbox } = collectTriangles(root as DuckObject3D);
|
|
511
|
+
return { min: [...bbox.min], max: [...bbox.max] };
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/** Unlike camera framing, an empty part has no measurable geometry bounds. */
|
|
515
|
+
export function measurePartBounds(root: unknown): ReturnType<typeof measureBounds> | null {
|
|
516
|
+
const { tris, bbox } = collectTriangles(root as DuckObject3D);
|
|
517
|
+
return tris.length ? { min: [...bbox.min], max: [...bbox.max] } : null;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* `measurePartBounds` for many nodes of one scene: the same meshes (each node as it
|
|
522
|
+
* draws when shown, hidden descendants left out, every position vertex, null without a
|
|
523
|
+
* triangle), but each mesh is transformed once however many requested ancestors contain it.
|
|
524
|
+
*/
|
|
525
|
+
export function createPartBoundsReader(
|
|
526
|
+
root: unknown,
|
|
527
|
+
): (node: unknown) => ReturnType<typeof measureBounds> | null {
|
|
528
|
+
(root as DuckObject3D).updateMatrixWorld?.(true);
|
|
529
|
+
const own = new Map<unknown, { min: Vec3; max: Vec3; tris: number } | null>();
|
|
530
|
+
const meshBounds = (obj: unknown) => {
|
|
531
|
+
if (own.has(obj)) return own.get(obj)!;
|
|
532
|
+
const mesh = obj as DuckMesh;
|
|
533
|
+
const pos = mesh.isMesh ? mesh.geometry?.getAttribute?.('position') : undefined;
|
|
534
|
+
const m = mesh.matrixWorld?.elements;
|
|
535
|
+
let result: { min: Vec3; max: Vec3; tris: number } | null = null;
|
|
536
|
+
if (pos && pos.itemSize === 3 && m) {
|
|
537
|
+
const min: Vec3 = [Infinity, Infinity, Infinity];
|
|
538
|
+
const max: Vec3 = [-Infinity, -Infinity, -Infinity];
|
|
539
|
+
const arr = pos.array;
|
|
540
|
+
for (let i = 0; i < pos.count; i++) {
|
|
541
|
+
const x = arr[i * 3]!,
|
|
542
|
+
y = arr[i * 3 + 1]!,
|
|
543
|
+
z = arr[i * 3 + 2]!;
|
|
544
|
+
const w: Vec3 = [
|
|
545
|
+
m[0]! * x + m[4]! * y + m[8]! * z + m[12]!,
|
|
546
|
+
m[1]! * x + m[5]! * y + m[9]! * z + m[13]!,
|
|
547
|
+
m[2]! * x + m[6]! * y + m[10]! * z + m[14]!,
|
|
548
|
+
];
|
|
549
|
+
for (let k = 0; k < 3; k++) {
|
|
550
|
+
if (w[k]! < min[k]!) min[k] = w[k]!;
|
|
551
|
+
if (w[k]! > max[k]!) max[k] = w[k]!;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
const count = mesh.geometry?.index ? mesh.geometry.index.count : pos.count;
|
|
555
|
+
result = { min, max, tris: Math.floor(count / 3) };
|
|
556
|
+
}
|
|
557
|
+
own.set(obj, result);
|
|
558
|
+
return result;
|
|
559
|
+
};
|
|
560
|
+
return (node) => {
|
|
561
|
+
const min: Vec3 = [Infinity, Infinity, Infinity];
|
|
562
|
+
const max: Vec3 = [-Infinity, -Infinity, -Infinity];
|
|
563
|
+
let tris = 0;
|
|
564
|
+
forEachDrawn(node as DuckObject3D, (obj) => {
|
|
565
|
+
const bounds = meshBounds(obj);
|
|
566
|
+
if (!bounds) return;
|
|
567
|
+
tris += bounds.tris;
|
|
568
|
+
for (let k = 0; k < 3; k++) {
|
|
569
|
+
if (bounds.min[k]! < min[k]!) min[k] = bounds.min[k]!;
|
|
570
|
+
if (bounds.max[k]! > max[k]!) max[k] = bounds.max[k]!;
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
return tris ? { min, max } : null;
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Fraction of non-background pixels — used by tests and occupancy checks. The
|
|
579
|
+
* raster must be measured against the backdrop it was painted with, so pass the
|
|
580
|
+
* same `backdrop` the render used (omitted on both sides means the default).
|
|
581
|
+
*/
|
|
582
|
+
export function coverage(rgb: Uint8Array, size: number, backdrop?: BackdropId): number {
|
|
583
|
+
const BG = resolveBackdrop(backdrop).rgb;
|
|
584
|
+
let filled = 0;
|
|
585
|
+
for (let i = 0; i < size * size; i++) {
|
|
586
|
+
if (rgb[i * 3] !== BG[0] || rgb[i * 3 + 1] !== BG[1] || rgb[i * 3 + 2] !== BG[2]) filled++;
|
|
587
|
+
}
|
|
588
|
+
return filled / (size * size);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Hide a named subtree from the rasterizer so a view can see past it (lift a roof,
|
|
593
|
+
* cut away a near wall). `collectTriangles` hides a hidden node's subtree, but a flat
|
|
594
|
+
* duck scene (no `children`) culls per mesh, so this sets `.visible = false` on each
|
|
595
|
+
* matched node AND every descendant.
|
|
596
|
+
*
|
|
597
|
+
* `match` is either a string (case-insensitive exact match OR startsWith — so
|
|
598
|
+
* "Roof" also lifts "Roof_Ridge") or a predicate over the node name. Returns the
|
|
599
|
+
* number of matched subtree roots hidden (0 → nothing matched; the caller decides
|
|
600
|
+
* whether to warn). Pure helper; mutates `.visible` on the passed scene.
|
|
601
|
+
*/
|
|
602
|
+
export function hideNodeInScene(
|
|
603
|
+
root: unknown,
|
|
604
|
+
match: string | ((name: string) => boolean),
|
|
605
|
+
): number {
|
|
606
|
+
const test =
|
|
607
|
+
typeof match === 'function'
|
|
608
|
+
? match
|
|
609
|
+
: (name: string) => {
|
|
610
|
+
const t = match.toLowerCase();
|
|
611
|
+
const n = name.toLowerCase();
|
|
612
|
+
return n === t || n.startsWith(t);
|
|
613
|
+
};
|
|
614
|
+
let hidden = 0;
|
|
615
|
+
const r = root as DuckObject3D;
|
|
616
|
+
r.traverse?.((obj) => {
|
|
617
|
+
const node = obj as { name?: string; traverse?(cb: (o: unknown) => void): void };
|
|
618
|
+
if (!node.name || !test(node.name)) return;
|
|
619
|
+
hidden++;
|
|
620
|
+
// Flip the matched node and its whole subtree (the per-mesh cull means hiding
|
|
621
|
+
// just the group is not enough — the leaf meshes must be invisible).
|
|
622
|
+
node.traverse?.((d) => {
|
|
623
|
+
(d as { visible?: boolean }).visible = false;
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
return hidden;
|
|
627
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic identity of the pure-CPU rasterizer view producer.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the external render-service `rendererId` contract
|
|
5
|
+
* ("<family>:<identity...>", e.g. "dawn-vulkan:nvidia-rtx-a4500:NVIDIA: 550.100")
|
|
6
|
+
* so QA evidence and generation results can always name the honest producer of a
|
|
7
|
+
* view artifact. The engine version is read from package.json ONCE at module
|
|
8
|
+
* load — never per call — keeping the constant deterministic for a given build.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFileSync } from 'node:fs';
|
|
12
|
+
|
|
13
|
+
function engineVersion(): string {
|
|
14
|
+
// Source lives in src/views; Node bundles live directly in dist. Never use
|
|
15
|
+
// a consuming application's package version as the engine identity.
|
|
16
|
+
for (const path of ['../package.json', '../../package.json']) {
|
|
17
|
+
try {
|
|
18
|
+
const raw = readFileSync(new URL(path, import.meta.url), 'utf8');
|
|
19
|
+
const pkg = JSON.parse(raw) as { name?: unknown; version?: unknown };
|
|
20
|
+
if (pkg.name === '@instruktlabs/kiln' && typeof pkg.version === 'string' && pkg.version) {
|
|
21
|
+
return pkg.version;
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
// Try the other supported source/bundle layout.
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return 'unknown';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** e.g. "cpu-raster:0.6.0" — the CPU rasterizer's deterministic rendererId. */
|
|
31
|
+
export const CPU_RASTER_RENDERER_ID = `cpu-raster:${engineVersion()}`;
|