Match CLight, has issues with constants

Former-commit-id: b039acfac8
This commit is contained in:
Phillip Stephens 2022-10-06 01:40:00 -07:00
parent 7f30b385b2
commit ec9e639009
7 changed files with 268 additions and 51 deletions

View File

@ -77,11 +77,11 @@ lbl_80306090:
/* 803060C0 00303020 D0 01 00 0C */ stfs f0, 0xc(r1)
/* 803060C4 00303024 48 00 E7 F5 */ bl Magnitude__9CVector3fCFv
/* 803060C8 00303028 FC 40 08 18 */ frsp f2, f1
/* 803060CC 0030302C C0 02 C7 78 */ lfs f0, lbl_805AE498@sda21(r2)
/* 803060CC 0030302C C0 02 C7 78 */ lfs f0, gkEpsilon32@sda21(r2)
/* 803060D0 00303030 D0 21 00 08 */ stfs f1, 8(r1)
/* 803060D4 00303034 FC 02 00 40 */ fcmpo cr0, f2, f0
/* 803060D8 00303038 40 80 00 0C */ bge lbl_803060E4
/* 803060DC 0030303C 38 62 C7 78 */ addi r3, r2, lbl_805AE498@sda21
/* 803060DC 0030303C 38 62 C7 78 */ addi r3, r2, gkEpsilon32@sda21
/* 803060E0 00303040 48 00 00 08 */ b lbl_803060E8
lbl_803060E4:
/* 803060E4 00303044 38 61 00 08 */ addi r3, r1, 8
@ -491,15 +491,15 @@ __sinit_CLight_cpp:
.section .sdata2, "a"
.balign 8
.global lbl_805AE498
lbl_805AE498:
.global gkEpsilon32
gkEpsilon32:
# ROM: 0x3FAD38
.float 1.1920929E-7
.global lbl_805AE49C
lbl_805AE49C:
# ROM: 0x3FAD3C
.4byte 0x3B808081
.float 0.003921569
.global lbl_805AE4A0
lbl_805AE4A0:
@ -514,7 +514,7 @@ lbl_805AE4A4:
.global lbl_805AE4A8
lbl_805AE4A8:
# ROM: 0x3FAD48
.4byte 0
.float 0.0
.global lbl_805AE4AC
lbl_805AE4AC:
@ -524,10 +524,9 @@ lbl_805AE4AC:
.global lbl_805AE4B0
lbl_805AE4B0:
# ROM: 0x3FAD50
.4byte 0x7C1071DB
.float 3.0E36
.global lbl_805AE4B4
lbl_805AE4B4:
# ROM: 0x3FAD54
.4byte 0x43340000
.float 180.0

View File

@ -1,6 +1,82 @@
#ifndef __CLIGHT_HPP__
#define __CLIGHT_HPP__
class CLight {};
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/Math/CVector3f.hpp"
enum ELightType {
kLT_Spot = 0,
kLT_Point = 1,
kLT_Directional = 2,
kLT_LocalAmbient = 3,
kLT_Custom = 4,
};
enum EFallofType { kFT_Constant, kFT_Linear, kFT_Quadratic };
class CLight {
static const CVector3f kDefaultPosition;
static const CVector3f kDefaultDirection;
float CalculateLightRadius() const;
public:
CLight(ELightType type, const CVector3f& position, const CVector3f& direction,
const CColor& color, float cutoff);
CLight(const CVector3f& pos, const CVector3f& direction, const CColor& color, float distC,
float distL, float distQ, float angleC, float angleL, float angleQ);
void SetPosition(const CVector3f& pos);
const CVector3f& GetPosition() const { return x0_pos; }
void SetDirection(const CVector3f& dir);
const CVector3f& GetDirection() const { return xc_dir; }
void SetColor(const CColor& col);
void SetAttenuation(float constant, float linear, float quadratic);
float GetSpotCutoff() const { return x20_spotCutoff; }
float GetAttenuationConstant() const { return x24_distC; }
float GetAttenuationLinear() const { return x28_distL; }
float GetAttenuationQuadratic() const { return x2c_distQ; }
void SetAngleAttenuation(float constant, float linear, float quadratic);
float GetAngleAttenuationConstant() const { return x30_angleC; }
float GetAngleAttenuationLinear() const { return x34_angleL; }
float GetAngleAttenuationQuadratic() const { return x38_angleQ; }
ELightType GetType() const { return x1c_type; }
u32 GetId() const { return x40_lightId; }
float GetIntensity() const;
float GetRadius() const;
const CColor& GetColor() const { return x18_color; }
CVector3f GetNormalIndependentLightingAtPoint(const CVector3f& point) const;
static CLight BuildDirectional(const CVector3f& dir, const CColor& color);
static CLight BuildSpot(const CVector3f& pos, const CVector3f& dir, const CColor& color,
float cutoff);
static CLight BuildPoint(const CVector3f& pos, const CColor& color);
static CLight BuildCustom(const CVector3f& pos, const CVector3f& dir, const CColor& color,
float distC, float distL, float distQ, float angleC, float angleL,
float angleQ);
static CLight BuildLocalAmbient(const CVector3f& pos, const CColor& color);
private:
CVector3f x0_pos;
CVector3f xc_dir;
CColor x18_color;
ELightType x1c_type;
f32 x20_spotCutoff;
f32 x24_distC;
f32 x28_distL;
f32 x2c_distQ;
f32 x30_angleC;
f32 x34_angleL;
f32 x38_angleQ;
uint x3c_priority;
uint x40_lightId;
mutable f32 x44_cachedRadius;
mutable f32 x48_cachedIntensity;
mutable bool x4c_24_intensityDirty : 1;
mutable bool x4c_25_radiusDirty : 1;
};
CHECK_SIZEOF(CLight, 0x50)
#endif // __CLIGHT_HPP__

View File

@ -265,10 +265,10 @@ public:
void SetRotation(const CQuaternion& rot) {
SetTransform(rot.BuildTransform4f(GetTranslation()));
}
const CQuaternion& GetRotation() const {
CQuaternion GetRotation() const {
return CQuaternion::FromMatrix(GetTransform());
}
const CVector3f& GetTranslation() const { return x34_transform.GetTranslation(); }
CVector3f GetTranslation() const { return x34_transform.GetTranslation(); }
void SetTranslation(const CVector3f& vec);
CTransform4f GetLocatorTransform(const rstl::string& segName) const;
CTransform4f GetScaledLocatorTransform(const rstl::string& segName) const;

View File

@ -6,40 +6,11 @@
#include "MetroidPrime/TGameTypes.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/Graphics/CLight.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "rstl/reserved_vector.hpp"
enum ELightType {
kLT_Spot = 0,
kLT_Point = 1,
kLT_Directional = 2,
kLT_LocalAmbient = 3,
kLT_Custom = 4,
};
class CLight {
private:
CVector3f x0_pos;
CVector3f xc_dir;
CColor x18_color;
ELightType x1c_type;
f32 x20_spotCutoff;
f32 x24_distC;
f32 x28_distL;
f32 x2c_distQ;
f32 x30_angleC;
f32 x34_angleL;
f32 x38_angleQ;
uint x3c_priority;
uint x40_lightId;
mutable f32 x44_cachedRadius;
mutable f32 x48_cachedIntensity;
mutable bool x4c_24_intensityDirty : 1;
mutable bool x4c_25_radiusDirty : 1;
};
CHECK_SIZEOF(CLight, 0x50)
class CGameArea;
class CStateManager;
class CAABox;

View File

@ -101,11 +101,17 @@ public:
const CVector3f& GetConstantForceWR() const { return xfc_constantForce; }
void SetConstantForceWR(const CVector3f& force) { xfc_constantForce = force; }
const CAxisAngle& GetAngularMomentumWR() const { return x108_angularMomentum; }
void SetAngularMomentumWR(const CAxisAngle& angularMomentum) { x108_angularMomentum = angularMomentum; }
const CVector3f& GetMomentumWR() const { return x150_momentum; }
void SetMomentumWR(const CVector3f& momentum) { x150_momentum = momentum; }
const CVector3f& GetForceWR() const { return x15c_force; }
void SetForceWR(const CVector3f& force) { x15c_force = force; }
const CVector3f& GetImpulseWR() const { return x168_impulse; }
void SetImpulseWR(const CVector3f& impulse) { x168_impulse = impulse; }
const CAxisAngle& GetTorqueWR() const { return x174_torque; }
void SetTorqueWR(const CAxisAngle& torque) { x174_torque = torque; }
const CAxisAngle& GetAngularImpulseWR() const { return x180_angularImpulse; }
void SetAngularImpulseWR(const CAxisAngle& angularImpulse) { x180_angularImpulse = angularImpulse; }
CPhysicsState GetPhysicsState() const;
void SetPhysicsState(const CPhysicsState& state);
@ -121,6 +127,9 @@ public:
void SetMovable(bool v) { xf8_24_movable = v; }
void MoveToWR(const CVector3f&, float);
void MoveToInOneFrameWR(const CVector3f&, float);
CVector3f GetMoveToORImpulseWR(const CVector3f& impulse, float d) const;
CAxisAngle GetRotateToORAngularMomentumWR(const CQuaternion& q, float d) const;
void RotateToWR(const CQuaternion&, float);
void MoveToOR(const CVector3f&, float);

View File

@ -0,0 +1,149 @@
#include "Kyoto/Graphics/CLight.hpp"
#include "Kyoto/Math/CMath.hpp"
#include "rstl/math.hpp"
const CVector3f CLight::kDefaultPosition(0.f, 0.f, 0.f);
const CVector3f CLight::kDefaultDirection(0.f, -1.f, 0.f);
static const float gkEpsilon32 = FLT_EPSILON;
CLight::CLight(ELightType type, const CVector3f& position, const CVector3f& direction,
const CColor& color, float cutoff)
: x0_pos(position)
, xc_dir(direction)
, x18_color(color)
, x1c_type(type)
, x20_spotCutoff(cutoff)
, x24_distC(0.f)
, x28_distL(1.f)
, x2c_distQ(0.f)
, x30_angleC(0.f)
, x34_angleL(1.f)
, x38_angleQ(0.f)
, x3c_priority(0)
, x40_lightId(0)
, x44_cachedRadius(0.f)
, x48_cachedIntensity(0.f)
, x4c_24_intensityDirty(true)
, x4c_25_radiusDirty(true) {}
CLight::CLight(const CVector3f& position, const CVector3f& direction, const CColor& color,
float distC, float distL, float distQ, float angleC, float angleL, float angleQ)
: x0_pos(position)
, xc_dir(direction)
, x18_color(color)
, x1c_type(kLT_Custom)
, x20_spotCutoff(0.f)
, x24_distC(distC)
, x28_distL(distL)
, x2c_distQ(distQ)
, x30_angleC(angleC)
, x34_angleL(angleL)
, x38_angleQ(angleQ)
, x3c_priority(0)
, x40_lightId(0)
, x44_cachedRadius(0.f)
, x48_cachedIntensity(0.f)
, x4c_24_intensityDirty(true)
, x4c_25_radiusDirty(true) {}
CLight CLight::BuildLocalAmbient(const CVector3f& pos, const CColor& col) {
return CLight(kLT_LocalAmbient, pos, kDefaultDirection, col, 180.f);
}
CLight CLight::BuildDirectional(const CVector3f& direction, const CColor& col) {
return CLight(kLT_Directional, kDefaultPosition, direction, col, 180.f);
}
CLight CLight::BuildPoint(const CVector3f& pos, const CColor& color) {
return CLight(kLT_Point, pos, kDefaultDirection, color, 180.f);
}
CLight CLight::BuildSpot(const CVector3f& pos, const CVector3f& dir, const CColor& color,
float cutoff) {
return CLight(kLT_Spot, pos, dir, color, cutoff);
}
CLight CLight::BuildCustom(const CVector3f& pos, const CVector3f& dir, const 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);
}
void CLight::SetAttenuation(float constant, float linear, float quadratic) {
x24_distC = constant;
x28_distL = linear;
x2c_distQ = quadratic;
x4c_25_radiusDirty = true;
x4c_24_intensityDirty = true;
}
void CLight::SetAngleAttenuation(float constant, float linear, float quadratic) {
x30_angleC = constant;
x34_angleL = linear;
x38_angleQ = quadratic;
x4c_25_radiusDirty = true;
x4c_24_intensityDirty = true;
}
void CLight::SetColor(const CColor& col) {
x18_color = col;
x4c_25_radiusDirty = true;
x4c_24_intensityDirty = true;
}
void CLight::SetPosition(const CVector3f& position) { x0_pos = position; }
void CLight::SetDirection(const CVector3f& direction) { xc_dir = direction; }
float CLight::GetRadius() const {
if (x4c_25_radiusDirty) {
x44_cachedRadius = CalculateLightRadius();
x4c_25_radiusDirty = false;
}
return x44_cachedRadius;
}
float CLight::CalculateLightRadius() const {
if (x28_distL < gkEpsilon32 && x2c_distQ < gkEpsilon32) {
return FLT_MAX;
}
float intensity = GetIntensity();
float ret = 0.f;
if (x2c_distQ > gkEpsilon32) {
const float mulVal = rstl::min_val(0.05882353f, 0.2f); // Yes, retro really did do this
if (intensity > gkEpsilon32) {
ret = CMath::SqrtF(intensity / (mulVal * x2c_distQ));
}
} else {
const float mulVal = rstl::min_val(0.05882353f, 0.2f); // See above comment
if (x28_distL > gkEpsilon32) {
ret = intensity / (mulVal * x28_distL);
}
}
return ret;
}
float CLight::GetIntensity() const {
if (x4c_24_intensityDirty) {
x4c_24_intensityDirty = false;
float coef = 1.f;
if (x1c_type == kLT_Custom) {
coef = x30_angleC;
}
x48_cachedIntensity = coef * rstl::max_val(x18_color.GetRed(), rstl::max_val(x18_color.GetGreen(), x18_color.GetBlue()));
}
return x48_cachedIntensity;
}
CVector3f CLight::GetNormalIndependentLightingAtPoint(const CVector3f& point) const {
CVector3f floatCol(x18_color.GetRed(), x18_color.GetGreen(), x18_color.GetBlue());
if (x1c_type == kLT_LocalAmbient)
return floatCol;
float dist = rstl::max_val((x0_pos - point).Magnitude(), gkEpsilon32);
return floatCol * (1.f / (dist * (x2c_distQ * dist) + (x28_distL * dist + x24_distC)));
}

View File

@ -91,15 +91,16 @@ CPhysicsState CPhysicsActor::GetPhysicsState() const {
void CPhysicsActor::SetPhysicsState(const CPhysicsState& state) {
SetTranslation(state.GetTranslation());
const CQuaternion& quat = state.GetOrientationWR();
SetTransform(quat.BuildTransform4f(GetTranslation()));
xfc_constantForce = state.GetConstantForceWR();
x108_angularMomentum = state.GetAngularMomentumWR();
x150_momentum = state.GetMomentumWR();
x15c_force = state.GetForceWR();
x168_impulse = state.GetImpulseWR();
x174_torque = state.GetTorque();
x180_angularImpulse = state.GetAngularImpulseWR();
CQuaternion quat = state.GetOrientationWR();
CVector3f translation = GetTranslation();
SetTransform(quat.BuildTransform4f(translation));
SetConstantForceWR(state.GetConstantForceWR());
SetAngularMomentumWR(state.GetAngularMomentumWR());
SetMomentumWR(state.GetMomentumWR());
SetForceWR(state.GetForceWR());
SetImpulseWR(state.GetImpulseWR());
SetTorqueWR(state.GetTorque());
SetAngularImpulseWR(state.GetAngularImpulseWR());
ComputeDerivedQuantities();
}
@ -190,3 +191,15 @@ void CPhysicsActor::MoveToWR(const CVector3f& trans, float d) {
xfc_constantForce = (trans - GetTransform().GetTranslation()) * GetMass() * (1.f / d);
ComputeDerivedQuantities();
}
void CPhysicsActor::MoveToInOneFrameWR(const CVector3f& trans, float d) {
x18c_moveImpulse += (trans - GetTranslation()) * GetMass() * (1.f / d);
}
CVector3f CPhysicsActor::GetMoveToORImpulseWR(const CVector3f& trans, float d) const {
CVector3f impulse = x34_transform.Rotate(trans);
return (GetMass() * impulse) * (1.f / d);
}
CAxisAngle CPhysicsActor::GetRotateToORAngularMomentumWR(const CQuaternion& q, float d) const {}