#ifndef SPHERE_H #define SPHERE_H #include "entity.h" #include "lin_alg.h" #include "texture_sph.h" class Sphere : public Entity { public: Sphere(const vector3d¢er = vec_zero, double radius = 0.0) { c = center; r = radius; unitx = unit_x; unity = unit_y; unitz = unit_z; texture = 0; } virtual ~Sphere() {} virtual RayIntersect CalcRayIntersect(Ray ray, int flags, int special=-1); virtual vector3d CalcNormal(Ray ray, RayIntersect& ri); virtual void PathCompress(const Transform&, queue >&, vector&); virtual int IntersectionTest(Ray ray, int flags, int special=-1); virtual void GridCollect(vector& vec) { EntityWrapBound ewb; ewb.E = this; ewb.lo = c - vec_one * r; ewb.hi = c + vec_one * r; vec.push_back(ewb); } void SetCenter(const vector3d& v) {c = v;} void SetRadius(double v) {r = v;} void SetTexture(texture_image* T) {texture = T;} virtual Color GetTextureColor(Ray ray, RayIntersect& ri); virtual bool HasTexture() {return (bool)texture;} void SetTextureX(const vector3d& v) {unitx = v.ret_unit();} void SetTextureY(const vector3d& v) {unity = v.ret_unit();} void SetTextureZ(const vector3d& v) {unitz = v.ret_unit();} void ComputeTextureX() {unitx = unity.cross(unitz);} void ComputeTextureY() {unity = unitz.cross(unitx);} void ComputeTextureZ() {unitz = unitx.cross(unity);} private: vector3d c; double r; vector3d unitx, unity, unitz; // for textures texture_image * texture; }; inline void Sphere::PathCompress(const Transform&T, queue >&Q, vector&V) { Sphere * sp = new Sphere(*this); sp->c = T * c; sp->r = r * pow(fabs(T.rot.Det()), 1.0/3.0); sp->unitx = (T.rot * unitx).ret_unit(); sp->unity = (T.rot * unity).ret_unit(); sp->unitz = (T.rot * unitz).ret_unit(); V.push_back(sp); } #endif