InstancedMeshNode class final

One mesh drawn many times in one call, each copy with a transform and a colour of its own.

A thousand nodes is a thousand draws; this is one. Grass, rubble, a crowd, the pillars of a hall — the same geometry at many places is the commonest shape a scene has, and drawing it one node at a time spends a pipeline bind, six uniform writes and a draw on every copy. The particle system has drawn its embers this way since it existed; this is the same path for ordinary meshes.

What an instance is

A transform in the node's space and a colour that multiplies the vertex colour. Relative to the node rather than to the world, so the batch moves with its node the way a child would, and moving a batch of a thousand costs one uniform write. Sixteen floats each: three rows of a 3x4 affine matrix — the bottom row of one is always (0, 0, 0, 1), and a quarter of the buffer would be spent saying so — and an RGBA colour.

A copy can also wear its own morph weights — see setMorphWeights — which is how a crowd gets faces rather than one face repeated. Those do not live in the instance record: they are a texture read by instance id, so that the record's size, which is part of the vertex layout, is not paid by every batch in every game for a feature most of them never use.

What it is not, yet

  • Culled as one. The batch's bounds are the union of its instances' and the frustum test is one sphere around them, so a field that straddles the horizon is drawn whole. Per-instance culling is a CPU pass that costs more than it saves on a small batch, which is why other engines make it opt-in; it is not here until a scene asks.
  • Uniform scale per instance. A rotation and a uniform scale keep a normal a normal; a non-uniform instance scale skews the lighting, and the vertex stage says so rather than paying an inverse transpose per vertex.
  • No skinning. A skinned mesh has its own vertex stage and layout, and a skinned batch would be a third.
  • Sorted as one. A translucent batch sorts by the node, not by each instance, so overlapping translucent instances may draw in the wrong order within the batch.
  • Picked as a box. A ray hits the batch's bounds, not the instances.
Inheritance

Constructors

InstancedMeshNode(MeshGeometry mesh, Material material, {required int capacity, String? name})

Properties

capacity → int
How many instances the buffer can hold.
no setter
castsShadow ↔ bool
Whether this node is drawn into the shadow maps.
getter/setter pairinherited
castsShadowFromEveryFace → bool
Whether the shadow passes record every face of this node rather than the side ShadowSettings.casterFaces names for a lamp, or ShadowSettings.directionalCasterFaces for the sun.
no setterinherited
children → List<SceneNode>
no setterinherited
childrenView → List<SceneNode>
Direct access for internal traversal, avoiding the unmodifiable copy.
no setterinherited
count ↔ int
How many instances are drawn, never more than capacity.
getter/setter pair
dataVersion → int
Bumped on every write, so a reader can tell whether anything changed.
no setter
drawsTransparent → bool
Whether this draws in the transparent pass: its material blends, or tint fades it.
no setterinherited
frustumCulled ↔ bool
Skips frustum culling for this node.
getter/setter pairinherited
hashCode → int
The hash code for this object.
no setterinherited
hasInstanceMorphWeights → bool
Whether any instance has been given weights of its own.
no setter
instanceBytes → ByteData
The drawn instances as bytes, for binding as the per-instance slot.
no setter
instanceData → Float32List
The whole buffer, capacity instances of floatsPerInstance floats.
no setter
inverseWorldMatrix → Matrix4
The world-to-node transform, cached on worldVersion.
no setterinherited
isTinted → bool
Whether tint changes anything.
no setterinherited
layerMask ↔ int
Bitmask filtered against a render view's mask, in the manner of three.js layers. Bit 0 is the default layer.
getter/setter pairinherited
lightChannels ↔ int
Which light channels this node accepts — gfx-12n.
getter/setter pairinherited
lightmapped ↔ bool
Whether this mesh's vertex colour is its place in a lightmap.
getter/setter pairinherited
localBounds → Aabb3
The union of every drawn instance's transformed mesh bounds, in the node's space.
no setteroverride
localMatrix → Matrix4
no setterinherited
material ↔ Material
getter/setter pairinherited
mesh ↔ MeshGeometry
getter/setter pairinherited
morph ↔ MorphState?
The shapes this mesh blends towards, and how much of each.
getter/setter pairinherited
morphWeights → List<double>
What each target is worth right now, from nought to one.
no setterinherited
name ↔ String?
getter/setter pairinherited
occluder ↔ bool
Whether this mesh hides what is behind it from the software occlusion test — C2, RenderSettings.occlusion set to OcclusionMode.software.
getter/setter pairinherited
occluderMesh ↔ MeshData?
The triangles to occlude with in place of mesh's, in the same local space. A box standing in for a detailed building, or the walls of a room without its furniture. Null occludes with the mesh's own triangles, which have to be on the CPU (MeshGeometry.source) to be used at all.
getter/setter pairinherited
ownBounds → Aabb3?
What a subtree bound has to contain on this node's account — gfx-66n.
no setterinherited
ownBoundsAreCullable → bool
Whether ownBounds may be culled.
no setterinherited
parent → SceneNode?
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scene → Scene?
The scene this node currently belongs to, if any.
no setterinherited
shadowCasting ↔ ShadowCastingMode
How this node takes part in the shadow passes.
getter/setter pairinherited
shadowIsStatic ↔ bool
Whether this caster never moves.
getter/setter pairinherited
skeleton ↔ Skeleton?
The skeleton deforming this mesh, when it is skinned.
getter/setter pairinherited
skinReach ↔ double
How far the surface reaches from its joints, in the mesh's own units.
getter/setter pairinherited
subtreeAlwaysDrawn → bool
Whether anything in this subtree has opted out of frustum culling.
no setterinherited
subtreeBounds → Aabb3?
What this node and everything under it occupies, or null when the subtree draws nothing.
no setterinherited
tint → Vector4
Multiplies this node's colour and opacity, over whatever its material says: white is the material as it is, (1, 0.3, 0.3, 1) a red flash, (1, 1, 1, 0.5) half faded out.
finalinherited
visible ↔ bool
Whether this node and its subtree are drawn.
getter/setter pairinherited
visibleInHierarchy → bool
True when this node and every ancestor is visible.
no setterinherited
worldBounds → Aabb3
World-space axis-aligned bounds, recomputed only when the transform changes.
no setterinherited
worldBoundsCentre → Vector3
Centre of the world bounding sphere used for the cheap culling test.
no setterinherited
worldBoundsRadius → double
no setterinherited
worldIsMirrored → bool
True when the world transform mirrors, i.e. its determinant is negative.
no setterinherited
worldMatrix → Matrix4
The node-to-world transform, always current.
no setterinherited
worldNormalMatrix → Matrix4
Inverse-transpose of the world matrix, for transforming normals.
no setterinherited
worldVersion → int
Changes whenever worldMatrix changes. Use it as an invalidation key.
no setterinherited

Methods

acquire({Matrix4? transform, Vector4? color}) → InstanceHandle
Takes a slot for something that comes and goes, and returns the handle that keeps finding it: a shot, a spark, an invader.
add(SceneNode child) → void
Adds child, keeping its local transform (so it moves with this node).
inherited
addInstance(Matrix4 transform, {Vector4? color}) → int
Appends an instance and returns its index.
attach(SceneNode child) → void
Adds child while preserving its current world transform.
inherited
bindToScene(Scene? scene) → void
Binds this node's subtree to scene. Called by Scene for its own root; user code attaches nodes with add instead.
inherited
clear() → void
Empties the batch without giving up the buffer it has.
ensureCapacity(int wanted) → void
Grows the buffer to hold at least wanted instances, keeping what is in it.
findByName(String target) → SceneNode?
First descendant with a matching name, or null.
inherited
instanceMorphWeights(GraphicsDevice device) → TextureHandle?
The weights as a texture the instanced vertex stage can read, or null when no instance has any.
lookAt(Vector3 target, {Vector3? up}) → void
Points the node's local -Z at target, given in world space.
inherited
markBoundsDirty() → void
Says the cached bounds no longer describe the node.
inherited
markInstancesChanged() → void
Says the buffer was written through instanceData.
morphWeightsOf(int index) → List<double>
Instance index's weights, as they were set.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onAttachedToScene(Scene scene) → void
Hook for subclasses to register themselves in the scene's flat registries.
inherited
onDetachedFromScene(Scene scene) → void
inherited
readPosition([Vector3? out]) → Vector3
Reads the local position into out to avoid allocating.
inherited
readRotation([Quaternion? out]) → Quaternion
inherited
readScale([Vector3? out]) → Vector3
inherited
readTransform(int index, Matrix4 out) → void
Reads instance index's transform back into out.
readWorldPosition([Vector3? out]) → Vector3
inherited
release(InstanceHandle handle) → void
Gives handle's slot back: the last drawn slot moves into it, colour and morph weights with it, and count drops by one. Releasing a handle twice, or one from another batch, is a mistake and throws.
remove(SceneNode child) → void
inherited
removeFromParent() → void
Detaches this node from its parent.
inherited
setColor(int index, Vector4 color) → void
Tints instance index: multiplied into the vertex colour.
setLocalForward(Vector3 direction, {Vector3? up}) → void
Aims the node's local -Z along direction, expressed in the parent's space.
inherited
setLocalMatrix(Matrix4 value) → void
Replaces the local transform by decomposing a matrix.
inherited
setMorphWeights(int index, List<double> weights) → void
Gives instance index its own morph weights.
setPosition(double x, double y, double z) → void
inherited
setPositionFrom(Vector3 value) → void
inherited
setRotation(Quaternion value) → void
inherited
setRotationYawPitchRoll(double yaw, double pitch, double roll) → void
Yaw about Y, then pitch about X, then roll about Z — the order that reads naturally for cameras and turntables.
inherited
setScale(double x, double y, double z) → void
inherited
setTransform(int index, Matrix4 transform) → void
Places instance index with transform, in the node's space.
setUniformScale(double value) → void
inherited
toString() → String
A string representation of this object.
inherited
translate(double dx, double dy, double dz) → void
inherited
traverse(void visit(SceneNode child)) → void
Walks this node and its descendants.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Constants

floatsPerInstance → const int
Floats one instance occupies: three rows of the transform, then RGBA.
maxMorphTargets → const int
The most targets an instance can be given weights for. kMorphMax in lib/morph.glsl, and the two have to move together.
strideInBytes → const int
Bytes one instance occupies.