robolib.systems.render_system
render_system.py - The main (3D cameras) render system used by the simulator and other tools (e.g. map editor)
1"""render_system.py - The main (3D cameras) render system used by the simulator and other tools (e.g. map editor)""" 2from typing import Callable 3import raylib as rl 4 5from microecs import World, EntityId 6 7from robolib.constants import DEFAULT_BACKGROUND 8from robolib.traits import Drawable 9from robolib.components import HasFPV, HasModel, HasPose, HasCollision, ColliderKinds, GroundFloor 10from robolib.camera import Camera 11 12class RenderSystem: 13 """Only the main 3D render camera(s). For FPV rendering on a texture, use FPVRenderSystem.""" 14 def __call__(self, world: World, camera: Camera, extra_drawables: list[Drawable] | None = None, 15 camera_entity_id: EntityId | None = None, wireframe_mode: bool = False, 16 collision_mode: bool = False, display_uav_trace: bool = False, uav_traces: dict | None = None, 17 display_hud: bool = False, extra_callables: list[Callable] | None = None): 18 rl.ClearBackground(DEFAULT_BACKGROUND) 19 20 rl.BeginMode3D(camera.camera[0]) 21 22 if wireframe_mode: 23 rl.rlEnableWireMode() 24 25 if collision_mode: 26 qr = world.query(HasModel, HasPose, exclude=[HasCollision]) 27 for model, pose, scale in zip(qr.model, qr.pose, qr.scale): 28 rl.DrawModel(model.item().model, pose[0:3, 3].tolist(), scale.item(), rl.WHITE) 29 30 qr = world.query(HasModel, HasPose, GroundFloor) 31 for model, pose, scale in zip(qr.model, qr.pose, qr.scale): 32 rl.DrawModel(model.item().model, pose[0:3, 3].tolist(), scale.item(), rl.WHITE) 33 34 qr = world.query(HasModel, HasPose, HasCollision, exclude=[GroundFloor]) 35 collider_size = qr.collider_bbox[:, 1] - qr.collider_bbox[:, 0] 36 for pose, kind, radius, size, colliding in zip(qr.pose, qr.collider_kind, qr.collider_radii, 37 collider_size, qr.is_colliding): 38 color = rl.RED if colliding else rl.GREEN 39 if kind == ColliderKinds.SPHERE: 40 rl.DrawSphere(pose[0:3, 3].tolist(), radius.item(), color) 41 else: # AABB 42 rl.DrawCube(pose[0:3, 3].tolist(), *size.tolist(), color) 43 44 else: 45 qr = world.query(HasModel, HasPose) 46 for i, (model, pose, scale) in enumerate(zip(qr.model, qr.pose, qr.scale)): 47 if camera_entity_id is not None and qr.entity_ids[i] == camera_entity_id: # don't draw yourself in FPV 48 continue 49 rl.DrawModel(model.item().model, pose[0:3, 3].tolist(), scale.item(), rl.WHITE) 50 51 for drawable in (extra_drawables or []): # e.g. plugins 52 drawable.draw(world=world, entity_id=camera_entity_id) 53 for callable_fn in (extra_callables or []): 54 callable_fn(world=world) 55 56 if display_uav_trace: 57 assert uav_traces is not None, uav_traces 58 for traces in uav_traces.values(): 59 for trace in traces.keys(): 60 rl.DrawSphere(trace, 0.05, rl.GREEN) 61 62 rl.EndMode3D() 63 64 if wireframe_mode: 65 rl.rlDisableWireMode() 66 67 if display_hud: 68 n_robots = len(world.query(HasFPV)) 69 msg = f"{camera.label}\nObjects: {len(world)} (robots: {n_robots})" 70 rl.DrawText(msg.encode(), 10, 10, 20, rl.DARKGRAY) 71 rl.DrawFPS(rl.GetScreenWidth() - 80, 10)
class
RenderSystem:
13class RenderSystem: 14 """Only the main 3D render camera(s). For FPV rendering on a texture, use FPVRenderSystem.""" 15 def __call__(self, world: World, camera: Camera, extra_drawables: list[Drawable] | None = None, 16 camera_entity_id: EntityId | None = None, wireframe_mode: bool = False, 17 collision_mode: bool = False, display_uav_trace: bool = False, uav_traces: dict | None = None, 18 display_hud: bool = False, extra_callables: list[Callable] | None = None): 19 rl.ClearBackground(DEFAULT_BACKGROUND) 20 21 rl.BeginMode3D(camera.camera[0]) 22 23 if wireframe_mode: 24 rl.rlEnableWireMode() 25 26 if collision_mode: 27 qr = world.query(HasModel, HasPose, exclude=[HasCollision]) 28 for model, pose, scale in zip(qr.model, qr.pose, qr.scale): 29 rl.DrawModel(model.item().model, pose[0:3, 3].tolist(), scale.item(), rl.WHITE) 30 31 qr = world.query(HasModel, HasPose, GroundFloor) 32 for model, pose, scale in zip(qr.model, qr.pose, qr.scale): 33 rl.DrawModel(model.item().model, pose[0:3, 3].tolist(), scale.item(), rl.WHITE) 34 35 qr = world.query(HasModel, HasPose, HasCollision, exclude=[GroundFloor]) 36 collider_size = qr.collider_bbox[:, 1] - qr.collider_bbox[:, 0] 37 for pose, kind, radius, size, colliding in zip(qr.pose, qr.collider_kind, qr.collider_radii, 38 collider_size, qr.is_colliding): 39 color = rl.RED if colliding else rl.GREEN 40 if kind == ColliderKinds.SPHERE: 41 rl.DrawSphere(pose[0:3, 3].tolist(), radius.item(), color) 42 else: # AABB 43 rl.DrawCube(pose[0:3, 3].tolist(), *size.tolist(), color) 44 45 else: 46 qr = world.query(HasModel, HasPose) 47 for i, (model, pose, scale) in enumerate(zip(qr.model, qr.pose, qr.scale)): 48 if camera_entity_id is not None and qr.entity_ids[i] == camera_entity_id: # don't draw yourself in FPV 49 continue 50 rl.DrawModel(model.item().model, pose[0:3, 3].tolist(), scale.item(), rl.WHITE) 51 52 for drawable in (extra_drawables or []): # e.g. plugins 53 drawable.draw(world=world, entity_id=camera_entity_id) 54 for callable_fn in (extra_callables or []): 55 callable_fn(world=world) 56 57 if display_uav_trace: 58 assert uav_traces is not None, uav_traces 59 for traces in uav_traces.values(): 60 for trace in traces.keys(): 61 rl.DrawSphere(trace, 0.05, rl.GREEN) 62 63 rl.EndMode3D() 64 65 if wireframe_mode: 66 rl.rlDisableWireMode() 67 68 if display_hud: 69 n_robots = len(world.query(HasFPV)) 70 msg = f"{camera.label}\nObjects: {len(world)} (robots: {n_robots})" 71 rl.DrawText(msg.encode(), 10, 10, 20, rl.DARKGRAY) 72 rl.DrawFPS(rl.GetScreenWidth() - 80, 10)
Only the main 3D render camera(s). For FPV rendering on a texture, use FPVRenderSystem.