95 lines
4.0 KiB
Python
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)
|