guitarHeroButBetter/py/engine/physics_debug.py
James Whiteman 3f7b409302 Python code
2026-01-30 21:16:42 -08:00

95 lines
4.0 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import Tuple
from Box2D import b2Color, b2Draw
import pyray as rl
@dataclass
class DebugDrawCtx:
meters_to_pixels: float = 30.0
line_thickness: float = 1.0
def _to_raylib_color(color: b2Color, alpha: float = 1.0) -> rl.Color:
r = int(max(0, min(255, color.r * 255)))
g = int(max(0, min(255, color.g * 255)))
b = int(max(0, min(255, color.b * 255)))
a = int(max(0, min(255, alpha * 255)))
return rl.Color(r, g, b, a)
class PhysicsDebugRenderer(b2Draw):
def __init__(self, meters_to_pixels: float = 30.0, line_thickness: float = 1.0) -> None:
super().__init__()
self.ctx = DebugDrawCtx(meters_to_pixels=meters_to_pixels, line_thickness=line_thickness)
def DrawPolygon(self, vertices, color):
count = len(vertices)
if count < 2:
return
c = _to_raylib_color(color)
for i in range(count):
p0 = vertices[i]
p1 = vertices[(i + 1) % count]
a = rl.Vector2(p0[0] * self.ctx.meters_to_pixels, p0[1] * self.ctx.meters_to_pixels)
b = rl.Vector2(p1[0] * self.ctx.meters_to_pixels, p1[1] * self.ctx.meters_to_pixels)
rl.draw_line_ex(a, b, self.ctx.line_thickness, c)
def DrawSolidPolygon(self, vertices, color):
count = len(vertices)
if count < 2:
return
fill = _to_raylib_color(color, 0.8)
line = _to_raylib_color(color, 1.0)
pts = [rl.Vector2(v[0] * self.ctx.meters_to_pixels, v[1] * self.ctx.meters_to_pixels) for v in vertices]
center = rl.Vector2(0.0, 0.0)
for p in pts:
center.x += p.x
center.y += p.y
center.x /= count
center.y /= count
for i in range(count - 1):
rl.draw_triangle(pts[i], center, pts[i + 1], fill)
rl.draw_triangle(pts[count - 1], center, pts[0], fill)
for i in range(count):
rl.draw_line_ex(pts[i], pts[(i + 1) % count], self.ctx.line_thickness, line)
def DrawCircle(self, center, radius, color):
c = _to_raylib_color(color)
rl.draw_circle_lines(int(center[0] * self.ctx.meters_to_pixels),
int(center[1] * self.ctx.meters_to_pixels),
radius * self.ctx.meters_to_pixels,
c)
def DrawSolidCircle(self, center, radius, axis, color):
fill = _to_raylib_color(color, 0.8)
line = _to_raylib_color(color, 1.0)
c = rl.Vector2(center[0] * self.ctx.meters_to_pixels, center[1] * self.ctx.meters_to_pixels)
rl.draw_circle_v(c, radius * self.ctx.meters_to_pixels, fill)
axis_end = rl.Vector2((center[0] + axis[0] * radius) * self.ctx.meters_to_pixels,
(center[1] + axis[1] * radius) * self.ctx.meters_to_pixels)
rl.draw_line_ex(c, axis_end, self.ctx.line_thickness, line)
def DrawSegment(self, p1, p2, color):
c = _to_raylib_color(color)
a = rl.Vector2(p1[0] * self.ctx.meters_to_pixels, p1[1] * self.ctx.meters_to_pixels)
b = rl.Vector2(p2[0] * self.ctx.meters_to_pixels, p2[1] * self.ctx.meters_to_pixels)
rl.draw_line_ex(a, b, self.ctx.line_thickness, c)
def DrawTransform(self, xf):
p = xf.position
x_axis = xf.R.x_axis
y_axis = xf.R.y_axis
origin = rl.Vector2(p[0] * self.ctx.meters_to_pixels, p[1] * self.ctx.meters_to_pixels)
x_end = rl.Vector2((p[0] + x_axis[0]) * self.ctx.meters_to_pixels, (p[1] + x_axis[1]) * self.ctx.meters_to_pixels)
y_end = rl.Vector2((p[0] + y_axis[0]) * self.ctx.meters_to_pixels, (p[1] + y_axis[1]) * self.ctx.meters_to_pixels)
rl.draw_line_ex(origin, x_end, self.ctx.line_thickness, rl.RED)
rl.draw_line_ex(origin, y_end, self.ctx.line_thickness, rl.GREEN)
def DrawPoint(self, p, size, color):
c = _to_raylib_color(color)
rl.draw_circle_v(rl.Vector2(p[0] * self.ctx.meters_to_pixels, p[1] * self.ctx.meters_to_pixels), size, c)