@felbrasil/dreamy 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +69 -2
- package/dist/api.d.ts +1 -0
- package/dist/api.js +2 -0
- package/dist/api.js.map +7 -0
- package/dist/chunks/chunk-72DMUKP3.js +1470 -0
- package/dist/chunks/chunk-72DMUKP3.js.map +7 -0
- package/dist/chunks/chunk-VZMBE5MV.js +5936 -0
- package/dist/chunks/chunk-VZMBE5MV.js.map +7 -0
- package/dist/chunks/chunk-ZU72KKME.js +8600 -0
- package/dist/chunks/chunk-ZU72KKME.js.map +7 -0
- package/dist/core.d.ts +1 -0
- package/dist/core.js +34 -0
- package/dist/core.js.map +7 -0
- package/dist/dreamy_evaluator.wasm +0 -0
- package/dist/evaluator.d.ts +1 -0
- package/dist/evaluator.js +52 -0
- package/dist/evaluator.js.map +7 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7280 -0
- package/dist/index.js.map +7 -0
- package/dist/styles.css +1 -0
- package/dist/types/api/src/commands/command.d.ts +7 -0
- package/dist/types/api/src/commands/decal-commands.d.ts +35 -0
- package/dist/types/api/src/commands/palette-commands.d.ts +14 -0
- package/dist/types/api/src/commands/rig-commands.d.ts +229 -0
- package/dist/types/api/src/commands/scene-commands.d.ts +64 -0
- package/dist/types/api/src/commands/sculpt-commands.d.ts +111 -0
- package/dist/types/api/src/commands/stamp-spec.d.ts +3 -0
- package/dist/types/api/src/commands/target.d.ts +8 -0
- package/dist/types/api/src/creation-api.d.ts +52 -0
- package/dist/types/api/src/events/creation-event.d.ts +7 -0
- package/dist/types/api/src/events/decal-events.d.ts +20 -0
- package/dist/types/api/src/events/event-of.d.ts +6 -0
- package/dist/types/api/src/events/palette-events.d.ts +8 -0
- package/dist/types/api/src/events/rig-events.d.ts +161 -0
- package/dist/types/api/src/events/scene-events.d.ts +34 -0
- package/dist/types/api/src/events/sculpt-events.d.ts +53 -0
- package/dist/types/api/src/id.d.ts +1 -0
- package/dist/types/api/src/index.d.ts +31 -0
- package/dist/types/api/src/model/creation.d.ts +22 -0
- package/dist/types/api/src/model/decal.d.ts +48 -0
- package/dist/types/api/src/model/look.d.ts +56 -0
- package/dist/types/api/src/model/math.d.ts +18 -0
- package/dist/types/api/src/model/palette.d.ts +11 -0
- package/dist/types/api/src/model/rig.d.ts +125 -0
- package/dist/types/api/src/model/scene-object.d.ts +22 -0
- package/dist/types/api/src/model/sculpt.d.ts +13 -0
- package/dist/types/api/src/model/stamp.d.ts +53 -0
- package/dist/types/api/src/model/wing.d.ts +35 -0
- package/dist/types/api/src/ports/basic-ports.d.ts +7 -0
- package/dist/types/api/src/ports/evaluator.d.ts +62 -0
- package/dist/types/api/src/ports/persistence.d.ts +89 -0
- package/dist/types/api/src/ports/viewport.d.ts +125 -0
- package/dist/types/core/src/apply/body-part-added.d.ts +2 -0
- package/dist/types/core/src/apply/body-part-removed.d.ts +2 -0
- package/dist/types/core/src/apply/bone-removed.d.ts +3 -0
- package/dist/types/core/src/apply/bone-renamed.d.ts +2 -0
- package/dist/types/core/src/apply/bone-reparented.d.ts +2 -0
- package/dist/types/core/src/apply/bone-sizes-set.d.ts +3 -0
- package/dist/types/core/src/apply/bone-tags-set.d.ts +2 -0
- package/dist/types/core/src/apply/bone-transforms-set.d.ts +6 -0
- package/dist/types/core/src/apply/bones-added.d.ts +2 -0
- package/dist/types/core/src/apply/creature-generated.d.ts +3 -0
- package/dist/types/core/src/apply/decal-removed.d.ts +2 -0
- package/dist/types/core/src/apply/decals-added.d.ts +2 -0
- package/dist/types/core/src/apply/design-deleted.d.ts +2 -0
- package/dist/types/core/src/apply/design-saved.d.ts +2 -0
- package/dist/types/core/src/apply/flat-wings-set.d.ts +2 -0
- package/dist/types/core/src/apply/object-renamed.d.ts +2 -0
- package/dist/types/core/src/apply/object-reparented.d.ts +2 -0
- package/dist/types/core/src/apply/object-transforms-set.d.ts +2 -0
- package/dist/types/core/src/apply/objects-deleted.d.ts +2 -0
- package/dist/types/core/src/apply/objects-duplicated.d.ts +3 -0
- package/dist/types/core/src/apply/palette-color-set.d.ts +2 -0
- package/dist/types/core/src/apply/palette-reset.d.ts +2 -0
- package/dist/types/core/src/apply/part-grafted.d.ts +3 -0
- package/dist/types/core/src/apply/part-slot-swapped.d.ts +3 -0
- package/dist/types/core/src/apply/pivot-set.d.ts +2 -0
- package/dist/types/core/src/apply/pose-preset-applied.d.ts +3 -0
- package/dist/types/core/src/apply/pose-reset.d.ts +3 -0
- package/dist/types/core/src/apply/premade-applied.d.ts +3 -0
- package/dist/types/core/src/apply/region-blend-set.d.ts +3 -0
- package/dist/types/core/src/apply/rig-created.d.ts +2 -0
- package/dist/types/core/src/apply/rig-mirror-set.d.ts +2 -0
- package/dist/types/core/src/apply/rig-mode-set.d.ts +2 -0
- package/dist/types/core/src/apply/sculpt-created.d.ts +2 -0
- package/dist/types/core/src/apply/sculpt-look-set.d.ts +3 -0
- package/dist/types/core/src/apply/smear-group-set.d.ts +2 -0
- package/dist/types/core/src/apply/stamp-placements-set.d.ts +2 -0
- package/dist/types/core/src/apply/stamp-props-set.d.ts +2 -0
- package/dist/types/core/src/apply/stamps-added.d.ts +2 -0
- package/dist/types/core/src/apply/stamps-removed.d.ts +2 -0
- package/dist/types/core/src/apply/symmetry-set-for-all.d.ts +2 -0
- package/dist/types/core/src/atoms/check/check.d.ts +7 -0
- package/dist/types/core/src/atoms/decal/decal-limits.d.ts +6 -0
- package/dist/types/core/src/atoms/decal/decal-problem.d.ts +4 -0
- package/dist/types/core/src/atoms/decal/design-problem.d.ts +4 -0
- package/dist/types/core/src/atoms/look/catalogs.d.ts +9 -0
- package/dist/types/core/src/atoms/look/default-look.d.ts +4 -0
- package/dist/types/core/src/atoms/look/look-problem.d.ts +7 -0
- package/dist/types/core/src/atoms/look/merge-look.d.ts +3 -0
- package/dist/types/core/src/atoms/math/mat4.d.ts +14 -0
- package/dist/types/core/src/atoms/math/quat.d.ts +18 -0
- package/dist/types/core/src/atoms/math/transform.d.ts +7 -0
- package/dist/types/core/src/atoms/math/vec3.d.ts +18 -0
- package/dist/types/core/src/atoms/palette/default-palette.d.ts +4 -0
- package/dist/types/core/src/atoms/palette/is-color-ref.d.ts +2 -0
- package/dist/types/core/src/atoms/palette/poc-color-ref.d.ts +6 -0
- package/dist/types/core/src/atoms/rig/bone-matrices.d.ts +8 -0
- package/dist/types/core/src/atoms/rig/bone-region.d.ts +8 -0
- package/dist/types/core/src/atoms/rig/bone-role.d.ts +11 -0
- package/dist/types/core/src/atoms/rig/bone-size.d.ts +7 -0
- package/dist/types/core/src/atoms/rig/compose-local.d.ts +6 -0
- package/dist/types/core/src/atoms/rig/find-rig.d.ts +11 -0
- package/dist/types/core/src/atoms/rig/mirror-partner.d.ts +3 -0
- package/dist/types/core/src/atoms/rig/mirror-sculpt.d.ts +9 -0
- package/dist/types/core/src/atoms/rig/mirror-transform.d.ts +9 -0
- package/dist/types/core/src/atoms/rig/partner-target.d.ts +3 -0
- package/dist/types/core/src/atoms/rig/pose-presets.d.ts +11 -0
- package/dist/types/core/src/atoms/rig/pose-rule.d.ts +48 -0
- package/dist/types/core/src/atoms/rig/pose-template-rules.d.ts +8 -0
- package/dist/types/core/src/atoms/rig/rebase-pose.d.ts +6 -0
- package/dist/types/core/src/atoms/rig/resize-bones.d.ts +12 -0
- package/dist/types/core/src/atoms/rig/rig-extent.d.ts +3 -0
- package/dist/types/core/src/atoms/rig/side-from-name.d.ts +7 -0
- package/dist/types/core/src/atoms/rig/size-frame.d.ts +18 -0
- package/dist/types/core/src/atoms/rig/with-slot-parts.d.ts +9 -0
- package/dist/types/core/src/atoms/scene/copy-with-new-ids.d.ts +7 -0
- package/dist/types/core/src/atoms/scene/object-tree.d.ts +8 -0
- package/dist/types/core/src/atoms/scene/place-in-order.d.ts +7 -0
- package/dist/types/core/src/atoms/scene/unique-name.d.ts +4 -0
- package/dist/types/core/src/atoms/scene/world-matrix.d.ts +4 -0
- package/dist/types/core/src/atoms/sculpt/all-sculpts.d.ts +3 -0
- package/dist/types/core/src/atoms/sculpt/is-wing-target.d.ts +3 -0
- package/dist/types/core/src/atoms/sculpt/target-sculpt.d.ts +10 -0
- package/dist/types/core/src/atoms/sculpt/update-target.d.ts +8 -0
- package/dist/types/core/src/atoms/stamp/apply-stamp-props.d.ts +11 -0
- package/dist/types/core/src/atoms/stamp/clamp-symmetry.d.ts +11 -0
- package/dist/types/core/src/atoms/stamp/clean-props.d.ts +3 -0
- package/dist/types/core/src/atoms/stamp/emptied-groups.d.ts +3 -0
- package/dist/types/core/src/atoms/stamp/move-locked-groups.d.ts +12 -0
- package/dist/types/core/src/atoms/stamp/normalize-base.d.ts +6 -0
- package/dist/types/core/src/atoms/stamp/resolve-stamp-props.d.ts +14 -0
- package/dist/types/core/src/atoms/stamp/smear.d.ts +15 -0
- package/dist/types/core/src/atoms/stamp/stamp-problem.d.ts +7 -0
- package/dist/types/core/src/atoms/wing/wing-problem.d.ts +6 -0
- package/dist/types/core/src/create-creation-api.d.ts +12 -0
- package/dist/types/core/src/decide.d.ts +4 -0
- package/dist/types/core/src/empty-creation.d.ts +2 -0
- package/dist/types/core/src/fold.d.ts +6 -0
- package/dist/types/core/src/index.d.ts +9 -0
- package/dist/types/core/src/molecules/add-body-part.d.ts +8 -0
- package/dist/types/core/src/molecules/add-bone.d.ts +8 -0
- package/dist/types/core/src/molecules/add-decals.d.ts +4 -0
- package/dist/types/core/src/molecules/add-stamps.d.ts +8 -0
- package/dist/types/core/src/molecules/apply-pose-preset.d.ts +4 -0
- package/dist/types/core/src/molecules/apply-premade.d.ts +9 -0
- package/dist/types/core/src/molecules/auto-tag-sides.d.ts +4 -0
- package/dist/types/core/src/molecules/create-rig.d.ts +4 -0
- package/dist/types/core/src/molecules/create-sculpt.d.ts +4 -0
- package/dist/types/core/src/molecules/delete-design.d.ts +4 -0
- package/dist/types/core/src/molecules/delete-objects.d.ts +4 -0
- package/dist/types/core/src/molecules/duplicate-objects.d.ts +6 -0
- package/dist/types/core/src/molecules/generate-creature.d.ts +7 -0
- package/dist/types/core/src/molecules/graft-part.d.ts +4 -0
- package/dist/types/core/src/molecules/mirror-objects.d.ts +7 -0
- package/dist/types/core/src/molecules/molecule.d.ts +17 -0
- package/dist/types/core/src/molecules/remove-body-part.d.ts +3 -0
- package/dist/types/core/src/molecules/remove-bone.d.ts +4 -0
- package/dist/types/core/src/molecules/remove-decal.d.ts +3 -0
- package/dist/types/core/src/molecules/remove-smear-group.d.ts +4 -0
- package/dist/types/core/src/molecules/remove-stamps.d.ts +4 -0
- package/dist/types/core/src/molecules/rename-bone.d.ts +3 -0
- package/dist/types/core/src/molecules/rename-object.d.ts +3 -0
- package/dist/types/core/src/molecules/reparent-bone.d.ts +4 -0
- package/dist/types/core/src/molecules/reparent-object.d.ts +4 -0
- package/dist/types/core/src/molecules/reset-palette.d.ts +3 -0
- package/dist/types/core/src/molecules/reset-pose.d.ts +3 -0
- package/dist/types/core/src/molecules/save-design.d.ts +4 -0
- package/dist/types/core/src/molecules/set-bone-sizes.d.ts +8 -0
- package/dist/types/core/src/molecules/set-bone-tags.d.ts +4 -0
- package/dist/types/core/src/molecules/set-bone-transforms.d.ts +7 -0
- package/dist/types/core/src/molecules/set-flat-wings.d.ts +4 -0
- package/dist/types/core/src/molecules/set-object-transforms.d.ts +3 -0
- package/dist/types/core/src/molecules/set-palette-color.d.ts +3 -0
- package/dist/types/core/src/molecules/set-pivot.d.ts +3 -0
- package/dist/types/core/src/molecules/set-region-blend.d.ts +4 -0
- package/dist/types/core/src/molecules/set-rig-mirror.d.ts +3 -0
- package/dist/types/core/src/molecules/set-rig-mode.d.ts +3 -0
- package/dist/types/core/src/molecules/set-sculpt-look.d.ts +7 -0
- package/dist/types/core/src/molecules/set-smear-group.d.ts +4 -0
- package/dist/types/core/src/molecules/set-stamp-placements.d.ts +4 -0
- package/dist/types/core/src/molecules/set-stamp-props.d.ts +3 -0
- package/dist/types/core/src/molecules/set-symmetry-for-all.d.ts +4 -0
- package/dist/types/core/src/molecules/swap-part-slot.d.ts +7 -0
- package/dist/types/core/src/premades/ant-bake.d.ts +2 -0
- package/dist/types/core/src/premades/bake-authoring.d.ts +35 -0
- package/dist/types/core/src/premades/bake-types.d.ts +65 -0
- package/dist/types/core/src/premades/baked-part-for.d.ts +11 -0
- package/dist/types/core/src/premades/bee-bake.d.ts +2 -0
- package/dist/types/core/src/premades/bird-bake.d.ts +2 -0
- package/dist/types/core/src/premades/body-stamps-for-bone.d.ts +14 -0
- package/dist/types/core/src/premades/bone-tree.d.ts +15 -0
- package/dist/types/core/src/premades/build-premade-rig.d.ts +23 -0
- package/dist/types/core/src/premades/build-template.d.ts +6 -0
- package/dist/types/core/src/premades/centipede-bake.d.ts +2 -0
- package/dist/types/core/src/premades/coat-stamps.d.ts +3 -0
- package/dist/types/core/src/premades/crab-bake.d.ts +2 -0
- package/dist/types/core/src/premades/dragon-bake.d.ts +2 -0
- package/dist/types/core/src/premades/face-decals.d.ts +17 -0
- package/dist/types/core/src/premades/fish-bake.d.ts +2 -0
- package/dist/types/core/src/premades/fit-part-slot.d.ts +21 -0
- package/dist/types/core/src/premades/generate-creature.d.ts +21 -0
- package/dist/types/core/src/premades/gorilla-bake.d.ts +2 -0
- package/dist/types/core/src/premades/graft-slot.d.ts +34 -0
- package/dist/types/core/src/premades/humanoid-bake.d.ts +2 -0
- package/dist/types/core/src/premades/insect6-bake.d.ts +2 -0
- package/dist/types/core/src/premades/jellyfish-bake.d.ts +2 -0
- package/dist/types/core/src/premades/lizard-bake.d.ts +2 -0
- package/dist/types/core/src/premades/make-baked-part.d.ts +9 -0
- package/dist/types/core/src/premades/make-body-part.d.ts +9 -0
- package/dist/types/core/src/premades/make-flat-part.d.ts +13 -0
- package/dist/types/core/src/premades/part-context.d.ts +20 -0
- package/dist/types/core/src/premades/part-kits.d.ts +36 -0
- package/dist/types/core/src/premades/part-slots.d.ts +17 -0
- package/dist/types/core/src/premades/part-stamp.d.ts +13 -0
- package/dist/types/core/src/premades/part-styles.d.ts +44 -0
- package/dist/types/core/src/premades/premade-fit.d.ts +18 -0
- package/dist/types/core/src/premades/premade-infos.d.ts +3 -0
- package/dist/types/core/src/premades/reseat-attachments.d.ts +31 -0
- package/dist/types/core/src/premades/rig-builder.d.ts +51 -0
- package/dist/types/core/src/premades/rodent-bake.d.ts +2 -0
- package/dist/types/core/src/premades/scorpion-bake.d.ts +2 -0
- package/dist/types/core/src/premades/shark-bake.d.ts +2 -0
- package/dist/types/core/src/premades/sitter-bake.d.ts +3 -0
- package/dist/types/core/src/premades/skeleton-bakes.d.ts +4 -0
- package/dist/types/core/src/premades/snake-bake.d.ts +2 -0
- package/dist/types/core/src/premades/spider-bake.d.ts +2 -0
- package/dist/types/core/src/premades/stamps-box.d.ts +9 -0
- package/dist/types/core/src/premades/style-for-bone.d.ts +7 -0
- package/dist/types/core/src/premades/swap-slot.d.ts +13 -0
- package/dist/types/core/src/premades/template-catalog.d.ts +20 -0
- package/dist/types/core/src/premades/template-color.d.ts +9 -0
- package/dist/types/core/src/premades/turtle-bake.d.ts +2 -0
- package/dist/types/core/src/premades/variants/aquatic-variants.d.ts +16 -0
- package/dist/types/core/src/premades/variants/coat-variants.d.ts +7 -0
- package/dist/types/core/src/premades/variants/ear-variants.d.ts +8 -0
- package/dist/types/core/src/premades/variants/fantasy-more-variants.d.ts +3 -0
- package/dist/types/core/src/premades/variants/fantasy-variants.d.ts +17 -0
- package/dist/types/core/src/premades/variants/head-variants.d.ts +9 -0
- package/dist/types/core/src/premades/variants/horn-variants.d.ts +7 -0
- package/dist/types/core/src/premades/variants/index.d.ts +10 -0
- package/dist/types/core/src/premades/variants/land-variants.d.ts +3 -0
- package/dist/types/core/src/premades/variants/leg-variants.d.ts +7 -0
- package/dist/types/core/src/premades/variants/part-variant.d.ts +14 -0
- package/dist/types/core/src/premades/variants/tail-variants.d.ts +6 -0
- package/dist/types/core/src/premades/variants/variant-authoring.d.ts +29 -0
- package/dist/types/core/src/premades/whale-bake.d.ts +2 -0
- package/dist/types/core/src/premades/wing-defaults.d.ts +4 -0
- package/dist/types/core/src/premades/wing-frame.d.ts +10 -0
- package/dist/types/core/src/premades/wolf-bake.d.ts +2 -0
- package/dist/types/core/src/premades/worm-bake.d.ts +2 -0
- package/dist/types/evaluator/src/abi.d.ts +64 -0
- package/dist/types/evaluator/src/chunks.d.ts +53 -0
- package/dist/types/evaluator/src/index.d.ts +11 -0
- package/dist/types/evaluator/src/prep/colors.d.ts +11 -0
- package/dist/types/evaluator/src/prep/mat3.d.ts +13 -0
- package/dist/types/evaluator/src/prep/pack.d.ts +23 -0
- package/dist/types/evaluator/src/prep/props.d.ts +16 -0
- package/dist/types/evaluator/src/prep/symmetry.d.ts +23 -0
- package/dist/types/evaluator/src/reference/core.d.ts +3 -0
- package/dist/types/evaluator/src/reference/mesher.d.ts +22 -0
- package/dist/types/evaluator/src/reference/skin.d.ts +8 -0
- package/dist/types/evaluator/src/session.d.ts +21 -0
- package/dist/types/evaluator/src/wasm/core.d.ts +9 -0
- package/dist/types/evaluator/src/worker/client.d.ts +28 -0
- package/dist/types/evaluator/src/worker/host.d.ts +8 -0
- package/dist/types/evaluator/src/worker/protocol.d.ts +39 -0
- package/dist/types/evaluator/src/worker/spawn.d.ts +6 -0
- package/dist/types/evaluator/src/worker/worker-inline.d.ts +1 -0
- package/dist/types/evaluator/src/worker/worker.d.ts +1 -0
- package/dist/types/module/src/index.d.ts +2 -0
- package/dist/types/module/src/ui/atoms/action-button.d.ts +10 -0
- package/dist/types/module/src/ui/atoms/badge.d.ts +9 -0
- package/dist/types/module/src/ui/atoms/checkbox.d.ts +6 -0
- package/dist/types/module/src/ui/atoms/color-input.d.ts +10 -0
- package/dist/types/module/src/ui/atoms/hex-chip.d.ts +5 -0
- package/dist/types/module/src/ui/atoms/icon-button.d.ts +14 -0
- package/dist/types/module/src/ui/atoms/icon.d.ts +8 -0
- package/dist/types/module/src/ui/atoms/kbd.d.ts +4 -0
- package/dist/types/module/src/ui/atoms/match-button.d.ts +10 -0
- package/dist/types/module/src/ui/atoms/number-input.d.ts +11 -0
- package/dist/types/module/src/ui/atoms/pill-button.d.ts +11 -0
- package/dist/types/module/src/ui/atoms/range-input.d.ts +17 -0
- package/dist/types/module/src/ui/atoms/select-input.d.ts +12 -0
- package/dist/types/module/src/ui/atoms/separator.d.ts +2 -0
- package/dist/types/module/src/ui/atoms/side-button.d.ts +13 -0
- package/dist/types/module/src/ui/atoms/swatch.d.ts +13 -0
- package/dist/types/module/src/ui/atoms/tool-button.d.ts +22 -0
- package/dist/types/module/src/ui/hooks/editor-actions.d.ts +50 -0
- package/dist/types/module/src/ui/hooks/editor-context.d.ts +37 -0
- package/dist/types/module/src/ui/hooks/use-compact.d.ts +2 -0
- package/dist/types/module/src/ui/hooks/use-editor-controller.d.ts +17 -0
- package/dist/types/module/src/ui/hooks/use-keyboard.d.ts +11 -0
- package/dist/types/module/src/ui/lib/catalog.d.ts +76 -0
- package/dist/types/module/src/ui/lib/colors.d.ts +15 -0
- package/dist/types/module/src/ui/lib/decals.d.ts +6 -0
- package/dist/types/module/src/ui/lib/design-geometry.d.ts +60 -0
- package/dist/types/module/src/ui/lib/math.d.ts +18 -0
- package/dist/types/module/src/ui/lib/placement.d.ts +8 -0
- package/dist/types/module/src/ui/lib/scene.d.ts +51 -0
- package/dist/types/module/src/ui/lib/symmetry.d.ts +5 -0
- package/dist/types/module/src/ui/lib/targets.d.ts +28 -0
- package/dist/types/module/src/ui/lib/view-state.d.ts +74 -0
- package/dist/types/module/src/ui/molecules/axis-pill.d.ts +7 -0
- package/dist/types/module/src/ui/molecules/color-field.d.ts +14 -0
- package/dist/types/module/src/ui/molecules/count-stepper.d.ts +9 -0
- package/dist/types/module/src/ui/molecules/floating-panel.d.ts +26 -0
- package/dist/types/module/src/ui/molecules/help-row.d.ts +8 -0
- package/dist/types/module/src/ui/molecules/inline-edit.d.ts +9 -0
- package/dist/types/module/src/ui/molecules/list-row.d.ts +25 -0
- package/dist/types/module/src/ui/molecules/modal.d.ts +11 -0
- package/dist/types/module/src/ui/molecules/mode-pill.d.ts +7 -0
- package/dist/types/module/src/ui/molecules/scroll-row.d.ts +10 -0
- package/dist/types/module/src/ui/molecules/slider-row.d.ts +16 -0
- package/dist/types/module/src/ui/molecules/swatch-row.d.ts +11 -0
- package/dist/types/module/src/ui/molecules/tab-bar.d.ts +9 -0
- package/dist/types/module/src/ui/molecules/toolbar-pill.d.ts +7 -0
- package/dist/types/module/src/ui/molecules/toolbar.d.ts +10 -0
- package/dist/types/module/src/ui/molecules/vec3-field.d.ts +10 -0
- package/dist/types/module/src/ui/organisms/bone-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/bone-size-sliders.d.ts +9 -0
- package/dist/types/module/src/ui/organisms/category-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/decal-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/decal-editor.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/fleck-style-tab.d.ts +7 -0
- package/dist/types/module/src/ui/organisms/git-sync-panel.d.ts +10 -0
- package/dist/types/module/src/ui/organisms/help-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/material-tab.d.ts +3 -0
- package/dist/types/module/src/ui/organisms/object-list-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/palette-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/parts-tab.d.ts +26 -0
- package/dist/types/module/src/ui/organisms/pattern-tab.d.ts +3 -0
- package/dist/types/module/src/ui/organisms/pose-tab.d.ts +8 -0
- package/dist/types/module/src/ui/organisms/premade-picker.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/properties-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/region-blends.d.ts +5 -0
- package/dist/types/module/src/ui/organisms/rendering-bar.d.ts +5 -0
- package/dist/types/module/src/ui/organisms/rig-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/scenes-modal.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/select-hint.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/shape-list-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/side-dock.d.ts +4 -0
- package/dist/types/module/src/ui/organisms/stamp-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/stamp-props-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/stamp-size-panel.d.ts +4 -0
- package/dist/types/module/src/ui/organisms/stats-badge.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/style-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/symmetry-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/toast.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/token-guide.d.ts +5 -0
- package/dist/types/module/src/ui/organisms/touch-mods.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/transform-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/transform-tab.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/utilities-bar.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/viewport-host.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/voxel-panel.d.ts +2 -0
- package/dist/types/module/src/ui/organisms/wing-tab.d.ts +10 -0
- package/dist/types/module/src/ui/pages/editor-page.d.ts +9 -0
- package/dist/types/module/src/ui/templates/editor-shell.d.ts +2 -0
- package/dist/types/studio/src/browser-files.d.ts +3 -0
- package/dist/types/studio/src/clock.d.ts +2 -0
- package/dist/types/studio/src/creation-file.d.ts +21 -0
- package/dist/types/studio/src/git-remote.d.ts +36 -0
- package/dist/types/studio/src/git-sync.d.ts +33 -0
- package/dist/types/studio/src/ids.d.ts +3 -0
- package/dist/types/studio/src/index.d.ts +15 -0
- package/dist/types/studio/src/indexed-db-library.d.ts +2 -0
- package/dist/types/studio/src/library-persistence.d.ts +29 -0
- package/dist/types/studio/src/library-sync.d.ts +29 -0
- package/dist/types/studio/src/preferences.d.ts +9 -0
- package/dist/types/studio/src/seed.d.ts +3 -0
- package/dist/types/studio/src/studio.d.ts +17 -0
- package/dist/types/viewport/src/create-viewport.d.ts +10 -0
- package/dist/types/viewport/src/decals/builtin-art.d.ts +19 -0
- package/dist/types/viewport/src/decals/builtin-docs.d.ts +7 -0
- package/dist/types/viewport/src/decals/decal-atlas.d.ts +37 -0
- package/dist/types/viewport/src/decals/decal-catalog.d.ts +17 -0
- package/dist/types/viewport/src/decals/decal-glsl.d.ts +2 -0
- package/dist/types/viewport/src/decals/decal-limits.d.ts +11 -0
- package/dist/types/viewport/src/decals/decal-uniforms.d.ts +40 -0
- package/dist/types/viewport/src/decals/design-raster.d.ts +8 -0
- package/dist/types/viewport/src/decals/interior-thumbs.d.ts +6 -0
- package/dist/types/viewport/src/index.d.ts +1 -0
- package/dist/types/viewport/src/interaction/bone-tool.d.ts +13 -0
- package/dist/types/viewport/src/interaction/bones-visible.d.ts +7 -0
- package/dist/types/viewport/src/interaction/cursor.d.ts +3 -0
- package/dist/types/viewport/src/interaction/decal-tool.d.ts +18 -0
- package/dist/types/viewport/src/interaction/esc-hold.d.ts +13 -0
- package/dist/types/viewport/src/interaction/ghost-geometry.d.ts +6 -0
- package/dist/types/viewport/src/interaction/gizmo.d.ts +34 -0
- package/dist/types/viewport/src/interaction/interaction-context.d.ts +41 -0
- package/dist/types/viewport/src/interaction/marquee.d.ts +8 -0
- package/dist/types/viewport/src/interaction/pivot-helper.d.ts +13 -0
- package/dist/types/viewport/src/interaction/select-tool.d.ts +30 -0
- package/dist/types/viewport/src/interaction/selection-boxes.d.ts +11 -0
- package/dist/types/viewport/src/interaction/stamp-tool.d.ts +41 -0
- package/dist/types/viewport/src/interaction/stamp-wires.d.ts +18 -0
- package/dist/types/viewport/src/interaction/surface-hit.d.ts +14 -0
- package/dist/types/viewport/src/materials/fleck-material.d.ts +69 -0
- package/dist/types/viewport/src/materials/global-uniforms.d.ts +15 -0
- package/dist/types/viewport/src/materials/skin.d.ts +18 -0
- package/dist/types/viewport/src/materials/wing-material.d.ts +21 -0
- package/dist/types/viewport/src/math/colors.d.ts +29 -0
- package/dist/types/viewport/src/math/convert.d.ts +15 -0
- package/dist/types/viewport/src/math/decal-pose.d.ts +7 -0
- package/dist/types/viewport/src/math/lod.d.ts +16 -0
- package/dist/types/viewport/src/math/picking.d.ts +32 -0
- package/dist/types/viewport/src/math/pixel-palette.d.ts +15 -0
- package/dist/types/viewport/src/math/screen.d.ts +26 -0
- package/dist/types/viewport/src/math/skeleton-math.d.ts +32 -0
- package/dist/types/viewport/src/math/smear.d.ts +20 -0
- package/dist/types/viewport/src/math/symmetry.d.ts +21 -0
- package/dist/types/viewport/src/objects/default-look.d.ts +3 -0
- package/dist/types/viewport/src/objects/mesh-driver.d.ts +26 -0
- package/dist/types/viewport/src/objects/mesh-key.d.ts +8 -0
- package/dist/types/viewport/src/objects/rig-view.d.ts +31 -0
- package/dist/types/viewport/src/objects/scene-views.d.ts +53 -0
- package/dist/types/viewport/src/objects/sculpt-view.d.ts +66 -0
- package/dist/types/viewport/src/objects/view-context.d.ts +19 -0
- package/dist/types/viewport/src/objects/wing-view.d.ts +27 -0
- package/dist/types/viewport/src/rig/bone-viz.d.ts +13 -0
- package/dist/types/viewport/src/scene/camera-motion.d.ts +10 -0
- package/dist/types/viewport/src/scene/camera-sun.d.ts +3 -0
- package/dist/types/viewport/src/scene/environment.d.ts +3 -0
- package/dist/types/viewport/src/scene/frame-camera.d.ts +10 -0
- package/dist/types/viewport/src/scene/play-mode.d.ts +9 -0
- package/dist/types/viewport/src/scene/render-pipeline.d.ts +26 -0
- package/dist/types/viewport/src/scene/render-settings.d.ts +18 -0
- package/dist/types/viewport/src/scene/resolve-frag.d.ts +3 -0
- package/dist/types/viewport/src/scene/stage.d.ts +38 -0
- package/dist/types/viewport/src/scene/stress-test.d.ts +6 -0
- package/dist/types/viewport/src/wings/wing-mesh.d.ts +19 -0
- package/dist/types/viewport/src/wings/wing-outlines.d.ts +32 -0
- package/dist/types/viewport/src/wings/wing-pattern.d.ts +7 -0
- package/dist/viewport.d.ts +1 -0
- package/dist/viewport.js +8 -0
- package/dist/viewport.js.map +7 -0
- package/package.json +74 -4
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SculptLook, SculptTarget } from "../../../../api/src/index.js";
|
|
2
|
+
export type LookTabProps = {
|
|
3
|
+
readonly look: SculptLook;
|
|
4
|
+
readonly targets: readonly SculptTarget[];
|
|
5
|
+
};
|
|
6
|
+
/** Fleck type and sliders, the rig's region blends, fleck and foundation colors. */
|
|
7
|
+
export declare function FleckStyleTab({ look, targets }: LookTabProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LibrarySync, SyncStatus } from "../../../../api/src/index.js";
|
|
2
|
+
/** The library's git status, kept current through the port. */
|
|
3
|
+
export declare function useSyncStatus(sync: LibrarySync | undefined): SyncStatus;
|
|
4
|
+
export type GitSyncPanelProps = {
|
|
5
|
+
readonly sync: LibrarySync;
|
|
6
|
+
readonly status: SyncStatus;
|
|
7
|
+
readonly toast: (message: string) => void;
|
|
8
|
+
};
|
|
9
|
+
/** Scenes dialog section: connect the library to one GitHub / GitLab repository, sync now, disconnect. */
|
|
10
|
+
export declare function GitSyncPanel({ sync, status, toast }: GitSyncPanelProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CreatureRecipe, CreatureTheme, PartSlot, RigObject } from "../../../../api/src/index.js";
|
|
2
|
+
/** What a generated creature can lock: its base skeleton, a slot, its proportions or its face art. */
|
|
3
|
+
type Lock = "base" | "sizes" | "eyes" | "mouth" | PartSlot;
|
|
4
|
+
/** The generator's themes: a whole creature built from one made-up kind (natural: none). */
|
|
5
|
+
export declare const THEME_OPTIONS: readonly {
|
|
6
|
+
readonly id: CreatureTheme | "none";
|
|
7
|
+
readonly name: string;
|
|
8
|
+
}[];
|
|
9
|
+
export declare const themeOf: (id: CreatureTheme | "none") => {
|
|
10
|
+
theme?: CreatureTheme;
|
|
11
|
+
};
|
|
12
|
+
/** A fresh seed for a roll. */
|
|
13
|
+
export declare const newSeed: () => number;
|
|
14
|
+
/** What a re-roll keeps from a recipe: everything in `locks`. */
|
|
15
|
+
export declare function keptOf(recipe: CreatureRecipe, locks: ReadonlySet<Lock>): Partial<Pick<CreatureRecipe, "base" | "kits" | "sizes" | "eyes" | "mouth">>;
|
|
16
|
+
/**
|
|
17
|
+
* A premade rig's part slots: each can take the parts of another premade (of the same family, or any with Chimera),
|
|
18
|
+
* fitted to this rig's bones, or a part variant (a tiger head, elephant ears). Picking the rig's own premade restores
|
|
19
|
+
* its own parts. Wings, horns or a tail the skeleton
|
|
20
|
+
* lacks can be grafted from a premade that has them. A generated rig also gets its generator: re-roll everything not
|
|
21
|
+
* locked, or one slot, its proportions or its face.
|
|
22
|
+
*/
|
|
23
|
+
export declare function PartsTab({ rig }: {
|
|
24
|
+
readonly rig: RigObject;
|
|
25
|
+
}): import("react").JSX.Element | null;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RigObject } from "../../../../api/src/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* A premade rig's pose presets: one pose, or two blended by a slider. Picking writes every bone's pose; posing
|
|
4
|
+
* bones by hand keeps that pose as Custom, offered here once it exists.
|
|
5
|
+
*/
|
|
6
|
+
export declare function PoseTab({ rig }: {
|
|
7
|
+
readonly rig: RigObject;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rendering: normal / pixel art, render resolution, selected only, camera sun, fit to view (the selection, or
|
|
3
|
+
* everything, contained in a centred square from the current angle) and decal line boost (view preferences).
|
|
4
|
+
*/
|
|
5
|
+
export declare function RenderingBar(): import("react").JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { GitProvider } from "../../../../api/src/index.js";
|
|
2
|
+
/** How to create an access token for the save repository (after vite-react's token guide). */
|
|
3
|
+
export declare function TokenGuide({ provider }: {
|
|
4
|
+
readonly provider: GitProvider;
|
|
5
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FlatWing, Id, Material } from "../../../../api/src/index.js";
|
|
2
|
+
export type WingTabProps = {
|
|
3
|
+
readonly wing: FlatWing;
|
|
4
|
+
/** The (first) wing part's material. */
|
|
5
|
+
readonly material: Material;
|
|
6
|
+
readonly rigId: Id;
|
|
7
|
+
readonly boneIds: readonly Id[];
|
|
8
|
+
};
|
|
9
|
+
/** Flat wing outline, size, pattern and colors; every edit goes to all listed wings. */
|
|
10
|
+
export declare function WingTab({ wing, material, rigId, boneIds }: WingTabProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "../studio.css";
|
|
2
|
+
import { type EditorControllerProps } from "../hooks/use-editor-controller.js";
|
|
3
|
+
/**
|
|
4
|
+
* One open creation in the studio. Logic comes from `api`; the 3D view is the injected `viewport`, mounted into
|
|
5
|
+
* a host element; `persistence` backs the Scenes dialog and autosave; `preferences` holds per-browser view
|
|
6
|
+
* settings. `onOpen` asks the host to switch to another library entry.
|
|
7
|
+
*/
|
|
8
|
+
export type EditorPageProps = EditorControllerProps;
|
|
9
|
+
export declare function EditorPage(props: EditorPageProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CreationLog } from "../../api/src/index.js";
|
|
2
|
+
export declare const EMPTY_LOG: CreationLog;
|
|
3
|
+
/** A log file is the format tag, the schema version and the events. */
|
|
4
|
+
export declare function serializeCreationLog(log: CreationLog): string;
|
|
5
|
+
/** Parses a file into a log, or undefined when it is not a log of this model (retired schemas included). */
|
|
6
|
+
export declare function parseCreationLog(text: string): CreationLog | undefined;
|
|
7
|
+
/** "My Bunny.dreamy.json" -> "My Bunny". */
|
|
8
|
+
export declare function creationNameFromFile(fileName: string): string;
|
|
9
|
+
export declare function fileNameFor(name: string): string;
|
|
10
|
+
/** A creation as a file in the save repository: the log plus its library entry. Import reads it too. */
|
|
11
|
+
export type CreationRecordFile = {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly updatedAt: number;
|
|
15
|
+
readonly thumbnail?: string;
|
|
16
|
+
readonly log: CreationLog;
|
|
17
|
+
};
|
|
18
|
+
/** Keys in a fixed order, one event per line, so equal records give equal bytes (and git diffs stay small). */
|
|
19
|
+
export declare function serializeCreationRecord({ id, name, updatedAt, thumbnail, log }: CreationRecordFile): string;
|
|
20
|
+
/** A record file, or a plain scene file (named `fallbackName`). */
|
|
21
|
+
export declare function parseCreationRecord(text: string, id: string, fallbackName?: string): CreationRecordFile | undefined;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { GitSettings } from "../../api/src/index.js";
|
|
2
|
+
/** Every creation is one file under this folder of the save repository. */
|
|
3
|
+
export declare const CREATIONS_DIR = "creations";
|
|
4
|
+
export declare const creationPath: (id: string) => string;
|
|
5
|
+
export declare function creationIdOf(path: string): string | undefined;
|
|
6
|
+
/** The branch head and the blob SHA of every creation file at that commit. */
|
|
7
|
+
export type RemoteSnapshot = {
|
|
8
|
+
readonly head: string;
|
|
9
|
+
readonly files: ReadonlyMap<string, string>;
|
|
10
|
+
};
|
|
11
|
+
/** A file to write, or to delete when `content` is absent. `exists` says whether the snapshot had it. */
|
|
12
|
+
export type FileChange = {
|
|
13
|
+
readonly path: string;
|
|
14
|
+
readonly exists: boolean;
|
|
15
|
+
readonly content?: string;
|
|
16
|
+
};
|
|
17
|
+
/** The branch moved since the snapshot: take a new snapshot and sync again. */
|
|
18
|
+
export declare class StaleRemoteError extends Error {
|
|
19
|
+
readonly name = "StaleRemoteError";
|
|
20
|
+
}
|
|
21
|
+
/** One branch of the save repository. */
|
|
22
|
+
export type GitRemote = {
|
|
23
|
+
readonly user: string;
|
|
24
|
+
/** "owner/name" as the provider shows it. */
|
|
25
|
+
readonly repo: string;
|
|
26
|
+
readonly branch: string;
|
|
27
|
+
snapshot(): Promise<RemoteSnapshot>;
|
|
28
|
+
read(path: string, sha: string): Promise<string>;
|
|
29
|
+
/** One commit on top of `parent`; throws StaleRemoteError when the branch is no longer at `parent`. */
|
|
30
|
+
commit(message: string, changes: readonly FileChange[], parent: string): Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
export type Fetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
33
|
+
/** Git's blob id: SHA-1 of "blob <byte length>\0" + the bytes (as vite-react computes it for differential push). */
|
|
34
|
+
export declare function gitBlobSha(text: string): Promise<string>;
|
|
35
|
+
/** Verifies the token, finds or creates the repository and the branch, and returns the remote. */
|
|
36
|
+
export declare function connectRemote(settings: GitSettings, fetcher: Fetch): Promise<GitRemote>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GitSettings, Id, LibrarySync, Persistence } from "../../api/src/index.js";
|
|
2
|
+
import { type GitRemote } from "./git-remote.js";
|
|
3
|
+
import type { LibraryDatabase } from "./library-persistence.js";
|
|
4
|
+
import type { KeyValueStorage } from "./preferences.js";
|
|
5
|
+
/** A push follows the last library change after this long. */
|
|
6
|
+
export declare const PUSH_DELAY_MS = 30000;
|
|
7
|
+
export type GitSyncDeps = {
|
|
8
|
+
readonly database: LibraryDatabase;
|
|
9
|
+
readonly storage: KeyValueStorage | undefined;
|
|
10
|
+
/** Verifies the settings and returns the remote (`connectRemote` over the browser's fetch). */
|
|
11
|
+
readonly connect: (settings: GitSettings) => Promise<GitRemote>;
|
|
12
|
+
readonly newId: () => Id;
|
|
13
|
+
readonly now: () => number;
|
|
14
|
+
/** The creation open in the editor. */
|
|
15
|
+
readonly openId: () => Id | undefined;
|
|
16
|
+
readonly pushDelayMs?: number;
|
|
17
|
+
};
|
|
18
|
+
/** The LibrarySync port plus what the composition root needs: scheduled pushes. */
|
|
19
|
+
export type GitSync = LibrarySync & {
|
|
20
|
+
readonly connected: boolean;
|
|
21
|
+
/** Debounced sync after a library change. */
|
|
22
|
+
schedule(): void;
|
|
23
|
+
/** Runs a scheduled sync now. */
|
|
24
|
+
flush(): void;
|
|
25
|
+
dispose(): void;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Git sync of the library, as vite-react's central vault: one repository, a personal access token kept in
|
|
29
|
+
* this browser's storage, browser requests to the GitHub / GitLab REST APIs. Syncs run one at a time.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createGitSync({ database, storage, connect, newId, now, openId, pushDelayMs }: GitSyncDeps): GitSync;
|
|
32
|
+
/** Persistence that schedules a push after every library write. */
|
|
33
|
+
export declare function withSyncSchedule(persistence: Persistence, sync: Pick<GitSync, "schedule">): Persistence;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { DreamyStudio } from "./studio.js";
|
|
2
|
+
export type { DreamyStudioProps } from "./studio.js";
|
|
3
|
+
export { createIndexedDbLibrary } from "./indexed-db-library.js";
|
|
4
|
+
export { createLibraryPersistence } from "./library-persistence.js";
|
|
5
|
+
export type { FileAccess, LibraryDatabase, LibraryDeps, LibraryRecord } from "./library-persistence.js";
|
|
6
|
+
export { browserFiles } from "./browser-files.js";
|
|
7
|
+
export { createPreferencesStore, DEFAULT_PREFERENCES } from "./preferences.js";
|
|
8
|
+
export type { KeyValueStorage } from "./preferences.js";
|
|
9
|
+
export { createGitSync, withSyncSchedule } from "./git-sync.js";
|
|
10
|
+
export type { GitSync, GitSyncDeps } from "./git-sync.js";
|
|
11
|
+
export { connectRemote } from "./git-remote.js";
|
|
12
|
+
export type { GitRemote } from "./git-remote.js";
|
|
13
|
+
export { EMPTY_LOG, parseCreationLog, serializeCreationLog } from "./creation-file.js";
|
|
14
|
+
export { createIds } from "./ids.js";
|
|
15
|
+
export { clock } from "./clock.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CreationLog, Id, LibraryEntry, Persistence } from "../../api/src/index.js";
|
|
2
|
+
export type LibraryRecord = LibraryEntry & {
|
|
3
|
+
readonly log: CreationLog;
|
|
4
|
+
};
|
|
5
|
+
/** Storage the library needs (IndexedDB in the browser, a map in tests). */
|
|
6
|
+
export type LibraryDatabase = {
|
|
7
|
+
list(): Promise<readonly LibraryRecord[]>;
|
|
8
|
+
read(id: Id): Promise<LibraryRecord | undefined>;
|
|
9
|
+
write(record: LibraryRecord): Promise<void>;
|
|
10
|
+
delete(id: Id): Promise<void>;
|
|
11
|
+
current(): Promise<Id | undefined>;
|
|
12
|
+
setCurrent(id: Id): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
/** Browser file access: download a text file, pick one to read. */
|
|
15
|
+
export type FileAccess = {
|
|
16
|
+
download(fileName: string, text: string): void;
|
|
17
|
+
pick(): Promise<{
|
|
18
|
+
readonly fileName: string;
|
|
19
|
+
readonly text: string;
|
|
20
|
+
} | undefined>;
|
|
21
|
+
};
|
|
22
|
+
export type LibraryDeps = {
|
|
23
|
+
readonly database: LibraryDatabase;
|
|
24
|
+
readonly files: FileAccess;
|
|
25
|
+
readonly newId: () => Id;
|
|
26
|
+
readonly now: () => number;
|
|
27
|
+
};
|
|
28
|
+
/** The Persistence port over a database and file access. Writes run one at a time, in order. */
|
|
29
|
+
export declare function createLibraryPersistence({ database, files, newId, now }: LibraryDeps): Persistence;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Id, SyncSummary } from "../../api/src/index.js";
|
|
2
|
+
import { type GitRemote } from "./git-remote.js";
|
|
3
|
+
import type { LibraryDatabase } from "./library-persistence.js";
|
|
4
|
+
/** What a creation looked like at its last sync: the repo's blob and the local record's blob. */
|
|
5
|
+
export type SyncedState = {
|
|
6
|
+
readonly remoteSha: string;
|
|
7
|
+
readonly localSha: string;
|
|
8
|
+
};
|
|
9
|
+
export type SyncDeps = {
|
|
10
|
+
readonly database: LibraryDatabase;
|
|
11
|
+
readonly remote: GitRemote;
|
|
12
|
+
/** Last-sync state per creation. Updated in place as the sync goes. */
|
|
13
|
+
readonly state: Map<Id, SyncedState>;
|
|
14
|
+
readonly newId: () => Id;
|
|
15
|
+
/** The creation open in the editor: never overwritten or deleted under it. */
|
|
16
|
+
readonly protect: () => Id | undefined;
|
|
17
|
+
};
|
|
18
|
+
export type SyncResult = SyncSummary & {
|
|
19
|
+
/** Local records the sync wrote or deleted. */
|
|
20
|
+
readonly changed: readonly Id[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* One three-way sync of the library with the repository, against the state of the last sync:
|
|
24
|
+
* - changed on one side only: that side wins (push or pull);
|
|
25
|
+
* - changed on both: keep both, the newer keeps the creation and the other becomes "<name> (conflict copy)";
|
|
26
|
+
* - deleted on one side and unchanged on the other: deleted on both; edited on the other: it comes back.
|
|
27
|
+
* Every push goes in one commit. A StaleRemoteError from the commit means: sync again.
|
|
28
|
+
*/
|
|
29
|
+
export declare function syncLibrary({ database, remote, state, newId, protect }: SyncDeps): Promise<SyncResult>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PreferencesStore, ViewPreferences } from "../../api/src/index.js";
|
|
2
|
+
export declare const DEFAULT_PREFERENCES: ViewPreferences;
|
|
3
|
+
export type KeyValueStorage = {
|
|
4
|
+
getItem(key: string): string | null;
|
|
5
|
+
setItem(key: string, value: string): void;
|
|
6
|
+
removeItem?(key: string): void;
|
|
7
|
+
};
|
|
8
|
+
/** View settings per browser. A missing, broken or blocked store falls back to the defaults. */
|
|
9
|
+
export declare function createPreferencesStore(storage: KeyValueStorage | undefined): PreferencesStore;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type LibraryDatabase } from "./library-persistence.js";
|
|
2
|
+
import { type KeyValueStorage } from "./preferences.js";
|
|
3
|
+
export type DreamyStudioProps = {
|
|
4
|
+
/** Where the library of creations lives. Default: this browser's IndexedDB ("dreamy-studio" database). */
|
|
5
|
+
readonly database?: LibraryDatabase;
|
|
6
|
+
/** Key-value storage for view preferences and git settings. Default: localStorage. */
|
|
7
|
+
readonly storage?: KeyValueStorage;
|
|
8
|
+
/** Offer git sync of the library (Scenes → Git). Default: true. */
|
|
9
|
+
readonly gitSync?: boolean;
|
|
10
|
+
/** Called once: the evaluator core is loaded, the creation is open and the studio has painted. */
|
|
11
|
+
readonly onReady?: () => void;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* The Dreamy studio: core, module, evaluator, viewport, persistence, git sync, preferences, ids and clock.
|
|
15
|
+
* It fills the page (fixed, full viewport); render one per page, client-side only.
|
|
16
|
+
*/
|
|
17
|
+
export declare function DreamyStudio({ database: injected, storage: injectedStorage, gitSync, onReady }: DreamyStudioProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Evaluator, Viewport } from "../../api/src/index.js";
|
|
2
|
+
export type ViewportOptions = {
|
|
3
|
+
/** The mesher (the app constructs it and hands it over; the viewport never imports `@dreamy/evaluator`). */
|
|
4
|
+
readonly evaluator: Evaluator;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* The 3D view (`Viewport` port): reads a Creation + ViewSession, never mutates the creation, reports gestures as
|
|
8
|
+
* Commands through `callbacks.command` and selection through `callbacks.select`. Meshes come from the evaluator.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createViewport({ evaluator }: ViewportOptions): Viewport;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BuiltinDecalCategory, ColorRef, Rgb } from "../../../api/src/index.js";
|
|
2
|
+
/** Resolves a palette ref to CSS and records that the art used it (palette edits re-raster those cells). */
|
|
3
|
+
export type Paint = (ref: ColorRef) => string;
|
|
4
|
+
export type BuiltinArt = {
|
|
5
|
+
readonly category: BuiltinDecalCategory;
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly tintable: boolean;
|
|
8
|
+
/** Default tint for tintable art. */
|
|
9
|
+
readonly tint?: ColorRef;
|
|
10
|
+
/** Interior room id: ray-traced in the shader, no atlas cell. */
|
|
11
|
+
readonly room?: number;
|
|
12
|
+
/** Interior wall color when the decal has no tint (the POC's raw defaults). */
|
|
13
|
+
readonly wall?: Rgb;
|
|
14
|
+
readonly draw: (g: CanvasRenderingContext2D, S: number, paint: Paint) => void;
|
|
15
|
+
};
|
|
16
|
+
/** Category order of the picker (the POC's DECAL_ORDER, built-ins only). */
|
|
17
|
+
export declare const DECAL_CATEGORIES: readonly BuiltinDecalCategory[];
|
|
18
|
+
export declare const BUILTIN_ART: readonly BuiltinArt[];
|
|
19
|
+
export declare const findBuiltin: (category: BuiltinDecalCategory, name: string) => BuiltinArt | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DesignShape } from "../../../api/src/index.js";
|
|
2
|
+
/** Built-in decals drawn as designs (palette-driven), from the POC's BUILTIN_DOCS. */
|
|
3
|
+
export declare const BUILTIN_DOCS: Record<string, {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly category: "eye" | "mouth" | "mark";
|
|
6
|
+
readonly shapes: readonly DesignShape[];
|
|
7
|
+
}>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DecalArt, Design, Palette } from "../../../api/src/index.js";
|
|
2
|
+
import { CanvasTexture } from "three";
|
|
3
|
+
import { type BuiltinArt } from "./builtin-art.js";
|
|
4
|
+
import type { DecalArtInfo } from "./decal-uniforms.js";
|
|
5
|
+
/**
|
|
6
|
+
* One canvas atlas per viewport (the POC's decal atlas): built-in art first, then one cell per design of the
|
|
7
|
+
* open creation. Palette edits and design saves re-raster only the cells they touch; the GPU upload happens at
|
|
8
|
+
* most once per frame (`flush`).
|
|
9
|
+
*/
|
|
10
|
+
export declare class DecalAtlas {
|
|
11
|
+
readonly canvas: HTMLCanvasElement;
|
|
12
|
+
readonly texture: CanvasTexture;
|
|
13
|
+
private readonly ctx;
|
|
14
|
+
private readonly builtins;
|
|
15
|
+
private readonly designs;
|
|
16
|
+
private readonly free;
|
|
17
|
+
private palette;
|
|
18
|
+
private dirty;
|
|
19
|
+
constructor(palette: Palette);
|
|
20
|
+
private newCell;
|
|
21
|
+
private raster;
|
|
22
|
+
/** Re-rasters the cells that use a slot whose color changed. */
|
|
23
|
+
setPalette(palette: Palette): void;
|
|
24
|
+
/** Cells for the creation's designs: new / changed ones rasterized, deleted ones freed. */
|
|
25
|
+
setDesigns(designs: readonly Design[]): void;
|
|
26
|
+
/** At most one GPU upload per frame. */
|
|
27
|
+
flush(): void;
|
|
28
|
+
private cellOf;
|
|
29
|
+
builtinOf(art: DecalArt): BuiltinArt | undefined;
|
|
30
|
+
info(art: DecalArt): DecalArtInfo;
|
|
31
|
+
/** The art's own canvas (ghost preview, thumbnails), and a version that changes on every re-raster. */
|
|
32
|
+
cellCanvas(art: DecalArt): {
|
|
33
|
+
canvas: HTMLCanvasElement;
|
|
34
|
+
version: number;
|
|
35
|
+
} | undefined;
|
|
36
|
+
dispose(): void;
|
|
37
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Creation, DecalCatalogEntry } from "../../../api/src/index.js";
|
|
2
|
+
import type { DecalAtlas } from "./decal-atlas.js";
|
|
3
|
+
export type CatalogEntry = DecalCatalogEntry & {
|
|
4
|
+
readonly category: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* The picker's list: built-ins by category, then the creation's designs (category "custom"). Thumbnails are
|
|
8
|
+
* 64 px data URLs drawn with the current palette; tintable art is multiplied by its default tint.
|
|
9
|
+
*/
|
|
10
|
+
export declare class DecalCatalog {
|
|
11
|
+
private readonly atlas;
|
|
12
|
+
private interiors;
|
|
13
|
+
private readonly thumbs;
|
|
14
|
+
constructor(atlas: () => DecalAtlas);
|
|
15
|
+
entries(creation: Creation): CatalogEntry[];
|
|
16
|
+
private thumb;
|
|
17
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const INTERIOR_GLSL = "\n // ---- Interior rooms: a box behind a flat window, ray-traced in decal space ----\n // Window = x, y in [-0.5, 0.5] on the z = 0 plane; the room runs from z = 0 down to z = -D.\n float rHash(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n vec3 rPal(float h) { return 0.35 + 0.5 * cos(6.2831853 * (h + vec3(0.0, 0.33, 0.67))); }\n\n // Nearest-hit box test (material id, normal and distance are only written when this box is closer)\n void rBox(vec3 o, vec3 d, vec3 mn, vec3 mx, int mat, inout float tB, inout vec3 nB, inout int mB) {\n vec3 inv = 1.0 / d;\n vec3 t1 = (mn - o) * inv, t2 = (mx - o) * inv;\n vec3 tmn = min(t1, t2), tmx = max(t1, t2);\n float tN = max(max(tmn.x, tmn.y), tmn.z);\n float tF = min(min(tmx.x, tmx.y), tmx.z);\n if (tN < tF && tN > 0.0 && tN < tB) {\n tB = tN; mB = mat;\n nB = -sign(d) * step(vec3(tN - 1e-5), tmn);\n }\n }\n\n bool rAabb(vec3 o, vec3 d, vec3 mn, vec3 mx) {\n vec3 inv = 1.0 / d;\n vec3 t1 = (mn - o) * inv, t2 = (mx - o) * inv;\n vec3 a = min(t1, t2), b = max(t1, t2);\n float tF = min(min(b.x, b.y), b.z);\n return max(max(a.x, a.y), a.z) < tF && tF > 0.0;\n }\n\n // Bookcase face: shelf boards plus hashed book spines\n vec3 rBooks(vec3 h, float D, float seed) {\n float ry = (h.y + 0.5) / 0.23;\n if (ry > 4.0) return vec3(0.34, 0.21, 0.11);\n float ri = floor(ry), fy = fract(ry);\n if (fy < 0.07) return vec3(0.34, 0.21, 0.11);\n float s = (-h.z / D) * 26.0;\n float bi = floor(s), fx = fract(s);\n float r1 = rHash(vec2(bi, ri + seed * 3.1));\n float r2 = rHash(vec2(bi + 41.0, ri + seed));\n if (fy > 0.07 + (0.55 + 0.4 * r1) * 0.88) return vec3(0.16, 0.10, 0.06);\n if (fx < 0.08) return vec3(0.10, 0.08, 0.06);\n return rPal(r2) * (0.8 + 0.3 * fract(r1 * 7.0));\n }\n\n // pd: surface point in decal space (flip already applied), d: unit view direction in decal space (z < 0 = into the wall)\n // room ids: 0 bed, 1 books, 2 table + chairs, 3 double doors with small windows, 4 grid\n // returns linear colour\n vec3 interiorRoom(vec3 pd, vec3 d, float variant, float D, vec3 wall, float seed) {\n if (abs(d.x) < 1e-4) d.x = d.x < 0.0 ? -1e-4 : 1e-4;\n if (abs(d.y) < 1e-4) d.y = d.y < 0.0 ? -1e-4 : 1e-4;\n vec3 o = pd - d * (pd.z / d.z); // slide along the ray to the window plane\n o = vec3(clamp(o.xy, -0.499, 0.499), 0.0);\n int V = int(variant + 0.5);\n\n // Shell: floor (1), ceiling (2), side walls (3), back wall (4)\n float tx = ((d.x > 0.0 ? 0.5 : -0.5) - o.x) / d.x;\n float ty = ((d.y > 0.0 ? 0.5 : -0.5) - o.y) / d.y;\n float tz = -D / d.z;\n float tB; vec3 nB; int mB;\n if (tz <= tx && tz <= ty) { tB = tz; nB = vec3(0.0, 0.0, 1.0); mB = 4; }\n else if (tx <= ty) { tB = tx; nB = vec3(-sign(d.x), 0.0, 0.0); mB = 3; }\n else { tB = ty; nB = vec3(0.0, -sign(d.y), 0.0); mB = d.y > 0.0 ? 2 : 1; }\n\n // Contents (materials: 5 wood, 6 accent cloth, 7 linen, 8 bookcase)\n if (V == 0 && rAabb(o, d, vec3(-0.49, -0.50, -D), vec3(-0.17, -0.10, -D * 0.40))) { // bed against the left wall\n float zA = -D * 0.97, zF = -D * 0.40;\n rBox(o, d, vec3(-0.48, -0.50, zA), vec3(-0.18, -0.38, zF), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.47, -0.38, zA), vec3(-0.19, -0.30, zF), 7, tB, nB, mB);\n rBox(o, d, vec3(-0.475, -0.38, -D * 0.72), vec3(-0.185, -0.285, zF), 6, tB, nB, mB);\n rBox(o, d, vec3(-0.44, -0.30, zA), vec3(-0.22, -0.235, -D * 0.86), 7, tB, nB, mB);\n rBox(o, d, vec3(-0.49, -0.50, -D * 0.995), vec3(-0.17, -0.10, zA), 5, tB, nB, mB);\n } else if (V == 1) { // bookcase along the right wall\n rBox(o, d, vec3(0.36, -0.50, -D * 0.92), vec3(0.50, 0.42, -D * 0.12), 8, tB, nB, mB);\n } else if (V == 2 && rAabb(o, d, vec3(-0.42, -0.50, -D * 0.72), vec3(0.42, -0.08, -D * 0.30))) { // table + two chairs\n rBox(o, d, vec3(-0.24, -0.22, -D * 0.72), vec3(0.24, -0.17, -D * 0.30), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.235, -0.50, -D * 0.70), vec3(-0.195, -0.22, -D * 0.66), 5, tB, nB, mB);\n rBox(o, d, vec3(0.195, -0.50, -D * 0.70), vec3(0.235, -0.22, -D * 0.66), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.235, -0.50, -D * 0.36), vec3(-0.195, -0.22, -D * 0.32), 5, tB, nB, mB);\n rBox(o, d, vec3(0.195, -0.50, -D * 0.36), vec3(0.235, -0.22, -D * 0.32), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.40, -0.36, -D * 0.58), vec3(-0.28, -0.31, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(-0.41, -0.31, -D * 0.58), vec3(-0.39, -0.08, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(-0.36, -0.50, -D * 0.53), vec3(-0.32, -0.36, -D * 0.49), 5, tB, nB, mB);\n rBox(o, d, vec3(0.28, -0.36, -D * 0.58), vec3(0.40, -0.31, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(0.39, -0.31, -D * 0.58), vec3(0.41, -0.08, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(0.32, -0.50, -D * 0.53), vec3(0.36, -0.36, -D * 0.49), 5, tB, nB, mB);\n }\n\n // Open curtains just inside the window (9), hung from a rod\n float tc = -0.05 / d.z;\n if (tc < tB) {\n vec3 pc = o + d * tc;\n float edge = 0.28 + 0.08 * clamp(abs(pc.y + 0.05) * 2.0, 0.0, 1.0); // tied back at mid height\n if (pc.y > 0.465) { tB = tc; nB = vec3(0.0, 0.0, 1.0); mB = 5; }\n else if (abs(pc.x) > edge && pc.y > -0.46) { tB = tc; nB = vec3(0.0, 0.0, 1.0); mB = 9; }\n }\n\n // Surface colour at the hit\n vec3 h = o + d * tB;\n vec3 col = vec3(0.5);\n float emit = 0.0;\n if (V == 4 && mB <= 4) { // grid room: tiled walls with dark gaps\n vec2 g = mB <= 2 ? vec2(h.x + 0.5, -h.z / D) : (mB == 3 ? vec2(-h.z / D, h.y + 0.5) : vec2(h.x + 0.5, h.y + 0.5));\n vec2 f = fract(g * 4.0);\n col = wall * mix(0.12, 1.0, step(0.1, f.x) * step(0.1, f.y));\n } else if (mB == 1) {\n float pu = h.x * 7.0;\n col = vec3(0.56, 0.38, 0.22) * (0.82 + 0.3 * rHash(vec2(floor(pu), 1.0)));\n if (fract(pu) < 0.06) col *= 0.55;\n } else if (mB == 2) {\n col = vec3(0.93, 0.92, 0.88);\n } else if (mB == 3 || mB == 4) {\n col = h.y < -0.46 ? vec3(0.88, 0.86, 0.82) : wall;\n } else if (mB == 5) {\n col = vec3(0.50, 0.32, 0.17);\n } else if (mB == 6) {\n col = rPal(rHash(vec2(seed, 5.0)));\n } else if (mB == 7) {\n col = vec3(0.93, 0.93, 0.90);\n } else if (mB == 8) {\n col = nB.x < -0.5 ? rBooks(h, D, seed) : vec3(0.50, 0.32, 0.17);\n } else if (mB == 9) {\n col = rPal(rHash(vec2(seed, 13.0))) * (0.72 + 0.28 * abs(fract(h.x * 11.0) - 0.5) * 2.0);\n }\n\n // Door in the middle of the back wall (every room has one)\n if (mB == 4) {\n if (V == 3) { // double doors with small windows\n if (abs(h.x) < 0.26 && h.y < 0.2) {\n float dx = (h.x + 0.26) / 0.52, dy = (h.y + 0.5) / 0.70;\n float lx = fract(dx * 2.0);\n col = vec3(0.82, 0.80, 0.76);\n if (abs(dx - 0.5) < 0.012 || lx < 0.02 || lx > 0.98) col = vec3(0.25, 0.22, 0.2);\n else if (dy < 0.45 && lx > 0.14 && lx < 0.86 && dy > 0.06) col *= 0.88;\n if (lx > 0.14 && lx < 0.86 && dy > 0.52 && dy < 0.92) {\n vec2 q = vec2((lx - 0.14) / 0.72, (dy - 0.52) / 0.4) * 2.0;\n vec2 gq = fract(q);\n if (gq.x > 0.1 && gq.x < 0.9 && gq.y > 0.1 && gq.y < 0.9) { col = vec3(0.65, 0.82, 0.98); emit = 1.0; }\n }\n if (length(vec2(abs(dx - 0.5) - 0.04, dy - 0.42)) < 0.025) col = vec3(0.85, 0.70, 0.20);\n }\n } else if (abs(h.x) < 0.14 && h.y < 0.14) {\n float lx = (h.x + 0.14) / 0.28, ly = (h.y + 0.5) / 0.64;\n col = vec3(0.45, 0.28, 0.14);\n bool pan = lx > 0.18 && lx < 0.82 && ((ly > 0.1 && ly < 0.45) || (ly > 0.55 && ly < 0.9));\n if (pan) col *= 0.82;\n if (lx < 0.05 || lx > 0.95 || ly > 0.96) col = vec3(0.9, 0.88, 0.84);\n if (length(vec2(lx - 0.85, ly - 0.48)) < 0.045) col = vec3(0.85, 0.70, 0.20);\n }\n }\n\n float lit = 0.55 + 0.45 * max(dot(normalize(nB), vec3(0.2494, 0.798, 0.5486)), 0.0);\n lit *= 1.0 - 0.35 * smoothstep(0.0, 2.0, tB);\n col = emit > 0.5 ? col * 1.1 : col * lit;\n col = clamp(col, 0.0, 1.0);\n return col * col; // ~gamma 2.0, cheaper than pow()\n }\n\n // Window frame around the room\n vec3 interiorWindow(vec3 pd, vec3 d, float variant, float D, vec3 wall, float seed) {\n if (max(abs(pd.x), abs(pd.y)) > 0.46) return wall * wall * 0.09;\n return interiorRoom(pd, d, variant, D, wall, seed);\n }\n";
|
|
2
|
+
export declare const DECAL_GLSL = "\n // Sampling happens inside a loop with break / continue, so ask for level 0 explicitly where the GLSL version allows it\n #if __VERSION__ >= 300\n #define DECAL_SAMPLE(s, uv) textureLod(s, uv, 0.0)\n #else\n #define DECAL_SAMPLE(s, uv) texture2D(s, uv)\n #endif\n uniform sampler2D uDecalData;\n uniform sampler2D uDecalAtlas;\n uniform float uDecalCount;\n uniform float uDecalBoostDist;\n uniform vec4 uDecalBounds[64]; // bounding sphere per decal: centre xyz, radius\n uniform vec3 uLocalCam; // camera in the object's local space (interior rays)\n varying vec3 vLocalNormal;\n float gDecalGlow = 0.0; // interior windows read as lit from inside; the fleck material adds this as emission\n \n // ---- Interior rooms: a box behind a flat window, ray-traced in decal space ----\n // Window = x, y in [-0.5, 0.5] on the z = 0 plane; the room runs from z = 0 down to z = -D.\n float rHash(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * 0.1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n vec3 rPal(float h) { return 0.35 + 0.5 * cos(6.2831853 * (h + vec3(0.0, 0.33, 0.67))); }\n\n // Nearest-hit box test (material id, normal and distance are only written when this box is closer)\n void rBox(vec3 o, vec3 d, vec3 mn, vec3 mx, int mat, inout float tB, inout vec3 nB, inout int mB) {\n vec3 inv = 1.0 / d;\n vec3 t1 = (mn - o) * inv, t2 = (mx - o) * inv;\n vec3 tmn = min(t1, t2), tmx = max(t1, t2);\n float tN = max(max(tmn.x, tmn.y), tmn.z);\n float tF = min(min(tmx.x, tmx.y), tmx.z);\n if (tN < tF && tN > 0.0 && tN < tB) {\n tB = tN; mB = mat;\n nB = -sign(d) * step(vec3(tN - 1e-5), tmn);\n }\n }\n\n bool rAabb(vec3 o, vec3 d, vec3 mn, vec3 mx) {\n vec3 inv = 1.0 / d;\n vec3 t1 = (mn - o) * inv, t2 = (mx - o) * inv;\n vec3 a = min(t1, t2), b = max(t1, t2);\n float tF = min(min(b.x, b.y), b.z);\n return max(max(a.x, a.y), a.z) < tF && tF > 0.0;\n }\n\n // Bookcase face: shelf boards plus hashed book spines\n vec3 rBooks(vec3 h, float D, float seed) {\n float ry = (h.y + 0.5) / 0.23;\n if (ry > 4.0) return vec3(0.34, 0.21, 0.11);\n float ri = floor(ry), fy = fract(ry);\n if (fy < 0.07) return vec3(0.34, 0.21, 0.11);\n float s = (-h.z / D) * 26.0;\n float bi = floor(s), fx = fract(s);\n float r1 = rHash(vec2(bi, ri + seed * 3.1));\n float r2 = rHash(vec2(bi + 41.0, ri + seed));\n if (fy > 0.07 + (0.55 + 0.4 * r1) * 0.88) return vec3(0.16, 0.10, 0.06);\n if (fx < 0.08) return vec3(0.10, 0.08, 0.06);\n return rPal(r2) * (0.8 + 0.3 * fract(r1 * 7.0));\n }\n\n // pd: surface point in decal space (flip already applied), d: unit view direction in decal space (z < 0 = into the wall)\n // room ids: 0 bed, 1 books, 2 table + chairs, 3 double doors with small windows, 4 grid\n // returns linear colour\n vec3 interiorRoom(vec3 pd, vec3 d, float variant, float D, vec3 wall, float seed) {\n if (abs(d.x) < 1e-4) d.x = d.x < 0.0 ? -1e-4 : 1e-4;\n if (abs(d.y) < 1e-4) d.y = d.y < 0.0 ? -1e-4 : 1e-4;\n vec3 o = pd - d * (pd.z / d.z); // slide along the ray to the window plane\n o = vec3(clamp(o.xy, -0.499, 0.499), 0.0);\n int V = int(variant + 0.5);\n\n // Shell: floor (1), ceiling (2), side walls (3), back wall (4)\n float tx = ((d.x > 0.0 ? 0.5 : -0.5) - o.x) / d.x;\n float ty = ((d.y > 0.0 ? 0.5 : -0.5) - o.y) / d.y;\n float tz = -D / d.z;\n float tB; vec3 nB; int mB;\n if (tz <= tx && tz <= ty) { tB = tz; nB = vec3(0.0, 0.0, 1.0); mB = 4; }\n else if (tx <= ty) { tB = tx; nB = vec3(-sign(d.x), 0.0, 0.0); mB = 3; }\n else { tB = ty; nB = vec3(0.0, -sign(d.y), 0.0); mB = d.y > 0.0 ? 2 : 1; }\n\n // Contents (materials: 5 wood, 6 accent cloth, 7 linen, 8 bookcase)\n if (V == 0 && rAabb(o, d, vec3(-0.49, -0.50, -D), vec3(-0.17, -0.10, -D * 0.40))) { // bed against the left wall\n float zA = -D * 0.97, zF = -D * 0.40;\n rBox(o, d, vec3(-0.48, -0.50, zA), vec3(-0.18, -0.38, zF), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.47, -0.38, zA), vec3(-0.19, -0.30, zF), 7, tB, nB, mB);\n rBox(o, d, vec3(-0.475, -0.38, -D * 0.72), vec3(-0.185, -0.285, zF), 6, tB, nB, mB);\n rBox(o, d, vec3(-0.44, -0.30, zA), vec3(-0.22, -0.235, -D * 0.86), 7, tB, nB, mB);\n rBox(o, d, vec3(-0.49, -0.50, -D * 0.995), vec3(-0.17, -0.10, zA), 5, tB, nB, mB);\n } else if (V == 1) { // bookcase along the right wall\n rBox(o, d, vec3(0.36, -0.50, -D * 0.92), vec3(0.50, 0.42, -D * 0.12), 8, tB, nB, mB);\n } else if (V == 2 && rAabb(o, d, vec3(-0.42, -0.50, -D * 0.72), vec3(0.42, -0.08, -D * 0.30))) { // table + two chairs\n rBox(o, d, vec3(-0.24, -0.22, -D * 0.72), vec3(0.24, -0.17, -D * 0.30), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.235, -0.50, -D * 0.70), vec3(-0.195, -0.22, -D * 0.66), 5, tB, nB, mB);\n rBox(o, d, vec3(0.195, -0.50, -D * 0.70), vec3(0.235, -0.22, -D * 0.66), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.235, -0.50, -D * 0.36), vec3(-0.195, -0.22, -D * 0.32), 5, tB, nB, mB);\n rBox(o, d, vec3(0.195, -0.50, -D * 0.36), vec3(0.235, -0.22, -D * 0.32), 5, tB, nB, mB);\n rBox(o, d, vec3(-0.40, -0.36, -D * 0.58), vec3(-0.28, -0.31, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(-0.41, -0.31, -D * 0.58), vec3(-0.39, -0.08, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(-0.36, -0.50, -D * 0.53), vec3(-0.32, -0.36, -D * 0.49), 5, tB, nB, mB);\n rBox(o, d, vec3(0.28, -0.36, -D * 0.58), vec3(0.40, -0.31, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(0.39, -0.31, -D * 0.58), vec3(0.41, -0.08, -D * 0.44), 6, tB, nB, mB);\n rBox(o, d, vec3(0.32, -0.50, -D * 0.53), vec3(0.36, -0.36, -D * 0.49), 5, tB, nB, mB);\n }\n\n // Open curtains just inside the window (9), hung from a rod\n float tc = -0.05 / d.z;\n if (tc < tB) {\n vec3 pc = o + d * tc;\n float edge = 0.28 + 0.08 * clamp(abs(pc.y + 0.05) * 2.0, 0.0, 1.0); // tied back at mid height\n if (pc.y > 0.465) { tB = tc; nB = vec3(0.0, 0.0, 1.0); mB = 5; }\n else if (abs(pc.x) > edge && pc.y > -0.46) { tB = tc; nB = vec3(0.0, 0.0, 1.0); mB = 9; }\n }\n\n // Surface colour at the hit\n vec3 h = o + d * tB;\n vec3 col = vec3(0.5);\n float emit = 0.0;\n if (V == 4 && mB <= 4) { // grid room: tiled walls with dark gaps\n vec2 g = mB <= 2 ? vec2(h.x + 0.5, -h.z / D) : (mB == 3 ? vec2(-h.z / D, h.y + 0.5) : vec2(h.x + 0.5, h.y + 0.5));\n vec2 f = fract(g * 4.0);\n col = wall * mix(0.12, 1.0, step(0.1, f.x) * step(0.1, f.y));\n } else if (mB == 1) {\n float pu = h.x * 7.0;\n col = vec3(0.56, 0.38, 0.22) * (0.82 + 0.3 * rHash(vec2(floor(pu), 1.0)));\n if (fract(pu) < 0.06) col *= 0.55;\n } else if (mB == 2) {\n col = vec3(0.93, 0.92, 0.88);\n } else if (mB == 3 || mB == 4) {\n col = h.y < -0.46 ? vec3(0.88, 0.86, 0.82) : wall;\n } else if (mB == 5) {\n col = vec3(0.50, 0.32, 0.17);\n } else if (mB == 6) {\n col = rPal(rHash(vec2(seed, 5.0)));\n } else if (mB == 7) {\n col = vec3(0.93, 0.93, 0.90);\n } else if (mB == 8) {\n col = nB.x < -0.5 ? rBooks(h, D, seed) : vec3(0.50, 0.32, 0.17);\n } else if (mB == 9) {\n col = rPal(rHash(vec2(seed, 13.0))) * (0.72 + 0.28 * abs(fract(h.x * 11.0) - 0.5) * 2.0);\n }\n\n // Door in the middle of the back wall (every room has one)\n if (mB == 4) {\n if (V == 3) { // double doors with small windows\n if (abs(h.x) < 0.26 && h.y < 0.2) {\n float dx = (h.x + 0.26) / 0.52, dy = (h.y + 0.5) / 0.70;\n float lx = fract(dx * 2.0);\n col = vec3(0.82, 0.80, 0.76);\n if (abs(dx - 0.5) < 0.012 || lx < 0.02 || lx > 0.98) col = vec3(0.25, 0.22, 0.2);\n else if (dy < 0.45 && lx > 0.14 && lx < 0.86 && dy > 0.06) col *= 0.88;\n if (lx > 0.14 && lx < 0.86 && dy > 0.52 && dy < 0.92) {\n vec2 q = vec2((lx - 0.14) / 0.72, (dy - 0.52) / 0.4) * 2.0;\n vec2 gq = fract(q);\n if (gq.x > 0.1 && gq.x < 0.9 && gq.y > 0.1 && gq.y < 0.9) { col = vec3(0.65, 0.82, 0.98); emit = 1.0; }\n }\n if (length(vec2(abs(dx - 0.5) - 0.04, dy - 0.42)) < 0.025) col = vec3(0.85, 0.70, 0.20);\n }\n } else if (abs(h.x) < 0.14 && h.y < 0.14) {\n float lx = (h.x + 0.14) / 0.28, ly = (h.y + 0.5) / 0.64;\n col = vec3(0.45, 0.28, 0.14);\n bool pan = lx > 0.18 && lx < 0.82 && ((ly > 0.1 && ly < 0.45) || (ly > 0.55 && ly < 0.9));\n if (pan) col *= 0.82;\n if (lx < 0.05 || lx > 0.95 || ly > 0.96) col = vec3(0.9, 0.88, 0.84);\n if (length(vec2(lx - 0.85, ly - 0.48)) < 0.045) col = vec3(0.85, 0.70, 0.20);\n }\n }\n\n float lit = 0.55 + 0.45 * max(dot(normalize(nB), vec3(0.2494, 0.798, 0.5486)), 0.0);\n lit *= 1.0 - 0.35 * smoothstep(0.0, 2.0, tB);\n col = emit > 0.5 ? col * 1.1 : col * lit;\n col = clamp(col, 0.0, 1.0);\n return col * col; // ~gamma 2.0, cheaper than pow()\n }\n\n // Window frame around the room\n vec3 interiorWindow(vec3 pd, vec3 d, float variant, float D, vec3 wall, float seed) {\n if (max(abs(pd.x), abs(pd.y)) > 0.46) return wall * wall * 0.09;\n return interiorRoom(pd, d, variant, D, wall, seed);\n }\n\n\n vec4 decalTexel(float i, float k) {\n return DECAL_SAMPLE(uDecalData, vec2((k + 0.5) / 6.0, (i + 0.5) / 64.0));\n }\n\n // Returns straight-alpha colour (rgb) and coverage (a) of every decal at a bind-pose point\n vec4 evalDecals(vec3 p, vec3 n) {\n vec3 accRGB = vec3(0.0);\n float accA = 0.0;\n for (int i = 0; i < 64; i++) {\n float fi = float(i);\n if (fi >= uDecalCount) break;\n vec4 bs = uDecalBounds[i];\n if (dot(p - bs.xyz, p - bs.xyz) > bs.w * bs.w) continue;\n vec4 r0 = decalTexel(fi, 0.0);\n vec4 r1 = decalTexel(fi, 1.0);\n vec4 r2 = decalTexel(fi, 2.0);\n vec3 pd = vec3(dot(r0.xyz, p) + r0.w, dot(r1.xyz, p) + r1.w, dot(r2.xyz, p) + r2.w);\n if (abs(pd.x) > 0.5 || abs(pd.y) > 0.5 || abs(pd.z) > 0.35) continue;\n\n // Fade out where the surface turns away from the projection direction\n vec3 nd = vec3(dot(r0.xyz, n), dot(r1.xyz, n), dot(r2.xyz, n));\n float facing = smoothstep(0.25, 0.6, nd.z / max(length(nd), 1e-4));\n if (facing <= 0.0) continue;\n\n vec4 pm = decalTexel(fi, 3.0); // atlas col, atlas row, flip, tintable\n vec4 tn = decalTexel(fi, 4.0); // tint rgb, opacity\n vec4 ex = decalTexel(fi, 5.0); // interior: 1, room id, depth, seed\n float k = facing * tn.a;\n vec3 pc;\n float a;\n if (ex.x > 0.5) {\n // Interior: view ray from the camera, expressed in decal space\n vec3 dl = normalize(p - uLocalCam);\n vec3 dd = vec3(dot(r0.xyz, dl), dot(r1.xyz, dl), dot(r2.xyz, dl));\n vec3 pdr = pd;\n if (pm.z > 0.5) { pdr.x = -pdr.x; dd.x = -dd.x; }\n dd = normalize(dd);\n if (dd.z > -0.04) continue; // grazing: the ray would run along the wall\n pc = interiorWindow(pdr, dd, ex.y, ex.z, tn.rgb, ex.w) * k;\n a = k;\n gDecalGlow = gDecalGlow * (1.0 - a) + 0.9 * a;\n } else {\n vec2 uv = pd.xy + 0.5;\n if (pm.z > 0.5) uv.x = 1.0 - uv.x;\n uv = clamp(uv, 0.002, 0.998);\n vec2 auv = vec2((pm.x + uv.x) / 8.0, 1.0 - (pm.y + 1.0 - uv.y) / 16.0);\n vec4 s = DECAL_SAMPLE(uDecalAtlas, auv); // premultiplied alpha\n\n if (uPixelOut > 0.5) {\n // PIXEL ART MODE: ink survives at any size. A line or a dot thinner than a pixel misses a single\n // centre sample, so the whole footprint of the pixel is searched (a 4 x 4 grid): any dark ink in it\n // makes the pixel solid ink; a highlight stays only where the pixel's centre is on it; anything else\n // is the centre colour, solid or gone (no half-covered blur).\n // past the line boost distance (a view preference), the search spreads up to twice the pixel's\n // area: far-away lines are still caught, and drawn bolder\n float camDist = length(p - uLocalCam);\n float grow = 1.0 + clamp((camDist - uDecalBoostDist) * 0.25, 0.0, 1.0);\n vec2 fx = dFdx(auv) * grow, fy = dFdy(auv) * grow;\n // the samples stay inside this decal's cell of the atlas (its neighbours' art is right next to it)\n vec2 cellLo = vec2(pm.x / 8.0, 1.0 - (pm.y + 1.0) / 16.0);\n vec2 cellHi = vec2((pm.x + 1.0) / 8.0, 1.0 - pm.y / 16.0);\n vec2 pad = vec2(0.002 / 8.0, 0.002 / 16.0);\n float minL = 1.0, inkA = 0.0;\n vec3 inkRGB = vec3(0.0);\n for (int gy = 0; gy < 4; gy++) {\n for (int gx = 0; gx < 4; gx++) {\n vec2 o = (vec2(float(gx), float(gy)) - 1.5) * 0.25;\n vec4 t = DECAL_SAMPLE(uDecalAtlas, clamp(auv + fx * o.x + fy * o.y, cellLo + pad, cellHi - pad));\n if (t.a < 0.35) continue;\n // judged as drawn: a tintable art (a mouth) is white in the atlas and tinted when drawn\n vec3 c = t.rgb / t.a;\n float l = dot(pm.w > 0.5 ? c * tn.rgb : c, vec3(0.299, 0.587, 0.114));\n if (l < minL) { minL = l; inkRGB = c; inkA = t.a; }\n }\n }\n float lC = s.a > 0.01 ? dot(pm.w > 0.5 ? s.rgb / s.a * tn.rgb : s.rgb / s.a, vec3(0.299, 0.587, 0.114)) : 0.5;\n if (s.a > 0.35 && lC > 0.8) {\n s = vec4(1.0); // the centre is on a highlight: keep it\n } else if (minL < 0.22 && inkA > 0.0) {\n s = vec4(inkRGB, 1.0); // dark ink anywhere in the pixel: solid ink\n } else if (s.a > 0.35) {\n s = vec4(s.rgb / s.a, 1.0); // the centre's colour, solid\n } else {\n s = vec4(0.0); // a colour fill only touching the pixel's edge\n }\n } else {\n // NORMAL 3D MODE: Distance boost\n float camDist = length(p - uLocalCam);\n if (camDist > uDecalBoostDist && s.a > 0.01) {\n float intensity = max(s.r, max(s.g, s.b)) / s.a;\n float isDark = 1.0 - smoothstep(0.0, 0.25, intensity);\n float boost = 1.0 + isDark * clamp((camDist - uDecalBoostDist) * 0.5, 0.0, 8.0);\n s.rgb = clamp(s.rgb * boost, 0.0, 1.0);\n s.a = clamp(s.a * boost, 0.0, 1.0);\n }\n }\n\n pc = (pm.w > 0.5 ? s.rgb * tn.rgb : s.rgb) * k;\n a = s.a * k;\n gDecalGlow *= (1.0 - a);\n }\n accRGB = pc + accRGB * (1.0 - a);\n accA = a + accA * (1.0 - a);\n }\n return vec4(accRGB / max(accA, 1e-4), accA);\n }\n";
|