CVector3f clampToBox(const CVector3f& vec) const { CVector3f ret = vec; ret.x() = clamp(min.x(), float(ret.x()), max.x()); ret.y() = clamp(min.y(), float(ret.y()), max.y()); ret.z() = clamp(min.z(), float(ret.z()), max.z()); return ret; }
void splitZ(CAABox& negZ, CAABox& posZ) const { float midZ = (max.z() - min.z()) * .5f + min.z(); posZ.max = max; posZ.min = min; posZ.min.z() = midZ; negZ.max = max; negZ.max.z() = midZ; negZ.min = min; }
float distanceBetween(const CAABox& other) { int intersects = 0; if (max.x() >= other.min.x() && min.x() <= other.max.x()) intersects |= 0x1; if (max.y() >= other.min.y() && min.y() <= other.max.y()) intersects |= 0x2; if (max.z() >= other.min.z() && min.z() <= other.max.z()) intersects |= 0x4; float minX, maxX; if (max.x() < other.min.x()) { minX = max.x(); maxX = other.min.x(); } else { minX = min.x(); maxX = other.max.x(); } float minY, maxY; if (max.y() < other.min.y()) { minY = max.y(); maxY = other.min.y(); } else { minY = min.y(); maxY = other.max.y(); } float minZ, maxZ; if (max.z() < other.min.z()) { minZ = max.z(); maxZ = other.min.z(); } else { minZ = min.z(); maxZ = other.max.z(); } switch (intersects) { case 0: return zeus::CVector3f(maxX - minX, maxY - minY, maxZ - minZ).magnitude(); case 1: return zeus::CVector2f(maxY - minY, maxZ - minZ).magnitude(); case 2: return zeus::CVector2f(maxX - minX, maxZ - minZ).magnitude(); case 3: return std::fabs(maxZ - minZ); case 4: return zeus::CVector2f(maxX - minX, maxY - minY).magnitude(); case 5: return std::fabs(maxY - minY); case 6: return std::fabs(maxX - minX); case 7: default: return 0.f; } }
void accumulateBounds(const CVector3f& point) { if (min.x() > point.x()) min.x() = point.x(); if (min.y() > point.y()) min.y() = point.y(); if (min.z() > point.z()) min.z() = point.z(); if (max.x() < point.x()) max.x() = point.x(); if (max.y() < point.y()) max.y() = point.y(); if (max.z() < point.z()) max.z() = point.z(); }
bool invalid() { return (max.x() < min.x() || max.y() < min.y() || max.z() < min.z()); }
CVector3f furthestPointAlongVector(const CVector3f& other) const { return {(other.x() >= 0.f ? max.x() : min.x()), (other.y() >= 0.f ? max.y() : min.y()), (other.z() >= 0.f ? max.z() : min.z())}; }
bool pointInside(const CVector3f& other) const { return (min.x() <= other.x() && other.x() <= max.x() && min.y() <= other.y() && other.y() <= max.y() && min.z() <= other.z() && other.z() <= max.z()); }
CLineSeg getEdge(EBoxEdgeId id) const { switch (id) { case EBoxEdgeId::Z0: default: return CLineSeg({min.x(), min.y(), max.z()}, {min.x(), min.y(), min.z()}); case EBoxEdgeId::X0: return CLineSeg({min.x(), min.y(), min.z()}, {max.x(), min.y(), min.z()}); case EBoxEdgeId::Z1: return CLineSeg({max.x(), min.y(), min.z()}, {max.x(), min.y(), max.z()}); case EBoxEdgeId::X1: return CLineSeg({max.x(), min.y(), max.z()}, {min.x(), min.y(), max.z()}); case EBoxEdgeId::Z2: return CLineSeg({max.x(), max.y(), max.z()}, {max.x(), max.y(), min.z()}); case EBoxEdgeId::X2: return CLineSeg({max.x(), max.y(), min.z()}, {min.x(), max.y(), min.z()}); case EBoxEdgeId::Z3: return CLineSeg({min.x(), max.y(), min.z()}, {min.x(), max.y(), max.z()}); case EBoxEdgeId::X3: return CLineSeg({min.x(), max.y(), max.z()}, {max.x(), max.y(), max.z()}); case EBoxEdgeId::Y0: return CLineSeg({min.x(), min.y(), max.z()}, {min.x(), max.y(), max.z()}); case EBoxEdgeId::Y1: return CLineSeg({min.x(), min.y(), min.z()}, {min.x(), max.y(), min.z()}); case EBoxEdgeId::Y2: return CLineSeg({max.x(), min.y(), min.z()}, {max.x(), max.y(), min.z()}); case EBoxEdgeId::Y3: return CLineSeg({max.x(), min.y(), max.z()}, {max.x(), max.y(), max.z()}); } }