opennurbs_light.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00017 
00018 ON_OBJECT_IMPLEMENT(ON_Light,ON_Geometry,"85A08513-F383-11d3-BFE7-0010830122F0");
00019 
00020 void ON_Light::Default()
00021 {
00022   m_light_name.Destroy();
00023   m_bOn = 1;
00024   m_intensity = 1.0;
00025   m_watts = 0.0;
00026   m_style =  ON::camera_directional_light;
00027   m_ambient = ON_Color(0,0,0);
00028   m_diffuse = ON_Color(255,255,255);
00029   m_specular = ON_Color(255,255,255);
00030   m_direction = ON_3dVector(0.0,0.0,-1.0);
00031   m_location = ON_3dPoint(0.0,0.0,0.0);
00032   m_length = ON_3dVector(0.0,0.0,0.0);
00033   m_width = ON_3dVector(0.0,0.0,0.0);
00034   m_spot_angle = 180.0;
00035   m_spot_exponent = 0.0;
00036   m_hotspot = 1.0;
00037   m_attenuation = ON_3dVector(1.0,0.0,0.0);
00038   m_shadow_intensity = 1.0;
00039   m_light_index = 0;
00040   memset(&m_light_id,0,sizeof(m_light_id));
00041 }
00042 
00043 ON_Light::ON_Light() 
00044 {
00045   Default();
00046 }
00047 
00048 ON_Light::~ON_Light()
00049 {
00050 }
00051 
00052 ON_BOOL32 ON_Light::IsValid( ON_TextLog* text_log ) const
00053 {
00054   int s = Style();
00055   if ( s <= ON::unknown_light_style || s >= ON::light_style_count ) {
00056     ON_ERROR("ON_Light::IsValid(): illegal light style.");
00057     return false;
00058   }
00059   return true;
00060 }
00061 
00062 void ON_Light::Dump( ON_TextLog& dump ) const
00063 {
00064   ON_BOOL32 bDumpDir = false;
00065   ON_BOOL32 bDumpLength = false;
00066   ON_BOOL32 bDumpWidth = false;
00067 
00068   const char* sStyle = "unknown";
00069   switch(Style())
00070   {
00071   //case ON::view_directional_light:
00072   //  sStyle = "view_directional_light";
00073   //  bDumpDir = true;
00074   //  break;
00075   //case ON::view_point_light:
00076   //  sStyle = "view_point_light";
00077   //  break;
00078   //case ON::view_spot_light:
00079   //  sStyle = "view_spot_light";
00080   //  bDumpDir = true;
00081   //  break;
00082   case ON::camera_directional_light:
00083     sStyle = "camera_directional_light";
00084     bDumpDir = true;
00085     break;
00086   case ON::camera_point_light:
00087     sStyle = "camera_point_light";
00088     break;
00089   case ON::camera_spot_light:
00090     sStyle = "camera_spot_light";
00091     bDumpDir = true;
00092     break;
00093   case ON::world_directional_light:
00094     sStyle = "world_directional_light";
00095     bDumpDir = true;
00096     break;
00097   case ON::world_point_light:
00098     sStyle = "world_point_light";
00099     break;
00100   case ON::world_spot_light:
00101     sStyle = "world_spot_light";
00102     bDumpDir = true;
00103     break;
00104   case ON::world_linear_light:
00105     sStyle = "linear_light";
00106     bDumpDir = true;
00107     bDumpLength = true;
00108     break;
00109   case ON::world_rectangular_light:
00110     sStyle = "rectangular_light";
00111     bDumpDir = true;
00112     bDumpLength = true;
00113     bDumpWidth = true;
00114     break;
00115   case ON::ambient_light:
00116     sStyle = "ambient_light";
00117     break;
00118   case ON::unknown_light_style:
00119     sStyle = "unknown";
00120     break;
00121   default:
00122     sStyle = "unknown";
00123     break;
00124   }
00125   dump.Print("index = %d  style = %s\n",LightIndex(),sStyle);
00126 
00127   dump.Print("location = "); dump.Print(Location()); dump.Print("\n");
00128   if ( bDumpDir )
00129     dump.Print("direction = "); dump.Print(Direction()); dump.Print("\n");
00130   if ( bDumpLength )
00131     dump.Print("length = "); dump.Print(Length()); dump.Print("\n");
00132   if ( bDumpWidth )
00133     dump.Print("width = "); dump.Print(Width()); dump.Print("\n");
00134 
00135   dump.Print("intensity = %g%%\n",Intensity()*100.0);
00136 
00137   dump.Print("ambient rgb = "); dump.PrintRGB(Ambient()); dump.Print("\n");
00138   dump.Print("diffuse rgb = "); dump.PrintRGB(Diffuse()); dump.Print("\n");
00139   dump.Print("specular rgb = "); dump.PrintRGB(Specular()); dump.Print("\n");
00140 
00141   dump.Print("spot angle = %g degrees\n",SpotAngleDegrees());
00142 }
00143 
00144 ON_BOOL32 ON_Light::Write(
00145        ON_BinaryArchive& file
00146      ) const
00147 {
00148   int i;
00149   ON_BOOL32 rc = file.Write3dmChunkVersion(1,2);
00150   // version 1.0 fields
00151   if ( rc ) rc = file.WriteInt( m_bOn );
00152   i = m_style;
00153   if ( rc ) rc = file.WriteInt( i );
00154   if ( rc ) rc = file.WriteDouble( m_intensity );
00155   if ( rc ) rc = file.WriteDouble( m_watts );
00156   if ( rc ) rc = file.WriteColor( m_ambient );
00157   if ( rc ) rc = file.WriteColor( m_diffuse );
00158   if ( rc ) rc = file.WriteColor( m_specular );
00159   if ( rc ) rc = file.WriteVector( m_direction );
00160   if ( rc ) rc = file.WritePoint( m_location );
00161   if ( rc ) rc = file.WriteDouble( m_spot_angle );
00162   if ( rc ) rc = file.WriteDouble( m_spot_exponent );
00163   if ( rc ) rc = file.WriteVector( m_attenuation );
00164   if ( rc ) rc = file.WriteDouble( m_shadow_intensity );
00165   if ( rc ) rc = file.WriteInt( m_light_index );
00166   if ( rc ) rc = file.WriteUuid( m_light_id );
00167   if ( rc ) rc = file.WriteString( m_light_name );
00168   // version 1.1 added support for linear and rectangular
00169   if ( rc ) rc = file.WriteVector( m_length );
00170   if ( rc ) rc = file.WriteVector( m_width );
00171   // version 1.2 added m_hotspot support
00172   if ( rc ) rc = file.WriteDouble( m_hotspot );
00173   return rc;
00174 }
00175 
00176 ON_BOOL32 ON_Light::Read(
00177        ON_BinaryArchive&  file
00178      )
00179 {
00180   Default();
00181   int major_version = 0;
00182   int minor_version = 0;
00183   ON_BOOL32 rc = file.Read3dmChunkVersion(&major_version,&minor_version);
00184   if ( rc && major_version == 1 ) {
00185     int i;
00186     // version 1.0 fields
00187     i = 0;
00188     if ( rc ) rc = file.ReadInt( &i );
00189     if ( rc ) Enable(i);
00190     if ( rc ) rc = file.ReadInt( &i );
00191     if ( rc ) SetStyle(ON::LightStyle(i));
00192     if ( rc ) rc = file.ReadDouble( &m_intensity );
00193     if ( rc ) rc = file.ReadDouble( &m_watts );
00194     if ( rc ) rc = file.ReadColor( m_ambient );
00195     if ( rc ) rc = file.ReadColor( m_diffuse );
00196     if ( rc ) rc = file.ReadColor( m_specular );
00197     if ( rc ) rc = file.ReadVector( m_direction );
00198     if ( rc ) rc = file.ReadPoint( m_location );
00199     if ( rc ) rc = file.ReadDouble( &m_spot_angle );
00200     if ( rc ) rc = file.ReadDouble( &m_spot_exponent );
00201     if ( rc ) rc = file.ReadVector( m_attenuation );
00202     if ( rc ) rc = file.ReadDouble( &m_shadow_intensity );
00203     if ( rc ) rc = file.ReadInt( &m_light_index );
00204     if ( rc ) rc = file.ReadUuid( m_light_id );
00205     if ( rc ) rc = file.ReadString( m_light_name );
00206 
00207     if ( minor_version < 2 ) {
00208       // set hotspot from 1.0 or 1.1 m_spot_exponent
00209       double h = 1.0 - m_spot_exponent/128.0;
00210       if ( h < 0.0 ) 
00211         h = 0.0;
00212       else if ( h > 1.0 )
00213         h = 1.0;
00214       m_hotspot = h;
00215       m_spot_exponent = 0.0;
00216     }
00217 
00218     if ( minor_version >= 1 ) {
00219       // version 1.1 fields
00220       if ( rc ) rc = file.ReadVector( m_length );
00221       if ( rc ) rc = file.ReadVector( m_width );
00222       if ( minor_version >= 2 ) {
00223         // version 1.2 fields
00224         if ( rc ) rc = file.ReadDouble( &m_hotspot );
00225       }
00226     }
00227   }
00228   return rc;
00229 }
00230 
00231 ON::object_type ON_Light::ObjectType() const
00232 {
00233   return ON::light_object;
00234 }
00235 
00236 int ON_Light::Dimension() const
00237 {
00238   return 3;
00239 }
00240 
00241 ON_BOOL32 ON_Light::GetBBox( // returns true if successful
00242        double* boxmin,    // boxmin[dim]
00243        double* boxmax,    // boxmax[dim]
00244        ON_BOOL32 bGrowBox
00245        ) const
00246 {
00247   bool rc = true;
00248   ON_3dPointArray points(16);
00249 
00250   switch(m_style)
00251   {
00252   case ON::camera_directional_light:
00253   case ON::world_directional_light:
00254     points.Append(m_location);
00255     points.Append(m_location+m_direction);
00256     break;
00257 
00258   case ON::camera_point_light:
00259   case ON::world_point_light:
00260     points.Append(m_location);
00261     break;
00262 
00263   case ON::camera_spot_light:
00264   case ON::world_spot_light:
00265     if ( m_spot_angle > 0.0 && m_spot_angle < 90.0 )
00266     {
00267       double r = m_direction.Length()*tan(ON_PI*m_spot_angle/180.0);
00268       ON_Circle c(ON_Plane(m_location+m_direction,m_direction),r);
00269       ON_BoundingBox cbox = c.BoundingBox();
00270       cbox.GetCorners( points );
00271     }
00272     else
00273     {
00274       points.Append(m_location+m_direction);
00275     }
00276     points.Append(m_location);
00277     break;
00278 
00279   case ON::ambient_light:
00280     points.Append(m_location);
00281     rc = false;
00282     break;
00283   
00284   case ON::world_linear_light:
00285     points.Append(m_location);
00286     points.Append(m_location+m_length);
00287     break;
00288 
00289   case ON::world_rectangular_light:
00290     points.Append(m_location);
00291     points.Append(m_location+m_length);
00292     points.Append(m_location+m_width);
00293     points.Append(m_location+m_width+m_length);
00294     {
00295       // include target and direction marker to avoid display clipping
00296       ON_3dPoint center(m_location+(m_width+m_length)*0.5);
00297       points.Append(center+m_direction);
00298       ON_3dVector marker(m_direction); 
00299       marker.Unitize();
00300       marker *= (m_width+m_length).Length()/12.0; // from GetRectangularLightSegments
00301       points.Append(center+marker);
00302     }
00303     break;
00304 
00305   default:
00306     rc = false;
00307     break;
00308   }
00309 
00310   if ( rc && points.Count() > 0 )
00311   {
00312      rc = ON_GetPointListBoundingBox( 3, 0, points.Count(), 3, 
00313                                       (double*)points.Array(), 
00314                                       boxmin, boxmax, 
00315                                       bGrowBox?true:false )
00316         ? true 
00317         : false;
00318   }
00319 
00320   return rc;
00321 }
00322 
00323 ON_BOOL32 ON_Light::Transform( 
00324        const ON_Xform& xform
00325        )
00326 {
00327   ON_3dVector v;
00328   double vlen;
00329   TransformUserData(xform);
00330   m_location = xform*m_location;
00331   
00332   v = xform*m_direction;
00333   vlen = v.Length();
00334   if ( vlen > 0.0 ) {
00335     m_direction = v;
00336   }
00337   
00338   v = xform*m_length;
00339   vlen = v.Length();
00340   if ( vlen > 0.0 ) {
00341     m_length = v;
00342   }
00343   
00344   v = xform*m_width;
00345   vlen = v.Length();
00346   if ( vlen > 0.0 ) {
00347     m_width = v;
00348   }
00349   return true;
00350 }
00351 
00352 ON_BOOL32 ON_Light::Enable(ON_BOOL32 b)
00353 {
00354   ON_BOOL32 oldb = m_bOn;
00355   m_bOn = (b)?true:false;
00356   return oldb;
00357 }
00358 
00359 ON_BOOL32 ON_Light::IsEnabled() const
00360 {
00361   return m_bOn;
00362 }
00363 
00364 ON::light_style ON_Light::Style() const
00365 {
00366   return m_style;
00367 }
00368 
00369 const ON_BOOL32 ON_Light::IsPointLight() const
00370 {
00371   ON_BOOL32 rc;
00372   switch(m_style)
00373   {
00374   //case ON::view_point_light:
00375   case ON::camera_point_light:
00376   case ON::world_point_light:
00377     rc = true;
00378     break;
00379   default:
00380     rc = false;
00381     break;
00382   }
00383   return rc;
00384 }
00385 
00386 const ON_BOOL32 ON_Light::IsDirectionalLight() const
00387 {
00388   ON_BOOL32 rc;
00389   switch(m_style)
00390   {
00391   //case ON::view_directional_light:
00392   case ON::camera_directional_light:
00393   case ON::world_directional_light:
00394     rc = true;
00395     break;
00396   default:
00397     rc = false;
00398     break;
00399   }
00400   return rc;
00401 }
00402 
00403 const ON_BOOL32 ON_Light::IsSpotLight() const
00404 {
00405   ON_BOOL32 rc;
00406   switch(m_style)
00407   {
00408   //case ON::view_spot_light:
00409   case ON::camera_spot_light:
00410   case ON::world_spot_light:
00411     rc = true;
00412     break;
00413   default:
00414     rc = false;
00415     break;
00416   }
00417   return rc;
00418 }
00419 
00420 const ON_BOOL32 ON_Light::IsLinearLight() const
00421 {
00422   ON_BOOL32 rc;
00423   switch(m_style)
00424   {
00425   //case ON::view_linear_light:
00426   //case ON::camera_linear_light:
00427   case ON::world_linear_light:
00428     rc = true;
00429     break;
00430   default:
00431     rc = false;
00432     break;
00433   }
00434   return rc;
00435 }
00436 
00437 const ON_BOOL32 ON_Light::IsRectangularLight() const
00438 {
00439   ON_BOOL32 rc;
00440   switch(m_style)
00441   {
00442   //case ON::view_rectangular_light:
00443   //case ON::camera_rectangular_light:
00444   case ON::world_rectangular_light:
00445     rc = true;
00446     break;
00447   default:
00448     rc = false;
00449     break;
00450   }
00451   return rc;
00452 }
00453 
00454 
00455 void ON_Light::SetStyle(ON::light_style s )
00456 {
00457   m_style = s;
00458 }
00459 
00460 void ON_Light::SetLightName( const char* s )
00461 {
00462   m_light_name = s;
00463   m_light_name.TrimLeftAndRight();
00464 }
00465 
00466 void ON_Light::SetLightName( const wchar_t* s )
00467 {
00468   m_light_name = s;
00469   m_light_name.TrimLeftAndRight();
00470 }
00471 
00472 const ON_wString& ON_Light::LightName() const
00473 {
00474   return m_light_name;
00475 }
00476 
00477 //void ON_Light::SetLightUuid( const ON_UUID& uuid )
00478 //{
00479 //  // m_light_id is set and maintained by Rhino - if your
00480 //  // plug-in is messing with this field, fix the plugin
00481 //  m_light_id = uuid;
00482 //}
00483 
00484 //const ON_UUID& ON_Light::LightUuid() const
00485 //{
00486 //  // m_light_id is set and maintained by Rhino - if your
00487 //  // plug-in is messing with this field, fix the plugin
00488 //  return m_light_id;
00489 //}
00490 
00491 
00492 void ON_Light::SetAttenuation(double a,double b,double c)
00493 {
00494   m_attenuation = ON_3dVector(a,b,c);;
00495 }
00496 
00497 void ON_Light::SetAttenuation(const ON_3dVector& att )
00498 {
00499   m_attenuation = att;
00500 }
00501 
00502 ON_3dVector ON_Light::Attenuation() const
00503 {
00504   return m_attenuation;
00505 }
00506 
00507 double ON_Light::Attenuation(double d) const
00508 {
00509   // computes 1/(a[0] + d*a[1] + d^2*a[2]) where d = argument
00510   // returns 0 if a[0] + d*a[1] + d^2*a[2] <= 0
00511   double a = m_attenuation.x + d*(m_attenuation.y + d*m_attenuation.z);
00512   if ( a > 0.0 )
00513     a = 1.0/a;
00514   else
00515     a = 0.0;
00516   return a;
00517 }
00518 
00520 //
00521 // spot light parameters (ignored for non-spot lights)
00522 //
00523 // angle = 0 to 90 degrees
00524 // exponent = 0 to 128 (0=uniform, 128=high focus)
00525 //
00526 void ON_Light::SetSpotAngleRadians( double a )
00527 {
00528   a *= 180.0/ON_PI;
00529   if ( a > 90.0 )
00530     m_spot_angle = 90.0;
00531   else if ( a > 0.0 )
00532     m_spot_angle = a;
00533 }
00534 
00535 double ON_Light::SpotAngleRadians() const
00536 {
00537   return m_spot_angle*ON_PI/180.0;
00538 }
00539 
00540 void ON_Light::SetSpotAngleDegrees( double a )
00541 {
00542   if ( a >= 90.0 )
00543     m_spot_angle = 90.0;
00544   else if ( a > 0.0 )
00545     m_spot_angle = a;
00546 }
00547 
00548 double ON_Light::SpotAngleDegrees() const
00549 {
00550   return m_spot_angle;
00551 }
00552 
00553 // The spot exponent "e", hot spot "h", and spotlight cone angle "a"
00554 // are mutually constrained by the formula
00555 //   cos(h*angle)^e = hotspot_min
00556 // where hotspot_min = value of spotlight exponential attenuation factor 
00557 // at the hot spot radius.  hotspot_min must be >0, < 1, and should be >= 1/2;
00558 //static double log_hotspot_min = log(0.5);
00559 static double log_hotspot_min = log(0.70710678118654752440084436210485);
00560 
00561 void ON_Light::SetSpotExponent( double e )
00562 {
00563   // cos(h)^e = 0.5
00564   if ( e < 0.0 || !ON_IsValid(e) )
00565     m_spot_exponent = 0.0;
00566   else
00567     m_spot_exponent = e;
00568   m_hotspot = ON_UNSET_VALUE; // indicates hotspot should be computed from m_spot_exponent
00569 }
00570 
00571 void ON_Light::SetHotSpot( double h )
00572 {
00573   if ( h == ON_UNSET_VALUE || !ON_IsValid(h) )
00574     m_hotspot = ON_UNSET_VALUE;
00575   else if ( h <= 0.0 ) 
00576     m_hotspot = 0.0;
00577   else if ( h >= 1.0 )
00578     m_hotspot = 1.0;
00579   else
00580     m_hotspot = h;
00581 }
00582 
00583 double ON_Light::SpotExponent() const
00584 {
00585   double e = m_spot_exponent;
00586   if ( m_hotspot >= 0.0 && m_hotspot <= 1.0 ) {
00587     // spotlight is using hot spot interface
00588     double h = m_hotspot;
00589     if ( h < 0.015 )
00590       h = 0.015;
00591     if ( h >= 1.0 || m_spot_angle <= 0.0 || m_spot_angle > 90.0)
00592       e = 0.0;
00593     else {
00594       // compute SpotExponent() from  cos(h*angle)^e = hotspot_min
00595       double a, c;
00596       a = h*SpotAngleRadians();
00597       c = cos(a);
00598       if ( c <= 0.0 )
00599         e = 1.0;
00600       else {
00601         e = log_hotspot_min/log(c);
00602         if ( e < 0.0 )
00603           e = 0.0;
00604       }
00605     }
00606   }
00607   return e;
00608 }
00609 
00610 double ON_Light::HotSpot() const
00611 {
00612   double h = m_hotspot;
00613   if ( h < 0.0 || h > 1.0 ) {
00614     // spotlight is using spot exponent interface
00615     if ( m_spot_exponent >= 65536.0 )
00616       h = 0.0;
00617     else if ( m_spot_exponent <= 0.0 || m_spot_angle <= 0.0 || m_spot_angle > 90.0 )
00618       h = 1.0;
00619     else {
00620       // compute HotSpot() from cos(h*angle)^e = hotspot_min
00621       double x, a, cos_ha;
00622       x = log_hotspot_min/m_spot_exponent; // note that x < 0.0
00623       if ( x < -690.0 ) {
00624         // prevent underflow.  cos_ha is close to zero so
00625         h = 1.0;
00626       }
00627       else 
00628       {
00629         cos_ha = exp(x);
00630         if (!ON_IsValid(cos_ha))  cos_ha =  0.0;
00631         else if ( cos_ha >  1.0 ) cos_ha =  1.0;
00632         else if ( cos_ha < -1.0 ) cos_ha = -1.0;
00633         a = SpotAngleRadians();
00634         h = acos(cos_ha)/a;
00635         if ( h < 0.0 )
00636           h = 0.0;
00637         else if ( h > 1.0 ) {
00638           // happens for smaller e
00639           h = 1.0;
00640         }
00641       }
00642     }
00643   }
00644   return h;
00645 }
00646 
00647 void ON_Light::SetLength( const ON_3dVector& v )
00648 {
00649   m_length = v;
00650 }
00651 
00652 ON_3dVector ON_Light::Length() const
00653 {
00654   return m_length;
00655 }
00656 
00657 void ON_Light::SetWidth( const ON_3dVector& v )
00658 {
00659   m_width = v;
00660 }
00661 
00662 ON_3dVector ON_Light::Width() const
00663 {
00664   return m_width;
00665 }
00666 
00667 
00668 void ON_Light::SetShadowIntensity(double s )
00669 {
00670   if ( s < 0.0 )
00671     s = 0.0;
00672   else if (s > 1.0 )
00673     s = 1.0;
00674   m_shadow_intensity = s;
00675 }
00676 
00677 double ON_Light::ShadowIntensity() const
00678 {
00679   return m_shadow_intensity;
00680 }
00681 
00682 void ON_Light::SetLightIndex( int i )
00683 {
00684   m_light_index = i;
00685 }
00686 
00687 int ON_Light::LightIndex() const
00688 {
00689   return m_light_index;
00690 }
00691 
00692 void ON_Light::SetAmbient(  ON_Color c )
00693 {
00694   m_ambient = c;
00695 }
00696 
00697 void ON_Light::SetDiffuse(  ON_Color c )
00698 {
00699   m_diffuse = c;
00700 }
00701 
00702 void ON_Light::SetSpecular( ON_Color c )
00703 {
00704   m_specular = c;;
00705 }
00706 
00707 ON_Color ON_Light::Ambient() const
00708 {
00709   return m_ambient;
00710 }
00711 
00712 ON_Color ON_Light::Diffuse() const
00713 {
00714   return m_diffuse;
00715 }
00716 
00717 ON_Color ON_Light::Specular() const
00718 {
00719   return m_specular;
00720 }
00721 
00722 ON::coordinate_system ON_Light::CoordinateSystem() const // determined by style
00723 {
00724   ON::coordinate_system cs = ON::world_cs;
00725   switch( m_style ) {
00726   case ON::unknown_light_style:
00727     cs = ON::world_cs;
00728     break;
00729   //case ON::view_directional_light:
00730   //case ON::view_point_light:
00731   //case ON::view_spot_light:
00732   //  cs = ON::clip_cs;
00733   //  break;
00734   case ON::camera_directional_light:
00735   case ON::camera_point_light:
00736   case ON::camera_spot_light:
00737     cs = ON::camera_cs;
00738     break;
00739   case ON::world_directional_light:
00740   case ON::world_point_light:
00741   case ON::world_spot_light:
00742   case ON::world_linear_light:
00743   case ON::world_rectangular_light:
00744   case ON::ambient_light:
00745     cs = ON::world_cs;
00746     break;
00747   default:
00748     cs = ON::world_cs;
00749     break;
00750   }
00751   return cs;
00752 }
00753 
00754 ON_BOOL32 ON_Light::GetLightXform( 
00755          const ON_Viewport& vp,
00756          ON::coordinate_system dest_cs, 
00757          ON_Xform& xform 
00758          ) const
00759 {
00760   ON::coordinate_system src_cs = CoordinateSystem();
00761   return vp.GetXform( src_cs, dest_cs, xform );
00762 }
00763 
00764 
00765 
00766 void ON_Light::SetLocation( const ON_3dPoint& loc )
00767 {
00768   m_location = loc;
00769 }
00770 
00771 void ON_Light::SetDirection( const ON_3dVector& dir )
00772 {
00773   m_direction = dir;
00774 }
00775 
00776 ON_3dPoint ON_Light::Location() const
00777 {
00778   return m_location;
00779 }
00780 
00781 ON_3dVector ON_Light::Direction() const
00782 {
00783   return m_direction;
00784 }
00785 
00786 ON_3dVector ON_Light::PerpindicularDirection() const
00787 {
00788   // returns a consistent vector perpendicular to the
00789   // light's direction.  This vector is useful for
00790   // user interface display.
00791   ON_3dVector dir = m_direction;
00792   if ( !dir.IsValid() || !dir.Unitize() )
00793     return ON_UNSET_VECTOR;
00794 
00795   ON_3dVector xdir;
00796   if ( IsLinearLight() || IsRectangularLight() )
00797   {
00798     xdir = m_length;
00799     if ( xdir.IsValid() && xdir.Unitize() && fabs(xdir*dir) <= ON_SQRT_EPSILON )
00800       return xdir;
00801   }
00802 
00803   if( dir.IsParallelTo( ON_zaxis, ON_DEGREES_TO_RADIANS * 3.0))
00804     xdir = ON_CrossProduct( dir, ON_xaxis);
00805   else
00806     xdir = ON_CrossProduct( dir, ON_zaxis);
00807   xdir.Unitize();
00808   ON_3dVector ydir = ON_CrossProduct(dir,xdir);
00809   ydir.Unitize();
00810   ON_3dVector right;
00811 
00812   switch(dir.MaximumCoordinateIndex())
00813   {
00814   case 0:
00815     right = (fabs(xdir.y) > fabs(ydir.y)) ? xdir : ydir;
00816     if ( right.y < 0.0 )
00817       right.Reverse();
00818     break;
00819   case 1:
00820   case 2:
00821     right = (fabs(xdir.x) > fabs(ydir.x)) ? xdir : ydir;
00822     if ( right.x < 0.0 )
00823       right.Reverse();
00824     break;
00825   default:
00826     right = xdir;
00827     break;
00828   }
00829 
00830   if ( right[right.MaximumCoordinateIndex()] < 0.0 )
00831     right.Reverse();
00832 
00833   return right;  
00834 }
00835 
00836 bool ON_Light::GetSpotLightRadii( double* inner_radius, double* outer_radius ) const
00837 {
00838   bool rc = IsSpotLight()?true:false;
00839   if (rc)
00840   {
00841     double angle = SpotAngleRadians();
00842     if ( !ON_IsValid(angle) || angle <= 0.0 || angle >= 0.5*ON_PI )
00843       angle = 0.25*ON_PI;
00844     double spot = HotSpot();
00845     if ( !ON_IsValid(spot) || spot < 0.0 || spot > 1.0 )
00846       spot = 0.5;
00847     double cone_height = Direction().Length();
00848     if ( !ON_IsValid(cone_height) || cone_height <= 0.0 )
00849       cone_height = 1.0;
00850 
00851     if ( outer_radius )
00852       *outer_radius = tan( angle) * cone_height;
00853     if ( inner_radius )
00854       *inner_radius = tan( angle * spot) * cone_height;
00855   }
00856   return rc;
00857 }
00858 
00859 
00860 
00861 double ON_Light::Intensity() const
00862 {
00863   // 0.0 = 0%  1.0 = 100%
00864   return m_intensity;
00865 }
00866 
00867 void ON_Light::SetIntensity(double v)
00868 {
00869   if ( v <= 0.0 )
00870     m_intensity = 0.0;
00871   else if (v >= 1.0 )
00872     m_intensity = 1.0;
00873   else
00874     m_intensity = v;
00875 }
00876 
00877 double ON_Light::PowerWatts() const
00878 {
00879   return m_watts;
00880 }
00881 
00882 double ON_Light::PowerLumens() const
00883 {
00884   return m_watts/683.0;
00885 }
00886 
00887 double ON_Light::PowerCandela() const
00888 {
00889   return m_watts/683.0;
00890 }
00891 
00892 void ON_Light::SetPowerWatts( double watts )
00893 {
00894   m_watts = (watts > 0.0) ? watts : 0.0;
00895 }
00896 
00897 void ON_Light::SetPowerLumens( double lumens )
00898 {
00899   m_watts = (lumens > 0.0) ? lumens*683.0 : 0.0;
00900 }
00901 
00902 void ON_Light::SetPowerCandela( double candela )
00903 {
00904   m_watts = (candela > 0.0) ? candela*683.0 : 0.0;
00905 }
00906 
00907 
00908 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:01