2025-11-23 23:43:48 +00:00
|
|
|
use glam::Quat;
|
2025-11-23 18:40:48 +00:00
|
|
|
use macroquad::prelude as mq;
|
|
|
|
|
use rapier3d::prelude::*;
|
|
|
|
|
|
|
|
|
|
mod engine;
|
|
|
|
|
use engine::*;
|
|
|
|
|
|
2025-11-23 23:43:48 +00:00
|
|
|
mod camera;
|
|
|
|
|
|
2025-11-23 18:40:48 +00:00
|
|
|
mod graphics_util;
|
|
|
|
|
use graphics_util::*;
|
|
|
|
|
|
|
|
|
|
#[macroquad::main("3D")]
|
|
|
|
|
async fn main() {
|
|
|
|
|
// Graphics Initialization
|
|
|
|
|
let vertex = include_str!("shaders/shader.vert");
|
|
|
|
|
let fragment = include_str!("shaders/shader.frag");
|
|
|
|
|
|
|
|
|
|
let material = mq::load_material(
|
|
|
|
|
mq::ShaderSource::Glsl { vertex, fragment },
|
|
|
|
|
mq::MaterialParams {
|
|
|
|
|
pipeline_params: mq::PipelineParams {
|
|
|
|
|
depth_test: mq::Comparison::LessOrEqual,
|
|
|
|
|
depth_write: true,
|
|
|
|
|
..Default::default()
|
|
|
|
|
},
|
|
|
|
|
uniforms: vec![mq::UniformDesc::new(
|
|
|
|
|
"render_normals_bool",
|
|
|
|
|
mq::UniformType::Int1,
|
|
|
|
|
)],
|
|
|
|
|
..Default::default()
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
material.set_uniform("render_normals_bool", 0);
|
|
|
|
|
|
|
|
|
|
// Physics Initialization
|
|
|
|
|
let mut world = World::default();
|
|
|
|
|
world.register_free_collider(
|
2025-11-23 23:43:48 +00:00
|
|
|
ColliderBuilder::cuboid(50.0, 0.1, 50.0)
|
2025-11-23 18:40:48 +00:00
|
|
|
.restitution(0.5)
|
|
|
|
|
.build(),
|
|
|
|
|
None,
|
|
|
|
|
);
|
|
|
|
|
|
2025-11-23 23:43:48 +00:00
|
|
|
for i in 0..10 {
|
|
|
|
|
let body = world.register_body(
|
|
|
|
|
RigidBodyBuilder::dynamic()
|
|
|
|
|
.translation(vector![0.0, 10.0 + i as f32, 0.0])
|
|
|
|
|
.rotation(vector![std::f32::consts::PI / 4.2, i as f32, i as f32])
|
|
|
|
|
.build(),
|
|
|
|
|
);
|
|
|
|
|
world.register_collider(
|
|
|
|
|
ColliderBuilder::cuboid(0.5, 0.5, 0.5)
|
|
|
|
|
.restitution(0.5)
|
|
|
|
|
.build(),
|
|
|
|
|
body,
|
|
|
|
|
None,
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-11-23 18:40:48 +00:00
|
|
|
|
2025-11-23 23:43:48 +00:00
|
|
|
let mut cam: camera::FirstPersonCamera =
|
|
|
|
|
camera::FirstPersonCamera::new(mq::vec3(0.0, 10.0, -5.0));
|
2025-11-23 18:40:48 +00:00
|
|
|
loop {
|
|
|
|
|
// Physics Simulation
|
|
|
|
|
world.step();
|
|
|
|
|
|
|
|
|
|
// Graphics Rendering
|
|
|
|
|
mq::clear_background(mq::LIGHTGRAY);
|
2025-11-23 23:43:48 +00:00
|
|
|
cam.update(mq::get_frame_time());
|
|
|
|
|
cam.apply();
|
2025-11-23 18:40:48 +00:00
|
|
|
|
|
|
|
|
mq::draw_grid(20, 1., mq::BLACK, mq::GRAY);
|
|
|
|
|
|
|
|
|
|
for (handle, coll) in world.colliders.iter() {
|
|
|
|
|
let position: glam::Vec3 = world.position_of_collider(handle).unwrap().into();
|
|
|
|
|
let rotation = *coll.rotation();
|
|
|
|
|
unsafe {
|
|
|
|
|
let context = mq::get_internal_gl().quad_gl;
|
|
|
|
|
|
|
|
|
|
context.push_model_matrix(mq::Mat4::from_rotation_translation(
|
|
|
|
|
rotation.into(),
|
|
|
|
|
position,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
let color = world.collider_data.get(&handle).unwrap().color;
|
|
|
|
|
match coll.shape().shape_type() {
|
|
|
|
|
ShapeType::Ball => {
|
|
|
|
|
mq::draw_sphere(
|
|
|
|
|
mq::vec3(0.0, 0.0, 0.0),
|
|
|
|
|
coll.shape().as_ball().unwrap().radius,
|
|
|
|
|
None,
|
|
|
|
|
color,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
ShapeType::Cuboid => {
|
|
|
|
|
mq::gl_use_material(&material);
|
|
|
|
|
draw_cuboid(
|
|
|
|
|
mq::vec3(0.0, 0.0, 0.0),
|
|
|
|
|
(coll.shape().as_cuboid().unwrap().half_extents * 2.0).into(),
|
|
|
|
|
color,
|
|
|
|
|
);
|
|
|
|
|
mq::gl_use_default_material();
|
|
|
|
|
}
|
|
|
|
|
_ => println!("Not implemented.. Skipping"),
|
|
|
|
|
}
|
|
|
|
|
unsafe {
|
|
|
|
|
let context = mq::get_internal_gl().quad_gl;
|
|
|
|
|
context.pop_model_matrix();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mq::next_frame().await
|
|
|
|
|
}
|
|
|
|
|
}
|