@@ -9,8 +9,10 @@ visual layer — no D3D, no SwapChainPanel, no shaders.
99> * ([ Wiktionary] ( https://en.wiktionary.org/wiki/combobulate ) )*
1010
1111Each quad becomes a ` SpriteVisual ` placed in 3D by a perspective
12- ` TransformMatrix ` , with back-face culling and a topology-aware painter's
13- algorithm to get the draw order right without a depth buffer.
12+ ` TransformMatrix ` . Back-face culling and a polygon sort keep the draw
13+ order right without a depth buffer, and a fully analytical * baked aspect
14+ graph* renderer can sustain GPU-driven animation with ** zero CPU work
15+ per frame** .
1416
1517[ composition ] : https://learn.microsoft.com/windows/uwp/composition/visual-layer
1618
@@ -38,27 +40,90 @@ samples/
3840## Getting Started
3941
40421 . Add the ` Combobulate ` NuGet package to your UWP or WinUI 3 app.
41- 2 . Drop a ` .obj ` file into your app (e.g. ` Assets/book.obj ` , marked as
42- ` Content ` so it ships with the package).
43- 3 . Place a ` Combobulate ` control in your XAML and point ` Source ` at the file:
43+ 2 . Place a ` Combobulate ` control in your XAML:
4444
4545 ``` xml
4646 <Page xmlns : c =" using:Combobulate" >
47- <c : Combobulate Source =" ms-appx:///Assets/book.obj"
47+ <c : Combobulate x : Name =" Viewer"
48+ Source =" ms-appx:///Assets/book.obj"
4849 ModelScale =" 200"
4950 RotationX =" -30"
50- RotationY =" 40" />
51+ RotationY =" 40"
52+ RotationZ =" 0" />
5153 </Page >
5254 ```
5355
54- That's it — no code-behind required. The control parses the ` .obj ` on demand,
55- caches it process-wide, and auto-loads any ` mtllib ` referenced by the file
56- (textures resolved relative to the ` .obj ` ) .
56+ ` Source ` accepts an ` ms-appx:/// ` URI, an absolute file path, or an
57+ ` ObjCache ` key — geometry, materials (via sibling ` mtllib ` ), and texture
58+ surfaces are all loaded and cached process-wide .
5759
58- For everything else — loading from arbitrary paths or streams, supplying
59- custom textures per face, live-updating pixels, the full property reference,
60- the supported ` .obj ` / ` .mtl ` subset, and the caching model — see
61- [ ** docs/usage.md** ] ( docs/usage.md ) .
60+ 3 . Or parse an ` .obj ` yourself and assign the resulting model directly:
61+
62+ ``` csharp
63+ using Combobulate .Parsing ;
64+
65+ var text = await FileIO .ReadTextAsync (
66+ await StorageFile .GetFileFromPathAsync (@" C:\path\to\book.obj" ));
67+ var result = ObjParser .Parse (text );
68+ Viewer .Model = result .Model ; // partial model on parse error
69+ foreach (var err in result .Errors ) // optional: inspect parse diagnostics
70+ System .Diagnostics .Debug .WriteLine (err );
71+ ```
72+
73+ That's it — the control rebuilds its visual tree whenever any of its
74+ inputs change.
75+
76+ ### Highlights
77+
78+ - ** Materials.** Auto-loaded from ` mtllib ` or supplied via ` ObjMaterialPack ` ,
79+ with live texture updates from ` SoftwareBitmap ` or streams.
80+ - ** Three sort algorithms.** ` Bsp ` (default, exact, O(n)), ` Newell `
81+ (split-on-cycle, deformable-friendly), and ` Topological ` (legacy, fast).
82+ - ** Composition-driven rotation.** ` SetExternalRotation(ExpressionAnimation) `
83+ binds rotation directly to the compositor; pair with ` EnableAutoRefresh `
84+ to keep cull and sort in lock-step with the compositor clock.
85+ - ** Baked aspect graph.** Pre-computes every painter-order breakpoint
86+ along an animation axis and emits one ` ContainerVisual ` per cell, each
87+ gated by an opacity expression on a live scalar. Smooth GPU spin
88+ without per-frame CPU cost. See
89+ [ docs/rendering-pipeline.md] ( docs/rendering-pipeline.md ) .
90+
91+ For everything beyond "drop a control, point ` Source ` at a file" see the
92+ ** [ usage guide] ( docs/usage.md ) ** and the
93+ ** [ rendering pipeline] ( docs/rendering-pipeline.md ) ** doc.
94+
95+ ### Supported ` .obj ` subset
96+
97+ - ` v x y z [w] ` — vertex positions
98+ - ` vt u v [w] ` — texture coordinates
99+ - ` vn x y z ` — vertex normals (parsed; not used for shading today)
100+ - ` f a b c d ` — ** quad** faces; ` a/ta/na ` style references accepted
101+ - ` usemtl <name> ` , ` mtllib <file> ` — material binding and library load
102+ - ` o ` , ` g ` , ` s ` — preserved; ` l ` , ` p ` , ` vp ` , curves/surfaces are ignored
103+
104+ Faces must be ** quads** (triangles and n-gons are reported as parse errors).
105+ Wind each face so that ` (V1 - V0) × (V3 - V0) ` points outward — that's the
106+ direction the renderer treats as front-facing for back-face culling.
107+
108+ See [ ` samples/book.obj ` ] ( samples/book.obj ) for a worked example.
109+
110+ ### Control properties at a glance
111+
112+ | Property | Type | Default | Notes |
113+ | --- | --- | --- | --- |
114+ | ` Source ` | ` string? ` | ` null ` | Path, ` ms-appx:/// ` URI, or ` ObjCache ` key |
115+ | ` Model ` | ` ObjModel? ` | ` null ` | Direct model assignment |
116+ | ` Materials ` | ` ObjMaterialPack? ` | ` null ` | Overrides any auto-loaded ` mtllib ` |
117+ | ` MaterialMode ` | ` MaterialMode ` | ` Auto ` | ` Auto ` / ` UseDiffuse ` / ` UseFallback ` |
118+ | ` ModelScale ` | ` double ` | ` 100 ` | Pixels per model unit |
119+ | ` EnablePerspective ` | ` bool ` | ` true ` | Apply perspective ` M34 ` to the root |
120+ | ` PerspectiveDistance ` | ` double ` | ` 0 ` | Focal distance in px (0 = host width) |
121+ | ` RotationX/Y/Z ` | ` double ` | ` 0 ` | Euler angles in degrees |
122+ | ` SortAlgorithm ` | ` SortAlgorithm ` | ` Bsp ` | ` Bsp ` / ` Newell ` / ` Topological ` |
123+ | ` CullMarginDegrees ` | ` double ` | ` 0 ` | Widen back-face cull cone for GPU lag |
124+ | ` RenderingMode ` | ` RenderingMode ` | ` SpritePainter ` | ` SpritePainter ` / ` BakedAspectGraph ` |
125+
126+ Full descriptions and examples are in the [ usage guide] ( docs/usage.md ) .
62127
63128## Releasing
64129
0 commit comments