From a39cf62b0bed1c8486fd42988ae8729395b520bb Mon Sep 17 00:00:00 2001
From: zomseffen <steffen@tom.bi>
Date: Mon, 7 Apr 2025 17:10:22 +0200
Subject: [PATCH] adds cone component

---
 shaders/compiled/rt_compute.spv | Bin 25952 -> 33268 bytes
 shaders/rt_compute.comp         |  68 ++++++++++++++++-
 src/scene/generators.rs         |   7 +-
 src/scene/volumetrics/mod.rs    | 128 +++++++++++++++++++++++++++++++-
 4 files changed, 197 insertions(+), 6 deletions(-)

diff --git a/shaders/compiled/rt_compute.spv b/shaders/compiled/rt_compute.spv
index 39f83f37be61949f1a0159340e64cc0a7ecb48bc..c0e451b5c7634959a077e82cc2c88d265d0021e1 100644
GIT binary patch
literal 33268
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
USFh`7et2p!uQjRZo4?onKXdpLw*UYD

delta 4634
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
X#bcVYdQZXCqTAX|)u&c%KfU4qzTebx

diff --git a/shaders/rt_compute.comp b/shaders/rt_compute.comp
index 7ec8245..13f9361 100644
--- a/shaders/rt_compute.comp
+++ b/shaders/rt_compute.comp
@@ -200,6 +200,19 @@ void main() {
             uint component_type = compounds[component_index];
             vec3 component_pos = vec3(uintBitsToFloat(compounds[component_index + 1]), uintBitsToFloat(compounds[component_index + 2]), uintBitsToFloat(compounds[component_index + 3]));
             vec3 component_rot = vec3(uintBitsToFloat(compounds[component_index + 4]), uintBitsToFloat(compounds[component_index + 5]), uintBitsToFloat(compounds[component_index + 6]));
+            mat3 component_rot_mat = mat3(
+                    vec3(1.0, 0.0, 0.0),
+                    vec3(0.0, cos(component_rot.x), sin(component_rot.x)),
+                    vec3(0.0, -sin(component_rot.x), cos(component_rot.x))
+                ) * mat3(
+                    vec3(cos(component_rot.y), 0.0, sin(component_rot.y)),
+                    vec3(0.0, 1.0, 0.0),
+                    vec3(-sin(component_rot.y), 0.0, cos(component_rot.y))
+                ) * mat3(
+                    vec3(cos(component_rot.z), sin(component_rot.z), 0.0),
+                    vec3(-sin(component_rot.z), cos(component_rot.y), 0.0),
+                    vec3(0.0, 0.0, 1.0)
+                );
 
             uvec4 component_color = unpack_color(compounds[component_index + 7]);
 
@@ -214,6 +227,27 @@ void main() {
                     color = vec3(float(component_color.x) / 255.0, float(component_color.y) / 255.0, float(component_color.z) / 255.0);
                     break;
                 }
+                continue;
+            }
+
+            if (component_type == 1) {
+                // handle cone
+                float radius1 = uintBitsToFloat(compounds[component_index + 9]);
+                float radius2 = uintBitsToFloat(compounds[component_index + 10]);
+                vec3 direction = component_rot_mat * vec3(uintBitsToFloat(compounds[component_index + 11]), uintBitsToFloat(compounds[component_index + 12]), uintBitsToFloat(compounds[component_index + 13]));
+
+                vec3 diff = check_pos - component_pos;
+                float factor = dot(direction, diff) / dot(direction, direction);
+                
+                vec3 n = diff - factor * direction;
+                float radius = radius1 * (1.0 - factor) + radius2 * factor;
+
+                render = length(n) <= radius && 0 <= factor && factor <= 1.0;
+                if (render) {
+                    color = vec3(float(component_color.x) / 255.0, float(component_color.y) / 255.0, float(component_color.z) / 255.0);
+                    break;
+                }
+                continue;
             }
 
             
@@ -224,7 +258,19 @@ void main() {
             uint component_type = compounds[component_index];
             vec3 component_pos = vec3(uintBitsToFloat(compounds[component_index + 1]), uintBitsToFloat(compounds[component_index + 2]), uintBitsToFloat(compounds[component_index + 3]));
             vec3 component_rot = vec3(uintBitsToFloat(compounds[component_index + 4]), uintBitsToFloat(compounds[component_index + 5]), uintBitsToFloat(compounds[component_index + 6]));
-
+            mat3 component_rot_mat = mat3(
+                    vec3(1.0, 0.0, 0.0),
+                    vec3(0.0, cos(component_rot.x), sin(component_rot.x)),
+                    vec3(0.0, -sin(component_rot.x), cos(component_rot.x))
+                ) * mat3(
+                    vec3(cos(component_rot.y), 0.0, sin(component_rot.y)),
+                    vec3(0.0, 1.0, 0.0),
+                    vec3(-sin(component_rot.y), 0.0, cos(component_rot.y))
+                ) * mat3(
+                    vec3(cos(component_rot.z), sin(component_rot.z), 0.0),
+                    vec3(-sin(component_rot.z), cos(component_rot.y), 0.0),
+                    vec3(0.0, 0.0, 1.0)
+                );
             uvec4 color = unpack_color(compounds[component_index + 7]);
 
             uint transparent = compounds[component_index + 8];
@@ -237,6 +283,26 @@ void main() {
                 if (!render) {
                     break;
                 }
+                continue;
+            }
+
+            if (component_type == 1) {
+                // handle cone
+                float radius1 = uintBitsToFloat(compounds[component_index + 9]);
+                float radius2 = uintBitsToFloat(compounds[component_index + 10]);
+                vec3 direction = component_rot_mat * vec3(uintBitsToFloat(compounds[component_index + 11]), uintBitsToFloat(compounds[component_index + 12]), uintBitsToFloat(compounds[component_index + 13]));
+
+                vec3 diff = check_pos - component_pos;
+                float factor = dot(direction, diff) / dot(direction, direction);
+                
+                vec3 n = diff - factor * direction;
+                float radius = radius1 * (1.0 - factor) + radius2 * factor;
+
+                render = render && !(length(n) <= radius && 0 <= factor && factor <= 1.0);
+                if (!render) {
+                    break;
+                }
+                continue;
             }
         }
 
diff --git a/src/scene/generators.rs b/src/scene/generators.rs
index 32f107e..3aa7c64 100644
--- a/src/scene/generators.rs
+++ b/src/scene/generators.rs
@@ -4,7 +4,7 @@ use crate::primitives::cube::Cube;
 use crate::primitives::rec_cuboid::Cuboid;
 use crate::primitives::drawable::Drawable;
 use crate::app_data::AppData;
-use super::volumetrics::{ShapeComposition, Sphere};
+use super::volumetrics::{Cone, ShapeComposition, Sphere};
 
 extern crate rand;
 use rand::Rng;
@@ -125,9 +125,8 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi
     scene.volumetrics.push(Rc::new(RefCell::new(comp)));
 
     let mut comp = ShapeComposition::new(64);
-    comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.0, Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
-    comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.5, Vector3 { x: 255, y: 0, z: 0 }, 64, false))));
-    comp.excluded_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 11.5 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 1.5, Vector3 { x: 0, y: 255, z: 0 }, 64, false))));    
+    comp.included_shapes.push(Rc::new(RefCell::new(Cone::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 0.0, 2.5, Vector3 { x: 0.0, y: 10.0, z: 0.0 },Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
+    comp.excluded_shapes.push(Rc::new(RefCell::new(Cone::new(Vector3 { x: 20.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 0.0, 1.5, Vector3 { x: 0.0, y: 10.0, z: 0.0 },Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
     scene.volumetrics.push(Rc::new(RefCell::new(comp)));
 
     Ok((cgmath::point3(5.0, 5.0, 10.0)))
diff --git a/src/scene/volumetrics/mod.rs b/src/scene/volumetrics/mod.rs
index e28dbf9..7fbdf0b 100644
--- a/src/scene/volumetrics/mod.rs
+++ b/src/scene/volumetrics/mod.rs
@@ -1,7 +1,7 @@
 use crate::app_data::AppData;
 
 use super::{memorizable::Memorizable, Scene, memorizable::CompoundMemorizable};
-use cgmath::Vector3;
+use cgmath::{InnerSpace, Vector3};
 use winit::dpi::Size;
 
 use std::cell::RefCell;
@@ -22,6 +22,7 @@ pub trait Volumetrics: Memorizable {
 
 enum ShapeTypes {
     SPHERE,
+    CONE,
 }
 
 
@@ -221,6 +222,131 @@ impl Volumetrics for Sphere {
         self.transparent
     }
     
+    fn set_transparency(&mut self, transparent: bool) {
+        self.transparent = transparent;
+    }
+}
+
+
+#[derive(Clone, Debug, PartialEq)]
+pub struct Cone {
+    pos: Vector3<f32>,
+    rot: Vector3<f32>,
+    color: Vector3<u8>, // color, either as pure color or texture modifier
+    transparent: bool,
+    radius1: f32,
+    radius2: f32,
+    direction: Vector3<f32>,
+    roughness: u8,
+    memory_start: usize,
+    dirty: bool
+}
+
+impl Cone {
+    pub fn new(
+        pos: Vector3<f32>,
+        rot: Vector3<f32>, 
+        radius1: f32,
+        radius2: f32,
+        direction: Vector3<f32>,
+        color: Vector3<u8>,
+        roughness: u8,
+        transparent: bool) -> Self {
+        Self { pos: pos, rot: rot, radius1, radius2, color: color, roughness: roughness, memory_start: 0, dirty: true, transparent: transparent, direction }
+    }
+}
+
+impl Memorizable for Cone {
+    fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
+        // type, pos, rot, (color + roughness), transparent, radius1, radius2, direction
+        1 + 3 + 3 + 1 + 1 + 1 + 1 + 3
+    }
+
+    fn get_prev_buffer_mem_size(&self) -> u32 {
+        // constant memory size
+        1 + 3 + 3 + 1 + 1 + 1 + 1 + 3
+    }
+    fn is_dirty(&self) -> bool {
+        self.dirty
+    }
+    fn insert_into_memory(&mut self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
+        v[self.memory_start] = ShapeTypes::CONE as u32;
+        v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
+        v[self.memory_start + 2] = u32::from_ne_bytes(self.pos.y.to_ne_bytes());
+        v[self.memory_start + 3] = u32::from_ne_bytes(self.pos.z.to_ne_bytes());
+
+        v[self.memory_start + 4] = u32::from_ne_bytes(self.rot.x.to_ne_bytes());
+        v[self.memory_start + 5] = u32::from_ne_bytes(self.rot.y.to_ne_bytes());
+        v[self.memory_start + 6] = u32::from_ne_bytes(self.rot.z.to_ne_bytes());
+
+        v[self.memory_start + 7] = u32::from_ne_bytes([self.color.x, self.color.y, self.color.z, self.roughness]);
+
+        v[self.memory_start + 8] = self.transparent as u32;
+
+        v[self.memory_start + 9] = u32::from_ne_bytes(self.radius1.to_ne_bytes());
+        v[self.memory_start + 10] = u32::from_ne_bytes(self.radius2.to_ne_bytes());
+
+        v[self.memory_start + 11] = u32::from_ne_bytes(self.direction.x.to_ne_bytes());
+        v[self.memory_start + 12] = u32::from_ne_bytes(self.direction.y.to_ne_bytes());
+        v[self.memory_start + 13] = u32::from_ne_bytes(self.direction.z.to_ne_bytes());
+
+        v
+    }
+
+    fn get_memory_start(&self) -> usize {
+        self.memory_start
+    }
+    fn set_memory_start(&mut self, memory_start: usize) {
+        self.memory_start = memory_start;
+    }
+}
+
+impl Volumetrics for Cone {
+    fn get_pos(&self) -> Vector3<f32> {
+        self.pos
+    }
+
+    fn set_pos(&mut self, p: Vector3<f32>) {
+        self.pos = p;
+    }
+
+    fn get_rot(&self) -> Vector3<f32> {
+        self.rot
+    }
+
+    fn set_rot(&mut self, p: Vector3<f32>) {
+        self.rot = p;
+    }
+
+    fn get_bbox(&self) -> (Vector3<f32>, Vector3<f32>) {
+        let max_rad = self.radius1.max(self.radius2);
+        let rot = cgmath::Matrix3::from_angle_x(cgmath::Rad(self.rot.x)) * cgmath::Matrix3::from_angle_y(cgmath::Rad(self.rot.y)) * cgmath::Matrix3::from_angle_z(cgmath::Rad(self.rot.z));
+        let dir = rot * self.direction;
+        let vec_one;
+        let vec_two;
+        if dir.x != 0.0 || dir.z != 0.0 {
+            vec_one = dir.cross(Vector3 { x: 0.0, y: 1.0, z: 0.0 }).normalize();
+        } else {
+            vec_one = dir.cross(Vector3 { x: 1.0, y: 0.0, z: 0.0 }).normalize();
+        }
+        vec_two = dir.cross(vec_one).normalize();
+        
+        let pos_1_1 = self.pos + vec_one * max_rad + vec_two * max_rad;
+        let pos_1_2 = self.pos - vec_one * max_rad - vec_two * max_rad;
+
+        let pos_2_1 = self.pos + vec_one * max_rad + vec_two * max_rad + dir;
+        let pos_2_2 = self.pos - vec_one * max_rad - vec_two * max_rad + dir;
+
+        let min = Vector3 {x: pos_1_1.x.min(pos_1_2.x.min(pos_2_1.x.min(pos_2_2.x))), y: pos_1_1.y.min(pos_1_2.y.min(pos_2_1.y.min(pos_2_2.y))), z: pos_1_1.z.min(pos_1_2.z.min(pos_2_1.z.min(pos_2_2.z)))};
+        let max = Vector3 {x: pos_1_1.x.max(pos_1_2.x.max(pos_2_1.x.max(pos_2_2.x))), y: pos_1_1.y.max(pos_1_2.y.max(pos_2_1.y.max(pos_2_2.y))), z: pos_1_1.z.max(pos_1_2.z.max(pos_2_1.z.max(pos_2_2.z)))};
+
+        (min, max)
+    }
+    
+    fn is_transparent(&self) -> bool {
+        self.transparent
+    }
+    
     fn set_transparency(&mut self, transparent: bool) {
         self.transparent = transparent;
     }