entity spawning. great success

This commit is contained in:
2021-02-20 01:45:24 -08:00
parent a1305bed2d
commit c2b62a5f53
5 changed files with 276 additions and 225 deletions

View File

@@ -1,6 +1,11 @@
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
use std::time::Instant;
use cgmath::{Euler, Quaternion};
use config::Config;
use config::File;
use legion::world::SubWorld;
use legion::IntoQuery;
use legion::*;
@@ -8,15 +13,66 @@ use nalgebra::Quaternion as naQuaternion;
use rapier3d::dynamics::{IntegrationParameters, JointSet, RigidBodySet};
use rapier3d::geometry::{BroadPhase, ColliderSet, NarrowPhase};
use rapier3d::pipeline::PhysicsPipeline;
use crate::camera::{Camera, CameraController};
use crate::components::{Collider, LoopState, Mesh, Physics, Position};
use crate::geometry::{load_obj, RawMesh};
pub struct EntityMeta {
pub name: String,
pub ent_type: String,
pub mesh: String,
}
pub struct RuntimeState {
config_db: Config,
mesh_cache: HashMap<String, RawMesh>,
}
impl RuntimeState {
pub fn build() {
pub fn new() -> RuntimeState {
let mut settings = Config::default();
settings
// File::with_name(..) is shorthand for File::from(Path::new(..))
.merge(File::with_name("conf/entity_spawns.toml"))
.unwrap();
RuntimeState {
config_db: settings,
mesh_cache: Default::default(),
}
}
pub fn get_mesh(&mut self, mesh: &str) -> Option<&RawMesh> {
self.mesh_cache.get(mesh)
}
pub fn get_configured_entities(&mut self) -> Vec<EntityMeta> {
let mut out = Vec::new();
for entity in self.config_db.get_array("entities").unwrap() {
let table = entity.into_table().unwrap();
out.push(EntityMeta {
name: table.get("name").unwrap().kind.to_string(),
ent_type: table.get("type").unwrap().kind.to_string(),
mesh: table.get("mesh").unwrap().kind.to_string(),
});
}
out
}
pub fn preload_meshes(&mut self, resources_path: PathBuf) {
log::info!("Preloading meshes...");
let paths = fs::read_dir(resources_path).unwrap();
for file in paths {
let file = file.unwrap();
let filepath = file.path().clone();
let filename = String::from(file.file_name().to_str().unwrap());
if filename.ends_with(".obj") {
let mesh = load_obj(filepath.to_str().unwrap()).unwrap();
self.mesh_cache.insert(filename, mesh);
}
}
}
}

View File

@@ -1,33 +1,159 @@
use std::path::PathBuf;
use std::time::Instant;
use cgmath::{Euler, Quaternion};
use legion::world::SubWorld;
use legion::IntoQuery;
use cgmath::{Euler, Quaternion, Deg};
use imgui::FontSource;
use legion::*;
use legion::IntoQuery;
use legion::systems::CommandBuffer;
use legion::world::SubWorld;
use nalgebra::Quaternion as naQuaternion;
use rapier3d::dynamics::{IntegrationParameters, JointSet, RigidBodySet};
use rapier3d::geometry::{BroadPhase, ColliderSet, NarrowPhase};
use rapier3d::pipeline::{PhysicsPipeline, ChannelEventCollector};
use rapier3d::dynamics::{IntegrationParameters, JointSet, RigidBodyBuilder, RigidBodySet};
use rapier3d::geometry::{BroadPhase, ColliderBuilder, ColliderSet, NarrowPhase};
use rapier3d::na::{Isometry3, Vector, Vector3};
use rapier3d::pipeline::{ChannelEventCollector, PhysicsPipeline};
use crate::camera::{Camera, CameraController};
use crate::components::{Collider, LoopState, Mesh, Physics, Position};
use imgui::FontSource;
use crate::geometry::RawMesh;
use crate::physics::state::PhysicsState;
use crate::render::state::RenderState;
use crate::runtime::state::RuntimeState;
#[system]
#[write_component(Collider)]
#[write_component(Physics)]
#[write_component(Mesh)]
pub fn runtime_load(
world: &mut SubWorld,
#[resource] physics_state: &mut PhysicsState,
#[resource] physics_pipeline: &mut PhysicsPipeline,
#[resource] runtime_state: &mut RuntimeState,
) {
// Make sure all the entities we care about are added to the system
let mut query = <(&mut Collider, &mut Physics, &mut Mesh)>::query();
for (collider, physics, mesh) in query.iter_mut(world) {
runtime_state.preload_meshes(PathBuf::from("./resources"));
}
#[system]
#[write_component(Mesh)]
pub fn runtime_spawn(
cmd: &mut CommandBuffer,
world: &mut SubWorld,
#[resource] runtime_state: &mut RuntimeState,
#[resource] renderer: &mut RenderState,
) {
for entity in runtime_state.get_configured_entities(){
match entity.ent_type.as_ref() {
"Terrain" => {
let raw_mesh = match runtime_state.get_mesh(entity.mesh.as_str()) {
None => {
log::warn!("Skipping entity with invalid mesh file {:?} ", entity.mesh);
continue;
}
Some(mesh) => mesh
};
let mut static_body = RigidBodyBuilder::new_static()
.position(Isometry3::new(Vector3::new(0.0, -8.0, 0.0), Vector::y()))
.build();
let mesh_collider = ColliderBuilder::trimesh(
raw_mesh.vertices
.iter()
.map(|v| v.position())
.collect(),
raw_mesh.indices.clone(),
).build();
let gpu_mesh_buffer = renderer.upload_mesh_to_buffer(
raw_mesh,
Some(wgpu::Color {
r: 1.0,
g: 0.7,
b: 0.3,
a: 1.0,
})
).unwrap();
let entity: Entity = cmd.push((
Position {
x: 0.0,
y: -8.0,
z: 0.0,
rot: Euler {
x: Deg(0.0),
y: Deg(0.0),
z: Deg(0.0),
},
},
gpu_mesh_buffer,
Physics {
rigid_body: static_body,
rigid_body_handle: None,
},
Collider {
collider: mesh_collider,
collider_handle: None,
},
));
},
"PhysicsEntity" => {
let raw_mesh = match runtime_state.get_mesh(entity.mesh.as_str()) {
None => {
log::warn!("Skipping entity with invalid mesh file {:?} ", entity.mesh);
continue;
}
Some(mesh) => mesh
};
let mut dynamic_body = RigidBodyBuilder::new_dynamic()
.can_sleep(false)
.mass(1.0)
.translation(0.0, 35.0, 0.0)
.build();
let collider = ColliderBuilder::trimesh(
raw_mesh.vertices
.iter()
.map(|v| v.position())
.collect(),
raw_mesh.indices.clone(),
).build();
let gpu_mesh_buffer = renderer.upload_mesh_to_buffer(
raw_mesh,
Some(wgpu::Color {
r: 1.0,
g: 0.7,
b: 0.3,
a: 1.0,
})
).unwrap();
let entity: Entity = cmd.push((
Position {
x: 0.0,
y: 20.0,
z: 0.0,
rot: Euler {
x: Deg(25.0),
y: Deg(45.0),
z: Deg(15.0),
},
},
gpu_mesh_buffer,
Physics {
rigid_body: dynamic_body,
rigid_body_handle: None,
},
Collider {
collider: collider,
collider_handle: None,
},
));
}
_ => {},
}
}
}
}