Add some bodies
This commit is contained in:
parent
363ab111bc
commit
402a1b8ddf
5 changed files with 169 additions and 29 deletions
|
@ -12,6 +12,23 @@ pub struct BoundingBox {
|
|||
}
|
||||
|
||||
impl BoundingBox {
|
||||
pub fn init() -> Self {
|
||||
Self {
|
||||
min: [f32::INFINITY; 3],
|
||||
max: [-f32::INFINITY; 3],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check(&mut self, v: Vector3<f32>) {
|
||||
self.min[0] = self.min[0].min(v.x);
|
||||
self.min[1] = self.min[1].min(v.y);
|
||||
self.min[2] = self.min[2].min(v.z);
|
||||
|
||||
self.max[0] = self.max[0].max(v.x);
|
||||
self.max[1] = self.max[1].max(v.y);
|
||||
self.max[2] = self.max[2].max(v.z);
|
||||
}
|
||||
|
||||
pub fn is_zero(&self) -> bool {
|
||||
self.min[0] == 0.0
|
||||
&& self.min[1] == 0.0
|
||||
|
|
|
@ -111,7 +111,7 @@ void own_implementation() {
|
|||
int miss_shader_index = 0;
|
||||
int sbt_record_stride = 0;
|
||||
float tmin = 0.001;
|
||||
float tmax = 10000.0;
|
||||
float tmax = 1000000000.0;
|
||||
|
||||
vec3 direction = reflect(gl_WorldRayDirectionEXT, normal);
|
||||
|
||||
|
@ -145,7 +145,7 @@ void own_implementation() {
|
|||
int miss_shader_index = 0;
|
||||
int sbt_record_stride = 0;
|
||||
float tmin = 0.001;
|
||||
float tmax = 10000.0;
|
||||
float tmax = 1000000000.0;
|
||||
|
||||
pay_load.depth++;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ void main()
|
|||
int miss_shader_index = 0;
|
||||
int sbt_record_stride = 0;
|
||||
float tmin = 0.001;
|
||||
float tmax = 10000.0;
|
||||
float tmax = 1000000000.0;
|
||||
|
||||
pay_load.depth = 0;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use core::f32;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
|
@ -8,21 +9,57 @@ use engine::prelude::{
|
|||
};
|
||||
use hexasphere::shapes::IcoSphere;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum CelestialClass {
|
||||
Sun,
|
||||
Solid,
|
||||
Gas,
|
||||
}
|
||||
|
||||
impl CelestialClass {
|
||||
/// in g/cm³
|
||||
pub fn density(&self) -> f32 {
|
||||
match self {
|
||||
// our sun
|
||||
CelestialClass::Sun => 1.41,
|
||||
|
||||
// earth
|
||||
CelestialClass::Solid => 5.51,
|
||||
|
||||
// saturn
|
||||
CelestialClass::Gas => 0.69,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn color(&self) -> [f32; 4] {
|
||||
match self {
|
||||
CelestialClass::Sun => Color::Yellow.into(),
|
||||
CelestialClass::Solid => Color::Green.into(),
|
||||
CelestialClass::Gas => Color::Orange.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CelestialObject;
|
||||
|
||||
impl CelestialObject {
|
||||
pub fn new(
|
||||
world: &mut World,
|
||||
class: CelestialClass,
|
||||
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)?]);
|
||||
let mut celestial_settings = CelestialObjectSettings::default();
|
||||
celestial_settings.density = class.density();
|
||||
|
||||
let (mesh, bounding_box) = Self::create_asset(world, class, subdivisions)?;
|
||||
let draw = Draw::new(vec![mesh]);
|
||||
draw.set_transform(celestial_settings.model_matrix())?;
|
||||
|
||||
entity_object.insert_component(draw);
|
||||
entity_object.insert_component(bounding_box);
|
||||
entity_object.insert_component(celestial_settings);
|
||||
|
||||
if let Some(e) = celestial_reference.into() {
|
||||
|
@ -32,13 +69,19 @@ impl CelestialObject {
|
|||
Ok(entity_object)
|
||||
}
|
||||
|
||||
fn create_asset(world: &World, subdivisions: usize) -> Result<AssetMesh> {
|
||||
fn create_asset(
|
||||
world: &World,
|
||||
class: CelestialClass,
|
||||
subdivisions: usize,
|
||||
) -> Result<(AssetMesh, BoundingBox)> {
|
||||
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 (sphere, bounding_box) = Self::create_sphere(subdivisions);
|
||||
|
||||
let buffer = {
|
||||
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
|
@ -48,7 +91,7 @@ impl CelestialObject {
|
|||
.set_memory_usage(MemoryUsage::CpuToGpu)
|
||||
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
|
||||
.set_data(
|
||||
&Self::create_sphere(subdivisions)
|
||||
&sphere
|
||||
.into_iter()
|
||||
.map(|(v, n)| PositionNormal::new(v, n))
|
||||
.collect::<Vec<_>>(),
|
||||
|
@ -83,6 +126,7 @@ impl CelestialObject {
|
|||
None,
|
||||
None,
|
||||
PrimitiveMaterial {
|
||||
color: class.color(),
|
||||
emissive_factor: [0.65, 0.65, 0.65],
|
||||
metallic_factor: 0.5,
|
||||
roughness_factor: 0.7,
|
||||
|
@ -92,18 +136,25 @@ impl CelestialObject {
|
|||
false,
|
||||
)?;
|
||||
|
||||
Ok(asset_mesh)
|
||||
Ok((asset_mesh, bounding_box))
|
||||
}
|
||||
|
||||
fn create_sphere(subdivisions: usize) -> Vec<(Vector3<f32>, Vector3<f32>)> {
|
||||
fn create_sphere(subdivisions: usize) -> (Vec<(Vector3<f32>, Vector3<f32>)>, BoundingBox) {
|
||||
let mut bounding_box = BoundingBox::init();
|
||||
let sphere = IcoSphere::new(subdivisions, |_| ());
|
||||
|
||||
let points = sphere
|
||||
.raw_points()
|
||||
.into_iter()
|
||||
.map(|v| Vector3::from(v.to_array()))
|
||||
.map(|v| {
|
||||
let v = Vector3::from(v.to_array());
|
||||
bounding_box.check(v);
|
||||
|
||||
v
|
||||
})
|
||||
.collect::<Vec<Vector3<f32>>>();
|
||||
|
||||
(
|
||||
sphere
|
||||
.get_all_indices()
|
||||
.chunks(3)
|
||||
|
@ -120,7 +171,9 @@ impl CelestialObject {
|
|||
[(p1, n), (p2, n), (p3, n)]
|
||||
})
|
||||
.flatten()
|
||||
.collect()
|
||||
.collect(),
|
||||
bounding_box,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,8 +188,18 @@ pub struct CelestialObjectSettings {
|
|||
}
|
||||
|
||||
impl CelestialObjectSettings {
|
||||
fn model_matrix(&self) -> Matrix4<f32> {
|
||||
Matrix4::from_translation(self.location) * Matrix4::from_scale(self.radius)
|
||||
const SCALE: f32 = 0.5;
|
||||
|
||||
fn volume(&self) -> f32 {
|
||||
(4.0 / 3.0) * f32::consts::PI * self.radius.powi(3)
|
||||
}
|
||||
|
||||
fn mass(&self) -> f32 {
|
||||
self.volume() * self.density
|
||||
}
|
||||
|
||||
pub fn model_matrix(&self) -> Matrix4<f32> {
|
||||
Matrix4::from_translation(self.location) * Matrix4::from_scale(self.radius * Self::SCALE)
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
|
@ -145,6 +208,10 @@ impl CelestialObjectSettings {
|
|||
draw: &Draw,
|
||||
celestial_object_settings_reference: &CelestialObjectSettings,
|
||||
) -> Result<()> {
|
||||
self.last_update = now;
|
||||
|
||||
// TODO: velocity calculation around celestial reference
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +220,7 @@ impl Default for CelestialObjectSettings {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
location: Vector3::zero(),
|
||||
radius: 1.0,
|
||||
radius: 2.0,
|
||||
density: 1.0,
|
||||
velocity: 0.0,
|
||||
|
||||
|
|
|
@ -8,7 +8,12 @@ use engine::prelude::{
|
|||
*,
|
||||
};
|
||||
|
||||
use crate::{FREE_CAMERA_CONTROL, celestial_object::CelestialObject};
|
||||
use crate::{
|
||||
FREE_CAMERA_CONTROL,
|
||||
celestial_object::{
|
||||
CelestialClass, CelestialObject, CelestialObjectSettings, CelestialReference,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
struct PlayerEntity(Entity);
|
||||
|
@ -264,6 +269,20 @@ impl Game {
|
|||
world_builder.add_update("camera_position", 1_000, Self::camera_update, EmptyFilter)?;
|
||||
}
|
||||
|
||||
world_builder.add_update(
|
||||
"celestial velocity update",
|
||||
100,
|
||||
Self::celestial_velocity_update,
|
||||
(EmptyFilter, EmptyFilter),
|
||||
)?;
|
||||
|
||||
world_builder.add_update(
|
||||
"celestial buffer update",
|
||||
110,
|
||||
Self::celestial_buffer_update,
|
||||
EmptyFilter,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -278,7 +297,16 @@ impl Game {
|
|||
// world.resources.insert(player);
|
||||
world.resources.insert(InputSettings::default());
|
||||
|
||||
let example_planet = CelestialObject::new(world, 5, None)?;
|
||||
let mut example_sun = CelestialObject::new(world, CelestialClass::Sun, 5, None)?;
|
||||
let sun_settings = example_sun.get_component_mut::<CelestialObjectSettings>()?;
|
||||
sun_settings.location = vec3(10_000.0, 10_000.0, 0.0);
|
||||
sun_settings.radius = 1_000.0;
|
||||
let sun_entity = world.add_entity(example_sun)?;
|
||||
|
||||
let mut example_planet = CelestialObject::new(world, CelestialClass::Solid, 5, sun_entity)?;
|
||||
let sun_settings = example_planet.get_component_mut::<CelestialObjectSettings>()?;
|
||||
sun_settings.location.x = 1000.0;
|
||||
sun_settings.radius = 250.0;
|
||||
world.add_entity(example_planet)?;
|
||||
|
||||
let context = world.resources.get::<Context>();
|
||||
|
@ -325,4 +353,32 @@ impl Game {
|
|||
|
||||
view.update_buffer()
|
||||
}
|
||||
|
||||
fn celestial_buffer_update(
|
||||
_: &mut World,
|
||||
_: Entity,
|
||||
draw: &mut Draw,
|
||||
control: &mut CelestialObjectSettings,
|
||||
) -> Result<()> {
|
||||
draw.set_transform(control.model_matrix())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn celestial_velocity_update(
|
||||
world: &mut World,
|
||||
(_, draw, lhs_control, reference): (
|
||||
Entity,
|
||||
&mut Draw,
|
||||
&mut CelestialObjectSettings,
|
||||
&mut CelestialReference,
|
||||
),
|
||||
(rhs_entity, rhs_control): (Entity, &mut CelestialObjectSettings),
|
||||
) -> Result<()> {
|
||||
if reference.entity == rhs_entity {
|
||||
lhs_control.update(world.now(), draw, rhs_control)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue