#ifndef quadric_h #define quadric_h #include <jgl/roots.h> #include "object.h" class rtl_quadric : public rtl_object { protected: rtl_quadric(); inline jFlt lclintersect( const rtl_ray& ); inline jFlt rehit(); virtual void coefficients( const rtl_ray&, jFlt* ) = 0; jFlt s[2]; jInt si; }; class rtl_sphere : public rtl_quadric { public: rtl_sphere(); Type type() const { return objSphere; } private: void coefficients( const rtl_ray& ray, jFlt* k ) { k[2] = 1.0; k[1] = 2*( ray.direction()[0]*ray.origin()[0] + ray.direction()[1]*ray.origin()[1] + ray.direction()[2]*ray.origin()[2]); k[0] = (sqr(ray.origin()[0])+ sqr(ray.origin()[1])+ sqr(ray.origin()[2])) - 1.0; } jNorm3 lclnormal( const jVec3& ix ) { return jNorm3(ix); } jVec2 uv( const jVec3& p ) { jFlt d = sqrt(p[0]*p[0]+p[1]*p[1]); jFlt v = 1.0-(p[2]+1.0)/2.0; jFlt u = p[0]<0 ? asin(fltabs(p[1])/d) : pi-asin(fltabs(p[1])/d); if(p[1] > 0) u = pi2-u; return jVec2(u/pi2,v); } }; class rtl_infcylinder : public rtl_quadric { public: rtl_infcylinder(); private: void coefficients( const rtl_ray& ray, jFlt* k ) { k[2] = sqr(ray.direction()[0]) + sqr(ray.direction()[2]); k[1] = 2*(ray.direction()[0]*ray.origin()[0] + ray.direction()[2]*ray.origin()[2]); k[0] = sqr(ray.origin()[0]) + sqr(ray.origin()[2]) - 1; } jNorm3 lclnormal( const jVec3& ix ) { return jNorm3(ix[0],0,ix[2]); } }; class rtl_infcone : public rtl_quadric { public: rtl_infcone(); private: void coefficients( const rtl_ray& ray, jFlt* k ) { k[2] = (sqr(ray.direction()[0]) - sqr(ray.direction()[1]) + sqr(ray.direction()[2])); k[1] = 2*(ray.direction()[0]*ray.origin()[0] - ray.direction()[1]*ray.origin()[1] + ray.direction()[2]*ray.origin()[2]); k[0] = (sqr(ray.origin()[0]) - sqr(ray.origin()[1]) + sqr(ray.origin()[2])); } inline jFlt lclintersect( const rtl_ray& ); jNorm3 lclnormal( const jVec3& ix ) { return jNorm3(ix[0],-ix[1],ix[2]); } }; #include "quadric.inl" #endif