Files
2025-10-28 14:05:46 -04:00

174 lines
4.0 KiB
C++

#pragma once
#include "Util/Vector3int32.h"
#include "Util/Extents.h"
#include "rbx/Debug.h"
namespace RBX {
class ExtentsInt32 {
public:
Vector3int32 low;
Vector3int32 high;
ExtentsInt32()
: low(Vector3int32::maxInt())
, high(Vector3int32::minInt())
{}
ExtentsInt32(const Vector3int32& _min, const Vector3int32& _max)
: low(_min)
, high(_max)
{
RBXASSERT_SLOW(low == low.min(high));
RBXASSERT_SLOW(high == high.max(low));
}
bool operator==(const ExtentsInt32& other) const {
return ((low == other.low) && (high == other.high));
}
bool operator!=(const ExtentsInt32& other) const {
return !(*this == other);
}
ExtentsInt32& operator= (const ExtentsInt32& other) {
low = other.low;
high = other.high;
return *this;
}
ExtentsInt32 shiftRight(int shift) const {
RBXASSERT_SLOW(shift >= 0);
RBXASSERT_SLOW(shift <= 32);
return ExtentsInt32(low >> shift, high >> shift);
}
ExtentsInt32 shiftRight(const Vector3int32& shift) const {
return ExtentsInt32(low >> shift, high >> shift);
}
ExtentsInt32 shiftLeft(int shift) const {
RBXASSERT_SLOW(shift >= 0);
RBXASSERT_SLOW(shift <= 32);
return ExtentsInt32(low << shift, high << shift);
}
ExtentsInt32 shiftLeft(const Vector3int32& shift) const {
return ExtentsInt32(low << shift, high << shift);
}
static ExtentsInt32 vv(const Vector3int32& v0, const Vector3int32& v1) {
ExtentsInt32 e;
e.low = v0.min(v1);
e.high = v0.max(v1);
return e;
}
const Vector3int32& min() const {return low;}
const Vector3int32& max() const {return high;}
Vector3int32 getCorner(int i) const;
Vector3int32 size() const {
return high - low;
}
Vector3int32 center() const {
return ((low + high) >> 1);
}
Vector3int32 bottomCenter() const {
Vector3int32 answer = center();
answer.y = low.y;
return answer;
}
Vector3int32 topCenter() const {
Vector3int32 answer = center();
answer.y = high.y;
return answer;
}
int longestSide() const {
Vector3int32 s = size();
return std::max(std::max(s.x, s.y), s.z);
}
int volume() const {
Vector3int32 s = size();
long long int answer = s.x * s.y * s.z;
RBXASSERT(answer < INT_MAX);
return static_cast<int>(answer);
}
static ExtentsInt32 unionExtents(const ExtentsInt32& a, const ExtentsInt32& b) {
return ExtentsInt32(a.low.min(b.low), a.high.max(b.high));
}
void shift(const Vector3int32& shiftVector) {
low = low + shiftVector;
high = high + shiftVector;
}
void expand(int x) {
low = low - Vector3int32(x,x,x);
high = high + Vector3int32(x,x,x);
}
const Vector3int32& operator[] (int i) const {
return ((Vector3int32*)this)[i];
}
Vector3int32& operator[] (int i) {
return ((Vector3int32*)this)[i];
}
operator Vector3int32* () {
return (Vector3int32*)this;
}
operator const Vector3int32* () const {
return (Vector3int32*)this;
}
bool contains(int x, int y, int z) const {
return ( (x >= low.x)
&& (y >= low.y)
&& (z >= low.z)
&& (x <= high.x)
&& (y <= high.y)
&& (z <= high.z) );
}
bool contains(const Vector3int32& point) const {
return contains(point.x, point.y, point.z);
}
bool overlapsOrTouches(const ExtentsInt32& 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 ExtentsInt32& e0, const ExtentsInt32& e1) {return e0.overlapsOrTouches(e1);}
Extents toExtents() const {
return Extents(low.toVector3(), high.toVector3());
}
static const ExtentsInt32& zero() {
static ExtentsInt32 e(Vector3int32::zero(), Vector3int32::zero());
return e;
}
static const ExtentsInt32& empty() {
static ExtentsInt32 e; // constructor sets negatives
return e;
}
};
} // namespace