metaforce/Runtime/Graphics/CLight.cpp

121 lines
3.5 KiB
C++
Raw Normal View History

#include "Runtime/Graphics/CLight.hpp"
2016-03-16 13:49:35 -07:00
#include <cfloat>
2016-03-04 15:04:53 -08:00
2018-12-07 21:30:43 -08:00
namespace urde {
2016-03-04 15:04:53 -08:00
constexpr zeus::CVector3f kDefaultPosition(0.f, 0.f, 0.f);
constexpr zeus::CVector3f kDefaultDirection(0.f, -1.f, 0.f);
2016-03-16 13:49:35 -07:00
2018-12-07 21:30:43 -08:00
float CLight::CalculateLightRadius() const {
if (x28_distL < FLT_EPSILON && x2c_distQ < FLT_EPSILON)
return FLT_MAX;
2016-03-16 13:49:35 -07:00
2018-12-07 21:30:43 -08:00
float intens = GetIntensity();
2016-03-16 13:49:35 -07:00
2018-12-07 21:30:43 -08:00
if (x2c_distQ > FLT_EPSILON) {
if (intens <= FLT_EPSILON)
return 0.f;
2019-01-22 23:52:19 -08:00
return std::sqrt(intens / (0.0588235f * x2c_distQ));
2018-12-07 21:30:43 -08:00
}
2016-03-16 13:49:35 -07:00
2019-01-22 23:52:19 -08:00
if (x28_distL > FLT_EPSILON)
return intens / (0.0588235f * x28_distL);
return 0.f;
2016-03-16 13:49:35 -07:00
}
2018-12-07 21:30:43 -08:00
float CLight::GetIntensity() const {
if (x4c_24_intensityDirty) {
x4c_24_intensityDirty = false;
2018-12-07 21:30:43 -08:00
float coef = 1.f;
if (x1c_type == ELightType::Custom) {
2018-12-07 21:30:43 -08:00
coef = x30_angleC;
}
x48_cachedIntensity = coef * std::max(x18_color.r(), std::max(x18_color.g(), x18_color.b()));
2018-12-07 21:30:43 -08:00
}
return x48_cachedIntensity;
2016-03-16 13:49:35 -07:00
}
2019-02-07 23:56:54 -08:00
float CLight::GetRadius() const {
if (x4c_25_radiusDirty) {
x44_cachedRadius = CalculateLightRadius();
x4c_25_radiusDirty = false;
2019-02-07 23:56:54 -08:00
}
return x44_cachedRadius;
}
2018-12-07 21:30:43 -08:00
CLight::CLight(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color, float distC,
float distL, float distQ, float angleC, float angleL, float angleQ)
: x0_pos(pos)
, xc_dir(dir)
, x18_color(color)
, x24_distC(distC)
, x28_distL(distL)
, x2c_distQ(distQ)
, x30_angleC(angleC)
, x34_angleL(angleL)
, x38_angleQ(angleQ)
, x4c_24_intensityDirty(true)
, x4c_25_radiusDirty(true) {}
CLight::CLight(ELightType type, const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color,
2016-04-03 19:32:57 -07:00
float cutoff)
2018-12-07 21:30:43 -08:00
: x0_pos(pos)
, xc_dir(dir)
, x18_color(color)
, x1c_type(type)
, x20_spotCutoff(cutoff)
, x4c_24_intensityDirty(true)
, x4c_25_radiusDirty(true) {
switch (type) {
case ELightType::Spot: {
const float cosCutoff = std::cos(zeus::degToRad(cutoff));
2018-12-07 21:30:43 -08:00
x30_angleC = 0.f;
x34_angleL = -cosCutoff / (1.0f - cosCutoff);
x38_angleQ = 1.f / (1.0f - cosCutoff);
2018-12-07 21:30:43 -08:00
break;
}
case ELightType::Directional: {
x24_distC = 1.f;
x28_distL = 0.f;
x2c_distQ = 0.f;
break;
}
default:
break;
}
2016-04-03 19:32:57 -07:00
}
2018-12-07 21:30:43 -08:00
zeus::CColor CLight::GetNormalIndependentLightingAtPoint(const zeus::CVector3f& point) const {
if (x1c_type == ELightType::LocalAmbient)
return x18_color;
2018-12-07 21:30:43 -08:00
float dist = std::max((x0_pos - point).magnitude(), FLT_EPSILON);
return x18_color * (1.f / (x2c_distQ * dist * dist + x28_distL * dist + x24_distC));
}
2018-12-07 21:30:43 -08:00
CLight CLight::BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color) {
return CLight(ELightType::Directional, kDefaultPosition, dir, color, 180.f);
2016-03-04 15:04:53 -08:00
}
2018-12-07 21:30:43 -08:00
CLight CLight::BuildSpot(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color,
float angle) {
return CLight(ELightType::Spot, pos, dir, color, angle);
2016-03-16 13:49:35 -07:00
}
2018-12-07 21:30:43 -08:00
CLight CLight::BuildPoint(const zeus::CVector3f& pos, const zeus::CColor& color) {
return CLight(ELightType::Point, pos, kDefaultDirection, color, 180.f);
2016-03-04 15:04:53 -08:00
}
2018-12-07 21:30:43 -08:00
CLight CLight::BuildCustom(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color,
float distC, float distL, float distQ, float angleC, float angleL, float angleQ) {
return CLight(pos, dir, color, distC, distL, distQ, angleC, angleL, angleQ);
2016-03-16 13:49:35 -07:00
}
2018-12-07 21:30:43 -08:00
CLight CLight::BuildLocalAmbient(const zeus::CVector3f& pos, const zeus::CColor& color) {
return CLight(ELightType::LocalAmbient, pos, kDefaultDirection, color, 180.f);
2016-03-04 15:04:53 -08:00
}
2018-12-07 21:30:43 -08:00
} // namespace urde