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]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
ecs.workspace = true
|
ecs.workspace = true
|
||||||
|
hexasphere = "15.1.0"
|
||||||
|
|
||||||
engine = { path = "../../engine" }
|
engine = { path = "../../engine" }
|
||||||
skybox = { path = "../../skybox" }
|
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)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct PlayerEntity(Entity);
|
struct PlayerEntity(Entity);
|
||||||
|
@ -268,16 +268,19 @@ impl Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_scene(world: &mut World) -> Result<()> {
|
pub fn setup_scene(world: &mut World) -> Result<()> {
|
||||||
let mut fighter = AssetHandler::create(world).create_entity("fighter_edited")?;
|
// let mut fighter = AssetHandler::create(world).create_entity("fighter_edited")?;
|
||||||
fighter.insert_component(FreeSpaceControl::new(
|
// fighter.insert_component(FreeSpaceControl::new(
|
||||||
0.02,
|
// 0.02,
|
||||||
FreeSpaceControlSettings::default(),
|
// FreeSpaceControlSettings::default(),
|
||||||
));
|
// ));
|
||||||
|
|
||||||
let player = PlayerEntity(world.add_entity(fighter)?);
|
// let player = PlayerEntity(world.add_entity(fighter)?);
|
||||||
world.resources.insert(player);
|
// world.resources.insert(player);
|
||||||
world.resources.insert(InputSettings::default());
|
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 context = world.resources.get::<Context>();
|
||||||
let mut light = Light::point_light(context.device())?;
|
let mut light = Light::point_light(context.device())?;
|
||||||
light.set_position(vec3(10_000.0, 10_000.0, 10_000.0))?;
|
light.set_position(vec3(10_000.0, 10_000.0, 10_000.0))?;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod celestial_object;
|
||||||
mod game;
|
mod game;
|
||||||
mod game_state;
|
mod game_state;
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ use game::Game;
|
||||||
use game_state::GameState;
|
use game_state::GameState;
|
||||||
use skybox::SkyBox;
|
use skybox::SkyBox;
|
||||||
|
|
||||||
const FREE_CAMERA_CONTROL: bool = false;
|
const FREE_CAMERA_CONTROL: bool = true;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut world_builder = World::builder();
|
let mut world_builder = World::builder();
|
||||||
|
|
Loading…
Reference in a new issue