kicad/3d-viewer/3d_rendering/raytracing/light.h

149 lines
4.5 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file light.h
* @brief Declare and implement light sources.
*/
#ifndef LIGHT_H
#define LIGHT_H
#include "ray.h"
#include "hitinfo.h"
/**
* A base light class to derive to implement other light classes.
*/
class LIGHT
{
public:
LIGHT() { m_castShadow = true; }
virtual ~LIGHT() {}
/**
* Get parameters from this light.
*
* @param aHitPoint: input hit position
* @param aOutVectorToLight a vector that points from the hit
* position in direction to the light
* @param aOutLightColor the color of this light
* @param aOutDistance the distance from the point to the light
*/
virtual void GetLightParameters( const SFVEC3F& aHitPoint, SFVEC3F& aOutVectorToLight,
SFVEC3F& aOutLightColor, float& aOutDistance ) const = 0;
void SetCastShadows( bool aCastShadow ) { m_castShadow = aCastShadow; }
bool GetCastShadows() const { return m_castShadow; }
protected:
bool m_castShadow;
};
/**
* Point light source based on http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html.
*/
class POINT_LIGHT : public LIGHT
{
public:
POINT_LIGHT( const SFVEC3F& aPos, const SFVEC3F& aColor )
{
m_position = aPos;
m_color = aColor;
m_att_constant = 0.9f;
m_att_linear = 0.0005f;
m_att_exp = 0.001f;
m_castShadow = true;
}
// Imported functions from LIGHT
void GetLightParameters( const SFVEC3F& aHitPoint, SFVEC3F& aOutVectorToLight,
SFVEC3F& aOutLightColor, float& aOutDistance ) const override
{
const SFVEC3F vectorLight = m_position - aHitPoint;
aOutDistance = glm::length( vectorLight );
aOutVectorToLight = vectorLight / aOutDistance; // normalize
const float att = 1.0f / ( m_att_constant +
m_att_linear * aOutDistance +
m_att_exp * aOutDistance * aOutDistance );
if( att <= 0.0f )
aOutLightColor = SFVEC3F( 0.0f, 0.0f, 0.0f );
else
aOutLightColor = m_color * att;
}
private:
SFVEC3F m_position;
SFVEC3F m_color;
float m_att_constant;
float m_att_linear;
float m_att_exp;
};
/**
* A light source based only on a directional vector.
*/
class DIRECTIONAL_LIGHT : public LIGHT
{
public:
DIRECTIONAL_LIGHT( const SFVEC3F& aDir, const SFVEC3F& aColor )
{
// Invert light direction and make sure it is normalized
m_inv_direction = glm::normalize( -aDir );
m_color = aColor;
m_castShadow = true; // Set as default to cast shadows
}
/**
* Set directional light orientation.
*
* @param aDir is the vector defining the direction of the light source.
*/
void SetDirection( const SFVEC3F& aDir ) { m_inv_direction = -aDir; }
// Imported functions from LIGHT
void GetLightParameters( const SFVEC3F& /* aHitPoint */, SFVEC3F& aOutVectorToLight,
SFVEC3F& aOutLightColor, float& aOutDistance ) const override
{
aOutVectorToLight = m_inv_direction;
aOutDistance = std::numeric_limits<float>::infinity();
aOutLightColor = m_color;
}
private:
SFVEC3F m_inv_direction; ///< opposite direction of the light
SFVEC3F m_color; ///< light color
};
#endif // LIGHT_H