#include "RayInfo.h" #include "Ray.h" #include "VssRay.h" #include "Plane3.h" using namespace std; namespace GtpVisibilityPreprocessor { RayInfo::RayInfo(): mRay(NULL), mMinT(0), #if USE_FIXEDPOINT_T #define FIXEDPOINT_ONE 0x7FFE // mMaxT(0xFFFF) mMaxT(FIXEDPOINT_ONE) #else mMaxT(1.0f) #endif {} RayInfo::RayInfo(VssRay *r):mRay(r), mMinT(0), #if USE_FIXEDPOINT_T #define FIXEDPOINT_ONE 0x7FFE // mMaxT(0xFFFF) mMaxT(FIXEDPOINT_ONE) #else mMaxT(1.0f) #endif {} RayInfo::RayInfo(VssRay *r, const float _min, const float _max): mRay(r) { SetMinT(_min); SetMaxT(_max); } RayInfo::RayInfo(VssRay *r, const short _min, const float _max): mRay(r), mMinT(_min) { SetMaxT(_max); } RayInfo::RayInfo(VssRay *r, const float _min, const short _max): mRay(r), mMaxT(_max) { SetMinT(_min); } int RayInfo::ComputeRayIntersection(const int axis, const float position, float &t) const { // intersect the ray with the plane const float denom = mRay->GetDir(axis); if (fabs(denom) < 1e-20) //if (denom == 0.0f) return (mRay->GetOrigin(axis) > position) ? 1 : -1; t = (position - mRay->GetOrigin(axis)) / denom; if (t < GetMinT()) return (denom > 0) ? 1 : -1; if (t > GetMaxT()) return (denom > 0) ? -1 : 1; return 0; } int RayInfo::ComputeRayIntersection(const Plane3 &splitPlane, float &t) const { t = splitPlane.FindT(mRay->GetOrigin(), mRay->GetTermination()); if (0) Debug << "t: " << t << " mint " << GetMinT() << " maxt " << GetMaxT() << " orig: " << mRay->GetOrigin() << " term " << mRay->GetTermination() << endl; // NOTE: if plane equals end point of ray, the ray should be classified // non-intersecting, otherwise polygon-plane intersections of bsp tree // approaches are not eliminating any rays intersecting the polygon! const float thresh = 1e-6f; // segment is not intersecting plane: fond out if on front or back side if (t >= (GetMaxT() - thresh)) { return splitPlane.Side(ExtrapOrigin()); } if (t <= (GetMinT() + thresh)) { return splitPlane.Side(ExtrapTermination()); } return 0; } float RayInfo::SegmentLength() const { return Distance(ExtrapOrigin(), ExtrapTermination()); } float RayInfo::SqrSegmentLength() const { return SqrDistance(ExtrapOrigin(), ExtrapTermination()); } void GetRayInfoSets(const RayInfoContainer &sourceRays, const int maxSize, RayInfoContainer &usedRays, RayInfoContainer *savedRays) { const int limit = min(maxSize, (int)sourceRays.size()); const float prop = (float)limit / ((float)sourceRays.size() + Limits::Small); RayInfoContainer::const_iterator it, it_end = sourceRays.end(); for (it = sourceRays.begin(); it != it_end; ++ it) { if (Random(1.0f) < prop) usedRays.push_back(*it); else if (savedRays) savedRays->push_back(*it); } } }