#pragma once #include #include #include namespace J3ML::Geometry { /// A 3D arbitrarily oriented bounding box // This data structure represents a box in 3D space. The local axes of this box can be arbitrarily oriented/rotated // with respect to the global world coordinate system. This allows OBBs to more tightly bound objects than AABBs do, // which always align with the world space axes. This flexibility has the drawback that the geometry tests and operations // involving OBBs are more costly, and representing an OBB in memory takes more space (15 floats vs 6 floats) class OBB : public Shape { public: // The center position of this OBB Vector3 pos; // Stores half-sizes to x, y, and z directions in the local space of this OBB. Vector3 r; // Specifies normalized direction vectors for the local axes Vector3 axis[3]; /// Default constructor that does not initialize any member values. OBB() {} // Constructs an OBB by explicitly initializing all member values OBB(const Vector3& pos, const Vector3& radii, const Vector3& axis0, const Vector3& axis1, const Vector3& axis2); OBB(const AABB& aabb); inline static int NumFaces() { return 6; } inline static int NumEdges() { return 12; } inline static int NumVertices() { return 8; } Polyhedron ToPolyhedron() const; //PBVolume<6> ToPBVolume() const; AABB MinimalEnclosingAABB() const { AABB aabb; aabb.SetFrom(*this); return aabb; } bool Intersects(const LineSegment &lineSegment) const; Sphere MinimalEnclosingSphere() const; Sphere MaximalContainedSphere() const; Vector3 Size() const; Vector3 HalfSize() const; Vector3 Diagonal() const; Vector3 HalfDiagonal() const; void Transform(const Matrix3x3& transform); void Transform(const Matrix4x4& transform); void Transform(const Quaternion& transform); bool IsFinite() const; bool IsDegenerate() const; Vector3 CenterPoint() const; Vector3 Centroid() const; Vector3 AnyPointFast() const { return pos; } float Volume() const; float SurfaceArea() const; Geometry::LineSegment Edge(int edgeIndex) const; Vector3 CornerPoint(int cornerIndex) const; Vector3 PointInside(float x, float y, float z) const; Vector3 PointInside(const Vector3& pt) const; void ProjectToAxis(const Vector3 &direction, float &outMin, float &outMax) const; int UniqueFaceNormals(Vector3 *out) const; int UniqueEdgeDirections(Vector3 *out) const; Vector3 PointOnEdge(int edgeIndex, float u) const; Vector3 FaceCenterPoint(int faceIndex) const; void GetCornerPoints(Vector3 *outPointArray) const; void GetFacePlanes(Plane *outPlaneArray) const; Plane FacePlane(int faceIndex) const; void ExtremePointsAlongDirection(const Vector3 &dir, const Vector3 *pointArray, int numPoints, int &idxSmallest, int &idxLargest, float &smallestD, float &largestD); Vector3 FacePoint(int faceIndex, float u, float v) const; Vector3 ExtremePoint(const Vector3 &direction, float &projectionDistance) const; Vector3 ExtremePoint(const Vector3 &direction) const; void SetFrom(const AABB &aabb, const Matrix3x3 &transform); void SetFrom(const AABB &aabb, const Matrix4x4 &transform); void SetFrom(const AABB &aabb, const Quaternion &transform); bool Intersects(const Plane& plane) const; Matrix4x4 LocalToWorld() const; Matrix4x4 WorldToLocal() const; }; }