DecalNode class base Rendering

A box-projected decal. Its material paints every opaque surface inside the box, conforming to that surface rather than to the box's own faces, so a scorch mark follows terrain, steps, and props. It adds no geometry in the surface's plane, so it never fights the surface (z-fighting) the way a quad laid on it can; prefer it for marks on uneven surfaces.

Drive it with a .fmat declaring engine_inputs: [scene_depth], depth_test: always, and culling: front (see the decals section of MATERIALS.md). The node keeps the material's decal_inverse and decal_fade parameters in sync with its own world transform each frame, so moving or reparenting a placed decal is enough; names the material does not declare are skipped. The projection lives in those parameters, so each decal needs its own material instance.

Unprojecting the receiving surface needs the opaque depth and a perspective camera, so a decal draws nothing under an OrthographicCamera.

final decal = DecalNode(material: await loadFmatMaterial('assets/scorch_decal.fmat'))
  ..project(point: impactPoint, normal: groundNormal, size: 2.4);
scene.add(decal);
Inheritance

Constructors

DecalNode({required PreprocessedMaterial material, String name = ''})
Creates a decal drawn with material, unplaced until project runs.

Properties

castsShadows ↔ bool
Whether this node's meshes cast shadows.
getter/setter pairinherited
children → List<Node>
This list allows the node to act as a parent in the scene graph hierarchy. Transformations applied to this node, such as translation, rotation, and scaling, will also affect all child nodes.
finalinherited
combinedLocalBounds → Aabb3?
Local-space AABB covering this node's mesh and every descendant's (transformed) bounds. Returns null when the subtree contains skinned content or geometry without computable bounds, signalling "treat as always visible." Cached; invalidated by markBoundsDirty.
no setterinherited
combinedWorldBounds → Aabb3?
The subtree's axis-aligned bounds in world space, or null when the subtree is unbounded (combinedLocalBounds is null, e.g. skinned content or caller-managed geometry).
no setterinherited
debugView ↔ DebugView? Scene graph
A surface debug view for this subtree, overriding the scene's Scene.debug.view. Null (the default) inherits from the nearest ancestor that sets one, then the scene. DebugView.none excludes the subtree from an active scene view, so it shades normally.
getter/setter pairinherited
defaultMorphWeights → Float32List?
The mesh-authored default morph weights, or null when the mesh has no targets. Returns a copy.
no setterinherited
fade ↔ double
Overall opacity, animated to fade a decal out before removing it.
getter/setter pair
frustumCulled ↔ bool
Whether this node and its descendants should be tested against the camera frustum each frame. When true (the default), subtrees whose combinedLocalBounds don't intersect the frustum are skipped entirely. Set to false for procedural geometry, large terrain pieces, or anything else where the cached bound is known-stale or known-misleading.
getter/setter pairinherited
globalTransform ↔ Matrix4
The world-space transform of this node, with every ancestor's transform applied.
getter/setter pairinherited
hashCode → int
The hash code for this object.
no setterinherited
highlightColor ↔ Vector4? Rendering
A highlight/outline color (linear RGBA) for this node, or null for none.
getter/setter pairinherited
isJoint ↔ bool
Whether this node is a joint in a skeleton for animation.
getter/setter pairinherited
layers ↔ int
The render layers this node occupies, a 32-bit bitmask. A RenderView renders this node's mesh only when its RenderView.layerMask intersects these layers (layers & layerMask != 0). Defaults to kRenderLayerDefault (layer 0). Each node carries its own layers; the value is not inherited by children.
getter/setter pairinherited
lightChannelMask ↔ int Scene graph
The light channels this node's meshes occupy, an 8-bit bitmask. A light reaches them only when its own channel mask intersects this one (light.channelMask & lightChannelMask != 0), so a light can be aimed at a subset of the scene without a second scene graph. 0xFF (the default) takes every channel; 0 takes none and leaves the meshes with only image-based lighting, which channels never gate. Not inherited by children; set it on each mesh-bearing node.
getter/setter pairinherited
localTransform ↔ Matrix4
The transform of this node relative to its parent: position, rotation, and scale.
getter/setter pairinherited
material ↔ PreprocessedMaterial
The projecting material. Its decal_inverse mat4 and decal_fade float parameters are written by this node.
getter/setter pair
mesh ↔ Mesh?
The collection of MeshPrimitive objects that represent the 3D geometry and material properties of this node.
getter/setter pairinherited
meshNodes → Iterable<Node>
The nodes in this subtree (this node and its descendants, depth-first) that carry a mesh with at least one primitive.
no setterinherited
morphTargetCount → int
The number of morph targets on this node's mesh, or zero when the mesh has none.
no setterinherited
morphTargetNames → List<String>
The morph target names from the source asset (extras.targetNames), empty strings for unnamed targets. Empty when the mesh has no targets.
no setterinherited
morphWeights → Float32List?
This node's current morph target weights, or null when the mesh has no targets. Returns a copy; drive weights through setMorphWeight or setMorphWeights.
no setterinherited
name ↔ String
The name of this node, used for identification.
getter/setter pairinherited
parent → Node?
The parent node of this node in the scene graph.
no setterinherited
parsedAnimations → List<Animation>
The list of animations parsed when this node was deserialized.
no setterinherited
position ↔ Vector3 Scene graph
This node's position relative to its parent.
getter/setter pairinherited
raycastable ↔ bool
Whether scene raycasts (Scene.raycast) test this node's meshes.
getter/setter pairinherited
renderOrder ↔ double
Where this node's meshes draw within their pass, lowest first. Draws sort by it before anything else: opaque ones before their state and depth sort, translucent ones before their back-to-front sort. Use it to pin the order of overlapping translucent surfaces that depth sorting gets wrong (a thing seen through glass, or parts of one object). The default 0 leaves ordering to the renderer. Not inherited by children.
getter/setter pairinherited
rotation ↔ Quaternion Scene graph
This node's rotation relative to its parent.
getter/setter pairinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scale ↔ Vector3 Scene graph
This node's scale relative to its parent.
getter/setter pairinherited
shadowCastingMode ↔ ShadowCastingMode Scene graph
How this node's meshes cast shadows. Defaults to ShadowCastingMode.on.
getter/setter pairinherited
shadowStatic ↔ bool
Marks this node's meshes as static shadow casters: their geometry, material coverage, and world transform are promised not to change while mounted, so the engine may render them into cached shadow-map tiles that are reused across frames instead of re-encoding every caster every frame. Large static worlds become dramatically cheaper to shadow; nodes left dynamic (the default) still cast per-frame shadows on top of the cache. A static node that does change (moves, remesh, material coverage edit) shows stale shadows until its render item re-registers, so flag only genuinely static content. Not inherited by children; set it on each mesh-bearing node. Materials with a vertex { } displacement stage should stay dynamic, since their cached shadows would not follow a camera-dependent displacement.
getter/setter pairinherited
skin ↔ Skin?
The skin attached to this node, used for skeletal animation. Set by importers (both the scene importer and the runtime glTF/GLB loader).
getter/setter pairinherited
visible ↔ bool
Whether this node is visible in the scene. If false, the node and its children will not be rendered.
getter/setter pairinherited

Methods

add(Node child) → void
Add a child node.
inherited
addAll(Iterable<Node> children) → void
Add a list of child nodes.
inherited
addComponent(Component component) → void
Attaches component to this node.
inherited
addMesh(Mesh mesh) → void
Add a mesh as a child node.
inherited
addParsedAnimation(Animation animation) → void
Append to the parsed animation list. Used by importers (including the runtime glTF/GLB loader).
inherited
clone({bool recursive = true}) → Node
Creates a copy of this node.
inherited
createAnimationClip(Animation animation) → AnimationClip
Instantiates animation as an AnimationClip bound to this node.
inherited
debugMountInto(RenderScene renderScene) → void
Mounts this subtree into renderScene without a full Scene.
inherited
debugPrintHierarchy({int depth = 0}) → void
Prints the hierarchy of this node and all its children to the console.
inherited
detach() → void
Detaches this node from its parent in the scene graph.
inherited
extractMeshData({Matrix4? transform}) → MeshData Geometry
This subtree's geometry flattened into one snapshot, with every descendant transform baked into the vertices.
inherited
findAnimationByName(String name) → Animation?
Searches for an Animation by name.
inherited
getChildByIndexPath(Iterable<int> indexPath) → Node?
Resolves an indexPath (as produced by getIndexPath) to a descendant node, or null if any segment is out of range.
inherited
getChildByName(String name, {bool excludeAnimationPlayers = false}) → Node?
Searches this node's descendants for the first child whose Node.name matches name.
inherited
getChildByNamePath(Iterable<String> namePath) → Node?
Resolves a namePath (as produced by getNamePath) to a descendant node, or null if any segment does not match.
inherited
getComponent<T>() → T?
Returns the first attached component of type T, or null.
inherited
getComponents<T>() → Iterable<T>
Returns every attached component of type T, in attach order.
inherited
getDepth() → int
Returns the depth of this node in the scene graph hierarchy. The root node has a depth of 0.
inherited
getRoot() → Node
Returns the root node of the graph that this node is a part of.
inherited
isVisibleTo(Camera camera, Size dimensions) → bool
Whether this node's subtree would survive frustum culling against camera for a render target of the given dimensions.
inherited
lookAt(Vector3 target, {Vector3? up}) → void Scene graph
Orients this node so its forward axis (local +Z) points at target in world space, keeping up as the reference up (defaults to +Y). Only the node's rotation changes; its world position and scale are preserved.
inherited
lookAtFrom(Vector3 eye, Vector3 target, {Vector3? up}) → void Scene graph
Places the node at eye and orients its forward axis (local +Z) at target in world space. The imperative camera one-liner, positioning and aiming in a single call; the node's world scale is preserved. See lookAt for the forward-axis convention and the up constraint.
inherited
markBoundsDirty() → void
Mark this node's combinedLocalBounds cache (and every ancestor's) stale. Call after replacing a mesh, mutating a child's local transform in place, or any other change that affects the bound.
inherited
markTransformDirty() → void
Marks this node's transform changed: its own and its descendants' cached world transforms become stale, and its own and its ancestors' cached bounds become stale.
inherited
mutateLocalTransform(void edit(Matrix4 transform)) → void Scene graph
Edits localTransform in place through edit, then marks the node stale.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
project({required Vector3 point, required Vector3 normal, required double size, double depth = 0.5, double rotation = 0.0}) → void
Places the box so it projects onto point along normal, spanning size world units across and depth units along the normal, centered on point. rotation spins the projection about the normal, in radians.
registerAsRoot(Scene scene) → void
Registers this node as the root node of the scene graph.
inherited
reloadParsedAnimations(List<Animation> animations, {Matrix4? restPoseOf(Node node)?}) → void
Replaces this node's parsed animations with animations and re-binds any AnimationClips created from the old set (matched by name), keeping their playback state.
inherited
remove(Node child) → void
Remove a child node.
inherited
removeAll() → void
Remove all children nodes.
inherited
removeAnimationClip(AnimationClip clip) → void
Unregisters clip from this node's animation player so it no longer contributes to the blend. No-op when clip is not registered here.
inherited
removeComponent(Component component) → void
Detaches component from this node.
inherited
sceneFixedPass(double fixedDt) → void
Walks this node's subtree once per physics substep and dispatches Component.fixedTick to every component.
inherited
scenePrePass(double deltaSeconds, [bool ancestorsVisible = true]) → void
Walks this node's subtree once per frame to prepare it for rendering: ticks components and animation players and refreshes the RenderItems the render passes iterate.
override
setMorphWeight(int index, double value) → void
Sets the weight of morph target index on this node instance.
inherited
setMorphWeights(List<double> values) → void
Replaces morph weights on this node instance, in target order. Entries beyond the mesh's target count are ignored; missing trailing entries keep their current value.
inherited
toString() → String
A string representation of this object.
inherited

Operators

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