198 lines
7.8 KiB
Rust
198 lines
7.8 KiB
Rust
use std::sync::Arc;
|
|
use cgmath as cgm;
|
|
|
|
use ecs_macros::Access;
|
|
use engine::{
|
|
globals, input, physics, render, scripting, util,
|
|
};
|
|
|
|
struct Main {
|
|
light1: ecs::EntityID,
|
|
cube1: ecs::EntityID,
|
|
|
|
cx: f32,
|
|
cy: f32,
|
|
}
|
|
|
|
impl Main {
|
|
pub fn new(world: &mut ecs::World, renderer: &mut render::Renderer) -> Self {
|
|
let mut rm = render::resource::Manager::new();
|
|
let mesh = {
|
|
let vertices = Arc::new(vec![
|
|
render::mesh::Vertex::new([-0.5, -0.5, 0.5], [ 0.0, 0.0, 1.0], [1.0, 0.0]),
|
|
render::mesh::Vertex::new([ 0.5, -0.5, 0.5], [ 0.0, 0.0, 1.0], [0.0, 0.0]),
|
|
render::mesh::Vertex::new([ 0.5, 0.5, 0.5], [ 0.0, 0.0, 1.0], [0.0, 1.0]),
|
|
render::mesh::Vertex::new([-0.5, 0.5, 0.5], [ 0.0, 0.0, 1.0], [1.0, 1.0]),
|
|
|
|
render::mesh::Vertex::new([ 0.5, -0.5, -0.5], [ 1.0, 0.0, 0.0], [0.0, 1.0]),
|
|
render::mesh::Vertex::new([ 0.5, 0.5, -0.5], [ 1.0, 0.0, 0.0], [1.0, 1.0]),
|
|
render::mesh::Vertex::new([ 0.5, 0.5, 0.5], [ 1.0, 0.0, 0.0], [1.0, 0.0]),
|
|
render::mesh::Vertex::new([ 0.5, -0.5, 0.5], [ 1.0, 0.0, 0.0], [0.0, 0.0]),
|
|
|
|
render::mesh::Vertex::new([-0.5, -0.5, -0.5], [-1.0, 0.0, 0.0], [1.0, 1.0]),
|
|
render::mesh::Vertex::new([-0.5, 0.5, -0.5], [-1.0, 0.0, 0.0], [0.0, 1.0]),
|
|
render::mesh::Vertex::new([-0.5, 0.5, 0.5], [-1.0, 0.0, 0.0], [0.0, 0.0]),
|
|
render::mesh::Vertex::new([-0.5, -0.5, 0.5], [-1.0, 0.0, 0.0], [1.0, 0.0]),
|
|
|
|
render::mesh::Vertex::new([-0.5, -0.5, -0.5], [ 0.0, -1.0, 0.0], [0.0, 1.0]),
|
|
render::mesh::Vertex::new([ 0.5, -0.5, -0.5], [ 0.0, -1.0, 0.0], [1.0, 1.0]),
|
|
render::mesh::Vertex::new([ 0.5, -0.5, 0.5], [ 0.0, -1.0, 0.0], [1.0, 0.0]),
|
|
render::mesh::Vertex::new([-0.5, -0.5, 0.5], [ 0.0, -1.0, 0.0], [0.0, 0.0]),
|
|
|
|
render::mesh::Vertex::new([-0.5, 0.5, -0.5], [ 0.0, 1.0, 0.0], [1.0, 1.0]),
|
|
render::mesh::Vertex::new([ 0.5, 0.5, -0.5], [ 0.0, 1.0, 0.0], [0.0, 1.0]),
|
|
render::mesh::Vertex::new([ 0.5, 0.5, 0.5], [ 0.0, 1.0, 0.0], [0.0, 0.0]),
|
|
render::mesh::Vertex::new([-0.5, 0.5, 0.5], [ 0.0, 1.0, 0.0], [1.0, 0.0]),
|
|
|
|
render::mesh::Vertex::new([-0.5, -0.5, -0.5], [ 0.0, 0.0, -1.0], [0.0, 0.0]),
|
|
render::mesh::Vertex::new([ 0.5, -0.5, -0.5], [ 0.0, 0.0, -1.0], [1.0, 0.0]),
|
|
render::mesh::Vertex::new([ 0.5, 0.5, -0.5], [ 0.0, 0.0, -1.0], [1.0, 1.0]),
|
|
render::mesh::Vertex::new([-0.5, 0.5, -0.5], [ 0.0, 0.0, -1.0], [0.0, 1.0]),
|
|
]);
|
|
let indices = Arc::new(vec![
|
|
0, 1, 2, 2, 3, 0,
|
|
|
|
4, 5, 6, 6, 7, 4,
|
|
8, 10, 9, 10, 8, 11,
|
|
|
|
12, 13, 14, 14, 15, 12,
|
|
16, 18, 17, 18, 16, 19,
|
|
|
|
20, 22, 21, 22, 20, 23,
|
|
|
|
]);
|
|
rm.add(render::Mesh::new(vertices, indices), Some("cube"))
|
|
};
|
|
|
|
let material = rm.add(render::material::PBRMaterialBuilder {
|
|
diffuse: render::material::Texture::from_image(String::from("//assets/test-128px.png")),
|
|
roughness: render::material::Texture::from_image(String::from("//assets/test-128px-roughness.png")),
|
|
}.build(), Some("test-128px"));
|
|
|
|
let light = rm.add(render::Light::omni_test(), Some("omni"));
|
|
|
|
// The Sun (Sol) is 1AU from the Earth. We ignore the diameter of the Sun and the Earth, as
|
|
// these are negligible at this scale.
|
|
let sun_distance: f32 = 149_597_870_700.0;
|
|
// Solar constant: solar radiant power per square meter of earth's area [w/m^2].
|
|
let solar_constant: f32 = 1366.0;
|
|
// Solar luminous emittance (assuming 93 luminous efficacy) [lm/m^2].
|
|
let sun_luminous_emittance: f32 = solar_constant * 93.0;
|
|
// Solar luminour power (integrating over a sphere of radius == sun_distance) [lm].
|
|
let sun_lumen: f32 = sun_luminous_emittance * (4.0 * 3.14159 * sun_distance * sun_distance);
|
|
|
|
let sun_color = physics::color::XYZ::new(sun_lumen/3.0, sun_lumen/3.0, sun_lumen/3.0);
|
|
let sun = rm.add(render::Light::omni_with_color(sun_color), Some("sun"));
|
|
|
|
// In our scene, the sun at a 30 degree zenith.
|
|
let sun_angle: f32 = (3.14159 * 2.0) / (360.0 / 30.0);
|
|
|
|
let light1 = world.new_entity()
|
|
.with(render::Transform::at(-10.0, -10.0, -5.0))
|
|
.with(render::Renderable::Light(light))
|
|
.build();
|
|
let cube1 = world.new_entity()
|
|
.with(render::Transform::at(-10.0, -10.0, -5.0))
|
|
.with(render::Renderable::Mesh(mesh, material))
|
|
.build();
|
|
world.new_entity()
|
|
.with(render::Transform::at(0.0, sun_angle.sin() * sun_distance, sun_angle.cos() * sun_distance))
|
|
.with(render::Renderable::Light(sun))
|
|
.build();
|
|
|
|
world.set_global(rm);
|
|
|
|
Self {
|
|
light1, cube1,
|
|
cx: 0.,
|
|
cy: 0.,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Access)]
|
|
struct MainData<'a> {
|
|
scene_info: ecs::ReadWriteGlobal<'a, render::SceneInfo>,
|
|
time: ecs::ReadGlobal<'a, globals::Time>,
|
|
input: ecs::ReadGlobal<'a, input::Input>,
|
|
transforms: ecs::ReadWriteComponent<'a, render::Transform>,
|
|
}
|
|
|
|
impl<'a> ecs::System <'a> for Main {
|
|
type SystemData = MainData<'a>;
|
|
fn run(&mut self, sd: Self::SystemData) {
|
|
|
|
let ts: f32 = (sd.time.get().instant() / 10.0) * 3.14 * 2.0;
|
|
let (dx, dy) = match sd.input.get().mouse_cursor() {
|
|
Some(cursor) => (cursor.dx, cursor.dy),
|
|
_ => (0.0, 0.0),
|
|
};
|
|
self.cx += (dx);
|
|
self.cy += (dy);
|
|
|
|
let camera = cgm::Point3::new(
|
|
self.cx.sin() * 20.0,
|
|
(self.cx.cos()*self.cy.cos()) * 20.0,
|
|
self.cy.sin() * 20.0,
|
|
);
|
|
|
|
let view = cgm::Matrix4::look_at(
|
|
camera.clone(),
|
|
cgm::Point3::new(0.0, 0.0, 0.0),
|
|
cgm::Vector3::new(0.0, 0.0, 1.0)
|
|
);
|
|
|
|
sd.scene_info.get().camera = camera;
|
|
sd.scene_info.get().view = view;
|
|
sd.scene_info.get().lock_cursor = true;
|
|
|
|
let lx = 0.0;
|
|
let ly = 4.0;
|
|
let lz = -0.0 + (ts*2.0).sin() * 4.0;
|
|
|
|
*sd.transforms.get_mut(self.light1).unwrap() = render::Transform::at(lx, ly, lz);
|
|
let mut ctransform = render::Transform::at(lx, ly, lz);
|
|
ctransform.0 = ctransform.0 * cgmath::Matrix4::from_scale(0.1);
|
|
*sd.transforms.get_mut(self.cube1).unwrap() = ctransform;
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
env_logger::init_from_env(env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"));
|
|
|
|
let mut world = ecs::World::new();
|
|
world.register_component_lua_bindings(render::Transform::bindings());
|
|
world.register_component_lua_bindings(render::Renderable::bindings());
|
|
let mut renderer = render::Renderer::initialize(&mut world);
|
|
let main = Main::new(&mut world, &mut renderer);
|
|
|
|
let context = scripting::WorldContext::new(&world);
|
|
|
|
let init = util::file::resource("//engine/lua/init.lua").unwrap().string().unwrap();
|
|
context.eval_init(&world, init).unwrap();
|
|
let scene = util::file::resource("//hsvr/lua/scene.lua").unwrap().string().unwrap();
|
|
context.eval_init(&world, scene).unwrap();
|
|
|
|
log::info!("Starting...");
|
|
|
|
let mut p = ecs::Processor::new();
|
|
p.add_system(main);
|
|
p.add_system(context);
|
|
p.add_system(renderer);
|
|
|
|
world.set_global(globals::Time::new());
|
|
world.set_global(input::Input::new());
|
|
loop {
|
|
world.queue_drain();
|
|
world.global_mut::<globals::Time>().get().update();
|
|
|
|
p.run(&world);
|
|
let status = world.global::<render::Status>().get();
|
|
if status.closed {
|
|
log::info!("Renderer closed, exiting.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|