Mesh Geometry
Editable geometry parameters for primitive meshes (cube, sphere, plane, capsule, cylinder) and the placeholder for model entities. Holds the authoring values plus shadow casting/receiving flags. The mesh-geometry system rebuilds the underlying BufferGeometry when parameters change.
Managed by:
MeshGeometrySystem
Properties
| Property | Type | Description |
|---|---|---|
kind | EditableMeshObjectKind | Primitive kind (cube, sphere, plane, capsule, cylinder) or model for loaded assets. |
geometryType | string | Three.js geometry class name (e.g. "BoxGeometry", "SphereGeometry"). Derived from kind. |
parameters | MeshGeometryParameters | Editable parameters whose shape depends on kind. The mesh-geometry system rebuilds geometry when these change. |
object | THREE.Object3D | null | Live three.js object whose geometry is being managed. null until the object is built. |
modelName | string | Human-readable model name shown in the inspector for model entities; empty for primitives. |
castShadow | boolean | Whether the mesh casts shadows in the renderer. |
receiveShadow | boolean | Whether the mesh receives shadows in the renderer. |
API reference
- Class:
MeshGeometryComponent - Source:
core/components/MeshGeometry.ts
Scripting examples
Component access patterns
Use this.getComponent(X) to access a component on the entity this script is attached to. Use this.world.getEntityByName to find another entity by name, then this.world.getComponent to read its component:
// Component on the entity this script is on
const geo = this.getComponent(MeshGeometryComponent);
// Component on another entity, found by its scene name
const other = this.world.getEntityByName("Floor");
if (other) {
const geo = this.world.getComponent(other.entityId, MeshGeometryComponent);
}Toggle shadow casting at runtime
Let the inspector or game logic control whether the mesh casts and receives shadows.
import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
import type { BooleanInput } from "@relu-interactives/spatial-ecs";
export default class ShadowDriver extends Behaviour {
data = {
castShadow: true as BooleanInput,
receiveShadow: true as BooleanInput,
};
protected onUpdate() {
const geo = this.getComponent(MeshGeometryComponent);
if (!geo) return;
geo.castShadow = this.data.castShadow;
geo.receiveShadow = this.data.receiveShadow;
}
}Animate sphere radius
Pulse the radius of a sphere primitive by writing to its geometry parameters each frame. The mesh-geometry system rebuilds the BufferGeometry when parameters change.
import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
import type { FloatInput } from "@relu-interactives/spatial-ecs";
export default class SphereGrow extends Behaviour {
data = {
speed: 1 as FloatInput,
minRadius: 0.3 as FloatInput,
maxRadius: 1 as FloatInput,
};
private elapsed = 0;
protected onUpdate() {
this.elapsed += this.deltaTime;
const geo = this.getComponent(MeshGeometryComponent);
if (!geo || geo.kind !== "sphere") return;
const t = (Math.sin(this.elapsed * this.data.speed) + 1) * 0.5;
const radius = this.data.minRadius + t * (this.data.maxRadius - this.data.minRadius);
(geo.parameters as { radius: number }).radius = radius;
}
}Via ComponentInput in the inspector
You can also pick this component from the inspector using a ComponentInput field. Assign any entity in the inspector and the field resolves to the live MeshGeometryComponent instance at runtime.
import {
Behaviour,
MeshGeometryComponent,
type ComponentInput,
} from "@relu-interactives/spatial-ecs";
export default class Example extends Behaviour {
data = {
targetGeometry: {
type: "component",
value: null,
} as unknown as ComponentInput,
};
protected onUpdate() {
const geo = this.data.targetGeometry.value as MeshGeometryComponent | null;
if (!geo) return;
// Use the live component instance.
}
}Via EntityInput in the inspector
Alternatively, pick an entity from the inspector using an EntityInput field and then read the component off that entity via world.getComponent:
import {
Behaviour,
MeshGeometryComponent,
type EntityInput,
type WorldEntityView,
} from "@relu-interactives/spatial-ecs";
export default class Example extends Behaviour {
data = {
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
};
protected onUpdate() {
const entity = this.data.targetEntity.value as WorldEntityView | null;
if (!entity) return;
const geo = this.world.getComponent(
entity.entityId,
MeshGeometryComponent,
) as MeshGeometryComponent | null;
if (!geo) return;
// Use the component on the picked entity.
}
}Geometry rebuild cost
The mesh-geometry system only rebuilds geometry when parameters actually change. Avoid writing the same value every frame unless the value is genuinely different, to prevent unnecessary geometry allocations.

