-
Notifications
You must be signed in to change notification settings - Fork 2
Component Overview
Entities are defined by combining a variety of components. These components define information such as position, rendering settings, physics properties, etc... This information is then used by various systems inside Stray Photons to simulate and render the world.
Component definitions can be found in the src/core/ecs/components/ Directory
This component is required by all entities. While names are optional when defining an entity, an auto-generated name will be filled in if necessary so that the entity can be referenced.
Names are in the form:
<scene_name>:<entity_name>
An example could be hello_world:platform
.
By leaving out the scene qualifier, names can also be defined relative to their entity scope. Inside the scene definiton the entity scope might be "hello_world:", meaning both hello_world:platform
and platform
would reference the same entity.
Relative names specified in a template take the form:
<scene_name>:<root_name>.<relative_name>
The special scoperoot
alias can also be used inside a template to reference the parent entity.
transform Field |
Type | Default Value | Description |
---|---|---|---|
parent | string | none | An entity name to position this entity relative to. If no parent is specified, it is positioned relative to [0, 0, 0]
|
translate | vec3 | [0, 0, 0] | The position of the object in 3D space, relative to parent or the origin. |
rotate | vector<vec4> | [] | A list of rotations to be performed in order. Format: [angle_degrees, axis_x, axis_y, axis_z]
|
scale | vec3 | [1, 1, 1] | A scale factor to be applied to this entity and all child entities. |
Multiple entities can be used with transforms to create a tree of entities that all move together.
Transforms are combined in the following way:
scale -> rotate -> translate ( -> parent transform)
Vector field types can be specified in 2 formats:
"rotate": [[90, 1, 0, 0], [-90, 0, 1, 0]]
or a single combined rotation:
"rotate": [120, 1, -1, -1]
The rotation axis is automatically normalized.
Note: When combinding multiple transformations together with scaling factors, behavior is undefined if the combinations introduce skew. (Scale should be axis-aligned to the model)
renderable Field |
Type | Default Value | Description |
---|---|---|---|
model | string | none | Name of the GLTF model to display |
mesh_index | size_t | 0 | Index of the mesh within the GLTF model |
visibility | "None", "DirectCamera", "DirectEye", "Transparent", "LightingShadow", "LightingVoxel", "Optics", "OutlineSelection" | "DirectCamera|DirectEye|LightingShadow|LightingVoxel" | Visibility mask for different render passes |
emissive | float | 0.0 | Emissive multiplier to turn this model into a light source |
color_override | vec4 | none | Override the mesh's texture to a flat RGBA color |
metallic_roughness_override | vec2 | none | Override the mesh's metallic and roughness material properties |
Models are loaded from the assets/models/
folder. .glb
and .gltf
are supported,
and models can be loaded from either assets/models/<model_name>.gltf
or assets/models/<model_name>/model_name.gltf
.
Note for GLTF models with multiple meshes:
It is usually preferred to load the model using the gltf
prefab script to automatically generate the correct transform tree and entity structure.
See the definition here: https://github.com/frustra/strayphotons/blob/master/src/scripts/prefabs/GltfPrefab.cc
Physics Field |
Type | Default Value |
---|---|---|
shapes | vector<PhysicsShape > |
[] |
group | "NoClip", "World", "Interactive", "HeldObject", "Player", "PlayerLeftHand", "PlayerRightHand", "UserInterface" | "World" |
type | "Static", "Dynamic", "Kinematic", "SubActor" | "Dynamic" |
parent_actor | EntityRef | none |
mass | float | 0.0 |
density | float | 1000.0 |
angular_damping | float | 0.05 |
linear_damping | float | 0.0 |
contact_report_force | float | -1.0 |
force | vec3 | [0, 0, 0] |
Most physics shapes correlate with the underlying PhysX Geometry Shapes. The diagrams provided in the PhysX docs may be helpful in visualizing collisions.
Note: Only one of model
, plane
, capsule
, sphere
, or box
may be specified per shape.
PhysicsShape Field |
Type | Default Value | Description |
---|---|---|---|
model | ConvexMesh | none | Name of the GLTF cooked physics collisions to load |
plane | Plane | N/A | Planes face the +X axis relative to the actor |
capsule | Capsule | { "radius": 0.5, "height": 1.0 } | A capsule's total length along the X axis will be equal to height + radius * 2
|
sphere | float | 1.0 | Spheres are defined by their radius |
box | vec3 | [1.0, 1.0, 1.0] | Boxes define their dimensions by specifying the total length along the X, Y, and X axes relative to the actor |
transform | Transform |
none | See transform Component
|
static_friction | float | 0.6 | A scalar >= 0.0 for this shape's material static friction |
dynamic_friction | float | 0.5 | A scalar >= 0.0 for this shape's material dynamic friction |
restitution | float | 0.0 | A scalar 0.0 - 1.0 representing the percentage energy absorbed on impact |
animation Field |
Type | Default Value |
---|---|---|
states | vector<AnimationState > |
[] |
interpolation | "Step", "Linear", or "Cubic" | "Linear" |
cubic_tension | float | 0.5 |
Animations control the position of an entity by moving it between a set of animation states. Animation updates happen in the physics thread before each simulation step.
When an animation state is defined, the transform
position is ignored except for the transform parent, using the pose from the animation.
Animations read and write two signal values:
-
animation_state - The current state index represented as a double from
0.0
toN-1.0
.
A state value of0.5
represents a state half way between states 0 and 1 based on transition time. - animation_target - The target state index. The entity will always animate towards this state.
The animation is running any time these values are different, and paused when they are equal.
AnimationState Field |
Type | Default Value | Description |
---|---|---|---|
delay | double | 0.0 | Time to move to this state from any other state |
translate | vec3 | [0, 0, 0] | A new position to override this entity's transform
|
scale | vec3 | none | A new scale to override this entity's transform
|
translate_tangent | vec3 | [0, 0, 0] | Cubic interpolation tangent for translate |
scale_tangent | vec3 | [0, 0, 0] | Cubic interpolation tangent for scale |
An example of a 3-state linear animation might look like this:
"animation": {
"states": [
{
"delay": 0.5,
"translate": [0, 0, 0]
},
{
"delay": 0.5,
"translate": [0, 1, 0]
},
{
"delay": 0.5,
"translate": [0, 0, 1]
}
]
}
When moving from state 2.0
to state 0.0
, the animation will follow the path through state 1.0
, rather than moving directly to the target position. The animation_state
signal can however be manually controlled to teleport the animation to a specific state.
Global Components are not attached to a specific entity, and instead there can be up to 1 global instance of each global component.