@developerz.ai/ts23d 0.0.0-stage → 0.2.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/.claude/agents/bug-hunter.md +21 -0
- package/.claude/agents/docs-author.md +13 -0
- package/.claude/agents/dx-auditor.md +14 -0
- package/.claude/agents/primitive-author.md +22 -0
- package/.claude/agents/recipe-author.md +36 -0
- package/.claude/agents/visual-reviewer.md +23 -0
- package/.claude/commands/feature.md +28 -0
- package/.claude/commands/new-recipe.md +19 -0
- package/.claude/commands/release.md +14 -0
- package/.claude/commands/verify.md +9 -0
- package/.claude/skills/author-recipe/SKILL.md +93 -0
- package/CHANGELOG.md +90 -0
- package/CLAUDE.md +85 -0
- package/LICENSE +21 -0
- package/README.md +385 -2
- package/dist/chunk-6b05mnmx.js +19 -0
- package/dist/chunk-6b05mnmx.js.map +11 -0
- package/dist/chunk-7rtfjh9f.js +45 -0
- package/dist/chunk-7rtfjh9f.js.map +10 -0
- package/dist/chunk-8j4c28jt.js +4085 -0
- package/dist/chunk-8j4c28jt.js.map +46 -0
- package/dist/chunk-d1fv6hrm.js +2532 -0
- package/dist/chunk-d1fv6hrm.js.map +43 -0
- package/dist/chunk-dbq4qf52.js +902 -0
- package/dist/chunk-dbq4qf52.js.map +25 -0
- package/dist/chunk-drna2rny.js +836 -0
- package/dist/chunk-drna2rny.js.map +17 -0
- package/dist/chunk-dxvypr7y.js +89 -0
- package/dist/chunk-dxvypr7y.js.map +11 -0
- package/dist/chunk-f6yme003.js +1589 -0
- package/dist/chunk-f6yme003.js.map +30 -0
- package/dist/chunk-hg7pf34j.js +465 -0
- package/dist/chunk-hg7pf34j.js.map +19 -0
- package/dist/chunk-jq4e17tj.js +1031 -0
- package/dist/chunk-jq4e17tj.js.map +21 -0
- package/dist/chunk-y63c6zcv.js +2668 -0
- package/dist/chunk-y63c6zcv.js.map +53 -0
- package/dist/cli/args.d.ts +30 -0
- package/dist/cli/bin.d.ts +2 -0
- package/dist/cli/bin.js +348 -0
- package/dist/cli/bin.js.map +15 -0
- package/dist/cli/load.d.ts +2 -0
- package/dist/cli/manifest.d.ts +53 -0
- package/dist/cli/render-cmds.d.ts +12 -0
- package/dist/cli/run.d.ts +1 -0
- package/dist/cli/texture-cache.d.ts +4 -0
- package/dist/core/asset.d.ts +10 -0
- package/dist/core/definition.d.ts +155 -0
- package/dist/core/errors.d.ts +17 -0
- package/dist/core/family.d.ts +23 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.js +69 -0
- package/dist/core/index.js.map +9 -0
- package/dist/core/mesh.d.ts +35 -0
- package/dist/core/part.d.ts +114 -0
- package/dist/core/png.d.ts +1 -0
- package/dist/core/rng.d.ts +12 -0
- package/dist/core/transform.d.ts +20 -0
- package/dist/core/vec.d.ts +11 -0
- package/dist/core/world.d.ts +16 -0
- package/dist/export/bin-writer.d.ts +16 -0
- package/dist/export/container.d.ts +3 -0
- package/dist/export/credits.d.ts +4 -0
- package/dist/export/glb-options.d.ts +48 -0
- package/dist/export/glb.d.ts +8 -0
- package/dist/export/hierarchy.d.ts +23 -0
- package/dist/export/index.d.ts +5 -0
- package/dist/export/index.js +40 -0
- package/dist/export/index.js.map +9 -0
- package/dist/export/lights.d.ts +8 -0
- package/dist/export/lod-coverage.d.ts +12 -0
- package/dist/export/materials.d.ts +23 -0
- package/dist/export/merge-pivots.d.ts +6 -0
- package/dist/export/metadata.d.ts +21 -0
- package/dist/export/motion.d.ts +9 -0
- package/dist/export/optimize-parts.d.ts +26 -0
- package/dist/export/primitive.d.ts +3 -0
- package/dist/export/tangents.d.ts +2 -0
- package/dist/export/textures.d.ts +22 -0
- package/dist/export/version.d.ts +2 -0
- package/dist/grammar/index.d.ts +2 -0
- package/dist/grammar/index.js +16 -0
- package/dist/grammar/index.js.map +9 -0
- package/dist/grammar/split.d.ts +21 -0
- package/dist/grammar/whyte.d.ts +5 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +457 -0
- package/dist/index.js.map +9 -0
- package/dist/kinds/building.d.ts +44 -0
- package/dist/kinds/faces.d.ts +27 -0
- package/dist/kinds/head-armour.d.ts +5 -0
- package/dist/kinds/head-beard.d.ts +6 -0
- package/dist/kinds/head-bust.d.ts +5 -0
- package/dist/kinds/head-extras.d.ts +15 -0
- package/dist/kinds/head-face.d.ts +8 -0
- package/dist/kinds/head-garb.d.ts +4 -0
- package/dist/kinds/head-geom.d.ts +7 -0
- package/dist/kinds/head-hair.d.ts +4 -0
- package/dist/kinds/head-layout.d.ts +29 -0
- package/dist/kinds/head-mesh.d.ts +31 -0
- package/dist/kinds/head-mouth.d.ts +4 -0
- package/dist/kinds/head-params.d.ts +116 -0
- package/dist/kinds/head-presets.d.ts +19 -0
- package/dist/kinds/head-rim.d.ts +10 -0
- package/dist/kinds/head-tone.d.ts +10 -0
- package/dist/kinds/head-torso.d.ts +35 -0
- package/dist/kinds/head.d.ts +39 -0
- package/dist/kinds/hull-lines.d.ts +65 -0
- package/dist/kinds/hull-skin.d.ts +6 -0
- package/dist/kinds/hull.d.ts +14 -0
- package/dist/kinds/index.d.ts +16 -0
- package/dist/kinds/index.js +78 -0
- package/dist/kinds/index.js.map +9 -0
- package/dist/kinds/mass.d.ts +15 -0
- package/dist/kinds/openings.d.ts +30 -0
- package/dist/kinds/planned.d.ts +6 -0
- package/dist/kinds/roof-chimney.d.ts +16 -0
- package/dist/kinds/roof-shape.d.ts +64 -0
- package/dist/kinds/roof.d.ts +31 -0
- package/dist/kinds/vegetation-fronds.d.ts +15 -0
- package/dist/kinds/vegetation-impostor.d.ts +9 -0
- package/dist/kinds/vegetation-leaves.d.ts +15 -0
- package/dist/kinds/vegetation-mesh.d.ts +21 -0
- package/dist/kinds/vegetation-params.d.ts +90 -0
- package/dist/kinds/vegetation-presets.d.ts +20 -0
- package/dist/kinds/vegetation-skeleton.d.ts +20 -0
- package/dist/kinds/vegetation.d.ts +42 -0
- package/dist/kinds/vehicle.d.ts +42 -0
- package/dist/material/cc0.d.ts +4 -0
- package/dist/material/define.d.ts +34 -0
- package/dist/material/generator.d.ts +4 -0
- package/dist/material/index.d.ts +9 -0
- package/dist/material/index.js +70 -0
- package/dist/material/index.js.map +9 -0
- package/dist/material/library.d.ts +7 -0
- package/dist/material/material-def.d.ts +30 -0
- package/dist/material/paint/bond.d.ts +3 -0
- package/dist/material/paint/canvas.d.ts +39 -0
- package/dist/material/paint/cell.d.ts +4 -0
- package/dist/material/paint/cells-round.d.ts +5 -0
- package/dist/material/paint/cells.d.ts +7 -0
- package/dist/material/paint/compose.d.ts +5 -0
- package/dist/material/paint/concrete.d.ts +3 -0
- package/dist/material/paint/courses.d.ts +31 -0
- package/dist/material/paint/decode-png.d.ts +6 -0
- package/dist/material/paint/default-sheet.d.ts +4 -0
- package/dist/material/paint/fabric.d.ts +4 -0
- package/dist/material/paint/foliage-broad.d.ts +5 -0
- package/dist/material/paint/foliage-common.d.ts +35 -0
- package/dist/material/paint/foliage-compound.d.ts +4 -0
- package/dist/material/paint/foliage-conifer.d.ts +5 -0
- package/dist/material/paint/foliage-raster.d.ts +26 -0
- package/dist/material/paint/foliage.d.ts +3 -0
- package/dist/material/paint/image-strip.d.ts +4 -0
- package/dist/material/paint/kit.d.ts +5 -0
- package/dist/material/paint/masks.d.ts +3 -0
- package/dist/material/paint/metal.d.ts +3 -0
- package/dist/material/paint/noise.d.ts +9 -0
- package/dist/material/paint/normal.d.ts +8 -0
- package/dist/material/paint/orm.d.ts +8 -0
- package/dist/material/paint/planks.d.ts +3 -0
- package/dist/material/paint/plates.d.ts +3 -0
- package/dist/material/paint/shapes.d.ts +8 -0
- package/dist/material/paint/slate.d.ts +3 -0
- package/dist/material/paint/stamp.d.ts +3 -0
- package/dist/material/paint/strip.d.ts +3 -0
- package/dist/material/paint/surface.d.ts +5 -0
- package/dist/material/paint/types.d.ts +65 -0
- package/dist/material/paint/validate.d.ts +3 -0
- package/dist/material/palette.d.ts +14 -0
- package/dist/material/shader-godot.d.ts +2 -0
- package/dist/material/shader-three.d.ts +2 -0
- package/dist/material/shader.d.ts +46 -0
- package/dist/material/slots.d.ts +5 -0
- package/dist/material/texture-source.d.ts +34 -0
- package/dist/material/trim-sheet.d.ts +38 -0
- package/dist/neural/generator.d.ts +25 -0
- package/dist/neural/images.d.ts +17 -0
- package/dist/neural/index.d.ts +2 -0
- package/dist/neural/index.js +14 -0
- package/dist/neural/index.js.map +9 -0
- package/dist/passes/bake-ao.d.ts +17 -0
- package/dist/passes/grime.d.ts +15 -0
- package/dist/passes/index.d.ts +6 -0
- package/dist/passes/index.js +22 -0
- package/dist/passes/index.js.map +9 -0
- package/dist/passes/livery.d.ts +19 -0
- package/dist/passes/optimize-cache.d.ts +15 -0
- package/dist/passes/optimize-weld.d.ts +15 -0
- package/dist/passes/optimize.d.ts +28 -0
- package/dist/passes/ray-grid.d.ts +23 -0
- package/dist/passes/weighted-normals.d.ts +8 -0
- package/dist/primitives/beam.d.ts +17 -0
- package/dist/primitives/bevel-box.d.ts +13 -0
- package/dist/primitives/box.d.ts +16 -0
- package/dist/primitives/cell.d.ts +20 -0
- package/dist/primitives/check.d.ts +12 -0
- package/dist/primitives/closed.d.ts +11 -0
- package/dist/primitives/erosion.d.ts +22 -0
- package/dist/primitives/font-5x7.d.ts +3 -0
- package/dist/primitives/heightfield.d.ts +16 -0
- package/dist/primitives/index.d.ts +23 -0
- package/dist/primitives/index.js +81 -0
- package/dist/primitives/index.js.map +9 -0
- package/dist/primitives/lathe-facets.d.ts +8 -0
- package/dist/primitives/lathe.d.ts +26 -0
- package/dist/primitives/lattice.d.ts +30 -0
- package/dist/primitives/loft.d.ts +15 -0
- package/dist/primitives/mc-table.d.ts +2 -0
- package/dist/primitives/member.d.ts +19 -0
- package/dist/primitives/noise.d.ts +34 -0
- package/dist/primitives/planar.d.ts +10 -0
- package/dist/primitives/prism.d.ts +13 -0
- package/dist/primitives/sculpt-edit.d.ts +56 -0
- package/dist/primitives/sculpt-tree.d.ts +23 -0
- package/dist/primitives/sculpt.d.ts +27 -0
- package/dist/primitives/sdf-grid.d.ts +17 -0
- package/dist/primitives/sdf-ops.d.ts +37 -0
- package/dist/primitives/sdf.d.ts +21 -0
- package/dist/primitives/strip-uv.d.ts +11 -0
- package/dist/primitives/surface-nets.d.ts +7 -0
- package/dist/primitives/sweep.d.ts +19 -0
- package/dist/primitives/terrain-color.d.ts +30 -0
- package/dist/primitives/terrain-grid.d.ts +36 -0
- package/dist/primitives/text-layout.d.ts +22 -0
- package/dist/primitives/text.d.ts +27 -0
- package/dist/primitives/tiled.d.ts +22 -0
- package/dist/primitives/transport.d.ts +17 -0
- package/dist/primitives/triangulate.d.ts +2 -0
- package/dist/primitives/value-noise.d.ts +10 -0
- package/dist/qa/checks.d.ts +11 -0
- package/dist/qa/clash.d.ts +2 -0
- package/dist/qa/floating.d.ts +5 -0
- package/dist/qa/gates.d.ts +12 -0
- package/dist/qa/geometry.d.ts +21 -0
- package/dist/qa/index.d.ts +12 -0
- package/dist/qa/index.js +78 -0
- package/dist/qa/index.js.map +9 -0
- package/dist/qa/inside.d.ts +12 -0
- package/dist/qa/inspect.d.ts +18 -0
- package/dist/qa/lods.d.ts +12 -0
- package/dist/qa/measures.d.ts +4 -0
- package/dist/qa/occlusion.d.ts +3 -0
- package/dist/qa/sanity.d.ts +7 -0
- package/dist/qa/types.d.ts +12 -0
- package/dist/render/beauty.d.ts +40 -0
- package/dist/render/camera.d.ts +33 -0
- package/dist/render/depth-map.d.ts +38 -0
- package/dist/render/font.d.ts +1 -0
- package/dist/render/ground.d.ts +13 -0
- package/dist/render/index.d.ts +10 -0
- package/dist/render/index.js +47 -0
- package/dist/render/index.js.map +9 -0
- package/dist/render/lighting.d.ts +27 -0
- package/dist/render/lod-strip.d.ts +5 -0
- package/dist/render/metrics.d.ts +37 -0
- package/dist/render/options.d.ts +28 -0
- package/dist/render/photo-match.d.ts +19 -0
- package/dist/render/raster.d.ts +25 -0
- package/dist/render/resolve.d.ts +11 -0
- package/dist/render/review-prompt.d.ts +2 -0
- package/dist/render/review-warnings.d.ts +34 -0
- package/dist/render/review.d.ts +24 -0
- package/dist/render/scene.d.ts +18 -0
- package/dist/render/shade.d.ts +22 -0
- package/dist/render/sheet.d.ts +15 -0
- package/dist/render/texture.d.ts +15 -0
- package/dist/render/thumbnail.d.ts +8 -0
- package/dist/render/vis-buffer.d.ts +18 -0
- package/dist/testing/assert.d.ts +21 -0
- package/dist/testing/compiled.d.ts +15 -0
- package/dist/testing/hash.d.ts +1 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +134 -0
- package/dist/testing/index.js.map +13 -0
- package/dist/testing/snapshot.d.ts +13 -0
- package/docs/README.md +56 -0
- package/docs/architecture/README.md +68 -0
- package/docs/architecture/adding-a-kind.md +44 -0
- package/docs/architecture/adding-a-primitive.md +49 -0
- package/docs/architecture/errors.md +47 -0
- package/docs/architecture/glb-production.md +214 -0
- package/docs/architecture/gltf-capabilities.md +117 -0
- package/docs/architecture/materials.md +151 -0
- package/docs/decisions/001-recipe-compiler-over-ai-meshes.md +27 -0
- package/docs/decisions/002-typescript-not-json.md +22 -0
- package/docs/decisions/003-shared-trim-sheet.md +21 -0
- package/docs/decisions/004-z-up-metres.md +21 -0
- package/docs/decisions/005-zero-runtime-deps.md +21 -0
- package/docs/decisions/006-single-package-subpath-exports.md +20 -0
- package/docs/decisions/007-cpu-contact-sheets.md +21 -0
- package/docs/decisions/008-surface-materials.md +21 -0
- package/docs/decisions/009-gltf-front-axis.md +21 -0
- package/docs/decisions/README.md +15 -0
- package/docs/idea/01-vision.md +117 -0
- package/docs/idea/02-dsl.md +343 -0
- package/docs/idea/03-ir.md +97 -0
- package/docs/idea/04-materials.md +114 -0
- package/docs/idea/05-agent-loop.md +141 -0
- package/docs/idea/06-qa.md +101 -0
- package/docs/idea/07-what-fits.md +45 -0
- package/docs/idea/08-neural-adapters.md +78 -0
- package/docs/idea/09-kinds.md +105 -0
- package/docs/idea/10-sculpting.md +166 -0
- package/docs/idea/11-materials-authoring.md +132 -0
- package/docs/idea/12-blender-bridge.md +136 -0
- package/docs/idea/13-asset-pipeline-research.md +89 -0
- package/docs/landscape.md +49 -0
- package/docs/plans/roadmap.md +139 -0
- package/examples/build-with-bun.ts +41 -0
- package/llms.txt +47 -0
- package/package.json +100 -4
- package/recipes/README.md +38 -0
- package/recipes/asteroid/README.md +46 -0
- package/recipes/asteroid/asteroid.ts +336 -0
- package/recipes/boulders/README.md +28 -0
- package/recipes/boulders/boulders.ts +117 -0
- package/recipes/boxcar/README.md +53 -0
- package/recipes/boxcar/boxcar.ts +1000 -0
- package/recipes/cargo_container_scifi/README.md +52 -0
- package/recipes/cargo_container_scifi/cargo_container_scifi.ts +461 -0
- package/recipes/dropship/README.md +84 -0
- package/recipes/dropship/dropship.ts +1144 -0
- package/recipes/eiffel_tower/README.md +110 -0
- package/recipes/eiffel_tower/eiffel_tower.ts +781 -0
- package/recipes/goblin_head/README.md +75 -0
- package/recipes/goblin_head/goblin_head.ts +38 -0
- package/recipes/human_head/README.md +68 -0
- package/recipes/human_head/human_head.ts +38 -0
- package/recipes/loco_440/README.md +32 -0
- package/recipes/loco_440/loco_440.ts +1404 -0
- package/recipes/material_swatches/README.md +21 -0
- package/recipes/material_swatches/material_swatches.ts +189 -0
- package/recipes/mountain_range/README.md +45 -0
- package/recipes/mountain_range/mountain_range.ts +128 -0
- package/recipes/oak/README.md +30 -0
- package/recipes/oak/oak.ts +19 -0
- package/recipes/orc_head/README.md +78 -0
- package/recipes/orc_head/orc_head.ts +41 -0
- package/recipes/palm/README.md +30 -0
- package/recipes/palm/palm.ts +19 -0
- package/recipes/pine/README.md +29 -0
- package/recipes/pine/pine.ts +19 -0
- package/recipes/signal_gantry/README.md +36 -0
- package/recipes/signal_gantry/signal_gantry.ts +522 -0
- package/recipes/station_halt/README.md +39 -0
- package/recipes/station_halt/station_halt.ts +722 -0
- package/recipes/t34/README.md +44 -0
- package/recipes/t34/t34.ts +1068 -0
- package/recipes/tiger_1/README.md +75 -0
- package/recipes/tiger_1/tiger_1.ts +1370 -0
- package/recipes/water_tower/README.md +40 -0
- package/recipes/water_tower/water_tower.ts +542 -0
- package/src/cli/args.ts +125 -0
- package/src/cli/bin.ts +7 -0
- package/src/cli/load.ts +17 -0
- package/src/cli/manifest.ts +95 -0
- package/src/cli/render-cmds.ts +66 -0
- package/src/cli/run.ts +192 -0
- package/src/cli/texture-cache.ts +24 -0
- package/src/core/asset.ts +129 -0
- package/src/core/definition.ts +156 -0
- package/src/core/errors.ts +50 -0
- package/src/core/family.ts +50 -0
- package/src/core/index.ts +66 -0
- package/src/core/mesh.ts +114 -0
- package/src/core/part.ts +130 -0
- package/src/core/png.ts +49 -0
- package/src/core/rng.ts +49 -0
- package/src/core/transform.ts +90 -0
- package/src/core/vec.ts +26 -0
- package/src/core/world.ts +80 -0
- package/src/export/bin-writer.ts +79 -0
- package/src/export/container.ts +35 -0
- package/src/export/credits.ts +25 -0
- package/src/export/glb-options.ts +53 -0
- package/src/export/glb.ts +187 -0
- package/src/export/hierarchy.ts +122 -0
- package/src/export/index.ts +34 -0
- package/src/export/lights.ts +49 -0
- package/src/export/lod-coverage.ts +71 -0
- package/src/export/materials.ts +126 -0
- package/src/export/merge-pivots.ts +146 -0
- package/src/export/metadata.ts +62 -0
- package/src/export/motion.ts +70 -0
- package/src/export/optimize-parts.ts +80 -0
- package/src/export/primitive.ts +35 -0
- package/src/export/tangents.ts +75 -0
- package/src/export/textures.ts +88 -0
- package/src/export/version.ts +6 -0
- package/src/grammar/index.ts +4 -0
- package/src/grammar/split.ts +87 -0
- package/src/grammar/whyte.ts +20 -0
- package/src/index.ts +14 -0
- package/src/kinds/building.ts +153 -0
- package/src/kinds/faces.ts +138 -0
- package/src/kinds/head-armour.ts +181 -0
- package/src/kinds/head-beard.ts +133 -0
- package/src/kinds/head-bust.ts +184 -0
- package/src/kinds/head-extras.ts +150 -0
- package/src/kinds/head-face.ts +242 -0
- package/src/kinds/head-garb.ts +181 -0
- package/src/kinds/head-geom.ts +31 -0
- package/src/kinds/head-hair.ts +193 -0
- package/src/kinds/head-layout.ts +63 -0
- package/src/kinds/head-mesh.ts +195 -0
- package/src/kinds/head-mouth.ts +111 -0
- package/src/kinds/head-params.ts +162 -0
- package/src/kinds/head-presets.ts +155 -0
- package/src/kinds/head-rim.ts +128 -0
- package/src/kinds/head-tone.ts +52 -0
- package/src/kinds/head-torso.ts +230 -0
- package/src/kinds/head.ts +176 -0
- package/src/kinds/hull-lines.ts +160 -0
- package/src/kinds/hull-skin.ts +83 -0
- package/src/kinds/hull.ts +209 -0
- package/src/kinds/index.ts +63 -0
- package/src/kinds/mass.ts +110 -0
- package/src/kinds/openings.ts +141 -0
- package/src/kinds/planned.ts +12 -0
- package/src/kinds/roof-chimney.ts +100 -0
- package/src/kinds/roof-shape.ts +230 -0
- package/src/kinds/roof.ts +250 -0
- package/src/kinds/vegetation-fronds.ts +126 -0
- package/src/kinds/vegetation-impostor.ts +118 -0
- package/src/kinds/vegetation-leaves.ts +168 -0
- package/src/kinds/vegetation-mesh.ts +174 -0
- package/src/kinds/vegetation-params.ts +147 -0
- package/src/kinds/vegetation-presets.ts +184 -0
- package/src/kinds/vegetation-skeleton.ts +168 -0
- package/src/kinds/vegetation.ts +199 -0
- package/src/kinds/vehicle.ts +144 -0
- package/src/material/cc0.ts +41 -0
- package/src/material/define.ts +130 -0
- package/src/material/generator.ts +63 -0
- package/src/material/index.ts +60 -0
- package/src/material/library.ts +196 -0
- package/src/material/material-def.ts +84 -0
- package/src/material/paint/bond.ts +60 -0
- package/src/material/paint/canvas.ts +101 -0
- package/src/material/paint/cell.ts +39 -0
- package/src/material/paint/cells-round.ts +119 -0
- package/src/material/paint/cells.ts +111 -0
- package/src/material/paint/compose.ts +53 -0
- package/src/material/paint/concrete.ts +62 -0
- package/src/material/paint/courses.ts +85 -0
- package/src/material/paint/decode-png.ts +106 -0
- package/src/material/paint/default-sheet.ts +73 -0
- package/src/material/paint/fabric.ts +63 -0
- package/src/material/paint/foliage-broad.ts +126 -0
- package/src/material/paint/foliage-common.ts +93 -0
- package/src/material/paint/foliage-compound.ts +135 -0
- package/src/material/paint/foliage-conifer.ts +143 -0
- package/src/material/paint/foliage-raster.ts +196 -0
- package/src/material/paint/foliage.ts +23 -0
- package/src/material/paint/image-strip.ts +88 -0
- package/src/material/paint/kit.ts +37 -0
- package/src/material/paint/masks.ts +46 -0
- package/src/material/paint/metal.ts +109 -0
- package/src/material/paint/noise.ts +52 -0
- package/src/material/paint/normal.ts +52 -0
- package/src/material/paint/orm.ts +108 -0
- package/src/material/paint/planks.ts +101 -0
- package/src/material/paint/plates.ts +72 -0
- package/src/material/paint/shapes.ts +28 -0
- package/src/material/paint/slate.ts +52 -0
- package/src/material/paint/stamp.ts +40 -0
- package/src/material/paint/strip.ts +48 -0
- package/src/material/paint/surface.ts +60 -0
- package/src/material/paint/types.ts +94 -0
- package/src/material/paint/validate.ts +74 -0
- package/src/material/palette.ts +46 -0
- package/src/material/shader-godot.ts +77 -0
- package/src/material/shader-three.ts +103 -0
- package/src/material/shader.ts +100 -0
- package/src/material/slots.ts +18 -0
- package/src/material/texture-source.ts +86 -0
- package/src/material/trim-sheet.ts +166 -0
- package/src/neural/generator.ts +37 -0
- package/src/neural/images.ts +27 -0
- package/src/neural/index.ts +10 -0
- package/src/passes/bake-ao.ts +183 -0
- package/src/passes/grime.ts +37 -0
- package/src/passes/index.ts +8 -0
- package/src/passes/livery.ts +66 -0
- package/src/passes/optimize-cache.ts +175 -0
- package/src/passes/optimize-weld.ts +147 -0
- package/src/passes/optimize.ts +85 -0
- package/src/passes/ray-grid.ts +237 -0
- package/src/passes/weighted-normals.ts +125 -0
- package/src/primitives/beam.ts +60 -0
- package/src/primitives/bevel-box.ts +140 -0
- package/src/primitives/box.ts +90 -0
- package/src/primitives/cell.ts +115 -0
- package/src/primitives/check.ts +49 -0
- package/src/primitives/closed.ts +74 -0
- package/src/primitives/erosion.ts +183 -0
- package/src/primitives/font-5x7.ts +117 -0
- package/src/primitives/heightfield.ts +101 -0
- package/src/primitives/index.ts +56 -0
- package/src/primitives/lathe-facets.ts +45 -0
- package/src/primitives/lathe.ts +174 -0
- package/src/primitives/lattice.ts +131 -0
- package/src/primitives/loft.ts +174 -0
- package/src/primitives/mc-table.ts +41 -0
- package/src/primitives/member.ts +130 -0
- package/src/primitives/noise.ts +157 -0
- package/src/primitives/planar.ts +55 -0
- package/src/primitives/prism.ts +85 -0
- package/src/primitives/sculpt-edit.ts +212 -0
- package/src/primitives/sculpt-tree.ts +226 -0
- package/src/primitives/sculpt.ts +80 -0
- package/src/primitives/sdf-grid.ts +131 -0
- package/src/primitives/sdf-ops.ts +145 -0
- package/src/primitives/sdf.ts +83 -0
- package/src/primitives/strip-uv.ts +26 -0
- package/src/primitives/surface-nets.ts +161 -0
- package/src/primitives/sweep.ts +162 -0
- package/src/primitives/terrain-color.ts +85 -0
- package/src/primitives/terrain-grid.ts +137 -0
- package/src/primitives/text-layout.ts +85 -0
- package/src/primitives/text.ts +197 -0
- package/src/primitives/tiled.ts +93 -0
- package/src/primitives/transport.ts +85 -0
- package/src/primitives/triangulate.ts +42 -0
- package/src/primitives/value-noise.ts +62 -0
- package/src/qa/checks.ts +110 -0
- package/src/qa/clash.ts +177 -0
- package/src/qa/floating.ts +63 -0
- package/src/qa/gates.ts +126 -0
- package/src/qa/geometry.ts +187 -0
- package/src/qa/index.ts +28 -0
- package/src/qa/inside.ts +114 -0
- package/src/qa/inspect.ts +107 -0
- package/src/qa/lods.ts +97 -0
- package/src/qa/measures.ts +67 -0
- package/src/qa/occlusion.ts +166 -0
- package/src/qa/sanity.ts +137 -0
- package/src/qa/types.ts +17 -0
- package/src/render/beauty.ts +115 -0
- package/src/render/camera.ts +142 -0
- package/src/render/depth-map.ts +191 -0
- package/src/render/font.ts +76 -0
- package/src/render/ground.ts +87 -0
- package/src/render/index.ts +34 -0
- package/src/render/lighting.ts +121 -0
- package/src/render/lod-strip.ts +34 -0
- package/src/render/metrics.ts +147 -0
- package/src/render/options.ts +81 -0
- package/src/render/photo-match.ts +28 -0
- package/src/render/raster.ts +143 -0
- package/src/render/resolve.ts +109 -0
- package/src/render/review-prompt.ts +59 -0
- package/src/render/review-warnings.ts +92 -0
- package/src/render/review.ts +103 -0
- package/src/render/scene.ts +119 -0
- package/src/render/shade.ts +204 -0
- package/src/render/sheet.ts +88 -0
- package/src/render/texture.ts +97 -0
- package/src/render/thumbnail.ts +75 -0
- package/src/render/vis-buffer.ts +119 -0
- package/src/testing/assert.ts +115 -0
- package/src/testing/compiled.ts +31 -0
- package/src/testing/hash.ts +14 -0
- package/src/testing/index.ts +14 -0
- package/src/testing/snapshot.ts +37 -0
- package/src/types/gltf-validator.d.ts +13 -0
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
// Mineable asteroid — a ~10 m rubble-pile rock for a mining game, in three seeded variants.
|
|
2
|
+
// A signed-distance field meshed by `sdf`: a lumpy ellipsoid (smooth-union lobes), fractal
|
|
3
|
+
// value-noise displacement, impact craters (smooth subtract + raised rims), then vertex colour:
|
|
4
|
+
// carbonaceous dark rock (C-type albedo 0.03–0.09), dust on up-facing slopes, darker crater
|
|
5
|
+
// floors, and nickel-iron ore veins (M-type). Glowing crystal clusters mark the mining points.
|
|
6
|
+
// The bottom is clipped flat at z = 0 so it rests on (or in) the ground. +X front, Z up, metres.
|
|
7
|
+
//
|
|
8
|
+
// Engine contract: `rock` (the collider-friendly mass), `ore_crystals` (glow), interact sockets
|
|
9
|
+
// `mine_point_*` at each crystal cluster, `dust` emitter for mining debris.
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
type Asset,
|
|
13
|
+
type BuildContext,
|
|
14
|
+
bakeAo,
|
|
15
|
+
defineAsset,
|
|
16
|
+
type Field,
|
|
17
|
+
hex,
|
|
18
|
+
lathe,
|
|
19
|
+
type Mesh,
|
|
20
|
+
merge,
|
|
21
|
+
place,
|
|
22
|
+
sdf,
|
|
23
|
+
type Vec3,
|
|
24
|
+
valueNoise,
|
|
25
|
+
} from '@developerz.ai/ts23d';
|
|
26
|
+
|
|
27
|
+
const ROCK = hex('#3b3632');
|
|
28
|
+
const ROCK_LIGHT = hex('#4f4841');
|
|
29
|
+
const DUST = hex('#6a6157');
|
|
30
|
+
const CRATER = hex('#26221f');
|
|
31
|
+
const ORE = hex('#b78a45');
|
|
32
|
+
const CRYSTAL = hex('#3fe0d0');
|
|
33
|
+
const CRYSTAL_TINT = hex('#1f6f6a');
|
|
34
|
+
|
|
35
|
+
type V = [number, number, number];
|
|
36
|
+
const step = (a: number, b: number, x: number): number => {
|
|
37
|
+
const t = Math.max(0, Math.min(1, (x - a) / (b - a)));
|
|
38
|
+
return t * t * (3 - 2 * t);
|
|
39
|
+
};
|
|
40
|
+
const mix = (a: Vec3, b: Vec3, t: number): Vec3 => [
|
|
41
|
+
a[0] + (b[0] - a[0]) * t,
|
|
42
|
+
a[1] + (b[1] - a[1]) * t,
|
|
43
|
+
a[2] + (b[2] - a[2]) * t,
|
|
44
|
+
];
|
|
45
|
+
const len = (x: number, y: number, z: number): number => Math.sqrt(x * x + y * y + z * z);
|
|
46
|
+
const norm = (v: Vec3): V => {
|
|
47
|
+
const l = len(v[0], v[1], v[2]) || 1;
|
|
48
|
+
return [v[0] / l, v[1] / l, v[2] / l];
|
|
49
|
+
};
|
|
50
|
+
const smin = (a: number, b: number, k: number): number => {
|
|
51
|
+
const h = Math.max(0, Math.min(1, 0.5 + (0.5 * (b - a)) / k));
|
|
52
|
+
return b + (a - b) * h - k * h * (1 - h);
|
|
53
|
+
};
|
|
54
|
+
const smax = (a: number, b: number, k: number): number => -smin(-a, -b, k);
|
|
55
|
+
const ellipsoid = (p: Vec3, c: Vec3, r: Vec3): number => {
|
|
56
|
+
const x = (p[0] - c[0]) / r[0];
|
|
57
|
+
const y = (p[1] - c[1]) / r[1];
|
|
58
|
+
const z = (p[2] - c[2]) / r[2];
|
|
59
|
+
const k0 = len(x, y, z);
|
|
60
|
+
const k1 = len(x / r[0], y / r[1], z / r[2]);
|
|
61
|
+
return k1 === 0 ? -Math.min(...r) : (k0 * (k0 - 1)) / k1;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
interface Crater {
|
|
65
|
+
readonly centre: V; // sphere centre (cuts the bowl)
|
|
66
|
+
readonly r: number;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface Shape {
|
|
70
|
+
readonly field: Field;
|
|
71
|
+
readonly craters: readonly Crater[];
|
|
72
|
+
readonly gradient: (p: Vec3) => V;
|
|
73
|
+
/** Surface point along a ray from the core (bisection on the field). */
|
|
74
|
+
readonly surface: (dir: Vec3) => V;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Below every variant's z radius, so the field always crosses z = 0 and the rock sits clipped flat.
|
|
78
|
+
const CORE: V = [0, 0, 2.2];
|
|
79
|
+
|
|
80
|
+
/** The rock's field. Every draw comes from forks of `ctx.rng`, identical at every LOD. */
|
|
81
|
+
function shape(ctx: BuildContext, size: V): Shape {
|
|
82
|
+
const rng = ctx.rng.fork('shape');
|
|
83
|
+
const big = valueNoise(rng.fork('big'), { scale: 2.8, octaves: 4 });
|
|
84
|
+
const pits = valueNoise(rng.fork('pits'), { scale: 0.8, octaves: 2 });
|
|
85
|
+
const lobes = Array.from({ length: 3 }, () => ({
|
|
86
|
+
c: [rng.range(-2.6, 2.6), rng.range(-1.8, 1.8), CORE[2] + rng.range(-0.6, 1.0)] as V,
|
|
87
|
+
r: [rng.range(1.8, 2.8), rng.range(1.6, 2.4), rng.range(1.4, 2.2)] as V,
|
|
88
|
+
}));
|
|
89
|
+
// Fracture planes: half-spaces that chip flat, angular facets off the lumpy mass.
|
|
90
|
+
const chips = Array.from({ length: 12 }, () => {
|
|
91
|
+
const a = rng.range(0, Math.PI * 2);
|
|
92
|
+
const up = rng.range(-0.2, 0.9);
|
|
93
|
+
const m = norm([
|
|
94
|
+
Math.cos(a) * Math.sqrt(1 - up * up),
|
|
95
|
+
Math.sin(a) * Math.sqrt(1 - up * up),
|
|
96
|
+
up,
|
|
97
|
+
]);
|
|
98
|
+
const reach = Math.abs(m[0]) * size[0] + Math.abs(m[1]) * size[1] + Math.abs(m[2]) * size[2];
|
|
99
|
+
return { m, c: reach * rng.range(0.62, 0.8) };
|
|
100
|
+
});
|
|
101
|
+
const body = (p: Vec3): number => {
|
|
102
|
+
let d = ellipsoid(p, CORE, size);
|
|
103
|
+
for (const l of lobes) d = smin(d, ellipsoid(p, l.c, l.r), 1.0);
|
|
104
|
+
d += 0.65 * big(p) + 0.12 * pits(p);
|
|
105
|
+
const x = p[0] - CORE[0];
|
|
106
|
+
const y = p[1] - CORE[1];
|
|
107
|
+
const z = p[2] - CORE[2];
|
|
108
|
+
for (const c of chips)
|
|
109
|
+
d = smax(d, x * c.m[0] + y * c.m[1] + z * c.m[2] - c.c + 0.08 * pits(p), 0.12);
|
|
110
|
+
return d;
|
|
111
|
+
};
|
|
112
|
+
const gradOf =
|
|
113
|
+
(f: Field) =>
|
|
114
|
+
(p: Vec3): V => {
|
|
115
|
+
const e = 0.05;
|
|
116
|
+
return norm([
|
|
117
|
+
f([p[0] + e, p[1], p[2]]) - f([p[0] - e, p[1], p[2]]),
|
|
118
|
+
f([p[0], p[1] + e, p[2]]) - f([p[0], p[1] - e, p[2]]),
|
|
119
|
+
f([p[0], p[1], p[2] + e]) - f([p[0], p[1], p[2] - e]),
|
|
120
|
+
]);
|
|
121
|
+
};
|
|
122
|
+
const surfaceOf =
|
|
123
|
+
(f: Field) =>
|
|
124
|
+
(dir: Vec3): V => {
|
|
125
|
+
const d = norm(dir);
|
|
126
|
+
let lo = 0;
|
|
127
|
+
let hi = 9;
|
|
128
|
+
for (let i = 0; i < 40; i++) {
|
|
129
|
+
const t = (lo + hi) / 2;
|
|
130
|
+
if (f([CORE[0] + d[0] * t, CORE[1] + d[1] * t, CORE[2] + d[2] * t]) < 0) lo = t;
|
|
131
|
+
else hi = t;
|
|
132
|
+
}
|
|
133
|
+
return [CORE[0] + d[0] * lo, CORE[1] + d[1] * lo, CORE[2] + d[2] * lo];
|
|
134
|
+
};
|
|
135
|
+
const bodySurface = surfaceOf(body);
|
|
136
|
+
const bodyGrad = gradOf(body);
|
|
137
|
+
const craters: Crater[] = Array.from({ length: 9 }, (_, i) => {
|
|
138
|
+
const a = rng.range(0, Math.PI * 2);
|
|
139
|
+
const up = i < 3 ? rng.range(0.55, 0.95) : rng.range(-0.1, 0.7);
|
|
140
|
+
const s = bodySurface([
|
|
141
|
+
Math.cos(a) * Math.sqrt(1 - up * up),
|
|
142
|
+
Math.sin(a) * Math.sqrt(1 - up * up),
|
|
143
|
+
up,
|
|
144
|
+
]);
|
|
145
|
+
const n = bodyGrad(s);
|
|
146
|
+
const r = i < 2 ? rng.range(1.3, 1.9) : rng.range(0.45, 1.0);
|
|
147
|
+
return {
|
|
148
|
+
centre: [s[0] + n[0] * r * 0.6, s[1] + n[1] * r * 0.6, s[2] + n[2] * r * 0.6],
|
|
149
|
+
r,
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
const field: Field = (p) => {
|
|
153
|
+
let d = body(p);
|
|
154
|
+
for (const c of craters) {
|
|
155
|
+
// Raised rim: a radial bump that displaces the surface itself (a torus in the tangent
|
|
156
|
+
// plane floats off convex slopes), then the bowl: a smooth-subtracted sphere.
|
|
157
|
+
const ds = len(p[0] - c.centre[0], p[1] - c.centre[1], p[2] - c.centre[2]);
|
|
158
|
+
const u = (ds - c.r * 1.05) / (c.r * 0.28);
|
|
159
|
+
if (u > -3 && u < 3) d -= c.r * 0.16 * Math.exp(-u * u);
|
|
160
|
+
d = smax(d, -(ds - c.r), c.r * 0.3);
|
|
161
|
+
}
|
|
162
|
+
return d;
|
|
163
|
+
};
|
|
164
|
+
return { field, craters, gradient: gradOf(field), surface: surfaceOf(field) };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** One faceted crystal, base at the origin growing up +Z: hexagonal prism with a pointed tip. */
|
|
168
|
+
const crystal = (r: number, h: number, segments: number): Mesh =>
|
|
169
|
+
lathe({
|
|
170
|
+
profile: [
|
|
171
|
+
[r * 0.7, -0.35],
|
|
172
|
+
[r, 0],
|
|
173
|
+
[r * 0.95, h * 0.75],
|
|
174
|
+
[0, h],
|
|
175
|
+
],
|
|
176
|
+
segments,
|
|
177
|
+
color: CRYSTAL,
|
|
178
|
+
creaseDeg: 20,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
function asteroidVariant(
|
|
182
|
+
name: string,
|
|
183
|
+
seed: number,
|
|
184
|
+
size: V,
|
|
185
|
+
description: string,
|
|
186
|
+
/** Measured per seed (SDF triangle counts follow the surface area), headroom ≤ 20%. */
|
|
187
|
+
triangles: readonly [number, number, number],
|
|
188
|
+
): Asset {
|
|
189
|
+
return defineAsset({
|
|
190
|
+
name,
|
|
191
|
+
kind: 'prop',
|
|
192
|
+
description,
|
|
193
|
+
tags: ['sci-fi', 'asteroid', 'rock', 'mining', 'sdf'],
|
|
194
|
+
license: 'CC0-1.0',
|
|
195
|
+
seed,
|
|
196
|
+
sources: [
|
|
197
|
+
'https://www.esa.int/Science_Exploration/Space_Science/Rosetta/Debris_of_the_Solar_System_Asteroids',
|
|
198
|
+
'https://starlust.org/what-are-the-different-types-of-asteroids',
|
|
199
|
+
],
|
|
200
|
+
budget: { triangles },
|
|
201
|
+
glow: [{ parts: ['ore_crystals'], color: CRYSTAL, strength: 5 }],
|
|
202
|
+
build(ctx) {
|
|
203
|
+
const s = shape(ctx, size);
|
|
204
|
+
const veins = valueNoise(ctx.rng.fork('veins'), { scale: 1.9, octaves: 2 });
|
|
205
|
+
const tone = valueNoise(ctx.rng.fork('tone'), { scale: 1.2, octaves: 3 });
|
|
206
|
+
// Mining points: cluster sites on the upper half, away from the two big craters.
|
|
207
|
+
const pick = ctx.rng.fork('clusters');
|
|
208
|
+
const sites = Array.from({ length: 4 }, () => {
|
|
209
|
+
const a = pick.range(0, Math.PI * 2);
|
|
210
|
+
const up = pick.range(0.05, 0.75);
|
|
211
|
+
const p = s.surface([
|
|
212
|
+
Math.cos(a) * Math.sqrt(1 - up * up),
|
|
213
|
+
Math.sin(a) * Math.sqrt(1 - up * up),
|
|
214
|
+
up,
|
|
215
|
+
]);
|
|
216
|
+
return { p, n: s.gradient(p) };
|
|
217
|
+
});
|
|
218
|
+
const color = (p: Vec3, n: Vec3): Vec3 => {
|
|
219
|
+
let near = 99;
|
|
220
|
+
for (const site of sites)
|
|
221
|
+
near = Math.min(near, len(p[0] - site.p[0], p[1] - site.p[1], p[2] - site.p[2]));
|
|
222
|
+
let c = mix(ROCK, ROCK_LIGHT, step(-0.25, 0.35, tone(p)));
|
|
223
|
+
c = mix(c, DUST, step(0.55, 0.85, n[2]) * 0.8);
|
|
224
|
+
const vein = 1 - step(0.018, 0.05, Math.abs(veins(p)));
|
|
225
|
+
c = mix(c, near < 2.4 ? CRYSTAL_TINT : ORE, vein);
|
|
226
|
+
c = mix(c, CRYSTAL_TINT, (1 - step(0.6, 1.6, near)) * 0.7);
|
|
227
|
+
for (const cr of s.craters) {
|
|
228
|
+
const d = len(p[0] - cr.centre[0], p[1] - cr.centre[1], p[2] - cr.centre[2]);
|
|
229
|
+
c = mix(c, CRATER, (1 - step(cr.r * 0.8, cr.r * 1.2, d)) * 0.85);
|
|
230
|
+
}
|
|
231
|
+
return c;
|
|
232
|
+
};
|
|
233
|
+
const ext = Math.max(...size) + 3.2;
|
|
234
|
+
const rock = sdf({
|
|
235
|
+
field: s.field,
|
|
236
|
+
bounds: [
|
|
237
|
+
[-ext, -ext, 0],
|
|
238
|
+
[ext, ext, CORE[2] + size[2] + 2.2],
|
|
239
|
+
],
|
|
240
|
+
resolution: ctx.pick([0.17, 0.38, 0.95]),
|
|
241
|
+
color,
|
|
242
|
+
lipschitz: 2,
|
|
243
|
+
strip: 'plain',
|
|
244
|
+
});
|
|
245
|
+
ctx.part(
|
|
246
|
+
'rock',
|
|
247
|
+
ctx.lod < 2
|
|
248
|
+
? bakeAo(rock, {
|
|
249
|
+
samples: ctx.pick([16, 8, 0]),
|
|
250
|
+
radius: 1.5,
|
|
251
|
+
strength: 0.55,
|
|
252
|
+
ground: true,
|
|
253
|
+
})
|
|
254
|
+
: rock,
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
// Crystal clusters: 7 / 4 / 1 shards per site, sunk 0.3 m into the rock along its normal.
|
|
258
|
+
const shards = ctx.pick([11, 5, 1]);
|
|
259
|
+
const seg = ctx.pick([6, 6, 4]);
|
|
260
|
+
const grow = ctx.rng.fork('shards');
|
|
261
|
+
const out: Mesh[] = [];
|
|
262
|
+
sites.forEach((site, i) => {
|
|
263
|
+
for (let k = 0; k < shards; k++) {
|
|
264
|
+
const jitter = k === 0 ? 0 : 0.6;
|
|
265
|
+
const n = norm([
|
|
266
|
+
site.n[0] + grow.range(-jitter, jitter),
|
|
267
|
+
site.n[1] + grow.range(-jitter, jitter),
|
|
268
|
+
site.n[2] + grow.range(-jitter, jitter) * 0.5,
|
|
269
|
+
]);
|
|
270
|
+
const off: V =
|
|
271
|
+
k === 0
|
|
272
|
+
? [0, 0, 0]
|
|
273
|
+
: [grow.range(-0.5, 0.5), grow.range(-0.5, 0.5), grow.range(-0.3, 0.3)];
|
|
274
|
+
const base = s.surface([
|
|
275
|
+
site.p[0] + off[0] - CORE[0],
|
|
276
|
+
site.p[1] + off[1] - CORE[1],
|
|
277
|
+
site.p[2] + off[2] - CORE[2],
|
|
278
|
+
]);
|
|
279
|
+
const r = k === 0 ? 0.3 : grow.range(0.1, 0.22);
|
|
280
|
+
const h = k === 0 ? 1.9 : grow.range(0.6, 1.4);
|
|
281
|
+
out.push(
|
|
282
|
+
place(crystal(r, h, seg), {
|
|
283
|
+
at: base,
|
|
284
|
+
yaw: Math.atan2(n[1], n[0]),
|
|
285
|
+
pitch: Math.acos(Math.max(-1, Math.min(1, n[2]))),
|
|
286
|
+
}),
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
ctx.socket(`mine_point_${i}`, {
|
|
290
|
+
kind: 'interact',
|
|
291
|
+
at: [
|
|
292
|
+
site.p[0] + site.n[0] * 0.8,
|
|
293
|
+
site.p[1] + site.n[1] * 0.8,
|
|
294
|
+
site.p[2] + site.n[2] * 0.8,
|
|
295
|
+
],
|
|
296
|
+
dir: [-site.n[0], -site.n[1], -site.n[2]],
|
|
297
|
+
data: { resource: 'crystal', yield: 120 },
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
ctx.part('ore_crystals', merge(out));
|
|
301
|
+
const top = s.surface([0, 0, 1]);
|
|
302
|
+
ctx.emitter('dust', {
|
|
303
|
+
kind: 'dust',
|
|
304
|
+
at: [top[0], top[1], top[2] + 0.2],
|
|
305
|
+
rate: 30,
|
|
306
|
+
life: 2.5,
|
|
307
|
+
size: [0.2, 1.2],
|
|
308
|
+
speed: 1.5,
|
|
309
|
+
spreadDeg: 70,
|
|
310
|
+
when: 'event',
|
|
311
|
+
});
|
|
312
|
+
},
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export const asteroid = asteroidVariant(
|
|
317
|
+
'asteroid',
|
|
318
|
+
1,
|
|
319
|
+
[5.0, 3.8, 3.0],
|
|
320
|
+
'Mineable ~10 m asteroid: SDF rock with craters, ore veins and glowing crystal clusters',
|
|
321
|
+
[24000, 5200, 760],
|
|
322
|
+
);
|
|
323
|
+
export const asteroid_b = asteroidVariant(
|
|
324
|
+
'asteroid_b',
|
|
325
|
+
2,
|
|
326
|
+
[4.2, 4.0, 3.3],
|
|
327
|
+
'Rounder asteroid variant (seed 2) with craters, ore veins and crystal clusters',
|
|
328
|
+
[21500, 4800, 670],
|
|
329
|
+
);
|
|
330
|
+
export const asteroid_c = asteroidVariant(
|
|
331
|
+
'asteroid_c',
|
|
332
|
+
3,
|
|
333
|
+
[5.6, 3.2, 2.6],
|
|
334
|
+
'Elongated asteroid shard variant (seed 3) with craters, ore veins and crystal clusters',
|
|
335
|
+
[24500, 5300, 750],
|
|
336
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Boulders — a set of four weathered granite/limestone boulders
|
|
2
|
+
|
|
3
|
+
## Identity
|
|
4
|
+
Generic alpine/glacial erratics for scattering on terrain tiles (see `mountain_range`). What makes
|
|
5
|
+
them read as rock rather than blobs: **a flattened, blocky core** (two or three intersecting or
|
|
6
|
+
smooth-unioned masses, never a sphere), **fractured facets** (a flat cut plane or two), **pitted,
|
|
7
|
+
weathered surface** (fractal value-noise displacement, larger features than the strip texture), a
|
|
8
|
+
**flat bearing face** where it sits on the ground, and **lichen/moss on the upward faces**.
|
|
9
|
+
|
|
10
|
+
## Specs
|
|
11
|
+
General values cited from prior knowledge, **unsourced / approximate**.
|
|
12
|
+
|
|
13
|
+
| Quantity | Value | Used as | Source |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| boulder (Udden–Wentworth: > 256 mm) | 0.26 m and up | smallest ~0.6 m | unsourced, approximate (standard grain-size class) |
|
|
16
|
+
| typical field / glacial erratic boulders | 0.5–3 m | 0.6, 1.0, 1.6, 2.4 m long | unsourced, approximate |
|
|
17
|
+
| height / length of resting boulders | ~0.4–0.7 (they settle on a broad face) | 0.45–0.65 | unsourced, approximate |
|
|
18
|
+
| moss / lichen | on the tops and the shaded side, not the bearing face | normal-based tint | observation |
|
|
19
|
+
|
|
20
|
+
## Photos (by view)
|
|
21
|
+
To be added (no web access in this session).
|
|
22
|
+
|
|
23
|
+
## Parts the engine needs
|
|
24
|
+
`boulder_0` … `boulder_3`: one static mesh each, base at z = 0 (the flat bearing face), laid out
|
|
25
|
+
along +Y with 0.5 m gaps so the contact sheet shows the set. One shared material.
|
|
26
|
+
|
|
27
|
+
## Open questions
|
|
28
|
+
Rock type is left to the palette (grey granite here); limestone or sandstone is a colour swap.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// Boulders: four weathered rocks meshed from signed-distance fields (surface nets, smooth gradient
|
|
2
|
+
// normals). Each is a blocky core (smooth-unioned ellipsoids and a rounded box), cut by one or two
|
|
3
|
+
// fracture planes, pitted by seeded fractal noise, flattened on its bearing face at z = 0, and
|
|
4
|
+
// tinted with lichen on upward faces. Resolution (cell edge, m) is the LOD knob. Dossier: README.md.
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
type BuildContext,
|
|
8
|
+
defineAsset,
|
|
9
|
+
type Field,
|
|
10
|
+
hex,
|
|
11
|
+
sd,
|
|
12
|
+
sdf,
|
|
13
|
+
type Vec3,
|
|
14
|
+
valueNoise,
|
|
15
|
+
} from '@developerz.ai/ts23d';
|
|
16
|
+
|
|
17
|
+
const STONE = hex('#8d8a84');
|
|
18
|
+
const DARK = hex('#5f5c58');
|
|
19
|
+
const LICHEN = hex('#7d8a4e');
|
|
20
|
+
|
|
21
|
+
/** Length (X), width (Y), height (Z) in metres; `cuts` fracture planes. */
|
|
22
|
+
const ROCKS: readonly { size: Vec3; cuts: number }[] = [
|
|
23
|
+
{ size: [0.6, 0.45, 0.35], cuts: 2 },
|
|
24
|
+
{ size: [1.0, 0.75, 0.6], cuts: 3 },
|
|
25
|
+
{ size: [1.6, 1.1, 0.85], cuts: 2 },
|
|
26
|
+
{ size: [2.4, 1.7, 1.1], cuts: 3 },
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/** A plane through `at` with outward normal `n` (unit): negative behind it. */
|
|
30
|
+
const plane =
|
|
31
|
+
(at: Vec3, n: Vec3): Field =>
|
|
32
|
+
(p) =>
|
|
33
|
+
(p[0] - at[0]) * n[0] + (p[1] - at[1]) * n[1] + (p[2] - at[2]) * n[2];
|
|
34
|
+
|
|
35
|
+
function rock(ctx: BuildContext, i: number, size: Vec3, cuts: number, y: number): void {
|
|
36
|
+
const rng = ctx.rng.fork(`rock-${i}`);
|
|
37
|
+
const [l, w, h] = size;
|
|
38
|
+
const c: Vec3 = [0, y, h * 0.45];
|
|
39
|
+
// Core: an ellipsoid mass, a rounded block offset inside it, a smaller lobe: blocky, not round.
|
|
40
|
+
let f: Field = sd.smoothUnion(
|
|
41
|
+
0.12 * h,
|
|
42
|
+
sd.ellipsoid(c, [l * 0.5, w * 0.5, h * 0.6]),
|
|
43
|
+
sd.box(
|
|
44
|
+
[c[0] + rng.range(-0.1, 0.1) * l, y, c[2] - 0.05 * h],
|
|
45
|
+
[l * 0.8, w * 0.75, h * 0.9],
|
|
46
|
+
0.15 * h,
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
f = sd.smoothUnion(
|
|
50
|
+
0.1 * h,
|
|
51
|
+
f,
|
|
52
|
+
sd.ellipsoid(
|
|
53
|
+
[l * rng.range(0.15, 0.3), y + w * rng.range(-0.2, 0.2), h * 0.6],
|
|
54
|
+
[l * 0.3, w * 0.35, h * 0.35],
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
// Fracture planes: sliced faces read as split rock.
|
|
58
|
+
for (let k = 0; k < cuts; k++) {
|
|
59
|
+
const nx = rng.range(-1, 1);
|
|
60
|
+
const ny = rng.range(-1, 1);
|
|
61
|
+
const len = Math.sqrt(nx * nx + ny * ny + 0.09) || 1;
|
|
62
|
+
const n: Vec3 = [nx / len, ny / len, 0.3 / len];
|
|
63
|
+
const d = rng.range(0.26, 0.36);
|
|
64
|
+
f = sd.intersect(f, plane([n[0] * l * d, y + n[1] * w * d, c[2]], n));
|
|
65
|
+
}
|
|
66
|
+
const pits = valueNoise(rng.fork('pits'), { scale: Math.max(0.12, l * 0.18), octaves: 4 });
|
|
67
|
+
const rough = sd.displace(f, pits, 0.08 * h);
|
|
68
|
+
// Bearing face: cut flat at the ground.
|
|
69
|
+
const field: Field = (p) => Math.max(rough(p), -p[2]);
|
|
70
|
+
const pad = 0.15 * l;
|
|
71
|
+
ctx.part(
|
|
72
|
+
`boulder_${i}`,
|
|
73
|
+
sdf({
|
|
74
|
+
field,
|
|
75
|
+
bounds: [
|
|
76
|
+
[-l / 2 - pad, y - w / 2 - pad, 0],
|
|
77
|
+
[l / 2 + pad, y + w / 2 + pad, h * 1.15],
|
|
78
|
+
],
|
|
79
|
+
resolution: ctx.pick([0.035, 0.08, 0.2]) * Math.max(0.6, l / 1.6),
|
|
80
|
+
// 'concrete' is the sheet's fractal-noise strip; 'stone' is coursed masonry (walls, not rock).
|
|
81
|
+
strip: 'concrete',
|
|
82
|
+
lipschitz: 1.6,
|
|
83
|
+
color: (p, nrm) => {
|
|
84
|
+
const up = Math.max(0, nrm[2]);
|
|
85
|
+
const t = Math.min(1, p[2] / h);
|
|
86
|
+
const base: Vec3 = [
|
|
87
|
+
DARK[0] + (STONE[0] - DARK[0]) * t,
|
|
88
|
+
DARK[1] + (STONE[1] - DARK[1]) * t,
|
|
89
|
+
DARK[2] + (STONE[2] - DARK[2]) * t,
|
|
90
|
+
];
|
|
91
|
+
const moss = up > 0.75 ? Math.min(1, (up - 0.75) * 4) * 0.8 : 0;
|
|
92
|
+
return [
|
|
93
|
+
base[0] + (LICHEN[0] - base[0]) * moss,
|
|
94
|
+
base[1] + (LICHEN[1] - base[1]) * moss,
|
|
95
|
+
base[2] + (LICHEN[2] - base[2]) * moss,
|
|
96
|
+
];
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const boulders = defineAsset({
|
|
103
|
+
name: 'boulders',
|
|
104
|
+
kind: 'prop',
|
|
105
|
+
description:
|
|
106
|
+
'Four weathered boulders (0.6–2.4 m): SDF masses, fracture cuts, noise pitting, lichen.',
|
|
107
|
+
tags: ['rock', 'boulder', 'nature', 'sdf', 'scatter'],
|
|
108
|
+
seed: 7,
|
|
109
|
+
budget: { triangles: [40000, 9000, 2000] },
|
|
110
|
+
build(ctx) {
|
|
111
|
+
let y = 0;
|
|
112
|
+
ROCKS.forEach(({ size, cuts }, i) => {
|
|
113
|
+
rock(ctx, i, size, cuts, y + size[1] / 2);
|
|
114
|
+
y += size[1] + 0.5;
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# USRA 50-ton single-sheathed boxcar — 1918 (`boxcar`, `boxcar_nw`)
|
|
2
|
+
|
|
3
|
+
## Identity
|
|
4
|
+
The US Railroad Administration's standard 40 ft single-sheathed boxcar (spec 1001-B, 25,000 built
|
|
5
|
+
from Oct 1918), chosen because it is THE generic American freight car of 1918–1950 and because its
|
|
6
|
+
outside steel framing reads at any distance. `boxcar` is Clinchfield (C.C.& O.) 8024 as built by
|
|
7
|
+
Bettendorf (NARA photo below); `boxcar_nw` is a Norfolk & Western car (same body, other livery).
|
|
8
|
+
|
|
9
|
+
Signature features: vertical wood sheathing with the steel posts and diagonal braces OUTSIDE it
|
|
10
|
+
(braces lean toward the door), a 6 ft sliding door hung on a bottom track, a low steel roof with a
|
|
11
|
+
wooden running board, grab-iron ladders at diagonally opposite corners, a vertical brake staff with
|
|
12
|
+
a horizontal wheel at roof level on the B end, knuckle couplers, cast-steel side-frame trucks.
|
|
13
|
+
|
|
14
|
+
## Specs
|
|
15
|
+
| Dimension | Value | Source |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| inside length | 40 ft 6 in (12.344 m) | B&M RHS ORER table, https://bostonmaine.squarespace.com/box_71000_series (via search summary; page 404s to fetchers) |
|
|
18
|
+
| inside width / height | 8 ft 6 in / 8 ft 7 in (2.591 / 2.616 m) | same |
|
|
19
|
+
| outside (body) length | 41 ft 3 in (12.573 m) | same |
|
|
20
|
+
| extreme width | 9 ft 6 in (2.896 m) | same |
|
|
21
|
+
| extreme height (top of running board over rail) | 13 ft 3 in (4.039 m) | same |
|
|
22
|
+
| length over pulling faces | ≈ 43 ft 9 in (13.34 m): body + 2 × 15 in coupler reach | coupler reach from PRR X29 plan (railroads/tools/procgen recipe wagon_goods_boxcar) |
|
|
23
|
+
| wheel diameter | 33 in (0.838 m), the US freight standard | https://kadee.com/553-ho-scale-andrews-1898-self-centering-trucks-with-33-ribbed-back-wheels-metal-fully-sprung |
|
|
24
|
+
| truck wheelbase | 5 ft 6 in (1.676 m) | Andrews truck, https://www.nasg.org/Gallery/reports/scale/cars/modeltype/StrucksAndrews.php |
|
|
25
|
+
| door opening | ≈ 6 ft (1.83 m) | scaled from the NARA photo against the 41 ft 3 in body |
|
|
26
|
+
| coupler centre over rail | 34½ in (0.876 m), MCB standard | MCB / AAR standard height |
|
|
27
|
+
| truck centres | ≈ 30 ft 9 in (9.37 m) | ESTIMATE, scaled from the NARA photo |
|
|
28
|
+
| gauge | 4 ft 8½ in (1.435 m) | standard gauge |
|
|
29
|
+
|
|
30
|
+
## Photos (by view)
|
|
31
|
+
| View | URL | Notes |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| side, 3/4 front | https://commons.wikimedia.org/wiki/File:Military_Administration_-_Transportation_-_Rail_-_Construction_-_50_TON_SINGLE_SHEATHED_BOX_CAR_being_constructed_for_U.S._Railroad_Administration_by_the_Bettendorff_Co.,_Bettendorff,_Iowa_-_NARA_-_45502055.jpg | Clinchfield 8024, Bettendorf 1918: 4 braced panels each side of the door, lettering layout |
|
|
34
|
+
| model reference, all views | https://rapidotrains.com/ho-scale/freight-car/usra-ss-boxcar.html | N&W 42574 livery, ends, roof, brake gear |
|
|
35
|
+
| background | https://en.wikipedia.org/wiki/USRA_standard | spec 1001-B, 25,000 built |
|
|
36
|
+
|
|
37
|
+
## Parts the engine needs
|
|
38
|
+
`truck_a`, `truck_b` (pivots; engines yaw them on curves) · `axle_a_0` … `axle_b_1` (spin about Y,
|
|
39
|
+
children `*_wheel_l/_r`) · `door_l`, `door_r` (slide one way toward −X, `oneWay`) · `coupler_a`, `coupler_b` (+X / −X).
|
|
40
|
+
|
|
41
|
+
## Open questions
|
|
42
|
+
- The ORER row (B&M 71000) carries 8 ft 7 in inside height; another page claims 9 ft. The ORER value
|
|
43
|
+
is used; 13 ft 3 in extreme height is consistent with it.
|
|
44
|
+
- Truck centres are not published in the sources found: 9.37 m is scaled from the photo.
|
|
45
|
+
- Lettering is painted on the boards and post faces; the diagonal braces cross over it (a stroke
|
|
46
|
+
painted on a brace face jumps sideways in parallax and garbles the word at 3/4 views).
|
|
47
|
+
|
|
48
|
+
## Materials
|
|
49
|
+
Painted plank sheathing and door (`wood_painted`: car colour over grey wood, worn at board edges and
|
|
50
|
+
ends), silver-grey running board and saddles (`wood_weathered`), painted steel frame, sills and roof
|
|
51
|
+
(`steel_painted`), sand-cast trucks, wheels and bolsters (`iron_cast`), and rusty hardware: grab
|
|
52
|
+
irons, couplers, brake gear (`iron_rust`). The numbers and sources are in
|
|
53
|
+
`docs/architecture/materials.md`.
|