import math
from dataclasses import dataclass
from pybevy.prelude import *
@component
@dataclass
class Orbiter(Component):
move_speed: float = 2.0
turn_speed: float = 0.2
def setup(
commands: Commands,
meshes: ResMut[Assets[Mesh]],
materials: ResMut[Assets[StandardMaterial]],
) -> None:
commands.spawn(
Mesh3d(meshes.add(Sphere(radius=1.0).mesh().ico(32))),
MeshMaterial3d(materials.add(StandardMaterial(base_color=Color.srgb(1.0, 1.0, 0.0)))),
Transform.from_translation(Vec3.ZERO),
)
cube_spawn = Transform.from_translation(Vec3(0.0, 0.0, -10.0)).with_rotation(
Quat.from_rotation_y(math.pi / 2.0)
)
commands.spawn(
Mesh3d(meshes.add(Cuboid().mesh())),
MeshMaterial3d(materials.add(StandardMaterial(base_color=Color.WHITE))),
cube_spawn,
Orbiter(),
)
commands.spawn(Camera3d(), Transform.from_xyz(0.0, 10.0, 20.0).looking_at(Vec3.ZERO, Vec3.Y))
commands.spawn(DirectionalLight(), Transform.from_xyz(3.0, 3.0, 3.0).looking_at(Vec3.ZERO, Vec3.Y))
def move_and_rotate_orbiter(
orbiters: Query[tuple[Mut[Transform], Orbiter]],
time: Res[Time],
) -> None:
for transform, orbiter in orbiters:
forward = transform.forward()
transform.translation = (
transform.translation + forward * orbiter.move_speed * time.delta_secs()
)
look_at_center = transform.looking_at(Vec3.ZERO, transform.local_y())
incremental_turn = orbiter.turn_speed * time.delta_secs()
transform.rotation = transform.rotation.lerp(look_at_center.rotation, incremental_turn)
@entrypoint
def main(app: App) -> App:
return (
app.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, move_and_rotate_orbiter)
)
if __name__ == "__main__":
main().run()