Add celestial body
This commit is contained in:
parent
c1c29efcf0
commit
363ab111bc
4 changed files with 206 additions and 9 deletions
|
@ -6,6 +6,7 @@ edition = "2024"
|
|||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
ecs.workspace = true
|
||||
hexasphere = "15.1.0"
|
||||
|
||||
engine = { path = "../../engine" }
|
||||
skybox = { path = "../../skybox" }
|
||||
|
|
192
examples/free_space/src/celestial_object.rs
Normal file
192
examples/free_space/src/celestial_object.rs
Normal file
|
@ -0,0 +1,192 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use ecs::*;
|
||||
use engine::prelude::{
|
||||
cgmath::{Matrix4, Vector3},
|
||||
*,
|
||||
};
|
||||
use hexasphere::shapes::IcoSphere;
|
||||
|
||||
pub struct CelestialObject;
|
||||
|
||||
impl CelestialObject {
|
||||
pub fn new(
|
||||
world: &mut World,
|
||||
subdivisions: usize,
|
||||
celestial_reference: impl Into<Option<Entity>>,
|
||||
) -> Result<EntityObject> {
|
||||
let mut entity_object = AssetHandler::create(world).empty_entity();
|
||||
|
||||
let celestial_settings = CelestialObjectSettings::default();
|
||||
let draw = Draw::new(vec![Self::create_asset(world, subdivisions)?]);
|
||||
draw.set_transform(celestial_settings.model_matrix())?;
|
||||
|
||||
entity_object.insert_component(draw);
|
||||
entity_object.insert_component(celestial_settings);
|
||||
|
||||
if let Some(e) = celestial_reference.into() {
|
||||
entity_object.insert_component(CelestialReference { entity: e });
|
||||
}
|
||||
|
||||
Ok(entity_object)
|
||||
}
|
||||
|
||||
fn create_asset(world: &World, subdivisions: usize) -> Result<AssetMesh> {
|
||||
let context = world.resources.get::<Context>();
|
||||
let scene = world.resources.get::<Scene>();
|
||||
|
||||
let command_buffer = CommandBuffer::new_primary()
|
||||
.build(context.device().clone(), context.queue().clone())?;
|
||||
|
||||
let buffer = {
|
||||
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
))?;
|
||||
|
||||
Buffer::builder()
|
||||
.set_memory_usage(MemoryUsage::CpuToGpu)
|
||||
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
|
||||
.set_data(
|
||||
&Self::create_sphere(subdivisions)
|
||||
.into_iter()
|
||||
.map(|(v, n)| PositionNormal::new(v, n))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.build(context.device().clone())?
|
||||
.into_device_local(
|
||||
&mut recorder,
|
||||
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
|
||||
)?
|
||||
};
|
||||
|
||||
// submit
|
||||
let submit = SubmitInfo::default().add_command_buffer(&command_buffer);
|
||||
let fence = Fence::builder().build(context.device().clone())?;
|
||||
|
||||
context
|
||||
.queue()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.submit(Some(&fence), &[submit])?;
|
||||
|
||||
context
|
||||
.device()
|
||||
.wait_for_fences(&[&fence], true, Duration::from_secs(1))?;
|
||||
|
||||
let mut asset_mesh = AssetMesh::new(context.device(), scene.render_type())?;
|
||||
|
||||
asset_mesh.add_primitive(
|
||||
buffer,
|
||||
None,
|
||||
None,
|
||||
PrimitiveMaterial {
|
||||
emissive_factor: [0.65, 0.65, 0.65],
|
||||
metallic_factor: 0.5,
|
||||
roughness_factor: 0.7,
|
||||
|
||||
..PrimitiveMaterial::default()
|
||||
},
|
||||
false,
|
||||
)?;
|
||||
|
||||
Ok(asset_mesh)
|
||||
}
|
||||
|
||||
fn create_sphere(subdivisions: usize) -> Vec<(Vector3<f32>, Vector3<f32>)> {
|
||||
let sphere = IcoSphere::new(subdivisions, |_| ());
|
||||
|
||||
let points = sphere
|
||||
.raw_points()
|
||||
.into_iter()
|
||||
.map(|v| Vector3::from(v.to_array()))
|
||||
.collect::<Vec<Vector3<f32>>>();
|
||||
|
||||
sphere
|
||||
.get_all_indices()
|
||||
.chunks(3)
|
||||
.map(|triangle| {
|
||||
let p1 = points[triangle[0] as usize];
|
||||
let p2 = points[triangle[1] as usize];
|
||||
let p3 = points[triangle[2] as usize];
|
||||
|
||||
let v1 = p1 - p2;
|
||||
let v2 = p1 - p3;
|
||||
|
||||
let n = v2.cross(v1);
|
||||
|
||||
[(p1, n), (p2, n), (p3, n)]
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CelestialObjectSettings {
|
||||
pub location: Vector3<f32>,
|
||||
pub radius: f32,
|
||||
pub density: f32,
|
||||
pub velocity: f32,
|
||||
|
||||
last_update: Duration,
|
||||
}
|
||||
|
||||
impl CelestialObjectSettings {
|
||||
fn model_matrix(&self) -> Matrix4<f32> {
|
||||
Matrix4::from_translation(self.location) * Matrix4::from_scale(self.radius)
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
now: Duration,
|
||||
draw: &Draw,
|
||||
celestial_object_settings_reference: &CelestialObjectSettings,
|
||||
) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CelestialObjectSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
location: Vector3::zero(),
|
||||
radius: 1.0,
|
||||
density: 1.0,
|
||||
velocity: 0.0,
|
||||
|
||||
last_update: Duration::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EntityComponent for CelestialObjectSettings {
|
||||
fn name(&self) -> &str {
|
||||
Self::debug_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentDebug for CelestialObjectSettings {
|
||||
fn debug_name() -> &'static str {
|
||||
"CelestialObjectSettings"
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CelestialReference {
|
||||
pub entity: Entity,
|
||||
}
|
||||
|
||||
impl EntityComponent for CelestialReference {
|
||||
fn name(&self) -> &str {
|
||||
Self::debug_name()
|
||||
}
|
||||
}
|
||||
|
||||
impl ComponentDebug for CelestialReference {
|
||||
fn debug_name() -> &'static str {
|
||||
"CelestialReference"
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ use engine::prelude::{
|
|||
*,
|
||||
};
|
||||
|
||||
use crate::FREE_CAMERA_CONTROL;
|
||||
use crate::{FREE_CAMERA_CONTROL, celestial_object::CelestialObject};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct PlayerEntity(Entity);
|
||||
|
@ -268,16 +268,19 @@ impl Game {
|
|||
}
|
||||
|
||||
pub fn setup_scene(world: &mut World) -> Result<()> {
|
||||
let mut fighter = AssetHandler::create(world).create_entity("fighter_edited")?;
|
||||
fighter.insert_component(FreeSpaceControl::new(
|
||||
0.02,
|
||||
FreeSpaceControlSettings::default(),
|
||||
));
|
||||
// let mut fighter = AssetHandler::create(world).create_entity("fighter_edited")?;
|
||||
// fighter.insert_component(FreeSpaceControl::new(
|
||||
// 0.02,
|
||||
// FreeSpaceControlSettings::default(),
|
||||
// ));
|
||||
|
||||
let player = PlayerEntity(world.add_entity(fighter)?);
|
||||
world.resources.insert(player);
|
||||
// let player = PlayerEntity(world.add_entity(fighter)?);
|
||||
// world.resources.insert(player);
|
||||
world.resources.insert(InputSettings::default());
|
||||
|
||||
let example_planet = CelestialObject::new(world, 5, None)?;
|
||||
world.add_entity(example_planet)?;
|
||||
|
||||
let context = world.resources.get::<Context>();
|
||||
let mut light = Light::point_light(context.device())?;
|
||||
light.set_position(vec3(10_000.0, 10_000.0, 10_000.0))?;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
mod celestial_object;
|
||||
mod game;
|
||||
mod game_state;
|
||||
|
||||
|
@ -11,7 +12,7 @@ use game::Game;
|
|||
use game_state::GameState;
|
||||
use skybox::SkyBox;
|
||||
|
||||
const FREE_CAMERA_CONTROL: bool = false;
|
||||
const FREE_CAMERA_CONTROL: bool = true;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut world_builder = World::builder();
|
||||
|
|
Loading…
Reference in a new issue