geometry library

CPU-side geometry: vertex layouts, mesh data, shape generators and the ray arithmetic that reads them.

A library of flutter3d_core, importable on its own. A modeller's editable mesh, the tool an agent speaks to and a bench compiled by dart compile exe all want to say MeshData without the renderer, and a caller that imports only this library gets only this library. It was flutter3d_geometry until the package boundary turned out to protect nothing a library does not.

DeviceMesh is not here. It is the rest of the geometry layer by subject matter, but it holds the one type that has met a device, so it lives with the renderer (src/engine/geometry/device_mesh.dart) and flutter3d_core.dart exports both.

Classes

CapsuleShape
Capsule: a cylinder of height closed by two hemispheres of radius.
ConeShape
Cone with the apex at +Y: a cylinder whose top radius is zero.
CpuMesh
A mesh that lives only on the CPU.
CuboidShape
Axis-aligned box centred on the origin.
CylinderShape
Cylinder or truncated cone, centred on the origin, axis along Y.
DerivedShape
A shape defined by delegating to another one.
DiscShape
Flat annulus in the XZ plane facing +Y. An innerRadius of 0 gives a disc.
LatheShape
A surface of revolution: a profile polyline swept around the Y axis.
MeshBuilder
Accumulates vertices and indices into growing typed arrays.
MeshData
CPU-side geometry: interleaved vertices plus indices.
MeshGeometry
What the scene needs to know about a mesh, without knowing where it lives.
MorphBlend
Blends a mesh's morph targets into a copy of its vertices.
MorphTarget
One shape a mesh can be blended towards, as deltas from its base vertices.
MorphTexture
A mesh's morph deltas, packed the way lib/morph.glsl reads them.
PackedIndices
Indices packed for GPU upload.
PlaneShape
Subdivided plane in the XZ plane, normal pointing at +Y.
Ray
A ray: an origin and a direction.
Shape
A parameterized generator of geometry.
SphereShape
UV sphere, a revolved meridian arc.
TorusShape
Torus: a closed circular profile revolved around Y.
TriangleBvh
A bounding-volume hierarchy over the triangles of one mesh.
VertexAttribute
Describes a single vertex attribute.
VertexLayout
An ordered set of attributes making up an interleaved vertex.

Extensions

MeshTangents on MeshData
Tangent generation, split out of MeshData because Lengyel's method is a self-contained algorithm that only ever touches MeshData's public surface — an extension keeps it that way rather than granting it access to private state it does not need.

Constants

kDefaultVertexCacheSize → const int
A FIFO post-transform vertex cache's own size on real GPUs, give or take — the number optimizeVertexCache scores triangle choices against when the caller does not name one.
kNoHit → const double
Returned instead of a distance when nothing was hit.

Properties

kNeutralColor → Vector4
Opaque white: a vertex colour multiplies the surface, so this is the value that changes nothing.
final
kNeutralJoints → Vector4
Every vertex bound to joint zero.
final
kNeutralTangent → Vector4
A unit tangent along +X with a positive bitangent sign.
final
kNeutralWeights → Vector4
All the influence on the first joint.
final

Functions

averageCacheMissRatio(Uint32List indices, {int cacheSize = kDefaultVertexCacheSize}) → double
Cache misses per triangle simulating a FIFO cache of cacheSize entries reading indices in order — the standard ACMR metric (Hoppe, "Optimization of Mesh Locality for Transparent Vertex Caching", 1999) for how well a triangle order reuses recently-transformed vertices.
buildPolyline(List<Vector3> points, {required double width, List<Vector4>? colours, Vector4? colour}) → MeshData
points as one band width pixels across, coloured per point.
optimizeTriangleOrder(Uint32List indices, int vertexCount, {int cacheSize = kDefaultVertexCacheSize}) → Uint32List
indices reordered so triangles sharing recently-drawn vertices are drawn near each other, by Forsyth's greedy scoring: each step emits the unemitted triangle whose three vertices score highest, then ages every vertex still in the simulated cache and rescores the triangles that touch it.
optimizeVertexCache(MeshData mesh, {int cacheSize = kDefaultVertexCacheSize}) → MeshData
mesh with its triangles and vertices reordered for GPU cache reuse: optimizeTriangleOrder on the index buffer, then optimizeVertexFetch to renumber vertices by first use in that new order — the same two-pass scheme real engines and meshoptimizer split into, because the two caches they target (post- and pre-transform) are optimized by different orders.
optimizeVertexFetch(Uint32List indices, int vertexCount) → ({Uint32List indices, Uint32List oldToNew})
indices renumbered so a vertex's new index is the order it is first referenced in — the pre-transform ("vertex fetch") half of GPU cache friendliness, meant to run on triangle-cache-ordered indices ( optimizeTriangleOrder's output) the way meshoptimizer's optVertexFetch follows its own optVertexCache. A vertex a GPU fetches right after the one before it in memory is a vertex its prefetcher already has queued; a triangle order optimized for the post-transform cache alone can still reference vertex data scattered across the buffer.
rayAabb(Ray ray, Aabb3 box) → double
Distance along ray to box, or kNoHit.
raySphere(Ray ray, Vector3 centre, double radius) → double
Distance along ray to a sphere, or kNoHit. Inside counts as 0.
rayTriangle(Ray ray, Vector3 a, Vector3 b, Vector3 c, {Vector2? outUv, bool cullBackFace = false}) → double
Möller–Trumbore ray/triangle intersection.