simvx.core.nodes_3d.sprite

Sprite3D, SpriteAnimation3D, AnimatedSprite3D – billboarded sprites in 3D.

Module Contents

Classes

Sprite3D

Billboarded textured quad in 3D space.

SpriteAnimation3D

Named sprite animation with frame indices and playback settings.

AnimatedSprite3D

Animated billboarded sprite in 3D space.

API

class simvx.core.nodes_3d.sprite.Sprite3D(texture=None, **kwargs)[source]

Bases: simvx.core.nodes_3d.node3d.Node3D

Billboarded textured quad in 3D space.

Like Text3D but for images. Renders a textured quad positioned in the 3D world, optionally billboarded to always face the camera. Used for health bars, retro-3D sprites, vegetation cards, and particle-like effects.

The texture property holds a file path; the graphics backend loads it and stores the GPU index in _texture_id. The pixel_size property controls how many world units each pixel occupies.

Example::

sprite = Sprite3D(texture="tree.png", position=(0, 1, -5))
sprite.pixel_size = 0.01
sprite.billboard = True

Initialization

texture

‘Property(…)’

pixel_size

‘Property(…)’

billboard

‘Property(…)’

flip_h

‘Property(…)’

flip_v

‘Property(…)’

modulate

‘Property(…)’

centered

‘Property(…)’

offset

‘Property(…)’

alpha_cut

‘Property(…)’

render_priority

‘Property(…)’

region_enabled

‘Property(…)’

region_rect

‘Property(…)’

property texture_size: tuple[int, int]

Native texture size in pixels (width, height). Set by the graphics backend.

get_quad_size() simvx.core.math.types.Vec2[source]

Return the quad’s world-space size based on pixel_size and texture/region dimensions.

Returns: Vec2 with (width, height) in world units.

get_uv_rect() tuple[float, float, float, float][source]

Return (u0, v0, u1, v1) UV coordinates, accounting for region and flip.

Returns: Tuple of (u0, v0, u1, v1) in 0-1 normalised texture space.

get_aabb()[source]

Return axis-aligned bounding box for frustum culling.

Returns: AABB centred on the node’s global position, sized by the quad dimensions.

draw(renderer) None[source]

Emit a billboarded textured quad for the renderer.

render_layer

‘Property(…)’

property position
property rotation: simvx.core.math.types.Quat
property scale
property rotation_degrees: simvx.core.math.types.Vec3
property world_position: simvx.core.math.types.Vec3
property world_rotation: simvx.core.math.types.Quat
property world_scale: simvx.core.math.types.Vec3
property forward: simvx.core.math.types.Vec3
property right: simvx.core.math.types.Vec3
property up: simvx.core.math.types.Vec3
translate(offset: tuple[float, float, float] | numpy.ndarray)
translate_global(offset: tuple[float, float, float] | numpy.ndarray)
rotate(axis: tuple[float, float, float] | numpy.ndarray, angle: float)
rotate_x(angle: float)
rotate_y(angle: float)
rotate_z(angle: float)
look_at(target: tuple[float, float, float] | numpy.ndarray, up=None)
set_render_layer(index: int, enabled: bool = True) None
is_on_render_layer(index: int) bool
wrap_bounds(bounds: tuple[float, float, float] | numpy.ndarray, margin: float = 1.0)
strict_errors: ClassVar[bool]

True

script_error_raised

‘Signal(…)’

classmethod __init_subclass__(**kwargs)
property name: str
property process_mode: simvx.core.descriptors.ProcessMode
reset_error() None
add_child(node: simvx.core.node.Node) simvx.core.node.Node
remove_child(node: simvx.core.node.Node)
reparent(new_parent: simvx.core.node.Node)
get_node(path: str) simvx.core.node.Node
find_child(name: str, recursive: bool = False) simvx.core.node.Node | None
find(node_type: type, recursive: bool = True) simvx.core.node.Node | None
find_all(node_type: type, recursive: bool = True) list
property path: str
add_to_group(group: str)
remove_from_group(group: str)
is_in_group(group: str) bool
ready() None
enter_tree() None
exit_tree() None
process(dt: float) None
physics_process(dt: float) None
input_event(event: simvx.core.events.InputEvent) None
input(event: simvx.core.events.TreeInputEvent) None
unhandled_input(event: simvx.core.events.TreeInputEvent) None
start_coroutine(gen: simvx.core.descriptors.Coroutine) simvx.core.descriptors.CoroutineHandle
stop_coroutine(gen_or_handle)
clear_children()
destroy()
property app
property tree: simvx.core.scene_tree.SceneTree
get_tree() simvx.core.scene_tree.SceneTree
__getitem__(key: str)
classmethod get_properties() dict[str, simvx.core.descriptors.Property]
__repr__()
class simvx.core.nodes_3d.sprite.SpriteAnimation3D[source]

Named sprite animation with frame indices and playback settings.

name: str

None

frames: list[int]

None

fps: float

10.0

loop: bool

True

class simvx.core.nodes_3d.sprite.AnimatedSprite3D(texture=None, frames_horizontal: int = 1, frames_vertical: int = 1, **kwargs)[source]

Bases: simvx.core.nodes_3d.sprite.Sprite3D

Animated billboarded sprite in 3D space.

Plays frame-based animations from a sprite sheet, mirroring AnimatedSprite2D but positioned in 3D world space with billboard support.

Example::

sprite = AnimatedSprite3D(
    texture="enemy_sheet.png",
    frames_horizontal=4,
    frames_vertical=2,
    position=(0, 1, -5),
)
sprite.add_animation("walk", frames=[0, 1, 2, 3], fps=10, loop=True)
sprite.add_animation("die", frames=[4, 5, 6, 7], fps=8, loop=False)
sprite.play("walk")

Initialization

speed_scale

‘Property(…)’

frame_changed

‘Signal(…)’

animation_finished

‘Signal(…)’

add_animation(name: str, frames: list[int], fps: float = 10.0, loop: bool = True)[source]

Register a named animation.

Args: name: Animation identifier. frames: List of frame indices into the sprite sheet. fps: Playback speed in frames per second. loop: Whether the animation loops.

play(animation_name: str = 'default')[source]

Start playing a named animation.

If the animation name is not registered, a default animation covering all frames in the sheet is created automatically.

stop()[source]

Stop animation at current frame.

pause()[source]

Pause animation (alias for stop).

resume()[source]

Resume animation from current frame.

process(dt: float)[source]

Advance animation by dt seconds, respecting speed_scale.

get_current_frame_index() int[source]

Get the absolute frame index in the sprite sheet.

get_frame_uv() tuple[simvx.core.math.types.Vec2, simvx.core.math.types.Vec2][source]

Get UV coordinates for the current frame (top-left, bottom-right).

Returns: Tuple of (uv0, uv1) as Vec2, with flip applied.

get_uv_rect() tuple[float, float, float, float][source]

Override to use sprite-sheet frame UVs instead of region_rect.

get_quad_size() simvx.core.math.types.Vec2[source]

Override: frame size is texture size divided by sheet grid dimensions.

texture

‘Property(…)’

pixel_size

‘Property(…)’

billboard

‘Property(…)’

flip_h

‘Property(…)’

flip_v

‘Property(…)’

modulate

‘Property(…)’

centered

‘Property(…)’

offset

‘Property(…)’

alpha_cut

‘Property(…)’

render_priority

‘Property(…)’

region_enabled

‘Property(…)’

region_rect

‘Property(…)’

property texture_size: tuple[int, int]
get_aabb()
draw(renderer) None
render_layer

‘Property(…)’

property position
property rotation: simvx.core.math.types.Quat
property scale
property rotation_degrees: simvx.core.math.types.Vec3
property world_position: simvx.core.math.types.Vec3
property world_rotation: simvx.core.math.types.Quat
property world_scale: simvx.core.math.types.Vec3
property forward: simvx.core.math.types.Vec3
property right: simvx.core.math.types.Vec3
property up: simvx.core.math.types.Vec3
translate(offset: tuple[float, float, float] | numpy.ndarray)
translate_global(offset: tuple[float, float, float] | numpy.ndarray)
rotate(axis: tuple[float, float, float] | numpy.ndarray, angle: float)
rotate_x(angle: float)
rotate_y(angle: float)
rotate_z(angle: float)
look_at(target: tuple[float, float, float] | numpy.ndarray, up=None)
set_render_layer(index: int, enabled: bool = True) None
is_on_render_layer(index: int) bool
wrap_bounds(bounds: tuple[float, float, float] | numpy.ndarray, margin: float = 1.0)
strict_errors: ClassVar[bool]

True

script_error_raised

‘Signal(…)’

classmethod __init_subclass__(**kwargs)
property name: str
property process_mode: simvx.core.descriptors.ProcessMode
reset_error() None
add_child(node: simvx.core.node.Node) simvx.core.node.Node
remove_child(node: simvx.core.node.Node)
reparent(new_parent: simvx.core.node.Node)
get_node(path: str) simvx.core.node.Node
find_child(name: str, recursive: bool = False) simvx.core.node.Node | None
find(node_type: type, recursive: bool = True) simvx.core.node.Node | None
find_all(node_type: type, recursive: bool = True) list
property path: str
add_to_group(group: str)
remove_from_group(group: str)
is_in_group(group: str) bool
ready() None
enter_tree() None
exit_tree() None
physics_process(dt: float) None
input_event(event: simvx.core.events.InputEvent) None
input(event: simvx.core.events.TreeInputEvent) None
unhandled_input(event: simvx.core.events.TreeInputEvent) None
start_coroutine(gen: simvx.core.descriptors.Coroutine) simvx.core.descriptors.CoroutineHandle
stop_coroutine(gen_or_handle)
clear_children()
destroy()
property app
property tree: simvx.core.scene_tree.SceneTree
get_tree() simvx.core.scene_tree.SceneTree
__getitem__(key: str)
classmethod get_properties() dict[str, simvx.core.descriptors.Property]
__repr__()