aux.C

Go to the documentation of this file.
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 
00027 #include <GL/gl.h>
00028 
00029 #include <archon/x3d/server/field_type.H>
00030 #include <archon/x3d/server/field.H>
00031 #include <archon/x3d/server/aux.H>
00032 
00033 namespace Archon
00034 {
00035   namespace X3D
00036   {
00037     const NodeType *Torus::type = 0;  // Not a part of X3D
00038 
00039     void initializeAuxComponent()
00040     {
00041       vector<const FieldBase *> fields;
00042 
00043       // Torus
00044 
00045       fields.push_back(newPrivateField("majorRadius", SFFloat::type,
00046                                        &Torus::majorRadius));
00047       fields.push_back(newPrivateField("minorRadius", SFFloat::type,
00048                                        &Torus::minorRadius));
00049       Torus::type =
00050         NodeType::newConcrete("Torus", "geometry", Torus::instantiate, &fields,
00051                               Geometry3DNode::type);
00052       fields.clear();
00053     }
00054 
00055     int Torus::intersect(const Math::Ray3 &ray, double &dist) const
00056     {
00057       return Math::intersectTorus(ray, majorRadius, minorRadius, dist) ? 1 : 0;
00058     }
00059 
00063     void Torus::getNormalAndTexCoord(Vector3 hitPoint, int where,
00064                                      const Shape *,
00065                                      Vector3 *hitNormal,
00066                                      Vector2 *hitTexCoord) const
00067     {
00068       double a = sqrt(hitPoint[0]*hitPoint[0] + hitPoint[2]*hitPoint[2]);
00069       double b = a - majorRadius;
00070 
00071       if(hitTexCoord)
00072       {
00073         hitTexCoord->set(hitPoint[0] == 0 ? hitPoint[2] < 0 ? 0 : 0.5 :
00074                          (hitPoint[0] < 0 ? 0.25 : 0.75) -
00075                          atan(hitPoint[2]/hitPoint[0]) / (2 * M_PI),
00076                          hitPoint[1] == 0 ? b < 0 ? 0 : 0.5 :
00077                          (hitPoint[1] < 0 ? 0.25 : 0.75) -
00078                          atan(b/hitPoint[1]) / (2 * M_PI));
00079       }
00080 
00081       if(hitNormal)
00082       {
00083         b /= a;
00084         hitNormal->set(hitPoint[0]*b, hitPoint[1], hitPoint[2]*b);
00085       }
00086     }
00087 
00088     void renderNormals(const vector<Vector3> &, const RenderConfig *);
00089 
00090     void Torus::render(bool texture,
00091                        const Shape *shape,
00092                        const RenderConfig *config)
00093     {
00094       glFrontFace(GL_CW);
00095       glDisable(GL_COLOR_MATERIAL);
00096       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
00097       glEnable(GL_CULL_FACE);
00098 
00099       vector<Vector3> normals;
00100       const bool showNormals = config->showNormals;
00101 
00102       const int phiSteps = config->subdivision2;  // Around a section of the torus tube
00103       const int thetaSteps = config->subdivision1; // Around the hole
00104 
00105       vector<Vector3> nl(thetaSteps);
00106       vector<Vector3> vl(thetaSteps);
00107       vector<Vector3> fnl(thetaSteps);
00108       vector<Vector3> fvl(thetaSteps);
00109 
00110       for(int i=0; i<thetaSteps; ++i)
00111       {
00112         double texS = 1.0 / thetaSteps * i;
00113         double theta = 2 * M_PI * texS;
00114 
00115         double cos_theta = cos(theta);
00116         double sin_theta = sin(theta);
00117 
00118         fnl[i] = nl[i] = Vector3(sin_theta, 0, cos_theta);
00119         fvl[i] = vl[i] = nl[i] * (minorRadius - majorRadius);
00120       }
00121 
00122       double prevTexT = 0;
00123       Vector3 v;
00124 
00125       for(int i=1; i<phiSteps; ++i)
00126       {
00127         glBegin(GL_QUAD_STRIP);
00128 
00129         const Vector3 pvl0 = vl[0];
00130         const Vector3 pnl0 = nl[0];
00131 
00132         double texT = 1.0 / phiSteps * i;
00133         double phi = 2 * M_PI * texT;
00134 
00135         double cos_phi = cos(phi);
00136         double sin_phi = sin(phi);
00137 
00138         double a = majorRadius - minorRadius * cos_phi;
00139         double b = -minorRadius * sin_phi;
00140 
00141         for(int j=0; j<thetaSteps; ++j)
00142         {
00143           double texS = 1.0 / thetaSteps * j;
00144           double theta = 2 * M_PI * texS;
00145 
00146           double cos_theta = cos(theta);
00147           double sin_theta = sin(theta);
00148 
00149           if(texture) glTexCoord2d(texS, prevTexT);
00150           v = nl[j];
00151           glNormal3d(v[0], v[1], v[2]);
00152           v = vl[j];
00153           glVertex3d(v[0], v[1], v[2]);
00154           if(showNormals)
00155           {
00156             normals.push_back(v);
00157             normals.push_back(nl[j]);
00158           }
00159 
00160           if(texture) glTexCoord2d(texS, texT);
00161           v = nl[j] = Vector3(cos_phi*sin_theta, -sin_phi, cos_phi*cos_theta);
00162           glNormal3d(v[0], v[1], v[2]);
00163           v = vl[j] = Vector3(-sin_theta * a, b, -cos_theta * a);
00164           glVertex3d(v[0], v[1], v[2]);
00165         }
00166 
00167         if(texture) glTexCoord2d(1, prevTexT);
00168         glNormal3d(pnl0[0], pnl0[1], pnl0[2]);
00169         glVertex3d(pvl0[0], pvl0[1], pvl0[2]);
00170 
00171         if(texture) glTexCoord2d(1, texT);
00172         v = nl[0];
00173         glNormal3d(v[0], v[1], v[2]);
00174         v = vl[0];
00175         glVertex3d(v[0], v[1], v[2]);
00176 
00177         prevTexT = texT;
00178 
00179         glEnd();
00180       }
00181 
00182       glBegin(GL_QUAD_STRIP);
00183 
00184       for(int i=0; i<thetaSteps; ++i)
00185       {
00186         double texS = 1.0 / thetaSteps * i;
00187 
00188         if(texture) glTexCoord2d(texS, prevTexT);
00189         v = nl[i];
00190         glNormal3d(v[0], v[1], v[2]);
00191         v = vl[i];
00192         glVertex3d(v[0], v[1], v[2]);
00193         if(showNormals)
00194         {
00195           normals.push_back(v);
00196           normals.push_back(nl[i]);
00197         }
00198 
00199         if(texture) glTexCoord2d(texS, 1);
00200         v = fnl[i];
00201         glNormal3d(v[0], v[1], v[2]);
00202         v = fvl[i];
00203         glVertex3d(v[0], v[1], v[2]);
00204       }
00205 
00206       if(texture) glTexCoord2d(1, prevTexT);
00207       v = nl[0];
00208       glNormal3d(v[0], v[1], v[2]);
00209       v = vl[0];
00210       glVertex3d(v[0], v[1], v[2]);
00211 
00212       if(texture) glTexCoord2d(1, 1);
00213       v = fnl[0];
00214       glNormal3d(v[0], v[1], v[2]);
00215       v = fvl[0];
00216       glVertex3d(v[0], v[1], v[2]);
00217 
00218       glEnd();
00219 
00220       if(showNormals) renderNormals(normals, config);
00221     }
00222   }
00223 }

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