00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
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
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
00169 if ( rc ) rc = file.WriteVector( m_length );
00170 if ( rc ) rc = file.WriteVector( m_width );
00171
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
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
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
00220 if ( rc ) rc = file.ReadVector( m_length );
00221 if ( rc ) rc = file.ReadVector( m_width );
00222 if ( minor_version >= 2 ) {
00223
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(
00242 double* boxmin,
00243 double* boxmax,
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
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;
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
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
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
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
00426
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
00443
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
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
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
00510
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
00522
00523
00524
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
00554
00555
00556
00557
00558
00559 static double log_hotspot_min = log(0.70710678118654752440084436210485);
00560
00561 void ON_Light::SetSpotExponent( double e )
00562 {
00563
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;
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
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
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
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
00621 double x, a, cos_ha;
00622 x = log_hotspot_min/m_spot_exponent;
00623 if ( x < -690.0 ) {
00624
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
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
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
00730
00731
00732
00733
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
00789
00790
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
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