module Graphics.LambdaCube.Frustum where import Graphics.LambdaCube.Types {- class Plane { public: Vec3 normal,point; float d; void set3Points( Vec3 &v1, Vec3 &v2, Vec3 &v3); float distance(Vec3 &p); }; void Plane::set3Points( Vec3 &v1, Vec3 &v2, Vec3 &v3) { Vec3 aux1, aux2; aux1 = v1 - v2; aux2 = v3 - v2; normal = aux2 * aux1; normal.normalize(); point.copy(v2); d = -(normal.innerProduct(point)); } float Plane::distance(Vec3 &p) { return (d + normal.innerProduct(p)); } class FrustumG { private: enum { TOP = 0, BOTTOM, LEFT, RIGHT, NEARP, FARP }; public: static enum {OUTSIDE, INTERSECT, INSIDE}; Plane pl[6]; Vec3 ntl,ntr,nbl,nbr,ftl,ftr,fbl,fbr; float nearD, farD, ratio, angle,tang; float nw,nh,fw,fh; void FrustumG::setCamInternals(float angle, float ratio, float nearD, float farD); void FrustumG::setCamDef(Vec3 &p, Vec3 &l, Vec3 &u); int FrustumG::pointInFrustum(Vec3 &p); int FrustumG::sphereInFrustum(Vec3 &p, float raio); int FrustumG::boxInFrustum(AABox &b); }; #define ANG2RAD 3.14159265358979323846/180.0 void FrustumG::setCamInternals(float angle, float ratio, float nearD, float farD) { this->ratio = ratio; this->angle = angle; this->nearD = nearD; this->farD = farD; tang = (float)tan(angle* ANG2RAD * 0.5) ; nh = nearD * tang; nw = nh * ratio; fh = farD * tang; fw = fh * ratio; } void FrustumG::setCamDef(Vec3 &p, Vec3 &l, Vec3 &u) { Vec3 dir,nc,fc,X,Y,Z; Z = p - l; Z.normalize(); X = u * Z; X.normalize(); Y = Z * X; nc = p - Z * nearD; fc = p - Z * farD; ntl = nc + Y * nh - X * nw; ntr = nc + Y * nh + X * nw; nbl = nc - Y * nh - X * nw; nbr = nc - Y * nh + X * nw; ftl = fc + Y * fh - X * fw; ftr = fc + Y * fh + X * fw; fbl = fc - Y * fh - X * fw; fbr = fc - Y * fh + X * fw; pl[TOP].set3Points(ntr,ntl,ftl); pl[BOTTOM].set3Points(nbl,nbr,fbr); pl[LEFT].set3Points(ntl,nbl,fbl); pl[RIGHT].set3Points(nbr,ntr,fbr); pl[NEARP].set3Points(ntl,ntr,nbr); pl[FARP].set3Points(ftr,ftl,fbl); } int FrustumG::pointInFrustum(Vec3 &p) { int result = INSIDE; for(int i=0; i < 6; i++) { if (pl[i].distance(p) < 0) return OUTSIDE; } return(result); } int FrustumG::sphereInFrustum(Vec3 &p, float raio) { int result = INSIDE; float distance; for(int i=0; i < 6; i++) { distance = pl[i].distance(p); if (distance < -raio) return OUTSIDE; else if (distance < raio) result = INTERSECT; } return(result); } int FrustumG::boxInFrustum(AABox &b) { int result = INSIDE; for(int i=0; i < 6; i++) { if (pl[i].distance(b.getVertexP(pl[i].normal)) < 0) return OUTSIDE; else if (pl[i].distance(b.getVertexN(pl[i].normal)) < 0) result = INTERSECT; } return(result); } -}