Implement AABB::CornerPoint/ExtremePoint/PointOnEdge/FaceCenterPoint/FacePoint
This commit is contained in:
@@ -44,71 +44,32 @@ namespace J3ML::Geometry
|
|||||||
static int NumFaces() { return 6; }
|
static int NumFaces() { return 6; }
|
||||||
static int NumEdges() { return 12;}
|
static int NumEdges() { return 12;}
|
||||||
static int NumVertices() { return 8;}
|
static int NumVertices() { return 8;}
|
||||||
|
static AABB FromCenterAndSize(const Vector3& center, const Vector3& size);
|
||||||
static AABB FromCenterAndSize(const Vector3& center, const Vector3& size)
|
float MinX() const;
|
||||||
{
|
float MinY() const;
|
||||||
Vector3 halfSize = size * 0.5f;
|
float MinZ() const;
|
||||||
return {center - halfSize, center + halfSize};
|
float MaxX() const;
|
||||||
}
|
float MaxY() const;
|
||||||
float MinX() const { return minPoint.x; }
|
float MaxZ() const;
|
||||||
float MinY() const { return minPoint.y; }
|
|
||||||
float MinZ() const { return minPoint.z; }
|
|
||||||
|
|
||||||
float MaxX() const { return maxPoint.x; }
|
|
||||||
float MaxY() const { return maxPoint.y; }
|
|
||||||
float MaxZ() const { return maxPoint.z; }
|
|
||||||
|
|
||||||
|
|
||||||
/// Returns the smallest sphere that contains this AABB.
|
/// Returns the smallest sphere that contains this AABB.
|
||||||
/// This function computes the minimal volume sphere that contains all the points inside this AABB
|
/// This function computes the minimal volume sphere that contains all the points inside this AABB
|
||||||
Sphere MinimalEnclosingSphere() const
|
Sphere MinimalEnclosingSphere() const;
|
||||||
{
|
Vector3 HalfSize() const;
|
||||||
return Sphere(Centroid(), Size().Length()*0.5f);
|
/// Returns the largest sphere that can fit inside this AABB
|
||||||
}
|
/// This function computes the largest sphere that can fit inside this AABB.
|
||||||
|
Sphere MaximalContainedSphere() const;
|
||||||
Vector3 HalfSize() const {
|
bool IsFinite() const;
|
||||||
return this->Size()/2.f;
|
Vector3 Centroid() const;
|
||||||
}
|
Vector3 Size() const;
|
||||||
|
|
||||||
// Returns the largest sphere that can fit inside this AABB
|
|
||||||
// This function computes the largest sphere that can fit inside this AABB.
|
|
||||||
Sphere MaximalContainedSphere() const
|
|
||||||
{
|
|
||||||
Vector3 halfSize = HalfSize();
|
|
||||||
return Sphere(Centroid(), std::min(halfSize.x, std::min(halfSize.y, halfSize.z)));
|
|
||||||
}
|
|
||||||
bool IsFinite() const
|
|
||||||
{
|
|
||||||
return minPoint.IsFinite() && maxPoint.IsFinite();
|
|
||||||
}
|
|
||||||
Vector3 Centroid() const
|
|
||||||
{
|
|
||||||
return (minPoint+maxPoint) * 0.5f;
|
|
||||||
}
|
|
||||||
Vector3 Size() const
|
|
||||||
{
|
|
||||||
return this->maxPoint - this->minPoint;
|
|
||||||
}
|
|
||||||
// Quickly returns an arbitrary point inside this AABB
|
// Quickly returns an arbitrary point inside this AABB
|
||||||
Vector3 AnyPointFast() const;
|
Vector3 AnyPointFast() const;
|
||||||
|
|
||||||
Vector3 PointInside(float x, float y, float z) const
|
Vector3 PointInside(float x, float y, float z) const;
|
||||||
{
|
|
||||||
Vector3 d = maxPoint - minPoint;
|
|
||||||
return minPoint + d.Mul({x, y, z});
|
|
||||||
}
|
|
||||||
// Returns an edge of this AABB
|
// Returns an edge of this AABB
|
||||||
LineSegment Edge(int edgeIndex) const
|
LineSegment Edge(int edgeIndex) const;
|
||||||
{
|
Vector3 CornerPoint(int cornerIndex) const;
|
||||||
switch(edgeIndex)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
case 0: return LineSegment(minPoint, {minPoint.x, minPoint.y, maxPoint.z});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vector3 CornerPoint(int cornerIndex);
|
|
||||||
Vector3 ExtremePoint(const Vector3& direction) const;
|
Vector3 ExtremePoint(const Vector3& direction) const;
|
||||||
Vector3 ExtremePoint(const Vector3& direction, float projectionDistance);
|
Vector3 ExtremePoint(const Vector3& direction, float &projectionDistance);
|
||||||
Vector3 PointOnEdge(int edgeIndex, float u) const;
|
Vector3 PointOnEdge(int edgeIndex, float u) const;
|
||||||
Vector3 FaceCenterPoint(int faceIndex) const;
|
Vector3 FaceCenterPoint(int faceIndex) const;
|
||||||
Vector3 FacePoint(int faceIndex, float u, float v) const;
|
Vector3 FacePoint(int faceIndex, float u, float v) const;
|
||||||
|
@@ -1,5 +1,143 @@
|
|||||||
#include <J3ML/Geometry/AABB.h>
|
#include <J3ML/Geometry/AABB.h>
|
||||||
|
|
||||||
namespace Geometry {
|
namespace J3ML::Geometry {
|
||||||
|
|
||||||
}
|
AABB AABB::FromCenterAndSize(const J3ML::Geometry::Vector3 ¢er, const J3ML::Geometry::Vector3 &size) {
|
||||||
|
Vector3 halfSize = size * 0.5f;
|
||||||
|
return {center - halfSize, center + halfSize};
|
||||||
|
}
|
||||||
|
|
||||||
|
float AABB::MinX() const { return minPoint.x; }
|
||||||
|
|
||||||
|
float AABB::MinY() const { return minPoint.y; }
|
||||||
|
|
||||||
|
float AABB::MinZ() const { return minPoint.z; }
|
||||||
|
|
||||||
|
float AABB::MaxX() const { return maxPoint.x; }
|
||||||
|
|
||||||
|
float AABB::MaxY() const { return maxPoint.y; }
|
||||||
|
|
||||||
|
float AABB::MaxZ() const { return maxPoint.z; }
|
||||||
|
|
||||||
|
Sphere AABB::MinimalEnclosingSphere() const {
|
||||||
|
return Sphere(Centroid(), Size().Length()*0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::HalfSize() const {
|
||||||
|
return this->Size()/2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sphere AABB::MaximalContainedSphere() const {
|
||||||
|
Vector3 halfSize = HalfSize();
|
||||||
|
return Sphere(Centroid(), std::min(halfSize.x, std::min(halfSize.y, halfSize.z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AABB::IsFinite() const {
|
||||||
|
return minPoint.IsFinite() && maxPoint.IsFinite();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::Centroid() const {
|
||||||
|
return (minPoint+maxPoint) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::Size() const {
|
||||||
|
return this->maxPoint - this->minPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::PointInside(float x, float y, float z) const {
|
||||||
|
Vector3 d = maxPoint - minPoint;
|
||||||
|
return minPoint + d.Mul({x, y, z});
|
||||||
|
}
|
||||||
|
|
||||||
|
LineSegment AABB::Edge(int edgeIndex) const {
|
||||||
|
switch(edgeIndex)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0: return LineSegment(minPoint, {minPoint.x, minPoint.y, maxPoint.z});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::CornerPoint(int cornerIndex) const {
|
||||||
|
// TODO: assert(0 <= cornerIndex && cornerIndex <= 7)
|
||||||
|
switch(cornerIndex)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case 0: return minPoint;
|
||||||
|
case 1: return {minPoint.x, minPoint.y, maxPoint.z};
|
||||||
|
case 2: return {minPoint.x, maxPoint.y, minPoint.z};
|
||||||
|
case 3: return {minPoint.x, maxPoint.y, maxPoint.z};
|
||||||
|
case 4: return {maxPoint.x, minPoint.y, minPoint.z};
|
||||||
|
case 5: return {maxPoint.x, minPoint.y, maxPoint.z};
|
||||||
|
case 6: return {maxPoint.x, maxPoint.y, minPoint.z};
|
||||||
|
case 7: return maxPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::ExtremePoint(const Vector3 &direction) const {
|
||||||
|
return {direction.x >= 0.f ? maxPoint.x : minPoint.x,
|
||||||
|
direction.y >= 0.f ? maxPoint.y : minPoint.y,
|
||||||
|
direction.z >= 0.f ? maxPoint.z : minPoint.z};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::ExtremePoint(const Vector3 &direction, float &projectionDistance) {
|
||||||
|
auto extremePt = ExtremePoint(direction);
|
||||||
|
projectionDistance = extremePt.Dot(direction);
|
||||||
|
return extremePt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::PointOnEdge(int edgeIndex, float u) const {
|
||||||
|
// TODO: assert(0 <= edgeIndex && edgeIndex <= 11);
|
||||||
|
// TODO: assert(0 <= u && u < 1.f);
|
||||||
|
|
||||||
|
auto d = maxPoint - minPoint;
|
||||||
|
switch(edgeIndex) {
|
||||||
|
default:
|
||||||
|
case 0: return {minPoint.x, minPoint.y, minPoint.z + u * d.z};
|
||||||
|
case 1: return {minPoint.x, maxPoint.y, minPoint.z + u * d.z};
|
||||||
|
case 2: return {maxPoint.x, minPoint.y, minPoint.z + u * d.z};
|
||||||
|
case 3: return {maxPoint.x, maxPoint.y, minPoint.z + u * d.z};
|
||||||
|
|
||||||
|
case 4: return {minPoint.x, minPoint.y + u * d.y, minPoint.z};
|
||||||
|
case 5: return {maxPoint.x, minPoint.y + u * d.y, minPoint.z};
|
||||||
|
case 6: return {minPoint.x, minPoint.y + u * d.y, maxPoint.z};
|
||||||
|
case 7: return {maxPoint.x, minPoint.y + u * d.y, maxPoint.z};
|
||||||
|
|
||||||
|
case 8: return {minPoint.x + u * d.x, minPoint.y, minPoint.z};
|
||||||
|
case 9: return {minPoint.x + u * d.x, minPoint.y, maxPoint.z};
|
||||||
|
case 10:return {minPoint.x + u * d.x, maxPoint.y, minPoint.z};
|
||||||
|
case 11:return {minPoint.x + u * d.x, maxPoint.y, maxPoint.z};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::FaceCenterPoint(int faceIndex) const {
|
||||||
|
// TODO: assert(0 <= faceIndex && faceIndex <= 5)
|
||||||
|
auto center = (minPoint + maxPoint) * 0.5f;
|
||||||
|
switch (faceIndex) {
|
||||||
|
default:
|
||||||
|
case 0: return {minPoint.x, center.y, center.z};
|
||||||
|
case 1: return {maxPoint.x, center.y, center.z};
|
||||||
|
case 2: return {center.x, minPoint.y, center.z};
|
||||||
|
case 3: return {center.x, maxPoint.y, center.z};
|
||||||
|
case 4: return {center.x, center.y, minPoint.z};
|
||||||
|
case 5: return {center.x, center.y, maxPoint.z};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 AABB::FacePoint(int faceIndex, float u, float v) const {
|
||||||
|
// TODO: assert(0 <= faceIndex && faceIndex <= 5);
|
||||||
|
// TODO: assert(0 <= u && u <= 1.f);
|
||||||
|
// TODO: assert(0 <= v && v <= 1.f);
|
||||||
|
|
||||||
|
auto d = maxPoint - minPoint;
|
||||||
|
switch(faceIndex)
|
||||||
|
{
|
||||||
|
default: // For release builds where assume() is disabled, return always the first option if out-of-bounds.
|
||||||
|
case 0: return {minPoint.x, minPoint.y + u * d.y, minPoint.z + v * d.z};
|
||||||
|
case 1: return {maxPoint.x, minPoint.y + u * d.y, minPoint.z + v * d.z};
|
||||||
|
case 2: return {minPoint.x + u * d.x, minPoint.y, minPoint.z + v * d.z};
|
||||||
|
case 3: return {minPoint.x + u * d.x, maxPoint.y, minPoint.z + v * d.z};
|
||||||
|
case 4: return {minPoint.x + u * d.x, minPoint.y + v * d.y, minPoint.z};
|
||||||
|
case 5: return {minPoint.x + u * d.x, minPoint.y + v * d.y, maxPoint.z};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user