CRenderObj.cpp

Go to the documentation of this file.
00001 
00015 #include <cmath>
00016 #include <sstream>
00017 #include <string>
00018 #include <vector>
00019 
00020 #include "popassert.h"
00021 #include "CColor.h"
00022 #include "CVector3f.h"
00023 #include "CVectBase.h"
00024 #include "compute.h"
00025 #include "CMathExpression.h"
00026 #include "CRenderObj.h"
00027 
00028 
00029 
00030 
00034 CRenderObj::CRenderObj()
00035   : m_FormulaString("z=10*x*y*exp(-x^2-y^2)"),
00036     m_MinVector(-2, -2, -2), m_MaxVector(2, 2, 2),
00037     m_ViewerPos(4, 0, 4),
00038     m_LightDirection(-1, -2, -3),
00039     m_SurfaceAmbientColor(0.15f, 0.15f, 0.3f),
00040     m_SurfaceDiffuseColor(0.35f, 0.35f, 0.7f),
00041     m_SurfaceSpecularColor(0.15f, 0.15f, 0.0f),
00042     m_BoxAmbientColor(0.15f, 0.15f, 0.15f),
00043     m_BoxDiffuseColor(0.35f, 0.35f, 0.35f),
00044     m_BoxSpecularColor(0, 0, 0),
00045     m_BackgroundColor(0.2f, 0.2f, 0.2f),
00046     m_CenterPos(0, 0, 0)
00047 {
00048   m_SignIncrement = 0.01f;
00049   m_NoSignIncrement = 0.001f;
00050   m_NoSignPrecision = 0.02f;
00051   m_Zoom = 0.0f;
00052 
00053   m_SurfaceSpecularExponent = 1.0f;
00054   m_BoxSpecularExponent = 1.0f;
00055 
00056   m_Options = OPTION_PERSPECTIVE | OPTION_BOUNDINGBOX | OPTION_SIGN;
00057   m_Width = 300;
00058   m_Height = 300;
00059 
00060   m_pFormula   = NULL;
00061   m_pFormulaDx = NULL;
00062   m_pFormulaDy = NULL;
00063   m_pFormulaDz = NULL;
00064 }
00065 
00066 
00067 
00072 void CRenderObj::Copy(const CRenderObj& obj)
00073 {
00074   m_FormulaString           = obj.m_FormulaString;
00075   m_MinVector               = obj.m_MinVector;
00076   m_MaxVector               = obj.m_MaxVector;
00077   m_ViewerPos               = obj.m_ViewerPos;
00078   m_LightDirection          = obj.m_LightDirection;
00079   m_SurfaceAmbientColor     = obj.m_SurfaceAmbientColor;
00080   m_SurfaceDiffuseColor     = obj.m_SurfaceDiffuseColor;
00081   m_SurfaceSpecularColor    = obj.m_SurfaceSpecularColor;
00082   m_SurfaceSpecularExponent = obj.m_SurfaceSpecularExponent;
00083   m_BoxAmbientColor         = obj.m_BoxAmbientColor;
00084   m_BoxDiffuseColor         = obj.m_BoxDiffuseColor;
00085   m_BoxSpecularColor        = obj.m_BoxSpecularColor;
00086   m_BoxSpecularExponent     = obj.m_BoxSpecularExponent;
00087   m_BackgroundColor         = obj.m_BackgroundColor;
00088   m_CenterPos               = obj.m_CenterPos;
00089   m_SignIncrement           = obj.m_SignIncrement;
00090   m_NoSignIncrement         = obj.m_NoSignIncrement;
00091   m_NoSignPrecision         = obj.m_NoSignPrecision;
00092   m_Zoom                    = obj.m_Zoom;
00093   m_Options                 = obj.m_Options;
00094   m_Width                   = obj.m_Width;
00095   m_Height                  = obj.m_Height;
00096 
00097   Update();
00098 }
00099 
00100 
00105 void CRenderObj::Update(void)
00106 {
00107   m_CenterPos = (m_MaxVector + m_MinVector) / 2;
00108   m_VectorBase.setRadius( (m_MaxVector - m_MinVector).Norm() / 2);
00109   m_VectorBase.setViewerPos(m_ViewerPos, false);
00110   m_VectorBase.setBoxPos(m_CenterPos);
00111 
00112   // Equation of the surface
00113   if (m_pFormula)
00114     {
00115       delete m_pFormula;
00116       m_pFormula = NULL;
00117     }
00118 
00119   if (CMathExpression::Validate(m_FormulaString))
00120     m_pFormula = new CMathExpression(m_FormulaString.c_str());
00121 
00122 
00123   // Derivative according to x
00124   if (m_pFormulaDx)
00125     {
00126       delete m_pFormulaDx;
00127       m_pFormulaDx = 0;
00128     }
00129 
00130   if (m_pFormula)
00131     m_pFormulaDx = m_pFormula->GetDerivative(CValue::TYPE_X);
00132       
00133 
00134   // Derivative according to y
00135   if (m_pFormulaDy)
00136     {
00137       delete m_pFormulaDy;
00138       m_pFormulaDy = 0;
00139     }
00140 
00141   if (m_pFormula)
00142     m_pFormulaDy = m_pFormula->GetDerivative(CValue::TYPE_Y);
00143 
00144 
00145   // Derivative according to z
00146   if (m_pFormulaDz)
00147     {
00148       delete m_pFormulaDz;
00149       m_pFormulaDz = 0;
00150     }
00151 
00152   if (m_pFormula)
00153     m_pFormulaDz = m_pFormula->GetDerivative(CValue::TYPE_Z);
00154 }
00155 
00156 
00157 
00162 std::string CRenderObj::Validate() const
00163 {
00164   // Check equation
00165   if (!CMathExpression::Validate(m_FormulaString))
00166     return ("The equation of the formula is not valid.");
00167 
00168 
00169   // Check floating point values
00170   if (m_SignIncrement <= 0)
00171     return ("Invalid SignIncrement");
00172   if (m_NoSignIncrement <= 0)
00173     return ("Invalid NoSignIncrement");
00174   if (m_NoSignPrecision <= 0)
00175     return ("Invalid NoSignPrecision");
00176   if (m_SurfaceSpecularExponent <= 0)
00177     return ("Invalid SurfaceSpecularExponent");
00178   if (m_BoxSpecularExponent <= 0)
00179     return ("Invalid BoxSpecularExponent");
00180 
00181 
00182   // Check for bounding box range
00183   if (m_MinVector.x >= m_MaxVector.x)
00184     return ("Error in the X range of the viewing volume.");
00185   if (m_MinVector.y >= m_MaxVector.y)
00186     return ("Error in the Y range of the viewing volume.");
00187   if (m_MinVector.z >= m_MaxVector.z)
00188     return ("Error in the Z range of the viewing volume.");
00189 
00190 
00191   // Check surface color
00192   // Ambient color
00193   if (m_SurfaceAmbientColor[0] < 0 || m_SurfaceAmbientColor[0] > 1)
00194     return ("The red component of the surface ambient "
00195             "color must be between 0 and 1");
00196   if (m_SurfaceAmbientColor[1] < 0 || m_SurfaceAmbientColor[1] > 1)
00197     return ("The green component of the surface ambient "
00198             "color must be between 0 and 1");
00199   if (m_SurfaceAmbientColor[2] < 0 || m_SurfaceAmbientColor[2] > 1)
00200     return ("The blue component of the surface ambient "
00201             "color must be between 0 and 1");
00202   if (m_SurfaceAmbientColor[3] < 0 || m_SurfaceAmbientColor[3] > 1)
00203     return ("The alpha component of the surface ambient "
00204             "color must be between 0 and 1");
00205 
00206   // Diffuse color
00207   if (m_SurfaceDiffuseColor[0] < 0 || m_SurfaceDiffuseColor[0] > 1)
00208     return ("The red component of the surface diffuse "
00209             "color must be between 0 and 1");
00210   if (m_SurfaceDiffuseColor[1] < 0 || m_SurfaceDiffuseColor[1] > 1)
00211     return ("The green component of the surface diffuse "
00212             "color must be between 0 and 1");
00213   if (m_SurfaceDiffuseColor[2] < 0 || m_SurfaceDiffuseColor[2] > 1)
00214     return ("The blue component of the surface diffuse "
00215             "color must be between 0 and 1");
00216   if (m_SurfaceDiffuseColor[3] < 0 || m_SurfaceDiffuseColor[3] > 1)
00217     return ("The alpha component of the surface diffuse "
00218             "color must be between 0 and 1");
00219 
00220   // Specular color
00221   if (m_SurfaceSpecularColor[0] < 0 || m_SurfaceSpecularColor[0] > 1)
00222     return ("The red component of the surface Specular "
00223             "color must be between 0 and 1");
00224   if (m_SurfaceSpecularColor[1] < 0 || m_SurfaceSpecularColor[1] > 1)
00225     return ("The green component of the surface Specular "
00226             "color must be between 0 and 1");
00227   if (m_SurfaceSpecularColor[2] < 0 || m_SurfaceSpecularColor[2] > 1)
00228     return ("The blue component of the surface Specular "
00229             "color must be between 0 and 1");
00230   if (m_SurfaceSpecularColor[3] < 0 || m_SurfaceSpecularColor[3] > 1)
00231     return ("The alpha component of the surface Specular "
00232             "color must be between 0 and 1");
00233 
00234 
00235   // Check box color
00236   // Ambient color
00237   if (m_BoxAmbientColor[0] < 0 || m_BoxAmbientColor[0] > 1)
00238     return ("The red component of the box ambient "
00239             "color must be between 0 and 1");
00240   if (m_BoxAmbientColor[1] < 0 || m_BoxAmbientColor[1] > 1)
00241     return ("The green component of the box ambient "
00242             "color must be between 0 and 1");
00243   if (m_BoxAmbientColor[2] < 0 || m_BoxAmbientColor[2] > 1)
00244     return ("The blue component of the box ambient "
00245             "color must be between 0 and 1");
00246   if (m_BoxAmbientColor[3] < 0 || m_BoxAmbientColor[3] > 1)
00247     return ("The alpha component of the box ambient "
00248             "color must be between 0 and 1");
00249 
00250   // Diffuse color
00251   if (m_BoxDiffuseColor[0] < 0 || m_BoxDiffuseColor[0] > 1)
00252     return ("The red component of the box diffuse "
00253             "color must be between 0 and 1");
00254   if (m_BoxDiffuseColor[1] < 0 || m_BoxDiffuseColor[1] > 1)
00255     return ("The green component of the box diffuse "
00256             "color must be between 0 and 1");
00257   if (m_BoxDiffuseColor[2] < 0 || m_BoxDiffuseColor[2] > 1)
00258     return ("The blue component of the box diffuse "
00259             "color must be between 0 and 1");
00260   if (m_BoxDiffuseColor[3] < 0 || m_BoxDiffuseColor[3] > 1)
00261     return ("The alpha component of the box diffuse "
00262             "color must be between 0 and 1");
00263 
00264   // Specular color
00265   if (m_BoxSpecularColor[0] < 0 || m_BoxSpecularColor[0] > 1)
00266     return ("The red component of the box specular "
00267             "color must be between 0 and 1");
00268   if (m_BoxSpecularColor[1] < 0 || m_BoxSpecularColor[1] > 1)
00269     return ("The green component of the box specular "
00270             "color must be between 0 and 1");
00271   if (m_BoxSpecularColor[2] < 0 || m_BoxSpecularColor[2] > 1)
00272     return ("The blue component of the box specular "
00273             "color must be between 0 and 1");
00274   if (m_BoxSpecularColor[3] < 0 || m_BoxSpecularColor[3] > 1)
00275     return ("The alpha component of the box specular "
00276             "color must be between 0 and 1");
00277 
00278 
00279   // Check background color
00280   if (m_BackgroundColor[0] < 0 || m_BackgroundColor[0] > 1)
00281     return ("The red component of the background "
00282             "color must be between 0 and 1");
00283   if (m_BackgroundColor[1] < 0 || m_BackgroundColor[1] > 1)
00284     return ("The green component of the background "
00285             "color must be between 0 and 1");
00286   if (m_BackgroundColor[2] < 0 || m_BackgroundColor[2] > 1)
00287     return ("The blue component of the background "
00288             "color must be between 0 and 1");
00289   if (m_BackgroundColor[3] < 0 || m_BackgroundColor[3] > 1)
00290     return ("The alpha component of the background "
00291             "color must be between 0 and 1");
00292 
00293 
00294   // Check for output image dimensions
00295   if (m_Width < 1)
00296     return ("Invalid witdh.");
00297   if (m_Height < 1)
00298     return ("Invalid height.");
00299 
00300   return ("");
00301 }
00302 
00303 
00304 
00314 CVector3f CRenderObj::GetDirection(int x, int y) const
00315 {
00316   if (m_Options & OPTION_PERSPECTIVE)
00317     {
00318       return (m_VectorBase.getB1()+
00319               2*m_VectorBase.getRadius()*
00320               (m_VectorBase.getB2()*(((float) x / (float) m_Width) - 0.5f) +
00321                m_VectorBase.getB3()*(0.5f - ((float) y / (float) m_Height))
00322                ) );
00323     }
00324   else
00325     {
00326       return m_VectorBase.getB1();
00327     }
00328 }
00329 
00330 
00341 CVector3f CRenderObj::GetStartingPoint(int x, int y) const
00342 {
00343   if (m_Options & OPTION_PERSPECTIVE)
00344     {
00345       return(m_ViewerPos - m_VectorBase.getB1() *
00346              (m_VectorBase.getRadius() / m_VectorBase.getB1().Norm() 
00347               * m_Zoom));
00348     }
00349   else
00350     {
00351       return (m_ViewerPos +
00352               2*m_VectorBase.getRadius()*
00353               (m_VectorBase.getB2()*(((float) x / (float) m_Width) - 0.5f) +
00354                m_VectorBase.getB3()*(0.5f - ((float) y / (float) m_Height))
00355                ) );
00356 
00357     }
00358 }
00359 
00360 
00361 
00366 void CRenderObj::GetCloseToBoundingBox(CVector3f& StartingPoint,
00367                                        const CVector3f& Direction) const
00368 {
00369   // Spacing when the ray is placed near the cube
00370   float Spacing = 2 *( (m_Options & OPTION_SIGN) ? 
00371                        m_SignIncrement : m_NoSignIncrement);
00372 
00373   // The ray is placed near the bounding box.  The nearest planed is
00374   // calculated three times and the ray is put at the nearest plane
00375   // (or doesn't move if it is already a face of the bounding box).
00376   if ( (StartingPoint.x > m_MaxVector.x) ||
00377        (StartingPoint.x < m_MinVector.x) ||
00378        (StartingPoint.y > m_MaxVector.y) ||
00379        (StartingPoint.y < m_MinVector.y) ||
00380        (StartingPoint.z > m_MaxVector.z) ||
00381        (StartingPoint.z < m_MinVector.z) )
00382     {
00383       for (int i = 0; i < 3; ++i)
00384         {
00385           float TempDistance;
00386           float StartingDistance = (m_CenterPos - StartingPoint).Norm();
00387 
00388           // plane: x = m_MinVector.x
00389           TempDistance = (m_MinVector.x - StartingPoint.x) / Direction.x;
00390           if ((TempDistance > 0) && (TempDistance < StartingDistance))
00391             StartingDistance = TempDistance;
00392 
00393           // plane: x = m_MaxVector.x
00394           TempDistance = (m_MaxVector.x - StartingPoint.x) / Direction.x;
00395           if ((TempDistance > 0) && (TempDistance < StartingDistance))
00396             StartingDistance = TempDistance;
00397 
00398           // plane: y = m_MinVector.y
00399           TempDistance = (m_MinVector.y - StartingPoint.y) / Direction.y;
00400           if ((TempDistance > 0) && (TempDistance < StartingDistance))
00401             StartingDistance = TempDistance;
00402 
00403           // plane: y = m_MaxVector.y
00404           TempDistance = (m_MaxVector.y - StartingPoint.y) / Direction.y;
00405           if ((TempDistance > 0) && (TempDistance < StartingDistance))
00406             StartingDistance = TempDistance;
00407 
00408           // plane: z = m_MinVector.z
00409           TempDistance = (m_MinVector.z - StartingPoint.z) / Direction.z;
00410           if ((TempDistance > 0) && (TempDistance < StartingDistance))
00411             StartingDistance = TempDistance;
00412 
00413           // plane: z = m_MaxVector.z
00414           TempDistance = (m_MaxVector.z - StartingPoint.z) / Direction.z;
00415           if ((TempDistance > 0) && (TempDistance < StartingDistance))
00416             StartingDistance = TempDistance;
00417 
00418           StartingPoint += StartingDistance * Direction;
00419 
00420           // If the end of the cube is reach, stop
00421           if ((StartingPoint.x < (m_MaxVector.x + Spacing)) &&
00422               (StartingPoint.x > (m_MinVector.x - Spacing)) &&
00423               (StartingPoint.y < (m_MaxVector.y + Spacing)) &&
00424               (StartingPoint.y > (m_MinVector.y - Spacing)) &&
00425               (StartingPoint.z < (m_MaxVector.z + Spacing)) &&
00426               (StartingPoint.z > (m_MinVector.z - Spacing)))
00427             {
00428               break;
00429             }
00430         }
00431     }
00432 }
00433 
00434 
00435 
00439 CColor CRenderObj::GetPixelColor(int x, int y) const
00440 {
00441   POP_ASSERT(m_pFormula != NULL, "Using a NULL pointer.");
00442   int StartingSign = 0;
00443   CVector3f Direction = GetDirection(x, y);
00444   Direction.Normalize();
00445   CVector3f StartingPoint = GetStartingPoint(x, y);
00446 
00447   bool Over = !(InBoundingBox(StartingPoint, Direction));
00448   bool Hit = false;
00449 
00450   // Step of the direction vector
00451   float VectInc;
00452 
00453   if (!Over)
00454     {
00455       GetCloseToBoundingBox(StartingPoint, Direction);
00456       Over = !(InBoundingBox(StartingPoint, Direction));
00457 
00458       if (m_Options & OPTION_SIGN)
00459         {
00460           if (m_pFormula->GetValue(StartingPoint) > 0)
00461             StartingSign = 1;
00462           else
00463             StartingSign = -1;
00464 
00465           VectInc = m_SignIncrement;
00466         }
00467       else
00468         {
00469           VectInc = m_NoSignIncrement;
00470         }
00471     }
00472 
00473   while (!Over)
00474     {
00475       // Check if the point is on the surface
00476       if (m_Options & OPTION_SIGN)
00477         Hit = (StartingSign * m_pFormula->GetValue(StartingPoint) < 0);
00478       else
00479         Hit = (fabs(m_pFormula->GetValue(StartingPoint)) < m_NoSignPrecision);
00480 
00481       if (Hit)
00482         {
00483           // If the point is on the surface, but no in the bounding
00484           // box, don't stop, but switch StartingSign.
00485           if ( !( (StartingPoint.x > m_MinVector.x) &&
00486                   (StartingPoint.x < m_MaxVector.x) &&
00487                   (StartingPoint.y > m_MinVector.y) &&
00488                   (StartingPoint.y < m_MaxVector.y) &&
00489                   (StartingPoint.z > m_MinVector.z) &&
00490                   (StartingPoint.z < m_MaxVector.z) ) )
00491             {
00492               StartingSign *= -1;
00493               Hit = false;
00494             }
00495           else
00496             {
00497               CVector3f Normal(m_pFormulaDx->GetValue(StartingPoint),
00498                                m_pFormulaDy->GetValue(StartingPoint),
00499                                m_pFormulaDz->GetValue(StartingPoint));
00500               if (Normal * Direction > 0)
00501                 Normal *= -1;
00502               Normal.Normalize();
00503 
00504               // Ambient color
00505               CColor ReturnColor = m_SurfaceAmbientColor;
00506 
00507               // Diffuse color
00508               float DiffuseFactor = - (m_LightDirection * Normal);
00509               if (DiffuseFactor > 0)
00510                 {
00511                   ReturnColor +=
00512                     m_SurfaceDiffuseColor * ( DiffuseFactor / 
00513                                               ( m_LightDirection.Norm()) ) ;
00514                 }
00515 
00516               // Specular color
00517               if (m_Options & OPTION_OPENGLSPECULAR)
00518                 {
00519                   if (m_LightDirection * Normal < 0)
00520                     {
00521                       CVector3f NewVect =
00522                         - m_LightDirection / m_LightDirection.Norm() -
00523                         Direction / Direction.Norm();
00524                       NewVect.Normalize();
00525 
00526                       float Fact = NewVect * Normal / Normal.Norm();
00527 
00528                       if (Fact > 0)
00529                         {
00530                           ReturnColor +=
00531                             m_SurfaceSpecularColor * 
00532                             pow(Fact, m_SurfaceSpecularExponent);
00533                         }
00534                     }
00535                 }
00536               else
00537                 {
00538                   CVector3f ReflectedRay =
00539                     2*(m_LightDirection * Normal) * Normal - m_LightDirection;
00540 
00541                   float SpecularFactor = ReflectedRay * Direction;
00542                   if (SpecularFactor > 0)
00543                     {
00544                       ReturnColor +=
00545                         m_SurfaceSpecularColor * pow( SpecularFactor /
00546                                                       ( ReflectedRay.Norm() *
00547                                                         Direction.Norm() ),
00548                                                       m_SurfaceSpecularExponent);
00549                     }
00550                 }
00551               return (ReturnColor);
00552             }
00553         }
00554 
00555       // Check to see if the point is close to a plane AND that it
00556       // is located between the minimum and maximum value of the
00557       // two other dimensions.
00558       if (m_Options & OPTION_BOUNDINGBOX)
00559         {
00560           CVector3f PlaneNormal;
00561           bool PlaneHit = false;
00562 
00563           if ( (fabs(StartingPoint.x - m_MinVector.x) < VectInc) &&
00564                (Direction.x < 0) &&
00565                (StartingPoint.y > m_MinVector.y) &&
00566                (StartingPoint.y < m_MaxVector.y) &&
00567                (StartingPoint.z > m_MinVector.z) &&
00568                (StartingPoint.z < m_MaxVector.z) )
00569             {
00570               PlaneNormal = CVector3f(-1, 0, 0);
00571               PlaneHit = true;
00572             }
00573           else if ( (fabs(StartingPoint.x - m_MaxVector.x) < VectInc) &&
00574                     (Direction.x > 0) &&
00575                     (StartingPoint.y > m_MinVector.y) &&
00576                     (StartingPoint.y < m_MaxVector.y) &&
00577                     (StartingPoint.z > m_MinVector.z) &&
00578                     (StartingPoint.z < m_MaxVector.z) )
00579             {
00580               PlaneNormal = CVector3f(1, 0, 0);
00581               PlaneHit = true;
00582             }
00583           else if ( (fabs(StartingPoint.y - m_MinVector.y) < VectInc) &&
00584                     (Direction.y < 0) &&
00585                     (StartingPoint.x > m_MinVector.x) &&
00586                     (StartingPoint.x < m_MaxVector.x) &&
00587                     (StartingPoint.z > m_MinVector.z) &&
00588                     (StartingPoint.z < m_MaxVector.z) )
00589             {
00590               PlaneNormal = CVector3f(0, -1, 0);
00591               PlaneHit = true;
00592             }
00593           else if ( (fabs(StartingPoint.y - m_MaxVector.y) < VectInc) &&
00594                     (Direction.y > 0) &&
00595                     (StartingPoint.x > m_MinVector.x) &&
00596                     (StartingPoint.x < m_MaxVector.x) &&
00597                     (StartingPoint.z > m_MinVector.z) &&
00598                     (StartingPoint.z < m_MaxVector.z) )
00599             {
00600               PlaneNormal = CVector3f(0, 1, 0);
00601               PlaneHit = true;
00602             }
00603           else if ( (fabs(StartingPoint.z - m_MinVector.z) < VectInc) &&
00604                     (Direction.z < 0) &&
00605                     (StartingPoint.x > m_MinVector.x) &&
00606                     (StartingPoint.x < m_MaxVector.x) &&
00607                     (StartingPoint.y > m_MinVector.y) &&
00608                     (StartingPoint.y < m_MaxVector.y) )
00609             {
00610               PlaneNormal = CVector3f(0, 0, -1);
00611               PlaneHit = true;
00612             }
00613           else if ( (fabs(StartingPoint.z - m_MaxVector.z) < VectInc) &&
00614                     (Direction.z > 0) &&
00615                     (StartingPoint.x > m_MinVector.x) &&
00616                     (StartingPoint.x < m_MaxVector.x) &&
00617                     (StartingPoint.y > m_MinVector.y) &&
00618                     (StartingPoint.y < m_MaxVector.y) )
00619             {
00620               PlaneNormal = CVector3f(0, 0, 1);
00621               PlaneHit = true;
00622             }
00623 
00624           if (PlaneHit)
00625             {
00626               // Ambient color
00627               CColor ReturnColor = m_BoxAmbientColor;
00628 
00629               // Diffuse color
00630               float PlaneDiffuseFactor = m_LightDirection * PlaneNormal;
00631               if (PlaneDiffuseFactor > 0)
00632                 {
00633                   ReturnColor +=
00634                     m_BoxDiffuseColor * ( PlaneDiffuseFactor /
00635                                           ( m_LightDirection.Norm()) ) ;
00636                 }
00637 
00638               // Specular color
00639               if (m_Options & OPTION_OPENGLSPECULAR)
00640                 {
00641                   if (m_LightDirection * PlaneNormal < 0)
00642                     {
00643                       CVector3f NewVect =
00644                         - m_LightDirection / m_LightDirection.Norm() -
00645                         Direction / Direction.Norm();
00646                       NewVect.Normalize();
00647 
00648                       float Fact = NewVect * PlaneNormal / PlaneNormal.Norm();
00649 
00650                       if (Fact > 0)
00651                         {
00652                           ReturnColor +=
00653                             m_BoxSpecularColor *
00654                             pow(Fact, m_BoxSpecularExponent);
00655                         }
00656                     }
00657                 }
00658               else
00659                 {
00660                   CVector3f ReflectedRay =
00661                     2*(m_LightDirection * PlaneNormal) * PlaneNormal -
00662                     m_LightDirection;
00663 
00664                   float SpecularFactor = ReflectedRay * Direction;
00665                   if (SpecularFactor > 0)
00666                     {
00667                       ReturnColor +=
00668                         m_BoxSpecularColor * pow( SpecularFactor /
00669                                                   ( ReflectedRay.Norm() *
00670                                                     Direction.Norm() ),
00671                                                   m_BoxSpecularExponent);
00672                     }
00673                 }
00674 
00675               return (ReturnColor);
00676             }
00677         }  // End of checking for the drawing of the bounding box.
00678 
00679       StartingPoint += Direction * VectInc;
00680 
00681       Over = !(InBoundingBox(StartingPoint, Direction));
00682     }
00683 
00684   return (m_BackgroundColor);
00685 }
00686 

Generated on Fri Dec 5 03:20:33 2008 for Mathematical Ray-tracer by  doxygen 1.5.4