mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 05:07:48 +00:00
fahhh
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
#pragma once
|
||||
|
||||
#include "Util/NormalId.h"
|
||||
#include "Util/G3DCore.h"
|
||||
#include "rbx/Debug.h"
|
||||
#include "Util/Math.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
class Extents {
|
||||
private:
|
||||
Vector3 low;
|
||||
Vector3 high;
|
||||
|
||||
public:
|
||||
Extents() // initialize to negativeInfiniteExtents;
|
||||
: low(Vector3::maxFinite())
|
||||
, high(-Vector3::maxFinite())
|
||||
{}
|
||||
|
||||
Extents(const Vector3& _min, const Vector3& _max)
|
||||
: low(_min)
|
||||
, high(_max)
|
||||
{
|
||||
RBXASSERT_SLOW(low == low.min(high));
|
||||
RBXASSERT_SLOW(high == high.max(low));
|
||||
}
|
||||
|
||||
bool isNanInf() const
|
||||
{
|
||||
return (Math::isNanInfVector3(low) || Math::isNanInfVector3(high));
|
||||
}
|
||||
|
||||
static Extents fromCenterCorner(const Vector3& center, const Vector3& corner) {
|
||||
return Extents(center-corner, center+corner);
|
||||
}
|
||||
|
||||
static Extents fromCenterRadius(const Vector3& center, float radius) {
|
||||
return fromCenterCorner(center, Vector3(radius, radius, radius));
|
||||
}
|
||||
|
||||
bool operator==(const Extents& other) const {
|
||||
return ((low == other.low) && (high == other.high));
|
||||
}
|
||||
|
||||
bool operator!=(const Extents& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
static Extents vv(const Vector3& v0, const Vector3& v1) {
|
||||
Extents e;
|
||||
e.low = v0.min(v1);
|
||||
e.high = v0.max(v1);
|
||||
return e;
|
||||
}
|
||||
|
||||
const Vector3& min() const {return low;}
|
||||
const Vector3& max() const {return high;}
|
||||
|
||||
Vector3int16 getCornerIndex(int i) const;
|
||||
Vector3 getCorner(int i) const;
|
||||
|
||||
Vector3 size() const {
|
||||
return high - low;
|
||||
}
|
||||
|
||||
Vector3 center() const {
|
||||
return 0.5 * (low + high);
|
||||
}
|
||||
|
||||
Vector3 bottomCenter() const {
|
||||
Vector3 answer = center();
|
||||
answer.y = low.y;
|
||||
return answer;
|
||||
}
|
||||
|
||||
Vector3 topCenter() const {
|
||||
Vector3 answer = center();
|
||||
answer.y = high.y;
|
||||
return answer;
|
||||
}
|
||||
|
||||
float longestSide() const {
|
||||
Vector3 s = size();
|
||||
return G3D::max(G3D::max(s.x, s.y), s.z);
|
||||
}
|
||||
|
||||
float volume() const {
|
||||
Vector3 s = size();
|
||||
return s.x * s.y * s.z;
|
||||
}
|
||||
|
||||
float areaXZ() const {
|
||||
Vector3 s = size();
|
||||
return s.x * s.z;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return low.x > high.x || low.y > high.y || low.z > high.z;
|
||||
}
|
||||
|
||||
Extents toWorldSpace(const CoordinateFrame& offset) const;
|
||||
|
||||
Extents express(const CoordinateFrame& myFrame, const CoordinateFrame& expressInFrame) const;
|
||||
|
||||
// faceId's are in order of x, y, z, -x, -y, -z
|
||||
Vector3 faceCenter(NormalId faceId) const;
|
||||
|
||||
/**
|
||||
Returns the four corners of a face (0 <= f < 6).
|
||||
The corners are returned to form a counter clockwise quad facing outwards.
|
||||
*/
|
||||
void getFaceCorners(
|
||||
NormalId faceId,
|
||||
Vector3& v0,
|
||||
Vector3& v1,
|
||||
Vector3& v2,
|
||||
Vector3& v3) const;
|
||||
|
||||
Plane getPlane(NormalId normalId) const;
|
||||
|
||||
// clip the vector to be inside the Extents
|
||||
Vector3 clip(const Vector3& clipVector) const {
|
||||
return clipVector.clamp(low, high);
|
||||
}
|
||||
|
||||
|
||||
float computeClosestSqDistanceToPoint(const Vector3& point) const;
|
||||
|
||||
// minimum amount to move innerExtents and keep them within Extents
|
||||
Vector3 clamp(const Extents& innerExtents) const;
|
||||
|
||||
NormalId closestFace(const Vector3& point);
|
||||
|
||||
void unionWith(const Extents& other) { // Extents& operator&= (const Extents& other) {
|
||||
low = low.min(other.low);
|
||||
high = high.max(other.high);
|
||||
}
|
||||
|
||||
Extents clampInsideOf(const Extents& other) const; // Extents& operator&= (const Extents& other) {
|
||||
|
||||
void shift(const Vector3& shiftVector) {// Extents& operator+= (const Vector3& shiftVector) {
|
||||
low += shiftVector;
|
||||
high += shiftVector;
|
||||
}
|
||||
|
||||
void scale(float x) { // Extents& operator*= (float x) {
|
||||
low *= x;
|
||||
high *= x;
|
||||
}
|
||||
|
||||
void expand(float x) {
|
||||
low -= Vector3(x,x,x);
|
||||
high += Vector3(x,x,x);
|
||||
}
|
||||
|
||||
void expand(const Vector3& p) {
|
||||
low -= p;
|
||||
high += p;
|
||||
}
|
||||
|
||||
void expandToContain(const Vector3& p) {
|
||||
low = low.min(p);
|
||||
high = high.max(p);
|
||||
}
|
||||
|
||||
void expandToContain(const Extents& e) {
|
||||
low = low.min(e.low);
|
||||
high = high.max(e.high);
|
||||
}
|
||||
|
||||
bool contains(const Vector3& point) const {
|
||||
return ( (point.x >= low.x)
|
||||
&& (point.y >= low.y)
|
||||
&& (point.z >= low.z)
|
||||
&& (point.x <= high.x)
|
||||
&& (point.y <= high.y)
|
||||
&& (point.z <= high.z) );
|
||||
}
|
||||
|
||||
bool fuzzyContains(const Vector3& point, float slop) const {
|
||||
return ( (point.x >= (low.x - slop))
|
||||
&& (point.y >= (low.y - slop))
|
||||
&& (point.z >= (low.z - slop))
|
||||
&& (point.x <= (high.x + slop))
|
||||
&& (point.y <= (high.y + slop))
|
||||
&& (point.z <= (high.z + slop)) );
|
||||
}
|
||||
|
||||
|
||||
bool overlapsOrTouches(const Extents& other) const { // true if sides are exactly equal (touching)
|
||||
return ( (this->low.x > other.high.x)
|
||||
|| (this->low.y > other.high.y)
|
||||
|| (this->low.z > other.high.z)
|
||||
|| (this->high.y < other.low.y)
|
||||
|| (this->high.x < other.low.x)
|
||||
|| (this->high.z < other.low.z)) ? false : true;
|
||||
}
|
||||
|
||||
static bool overlapsOrTouches(const Extents& e0, const Extents& e1) {return e0.overlapsOrTouches(e1);}
|
||||
|
||||
bool clampToOverlap(const Extents& other) {
|
||||
if ( (this->low.x >= other.high.x)
|
||||
|| (this->low.y >= other.high.y)
|
||||
|| (this->low.z >= other.high.z)
|
||||
|| (this->high.y <= other.low.y)
|
||||
|| (this->high.x <= other.low.x)
|
||||
|| (this->high.z <= other.low.z))
|
||||
return false; // not overlap
|
||||
low = low.clamp(other.low, other.high);
|
||||
high = high.clamp(other.low, other.high);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool separatedByMoreThan(const Extents& other, float distance) const;
|
||||
|
||||
|
||||
static const Extents& zero() {
|
||||
static Extents e(Vector3::zero(), Vector3::zero());
|
||||
return e;
|
||||
}
|
||||
|
||||
static const Extents& unit() {
|
||||
static Extents e(Vector3(-1,-1,-1), Vector3(1,1,1));
|
||||
return e;
|
||||
}
|
||||
|
||||
static const Extents& negativeMaxExtents() {
|
||||
static Extents e; // default constructor builds this;
|
||||
return e;
|
||||
}
|
||||
|
||||
static const Extents& maxExtents() {
|
||||
static Extents e(-Vector3::maxFinite(), Vector3::maxFinite());
|
||||
return e;
|
||||
}
|
||||
|
||||
};
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user