text: /*=========================================================================
  
    Program:   Visualization Toolkit
    Module:    vtkLight.h
  
    Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
    All rights reserved.
    See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
  
       This software is distributed WITHOUT ANY WARRANTY; without even
       the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
       PURPOSE.  See the above copyright notice for more information.
  
  =========================================================================*/
  /**
   * @class   vtkLight
   * @brief   a virtual light for 3D rendering
   *
   * vtkLight is a virtual light for 3D rendering. It provides methods to locate
   * and point the light, turn it on and off, and set its brightness and color.
   * In addition to the basic infinite distance point light source attributes,
   * you also can specify the light attenuation values and cone angle.
   * These attributes are only used if the light is a positional light.
   * The default is a directional light (e.g. infinite point light source).
   *
   * Lights have a type that describes how the light should move with respect
   * to the camera.  A Headlight is always located at the current camera position
   * and shines on the camera's focal point.  A CameraLight also moves with
   * the camera, but may not be coincident to it.  CameraLights are defined
   * in a normalized coordinate space where the camera is located at (0, 0, 1),
   * the camera is looking at (0, 0, 0), and up is (0, 1, 0).  Finally, a
   * SceneLight is part of the scene itself and does not move with the camera.
   * (Renderers are responsible for moving the light based on its type.)
   *
   * Lights have a transformation matrix that describes the space in which
   * they are positioned.  A light's world space position and focal point
   * are defined by their local position and focal point, transformed by
   * their transformation matrix (if it exists).
  */
  
  #ifndef vtkLight_h
  #define vtkLight_h
  
  #include "vtkRenderingCoreModule.h" // For export macro
  #include "vtkObject.h"
  
  /* need for virtual function */
  class vtkInformation;
  class vtkRenderer;
  class vtkMatrix4x4;
  
  #define VTK_LIGHT_TYPE_HEADLIGHT    1
  #define VTK_LIGHT_TYPE_CAMERA_LIGHT 2
  #define VTK_LIGHT_TYPE_SCENE_LIGHT  3
  
  class VTKRENDERINGCORE_EXPORT vtkLight : public vtkObject
  {
  public:
    vtkTypeMacro(vtkLight,vtkObject);
    void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE;
  
    /**
     * Create a light with the focal point at the origin and its position
     * set to (0,0,1). The light is a SceneLight, its color is white
     * (black ambient, white diffuse, white specular),
     * intensity=1, the light is turned on, positional lighting is off,
     * ConeAngle=30, AttenuationValues=(1,0,0), Exponent=1 and the
     * TransformMatrix is NULL.
     */
    static vtkLight *New();
  
    /**
     * Create a new light object with the same light parameters than the current
     * object (any ivar from the superclasses (vtkObject and vtkObjectBase),
     * like reference counting, timestamp and observers are not copied).
     * This is a shallow clone (TransformMatrix is referenced)
     */
    virtual vtkLight *ShallowClone();
  
    /**
     * Abstract interface to renderer. Each concrete subclass of vtkLight
     * will load its data into the graphics system in response to this method
     * invocation. The actual loading is performed by a vtkLightDevice
     * subclass, which will get created automatically.
     */
    virtual void Render(vtkRenderer *, int) {}
  
    //@{
    /**
     * Set/Get the color of the light. It is possible to set the ambient,
     * diffuse and specular colors separately. The SetColor() method sets
     * the diffuse and specular colors to the same color (this is a feature
     * to preserve backward compatbility.)
     */
    vtkSetVector3Macro(AmbientColor,double);
    vtkGetVectorMacro(AmbientColor,double,3);
    vtkSetVector3Macro(DiffuseColor,double);
    vtkGetVectorMacro(DiffuseColor,double,3);
    vtkSetVector3Macro(SpecularColor,double);
    vtkGetVectorMacro(SpecularColor,double,3);
    void SetColor(double, double, double);
    void SetColor(const double a[3]) { this->SetColor(a[0], a[1], a[2]); }
    //@}
  
    //@{
    /**
     * Set/Get the position of the light.
     * Note: The position of the light is defined in the coordinate
     * space indicated by its transformation matrix (if it exists).
     * Thus, to get the light's world space position, use
     * vtkGetTransformedPosition() instead of vtkGetPosition().
     */
    vtkSetVector3Macro(Position,double);
    vtkGetVectorMacro(Position,double,3);
    void SetPosition(const float *a) {this->SetPosition(a[0],a[1],a[2]);};
    //@}
  
    //@{
    /**
     * Set/Get the point at which the light is shining.
     * Note: The focal point of the light is defined in the coordinate
     * space indicated by its transformation matrix (if it exists).
     * Thus, to get the light's world space focal point, use
     * vtkGetTransformedFocalPoint() instead of vtkGetFocalPoint().
     */
    vtkSetVector3Macro(FocalPoint,double);
    vtkGetVectorMacro(FocalPoint,double,3);
    void SetFocalPoint(const float *a) {this->SetFocalPoint(a[0],a[1],a[2]);};
    //@}
  
    //@{
    /**
     * Set/Get the brightness of the light (from one to zero).
     */
    vtkSetMacro(Intensity,double);
    vtkGetMacro(Intensity,double);
    //@}
  
    //@{
    /**
     * Turn the light on or off.
     */
    vtkSetMacro(Switch,int);
    vtkGetMacro(Switch,int);
    vtkBooleanMacro(Switch,int);
    //@}
  
    //@{
    /**
     * Turn positional lighting on or off.
     */
    vtkSetMacro(Positional,int);
    vtkGetMacro(Positional,int);
    vtkBooleanMacro(Positional,int);
    //@}
  
    //@{
    /**
     * Set/Get the exponent of the cosine used in positional lighting.
     */
    vtkSetClampMacro(Exponent,double,0.0,128.0);
    vtkGetMacro(Exponent,double);
    //@}
  
    //@{
    /**
     * Set/Get the lighting cone angle of a positional light in degrees.
     * This is the angle between the axis of the cone and a ray along the edge of
     * the cone.
     * A value of 180 indicates that you want no spot lighting effects
     * just a positional light.
     */
    vtkSetMacro(ConeAngle,double);
    vtkGetMacro(ConeAngle,double);
    //@}
  
    //@{
    /**
     * Set/Get the quadratic attenuation constants. They are specified as
     * constant, linear, and quadratic, in that order.
     */
    vtkSetVector3Macro(AttenuationValues,double);
    vtkGetVectorMacro(AttenuationValues,double,3);
    //@}
  
    //@{
    /**
     * Set/Get the light's transformation matrix.  If a matrix is set for
     * a light, the light's parameters (position and focal point) are
     * transformed by the matrix before being rendered.
     */
    virtual void SetTransformMatrix(vtkMatrix4x4*);
    vtkGetObjectMacro(TransformMatrix,vtkMatrix4x4);
    //@}
  
    //@{
    /**
     * Get the position of the light, modified by the transformation matrix
     * (if it exists).
     */
    void GetTransformedPosition(double &a0, double &a1, double &a2);
    void GetTransformedPosition(double a[3]);
    double *GetTransformedPosition();
    //@}
  
    //@{
    /**
     * Get the focal point of the light, modified by the transformation matrix
     * (if it exists).
     */
    void GetTransformedFocalPoint(double &a0, double &a1, double &a2);
    void GetTransformedFocalPoint(double a[3]);
    double *GetTransformedFocalPoint();
    //@}
  
    //@{
    /**
     * Set the position and focal point of a light based on elevation and
     * azimuth.  The light is moved so it is shining from the given angle.
     * Angles are given in degrees.  If the light is a
     * positional light, it is made directional instead.
     */
    void SetDirectionAngle(double elevation, double azimuth);
    void SetDirectionAngle(const double ang[2]) {
      this->SetDirectionAngle(ang[0], ang[1]); };
    //@}
  
    /**
     * Perform deep copy of this light.
     */
    void DeepCopy(vtkLight *light);
  
    //@{
    /**
     * Set/Get the type of the light.
     * A SceneLight is a light located in the world coordinate space.  A light
     * is initially created as a scene light.
  
     * A Headlight is always located at the camera and is pointed at the
     * camera's focal point.  The renderer is free to modify the position and
     * focal point of the camera at any time.
  
     * A CameraLight is also attached to the camera, but is not necessarily
     * located at the camera's position.  CameraLights are defined in a
     * coordinate space where the camera is located at (0, 0, 1), looking
     * towards (0, 0, 0) at a distance of 1, with up being (0, 1, 0).
  
     * Note: Use SetLightTypeToSceneLight, rather than SetLightType(3), since
     * the former clears the light's transform matrix.
     */
    vtkSetMacro(LightType, int);
    vtkGetMacro(LightType, int);
    void SetLightTypeToHeadlight()
      {this->SetLightType(VTK_LIGHT_TYPE_HEADLIGHT);}
    void SetLightTypeToSceneLight()
    {
      this->SetTransformMatrix(nullptr);
      this->SetLightType(VTK_LIGHT_TYPE_SCENE_LIGHT);
    }
    void SetLightTypeToCameraLight()
      {this->SetLightType(VTK_LIGHT_TYPE_CAMERA_LIGHT);}
    //@}
  
    //@{
    /**
     * Query the type of the light.
     */
    int LightTypeIsHeadlight();
    int LightTypeIsSceneLight();
    int LightTypeIsCameraLight();
    //@}
  
    void ReadSelf(istream& is);
    void WriteSelf(ostream& os);
  
    //@{
    /**
     * Set/Get the shadow intensity
     * By default a light will be completely blocked when in shadow
     * by setting this value to less than 1.0 you can control how much
     * light is attenuated when in shadow
     */
    vtkSetMacro(ShadowAttenuation,float);
    vtkGetMacro(ShadowAttenuation,float);
    //@}
  
    //@{
    /**
     * Set/Get the information object associated with the light.
     */
    vtkGetObjectMacro(Information, vtkInformation);
    virtual void SetInformation(vtkInformation*);
    //@}
  
  protected:
    vtkLight();
    ~vtkLight() VTK_OVERRIDE;
  
    double FocalPoint[3];
    double Position[3];
    double Intensity;
    double AmbientColor[3];
    double DiffuseColor[3];
    double SpecularColor[3];
    int    Switch;
    int    Positional;
    double Exponent;
    double ConeAngle;
    double AttenuationValues[3];
    vtkMatrix4x4 *TransformMatrix;
    double TransformedFocalPointReturn[3];
    double TransformedPositionReturn[3];
    int    LightType;
    float  ShadowAttenuation;
  
    // Arbitrary extra information associated with this light.
    vtkInformation* Information;
  
  private:
    vtkLight(const vtkLight&) VTK_DELETE_FUNCTION;
    void operator=(const vtkLight&) VTK_DELETE_FUNCTION;
  };
  
  #endif
  