use qsi::prelude::*;
fn main() -> Result<()> {
env_logger::init();
App::new()
.with_title("qsi - Basic Grid Example")
.add_startup_system(setup_scene)
.add_system(physics_system)
.add_system(rotation_system)
.run()
}
fn setup_scene(world: &mut World, renderer: &mut qsi::graphics::Renderer) {
world
.spawn()
.with(Transform::at_position(Vector3::new(10.0, 5.0, 10.0)))
.with(Camera::default());
let cube_entity = world
.spawn()
.with(Transform::default())
.with(SpinComponent { speed: 1.0 })
.with(qsi::math::Velocity::angular(Vector3::new(0.0, 1.0, 0.0)))
.build();
let cube_mesh = create_cube_mesh(renderer);
world.add_component(cube_entity, cube_mesh);
let grid_entity = world.spawn().with(Transform::default()).build();
let grid_mesh = create_grid_mesh(renderer, 50, 1.0);
world.add_component(grid_entity, grid_mesh);
}
#[derive(Debug, Clone)]
struct SpinComponent {
speed: f32,
}
impl qsi::ecs::Component for SpinComponent {}
fn physics_system(world: &mut World, _input: &qsi::input::InputState, time: &qsi::time::TimeState) {
let dt = time.delta_seconds();
let mut updates = Vec::new();
for (entity, velocity) in world.query::<qsi::math::Velocity>() {
if let Some(transform) = world.get_component::<Transform>(entity) {
let mut new_transform = transform.clone();
new_transform.position += velocity.linear * dt;
new_transform.rotation += velocity.angular * dt;
updates.push((entity, new_transform));
}
}
for (entity, transform) in updates {
world.add_component(entity, transform);
}
}
fn rotation_system(
world: &mut World,
_input: &qsi::input::InputState,
time: &qsi::time::TimeState,
) {
let dt = time.delta_seconds();
let mut updates = Vec::new();
for (entity, spin) in world.query::<SpinComponent>() {
if let Some(transform) = world.get_component::<Transform>(entity) {
let mut new_transform = transform.clone();
new_transform.rotation.y += spin.speed * dt;
updates.push((entity, new_transform));
}
}
for (entity, transform) in updates {
world.add_component(entity, transform);
}
}
fn create_cube_mesh(renderer: &qsi::graphics::Renderer) -> qsi::graphics::Mesh {
let cube_color = [1.0, 0.5, 0.0]; let vertices = vec![
qsi::graphics::Vertex {
position: [-0.5, -0.5, 0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [0.5, -0.5, 0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [0.5, 0.5, 0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [-0.5, 0.5, 0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [-0.5, -0.5, -0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [0.5, -0.5, -0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [0.5, 0.5, -0.5],
color: cube_color,
},
qsi::graphics::Vertex {
position: [-0.5, 0.5, -0.5],
color: cube_color,
},
];
let indices: Vec<u16> = vec![
0, 1, 2, 2, 3, 0, 4, 6, 5, 6, 4, 7, 4, 0, 3, 3, 7, 4, 1, 5, 6, 6, 2, 1, 3, 2, 6, 6, 7, 3, 4, 5, 1, 1, 0, 4,
];
renderer.create_mesh(&vertices, &indices)
}
fn create_grid_mesh(
renderer: &qsi::graphics::Renderer,
size: u32,
spacing: f32,
) -> qsi::graphics::Mesh {
let mut vertices = Vec::new();
let mut indices = Vec::new();
let half_size = size as f32 * spacing * 0.5;
let grid_color = [0.3, 0.3, 0.3];
let axis_color = [0.6, 0.6, 0.6];
for i in 0..=size {
let z = i as f32 * spacing - half_size;
let color = if i == size / 2 {
axis_color
} else {
grid_color
};
vertices.push(qsi::graphics::Vertex {
position: [-half_size, 0.0, z],
color,
});
vertices.push(qsi::graphics::Vertex {
position: [half_size, 0.0, z],
color,
});
}
for i in 0..=size {
let x = i as f32 * spacing - half_size;
let color = if i == size / 2 {
axis_color
} else {
grid_color
};
vertices.push(qsi::graphics::Vertex {
position: [x, 0.0, -half_size],
color,
});
vertices.push(qsi::graphics::Vertex {
position: [x, 0.0, half_size],
color,
});
}
for i in 0..vertices.len() {
if i % 2 == 0 {
indices.push(i as u16);
indices.push((i + 1) as u16);
}
}
renderer.create_line_mesh(&vertices, &indices)
}