use macroquad::prelude::*;
use thimni::sdf::SDF;
use thimni::utils::{AABB, CollisionParameters};
const BALL_SPEED: f32 = 50.0;
struct MRect(Rect);
struct MCircle(Circle);
impl SDF<2, ::glam::Vec2> for MCircle {
fn dist(&self, p: ::glam::Vec2) -> f32 {
let k = p - ::glam::Vec2::new(self.0.x, self.0.y);
k.length() - self.0.r
}
fn gradient(&self, p: ::glam::Vec2, _params: &CollisionParameters) -> ::glam::Vec2 {
let k = p - ::glam::Vec2::new(self.0.x, self.0.y);
k.normalize_or_zero()
}
fn aabb(&self) -> AABB<2, ::glam::Vec2> {
AABB {
min: ::glam::Vec2::new(self.0.x - self.0.r, self.0.y - self.0.r),
max: ::glam::Vec2::new(self.0.x + self.0.r, self.0.y + self.0.r),
}
}
}
impl SDF<2, ::glam::Vec2> for MRect {
fn dist(&self, p: ::glam::Vec2) -> f32 {
let b = ::glam::Vec2 {
x: self.0.w * 0.5,
y: self.0.h * 0.5,
};
let c = ::glam::Vec2 {
x: self.0.x,
y: self.0.y,
} + b;
let w = (p - c).abs() - b;
w.max_element() }
fn aabb(&self) -> AABB<2, ::glam::Vec2> {
let top_left = ::glam::Vec2::new(self.0.x, self.0.y);
let bottom_rigt = top_left + ::glam::Vec2::new(self.0.w, self.0.h);
AABB {
min: top_left.min(bottom_rigt),
max: top_left.max(bottom_rigt),
}
}
}
#[macroquad::main("twod")]
async fn main() {
let mut collision_params = CollisionParameters::default();
collision_params.normal_epsilon = 0.01;
collision_params.area_percentage = 0.95;
let shape1 = MRect(Rect::new(100.0, 200.0, 70.0, 90.0));
let shape3 = MCircle(Circle::new(400.0, 200.0, 100.0));
let mut shape2 = MCircle(Circle::new(300.0, 400.0, 100.0));
let mut shape2_vel = Vec2::ZERO;
loop {
clear_background(BLACK);
shape2.0.x += shape2_vel.x * BALL_SPEED * get_frame_time();
shape2.0.y += shape2_vel.y * BALL_SPEED * get_frame_time();
if is_key_down(KeyCode::W) {
shape2_vel.y += 1.0;
}
if is_key_down(KeyCode::S) {
shape2_vel.y -= 1.0;
}
if is_key_down(KeyCode::D) {
shape2_vel.x -= 1.0;
}
if is_key_down(KeyCode::A) {
shape2_vel.x += 1.0;
}
shape2_vel = shape2_vel.lerp(Vec2::ZERO, get_frame_time() * 100.0);
shape2_vel = shape2_vel.normalize_or_zero();
draw_rectangle(shape1.0.x, shape1.0.y, shape1.0.w, shape1.0.h, RED);
draw_circle(shape2.0.x, shape2.0.y, shape2.0.r, BLUE);
draw_circle(shape3.0.x, shape3.0.y, shape3.0.r, PINK);
if let Some(res) = shape2.get_coll_point(&shape1, &mut collision_params) {
let l = res.gradient.length();
draw_line(
res.point.x,
res.point.y,
res.point.x + res.gradient.x * l * 40.0,
res.point.y + res.gradient.y * l * 40.0,
5.0,
PINK,
);
draw_circle(res.point.x, res.point.y, 5.0, PURPLE);
shape2_vel.x = res.gradient.x;
shape2_vel.y = res.gradient.y;
let depth = shape2.sum_gradient_depth(&shape1, &collision_params, &res);
shape2_vel.x += res.gradient.x * depth;
shape2_vel.y += res.gradient.y * depth;
};
if let Some(res) = shape2.get_coll_point(&shape3, &mut collision_params) {
let l = res.gradient.length();
draw_line(
res.point.x,
res.point.y,
res.point.x + res.gradient.x * l * 40.0,
res.point.y + res.gradient.y * l * 40.0,
5.0,
PINK,
);
draw_circle(res.point.x, res.point.y, 5.0, PURPLE);
let depth = shape2.sum_gradient_depth(&shape3, &collision_params, &res);
shape2_vel.x += res.gradient.x * depth;
shape2_vel.y += res.gradient.y * depth;
};
draw_text(&format!("{}", get_fps()), 70.0, 70.0, 50.0, YELLOW);
next_frame().await
}
}