Skip to content

uo-content: weapon-bone parts, weapon_motion, bow_draw and cloth_sim options - #38

Open
wverri wants to merge 2 commits into
DatMoshu:mainfrom
wverri:pr/uo-content-cloth-weapon-options
Open

wverri wants to merge 2 commits into
DatMoshu:mainfrom
wverri:pr/uo-content-cloth-weapon-options

Conversation

@wverri

@wverri wverri commented Oct 28, 2026

Copy link
Copy Markdown

Stacked on #37 (vendor update to UO_Model3D b212cee): this branch includes that commit. Review only the last commit, b344d81. cloth_sim needs the pin fix from #37; the other options also work on e9544f6.

Change

New optional tools/uo-content build settings, which we used to build custom UO equipment:

  • Weapon parts weapon1h, axe2h, polearm. They bind the item to the canonical body's weapon bones weapon1h.R, axe2h.L and polearm.L (backend uo_bind_item.py), so the item follows the class motion calibrated on the original weapons. The existing weapon part stays rigid in hand.R. The new parts get BODY_GAP 0, a starter blade and an auto-fit size (without these, starter() and the auto fit raised KeyError for any part outside the old four), plus equipment templates and layers, the studio picker and the Fit Lab poke rule.
  • weapon_motion {bone: entry} replaces one weapon bone's calibration for a single build and re-keys the weapon bones before the bind. Example: a bow.L class fitted on bows alone. The stock class is fitted on bows and crossbows together and turns a bow flat at the release of attack_bow.
  • bow_draw bends a bow during the draw. The item brings shape keys draw and string_x/y/z. The build keys the draw weight and the nock-to-hand offset per action frame on the rig, and drivers move the keys, so the limbs bend and the string follows the fingers. The optional orient turns the bow toward the drawing hand. import_asset keeps the asset's shape keys when bow_draw is on.
  • cloth_sim (robe, skirt) runs the backend uo_cloth_sim.py on the saved item.blend in a separate Blender (cloth_sim_run.py, because uo_cloth_sim expects bpy as a module), and the renderer adds cloth_sim.npz to the leg push. Meshes whose modifiers change the vertex count are refused up front with the reason. The procedural template's Solidify used to fail deep inside Blender with Array length mismatch.

pipeline.py validates every new field. All of this is documented in tools/uo-content/README.md.

Verification

  • New tests/unit/test_uo_content_spec.py (24 cases: parts, accepted and rejected cloth_sim / weapon_motion / bow_draw / orient). Full pytest tests: 245 passed, 2 skipped. The 2 failures are the Windows-path tests that also fail on main under macOS.

  • node --test tools/fit-lab/web/*.test.mjs: 11/11.

  • tools/uo-content/test_content.py: 8/9. test_partial_import_refused fails the same way on main.

  • Real Blender 4.5 LTS preview builds on macOS:

    • weapon1h from a prompt (no asset) builds and binds rigid on weapon1h.R. Before, this raised KeyError.
    • A synthetic bow with bow_draw weights [0,.4,.8,1,1,.3,0] on action 18: the shape keys follow the weights per frame (draw 0 → 0.4 → 0.8 → 1 → 1 → 0.3 → 0), with the string offset tracking the hand, and the bow turns in the 3 orient frames.
    • A robe GLB with cloth_sim {"arm_goal": -1, "thick": 0.005, "in_max": -1}: 2 actions simulated in 40 s and the sheet renders. The template robe with cloth_sim is refused with a clear ValueError.
  • These options shipped in our production items (two bows, a crossbow, a robe, 1H/2H weapons) before this PR. The bow shape keys were renamed to English here.

  • Tests pass; behavior changes have meaningful coverage.

  • No UO data, commercial assets, private mappings, credentials or local paths included.

  • Any media has redistribution permission and recorded provenance.

  • Blender/render changes were checked with actual renders, or remaining verification is stated.

Risks and remaining work

  • cloth_sim adds about a minute to a preview and runs --jobs 1 only, because inside Blender sys.executable is not Blender.
  • weapon_motion entries are checked for shape (parent, pivot, dir, poses), not for sensible values.
  • The full 35-action build was not re-run on this exact commit for every new part.

Vendor Levy's repo at b212cee (was e9544f6; through b2d22af and 9db841d), stripped
as before: the .blend re-saved by strip_originals.py with Blender 4.2 (no original
atlas, uo_exact 0), no .vd, .npz, .pkl, body13, test_data or the pipeline/ copy of
the original atlas.

- uo_cloth_sim.py drives the pin with animated shape keys (the frame handler left
  it on the first pose), gains fabric presets and imports bpy_compat.py, which
  pipeline.py setup now copies and the render fingerprint includes.
- render_uo_layer.py: adaptive item render, optional robe shading options.
- Pose keys re-fitted for natural motion, mounted head/neck yaw (9db841d).
- Upstream made README.md the English README and README_PL.md the Polish one;
  setup checks README.md.
…options

Weapon parts weapon1h, axe2h and polearm bind the item to the canonical body's
weapon bones (weapon1h.R, axe2h.L, polearm.L) instead of rigid in hand.R like
"weapon", so the item follows the class motion calibrated on the original
weapons. They get no push-out (BODY_GAP 0), a starter blade and an auto-fit
size, equipment templates/layers, the studio picker and the Fit Lab poke rule.

weapon_motion replaces the calibration of a weapon bone for one build and
re-keys the weapon bones before the bind (e.g. a bow.L class fitted on bows
alone: the stock one, fitted on bows and crossbows together, turns a bow flat
at the release of attack_bow).

bow_draw bends a bow in the draw: the item brings the shape keys draw and
string_x/y/z; the build keys the draw weight and the nock-to-hand offset per
action frame on the rig and drives the keys from them, and can turn the bow
about its axis toward the drawing hand ("orient"). import_asset keeps the
asset's shape keys when bow_draw is on.

cloth_sim (robe, skirt) runs uo_cloth_sim.py on the saved item.blend in a
separate Blender (cloth_sim_run.py) and the renderer adds cloth_sim.npz to the
leg push. It refuses meshes whose modifiers change the vertex count (the
procedural template's Solidify), which otherwise fail inside Blender.

pipeline.py validates the new fields; tests/unit/test_uo_content_spec.py
covers them.
@wverri
wverri requested a review from DatMoshu as a code owner October 28, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant