From e3d956adfb935357114bb83d9af7a41b1f969536 Mon Sep 17 00:00:00 2001 From: Synis Date: Wed, 17 Mar 2021 23:31:07 +0100 Subject: [PATCH 1/3] Added a bunch of primitives --- world/src/site2/gen.rs | 64 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/world/src/site2/gen.rs b/world/src/site2/gen.rs index af81fbec7a..f59ba970fe 100644 --- a/world/src/site2/gen.rs +++ b/world/src/site2/gen.rs @@ -12,11 +12,18 @@ pub enum Primitive { // Shapes Aabb(Aabb), Pyramid { aabb: Aabb, inset: i32 }, + Cylinder(Aabb), + Cone(Aabb), + Sphere(Aabb), + Plane(Aabr, Vec3, Vec2), // Combinators And(Id, Id), Or(Id, Id), Xor(Id, Id), + // Not commutative + Diff(Id, Id), + // Operators } pub enum Fill { @@ -51,7 +58,39 @@ impl Fill { < 1.0 - ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32 }, - + Primitive::Cylinder(aabb) => { + aabb_contains(*aabb, pos) + && (pos + .xy() + .as_() + .distance_squared(aabb.as_().center().xy() - 0.5) + as f32) + < (aabb.size().w.min(aabb.size().h) as f32 / 2.0).powi(2) + }, + Primitive::Cone(aabb) => { + aabb_contains(*aabb, pos) + && pos + .xy() + .as_() + .distance_squared(aabb.as_().center().xy() - 0.5) + < (((aabb.max.z - pos.z) as f32 / aabb.size().d as f32) + * (aabb.size().w.min(aabb.size().h) as f32 / 2.0)) + .powi(2) + }, + Primitive::Sphere(aabb) => { + aabb_contains(*aabb, pos) + && pos.as_().distance_squared(aabb.as_().center() - 0.5) + < (aabb.size().w.min(aabb.size().h) as f32 / 2.0).powi(2) + }, + Primitive::Plane(aabr, origin, gradient) => { + // Maybe <= instead of == + pos.z + == origin.z + + ((pos.xy() - origin.xy()) + .map(|x| x.abs()) + .as_() + .dot(*gradient) as i32) + }, Primitive::And(a, b) => { self.contains_at(tree, *a, pos) && self.contains_at(tree, *b, pos) }, @@ -61,6 +100,9 @@ impl Fill { Primitive::Xor(a, b) => { self.contains_at(tree, *a, pos) ^ self.contains_at(tree, *b, pos) }, + Primitive::Diff(a, b) => { + self.contains_at(tree, *a, pos) && !self.contains_at(tree, *b, pos) + }, } } @@ -98,6 +140,25 @@ impl Fill { Primitive::Empty => return None, Primitive::Aabb(aabb) => *aabb, Primitive::Pyramid { aabb, .. } => *aabb, + Primitive::Cylinder(aabb) => *aabb, + Primitive::Cone(aabb) => *aabb, + Primitive::Sphere(aabb) => *aabb, + Primitive::Plane(aabr, origin, gradient) => { + let half_size = aabr.half_size().reduce_max(); + let longest_dist = ((aabr.center() - origin.xy()).map(|x| x.abs()) + + half_size + + aabr.size().reduce_max() % 2) + .map(|x| x as f32); + let z = if gradient.x.signum() == gradient.y.signum() { + Vec2::new(0, longest_dist.dot(*gradient) as i32) + } else { + (longest_dist * gradient).as_() + }; + Aabb { + min: aabr.min.with_z(origin.z + z.reduce_min().min(0)), + max: aabr.max.with_z(origin.z + z.reduce_max().max(0)), + } + }, Primitive::And(a, b) => or_zip_with( self.get_bounds_inner(tree, *a), self.get_bounds_inner(tree, *b), @@ -108,6 +169,7 @@ impl Fill { self.get_bounds_inner(tree, *b), |a, b| a.union(b), )?, + Primitive::Diff(a, _) => self.get_bounds_inner(tree, *a)?, }) } From b91ee0476d694ae2ea26eb2d118b4b630afa7c00 Mon Sep 17 00:00:00 2001 From: Synis Date: Tue, 23 Mar 2021 18:47:31 +0100 Subject: [PATCH 2/3] Rotation primitive and some minor fixes --- world/src/site2/gen.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/world/src/site2/gen.rs b/world/src/site2/gen.rs index f59ba970fe..5b18172ea7 100644 --- a/world/src/site2/gen.rs +++ b/world/src/site2/gen.rs @@ -24,6 +24,7 @@ pub enum Primitive { // Not commutative Diff(Id, Id), // Operators + Rotate(Id, [Vec3; 3]), } pub enum Fill { @@ -59,7 +60,7 @@ impl Fill { - ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32 }, Primitive::Cylinder(aabb) => { - aabb_contains(*aabb, pos) + (aabb.min.z..aabb.max.z).contains(&pos.z) && (pos .xy() .as_() @@ -68,7 +69,7 @@ impl Fill { < (aabb.size().w.min(aabb.size().h) as f32 / 2.0).powi(2) }, Primitive::Cone(aabb) => { - aabb_contains(*aabb, pos) + (aabb.min.z..aabb.max.z).contains(&pos.z) && pos .xy() .as_() @@ -103,6 +104,14 @@ impl Fill { Primitive::Diff(a, b) => { self.contains_at(tree, *a, pos) && !self.contains_at(tree, *b, pos) }, + Primitive::Rotate(prim, [x, y, z]) => { + let aabb = self.get_bounds(tree, *prim); + let diff = pos - (aabb.min + (x+y+z).map(|x| x.min(0))); + let new_x = Vec3::new(x.x, y.x, z.x); + let new_y = Vec3::new(x.y, y.y, z.y); + let new_z = Vec3::new(x.z, y.z, z.z); + self.contains_at(tree, *prim, aabb.min + (new_x * diff.x) + (new_y * diff.y) + (new_z * diff.z)) + }, } } @@ -170,6 +179,16 @@ impl Fill { |a, b| a.union(b), )?, Primitive::Diff(a, _) => self.get_bounds_inner(tree, *a)?, + Primitive::Rotate(prim, [x, y, z]) => { + let aabb = self.get_bounds_inner(tree, *prim)?; + let extent = (*x * aabb.size().w) + (*y * aabb.size().h) + (*z * aabb.size().d); + let new_min = aabb.min + extent.map(|x| x.min(0)); + let new_aabb: Aabb = Aabb { + min: new_min, + max: new_min + extent.map(|x| x.abs()), + }; + new_aabb + }, }) } From 5b9b5c510195cff67a9ea3d06cc1d971e5e32ef9 Mon Sep 17 00:00:00 2001 From: Synis Date: Tue, 23 Mar 2021 23:28:09 +0100 Subject: [PATCH 3/3] Rotation uses matrix and some fixes for plane primitive --- world/src/site2/gen.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/world/src/site2/gen.rs b/world/src/site2/gen.rs index 5b18172ea7..f958b8732a 100644 --- a/world/src/site2/gen.rs +++ b/world/src/site2/gen.rs @@ -6,6 +6,7 @@ use common::{ }; use vek::*; +#[allow(dead_code)] pub enum Primitive { Empty, // Placeholder @@ -24,7 +25,7 @@ pub enum Primitive { // Not commutative Diff(Id, Id), // Operators - Rotate(Id, [Vec3; 3]), + Rotate(Id, Mat3), } pub enum Fill { @@ -85,12 +86,14 @@ impl Fill { }, Primitive::Plane(aabr, origin, gradient) => { // Maybe <= instead of == - pos.z - == origin.z - + ((pos.xy() - origin.xy()) - .map(|x| x.abs()) - .as_() - .dot(*gradient) as i32) + (aabr.min.x..aabr.max.x).contains(&pos.x) + && (aabr.min.y..aabr.max.y).contains(&pos.y) + && pos.z + == origin.z + + ((pos.xy() - origin.xy()) + .map(|x| x.abs()) + .as_() + .dot(*gradient) as i32) }, Primitive::And(a, b) => { self.contains_at(tree, *a, pos) && self.contains_at(tree, *b, pos) @@ -104,13 +107,10 @@ impl Fill { Primitive::Diff(a, b) => { self.contains_at(tree, *a, pos) && !self.contains_at(tree, *b, pos) }, - Primitive::Rotate(prim, [x, y, z]) => { + Primitive::Rotate(prim, mat) => { let aabb = self.get_bounds(tree, *prim); - let diff = pos - (aabb.min + (x+y+z).map(|x| x.min(0))); - let new_x = Vec3::new(x.x, y.x, z.x); - let new_y = Vec3::new(x.y, y.y, z.y); - let new_z = Vec3::new(x.z, y.z, z.z); - self.contains_at(tree, *prim, aabb.min + (new_x * diff.x) + (new_y * diff.y) + (new_z * diff.z)) + let diff = pos - (aabb.min + mat.cols.map(|x| x.reduce_min())); + self.contains_at(tree, *prim, aabb.min + mat.transposed() * diff) }, } } @@ -163,10 +163,11 @@ impl Fill { } else { (longest_dist * gradient).as_() }; - Aabb { + let aabb = Aabb { min: aabr.min.with_z(origin.z + z.reduce_min().min(0)), max: aabr.max.with_z(origin.z + z.reduce_max().max(0)), - } + }; + aabb.made_valid() }, Primitive::And(a, b) => or_zip_with( self.get_bounds_inner(tree, *a), @@ -179,15 +180,14 @@ impl Fill { |a, b| a.union(b), )?, Primitive::Diff(a, _) => self.get_bounds_inner(tree, *a)?, - Primitive::Rotate(prim, [x, y, z]) => { + Primitive::Rotate(prim, mat) => { let aabb = self.get_bounds_inner(tree, *prim)?; - let extent = (*x * aabb.size().w) + (*y * aabb.size().h) + (*z * aabb.size().d); - let new_min = aabb.min + extent.map(|x| x.min(0)); + let extent = *mat * Vec3::from(aabb.size()); let new_aabb: Aabb = Aabb { - min: new_min, - max: new_min + extent.map(|x| x.abs()), + min: aabb.min, + max: aabb.min + extent, }; - new_aabb + new_aabb.made_valid() }, }) }