use chaos_framework::*;
use glfw::Key;
fn main() {
let mut el = EventLoop::new(600, 600);
let mut renderer = Renderer::new();
unsafe {
Enable(DEPTH_TEST);
}
renderer.camera.set_projection(ProjectionType::Orthographic);
renderer.add_light(Light { position: vec3(0.0, 0.0, 3.0), color: Vec3::ONE })
.unwrap();
let player_handle = renderer.add_mesh(Quad::new(Vec3::ONE * 0.1, Vec4::ONE).mesh())
.unwrap();
renderer.meshes[player_handle].position = Vec3::Z * 2.0;
let mut segments = vec![];
for _ in 0..128 {
let new_segment = Segment::new(vec3(0.0, 0.0, 0.0), 0.05, &mut renderer);
segments.push(new_segment);
}
renderer.meshes[segments[0].handle].hidden = true;
renderer.meshes[segments[segments.len()-1].handle].hidden = true;
renderer.meshes[player_handle].hidden = true;
segments[0].pos = Vec3::new(-2.0, -2.0, 0.0);
let mut clamped_pos;
let mut player_vel;
let mut old_pos = Vec3::ZERO;
while !el.window.should_close() {
el.update();
renderer.update();
segments.iter_mut().for_each(|s| {
s.update(&mut renderer);
});
let player = &mut renderer.meshes[player_handle];
let mp = el.event_handler.mouse_pos / el.event_handler.width * 2.0;
let clamped_player_pos = {
clamped_pos = player.position;
vec3(clamped_pos.x, clamped_pos.y, 0.0)
};
fabrik(&mut segments, {
if el.event_handler.lmb {
clamped_player_pos + vec3(mp.x, mp.y, 0.0)
} else {
clamped_player_pos
}
}, 0.0, 2);
let first_segment_position = segments[0].pos;
let seg_amm = segments.len() as f32;
let distance = first_segment_position.distance(segments[segments.len()-1].pos);
let len = segments[0].length;
if distance > segments.len() as f32 * segments[0].length + segments[0].length {
segments[0].pos += ((clamped_player_pos - first_segment_position) / seg_amm) * len * f32::powf(distance, 2.3);
}
player_vel = player.position - old_pos;
old_pos = player.position;
player.color = vec3(0.5, 0.0, el.time.sin());
move_player(&el, &mut player.position);
renderer.camera.update(lerp(renderer.camera.pos, player.position, 0.125), &el);
renderer.camera.mouse_callback(el.event_handler.mouse_pos, &el.window);
let frame = el.ui.frame(&mut el.window);
frame.text("Hello, world! This is imgui.");
frame.text(format!("p: {:.1}\nv: {:.3}", player.position, player_vel));
unsafe {
Clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
ClearColor(0.1, 0.2, 0.3, 1.0);
renderer.draw();
el.ui.draw();
}
}
}
struct Segment {
pos: Vec3,
length: f32,
angle: f32,
handle: MeshHandle,
}
impl Segment {
fn new(a: Vec3, length: f32, renderer: &mut Renderer) -> Self {
let handle = renderer.add_mesh(Quad::new(Vec3::ONE * length, Vec4::ONE).mesh())
.unwrap();
Self {
pos: a,
length: length / 2.0,
angle: 0.0,
handle: handle,
}
}
fn get_end(&self) -> Vec3 {
self.pos + Vec3::new(self.length * self.angle.cos(), self.length * self.angle.sin(), 0.0)
}
fn update_position(&mut self, new_pos: Vec3) {
self.pos = new_pos;
}
fn update_angle(&mut self, direction: Vec3) {
self.angle = direction.y.atan2(direction.x);
}
fn update(&mut self, renderer: &mut Renderer) {
let rot = Quat::from_axis_angle(Vec3::Z, self.angle);
renderer.meshes[self.handle].position = self.pos;
renderer.meshes[self.handle].rotation = rot;
}
}
fn fabrik(segments: &mut [Segment], target: Vec3, tolerance: f32, max_iterations: usize) {
let b = segments[0].pos;
let mut diff = (segments.last().unwrap().get_end() - target).length();
let mut iterations = 0;
while diff > tolerance && iterations < max_iterations {
iterations += 1;
segments.last_mut().unwrap().update_position(target);
for i in (2..segments.len()).rev() {
let parent_end = segments[i].get_end();
let direction = (segments[i - 1].pos - parent_end).normalize();
let new_pos = parent_end + direction * segments[i - 1].length;
segments[i - 1].update_position(new_pos);
segments[i - 1].update_angle(direction);
}
segments[0].update_position(b);
for i in 1..segments.len()-1 {
let parent_end = segments[i - 1].get_end();
let direction = (segments[i].pos - parent_end).normalize();
let new_pos = parent_end + direction * segments[i - 1].length;
segments[i].update_position(new_pos);
segments[i].update_angle(direction);
}
diff = (segments.last().unwrap().get_end() - target).length();
}
}
fn move_player(el: &EventLoop, pos: &mut Vec3) {
let mut velocity = Vec3::ZERO;
let mut speed = 1.5;
if el.is_key_down(Key::LeftShift) {
speed *= 1.5;
}
if el.is_key_down(Key::W) {
velocity.y+=speed;
}
if el.is_key_down(Key::S) {
velocity.y-=speed;
}
if el.is_key_down(Key::D) {
velocity.x+=speed;
}
if el.is_key_down(Key::A) {
velocity.x-=speed;
}
*pos += velocity * el.dt;
}