2019-12-22 20:04:07 +00:00
|
|
|
#include "Runtime/World/CWorldLight.hpp"
|
2022-02-19 13:04:45 +00:00
|
|
|
#include "Runtime/Streams/IOStreams.hpp"
|
2019-12-22 20:04:07 +00:00
|
|
|
|
2017-10-25 07:47:49 +00:00
|
|
|
#include <cfloat>
|
2016-04-26 10:40:56 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce {
|
2016-04-26 10:40:56 +00:00
|
|
|
CWorldLight::CWorldLight(CInputStream& in)
|
2022-02-18 07:37:54 +00:00
|
|
|
: x0_type(EWorldLightType(in.ReadLong()))
|
|
|
|
, x4_color(in.Get<zeus::CVector3f>())
|
|
|
|
, x10_position(in.Get<zeus::CVector3f>())
|
|
|
|
, x1c_direction(in.Get<zeus::CVector3f>())
|
|
|
|
, x28_q(in.ReadFloat())
|
|
|
|
, x2c_cutoffAngle(in.ReadFloat())
|
|
|
|
, x30_(in.ReadFloat())
|
|
|
|
, x34_castShadows(in.ReadBool())
|
|
|
|
, x38_(in.ReadFloat())
|
|
|
|
, x3c_falloff(EFalloffType(in.ReadLong()))
|
|
|
|
, x40_(in.ReadFloat()) {}
|
2016-04-26 10:40:56 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
std::tuple<float, float, float> CalculateLightFalloff(EFalloffType falloff, float q) {
|
|
|
|
float constant = 0.f;
|
|
|
|
float linear = 0.f;
|
|
|
|
float quadratic = 0.f;
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (falloff == EFalloffType::Constant)
|
|
|
|
constant = 2.f / q;
|
|
|
|
else if (falloff == EFalloffType::Linear)
|
|
|
|
linear = 250.f / q;
|
|
|
|
else if (falloff == EFalloffType::Quadratic)
|
|
|
|
quadratic = 25000.f / q;
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
return {constant, linear, quadratic};
|
2017-01-21 15:46:51 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
CLight CWorldLight::GetAsCGraphicsLight() const {
|
|
|
|
zeus::CVector3f float_color = x4_color;
|
|
|
|
float q = x28_q;
|
|
|
|
if (q < FLT_EPSILON)
|
|
|
|
q = 0.000001f;
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (x0_type == EWorldLightType::LocalAmbient) {
|
|
|
|
float_color *= zeus::CVector3f(q);
|
|
|
|
if (float_color.x() >= 1.f)
|
|
|
|
float_color.x() = 1.f;
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (float_color.y() >= 1.f)
|
|
|
|
float_color.y() = 1.f;
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (float_color.z() >= 1.f)
|
|
|
|
float_color.z() = 1.f;
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
return CLight::BuildLocalAmbient(x10_position,
|
|
|
|
zeus::CColor(float_color.x(), float_color.y(), float_color.z(), 1.f));
|
|
|
|
} else if (x0_type == EWorldLightType::Directional) {
|
|
|
|
return CLight::BuildDirectional(x1c_direction, zeus::CColor{x4_color.x(), x4_color.y(), x4_color.z(), 1.f});
|
|
|
|
} else if (x0_type == EWorldLightType::Spot) {
|
|
|
|
CLight light =
|
|
|
|
CLight::BuildSpot(x10_position, x1c_direction.normalized(),
|
|
|
|
zeus::CColor{x4_color.x(), x4_color.y(), x4_color.z(), 1.f}, x2c_cutoffAngle * .5f);
|
2017-01-21 15:46:51 +00:00
|
|
|
|
2020-04-23 11:25:05 +00:00
|
|
|
const auto [constant, linear, quadratic] = CalculateLightFalloff(x3c_falloff, x28_q);
|
|
|
|
light.SetAttenuation(constant, linear, quadratic);
|
2018-12-08 05:30:43 +00:00
|
|
|
return light;
|
|
|
|
}
|
2020-04-23 11:25:05 +00:00
|
|
|
|
|
|
|
const auto [distC, distL, distQ] = CalculateLightFalloff(x3c_falloff, x28_q);
|
2018-12-08 05:30:43 +00:00
|
|
|
return CLight::BuildCustom(x10_position, zeus::CVector3f{0.f, 1.f, 0.f},
|
|
|
|
zeus::CColor{x4_color.x(), x4_color.y(), x4_color.z(), 1.f}, distC, distL, distQ, 1.f, 0.f,
|
|
|
|
0.f);
|
2016-04-26 10:40:56 +00:00
|
|
|
}
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce
|