#ifndef _gpuCacheFrustum_h_
#define _gpuCacheFrustum_h_
#include <maya/MMatrix.h>
#include <maya/MBoundingBox.h>
#include <cassert>
namespace GPUCache {
class Frustum
{
public:
enum ClippingResult {
kIntersectsLeft = (1),
kIntersectsRight = (1 << 1),
kIntersectsBottom = (1 << 2),
kIntersectsTop = (1 << 3),
kIntersectsNear = (1 << 4),
kIntersectsFar = (1 << 5),
kIntersectsMask = kIntersectsLeft | kIntersectsRight |
kIntersectsBottom | kIntersectsTop |
kIntersectsNear | kIntersectsFar,
kOutside = (1 << 6),
kInside = (1 << 7),
kIntersects = kIntersectsMask,
kUnknown = kIntersectsMask,
};
kDirectX,
};
const ClippingResult& parentResult = kUnknown) const
{
assert(!(parentResult & (kOutside | kInside)));
int result = 0;
int intersect = 1;
for (int i=kFirstPlane; i<=kLastPlane; ++i,intersect=intersect<<1) {
if (parentResult & intersect) {
ClippingResult res = planes[i].test(pmin, pmax);
if (res == kOutside) {
return kOutside;
}
if (res == kIntersects) {
result = result | intersect;
}
}
}
if (!(result & kIntersectsMask)) {
return kInside;
}
return (ClippingResult)result;
}
private:
enum PlaneId {
kLeft,
kRight,
kBottom,
kTop,
kNear,
kFar,
kFirstPlane = kLeft,
kLastPlane = kFar
};
class Plane
{
public:
{
d = -(n.
x*p1.x + n.
y*p1.y + n.
z*p1.z);
if (distance(opp) < 0.0f) {
a = -a; b = -b; c = -c; d = -d;
}
}
double distance(double x, double y, double z) const
{
return a*x + b*y + c*z + d;
}
double distance(
const MPoint& p)
const
{
return distance(p.
x, p.
y, p.
z);
}
ClippingResult test(
const MPoint& pmin,
{
const bool sa = a > 0.0;
const bool sb = b > 0.0;
const bool sc = c > 0.0;
if (distance(sa ? pmax.
x : pmin.
x,
sc ? pmax.
z : pmin.
z) < 0.0)
return kOutside;
if (distance(sa ? pmin.
x : pmax.
x,
sc ? pmin.
z : pmax.
z) > 0.0)
return kInside;
return kIntersects;
}
void print(const char* name,
private:
double a, b, c, d;
};
Plane planes[6];
};
}
#endif