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 {
|
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 {
|
pub fn is_zero(&self) -> bool {
|
||||||
self.min[0] == 0.0
|
self.min[0] == 0.0
|
||||||
&& self.min[1] == 0.0
|
&& self.min[1] == 0.0
|
||||||
|
|
|
@ -111,7 +111,7 @@ void own_implementation() {
|
||||||
int miss_shader_index = 0;
|
int miss_shader_index = 0;
|
||||||
int sbt_record_stride = 0;
|
int sbt_record_stride = 0;
|
||||||
float tmin = 0.001;
|
float tmin = 0.001;
|
||||||
float tmax = 10000.0;
|
float tmax = 1000000000.0;
|
||||||
|
|
||||||
vec3 direction = reflect(gl_WorldRayDirectionEXT, normal);
|
vec3 direction = reflect(gl_WorldRayDirectionEXT, normal);
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ void own_implementation() {
|
||||||
int miss_shader_index = 0;
|
int miss_shader_index = 0;
|
||||||
int sbt_record_stride = 0;
|
int sbt_record_stride = 0;
|
||||||
float tmin = 0.001;
|
float tmin = 0.001;
|
||||||
float tmax = 10000.0;
|
float tmax = 1000000000.0;
|
||||||
|
|
||||||
pay_load.depth++;
|
pay_load.depth++;
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ void main()
|
||||||
int miss_shader_index = 0;
|
int miss_shader_index = 0;
|
||||||
int sbt_record_stride = 0;
|
int sbt_record_stride = 0;
|
||||||
float tmin = 0.001;
|
float tmin = 0.001;
|
||||||
float tmax = 10000.0;
|
float tmax = 1000000000.0;
|
||||||
|
|
||||||
pay_load.depth = 0;
|
pay_load.depth = 0;
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use core::f32;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -8,21 +9,57 @@ use engine::prelude::{
|
||||||
};
|
};
|
||||||
use hexasphere::shapes::IcoSphere;
|
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;
|
pub struct CelestialObject;
|
||||||
|
|
||||||
impl CelestialObject {
|
impl CelestialObject {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
|
class: CelestialClass,
|
||||||
subdivisions: usize,
|
subdivisions: usize,
|
||||||
celestial_reference: impl Into<Option<Entity>>,
|
celestial_reference: impl Into<Option<Entity>>,
|
||||||
) -> Result<EntityObject> {
|
) -> Result<EntityObject> {
|
||||||
let mut entity_object = AssetHandler::create(world).empty_entity();
|
let mut entity_object = AssetHandler::create(world).empty_entity();
|
||||||
|
|
||||||
let celestial_settings = CelestialObjectSettings::default();
|
let mut celestial_settings = CelestialObjectSettings::default();
|
||||||
let draw = Draw::new(vec![Self::create_asset(world, subdivisions)?]);
|
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())?;
|
draw.set_transform(celestial_settings.model_matrix())?;
|
||||||
|
|
||||||
entity_object.insert_component(draw);
|
entity_object.insert_component(draw);
|
||||||
|
entity_object.insert_component(bounding_box);
|
||||||
entity_object.insert_component(celestial_settings);
|
entity_object.insert_component(celestial_settings);
|
||||||
|
|
||||||
if let Some(e) = celestial_reference.into() {
|
if let Some(e) = celestial_reference.into() {
|
||||||
|
@ -32,13 +69,19 @@ impl CelestialObject {
|
||||||
Ok(entity_object)
|
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 context = world.resources.get::<Context>();
|
||||||
let scene = world.resources.get::<Scene>();
|
let scene = world.resources.get::<Scene>();
|
||||||
|
|
||||||
let command_buffer = CommandBuffer::new_primary()
|
let command_buffer = CommandBuffer::new_primary()
|
||||||
.build(context.device().clone(), context.queue().clone())?;
|
.build(context.device().clone(), context.queue().clone())?;
|
||||||
|
|
||||||
|
let (sphere, bounding_box) = Self::create_sphere(subdivisions);
|
||||||
|
|
||||||
let buffer = {
|
let buffer = {
|
||||||
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
|
let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new(
|
||||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||||
|
@ -48,7 +91,7 @@ impl CelestialObject {
|
||||||
.set_memory_usage(MemoryUsage::CpuToGpu)
|
.set_memory_usage(MemoryUsage::CpuToGpu)
|
||||||
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
|
.set_usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT)
|
||||||
.set_data(
|
.set_data(
|
||||||
&Self::create_sphere(subdivisions)
|
&sphere
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(v, n)| PositionNormal::new(v, n))
|
.map(|(v, n)| PositionNormal::new(v, n))
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
@ -83,6 +126,7 @@ impl CelestialObject {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
PrimitiveMaterial {
|
PrimitiveMaterial {
|
||||||
|
color: class.color(),
|
||||||
emissive_factor: [0.65, 0.65, 0.65],
|
emissive_factor: [0.65, 0.65, 0.65],
|
||||||
metallic_factor: 0.5,
|
metallic_factor: 0.5,
|
||||||
roughness_factor: 0.7,
|
roughness_factor: 0.7,
|
||||||
|
@ -92,18 +136,25 @@ impl CelestialObject {
|
||||||
false,
|
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 sphere = IcoSphere::new(subdivisions, |_| ());
|
||||||
|
|
||||||
let points = sphere
|
let points = sphere
|
||||||
.raw_points()
|
.raw_points()
|
||||||
.into_iter()
|
.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>>>();
|
.collect::<Vec<Vector3<f32>>>();
|
||||||
|
|
||||||
|
(
|
||||||
sphere
|
sphere
|
||||||
.get_all_indices()
|
.get_all_indices()
|
||||||
.chunks(3)
|
.chunks(3)
|
||||||
|
@ -120,7 +171,9 @@ impl CelestialObject {
|
||||||
[(p1, n), (p2, n), (p3, n)]
|
[(p1, n), (p2, n), (p3, n)]
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect()
|
.collect(),
|
||||||
|
bounding_box,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,8 +188,18 @@ pub struct CelestialObjectSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CelestialObjectSettings {
|
impl CelestialObjectSettings {
|
||||||
fn model_matrix(&self) -> Matrix4<f32> {
|
const SCALE: f32 = 0.5;
|
||||||
Matrix4::from_translation(self.location) * Matrix4::from_scale(self.radius)
|
|
||||||
|
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(
|
pub fn update(
|
||||||
|
@ -145,6 +208,10 @@ impl CelestialObjectSettings {
|
||||||
draw: &Draw,
|
draw: &Draw,
|
||||||
celestial_object_settings_reference: &CelestialObjectSettings,
|
celestial_object_settings_reference: &CelestialObjectSettings,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
self.last_update = now;
|
||||||
|
|
||||||
|
// TODO: velocity calculation around celestial reference
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +220,7 @@ impl Default for CelestialObjectSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
location: Vector3::zero(),
|
location: Vector3::zero(),
|
||||||
radius: 1.0,
|
radius: 2.0,
|
||||||
density: 1.0,
|
density: 1.0,
|
||||||
velocity: 0.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)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
struct PlayerEntity(Entity);
|
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("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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +297,16 @@ impl Game {
|
||||||
// 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)?;
|
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)?;
|
world.add_entity(example_planet)?;
|
||||||
|
|
||||||
let context = world.resources.get::<Context>();
|
let context = world.resources.get::<Context>();
|
||||||
|
@ -325,4 +353,32 @@ impl Game {
|
||||||
|
|
||||||
view.update_buffer()
|
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