tirbofish/dropbear · diff
wip: added a new type to Component and removed old "u_fs_main" for the lighting.
last commit for the night...
Signature present but could not be verified.
Unverified
@@ -23,15 +23,8 @@ pub mod features; pub mod animation; features! { - pub mod build { - const Debug = 0b00000001, - const Release = 0b00000000 - } -} - -features! { - pub mod graphics_features { - const SupportsStorage = 0b00000001 + pub mod feature_list { + const EnablePuffinTracer = 0b00000001 } } @@ -165,12 +158,8 @@ impl State { .flags .contains(wgpu::DownlevelFlags::VERTEX_STORAGE) && device.limits().max_storage_buffers_per_shader_stage > 0; - - if supports_storage_resources { - graphics_features::enable(graphics_features::SupportsStorage); - } - log::debug!("graphics device {} support storage resources", if !supports_storage_resources { "DOES NOT" } else { "DOES" }); + log::debug!("graphics device {} support storage resources", if !supports_storage_resources { "DOES NOT" } else { "does" }); if WGPU_BACKEND.get().is_none() { let info = adapter.get_info(); @@ -960,7 +949,8 @@ impl App { /// Creates a new instance of the application. It only sets the default for the struct + the /// window config. fn new(app_data: AppInfo, future_queue: Option<Arc<FutureQueue>>) -> Self { - if build::is_enabled(build::Debug) { + if feature_list::is_enabled(feature_list::EnablePuffinTracer) { + log::info!("Enabling puffin profiler"); puffin::set_scopes_on(true); if let Err(e) = puffin_http::Server::new("127.0.0.1:8585") { @@ -6,7 +6,7 @@ use crate::{ entity::Transform, model::Model, }; -use glam::{DMat4, DVec3}; +use glam::{DMat4, DQuat, DVec3}; use std::fmt::{Display, Formatter}; use std::sync::Arc; use wgpu::{BindGroup}; @@ -208,6 +208,36 @@ impl LightComponent { } } + pub fn to_transform(&self) -> Transform { + Transform { + position: self.position, + rotation: Self::direction_to_quaternion(self.direction), + scale: DVec3::ONE, + } + } + + /// Converts a direction vector to a quaternion rotation + fn direction_to_quaternion(direction: DVec3) -> DQuat { + if direction.length_squared() < 1e-6 { + return DQuat::IDENTITY; + } + + let forward = DVec3::new(0.0, 0.0, -1.0); + let normalized_direction = direction.normalize(); + + let dot = forward.dot(normalized_direction); + + if dot > 0.9999 { + DQuat::IDENTITY + } else if dot < -0.9999 { + DQuat::from_axis_angle(DVec3::Y, std::f64::consts::PI) + } else { + let axis = forward.cross(normalized_direction).normalize(); + let angle = dot.acos(); + DQuat::from_axis_angle(axis, angle) + } + } + pub fn directional(colour: DVec3, intensity: f32) -> Self { Self::new(colour, LightType::Directional, intensity, None) } @@ -267,16 +297,13 @@ impl Light { pub async fn new( graphics: Arc<SharedGraphicsContext>, light: LightComponent, - transform: Transform, label: Option<&str>, ) -> Self { puffin::profile_function!(); - let forward = DVec3::new(0.0, 0.0, -1.0); - let direction = transform.rotation * forward; let uniform = LightUniform { - position: dvec3_to_uniform_array(transform.position), - direction: dvec3_direction_to_uniform_array(direction, light.outer_cutoff_angle), + position: dvec3_to_uniform_array(light.position), + direction: dvec3_direction_to_uniform_array(light.direction, light.outer_cutoff_angle), colour: dvec3_colour_to_uniform_array( light.colour * light.intensity as f64, light.light_type, @@ -312,7 +339,12 @@ impl Light { label, }); - let instance: InstanceInput = DMat4::from_scale_rotation_translation(transform.scale, transform.rotation, transform.position).into(); + let transform = light.to_transform(); + let instance: InstanceInput = DMat4::from_scale_rotation_translation( + transform.scale, + transform.rotation, + transform.position + ).into(); let mut instance_buffer = ResizableBuffer::new( &graphics.device, @@ -335,14 +367,13 @@ impl Light { } } - pub fn update(&mut self, graphics: &SharedGraphicsContext, light: &mut LightComponent, transform: &Transform) { + pub fn update(&mut self, graphics: &SharedGraphicsContext, light: &LightComponent) { puffin::profile_function!(); - self.uniform.position = dvec3_to_uniform_array(transform.position); - let forward = DVec3::new(0.0, 0.0, -1.0); - let direction = transform.rotation * forward; + self.uniform.position = dvec3_to_uniform_array(light.position); + self.uniform.direction = - dvec3_direction_to_uniform_array(direction, light.outer_cutoff_angle); + dvec3_direction_to_uniform_array(light.direction, light.outer_cutoff_angle); self.uniform.colour = dvec3_colour_to_uniform_array(light.colour * light.intensity as f64, light.light_type); @@ -2,7 +2,7 @@ use std::sync::Arc; use std::mem::size_of; use glam::DMat4; use slank::include_slang; -use wgpu::{BufferAddress, VertexAttribute, VertexFormat}; +use wgpu::{BufferAddress, CompareFunction, DepthBiasState, StencilState, VertexAttribute, VertexFormat}; use crate::buffer::{StorageBuffer, UniformBuffer}; use crate::entity::{EntityTransform, Transform}; use crate::graphics::SharedGraphicsContext; @@ -10,17 +10,14 @@ use crate::lighting::{Light, LightArrayUniform, LightComponent, MAX_LIGHTS}; use crate::model::Vertex; use crate::pipelines::DropbearShaderPipeline; use crate::shader::Shader; +use crate::texture::Texture; pub struct LightCubePipeline { shader: Shader, pipeline_layout: wgpu::PipelineLayout, pipeline: wgpu::RenderPipeline, storage_buffer: Option<StorageBuffer<LightArrayUniform>>, - uniform_buffer: Option<UniformBuffer<LightArrayUniform>>, - /// Bind group, defined in `shaders/shader.wgsl` as @group(2). - /// - /// This can either be a storage buffer or a uniform buffer depending on if the backend - /// supports storage resources. + /// Bind group, defined in `shaders/shader.wgsl` as @group(2) light_bind_group: wgpu::BindGroup, } @@ -69,17 +66,17 @@ impl DropbearShaderPipeline for LightCubePipeline { topology: wgpu::PrimitiveTopology::TriangleList, strip_index_format: None, front_face: wgpu::FrontFace::Cw, - cull_mode: Some(wgpu::Face::Back), + cull_mode: Some(wgpu::Face::Back), polygon_mode: wgpu::PolygonMode::Fill, unclipped_depth: false, conservative: false, }, depth_stencil: Some(wgpu::DepthStencilState { - format: crate::Texture::DEPTH_FORMAT, + format: Texture::DEPTH_FORMAT, depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Greater, - stencil: wgpu::StencilState::default(), - bias: wgpu::DepthBiasState::default(), + depth_compare: CompareFunction::Greater, + stencil: StencilState::default(), + bias: DepthBiasState::default(), }), multisample: wgpu::MultisampleState { count: 1, @@ -91,26 +88,16 @@ impl DropbearShaderPipeline for LightCubePipeline { }); let mut storage_buffer = None; - let mut uniform_buffer = None; - if crate::graphics_features::is_enabled(crate::graphics_features::SupportsStorage) { - storage_buffer = Some(StorageBuffer::new( - &graphics.device, - "light cube pipeline storage buffer", - )); - } else { - uniform_buffer = Some(UniformBuffer::new( - &graphics.device, - "light cube pipeline uniform buffer", - )); - } + storage_buffer = Some(StorageBuffer::new( + &graphics.device, + "light cube pipeline storage buffer", + )); let light_buffer: &wgpu::Buffer = if let Some(buf) = &storage_buffer { buf.buffer() - } else if let Some(buf) = &uniform_buffer { - buf.buffer() } else { - panic!("Either a storage buffer or a uniform buffer should have been created"); + panic!("A storage buffer should have been created"); }; let light_bind_group = graphics.device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -127,7 +114,6 @@ impl DropbearShaderPipeline for LightCubePipeline { pipeline_layout, pipeline, storage_buffer, - uniform_buffer, light_bind_group, } } @@ -151,11 +137,6 @@ impl LightCubePipeline { } pub fn update(&mut self, graphics: Arc<SharedGraphicsContext>, world: &hecs::World) { - debug_assert!( - self.storage_buffer.is_some() ^ self.uniform_buffer.is_some(), - "Expected exactly one of storage_buffer/uniform_buffer to exist" - ); - let mut light_array = LightArrayUniform::default(); let mut light_index: usize = 0; @@ -189,20 +170,16 @@ impl LightCubePipeline { if let Some(buf) = &self.storage_buffer { buf.write(&graphics.queue, &light_array); - } else if let Some(buf) = &self.uniform_buffer { - buf.write(&graphics.queue, &light_array); } else { - panic!("Either a storage buffer or a uniform buffer should have been created"); + panic!("A storage buffer should have been created"); } } pub fn buffer(&self) -> &wgpu::Buffer { if let Some(s) = &self.storage_buffer { s.buffer() - } else if let Some(u) = &self.uniform_buffer { - u.buffer() } else { - panic!("Either a storage buffer or a uniform buffer should have been created"); + panic!("A storage buffer should have been created"); } } } @@ -53,11 +53,7 @@ impl DropbearShaderPipeline for MainRenderPipeline { }, fragment: Some(wgpu::FragmentState { module: &shader.module, - entry_point: if crate::graphics_features::is_enabled(crate::graphics_features::SupportsStorage) { - Some("s_fs_main") - } else { - Some("u_fs_main") - }, + entry_point: Some("s_fs_main"), targets: &[Some(wgpu::ColorTargetState { format: hdr_format, blend: Some(wgpu::BlendState::REPLACE), @@ -12,6 +12,7 @@ impl SerializedComponent for AnimationComponent {} impl Component for AnimationComponent { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -22,15 +23,15 @@ impl Component for AnimationComponent { } } - async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Self::default()) + Ok((Self::default(), )) } - async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, world: &World, entity: Entity, dt: f32, graphics: Arc<SharedGraphicsContext>) { @@ -25,6 +25,7 @@ impl SerializedComponent for SerializableCamera {} impl Component for Camera { type SerializedForm = SerializableCamera; + type RequiredComponentTypes = (Self, CameraComponent); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -35,17 +36,19 @@ impl Component for Camera { } } - async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Camera::predetermined(graphics.clone(), None)) + let comp = CameraComponent::new(); + let cam = Camera::predetermined(graphics.clone(), Some("default camera")); + Ok((cam, comp)) } - async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { + async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { let label = ser.label.clone(); - let builder = CameraBuilder::from(ser); - Ok(Camera::new(graphics.clone(), builder, Some(label.as_str()))) + let builder = CameraBuilder::from(ser.clone()); + Ok((Camera::new(graphics.clone(), builder, Some(label.as_str())), CameraComponent::from(ser))) } fn update_component(&mut self, _world: &World, _entity: Entity, _dt: f32, graphics: Arc<SharedGraphicsContext>) { @@ -62,7 +65,7 @@ impl Component for Camera { fn inspect(&mut self, ui: &mut Ui) { CollapsingHeader::new("Camera3D").show(ui, |ui| { - ui.label("Not implemented yet!"); + ui.label("Not implemented yet!"); }); } } @@ -198,15 +198,20 @@ pub trait Component: Sized { /// ``` type SerializedForm: Serialize + for<'de> Deserialize<'de> + SerializedComponent; + /// Defines all output types for any type of init function or any world query. + /// + /// The default is typically `(Self, )`, however you can even define it as `(Self, Transform, ...)`. + type RequiredComponentTypes: hecs::DynamicBundle; + fn descriptor() -> ComponentDescriptor; /// Creates a new instance of the component for times when there is no existing component to /// initialise from. - async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self>; + async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes>; /// Converts [`Self::SerializedForm`] into a [`Component`] instance that can be added to /// `hecs::EntityBuilder` during scene initialisation. - async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self>; + async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes>; /// Called every frame to update the component's state. fn update_component(&mut self, world: &hecs::World, entity: hecs::Entity, dt: f32, graphics: Arc<SharedGraphicsContext>); @@ -225,6 +230,7 @@ impl SerializedComponent for SerializedMeshRenderer {} // sample for MeshRenderer impl Component for MeshRenderer { type SerializedForm = SerializedMeshRenderer; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -235,14 +241,14 @@ impl Component for MeshRenderer { } } - async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(MeshRenderer::from_handle(Handle::NULL)) + Ok((MeshRenderer::from_handle(Handle::NULL), )) } - async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { + async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { let import_scale = ser.import_scale.unwrap_or(1.0); let handle = match &ser.handle.ref_type { @@ -344,7 +350,7 @@ impl Component for MeshRenderer { } } - Ok(renderer) + Ok((renderer, )) } fn update_component(&mut self, world: &World, entity: Entity, _dt: f32, _graphics: Arc<SharedGraphicsContext>) { @@ -1,5 +1,5 @@ use std::sync::Arc; -use egui::Ui; +use egui::{CollapsingHeader, Ui}; use crate::ptr::WorldPtr; use crate::scripting::jni::utils::{FromJObject, ToJObject}; use crate::scripting::native::DropbearNativeError; @@ -20,6 +20,7 @@ impl SerializedComponent for SerializedLight {} impl Component for Light { type SerializedForm = SerializedLight; + type RequiredComponentTypes = (Self, LightComponent); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -30,35 +31,36 @@ impl Component for Light { } } - async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Light::new(graphics.clone(), LightComponent::default(), Transform::default(), None).await) + let comp = LightComponent::default(); + let light = Light::new(graphics.clone(), comp.clone(), None).await; + Ok((light, comp)) } - async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { + async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { let light = Light::new( graphics.clone(), - ser.light_component, - ser.transform, + ser.light_component.clone(), Some(ser.label.as_str()) ).await; - Ok(light) + Ok((light, ser.light_component)) } fn update_component(&mut self, world: &World, entity: Entity, _dt: f32, graphics: Arc<SharedGraphicsContext>) { - if let Ok((light, comp, trans)) = world.query_one::<(&mut Light, &mut LightComponent, &mut Transform)>(entity).get() { - light.update(&graphics, comp, trans); + if let Ok((light, comp)) = world.query_one::<(&mut Light, &mut LightComponent)>(entity).get() { + light.update(&graphics, comp); } } fn save(&self, world: &World, entity: Entity) -> Box<dyn SerializedComponent> { - if let Ok((_, comp, transform)) = world.query_one::<(&Light, &LightComponent, &Transform)>(entity).get() { + if let Ok((_, comp)) = world.query_one::<(&Light, &LightComponent)>(entity).get() { Box::new(SerializedLight { label: self.label.clone(), - transform: *transform, + transform: comp.to_transform(), light_component: comp.clone(), enabled: comp.enabled, entity_id: Some(entity), @@ -69,7 +71,9 @@ impl Component for Light { } fn inspect(&mut self, ui: &mut Ui) { - todo!() + CollapsingHeader::new("Light").default_open(true).show(ui, |ui| { + ui.label("Not implemented yet"); + }); } } @@ -61,6 +61,7 @@ impl SerializedComponent for ColliderGroup {} impl Component for ColliderGroup { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -71,15 +72,15 @@ impl Component for ColliderGroup { } } - async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Self::new()) + Ok((Self::new(), )) } - async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, _world: &World, _entity: Entity, _dt: f32, _graphics: Arc<SharedGraphicsContext>) {} @@ -39,6 +39,7 @@ impl SerializedComponent for KCC {} impl Component for KCC { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -49,15 +50,15 @@ impl Component for KCC { } } - async fn first_time(graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(_: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Self::default()) + Ok((Self::default(), )) } - async fn init(ser: Self::SerializedForm, graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, _: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, _world: &World, _entity: Entity, _dt: f32, _graphics: Arc<SharedGraphicsContext>) {} @@ -191,6 +191,7 @@ impl SerializedComponent for RigidBody {} impl Component for RigidBody { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -201,15 +202,15 @@ impl Component for RigidBody { } } - async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Self::default()) + Ok((Self::default(), )) } - async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, _world: &World, _entity: Entity, _dt: f32, _graphics: Arc<SharedGraphicsContext>) {} @@ -26,6 +26,7 @@ impl SerializedComponent for CustomProperties {} impl Component for CustomProperties { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -36,15 +37,15 @@ impl Component for CustomProperties { } } - async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Self::new()) + Ok((Self::new(), )) } - async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, _world: &World, _entity: Entity, _dt: f32, _graphics: Arc<SharedGraphicsContext>) {} @@ -163,6 +163,7 @@ impl SerializedComponent for Script {} impl Component for Script { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -173,15 +174,15 @@ impl Component for Script { } } - async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> + async fn first_time(_graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> where Self: Sized { - Ok(Self::default()) + Ok((Self::default(), )) } - async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, _graphics: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, _world: &World, _entity: Entity, _dt: f32, _graphics: Arc<SharedGraphicsContext>) {} @@ -19,6 +19,7 @@ impl SerializedComponent for EntityTransform {} impl Component for EntityTransform { type SerializedForm = Self; + type RequiredComponentTypes = (Self, ); fn descriptor() -> ComponentDescriptor { ComponentDescriptor { @@ -29,12 +30,12 @@ impl Component for EntityTransform { } } - async fn first_time(_: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(Self::default()) + async fn first_time(_: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((Self::default(), )) } - async fn init(ser: Self::SerializedForm, _: Arc<SharedGraphicsContext>) -> anyhow::Result<Self> { - Ok(ser) + async fn init(ser: Self::SerializedForm, _: Arc<SharedGraphicsContext>) -> anyhow::Result<Self::RequiredComponentTypes> { + Ok((ser, )) } fn update_component(&mut self, _: &World, _: Entity, _: f32, _: Arc<SharedGraphicsContext>) {} @@ -128,6 +128,14 @@ async fn main() -> anyhow::Result<()> { .global(true) .required(false) ) + .arg( + Arg::new("tracing") + .long("tracing") + .help("Enabled the puffin tracer. Makes the editor slower, but better debugging") + .action(clap::ArgAction::SetTrue) + .global(true) + .required(false) + ) .subcommand( Command::new("build") .about("Build a eucalyptus project, but only the .eupak file and its resources") @@ -182,6 +190,7 @@ async fn main() -> anyhow::Result<()> { let jvm_args = matches.get_one::<String>("jvm-args"); let await_jdb = matches.get_flag("await-jdb"); + let tracing = matches.get_flag("tracing"); if let Some(args) = jvm_args { let _ = JVM_ARGS.set(args.clone()); @@ -191,6 +200,10 @@ async fn main() -> anyhow::Result<()> { let _ = AWAIT_JDB.set(true); } + if tracing { + dropbear_engine::feature_list::enable(dropbear_engine::feature_list::EnablePuffinTracer) + } + EditorSettings::read()?; match matches.subcommand() { @@ -184,38 +184,28 @@ typedef struct IndexNative { uint32_t generation; } IndexNative; -typedef struct NCollider { - IndexNative index; - uint64_t entity_id; - uint32_t id; -} NCollider; - -typedef struct NShapeCastHit { - NCollider collider; - double distance; - NVector3 witness1; - NVector3 witness2; - NVector3 normal1; - NVector3 normal2; - NShapeCastStatus status; -} NShapeCastHit; +typedef struct IndexNativeArray { + IndexNative* values; + size_t length; + size_t capacity; +} IndexNativeArray; -typedef struct RigidBodyContext { - IndexNative index; +typedef struct CharacterCollisionArray { uint64_t entity_id; -} RigidBodyContext; + IndexNativeArray collisions; +} CharacterCollisionArray; -typedef struct AxisLock { - bool x; - bool y; - bool z; -} AxisLock; +typedef struct NAttenuation { + float constant; + float linear; + float quadratic; +} NAttenuation; -typedef struct Progress { - size_t current; - size_t total; - const char* message; -} Progress; +typedef struct NTransform { + NVector3 position; + NQuaternion rotation; + NVector3 scale; +} NTransform; typedef struct NColour { uint8_t r; @@ -229,57 +219,82 @@ typedef struct NRange { float end; } NRange; +typedef struct NVector4 { + double x; + double y; + double z; + double w; +} NVector4; + +typedef struct NVector2 { + double x; + double y; +} NVector2; + typedef struct i32Array { int32_t* values; size_t length; size_t capacity; } i32Array; -typedef struct NNodeTransform { - NVector3 translation; - NQuaternion rotation; - NVector3 scale; -} NNodeTransform; +typedef struct NModelVertex { + NVector3 position; + NVector3 normal; + NVector4 tangent; + NVector2 tex_coords0; + NVector2 tex_coords1; + NVector4 colour0; + i32Array joints0; + NVector4 weights0; +} NModelVertex; -typedef struct NNode { +typedef struct NModelVertexArray { + NModelVertex* values; + size_t length; + size_t capacity; +} NModelVertexArray; + +typedef struct NMesh { const char* name; - const int32_t* parent; - i32Array children; - NNodeTransform transform; -} NNode; + int32_t num_elements; + int32_t material_index; + NModelVertexArray vertices; +} NMesh; -typedef struct NNodeArray { - NNode* values; +typedef struct NMeshArray { + NMesh* values; size_t length; size_t capacity; -} NNodeArray; +} NMeshArray; -typedef void* WorldPtr; +typedef struct NCollider { + IndexNative index; + uint64_t entity_id; + uint32_t id; +} NCollider; -typedef struct NTransform { - NVector3 position; - NQuaternion rotation; - NVector3 scale; -} NTransform; +typedef struct RayHit { + NCollider collider; + double distance; +} RayHit; -typedef struct f64ArrayArray { - double* values; +typedef struct u64Array { + uint64_t* values; size_t length; size_t capacity; -} f64ArrayArray; +} u64Array; -typedef struct NSkin { - const char* name; - i32Array joints; - f64ArrayArray inverse_bind_matrices; - const int32_t* skeleton_root; -} NSkin; +typedef struct ConnectedGamepadIds { + u64Array ids; +} ConnectedGamepadIds; -typedef struct NSkinArray { - NSkin* values; - size_t length; - size_t capacity; -} NSkinArray; +typedef struct AxisLock { + bool x; + bool y; + bool z; +} AxisLock; + +typedef void* WorldPtr; typedef struct NColliderArray { NCollider* values; @@ -287,6 +302,41 @@ typedef struct NColliderArray { size_t capacity; } NColliderArray; +typedef void* InputStatePtr; + +typedef struct NShapeCastHit { + NCollider collider; + double distance; + NVector3 witness1; + NVector3 witness2; + NVector3 normal1; + NVector3 normal2; + NShapeCastStatus status; +} NShapeCastHit; + +typedef void* PhysicsStatePtr; + +typedef void* AssetRegistryPtr; + +typedef struct NNodeTransform { + NVector3 translation; + NQuaternion rotation; + NVector3 scale; +} NNodeTransform; + +typedef struct NNode { + const char* name; + const int32_t* parent; + i32Array children; + NNodeTransform transform; +} NNode; + +typedef struct NNodeArray { + NNode* values; + size_t length; + size_t capacity; +} NNodeArray; + typedef struct f64Array { double* values; size_t length; @@ -318,86 +368,14 @@ typedef struct NAnimationArray { size_t capacity; } NAnimationArray; -typedef void* AssetRegistryPtr; - -typedef void* InputStatePtr; - -typedef struct IndexNativeArray { - IndexNative* values; - size_t length; - size_t capacity; -} IndexNativeArray; - -typedef struct CharacterCollisionArray { - uint64_t entity_id; - IndexNativeArray collisions; -} CharacterCollisionArray; - -typedef struct NVector2 { - double x; - double y; -} NVector2; - -typedef void* GraphicsContextPtr; - -typedef struct NAttenuation { - float constant; - float linear; - float quadratic; -} NAttenuation; - -typedef struct u64Array { - uint64_t* values; - size_t length; - size_t capacity; -} u64Array; - -typedef void* SceneLoaderPtr; +typedef struct Progress { + size_t current; + size_t total; + const char* message; +} Progress; typedef void* CommandBufferPtr; -typedef struct NVector4 { - double x; - double y; - double z; - double w; -} NVector4; - -typedef struct NModelVertex { - NVector3 position; - NVector3 normal; - NVector4 tangent; - NVector2 tex_coords0; - NVector2 tex_coords1; - NVector4 colour0; - i32Array joints0; - NVector4 weights0; -} NModelVertex; - -typedef struct NModelVertexArray { - NModelVertex* values; - size_t length; - size_t capacity; -} NModelVertexArray; - -typedef struct NMesh { - const char* name; - int32_t num_elements; - int32_t material_index; - NModelVertexArray vertices; -} NMesh; - -typedef struct NMeshArray { - NMesh* values; - size_t length; - size_t capacity; -} NMeshArray; - -typedef struct RayHit { - NCollider collider; - double distance; -} RayHit; - typedef struct NMaterial { const char* name; uint64_t diffuse_texture; @@ -422,11 +400,33 @@ typedef struct NMaterialArray { size_t capacity; } NMaterialArray; -typedef void* PhysicsStatePtr; +typedef void* SceneLoaderPtr; -typedef struct ConnectedGamepadIds { - u64Array ids; -} ConnectedGamepadIds; +typedef struct RigidBodyContext { + IndexNative index; + uint64_t entity_id; +} RigidBodyContext; + +typedef struct f64ArrayArray { + double* values; + size_t length; + size_t capacity; +} f64ArrayArray; + +typedef struct NSkin { + const char* name; + i32Array joints; + f64ArrayArray inverse_bind_matrices; + const int32_t* skeleton_root; +} NSkin; + +typedef struct NSkinArray { + NSkin* values; + size_t length; + size_t capacity; +} NSkinArray; + +typedef void* GraphicsContextPtr; int32_t dropbear_gamepad_is_button_pressed(InputStatePtr input, uint64_t gamepad_id, int32_t button_ordinal, bool* out0); int32_t dropbear_gamepad_get_left_stick_position(InputStatePtr input, uint64_t gamepad_id, NVector2* out0);