Skip to content

Releases: tingham/Mobster

Mobster 0.2.0

Choose a tag to compare

@tingham tingham released this 17 Sep 15:20
d7468cf

Guides can be meshes. A construction is rendered and its paths are extracted from what was rendered, rather than plotted analytically in Swift — so a new guide can be an asset instead of a cut.

let guide = Guide(frame: frame)
try guide.initialize(source: .mesh(figure.mesh(in: frame), device: device),
                     frame: frame, adhesion: 0.4, duration: 1,
                     settleEpsilon: 1, budget: budget)
let moved = guide.evaluate(lines, at: t)

The mesh source

Rendered opaque with depth into an offscreen target where every fragment carries the identity of its component. Boundaries are where adjacent identities differ. Two things fall out:

Occlusion is free — the far arm loses the depth test, and there is no hidden line removal to write.

Interior seams come for nothing — where an upper arm's identity meets a forearm's is a boundary though it sits nowhere near the silhouette, and that seam is the construction line. A guide from silhouette alone is an outline; from identities it is a construction.

Identity marks structure rather than tessellation: a cube's six faces are six identities, a cylinder of eight facets is one, and subdivision never multiplies them. A component divided at its middle places a cross section, so a limb's mid slice and its joint seam are the same mechanism. Every meeting of a pair of components is its own path; only a run shorter than three fragments is dropped.

Whiplash fits and decimates — the first dependency, stateless as this is.

Perspective

A field of view opening at sixty degrees, the cone of vision a drawing stays inside before it reads as distorted. Viewing distance is derived from the field and the construction's bounds, so the field is the only dial and the construction always fits.

Presets

Cube — the box a figure or object is built inside. Positioned, sized, turned.

Head — the Loomis construction as a mesh, pointing at a target rather than taking a view angle, with roll, and its tilt held within forty five degrees of level so a basis can always be derived.

Figure — renamed from Ashcan. Proportion from Loomis 1943, measured off the plates rather than recalled. Two bone inverse kinematics from four targets; elbows back and knees forward anatomically rather than by control. Hands, feet, head break lines, and five named poses.

Grid joins Golden Ratio, Thirds, Columns, Rows and Ruler.

The plot mode is gone

How a preset answers a Frame is a property of what that preset is, so the consumer is not asked. Frame relative presets take the Frame as their design rectangle, Golden Ratio covers it, Head and Figure fit inside it with their proportions intact.

What is not here

Torso and pelvis depth could not be sourced — Loomis prints front views, so every width in that canon was measured and no depth was. Both are circular in section, which overstates a real pelvis by roughly forty percent. It is the only construction in the figure adding no sourced number, and a wrong canon would have been worse than an absent one.

Verification

311 tests. Six reconciliations and a documentation audit in Documentation/Reviews/.

Mobster 0.1.0

Choose a tag to compare

@tingham tingham released this 08 Sep 00:33
a669c15

A Guide is now a stateless evaluator. This replaces the surface 0.0.1 documented.

let guide = Guide(frame: frame)
try guide.initialize(source: .preset(GridPreset(count: 4, gutter: 0.05)),
                     frame: frame, adhesion: 0.4, duration: 1,
                     settleEpsilon: 1, budget: budget)
let moved = guide.evaluate(lines, at: t)

Mobster evaluates between two frames. Carrying positions across successive sets of targets is the consuming application's work.

Changed

Vert and Line replace Sample and Stroke. A vert carries a location, an optional identifier, and optional mass, drag and coupling. A line carries verts and an identifier and holds no behaviour of its own.

Tokens, membership, settlement listeners and the skip take lifecycle are gone. All existed because a Guide tracked points between frames.

Resolution is derived rather than supplied, from the Frame and the settle epsilon, because a read snaps to the containing texel and a texel larger than the epsilon carries more error than the tolerance being settled within. Where the derived resolution outruns the budget, initialize refuses and reports an epsilon that would fit.

Adhesion is a control between zero and one. The consumer never sees a reach.

The verts supplied are the anchors. A consumer holding undisplaced content receives a stable result where a vert far from every path settles short and stays short. One feeding a result back has declared a new anchor and asked for a further displacement.

Physics. Mass is an exponent on progress. Drag runs downward from one: one is the plain travel, zero holds back across the whole run, minus one carries a vert away before it returns. Coupling advances a vert's neighbours along their own travel, signed, decaying per hop so reach needs no parameter. Every vert is home at the duration regardless of any of it.

Grid preset joins Golden Ratio, Thirds, Columns, Rows, Ruler and Curve.

Not here

Source layer interpretation, which moved to OneBrush. Mobster takes paths or a preset.

Decimation and smoothing. The field is exact whatever the vertex count, so detail below what it can resolve is wasted work rather than a wrong answer, and the refusal guards the cost.

Shared displacement, where a line preserves its shape. Time offsets cannot produce it, and whether it is wanted is a judgement to be made from the harness.

What a guide costs

The field is a grid and the bake costs grid squares times guide segments. A finer epsilon means more squares, more verts mean more segments, and the two multiply. There is no single vert limit: a few hundred at a fine epsilon, thousands at a coarse one. The bake happens once, at initialize.

The promise not yet made

Two integration modes persist a relationship rather than positions, so they recompute displacement on every document open. Determinism holds within a build, verified bit exact across separate processes. Two builds agreeing is a separate promise and nothing makes it.

Verification

208 tests. Five reconciliations in Documentation/Reviews/. The cuts since the revamp began have not been reconciled.

Mobster 0.0.1

Choose a tag to compare

@tingham tingham released this 06 Sep 08:04
2318d43

First cut of the package, ready for integration.

Sources of guide geometry

Presets work. Six region frame responsive prototypes: Golden Ratio with quadlines and a selectable focus corner, Thirds, Columns, Rows, Ruler, Curve.

Direct paths work. update(paths:resolution:time:) takes geometry the caller has already prepared.

Source layers do not. path.interpret, path.decimate and path.complexity.cap have no implementation. A caller can hand raw stroke positions in as paths and it will run, silently skipping the decimation, curvature reinterpretation and complexity cap that Mobster is meant to own. Integration mode three in Documentation/Integration.md is defined by a source layer and is not available.

What is here

Boundary. No document model declared or imported. Identity crosses as an opaque unsigned integer, never dereferenced and never minted. The target side takes strokes carrying points with identifiers.

Field. Stores the nearest path location per texel rather than a distance, so direction is a subtraction and never a derivative of a sampled field. Exact, verified against a brute force reference across every preset, exterior geometry and placed Frames.

Guide. Tokens over a membership, targets through an inverse distance squared falloff, absolute time playback, dirty rectangles in scene coordinates, settlement on entering the settled condition.

Fixture and harness. A seeded population in its own target, because it mints identifiers and the library must not. A macOS harness drawing the field, guides, points and motion, with a slider for every magnitude.

Also missing

The adherence dial. guide.adherence.curve maps a zero to one control onto a reach and is unimplemented; the harness drives the reach raw in scene units.

The promise not yet made

Integration modes three and four persist a relationship rather than positions, so they recompute displacement on every document open. Determinism holds within a build, verified bit exact across separate processes. Two builds agreeing is a separate promise and nothing makes it. That is cheap to address before those modes ship and expensive afterward.

Verification

171 tests. Five reconciliations in Documentation/Reviews/. They found a preset wrong across three quarters of the field, a tie break resolved by loop order, a crash on a degenerate Frame, an incremental clock that broke scrubbing, and several requirements naming magnitudes no test could observe. The motion and guide correction cuts are not yet reconciled.