@relu-interactives/spatial-ecs 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +125 -0
- package/dist/System-rXAmagXA.d.cts +659 -0
- package/dist/System-rXAmagXA.d.ts +659 -0
- package/dist/Video-CDemv74U.d.cts +1261 -0
- package/dist/Video-ChKV1UI7.d.ts +1261 -0
- package/dist/assets/draco/draco_decoder.js +34 -0
- package/dist/assets/draco/draco_decoder.wasm +0 -0
- package/dist/assets/draco/draco_wasm_wrapper.js +117 -0
- package/dist/chunk-AYEF3X2P.js +223 -0
- package/dist/chunk-AYEF3X2P.js.map +1 -0
- package/dist/chunk-MAWBTMCG.js +1722 -0
- package/dist/chunk-MAWBTMCG.js.map +1 -0
- package/dist/chunk-NFDTIYR4.js +248 -0
- package/dist/chunk-NFDTIYR4.js.map +1 -0
- package/dist/chunk-OY7ZODZP.js +16 -0
- package/dist/chunk-OY7ZODZP.js.map +1 -0
- package/dist/chunk-P2YDX5DB.js +3304 -0
- package/dist/chunk-P2YDX5DB.js.map +1 -0
- package/dist/chunk-QHILSPT4.js +3 -0
- package/dist/chunk-QHILSPT4.js.map +1 -0
- package/dist/chunk-XWIEEJ7Z.js +1315 -0
- package/dist/chunk-XWIEEJ7Z.js.map +1 -0
- package/dist/components/index.cjs +1745 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +4 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +4 -0
- package/dist/components/index.js.map +1 -0
- package/dist/docs/api/Behaviour/classes/Behaviour.md +554 -0
- package/dist/docs/api/Behaviour/index.md +15 -0
- package/dist/docs/api/Component/classes/Component.md +57 -0
- package/dist/docs/api/Component/index.md +15 -0
- package/dist/docs/api/components/classes/AnimationComponent.md +318 -0
- package/dist/docs/api/components/classes/AudioComponent.md +114 -0
- package/dist/docs/api/components/classes/CameraComponent.md +59 -0
- package/dist/docs/api/components/classes/EntityType.md +48 -0
- package/dist/docs/api/components/classes/Environment.md +47 -0
- package/dist/docs/api/components/classes/ImageComponent.md +57 -0
- package/dist/docs/api/components/classes/ImageTarget.md +60 -0
- package/dist/docs/api/components/classes/ImageTargetAnchor.md +48 -0
- package/dist/docs/api/components/classes/LightComponent.md +70 -0
- package/dist/docs/api/components/classes/MaterialComponent.md +181 -0
- package/dist/docs/api/components/classes/MeshComponent.md +48 -0
- package/dist/docs/api/components/classes/MeshGeometryComponent.md +64 -0
- package/dist/docs/api/components/classes/ModelComponent.md +49 -0
- package/dist/docs/api/components/classes/Name.md +46 -0
- package/dist/docs/api/components/classes/Object3DRef.md +54 -0
- package/dist/docs/api/components/classes/ParentId.md +47 -0
- package/dist/docs/api/components/classes/PhysicsComponent.md +82 -0
- package/dist/docs/api/components/classes/Postprocessing.md +49 -0
- package/dist/docs/api/components/classes/ScriptComponent.md +54 -0
- package/dist/docs/api/components/classes/Selectable.md +46 -0
- package/dist/docs/api/components/classes/SelectionTransformState.md +54 -0
- package/dist/docs/api/components/classes/SpriteComponent.md +55 -0
- package/dist/docs/api/components/classes/TransformComponent.md +197 -0
- package/dist/docs/api/components/classes/VideoComponent.md +123 -0
- package/dist/docs/api/components/functions/normalizePhysicsState.md +23 -0
- package/dist/docs/api/components/index.md +94 -0
- package/dist/docs/api/components/type-aliases/AnimationComponentOptions.md +42 -0
- package/dist/docs/api/components/type-aliases/CameraComponentOptions.md +45 -0
- package/dist/docs/api/components/type-aliases/CameraProjection.md +15 -0
- package/dist/docs/api/components/type-aliases/CameraRuntimeType.md +15 -0
- package/dist/docs/api/components/type-aliases/ColliderShape.md +15 -0
- package/dist/docs/api/components/type-aliases/ColliderState.md +62 -0
- package/dist/docs/api/components/type-aliases/CubeMeshParameters.md +27 -0
- package/dist/docs/api/components/type-aliases/EditableMeshObjectKind.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentFogState.md +37 -0
- package/dist/docs/api/components/type-aliases/EnvironmentFogType.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentGradientEffect.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxState.md +34 -0
- package/dist/docs/api/components/type-aliases/EnvironmentSkyboxType.md +15 -0
- package/dist/docs/api/components/type-aliases/EnvironmentState.md +29 -0
- package/dist/docs/api/components/type-aliases/ImageTargetAnchorOptions.md +25 -0
- package/dist/docs/api/components/type-aliases/ImageTargetReference.md +33 -0
- package/dist/docs/api/components/type-aliases/LightValueState.md +41 -0
- package/dist/docs/api/components/type-aliases/MaterialTypeValue.md +15 -0
- package/dist/docs/api/components/type-aliases/MaterialValueState.md +75 -0
- package/dist/docs/api/components/type-aliases/MeshGeometryParameters.md +13 -0
- package/dist/docs/api/components/type-aliases/MeshGeometryParametersByKind.md +33 -0
- package/dist/docs/api/components/type-aliases/PhysicsState.md +25 -0
- package/dist/docs/api/components/type-aliases/PlaneMeshParameters.md +25 -0
- package/dist/docs/api/components/type-aliases/PostprocessingState.md +164 -0
- package/dist/docs/api/components/type-aliases/RadiusHeightMeshParameters.md +25 -0
- package/dist/docs/api/components/type-aliases/RadiusMeshParameters.md +23 -0
- package/dist/docs/api/components/type-aliases/RigidbodyState.md +53 -0
- package/dist/docs/api/components/type-aliases/RigidbodyType.md +19 -0
- package/dist/docs/api/components/type-aliases/ScriptEntry.md +38 -0
- package/dist/docs/api/components/type-aliases/TextureFilteringValue.md +15 -0
- package/dist/docs/api/components/type-aliases/TransformData.md +27 -0
- package/dist/docs/api/components/type-aliases/TransformModeValue.md +15 -0
- package/dist/docs/api/components/type-aliases/TransformSpaceValue.md +15 -0
- package/dist/docs/api/components/type-aliases/Vec3.md +27 -0
- package/dist/docs/api/components/variables/DEFAULT_COLLIDER_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_ENVIRONMENT_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_MESH_GEOMETRY_PARAMETERS.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_PHYSICS_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_POSTPROCESSING_STATE.md +13 -0
- package/dist/docs/api/components/variables/DEFAULT_RIGIDBODY_STATE.md +13 -0
- package/dist/docs/api/index/classes/AnimationStateMachine.md +201 -0
- package/dist/docs/api/index/classes/AnimationStateManager.md +253 -0
- package/dist/docs/api/index/classes/AnimationSystem.md +68 -0
- package/dist/docs/api/index/classes/AudioSystem.md +98 -0
- package/dist/docs/api/index/classes/CameraSyncSystem.md +49 -0
- package/dist/docs/api/index/classes/EnvironmentSyncSystem.md +75 -0
- package/dist/docs/api/index/classes/InputSystem.md +449 -0
- package/dist/docs/api/index/classes/LightSyncSystem.md +49 -0
- package/dist/docs/api/index/classes/MaterialSyncSystem.md +67 -0
- package/dist/docs/api/index/classes/MeshGeometrySystem.md +49 -0
- package/dist/docs/api/index/classes/ObjectManagementSystem.md +298 -0
- package/dist/docs/api/index/classes/ObjectVisibilitySystem.md +49 -0
- package/dist/docs/api/index/classes/PhysicsSyncSystem.md +83 -0
- package/dist/docs/api/index/classes/PostprocessingSyncSystem.md +80 -0
- package/dist/docs/api/index/classes/RenderSystem.md +64 -0
- package/dist/docs/api/index/classes/ScriptBehaviourSystem.md +83 -0
- package/dist/docs/api/index/classes/TransformSyncSystem.md +49 -0
- package/dist/docs/api/index/classes/VideoSystem.md +97 -0
- package/dist/docs/api/index/classes/World.md +1405 -0
- package/dist/docs/api/index/functions/createAnimationComponent.md +28 -0
- package/dist/docs/api/index/functions/createAudioComponent.md +32 -0
- package/dist/docs/api/index/functions/createCameraComponent.md +28 -0
- package/dist/docs/api/index/functions/createEntityTypeComponent.md +28 -0
- package/dist/docs/api/index/functions/createEnvironmentComponent.md +28 -0
- package/dist/docs/api/index/functions/createImageComponent.md +28 -0
- package/dist/docs/api/index/functions/createImageTargetAnchorComponent.md +28 -0
- package/dist/docs/api/index/functions/createImageTargetComponent.md +28 -0
- package/dist/docs/api/index/functions/createLightComponent.md +28 -0
- package/dist/docs/api/index/functions/createMaterialComponent.md +28 -0
- package/dist/docs/api/index/functions/createMeshComponent.md +28 -0
- package/dist/docs/api/index/functions/createMeshGeometryComponent.md +28 -0
- package/dist/docs/api/index/functions/createModelComponent.md +28 -0
- package/dist/docs/api/index/functions/createNameComponent.md +28 -0
- package/dist/docs/api/index/functions/createObject3DRefComponent.md +28 -0
- package/dist/docs/api/index/functions/createParentIdComponent.md +28 -0
- package/dist/docs/api/index/functions/createPhysicsComponent.md +30 -0
- package/dist/docs/api/index/functions/createPostprocessingComponent.md +28 -0
- package/dist/docs/api/index/functions/createScriptComponent.md +28 -0
- package/dist/docs/api/index/functions/createSelectableComponent.md +28 -0
- package/dist/docs/api/index/functions/createSelectionTransformStateComponent.md +28 -0
- package/dist/docs/api/index/functions/createSpriteComponent.md +28 -0
- package/dist/docs/api/index/functions/createTransformComponent.md +28 -0
- package/dist/docs/api/index/functions/createVideoComponent.md +28 -0
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshot.md +28 -0
- package/dist/docs/api/index/functions/hydrateWorldFromSnapshotDetailed.md +28 -0
- package/dist/docs/api/index/functions/registerDefaultComponentFactories.md +23 -0
- package/dist/docs/api/index/functions/registerDefaultFactories.md +23 -0
- package/dist/docs/api/index/index.md +249 -0
- package/dist/docs/api/index/interfaces/EcsSystem.md +50 -0
- package/dist/docs/api/index/interfaces/StateMachine.md +26 -0
- package/dist/docs/api/index/type-aliases/AnimationStateCallbacks.md +25 -0
- package/dist/docs/api/index/type-aliases/ComponentFactory.md +25 -0
- package/dist/docs/api/index/type-aliases/EcsComponentFactoryKind.md +37 -0
- package/dist/docs/api/index/type-aliases/EcsWorldComponentSnapshot.md +26 -0
- package/dist/docs/api/index/type-aliases/EcsWorldStateSnapshotLike.md +25 -0
- package/dist/docs/api/index/type-aliases/HydrateWorldFromSnapshotResult.md +23 -0
- package/dist/docs/api/index/type-aliases/KeyboardKey.md +13 -0
- package/dist/docs/api/index/type-aliases/MouseButton.md +13 -0
- package/dist/docs/api/index/type-aliases/SelectionContext.md +31 -0
- package/dist/docs/api/index/variables/HYDRATABLE_ENTITY_KINDS.md +13 -0
- package/dist/docs/api/index/variables/KeyboardKeys.md +195 -0
- package/dist/docs/api/index.md +15 -0
- package/dist/docs/api/typedoc-sidebar.json +1 -0
- package/dist/docs/api/types/index.md +34 -0
- package/dist/docs/api/types/type-aliases/AssetInput.md +23 -0
- package/dist/docs/api/types/type-aliases/CheckboxInput.md +13 -0
- package/dist/docs/api/types/type-aliases/ColorInput.md +13 -0
- package/dist/docs/api/types/type-aliases/ComponentInput.md +52 -0
- package/dist/docs/api/types/type-aliases/ComponentKind.md +37 -0
- package/dist/docs/api/types/type-aliases/DropdownInput.md +23 -0
- package/dist/docs/api/types/type-aliases/DropdownOption.md +23 -0
- package/dist/docs/api/types/type-aliases/EcsEntityEditorKind.md +15 -0
- package/dist/docs/api/types/type-aliases/EcsEntityKind.md +35 -0
- package/dist/docs/api/types/type-aliases/EntityId.md +16 -0
- package/dist/docs/api/types/type-aliases/EntityInput.md +23 -0
- package/dist/docs/api/types/type-aliases/FloatInput.md +13 -0
- package/dist/docs/api/types/type-aliases/IntersectionResult.md +29 -0
- package/dist/docs/api/types/type-aliases/ParentLookup.md +26 -0
- package/dist/docs/api/types/type-aliases/SelectionListener.md +25 -0
- package/dist/docs/api/types/type-aliases/SliderInput.md +27 -0
- package/dist/docs/api/types/type-aliases/TextInput.md +13 -0
- package/dist/docs/api/types/type-aliases/ToggleInput.md +13 -0
- package/dist/docs/api/types/type-aliases/Vec3.md +23 -0
- package/dist/docs/api/types/type-aliases/Vector2Input.md +23 -0
- package/dist/docs/api/types/type-aliases/Vector3Input.md +25 -0
- package/dist/docs/api/types/type-aliases/WorldEntityView.md +17 -0
- package/dist/docs/guide/accessing-components.md +399 -0
- package/dist/docs/guide/authoring-a-behaviour.md +166 -0
- package/dist/docs/guide/behaviour-lifecycle.md +43 -0
- package/dist/docs/guide/component-catalog.md +59 -0
- package/dist/docs/guide/components/_sidebar.json +78 -0
- package/dist/docs/guide/components/animation.md +171 -0
- package/dist/docs/guide/components/audio.md +181 -0
- package/dist/docs/guide/components/camera.md +179 -0
- package/dist/docs/guide/components/entity-type.md +141 -0
- package/dist/docs/guide/components/image-target-anchor.md +103 -0
- package/dist/docs/guide/components/image-target.md +122 -0
- package/dist/docs/guide/components/image.md +146 -0
- package/dist/docs/guide/components/light.md +157 -0
- package/dist/docs/guide/components/material.md +161 -0
- package/dist/docs/guide/components/mesh-geometry.md +153 -0
- package/dist/docs/guide/components/mesh.md +151 -0
- package/dist/docs/guide/components/model.md +96 -0
- package/dist/docs/guide/components/name.md +121 -0
- package/dist/docs/guide/components/object3d-ref.md +115 -0
- package/dist/docs/guide/components/parent-id.md +108 -0
- package/dist/docs/guide/components/physics.md +163 -0
- package/dist/docs/guide/components/script.md +142 -0
- package/dist/docs/guide/components/sprite.md +155 -0
- package/dist/docs/guide/components/transform.md +155 -0
- package/dist/docs/guide/components/video.md +153 -0
- package/dist/docs/guide/concepts.md +34 -0
- package/dist/docs/guide/getting-started/creating-objects.md +50 -0
- package/dist/docs/guide/getting-started/editing-objects.md +62 -0
- package/dist/docs/guide/getting-started/editor/assets-browser.md +55 -0
- package/dist/docs/guide/getting-started/editor/hierarchy.md +47 -0
- package/dist/docs/guide/getting-started/editor/index.md +16 -0
- package/dist/docs/guide/getting-started/editor/inspector.md +36 -0
- package/dist/docs/guide/getting-started/editor/modules.md +35 -0
- package/dist/docs/guide/getting-started/editor/scene-inspector.md +64 -0
- package/dist/docs/guide/getting-started/editor/toolbar.md +39 -0
- package/dist/docs/guide/getting-started/editor/viewport.md +43 -0
- package/dist/docs/guide/getting-started/first-launch.md +17 -0
- package/dist/docs/guide/getting-started/index.md +37 -0
- package/dist/docs/guide/getting-started/installation.md +59 -0
- package/dist/docs/guide/getting-started/preview-and-test.md +55 -0
- package/dist/docs/guide/getting-started/project-types/3d.md +30 -0
- package/dist/docs/guide/getting-started/project-types/ar.md +6 -0
- package/dist/docs/guide/getting-started/project-types/face-tracking.md +6 -0
- package/dist/docs/guide/getting-started/project-types/image-tracking.md +42 -0
- package/dist/docs/guide/getting-started/project-types/index.md +25 -0
- package/dist/docs/guide/getting-started/project-types/vr.md +6 -0
- package/dist/docs/guide/getting-started/projects.md +53 -0
- package/dist/docs/guide/getting-started/shortcuts.md +43 -0
- package/dist/docs/guide/inspector-data-binding.md +367 -0
- package/dist/docs/guide/reading-input.md +202 -0
- package/dist/docs/guide/scene/environment.md +101 -0
- package/dist/docs/guide/scene/index.md +36 -0
- package/dist/docs/guide/scene/postprocessing.md +108 -0
- package/dist/docs/guide/spawning/ambient-light.md +28 -0
- package/dist/docs/guide/spawning/area-light.md +32 -0
- package/dist/docs/guide/spawning/audio.md +42 -0
- package/dist/docs/guide/spawning/camera.md +50 -0
- package/dist/docs/guide/spawning/capsule.md +29 -0
- package/dist/docs/guide/spawning/cube.md +31 -0
- package/dist/docs/guide/spawning/cylinder.md +29 -0
- package/dist/docs/guide/spawning/directional-light.md +32 -0
- package/dist/docs/guide/spawning/empty.md +31 -0
- package/dist/docs/guide/spawning/image-target.md +48 -0
- package/dist/docs/guide/spawning/image.md +33 -0
- package/dist/docs/guide/spawning/index.md +79 -0
- package/dist/docs/guide/spawning/model.md +31 -0
- package/dist/docs/guide/spawning/plane.md +31 -0
- package/dist/docs/guide/spawning/point-light.md +32 -0
- package/dist/docs/guide/spawning/sphere.md +29 -0
- package/dist/docs/guide/spawning/spot-light.md +32 -0
- package/dist/docs/guide/spawning/sprite.md +31 -0
- package/dist/docs/guide/spawning/video.md +53 -0
- package/dist/docs/guide/system-overview.md +73 -0
- package/dist/docs/guide/systems/_sidebar.json +66 -0
- package/dist/docs/guide/systems/animation-system.md +32 -0
- package/dist/docs/guide/systems/audio-system.md +28 -0
- package/dist/docs/guide/systems/camera-sync-system.md +31 -0
- package/dist/docs/guide/systems/environment-sync-system.md +31 -0
- package/dist/docs/guide/systems/input-system.md +217 -0
- package/dist/docs/guide/systems/light-sync-system.md +29 -0
- package/dist/docs/guide/systems/material-sync-system.md +32 -0
- package/dist/docs/guide/systems/mesh-geometry-system.md +40 -0
- package/dist/docs/guide/systems/object-management-system.md +38 -0
- package/dist/docs/guide/systems/object-visibility-system.md +26 -0
- package/dist/docs/guide/systems/physics-sync-system.md +56 -0
- package/dist/docs/guide/systems/postprocessing-sync-system.md +43 -0
- package/dist/docs/guide/systems/render-system.md +22 -0
- package/dist/docs/guide/systems/script-behaviour-system.md +59 -0
- package/dist/docs/guide/systems/transform-sync-system.md +29 -0
- package/dist/docs/guide/systems/video-system.md +30 -0
- package/dist/docs/guide/world-api.md +405 -0
- package/dist/factories/index.cjs +3077 -0
- package/dist/factories/index.cjs.map +1 -0
- package/dist/factories/index.d.cts +69 -0
- package/dist/factories/index.d.ts +69 -0
- package/dist/factories/index.js +6 -0
- package/dist/factories/index.js.map +1 -0
- package/dist/index-B4-YyUNR.d.cts +73 -0
- package/dist/index-BZUOKeTO.d.ts +73 -0
- package/dist/index.cjs +8584 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +283 -0
- package/dist/index.d.ts +283 -0
- package/dist/index.js +1729 -0
- package/dist/index.js.map +1 -0
- package/dist/systems/index.cjs +5119 -0
- package/dist/systems/index.cjs.map +1 -0
- package/dist/systems/index.d.cts +200 -0
- package/dist/systems/index.d.ts +200 -0
- package/dist/systems/index.js +6 -0
- package/dist/systems/index.js.map +1 -0
- package/dist/types.cjs +4 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +3 -0
- package/dist/types.d.ts +3 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/worldSnapshotUtils.cjs +259 -0
- package/dist/worldSnapshotUtils.cjs.map +1 -0
- package/dist/worldSnapshotUtils.d.cts +3 -0
- package/dist/worldSnapshotUtils.d.ts +3 -0
- package/dist/worldSnapshotUtils.js +4 -0
- package/dist/worldSnapshotUtils.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Material
|
|
2
|
+
|
|
3
|
+
Material catalog for an entity. Tracks the live three.js materials (`materials`, `material`) plus serialized authoring state (`values[]`) mirrored from the inspector. Supports `standard`, `basic`, `phong`, and `physical` PBR types with optional texture map slots. Use `setMaterials`, `updateValue`, `setMaterialType`, `setTextureFiltering`, and `setUseMipmaps` to mutate state — these keep `values[]` and the live three.js materials in sync. Texture URLs use the `localasset://` protocol inside the editor.
|
|
4
|
+
|
|
5
|
+
> **Managed by:** [`MaterialSyncSystem`](../systems/material-sync-system)
|
|
6
|
+
|
|
7
|
+
## Editor inspector
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Properties
|
|
12
|
+
|
|
13
|
+
| Property | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `materials` | `THREE.Material[]` | Live three.js materials currently bound to the entity's mesh (one per submesh). |
|
|
16
|
+
| `material` | `THREE.Material \| null` | Convenience reference to `materials[0]`. `null` when no material is assigned. |
|
|
17
|
+
| `values` | `MaterialValueState[]` | Serialized authoring state (one entry per material in `materials`). Saved with the project. |
|
|
18
|
+
|
|
19
|
+
## API reference
|
|
20
|
+
|
|
21
|
+
- Class: [`MaterialComponent`](../../api/components/classes/MaterialComponent.md)
|
|
22
|
+
- Source: [`core/components/Material.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Material.ts)
|
|
23
|
+
|
|
24
|
+
## Scripting examples
|
|
25
|
+
|
|
26
|
+
::: tip Component access patterns
|
|
27
|
+
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:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Component on the entity this script is on
|
|
31
|
+
const mat = this.getComponent(MaterialComponent);
|
|
32
|
+
|
|
33
|
+
// Component on another entity, found by its scene name
|
|
34
|
+
const other = this.world.getEntityByName("Wall");
|
|
35
|
+
if (other) {
|
|
36
|
+
const mat = this.world.getComponent(other.entityId, MaterialComponent);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
:::
|
|
40
|
+
|
|
41
|
+
### Fade opacity with a sine wave
|
|
42
|
+
|
|
43
|
+
Animate material transparency to create a pulsing ghost or reveal effect. Use `updateValue` so the state persists in the ECS snapshot — `MaterialSyncSystem` applies it to the live material each frame.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { Behaviour, MaterialComponent } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
48
|
+
|
|
49
|
+
export default class MaterialFade extends Behaviour {
|
|
50
|
+
data = {
|
|
51
|
+
speed: 1 as FloatInput,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
private elapsed = 0;
|
|
55
|
+
|
|
56
|
+
protected onUpdate() {
|
|
57
|
+
this.elapsed += this.deltaTime;
|
|
58
|
+
const mat = this.getComponent(MaterialComponent);
|
|
59
|
+
if (!mat) return;
|
|
60
|
+
|
|
61
|
+
const opacity = (Math.sin(this.elapsed * this.data.speed) + 1) * 0.5;
|
|
62
|
+
mat.updateValue(0, 'transparent', true);
|
|
63
|
+
mat.updateValue(0, 'opacity', opacity);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
::: warning Transient vs persistent opacity
|
|
69
|
+
`mat.updateValue(0, 'opacity', value)` keeps `values[]` in sync with the live material — changes survive a project reload.
|
|
70
|
+
|
|
71
|
+
Mutating `mat.material?.opacity` directly can work for transient visual-only effects, but `MaterialSyncSystem` may overwrite it when other material properties change. Prefer `updateValue` for any state you want to persist.
|
|
72
|
+
:::
|
|
73
|
+
|
|
74
|
+
### Change material color at runtime
|
|
75
|
+
|
|
76
|
+
Let the inspector drive the diffuse color live without restarting the scene.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { Behaviour, MaterialComponent } from "@relu-interactives/spatial-ecs";
|
|
80
|
+
import type { ColorInput } from "@relu-interactives/spatial-ecs";
|
|
81
|
+
|
|
82
|
+
export default class MaterialColorDriver extends Behaviour {
|
|
83
|
+
data = {
|
|
84
|
+
color: "#ff0000" as ColorInput,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
private _prev: string | null = null;
|
|
88
|
+
|
|
89
|
+
protected onUpdate() {
|
|
90
|
+
// Guard — only call updateValue when the color actually changes
|
|
91
|
+
if (this.data.color === this._prev) return;
|
|
92
|
+
this._prev = this.data.color;
|
|
93
|
+
|
|
94
|
+
const mat = this.getComponent(MaterialComponent);
|
|
95
|
+
if (!mat) return;
|
|
96
|
+
mat.updateValue(0, 'color', this.data.color);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
::: tip Material sync
|
|
102
|
+
`updateValue(index, key, value)` writes to `values[]` (persisted with the project) and lets `MaterialSyncSystem` apply the change to the live THREE.js material. Mutating `material.color` or other THREE.js properties directly is not saved with the project.
|
|
103
|
+
:::
|
|
104
|
+
|
|
105
|
+
### Via `ComponentInput` in the inspector
|
|
106
|
+
|
|
107
|
+
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 `MaterialComponent` instance at runtime.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import {
|
|
111
|
+
Behaviour,
|
|
112
|
+
MaterialComponent,
|
|
113
|
+
type ComponentInput,
|
|
114
|
+
} from "@relu-interactives/spatial-ecs";
|
|
115
|
+
|
|
116
|
+
export default class Example extends Behaviour {
|
|
117
|
+
data = {
|
|
118
|
+
targetMaterial: {
|
|
119
|
+
type: "component",
|
|
120
|
+
value: null,
|
|
121
|
+
} as unknown as ComponentInput,
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
protected onUpdate() {
|
|
125
|
+
const mat = this.data.targetMaterial.value as MaterialComponent | null;
|
|
126
|
+
if (!mat) return;
|
|
127
|
+
// Use the live component instance.
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Via `EntityInput` in the inspector
|
|
133
|
+
|
|
134
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import {
|
|
138
|
+
Behaviour,
|
|
139
|
+
MaterialComponent,
|
|
140
|
+
type EntityInput,
|
|
141
|
+
type WorldEntityView,
|
|
142
|
+
} from "@relu-interactives/spatial-ecs";
|
|
143
|
+
|
|
144
|
+
export default class Example extends Behaviour {
|
|
145
|
+
data = {
|
|
146
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
protected onUpdate() {
|
|
150
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
151
|
+
if (!entity) return;
|
|
152
|
+
|
|
153
|
+
const mat = this.world.getComponent(
|
|
154
|
+
entity.entityId,
|
|
155
|
+
MaterialComponent,
|
|
156
|
+
) as MaterialComponent | null;
|
|
157
|
+
if (!mat) return;
|
|
158
|
+
// Use the component on the picked entity.
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Mesh Geometry
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
> **Managed by:** [`MeshGeometrySystem`](../systems/mesh-geometry-system)
|
|
6
|
+
|
|
7
|
+
## Properties
|
|
8
|
+
|
|
9
|
+
| Property | Type | Description |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `kind` | `EditableMeshObjectKind` | Primitive kind (`cube`, `sphere`, `plane`, `capsule`, `cylinder`) or `model` for loaded assets. |
|
|
12
|
+
| `geometryType` | `string` | Three.js geometry class name (e.g. `"BoxGeometry"`, `"SphereGeometry"`). Derived from `kind`. |
|
|
13
|
+
| `parameters` | `MeshGeometryParameters` | Editable parameters whose shape depends on `kind`. The mesh-geometry system rebuilds geometry when these change. |
|
|
14
|
+
| `object` | `THREE.Object3D \| null` | Live three.js object whose geometry is being managed. `null` until the object is built. |
|
|
15
|
+
| `modelName` | `string` | Human-readable model name shown in the inspector for `model` entities; empty for primitives. |
|
|
16
|
+
| `castShadow` | `boolean` | Whether the mesh casts shadows in the renderer. |
|
|
17
|
+
| `receiveShadow` | `boolean` | Whether the mesh receives shadows in the renderer. |
|
|
18
|
+
|
|
19
|
+
## API reference
|
|
20
|
+
|
|
21
|
+
- Class: [`MeshGeometryComponent`](../../api/components/classes/MeshGeometryComponent.md)
|
|
22
|
+
- Source: [`core/components/MeshGeometry.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/MeshGeometry.ts)
|
|
23
|
+
|
|
24
|
+
## Scripting examples
|
|
25
|
+
|
|
26
|
+
::: tip Component access patterns
|
|
27
|
+
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:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// Component on the entity this script is on
|
|
31
|
+
const geo = this.getComponent(MeshGeometryComponent);
|
|
32
|
+
|
|
33
|
+
// Component on another entity, found by its scene name
|
|
34
|
+
const other = this.world.getEntityByName("Floor");
|
|
35
|
+
if (other) {
|
|
36
|
+
const geo = this.world.getComponent(other.entityId, MeshGeometryComponent);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
:::
|
|
40
|
+
|
|
41
|
+
### Toggle shadow casting at runtime
|
|
42
|
+
|
|
43
|
+
Let the inspector or game logic control whether the mesh casts and receives shadows.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
|
|
47
|
+
import type { BooleanInput } from "@relu-interactives/spatial-ecs";
|
|
48
|
+
|
|
49
|
+
export default class ShadowDriver extends Behaviour {
|
|
50
|
+
data = {
|
|
51
|
+
castShadow: true as BooleanInput,
|
|
52
|
+
receiveShadow: true as BooleanInput,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
protected onUpdate() {
|
|
56
|
+
const geo = this.getComponent(MeshGeometryComponent);
|
|
57
|
+
if (!geo) return;
|
|
58
|
+
geo.castShadow = this.data.castShadow;
|
|
59
|
+
geo.receiveShadow = this.data.receiveShadow;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Animate sphere radius
|
|
65
|
+
|
|
66
|
+
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.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { Behaviour, MeshGeometryComponent } from "@relu-interactives/spatial-ecs";
|
|
70
|
+
import type { FloatInput } from "@relu-interactives/spatial-ecs";
|
|
71
|
+
|
|
72
|
+
export default class SphereGrow extends Behaviour {
|
|
73
|
+
data = {
|
|
74
|
+
speed: 1 as FloatInput,
|
|
75
|
+
minRadius: 0.3 as FloatInput,
|
|
76
|
+
maxRadius: 1 as FloatInput,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
private elapsed = 0;
|
|
80
|
+
|
|
81
|
+
protected onUpdate() {
|
|
82
|
+
this.elapsed += this.deltaTime;
|
|
83
|
+
const geo = this.getComponent(MeshGeometryComponent);
|
|
84
|
+
if (!geo || geo.kind !== "sphere") return;
|
|
85
|
+
|
|
86
|
+
const t = (Math.sin(this.elapsed * this.data.speed) + 1) * 0.5;
|
|
87
|
+
const radius = this.data.minRadius + t * (this.data.maxRadius - this.data.minRadius);
|
|
88
|
+
(geo.parameters as { radius: number }).radius = radius;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Via `ComponentInput` in the inspector
|
|
94
|
+
|
|
95
|
+
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.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import {
|
|
99
|
+
Behaviour,
|
|
100
|
+
MeshGeometryComponent,
|
|
101
|
+
type ComponentInput,
|
|
102
|
+
} from "@relu-interactives/spatial-ecs";
|
|
103
|
+
|
|
104
|
+
export default class Example extends Behaviour {
|
|
105
|
+
data = {
|
|
106
|
+
targetGeometry: {
|
|
107
|
+
type: "component",
|
|
108
|
+
value: null,
|
|
109
|
+
} as unknown as ComponentInput,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
protected onUpdate() {
|
|
113
|
+
const geo = this.data.targetGeometry.value as MeshGeometryComponent | null;
|
|
114
|
+
if (!geo) return;
|
|
115
|
+
// Use the live component instance.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Via `EntityInput` in the inspector
|
|
121
|
+
|
|
122
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import {
|
|
126
|
+
Behaviour,
|
|
127
|
+
MeshGeometryComponent,
|
|
128
|
+
type EntityInput,
|
|
129
|
+
type WorldEntityView,
|
|
130
|
+
} from "@relu-interactives/spatial-ecs";
|
|
131
|
+
|
|
132
|
+
export default class Example extends Behaviour {
|
|
133
|
+
data = {
|
|
134
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
protected onUpdate() {
|
|
138
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
139
|
+
if (!entity) return;
|
|
140
|
+
|
|
141
|
+
const geo = this.world.getComponent(
|
|
142
|
+
entity.entityId,
|
|
143
|
+
MeshGeometryComponent,
|
|
144
|
+
) as MeshGeometryComponent | null;
|
|
145
|
+
if (!geo) return;
|
|
146
|
+
// Use the component on the picked entity.
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
::: tip Geometry rebuild cost
|
|
152
|
+
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.
|
|
153
|
+
:::
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Mesh
|
|
2
|
+
|
|
3
|
+
Holds the live three.js `Object3D` for an entity that renders as a primitive mesh (cube, sphere, plane, capsule, cylinder). For loaded GLTF/GLB models see `ModelComponent`; for the editable geometry parameters see `MeshGeometryComponent`.
|
|
4
|
+
|
|
5
|
+
## Editor inspector
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Properties
|
|
10
|
+
|
|
11
|
+
| Property | Type | Description |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `mesh` | `THREE.Object3D` | Underlying three.js mesh placed in the scene graph. |
|
|
14
|
+
|
|
15
|
+
## API reference
|
|
16
|
+
|
|
17
|
+
- Class: [`MeshComponent`](../../api/components/classes/MeshComponent.md)
|
|
18
|
+
- Source: [`core/components/Mesh.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Mesh.ts)
|
|
19
|
+
|
|
20
|
+
## Scripting examples
|
|
21
|
+
|
|
22
|
+
::: tip Component access patterns
|
|
23
|
+
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:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// Component on the entity this script is on
|
|
27
|
+
const mesh = this.getComponent(MeshComponent);
|
|
28
|
+
|
|
29
|
+
// Component on another entity, found by its scene name
|
|
30
|
+
const other = this.world.getEntityByName("Terrain");
|
|
31
|
+
if (other) {
|
|
32
|
+
const mesh = this.world.getComponent(other.entityId, MeshComponent);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
:::
|
|
36
|
+
|
|
37
|
+
### Toggle shadow casting on all sub-meshes
|
|
38
|
+
|
|
39
|
+
Walk the mesh hierarchy and enable or disable shadow casting based on a boolean inspector field.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { Behaviour, MeshComponent } from "@relu-interactives/spatial-ecs";
|
|
43
|
+
import type { BooleanInput } from "@relu-interactives/spatial-ecs";
|
|
44
|
+
|
|
45
|
+
export default class ShadowToggle extends Behaviour {
|
|
46
|
+
data = {
|
|
47
|
+
castShadow: true as BooleanInput,
|
|
48
|
+
receiveShadow: true as BooleanInput,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
protected onUpdate() {
|
|
52
|
+
const mesh = this.getComponent(MeshComponent);
|
|
53
|
+
if (!mesh?.mesh) return;
|
|
54
|
+
|
|
55
|
+
mesh.mesh.traverse((child: any) => {
|
|
56
|
+
if (child.isMesh) {
|
|
57
|
+
child.castShadow = this.data.castShadow;
|
|
58
|
+
child.receiveShadow = this.data.receiveShadow;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Change vertex color or material on the raw mesh
|
|
66
|
+
|
|
67
|
+
Access the underlying `THREE.Object3D` directly for low-level material mutations that are not exposed through `MaterialComponent`.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { Behaviour, MeshComponent } from "@relu-interactives/spatial-ecs";
|
|
71
|
+
import type { ColorInput } from "@relu-interactives/spatial-ecs";
|
|
72
|
+
|
|
73
|
+
export default class MeshColorDriver extends Behaviour {
|
|
74
|
+
data = {
|
|
75
|
+
color: "#ffffff" as ColorInput,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
protected onUpdate() {
|
|
79
|
+
const mesh = this.getComponent(MeshComponent);
|
|
80
|
+
if (!mesh?.mesh) return;
|
|
81
|
+
|
|
82
|
+
mesh.mesh.traverse((child: any) => {
|
|
83
|
+
if (child.isMesh && child.material?.color) {
|
|
84
|
+
child.material.color.set(this.data.color);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
::: tip Prefer MaterialComponent for authored changes
|
|
92
|
+
For changes that should persist across save/reload, prefer `MaterialComponent.updateValue()` which keeps the serialised `values[]` in sync. Use `MeshComponent.mesh` for frame-by-frame visual effects only.
|
|
93
|
+
:::
|
|
94
|
+
|
|
95
|
+
### Via `ComponentInput` in the inspector
|
|
96
|
+
|
|
97
|
+
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 `MeshComponent` instance at runtime.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import {
|
|
101
|
+
Behaviour,
|
|
102
|
+
MeshComponent,
|
|
103
|
+
type ComponentInput,
|
|
104
|
+
} from "@relu-interactives/spatial-ecs";
|
|
105
|
+
|
|
106
|
+
export default class Example extends Behaviour {
|
|
107
|
+
data = {
|
|
108
|
+
targetMesh: {
|
|
109
|
+
type: "component",
|
|
110
|
+
value: null,
|
|
111
|
+
} as unknown as ComponentInput,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
protected onUpdate() {
|
|
115
|
+
const mesh = this.data.targetMesh.value as MeshComponent | null;
|
|
116
|
+
if (!mesh) return;
|
|
117
|
+
// Use the live component instance.
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Via `EntityInput` in the inspector
|
|
123
|
+
|
|
124
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import {
|
|
128
|
+
Behaviour,
|
|
129
|
+
MeshComponent,
|
|
130
|
+
type EntityInput,
|
|
131
|
+
type WorldEntityView,
|
|
132
|
+
} from "@relu-interactives/spatial-ecs";
|
|
133
|
+
|
|
134
|
+
export default class Example extends Behaviour {
|
|
135
|
+
data = {
|
|
136
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
protected onUpdate() {
|
|
140
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
141
|
+
if (!entity) return;
|
|
142
|
+
|
|
143
|
+
const mesh = this.world.getComponent(
|
|
144
|
+
entity.entityId,
|
|
145
|
+
MeshComponent,
|
|
146
|
+
) as MeshComponent | null;
|
|
147
|
+
if (!mesh) return;
|
|
148
|
+
// Use the component on the picked entity.
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Model
|
|
2
|
+
|
|
3
|
+
References a GLTF/GLB asset loaded from `path`. The model loading system resolves the asset asynchronously and populates `ModelComponent.object` once available; loading is deferred-tolerant so the entity exists before the model finishes loading.
|
|
4
|
+
|
|
5
|
+
## Properties
|
|
6
|
+
|
|
7
|
+
| Property | Type | Description |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `path` | `string` | Source URL or `localasset://` path of the GLTF/GLB asset. |
|
|
10
|
+
| `object` | `THREE.Object3D \| null` | Loaded model object, populated asynchronously by the model loader. `null` until loaded. |
|
|
11
|
+
|
|
12
|
+
## API reference
|
|
13
|
+
|
|
14
|
+
- Class: [`ModelComponent`](../../api/components/classes/ModelComponent.md)
|
|
15
|
+
- Source: [`core/components/Model.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Model.ts)
|
|
16
|
+
|
|
17
|
+
## Scripting examples
|
|
18
|
+
|
|
19
|
+
::: tip Component access patterns
|
|
20
|
+
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:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// Component on the entity this script is on
|
|
24
|
+
const model = this.getComponent(ModelComponent);
|
|
25
|
+
|
|
26
|
+
// Component on another entity, found by its scene name
|
|
27
|
+
const other = this.world.getEntityByName("Robot");
|
|
28
|
+
if (other) {
|
|
29
|
+
const model = this.world.getComponent(other.entityId, ModelComponent);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
:::
|
|
33
|
+
|
|
34
|
+
### Fade the model in after it loads
|
|
35
|
+
|
|
36
|
+
Wait for the async model load to complete, then animate opacity to 1 over one second.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { Behaviour, ModelComponent } from "@relu-interactives/spatial-ecs";
|
|
40
|
+
|
|
41
|
+
export default class ModelFadeIn extends Behaviour {
|
|
42
|
+
private fadeProgress = 0;
|
|
43
|
+
private started = false;
|
|
44
|
+
|
|
45
|
+
protected onUpdate() {
|
|
46
|
+
const model = this.getComponent(ModelComponent);
|
|
47
|
+
if (!model?.object) return; // wait for async load to complete
|
|
48
|
+
|
|
49
|
+
if (!this.started) {
|
|
50
|
+
this.started = true;
|
|
51
|
+
// Initialise all sub-mesh materials to transparent before fading in
|
|
52
|
+
model.object.traverse((child: any) => {
|
|
53
|
+
if (child.isMesh && child.material) {
|
|
54
|
+
child.material.transparent = true;
|
|
55
|
+
child.material.opacity = 0;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.fadeProgress = Math.min(1, this.fadeProgress + this.deltaTime);
|
|
61
|
+
model.object.traverse((child: any) => {
|
|
62
|
+
if (child.isMesh && child.material) {
|
|
63
|
+
child.material.opacity = this.fadeProgress;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Toggle model visibility
|
|
71
|
+
|
|
72
|
+
Show or hide the loaded model at runtime using the `Object3DRef` visibility flag.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { Behaviour, ModelComponent, Object3DRef } from "@relu-interactives/spatial-ecs";
|
|
76
|
+
import type { BooleanInput } from "@relu-interactives/spatial-ecs";
|
|
77
|
+
|
|
78
|
+
export default class ModelVisibility extends Behaviour {
|
|
79
|
+
data = {
|
|
80
|
+
visible: true as BooleanInput,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
protected onUpdate() {
|
|
84
|
+
const model = this.getComponent(ModelComponent);
|
|
85
|
+
if (!model?.object) return; // still loading
|
|
86
|
+
|
|
87
|
+
const ref = this.getComponent(Object3DRef);
|
|
88
|
+
if (ref) ref.visibility = this.data.visible;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
::: tip Async loading
|
|
94
|
+
Always guard with `model?.object` before traversing or mutating sub-meshes. The `object` property is `null` until the GLTF/GLB asset finishes loading.
|
|
95
|
+
:::
|
|
96
|
+
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Name
|
|
2
|
+
|
|
3
|
+
Human-readable name for an entity. Shown in the editor hierarchy panel and preserved across save/reload.
|
|
4
|
+
|
|
5
|
+
## Editor inspector
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Properties
|
|
10
|
+
|
|
11
|
+
| Property | Type | Description |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| `value` | `string` | Display name for the entity. Shown in the editor hierarchy. |
|
|
14
|
+
|
|
15
|
+
## API reference
|
|
16
|
+
|
|
17
|
+
- Class: [`Name`](../../api/components/classes/Name.md)
|
|
18
|
+
- Source: [`core/components/Name.ts`](https://github.com/Relu-Interactives/relu-spatial-ecs-engine/blob/main/core/components/Name.ts)
|
|
19
|
+
|
|
20
|
+
## Scripting examples
|
|
21
|
+
|
|
22
|
+
::: tip Component access patterns
|
|
23
|
+
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:
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// Component on the entity this script is on
|
|
27
|
+
const name = this.getComponent(Name);
|
|
28
|
+
|
|
29
|
+
// Component on another entity, found by its scene name
|
|
30
|
+
const other = this.world.getEntityByName("Player");
|
|
31
|
+
if (other) {
|
|
32
|
+
const name = this.world.getComponent(other.entityId, Name);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
:::
|
|
36
|
+
|
|
37
|
+
### Drive the display name from the inspector
|
|
38
|
+
|
|
39
|
+
Rename the entity at runtime from an inspector string field. Useful for dynamic labels or debug output.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { Behaviour, Name } from "@relu-interactives/spatial-ecs";
|
|
43
|
+
import type { StringInput } from "@relu-interactives/spatial-ecs";
|
|
44
|
+
|
|
45
|
+
export default class EntityRenamer extends Behaviour {
|
|
46
|
+
data = {
|
|
47
|
+
displayName: "My Entity" as StringInput,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
protected onUpdate() {
|
|
51
|
+
const name = this.getComponent(Name);
|
|
52
|
+
if (name && name.value !== this.data.displayName) {
|
|
53
|
+
name.value = this.data.displayName;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Find another entity by name
|
|
60
|
+
|
|
61
|
+
Query all `Name` components to locate a sibling entity and read its position.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Behaviour, Name, TransformComponent } from "@relu-interactives/spatial-ecs";
|
|
65
|
+
import type { StringInput } from "@relu-interactives/spatial-ecs";
|
|
66
|
+
|
|
67
|
+
export default class LookAtTarget extends Behaviour {
|
|
68
|
+
data = {
|
|
69
|
+
targetName: "Target" as StringInput,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
protected onUpdate() {
|
|
73
|
+
let targetTransform: TransformComponent | null = null;
|
|
74
|
+
|
|
75
|
+
for (const [id, nameComp] of this.world.query([Name])) {
|
|
76
|
+
if (nameComp.value === this.data.targetName) {
|
|
77
|
+
targetTransform = this.world.getComponent(id, TransformComponent);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!targetTransform) return;
|
|
83
|
+
|
|
84
|
+
// Rotate to face the target on the Y axis
|
|
85
|
+
const dx = targetTransform.position.x - this.transform.position.x;
|
|
86
|
+
const dz = targetTransform.position.z - this.transform.position.z;
|
|
87
|
+
this.transform.rotation.y = Math.atan2(dx, dz);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Via `EntityInput` in the inspector
|
|
93
|
+
|
|
94
|
+
Alternatively, pick an entity from the inspector using an `EntityInput` field and then read the component off that entity via `world.getComponent`:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import {
|
|
98
|
+
Behaviour,
|
|
99
|
+
Name,
|
|
100
|
+
type EntityInput,
|
|
101
|
+
type WorldEntityView,
|
|
102
|
+
} from "@relu-interactives/spatial-ecs";
|
|
103
|
+
|
|
104
|
+
export default class Example extends Behaviour {
|
|
105
|
+
data = {
|
|
106
|
+
targetEntity: { type: "entity", value: null } as unknown as EntityInput,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
protected onUpdate() {
|
|
110
|
+
const entity = this.data.targetEntity.value as WorldEntityView | null;
|
|
111
|
+
if (!entity) return;
|
|
112
|
+
|
|
113
|
+
const nameComp = this.world.getComponent(
|
|
114
|
+
entity.entityId,
|
|
115
|
+
Name,
|
|
116
|
+
) as Name | null;
|
|
117
|
+
if (!nameComp) return;
|
|
118
|
+
// Use the component on the picked entity.
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|