#ifndef __SIMPLE_RAY_H #define __SIMPLE_RAY_H #include using namespace std; #include "Vector3.h" class AxisAlignedBox3; class Intersectable; class VssRay { public: // various flags enum { FPosDirX = 1, // the direction of ray in X-axis is positive FPosDirY = 2, // the direction of ray in Y-axis is positive FPosDirZ = 4 // the direction of ray in Z-axis is positive }; static int mailID; int mMailbox; // side of the ray - used for the ray classification char mSide; // computed t float mT; // inverse of the ray size float mInvSize; // counter of references to this ray short mRefCount; // various flags char mFlags; Vector3 mOrigin; Vector3 mTermination; Intersectable *mOriginObject; Intersectable *mTerminationObject; ////////////////////////////// VssRay(const Vector3 &origin, const Vector3 &termination, Intersectable *originObject, Intersectable *terminationObject): mMailbox(-1), mOrigin(origin), mTermination(termination), mOriginObject(originObject), mTerminationObject(terminationObject), mRefCount(0), mFlags(0) { Precompute(); } void Precompute() { mFlags = 0; if (GetDir().x>0.0f) mFlags |= FPosDirX; if (GetDir().y>0.0f) mFlags |= FPosDirY; if (GetDir().z>0.0f) mFlags |= FPosDirZ; mInvSize = 1.0f/Magnitude(GetDir()); } void Mail() { mMailbox = mailID; } static void NewMail() { mailID++; } bool Mailed() const { return mMailbox == mailID; } bool Mailed(const int mail) { return mMailbox >= mailID + mail; } Vector3 GetOrigin() const { return mOrigin; } Vector3 GetTermination() const { return mTermination; } Vector3 GetDir() const { return mTermination - mOrigin; } // Vector3 GetNormalizedDir() const { return Normalize(termination - mOrigin); } Vector3 GetNormalizedDir() const { return (mTermination - mOrigin)*mInvSize; } float GetInvSize() const { return mInvSize; } float GetOrigin(const int axis) const { return mOrigin[axis]; } float GetTermination(const int axis) const { return mTermination[axis]; } float GetDir(const int axis) const { return mTermination[axis] - mOrigin[axis]; } float GetNormalizedDir(const int axis) const { return (mTermination[axis] - mOrigin[axis])*mInvSize; } bool ComputeMinMaxT(const AxisAlignedBox3 &box, float &tmin, float &tmax) const; bool Intersects(const AxisAlignedBox3 &box, float &tmin, float &tmax) const; bool IntersectsSphere(const Vector3 ¢er, const float sqrRadius, Vector3 &point, float &t) const; void Translate(const Vector3 &translation) { mOrigin += translation; mTermination += translation; } bool HasPosDir(const int axis) const { return mFlags & (1<0; } // reference counting for leaf nodes int RefCount() const { return mRefCount; } int Ref() { return mRefCount++; } void ScheduleForRemoval() { if (mRefCount>0) mRefCount = -mRefCount; } bool ScheduledForRemoval() const { return mRefCount<0; } void Unref() { if (mRefCount > 0) mRefCount--; else if (mRefCount < 0) mRefCount++; else { cerr<<"Trying to unref already deleted ray!"< VssRayContainer; #endif