systemManager.findSystem<SceneObjectSystem>().getSceneObject(myEntity)?.thenAccept { sceneObject -> sceneObject.addInputListener(myInputListener) }
open class SceneObject
SceneObject
(
scene
, mesh
, name
, entity
)
|
Constructor for a SceneObject.
Signature
constructor(scene: Scene, mesh: SceneMesh, name: String, entity: Entity? = null) Parameters Returns |
SceneObject
(
scene
, entity
)
|
Constructor for a SceneObject.
Signature
constructor(scene: Scene, entity: Entity? = null) Parameters Returns |
entity
: Entity?
[Get] |
Signature
val entity: Entity? |
handle
: Long
[Get] |
Signature
var handle: Long |
materials
: List?
[Get] |
Read-only list of SceneMaterials created from this SceneObject's mesh property.
You can read materials from this list and modify their properties (e.g., colors, textures), but you cannot replace a material at a specific index with a different material object. Changes to material properties will be unique to this SceneObject, but these materials will inherit any changes made in the SceneMesh they come from.
Materials are lazily populated on first access. This triggers material instance creation and marks the entity as dirty for rendering. If you don't need to customize materials, avoid accessing this property to improve performance.
Example usage:
// ✅ Allowed: Read and modify material properties
sceneObject.materials?.get(0)?.setColor(Color4(1f, 0f, 0f, 1f))
sceneObject.materials?.getOrNull(1)?.setTexture("albedo", myTexture)
sceneObject.materials?.forEach { it.setRoughness(0.5f) }
// ❌ Not allowed: Replace material at index (compile error)
// sceneObject.materials?.set(0, differentMaterial) // Compile error - List is immutable
// sceneObject.materials[0] = differentMaterial // Compile error - no set operator
Signature
val materials: List<SceneMaterial>? |
mesh
: SceneMesh?
[Get][Set] |
Reference to the SceneMesh used by this SceneObject. This property is a reference to the underlying mesh resource. Changes to the SceneMesh or its SceneMaterials will be reflected across all SceneObjects that reference it.
Signature
var mesh: SceneMesh? |
addInputListener
(
listener
)
|
Add an input listener to this SceneObject.
Signature
fun addInputListener(listener: InputListener): Long Parameters Returns
Long
|
destroy
()
|
Destory this SceneObject.
Signature
fun destroy() |
destroyInternal
()
|
Destroy this SceneObject's native components.
Signature
open fun destroyInternal() |
onClick
(
hitInfo
, sourceOfInput
)
| |
onClickDown
(
hitInfo
, sourceOfInput
)
|
Handler for click downs on this SceneObject. Use onClick() to ensure user releases the click on the SceneObject.
Signature
fun onClickDown(hitInfo: HitInfo, sourceOfInput: Entity) |
onHoverStart
(
sourceOfInput
)
|
Handler for the start of hovers on this SceneObject.
Signature
open fun onHoverStart(sourceOfInput: Entity) Parameters |
onHoverStop
(
sourceOfInput
)
|
Handler for the termination of hovers on this SceneObject.
Signature
open fun onHoverStop(sourceOfInput: Entity) Parameters |
onInput
(
hitInfo
, sourceOfInput
, changed
, buttonState
, downTime
)
|
Handler to handle generic input.
Signature
open fun onInput(hitInfo: HitInfo, sourceOfInput: Entity, changed: Int, buttonState: Int, downTime: Long): Boolean Parameters
changed:
Int
buttonState:
Int
downTime:
Long
Returns
Boolean
|
onPointerEvent
(
hitInfo
, type
, sourceOfInput
, scrollInfo
, semanticType
)
|
Handler to handle pointer events on this SceneObject.
Signature
open fun onPointerEvent(hitInfo: HitInfo, type: Int, sourceOfInput: Entity, scrollInfo: Vector2, semanticType: Int = SemanticType.Unknown.id) Parameters
type:
Int
semanticType:
Int
|
removeInputListener
(
id
)
|
Remove an input listener by id.
Signature
fun removeInputListener(id: Long) Parameters
id:
Long
|
setIsVisible
(
isVisible
)
|
Set whether this SceneObject is visible.
Signature
fun setIsVisible(isVisible: Boolean) Parameters
isVisible:
Boolean
|
setLocalNodePose
(
node
, pose
)
|
Sets the local transform of the node (relative to it's parent) to the input pose
Signature
fun setLocalNodePose(node: Int, pose: Pose) Parameters
node:
Int
|
setLocalNodePoses
(
nodePoses
)
|
Sets the local transforms of multiple nodes (relative to their parents) using a map of node ids to poses. This is more efficient than calling setLocalNodePose multiple times as it performs a single batch update.
Signature
fun setLocalNodePoses(nodePoses: Map<Int, Pose>) Parameters
nodePoses:
Map
|
setLocalNodePoses
(
poses
)
|
Sets the local transforms of multiple nodes (relative to their parents) using a list of poses. This is more efficient than calling setLocalNodePose multiple times as it performs a single batch update. Nodes are indexed sequentially starting from 0.
Signature
fun setLocalNodePoses(poses: List<Pose>) Parameters
poses:
List
|
setLocalNodePosesRange
(
fromNode
, count
, poses
)
|
Sets the local transforms of a range of nodes (relative to their parents) using a list of poses. This is more efficient than calling setLocalNodePose multiple times as it performs a single batch update.
Signature
fun setLocalNodePosesRange(fromNode: Int, count: Int, poses: List<Pose>) Parameters
fromNode:
Int
count:
Int
poses:
List
|
setLocalNodeTransformsBatch
(
nodes
, transforms
, components
)
|
Sets the local transforms of multiple nodes (relative to their parents) using direct FloatArray buffers. This is the most efficient way to update multiple nodes as it avoids intermediate object allocations. Use this for performance-critical batch updates.
Transform data format depends on components flags:
Components not set will retain their previous values.
Signature
fun setLocalNodeTransformsBatch(nodes: IntArray, transforms: FloatArray, components: Int = TRANSFORM_TRANSLATION_ROTATION) Parameters
nodes:
IntArray
transforms:
FloatArray
components:
Int
|
setLocalNodeTransformsRange
(
fromNode
, toNode
, transforms
, components
)
|
Sets the local transforms of a contiguous range of nodes (relative to their parents) using direct FloatArray buffers. This is the most efficient way to update a range of nodes as it avoids intermediate object allocations. Use this for performance-critical batch updates.
Transform data format depends on components flags:
Components not set will retain their previous values.
Signature
fun setLocalNodeTransformsRange(fromNode: Int, toNode: Int, transforms: FloatArray, components: Int = TRANSFORM_TRANSLATION_ROTATION) Parameters
fromNode:
Int
toNode:
Int
transforms:
FloatArray
components:
Int
|
setPosition
(
x
, y
, z
)
|
Set the 3D position of this SceneObject.
Signature
fun setPosition(x: Float, y: Float, z: Float) Parameters
x:
Float
y:
Float
z:
Float
|
setPosition
(
position
)
|
Set the 3D position of this SceneObject.
Signature
fun setPosition(position: Vector3) Parameters |
setRotation
(
pitch
, yaw
, roll
)
|
Set the rotation of this SceneObject.
Signature
fun setRotation(pitch: Float, yaw: Float, roll: Float) Parameters
pitch:
Float
yaw:
Float
roll:
Float
|
setRotationQuat
(
x
, y
, z
, w
)
|
Set the rotation of this SceneObject.
Signature
fun setRotationQuat(x: Float, y: Float, z: Float, w: Float) Parameters
x:
Float
y:
Float
z:
Float
w:
Float
|
setRotationQuat
(
quat
)
|
Set the rotation of this SceneObject.
Signature
fun setRotationQuat(quat: Quaternion) Parameters |
setScale
(
scale
)
|
Set the scale of the model. The default value is 1.0f.
Signature
open fun setScale(scale: Vector3) Parameters |
setSceneMesh
(
mesh
, name
)
| |
shouldFrustumCull
(
cull
)
|
Whether this SceneObject can be frustum culled (default is true)
Signature
fun shouldFrustumCull(cull: Boolean) Parameters
cull:
Boolean
|
stopInput
(
sourceOfInput
, downTime
)
|
This function calls the stopInput function on all InputListener for this SceneObject. This is called automatically by Scene when handling inputs.
Signature
open fun stopInput(sourceOfInput: Entity, downTime: Long) Parameters
downTime:
Long
|
updateAnimationTrackToTime
(
track
, timeInSeconds
)
|
Update the local transforms of the model to match the given animation track at the specified time (matching keyframe time in the glTF).
Track can be found from SceneMesh.getAnimationTracks
Signature
fun updateAnimationTrackToTime(track: Int, timeInSeconds: Float) Parameters
track:
Int
timeInSeconds:
Float
|
updateNodeLocalPoseToObjectPose
(
node
, pose
)
|
Sets the local transform of a node (relative to it's parent) such that the resulting object transform (relative to the model) is placed at the input pose
WARNING: This may be an expensive operation as it recalculates object positions
Signature
fun updateNodeLocalPoseToObjectPose(node: Int, pose: Pose) Parameters
node:
Int
|
updateSceneMesh
(
meshModifier
)
|
Modify and update this SceneObject's mesh.
Signature
fun updateSceneMesh(meshModifier: SceneMesh.() -> Unit) Parameters
meshModifier:
Function1
|
TRANSFORM_ALL
: Int
[Get] |
Transform component flag for all components (translation, rotation, scale)
Signature
const val TRANSFORM_ALL: Int |
TRANSFORM_RESET_UNSPECIFIED
: Int
[Get] |
Transform flag to reset nodes not explicitly updated to their GLTF default values. When this flag is set, any nodes not included in the update will be reset to their original GLTF local transform (translation, rotation, scale) before applying the specified updates.
When to use this flag:
Use this when animating a subset of nodes and you want to ensure other nodes don't retain stale values from previous updates. This is particularly useful when switching between different animation states that affect different node subsets.
Example: // Animate only nodes [5, 10, 15] and reset all others to GLTF defaults
sceneObject.setLocalNodeTransformsBatch(
nodes = intArrayOf(5, 10, 15),
transforms = animationData,
components = TRANSFORM_TRANSLATION_ROTATION or TRANSFORM_RESET_UNSPECIFIED
)
// Now: nodes 5,10,15 have custom animation, all others are at GLTF defaults
Without this flag, nodes not in the update would retain their previous transform values, which may not be desired when switching animation modes.
Signature
const val TRANSFORM_RESET_UNSPECIFIED: Int = 8 |
TRANSFORM_ROTATION
: Int
[Get] |
Transform component flag for rotation (qw, qx, qy, qz)
Signature
const val TRANSFORM_ROTATION: Int = 2 |
TRANSFORM_SCALE
: Int
[Get] |
Transform component flag for scale (sx, sy, sz)
Signature
const val TRANSFORM_SCALE: Int = 4 |
TRANSFORM_TRANSLATION
: Int
[Get] |
Transform component flag for translation (tx, ty, tz)
Signature
const val TRANSFORM_TRANSLATION: Int = 1 |
TRANSFORM_TRANSLATION_ROTATION
: Int
[Get] |
Default transform components (translation and rotation, no scale)
Signature
const val TRANSFORM_TRANSLATION_ROTATION: Int |
setLocalNodeTransformsBatch
(
sceneObjects
, transforms
, components
)
|
Sets the local transforms of all nodes across multiple SceneObjects using a single JNI call. This is the most efficient way to update multiple SceneObjects as it performs a single batch update across all objects. Use this for performance-critical updates of many SceneObjects.
Performance Characteristics:
Thread Safety:
Error Handling:
Data Format:
Transform data format depends on components flags:
Quaternion order in array: w, x, y, z (matches glm::quat constructor)
The transforms array should contain transform data for all nodes of all SceneObjects concatenated together.
Example: // Update 20 animated characters with 50 nodes each
val characters: Array<SceneObject> = ...
val transforms = FloatArray(20 * 50 * 7) // 7 floats per node (pos + rot)
// Fill transforms with animation data...
for (i in 0 until 20) {
for (j in 0 until 50) {
val offset = (i * 50 + j) * 7
// Set node j of character i
transforms[offset] = tx
transforms[offset + 1] = ty
// ... etc
}
}
// Single JNI call updates all 1000 nodes across 20 objects
SceneObject.setLocalNodeTransformsBatch(characters, transforms)
Example with default (TRANSFORM_TRANSLATION_ROTATION): If you have 2 SceneObjects, the first with 3 nodes and the second with 2 nodes, the transforms array should contain 5 * 7 = 35 floats total:
Signature
fun setLocalNodeTransformsBatch(sceneObjects: Array<SceneObject>, transforms: FloatArray, components: Int = TRANSFORM_TRANSLATION_ROTATION) Parameters
sceneObjects:
Array
transforms:
FloatArray
components:
Int
Throws
IllegalArgumentException
IllegalStateException
|
setLocalNodeTransformsBatch
(
sceneObjects
, nodes
, transforms
, components
)
|
Sets the local transforms of specific nodes across multiple SceneObjects using a single JNI call. This is the most efficient way to update the same subset of nodes across many SceneObjects. Use this for performance-critical sparse updates of many SceneObjects.
Performance Characteristics:
Thread Safety:
Error Handling:
Data Format:
Transform data format depends on components flags:
Quaternion order in array: w, x, y, z (matches glm::quat constructor)
The same nodes are updated on all SceneObjects. The transforms array should contain transform data for each node of each SceneObject concatenated together.
Example: // Update root nodes (1,4,7) on 100 animated characters
val characters: Array<SceneObject> = ...
val rootNodes = intArrayOf(1, 4, 7)
val transforms = FloatArray(100 * 3 * 7) // 7 floats per node (pos + rot)
// Fill transforms for each character's root nodes
for (i in 0 until 100) {
for (j in 0 until 3) {
val offset = (i * 3 + j) * 7
// Set root node j of character i
transforms[offset] = tx
transforms[offset + 1] = ty
// ... etc
}
}
// Single JNI call updates 300 nodes across 100 objects
SceneObject.setLocalNodeTransformsBatch(characters, rootNodes, transforms)
Example with default (TRANSFORM_TRANSLATION_ROTATION): If you have 2 SceneObjects and want to update nodes 1, 4, 7 on both, the transforms array should contain 2 * 3 * 7 = 42 floats total:
Signature
fun setLocalNodeTransformsBatch(sceneObjects: Array<SceneObject>, nodes: IntArray, transforms: FloatArray, components: Int = TRANSFORM_TRANSLATION_ROTATION) Parameters
sceneObjects:
Array
nodes:
IntArray
transforms:
FloatArray
components:
Int
Throws
IllegalArgumentException
IllegalStateException
|