00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_RAYTRACER_OBJECT_H
00021 #define ARCHON_RAYTRACER_OBJECT_H
00022
00023 #include <string>
00024 #include <vector>
00025
00026 #include <archon/math/vector.H>
00027 #include <archon/math/coord_system.H>
00028 #include <archon/math/geometry.H>
00029
00030 #include "exception.H"
00031 #include "surface.H"
00032 #include "light.H"
00033
00034 namespace Archon
00035 {
00036 namespace Raytracer
00037 {
00038 using namespace std;
00039 using namespace Utilities;
00040 using namespace Math;
00041
00042 class Object
00043 {
00044 public:
00045 class Part
00046 {
00047 protected:
00048 const Surface *surface;
00049
00050 Part(const Surface *surface): surface(surface) {}
00051 virtual ~Part() {}
00052
00053 public:
00054 const Surface *getSurface() const { return surface; }
00055 virtual void map(const Vector3 &point, Vector3 &normal) const = 0;
00056 virtual void map(const Vector3 &point, Vector3 &normal,
00057 Vector2 &texturePoint) const = 0;
00058 };
00059
00060 virtual ~Object() {}
00061
00082 virtual bool intersect(const Line3 &ray,
00083 const Object *originObject,
00084 const Part *originPart,
00085 double &dist, const Part **p = 0) const = 0;
00086 };
00087
00088 class Solid: public Object
00089 {
00090 public:
00099 virtual void interiorIntersect(const Line3 &ray,
00100 const Part *originPart,
00101 double &dist,
00102 const Part *&p) const = 0;
00103 };
00104
00105
00106 class Plane: public Object, public Object::Part
00107 {
00108 CoordSystem3x3 invMap;
00109 Vector3 origin;
00110 Vector3 normal;
00111 public:
00112 Plane(const Surface *surface, const CoordSystem3x3 &s):
00113 Object::Part(surface), origin(s.origin), normal(s.basis.y)
00114 {
00115 invMap.setInverseOf(s);
00116 normal.normalize();
00117 }
00118
00119 bool intersect(const Line3 &ray, const Object *originObject,
00120 const Object::Part *originPart, double &dist,
00121 const Object::Part ** = 0) const;
00122
00123 void map(const Vector3 &point, Vector3 &normal) const;
00124 void map(const Vector3 &point, Vector3 &normal,
00125 Vector2 &texturePoint) const;
00126 };
00127
00128 class Cylinder: public Solid, private Object::Part
00129 {
00130 private:
00131 CoordSystem3x3 invMap;
00132 CoordSystem3x3 pointToNormalMap;
00133 Plane *topCap;
00134 Plane *bottomCap;
00135
00136 public:
00141 Cylinder(const Surface *surface, const CoordSystem3x3 &s);
00142 ~Cylinder();
00143
00144 bool intersect(const Line3 &ray, const Object *originObject,
00145 const Object::Part *originPart, double &dist,
00146 const Object::Part ** = 0) const;
00147
00148 void interiorIntersect(const Line3 &ray,
00149 const Object::Part *originPart,
00150 double &dist, const Object::Part *&) const;
00151
00152 void map(const Vector3 &point, Vector3 &normal) const
00153 {
00154 normal = pointToNormalMap(point);
00155 normal.normalize();
00156 }
00157
00158 void map(const Vector3 &point, Vector3 &normal,
00159 Vector2 &texturePoint) const;
00160 };
00161
00162 class Sphere: public Solid, private Object::Part
00163 {
00164 CoordSystem3x3 invMap;
00165 CoordSystem3x3 pointToNormalMap;
00166
00167 public:
00172 Sphere(const Surface *surface, const CoordSystem3x3 &s):
00173 Object::Part(surface)
00174 {
00175 invMap.setInverseOf(s);
00176 pointToNormalMap = invMap;
00177 pointToNormalMap.basis.transpose();
00178 pointToNormalMap.basis.map(pointToNormalMap.origin);
00179 pointToNormalMap.basis *= invMap.basis;
00180 }
00181
00182 ~Sphere() {}
00183
00184 bool intersect(const Line3 &ray, const Object *originObject,
00185 const Object::Part *originPart, double &dist,
00186 const Object::Part ** = 0) const;
00187
00188 void interiorIntersect(const Line3 &ray,
00189 const Object::Part *originPart,
00190 double &dist, const Object::Part *&) const;
00191
00192 void map(const Vector3 &point, Vector3 &normal) const
00193 {
00194 normal = pointToNormalMap(point);
00195 normal.normalize();
00196 }
00197
00198 void map(const Vector3 &point, Vector3 &normal,
00199 Vector2 &texturePoint) const;
00200 };
00201
00205 class Torus: public Solid, private Object::Part
00206 {
00207 private:
00208 CoordSystem3x3 invMap;
00209 Matrix3x3 normalMap;
00210 double majorRadius, minorRadius;
00211
00212 public:
00213 Torus(const Surface *surface, const CoordSystem3x3 &s,
00214 double majorRadius, double minorRadius):
00215 Object::Part(surface),
00216 majorRadius(majorRadius), minorRadius(minorRadius)
00217 {
00218 invMap.setInverseOf(s);
00219 normalMap = invMap.basis;
00220 normalMap.transpose();
00221 }
00222
00223 ~Torus() {}
00224
00225 bool intersect(const Line3 &ray, const Object *originObject,
00226 const Object::Part *originPart, double &dist,
00227 const Object::Part ** = 0) const;
00228
00229 void interiorIntersect(const Line3 &ray,
00230 const Object::Part *originPart,
00231 double &dist, const Object::Part *&) const;
00232
00233 void map(const Vector3 &point, Vector3 &normal) const;
00234
00235 void map(const Vector3 &point, Vector3 &normal,
00236 Vector2 &texturePoint) const;
00237 };
00238
00239
00243 class Polygon: public Object, private Object::Part
00244 {
00245 friend class ConvexPolyhedron;
00246
00247 private:
00248 vector<Vector3 *> vertexList;
00249 Vector3 normal;
00250
00251 Vector3 texMapX;
00252 Vector3 texMapY;
00253 Vector2 texMapOrigin;
00254
00255
00256
00257
00258
00259
00260
00261
00262 public:
00269
00270 Polygon(const Surface *surface,
00271 const vector<Vector3 *> &vertexList,
00272 const Vector2 &textureVertex1,
00273 const Vector2 &textureVertex2);
00274
00275 Polygon(const Surface *surface,
00276 const vector<Vector3 *> &vertexList,
00277 const Vector2 &textureVertex1,
00278 const Vector2 &textureVertex2,
00279 const Vector2 &textureVertex3);
00280
00281 ~Polygon() {}
00282
00283 bool intersect(const Line3 &ray, const Object *originObject,
00284 const Object::Part *originPart, double &dist,
00285 const Object::Part ** = 0) const;
00286
00287 bool backfaceIntersect(const Line3 &ray, const Object *originObject,
00288 const Object::Part *originPart, double &dist,
00289 const Object::Part ** = 0) const;
00290
00291 void map(const Vector3 &point, Vector3 &normal) const
00292 {
00293 normal = this->normal;
00294 }
00295
00296 void map(const Vector3 &point, Vector3 &normal,
00297 Vector2 &texturePoint) const;
00298 };
00299
00300
00301 class ConvexPolyhedron: public Solid
00302 {
00303 private:
00304 vector<Polygon *> polygonList;
00305 Sphere3 boundingVolume;
00306
00307 public:
00308
00309
00310
00311
00312 ConvexPolyhedron(const vector<Polygon *> &polygonList);
00313 ~ConvexPolyhedron();
00314
00315 bool intersect(const Line3 &ray, const Object *originObject,
00316 const Part *originPart, double &dist,
00317 const Object::Part ** = 0) const;
00318
00319 void interiorIntersect(const Line3 &ray,
00320 const Object::Part *originPart,
00321 double &dist, const Object::Part *&) const;
00322 };
00323 }
00324 }
00325
00326 #endif // ARCHON_RAYTRACER_OBJECT_H