object.H

00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
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     // A thin X-Z plane
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; // The world coordinate system described in the coordinate system of the sphere
00132       CoordSystem3x3 pointToNormalMap; // The map that takes a world coordinate system point to the corresponding normal of the sphere surface.
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; // The world coordinate system described in the coordinate system of the sphere
00165       CoordSystem3x3 pointToNormalMap; // The map that takes a world coordinate system point to the corresponding normal of the sphere surface.
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; // The world coordinate system described in the coordinate system of the torus
00209       Matrix3x3 normalMap; // The map that takes a local normal to the corresponding normal in the global coordinate system.
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         Vector3 textureOrigin;
00257         Vector3 textureAxisX;
00258         Vector3 textureAxisY;
00259         double scaling;
00260       */
00261 
00262     public:
00269       // Unstretchable
00270       Polygon(const Surface *surface,
00271               const vector<Vector3 *> &vertexList,
00272               const Vector2 &textureVertex1,
00273               const Vector2 &textureVertex2);
00274       // Semi-stretchable (scale + skew) (works for triangles and parallelograms)
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        * The polyhedron is responsible for destroying the polygons that
00310        * are passed to the constructor.
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

Generated on Sun Jul 30 22:55:51 2006 for Archon by  doxygen 1.4.4