metaforce/Runtime/Graphics/CLight.cpp

119 lines
3.5 KiB
C++
Raw Normal View History

2016-03-04 23:04:53 +00:00
#include "CLight.hpp"
2016-03-16 20:49:35 +00:00
#include <cfloat>
2016-03-04 23:04:53 +00:00
namespace urde
{
2016-03-16 20:49:35 +00:00
static const zeus::CVector3f kDefaultPosition(0.f, 0.f, 0.f);
static const zeus::CVector3f kDefaultDirection(0.f, -1.f, 0.f);
float CLight::CalculateLightRadius() const
{
if (x28_distL < FLT_EPSILON && x2c_distQ < FLT_EPSILON)
return FLT_MAX;
float intens = GetIntensity();
if (x2c_distQ > FLT_EPSILON)
{
if (intens <= FLT_EPSILON)
return 0.f;
return std::sqrt(intens / 5.f * intens / 255.f * x2c_distQ);
}
float nextIntens = 5.f * intens / 255.f;
return intens / std::min(0.2f, nextIntens) * x28_distL;
}
float CLight::GetIntensity() const
{
if (x4c_24_intensityDirty)
{
((CLight*)this)->x4c_24_intensityDirty = false;
float coef = 1.f;
if (x1c_type == ELightType::Custom)
coef = x30_angleC;
((CLight*)this)->x48_cachedIntensity =
coef * std::max(x18_color.r, std::max(x18_color.g, x18_color.b));
}
return x48_cachedIntensity;
}
2016-04-04 02:32:57 +00: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),
x1c_type(ELightType::Custom), x20_spotCutoff(0.f),
x24_distC(distC), x28_distL(distL), x2c_distQ(distQ),
x30_angleC(angleC), x34_angleL(angleL), x38_angleQ(angleQ),
x44_cachedRadius(0.f), x48_cachedIntensity(0.f),
x4c_24_intensityDirty(true), x4c_25_radiusDirty(true)
{}
CLight::CLight(ELightType type,
const zeus::CVector3f& pos,
const zeus::CVector3f& dir,
const zeus::CColor& color,
float cutoff)
: x0_pos(pos), xc_dir(dir), x18_color(color),
x1c_type(type), x20_spotCutoff(cutoff),
2016-04-04 05:02:09 +00:00
x24_distC(1.f), x28_distL(0.f), x2c_distQ(0.f),
x30_angleC(1.f), x34_angleL(0.f), x38_angleQ(0.f),
2016-04-04 02:32:57 +00:00
x44_cachedRadius(0.f), x48_cachedIntensity(0.f),
x4c_24_intensityDirty(true), x4c_25_radiusDirty(true)
{
switch (type)
{
case ELightType::Spot:
{
float cosCutoff = std::cos(cutoff * M_PI / 180.0);
x30_angleC = 0.f;
x34_angleL = -cosCutoff / (1.0 - cosCutoff);
x38_angleQ = 1.f / (1.0 - cosCutoff);
break;
}
case ELightType::Directional:
{
x24_distC = 1.f;
x28_distL = 0.f;
x2c_distQ = 0.f;
break;
}
default: break;
}
}
2016-03-04 23:04:53 +00:00
CLight CLight::BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color)
{
2016-03-16 20:49:35 +00:00
return CLight(ELightType::Directional, kDefaultPosition, dir, color, 180.f);
2016-03-04 23:04:53 +00:00
}
CLight CLight::BuildSpot(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
const zeus::CColor& color, float angle)
{
2016-03-16 20:49:35 +00:00
return CLight(ELightType::Spot, pos, dir, color, angle);
}
CLight CLight::BuildPoint(const zeus::CVector3f& pos, const zeus::CColor& color)
{
return CLight(ELightType::Point, pos, kDefaultDirection, color, 180.f);
2016-03-04 23:04:53 +00:00
}
CLight CLight::BuildCustom(const zeus::CVector3f& pos, const zeus::CVector3f& dir,
2016-03-16 20:49:35 +00:00
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);
}
CLight CLight::BuildLocalAmbient(const zeus::CVector3f& pos, const zeus::CColor& color)
2016-03-04 23:04:53 +00:00
{
2016-03-16 20:49:35 +00:00
return CLight(ELightType::LocalAmbient, pos, kDefaultDirection, color, 180.f);
2016-03-04 23:04:53 +00:00
}
}