mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'synis/primitives' into 'master'
Primitives See merge request veloren/veloren!1937
This commit is contained in:
commit
5abdd0be8d
@ -6,17 +6,26 @@ use common::{
|
|||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub enum Primitive {
|
pub enum Primitive {
|
||||||
Empty, // Placeholder
|
Empty, // Placeholder
|
||||||
|
|
||||||
// Shapes
|
// Shapes
|
||||||
Aabb(Aabb<i32>),
|
Aabb(Aabb<i32>),
|
||||||
Pyramid { aabb: Aabb<i32>, inset: i32 },
|
Pyramid { aabb: Aabb<i32>, inset: i32 },
|
||||||
|
Cylinder(Aabb<i32>),
|
||||||
|
Cone(Aabb<i32>),
|
||||||
|
Sphere(Aabb<i32>),
|
||||||
|
Plane(Aabr<i32>, Vec3<i32>, Vec2<f32>),
|
||||||
|
|
||||||
// Combinators
|
// Combinators
|
||||||
And(Id<Primitive>, Id<Primitive>),
|
And(Id<Primitive>, Id<Primitive>),
|
||||||
Or(Id<Primitive>, Id<Primitive>),
|
Or(Id<Primitive>, Id<Primitive>),
|
||||||
Xor(Id<Primitive>, Id<Primitive>),
|
Xor(Id<Primitive>, Id<Primitive>),
|
||||||
|
// Not commutative
|
||||||
|
Diff(Id<Primitive>, Id<Primitive>),
|
||||||
|
// Operators
|
||||||
|
Rotate(Id<Primitive>, Mat3<i32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Fill {
|
pub enum Fill {
|
||||||
@ -51,7 +60,41 @@ impl Fill {
|
|||||||
< 1.0
|
< 1.0
|
||||||
- ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32
|
- ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32
|
||||||
},
|
},
|
||||||
|
Primitive::Cylinder(aabb) => {
|
||||||
|
(aabb.min.z..aabb.max.z).contains(&pos.z)
|
||||||
|
&& (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.min.z..aabb.max.z).contains(&pos.z)
|
||||||
|
&& 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 ==
|
||||||
|
(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) => {
|
Primitive::And(a, b) => {
|
||||||
self.contains_at(tree, *a, pos) && self.contains_at(tree, *b, pos)
|
self.contains_at(tree, *a, pos) && self.contains_at(tree, *b, pos)
|
||||||
},
|
},
|
||||||
@ -61,6 +104,14 @@ impl Fill {
|
|||||||
Primitive::Xor(a, b) => {
|
Primitive::Xor(a, b) => {
|
||||||
self.contains_at(tree, *a, pos) ^ self.contains_at(tree, *b, pos)
|
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)
|
||||||
|
},
|
||||||
|
Primitive::Rotate(prim, mat) => {
|
||||||
|
let aabb = self.get_bounds(tree, *prim);
|
||||||
|
let diff = pos - (aabb.min + mat.cols.map(|x| x.reduce_min()));
|
||||||
|
self.contains_at(tree, *prim, aabb.min + mat.transposed() * diff)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +149,26 @@ impl Fill {
|
|||||||
Primitive::Empty => return None,
|
Primitive::Empty => return None,
|
||||||
Primitive::Aabb(aabb) => *aabb,
|
Primitive::Aabb(aabb) => *aabb,
|
||||||
Primitive::Pyramid { 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_()
|
||||||
|
};
|
||||||
|
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(
|
Primitive::And(a, b) => or_zip_with(
|
||||||
self.get_bounds_inner(tree, *a),
|
self.get_bounds_inner(tree, *a),
|
||||||
self.get_bounds_inner(tree, *b),
|
self.get_bounds_inner(tree, *b),
|
||||||
@ -108,6 +179,16 @@ impl Fill {
|
|||||||
self.get_bounds_inner(tree, *b),
|
self.get_bounds_inner(tree, *b),
|
||||||
|a, b| a.union(b),
|
|a, b| a.union(b),
|
||||||
)?,
|
)?,
|
||||||
|
Primitive::Diff(a, _) => self.get_bounds_inner(tree, *a)?,
|
||||||
|
Primitive::Rotate(prim, mat) => {
|
||||||
|
let aabb = self.get_bounds_inner(tree, *prim)?;
|
||||||
|
let extent = *mat * Vec3::from(aabb.size());
|
||||||
|
let new_aabb: Aabb<i32> = Aabb {
|
||||||
|
min: aabb.min,
|
||||||
|
max: aabb.min + extent,
|
||||||
|
};
|
||||||
|
new_aabb.made_valid()
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user