Skip to content

Commit 32f6d40

Browse files
committed
Add Rays
1 parent f9df7c6 commit 32f6d40

6 files changed

Lines changed: 126 additions & 25 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@ version = "0.1.0"
44
edition = "2024"
55

66
[dependencies]
7-
macroquad = "0.4.13"
8-
7+
macroquad = "0.4.13"

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ git clone https://github.com/Pixels67/gravity-sim.git
88
cd gravity-sim
99
cargo build --release
1010
```
11-
***Note***: To get debug lines build with `--dev`
11+
***Note***: To get debug lines build with `--dev`
12+
## Controls
13+
**[A]** / **[D]**: Left / Right \
14+
**[W]** / **[S]**: Forward / Back \
15+
**[LShift]** / **[LCtrl]**: Up / Down

src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub mod object;
22
pub mod world;
33
pub mod physics;
4+
pub mod screen;
45

56
#[cfg(test)]
67
mod tests {
@@ -105,4 +106,24 @@ mod tests {
105106

106107
assert_eq!(new, original);
107108
}
109+
110+
use crate::screen::*;
111+
112+
#[test]
113+
fn raycast() {
114+
let ray = Ray::new(vec3(0., 0., 0.), vec3(1., 0., 0.), 10.);
115+
let pos = vec3(5., 0., 0.);
116+
117+
assert!(ray.raycast(pos, 0.));
118+
119+
let ray = Ray::new(vec3(0., 0., 0.), vec3(1., 0., 0.), 10.);
120+
let pos = vec3(5., 1., 0.);
121+
122+
assert!(ray.raycast(pos, 1.));
123+
124+
let ray = Ray::new(vec3(0., 0., 0.), vec3(1., 0., 0.), 10.);
125+
let pos = vec3(5., 2., 0.);
126+
127+
assert!(!ray.raycast(pos, 1.));
128+
}
108129
}

src/main.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
use macroquad::miniquad::*;
1+
use macroquad::miniquad::window::*;
22
use macroquad::prelude::*;
33
use gravity_sim::object::*;
44
use gravity_sim::world::*;
55

66
const BG_COLOR: Color = Color{r: 0.05, g: 0.05, b: 0.05, a: 1.};
77
const WINDOW_WIDTH: u32 = 1280;
88
const WINDOW_HEIGHT: u32 = 720;
9-
const GRAV_CONST: f32 = 1.;
10-
const UPDATE_INTERVAL: f32 = 0.005;
9+
const GRAV_CONST: f32 = 0.5;
10+
const UPDATE_INTERVAL: f32 = 0.001;
1111

1212
#[macroquad::main("Sim")]
1313
async fn main() {
1414
let mut world = World::new(GRAV_CONST, UPDATE_INTERVAL);
15-
window::set_window_size(WINDOW_WIDTH, WINDOW_HEIGHT);
15+
set_window_size(WINDOW_WIDTH, WINDOW_HEIGHT);
1616

17-
world.add_object(Object::new(vec3( 5., 0., 0.), vec3(0., 0., 0.025), 1., 0.5, RED));
18-
world.add_object(Object::new(vec3( 0., 1., 0.), vec3(0., 0.01, 0.), 1., 0.5, GREEN));
19-
world.add_object(Object::new(vec3(-5., 0., 0.), vec3(0., 0., -0.025), 1., 0.5, BLUE));
17+
world.add_object(Object::new(vec3( 5., 0., 0.), vec3(0., 0., 0.01), 1., 0.5, RED));
18+
world.add_object(Object::new(vec3( 0., 0., 0.), vec3(0., 0., 0.), 1., 0.5, GREEN));
19+
world.add_object(Object::new(vec3(-5., 0., 0.), vec3(0., 0., -0.01), 1., 0.5, BLUE));
2020

2121
loop {
2222
clear_background(BG_COLOR);

src/screen.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use macroquad::prelude::*;
2+
3+
pub fn get_mouse_pos() -> Vec2 {
4+
vec2(
5+
(mouse_position().0 - screen_width() / 2.) / screen_width(),
6+
(-mouse_position().1 + screen_height() / 2.) / screen_height(),
7+
) * 2.
8+
}
9+
10+
pub fn get_aspect_ratio() -> f32 {
11+
screen_width() / screen_height()
12+
}
13+
14+
pub struct Ray {
15+
pub origin: Vec3,
16+
pub dir: Vec3,
17+
pub len: f32,
18+
}
19+
20+
impl Ray {
21+
pub fn new(origin: Vec3, dir: Vec3, len: f32) -> Self {
22+
let dir = dir.normalize();
23+
Self { origin, dir, len }
24+
}
25+
26+
pub fn new_from_cam(cam: &Camera3D, pos: Vec2, len: f32) -> Self {
27+
let cam_forward = (cam.target - cam.position).normalize();
28+
let cam_right = Vec3::cross(cam_forward, cam.up).normalize();
29+
let cam_up = Vec3::cross(cam_right, cam_forward).normalize();
30+
31+
let aspect_ratio = get_aspect_ratio();
32+
let fov_scale = f32::tan(cam.fovy / 2.);
33+
34+
let offset = cam_right * (pos.x * aspect_ratio * fov_scale) + cam_up * (pos.y * fov_scale);
35+
let dir = (offset + cam_forward).normalize();
36+
37+
Self {
38+
origin: cam.position,
39+
dir,
40+
len,
41+
}
42+
}
43+
44+
pub fn raycast(&self, target_pos: Vec3, margin_of_err: f32) -> bool {
45+
if self.dir == Vec3::ZERO {
46+
return false;
47+
}
48+
49+
let closest_point_approx = self.origin + self.dir * (target_pos - self.origin).length();
50+
if target_pos == closest_point_approx {
51+
return true;
52+
}
53+
54+
let point_to_target = target_pos - closest_point_approx;
55+
let plane_normal = self.dir.cross(point_to_target).normalize();
56+
let mirror_axis = self.dir.cross(plane_normal);
57+
let mirror_target = (target_pos - closest_point_approx) * mirror_axis;
58+
59+
let closest_point = target_pos + mirror_target;
60+
61+
(closest_point - target_pos).length() <= margin_of_err
62+
}
63+
64+
#[cfg(debug_assertions)]
65+
pub fn draw(&self, color: Color) {
66+
draw_line_3d(self.origin, self.origin + self.dir * self.len, color);
67+
}
68+
}

src/world.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use super::object::*;
2-
use super::physics;
1+
use crate::object::*;
2+
use crate::physics;
33
use macroquad::prelude::*;
44
use std::vec;
5+
use crate::screen::{get_mouse_pos, Ray};
56

67
pub struct World {
78
pub grav_const: f32,
@@ -15,7 +16,7 @@ pub struct World {
1516
impl World {
1617
pub fn new(grav_const: f32, update_interval: f32) -> Self {
1718
let cam = Camera3D {
18-
position: vec3(15., 10., 0.),
19+
position: vec3(0., 10., -15.),
1920
up: vec3(0., 1., 0.),
2021
target: vec3(0., 0., 0.),
2122
..Default::default()
@@ -44,8 +45,8 @@ impl World {
4445
};
4546

4647
let obj_mat = load_material(shader, params).unwrap();
47-
obj_mat.set_uniform("light_pos", vec3(0., 10., 10.));
48-
obj_mat.set_uniform("ambient_light", 0.3f32);
48+
obj_mat.set_uniform("light_pos", Vec3::ONE);
49+
obj_mat.set_uniform("ambient_light", 0.25f32);
4950

5051
World {
5152
grav_const,
@@ -112,6 +113,14 @@ impl World {
112113

113114
self.objects.draw_all(&self.obj_mat);
114115

116+
let ray = Ray::new_from_cam(&self.cam, get_mouse_pos(), 100.);
117+
118+
for obj in self.objects.iter() {
119+
if ray.raycast(obj.position, 0.5) {
120+
draw_sphere(obj.position, 0.5, None, WHITE);
121+
}
122+
}
123+
115124
#[cfg(debug_assertions)]
116125
for obj in self.objects.iter() {
117126
draw_line_3d(
@@ -141,28 +150,28 @@ impl World {
141150

142151
fn handle_input(&mut self) {
143152
if get_keys_down().contains(&KeyCode::W) {
144-
self.cam.position.x -= 0.4;
145-
self.cam.target.x -= 0.4;
153+
self.cam.position.z += 0.4;
154+
self.cam.target.z += 0.4;
146155
}
147156
if get_keys_down().contains(&KeyCode::S) {
148-
self.cam.position.x += 0.4;
149-
self.cam.target.x += 0.4;
157+
self.cam.position.z -= 0.4;
158+
self.cam.target.z -= 0.4;
150159
}
151160
if get_keys_down().contains(&KeyCode::LeftControl) {
152161
self.cam.position.y -= 0.4;
153-
self.cam.target.y -= 0.4;
162+
self.cam.target.y -= 0.4;
154163
}
155164
if get_keys_down().contains(&KeyCode::LeftShift) {
156165
self.cam.position.y += 0.4;
157-
self.cam.target.y += 0.4;
166+
self.cam.target.y += 0.4;
158167
}
159168
if get_keys_down().contains(&KeyCode::D) {
160-
self.cam.position.z -= 0.4;
161-
self.cam.target.z -= 0.4;
169+
self.cam.position.x -= 0.4;
170+
self.cam.target.x -= 0.4;
162171
}
163172
if get_keys_down().contains(&KeyCode::A) {
164-
self.cam.position.z += 0.4;
165-
self.cam.target.z += 0.4;
173+
self.cam.position.x += 0.4;
174+
self.cam.target.x += 0.4;
166175
}
167176
}
168177
}

0 commit comments

Comments
 (0)