mirror of
https://github.com/zeldaret/ss
synced 2026-06-05 19:27:35 -04:00
eggLightObject good enough
This commit is contained in:
@@ -26621,9 +26621,9 @@ InitGX__Q23EGG11LightObjectCFP11_GXLightObj = .text:0x804A9D40; // type:function
|
||||
CopyToG3D_World__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObj = .text:0x804A9F40; // type:function size:0x150
|
||||
CopyToG3D_View__Q23EGG11LightObjectCFRQ34nw4r3g3d8LightObjRCQ34nw4r4math5MTX34 = .text:0x804AA090; // type:function size:0x144
|
||||
CopyFromG3D__Q23EGG11LightObjectFRCQ34nw4r3g3d11ResAnmLightfPQ23EGG11LightObjectb = .text:0x804AA1E0; // type:function size:0xD8
|
||||
FUN_804aa2c0 = .text:0x804AA2C0; // type:function size:0x9C
|
||||
FUN_804aa360 = .text:0x804AA360; // type:function size:0x168
|
||||
FUN_804aa4d0 = .text:0x804AA4D0; // type:function size:0xA8
|
||||
ApplyAnmResultInner__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA2C0; // type:function size:0x9C
|
||||
ApplyAnmResultA__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA360; // type:function size:0x168
|
||||
ApplyAnmResultB__Q23EGG11LightObjectFRCQ34nw4r3g3d14LightAnmResult = .text:0x804AA4D0; // type:function size:0xA8
|
||||
CalcDirDist__Q23EGG11LightObjectFv = .text:0x804AA580; // type:function size:0xD4
|
||||
CalcAt__Q23EGG11LightObjectFv = .text:0x804AA660; // type:function size:0x44
|
||||
SetPos__Q23EGG11LightObjectFRCQ34nw4r4math4VEC3 = .text:0x804AA6B0; // type:function size:0x1C
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef EGG_LIGHT_OBJ_H
|
||||
#define EGG_LIGHT_OBJ_H
|
||||
|
||||
#include "egg/math/eggVector.h"
|
||||
#include "egg/egg_types.h"
|
||||
#include "egg/prim/eggBinary.h"
|
||||
#include "nw4r/g3d/res/g3d_resanmlight.h"
|
||||
#include "nw4r/math/math_types.h"
|
||||
#include "rvl/GX/GXLight.h"
|
||||
#include "rvl/GX/GXTypes.h"
|
||||
@@ -23,7 +24,17 @@ public:
|
||||
void Reset();
|
||||
void Calc();
|
||||
void CalcView(nw4r::math::MTX34 const &);
|
||||
|
||||
void fn_804A9C30(const LightTexture *, nw4r::math::VEC3 *, GXColor *) const;
|
||||
|
||||
void InitGX(GXLightObj *obj) const;
|
||||
void CopyToG3D_World(nw4r::g3d::LightObj &) const;
|
||||
void CopyToG3D_View(nw4r::g3d::LightObj &, const nw4r::math::MTX34 &) const;
|
||||
void CopyFromG3D(const nw4r::g3d::ResAnmLight &, f32, EGG::LightObject *, bool);
|
||||
|
||||
void ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &);
|
||||
void ApplyAnmResultA(const nw4r::g3d::LightAnmResult &);
|
||||
bool ApplyAnmResultB(const nw4r::g3d::LightAnmResult &);
|
||||
|
||||
void CalcAt();
|
||||
void SetPos(const nw4r::math::VEC3 &);
|
||||
@@ -66,12 +77,12 @@ private:
|
||||
/* 0x48 */ f32 field_0x48;
|
||||
/* 0x4C */ nw4r::math::VEC3 field_0x4C;
|
||||
/* 0x58 */ nw4r::math::VEC3 field_0x58;
|
||||
/* 0x64 */ f32 field_0x64;
|
||||
/* 0x68 */ u16 field_0x68;
|
||||
/* 0x64 */ f32 mShininess;
|
||||
/* 0x68 */ u16 mFlags;
|
||||
/* 0x6C */ nw4r::math::VEC3 field_0x6C;
|
||||
/* 0x78 */ GXColor field_0x78;
|
||||
/* 0x7C */ nw4r::math::VEC3 field_0x7C;
|
||||
/* 0x88 */ nw4r::math::VEC3 field_0x88;
|
||||
/* 0x78 */ GXColor mLightColor;
|
||||
/* 0x7C */ nw4r::math::VEC3 mViewPos;
|
||||
/* 0x88 */ nw4r::math::VEC3 mViewAt;
|
||||
/* 0x94 */ nw4r::math::VEC3 field_0x94;
|
||||
/* 0xA0 */ u16 field_0xA0;
|
||||
};
|
||||
|
||||
@@ -53,12 +53,13 @@ public:
|
||||
const char *getName() const {
|
||||
return mName1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
f32 getFloat(u16 idx) const {
|
||||
return mpFloatData[idx];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
u8 getByte1(u16 idx) const {
|
||||
return mpByteData1[idx];
|
||||
}
|
||||
|
||||
+233
-37
@@ -1,6 +1,10 @@
|
||||
#include "egg/gfx/eggLightObject.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "egg/gfx/eggDrawGX.h"
|
||||
#include "egg/gfx/eggLightTexture.h"
|
||||
#include "nw4r/g3d/g3d_light.h"
|
||||
#include "nw4r/g3d/res/g3d_resanmlight.h"
|
||||
#include "nw4r/math/math_arithmetic.h"
|
||||
#include "nw4r/math/math_types.h"
|
||||
#include "rvl/GX/GXLight.h"
|
||||
@@ -8,6 +12,12 @@
|
||||
#include "rvl/MTX/mtxvec.h"
|
||||
#include "rvl/MTX/vec.h"
|
||||
|
||||
// TODO: This whole file does weird things with vectors!
|
||||
// NSMBW symbol names indicate that functions use nw4r::math::VEC3
|
||||
// arguments and we have some nw4r PS inlines, but
|
||||
// a fair number of vector assignments happen in a weird order
|
||||
// which might indicate EGG::Vector3f?
|
||||
|
||||
namespace EGG {
|
||||
|
||||
template <>
|
||||
@@ -35,17 +45,17 @@ LightObject::LightObject()
|
||||
mBlack(DrawGX::BLACK),
|
||||
field_0x3C(0),
|
||||
field_0x3D(1),
|
||||
mSpotFn(0),
|
||||
mDistAttnFn(0),
|
||||
mSpotFn(GX_SP_OFF),
|
||||
mDistAttnFn(GX_DA_OFF),
|
||||
field_0x40(90.0f),
|
||||
field_0x44(0.5f),
|
||||
field_0x48(0.5f),
|
||||
field_0x64(16.0f),
|
||||
field_0x68(0x661) {}
|
||||
mShininess(16.0f),
|
||||
mFlags(0x661) {}
|
||||
|
||||
void LightObject::Reset() {
|
||||
SetPosAt(nw4r::math::VEC3(-10000.0f, 10000.0f, 10000.0f), zeroVec);
|
||||
field_0x68 = 0x661;
|
||||
mFlags = 0x661;
|
||||
mWhite = DrawGX::WHITE;
|
||||
mBlack = DrawGX::BLACK;
|
||||
field_0x30 = 1.0;
|
||||
@@ -54,24 +64,24 @@ void LightObject::Reset() {
|
||||
field_0x40 = 90.0;
|
||||
field_0x44 = 0.5;
|
||||
field_0x48 = 0.5;
|
||||
mSpotFn = 0;
|
||||
mDistAttnFn = 0;
|
||||
field_0x64 = 16.0;
|
||||
mSpotFn = GX_SP_OFF;
|
||||
mDistAttnFn = GX_DA_OFF;
|
||||
mShininess = 16.0;
|
||||
field_0x58.x = 1.0;
|
||||
field_0x4C.x = 1.0;
|
||||
field_0x58.z = 0.0;
|
||||
field_0x4C.y = 0.0;
|
||||
field_0x58.y = 0.0;
|
||||
field_0x4C.z = 0.0;
|
||||
field_0x58.y = 0.0;
|
||||
field_0x4C.y = 0.0;
|
||||
}
|
||||
|
||||
void LightObject::Calc() {
|
||||
field_0x6C = mDir;
|
||||
field_0x78 = mWhite;
|
||||
mLightColor = mWhite;
|
||||
}
|
||||
|
||||
void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) {
|
||||
if ((field_0x68 & 1) == 0) {
|
||||
if ((mFlags & 1) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,35 +90,35 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) {
|
||||
case 3: {
|
||||
// Halp
|
||||
f32 scale = -1.0f;
|
||||
field_0x88.x = 0.0f;
|
||||
mViewAt.x = 0.0f;
|
||||
field_0x94.x = 0.0f;
|
||||
field_0x88.y = 0.0f;
|
||||
mViewAt.y = 0.0f;
|
||||
field_0x94.y = 0.0f;
|
||||
field_0x94.z = -1.0f;
|
||||
field_0x88.z = scale * mDist;
|
||||
field_0x7C.z = 0.0f;
|
||||
field_0x7C.y = 0.0f;
|
||||
field_0x7C.x = 0.0f;
|
||||
mViewAt.z = scale * mDist;
|
||||
mViewPos.z = 0.0f;
|
||||
mViewPos.y = 0.0f;
|
||||
mViewPos.x = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// Halp
|
||||
f32 scale = 1.0f;
|
||||
field_0x7C.x = 0.0f;
|
||||
mViewPos.x = 0.0f;
|
||||
field_0x94.x = 0.0f;
|
||||
field_0x7C.y = 0.0f;
|
||||
mViewPos.y = 0.0f;
|
||||
field_0x94.y = 0.0f;
|
||||
field_0x94.z = 1.0f;
|
||||
field_0x7C.z = scale * mDist;
|
||||
field_0x88.z = 0.0f;
|
||||
field_0x88.y = 0.0f;
|
||||
field_0x88.x = 0.0f;
|
||||
mViewPos.z = scale * mDist;
|
||||
mViewAt.z = 0.0f;
|
||||
mViewAt.y = 0.0f;
|
||||
mViewAt.x = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
field_0x94 = mDir;
|
||||
field_0x88 = mAt;
|
||||
field_0x7C = mPos;
|
||||
mViewAt = mAt;
|
||||
mViewPos = mPos;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -126,15 +136,30 @@ void LightObject::CalcView(nw4r::math::MTX34 const &viewMtx) {
|
||||
field_0x6C.z = 1.0f;
|
||||
}
|
||||
}
|
||||
PSMTXMultVec(viewMtx, mPos, field_0x7C);
|
||||
PSMTXMultVec(viewMtx, mAt, field_0x88);
|
||||
PSMTXMultVec(viewMtx, mPos, mViewPos);
|
||||
PSMTXMultVec(viewMtx, mAt, mViewAt);
|
||||
nw4r::math::VEC3TransformNormal(&field_0x94, &viewMtx, &field_0x6C);
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::fn_804A9C30(const LightTexture *tex, nw4r::math::VEC3 *pVec, GXColor *color) const {
|
||||
*pVec = field_0x94;
|
||||
*color = mLightColor;
|
||||
f32 f = tex->getFloat(mIndex);
|
||||
if (f < 1.0f) {
|
||||
color->r = color->r * f;
|
||||
color->g = color->g * f;
|
||||
color->b = color->b * f;
|
||||
color->a = color->a * f;
|
||||
} else {
|
||||
// Yes
|
||||
*color = *color;
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::InitGX(GXLightObj *obj) const {
|
||||
if ((field_0x68 & 1) != 0 && ((field_0x68 >> 6) & 1) != 0) {
|
||||
GXInitLightColor(obj, field_0x78);
|
||||
if ((mFlags & 1) != 0 && ((mFlags >> 6) & 1) != 0) {
|
||||
GXInitLightColor(obj, mLightColor);
|
||||
switch (field_0x3D) {
|
||||
case 1: {
|
||||
nw4r::math::VEC3 tmp = field_0x94 * -1e10f;
|
||||
@@ -143,31 +168,31 @@ void LightObject::InitGX(GXLightObj *obj) const {
|
||||
break;
|
||||
}
|
||||
case 0: {
|
||||
GXInitLightPos(obj, field_0x7C.x, field_0x7C.y, field_0x7C.z);
|
||||
GXInitLightPos(obj, mViewPos.x, mViewPos.y, mViewPos.z);
|
||||
GXInitLightDir(obj, zeroVec[0], zeroVec[1], zeroVec[2]);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
GXInitLightPos(obj, field_0x7C.x, field_0x7C.y, field_0x7C.z);
|
||||
GXInitLightPos(obj, mViewPos.x, mViewPos.y, mViewPos.z);
|
||||
GXInitLightDir(obj, field_0x94.x, field_0x94.y, field_0x94.z);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((field_0x68 & 0x80) != 0) {
|
||||
if ((mFlags & 0x80) != 0) {
|
||||
GXInitLightAttnA(obj, field_0x4C.x, field_0x4C.y, field_0x4C.z);
|
||||
} else {
|
||||
GXInitLightSpot(obj, field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn());
|
||||
}
|
||||
|
||||
if ((field_0x68 & 0x100) != 0) {
|
||||
if ((mFlags & 0x100) != 0) {
|
||||
GXInitLightAttnK(obj, field_0x58.x, field_0x58.y, field_0x58.z);
|
||||
} else {
|
||||
GXInitLightDistAttn(obj, field_0x44 * getDistance(), field_0x48, getDistAttnFn());
|
||||
}
|
||||
|
||||
if ((field_0x68 & 0x800) != 0) {
|
||||
f32 ka = field_0x64 / 2.0f;
|
||||
if ((mFlags & 0x800) != 0) {
|
||||
f32 ka = mShininess / 2.0f;
|
||||
GXInitLightAttn(obj, 0.0f, 0.0f, 1.0f, ka, 0.0f, 1.0f - ka);
|
||||
}
|
||||
|
||||
@@ -176,6 +201,178 @@ void LightObject::InitGX(GXLightObj *obj) const {
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::CopyToG3D_World(nw4r::g3d::LightObj &g3dObj) const {
|
||||
if ((mFlags & 1) != 0 && (mFlags & 0x40) != 0) {
|
||||
g3dObj.Clear();
|
||||
if ((mFlags & 0x200) == 0) {
|
||||
g3dObj.DisableColor();
|
||||
}
|
||||
if ((mFlags & 0x400) == 0) {
|
||||
g3dObj.DisableAlpha();
|
||||
}
|
||||
|
||||
g3dObj.Enable();
|
||||
g3dObj.InitLightColor(mLightColor);
|
||||
|
||||
if ((mFlags & 0x80) != 0) {
|
||||
g3dObj.InitLightAttnA(field_0x4C.x, field_0x4C.y, field_0x4C.z);
|
||||
} else {
|
||||
g3dObj.InitLightSpot(field_0x40 > 0.0f ? field_0x40 : 0.0001f, getSpotFn());
|
||||
}
|
||||
|
||||
if ((mFlags & 0x100) != 0) {
|
||||
g3dObj.InitLightAttnK(field_0x58.x, field_0x58.y, field_0x58.z);
|
||||
} else {
|
||||
g3dObj.InitLightDistAttn(field_0x44 * getDistance(), field_0x48, getDistAttnFn());
|
||||
}
|
||||
|
||||
if ((mFlags & 0x800) != 0) {
|
||||
g3dObj.InitLightShininess(mShininess);
|
||||
}
|
||||
} else {
|
||||
g3dObj.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::CopyToG3D_View(nw4r::g3d::LightObj &g3dObj, const nw4r::math::MTX34 &viewMtx) const {
|
||||
if (!g3dObj.IsEnable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
if (!(mFlags & 0x800)) {
|
||||
nw4r::math::VEC3 dir;
|
||||
nw4r::math::VEC3 pos;
|
||||
switch (field_0x3D) {
|
||||
case 1: {
|
||||
nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94);
|
||||
nw4r::math::VEC3Scale(&pos, &dir, -1e10f);
|
||||
dir.z = 0.0f;
|
||||
dir.y = 0.0f;
|
||||
dir.x = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 0: {
|
||||
PSMTXMultVec(viewMtx, mViewPos, pos);
|
||||
dir.z = 0.0f;
|
||||
dir.y = 0.0f;
|
||||
dir.x = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
PSMTXMultVec(viewMtx, mViewPos, pos);
|
||||
nw4r::math::VEC3TransformNormal(&dir, &viewMtx, &field_0x94);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g3dObj.InitLightPos(pos.x, pos.y, pos.z);
|
||||
g3dObj.InitLightDir(dir.x, dir.y, dir.z);
|
||||
} else {
|
||||
g3dObj.InitSpecularDir(mDir.x, mDir.y, mDir.z);
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::CopyFromG3D(
|
||||
const nw4r::g3d::ResAnmLight &g3dLight, f32 frame, EGG::LightObject *optObj, bool skipDoingSomething
|
||||
) {
|
||||
nw4r::g3d::LightAnmResult result;
|
||||
g3dLight.GetAnmResult(&result, frame);
|
||||
if (!skipDoingSomething || (result.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) {
|
||||
if ((result.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) {
|
||||
ApplyAnmResultA(result);
|
||||
if (optObj != nullptr && optObj->ApplyAnmResultB(result)) {
|
||||
optObj->field_0x06 = mIndex;
|
||||
optObj->mFlags |= 2;
|
||||
}
|
||||
} else {
|
||||
// TODO
|
||||
mFlags = mFlags & 0xFFFE;
|
||||
if (optObj != nullptr) {
|
||||
optObj->mFlags = optObj->mFlags & 0xFFFE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::ApplyAnmResultInner(const nw4r::g3d::LightAnmResult &res) {
|
||||
// TODO
|
||||
mFlags = mFlags & 0xF07E;
|
||||
field_0x40 = 90.0f;
|
||||
field_0x44 = 0.5f;
|
||||
field_0x48 = 0.5f;
|
||||
mSpotFn = GX_SP_OFF;
|
||||
mDistAttnFn = GX_DA_OFF;
|
||||
mShininess = 16.0f;
|
||||
// ...
|
||||
field_0x58.x = 1.0f;
|
||||
field_0x4C.x = 1.0f;
|
||||
field_0x58.z = 0.0f;
|
||||
field_0x4C.z = 0.0f;
|
||||
field_0x58.y = 0.0f;
|
||||
field_0x4C.y = 0.0f;
|
||||
if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_COLOR_ENABLE) != 0) {
|
||||
mFlags |= 0x200;
|
||||
}
|
||||
if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_ALPHA_ENABLE) != 0) {
|
||||
mFlags |= 0x400;
|
||||
}
|
||||
if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_ENABLE) != 0) {
|
||||
mFlags |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::ApplyAnmResultA(const nw4r::g3d::LightAnmResult &res) {
|
||||
ApplyAnmResultInner(res);
|
||||
switch ((int)(res.flags & nw4r::g3d::LightAnmResult::FLAG_LIGHT_TYPE_MASK)) {
|
||||
case 0: {
|
||||
field_0x3D = 0;
|
||||
mWhite = res.color;
|
||||
SetPosAt(res.pos, res.pos);
|
||||
field_0x40 = 0.0f;
|
||||
mSpotFn = GX_SP_OFF;
|
||||
field_0x44 = res.refDistance;
|
||||
field_0x48 = res.refBrightness;
|
||||
mDistAttnFn = res.distFunc;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
field_0x3D = 1;
|
||||
mWhite = res.color;
|
||||
SetPosAt(res.pos, res.aim);
|
||||
mSpotFn = GX_SP_OFF;
|
||||
mDistAttnFn = GX_AF_SPEC;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
field_0x3D = 2;
|
||||
mWhite = res.color;
|
||||
SetPosAt(res.pos, res.aim);
|
||||
mSpotFn = res.spotFunc;
|
||||
field_0x40 = res.cutoff;
|
||||
mDistAttnFn = res.distFunc;
|
||||
field_0x44 = res.refDistance;
|
||||
field_0x48 = res.refBrightness;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LightObject::ApplyAnmResultB(const nw4r::g3d::LightAnmResult &res) {
|
||||
if ((res.flags & nw4r::g3d::LightAnmResult::FLAG_SPECULAR_ENABLE) != 0) {
|
||||
ApplyAnmResultInner(res);
|
||||
field_0x3D = 1;
|
||||
mWhite = res.specColor;
|
||||
SetPosAt(res.pos, res.aim);
|
||||
mFlags |= 0x800;
|
||||
mShininess = res.shininess;
|
||||
return true;
|
||||
} else {
|
||||
// TODO
|
||||
mFlags = mFlags & 0xFFFE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void LightObject::CalcDirDist() {
|
||||
mDir.x = mAt.x - mPos.x;
|
||||
mDir.y = mAt.y - mPos.y;
|
||||
@@ -217,7 +414,6 @@ void LightObject::SetPosAt(nw4r::math::VEC3 const &pos, nw4r::math::VEC3 const &
|
||||
CalcDirDist();
|
||||
}
|
||||
|
||||
|
||||
void LightObject::SetBinaryInner(const Bin &bin) {}
|
||||
|
||||
void LightObject::GetBinaryInner(Bin *bin) const {}
|
||||
|
||||
Reference in New Issue
Block a user