use quaturn::game_context::node_manager::{
Behavior, Node, NodeManager, NodeTransform, Ready, Transformable,
};
use quaturn::game_context::nodes::empty::Empty;
use quaturn::game_context::nodes::{
camera::Camera3D,
directional_light::DirectionalLight,
model::{Model, Primitive},
ui::UI,
};
use quaturn::game_context::GameContext;
use quaturn::renderer::shader::Shader;
use quaturn::Engine;
use quaturn::{egui, glfw, glm};
const WINDOW_WIDTH: u32 = 1280;
const WINDOW_HEIGHT: u32 = 720;
struct CustomNode {
transform: NodeTransform,
children: NodeManager,
pub velocity: f32,
}
impl Node for CustomNode {
fn get_transform(&mut self) -> &mut NodeTransform {
&mut self.transform
}
fn get_children(&mut self) -> &mut NodeManager {
&mut self.children
}
fn as_ready(&mut self) -> Option<&mut (dyn Ready + 'static)> {
Some(self)
}
fn as_behavior(&mut self) -> Option<&mut (dyn Behavior + 'static)> {
Some(self)
}
}
impl Ready for CustomNode {
fn ready(&mut self) {
println!("Custom Node Ready");
}
}
impl Behavior for CustomNode {
fn behavior(&mut self, _context: &mut GameContext) {
let velocity = self.velocity;
self.apply_transform(&mut |t| {
t.rotate_euler_xyz(glm::vec3(0.0, velocity, 0.0));
});
}
}
impl CustomNode {
pub fn new() -> Self {
CustomNode {
transform: NodeTransform::default(),
children: NodeManager::new(),
velocity: 0.0,
}
}
}
fn main() {
let mut engine = Engine::init("Hello Pyramid", WINDOW_WIDTH, WINDOW_HEIGHT);
engine.set_clear_color(0.0, 0.0, 0.0, 1.0);
let mut cursor_locked = false;
let toggle_cursor_lock = |context: &mut GameContext, lock: bool| {
context.lock_cursor(lock);
};
engine
.context
.nodes
.add("custom", CustomNode::new())
.children
.add("childmodel", Model::new_primitive(Primitive::Pyramid));
engine
.context
.nodes
.add("plane", Model::new_primitive(Primitive::Plane))
.apply_transform(&mut |t| {
t.set_scale(glm::vec3(20.0, 20.0, 20.0));
t.set_position(glm::vec3(0.0, -2.0, 0.0));
});
engine.context.nodes.add(
"Direct Light",
DirectionalLight::new(
glm::vec3(-1.0, 1.0, 1.0),
glm::vec3(1.0, 1.0, 1.0),
1.0,
100.0,
4096,
),
);
let camera_pos = glm::vec3(20.0, 20.0, 20.0);
engine
.context
.nodes
.add(
"camera",
Camera3D::new(
camera_pos,
(glm::vec3(0.0, 0.0, 1.0) - camera_pos).normalize(),
0.78539,
WINDOW_WIDTH as f32 / WINDOW_HEIGHT as f32,
0.1,
1000.0,
),
)
.define_ready(|_camera| {
println!("camera ready");
})
.define_behavior(move |camera, context| {
if cursor_locked {
camera.take_input(&context.input, context.frame.time_delta.as_secs_f32());
}
if context
.input
.mouse_button_just_pressed
.contains(&glfw::MouseButton::Button2)
{
cursor_locked = !cursor_locked;
toggle_cursor_lock(context, cursor_locked);
}
});
engine
.context
.nodes
.add("game manager", Empty::new())
.define_ready(|_game_manager| {
println!("game manager ready");
})
.define_behavior(move |_game_manager, context| {
if context.input.keys.contains(&glfw::Key::Escape) {
context.window.set_should_close(true);
}
});
let shader = engine
.context
.nodes
.add_shader("default", Shader::default());
shader.bind();
shader.set_uniform4f("lightColor", 1.0, 1.0, 1.0, 1.0);
let ui = UI::init(&mut engine.context.window);
engine
.context
.nodes
.add("debug_panel", ui)
.define_ui(move |ctx, context| {
egui::Window::new("Debug Panel").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.label("FPS: ");
ui.label(format!("{:.2}", context.frame.fps));
});
if let Some(node) = context.nodes.get_mut::<CustomNode>("custom") {
let mut velocity = node.velocity;
ui.add(egui::Slider::new(&mut velocity, -10.0..=10.0).text("Velocity"));
node.velocity = velocity;
}
if let Some(model) = context.nodes.get_mut::<CustomNode>("custom") {
if let Some(child) = model.children.get_mut::<Model>("childmodel") {
let mut model_pos = child.get_transform().get_position();
ui.label("Model Position");
ui.horizontal(|ui| {
ui.label("X:");
ui.add(egui::DragValue::new(&mut model_pos.x));
ui.label("Y:");
ui.add(egui::DragValue::new(&mut model_pos.y));
ui.label("Z:");
ui.add(egui::DragValue::new(&mut model_pos.z));
});
child.apply_transform(&mut |t| {
t.set_position(model_pos);
});
}
}
if let Some(camera) = context.nodes.get_mut::<Camera3D>("camera") {
let (mut camera_pos_x, mut camera_pos_y, mut camera_pos_z) = (
camera.get_position().x,
camera.get_position().y,
camera.get_position().z,
);
let (mut camera_rotation_x, mut camera_rotation_y, mut camera_rotation_z) = (
camera.get_orientation_angles().x,
camera.get_orientation_angles().y,
camera.get_orientation_angles().z,
);
ui.label("Camera Position");
ui.horizontal(|ui| {
ui.label("X:");
ui.add(egui::DragValue::new(&mut camera_pos_x));
ui.label("Y:");
ui.add(egui::DragValue::new(&mut camera_pos_y));
ui.label("Z:");
ui.add(egui::DragValue::new(&mut camera_pos_z));
});
ui.label("Camera Rotation");
ui.horizontal(|ui| {
ui.label("X:");
ui.add(egui::DragValue::new(&mut camera_rotation_x));
ui.label("Y:");
ui.add(egui::DragValue::new(&mut camera_rotation_y));
ui.label("Z:");
ui.add(egui::DragValue::new(&mut camera_rotation_z));
});
ui.add(
egui::Slider::new(&mut camera.move_speed, 0.0..=1000.0).text("Move Speed"),
);
}
{
if let Some(light) = context.nodes.get_mut::<DirectionalLight>("Direct Light") {
let mut shadow_distance = light.get_far_plane();
ui.add(
egui::Slider::new(&mut shadow_distance, 0.0..=1000.0)
.text("Shadow Distance"),
);
light.set_far_plane(shadow_distance);
}
}
});
});
engine.begin();
}