mirror of https://github.com/zeldaret/mm.git
parent
484263dedc
commit
bb6b580a6b
|
|
@ -2052,7 +2052,7 @@ s32 func_80124020(void);
|
|||
u8 Player_GetMask(GlobalContext* globalCtx);
|
||||
void Player_RemoveMask(GlobalContext* globalCtx);
|
||||
s32 func_8012405C(GlobalContext* globalCtx);
|
||||
// void func_80124088(void);
|
||||
s32 func_80124088(GlobalContext* globalCtx);
|
||||
s32 func_801240C8(Player* player);
|
||||
// void func_801240DC(void);
|
||||
// void func_80124110(void);
|
||||
|
|
|
|||
5
spec
5
spec
|
|
@ -1254,8 +1254,11 @@ beginseg
|
|||
name "ovl_Mir_Ray"
|
||||
compress
|
||||
include "build/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.o"
|
||||
include "build/data/ovl_Mir_Ray/ovl_Mir_Ray.data.o"
|
||||
#ifdef NON_MATCHING
|
||||
include "build/src/overlays/actors/ovl_Mir_Ray/ovl_Mir_Ray_reloc.o"
|
||||
#else
|
||||
include "build/data/ovl_Mir_Ray/ovl_Mir_Ray.reloc.o"
|
||||
#endif
|
||||
endseg
|
||||
|
||||
beginseg
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
* File: z_mir_ray.c
|
||||
* Overlay: ovl_Mir_Ray
|
||||
* Description: Reflectible light ray (unused, somewhat broken)
|
||||
* Note: This actor is unchanged from OoT, and will not work correctly
|
||||
*/
|
||||
|
||||
#include "z_mir_ray.h"
|
||||
#include "objects/object_mir_ray/object_mir_ray.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20)
|
||||
|
||||
|
|
@ -15,7 +17,30 @@ void MirRay_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void MirRay_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
#if 0
|
||||
s32 MirRay_CheckInFrustum(Vec3f* vecA, Vec3f* vecB, f32 pointx, f32 pointy, f32 pointz, s16 radiusA, s16 radiusB);
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Vec3f pos;
|
||||
/* 0x0C */ MtxF mtx;
|
||||
/* 0x4C */ CollisionPoly* reflectionPoly;
|
||||
/* 0x50 */ u8 opacity;
|
||||
} MirRayShieldReflection; // size = 0x54
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Vec3s sourcePoint;
|
||||
/* 0x06 */ Vec3s poolPoint; // point at center of light pool on floor for windows and BigMirror, same as source
|
||||
// point for Cobra Mirror
|
||||
/* 0x0C */ s16 sourceEndRadius; // Radius of beam frustum at the source end
|
||||
/* 0x0E */ s16 poolEndRadius; // Radius of beam frustum at the pool end
|
||||
/* 0x10 */ f32 unk_10; // placement of collider center along beam
|
||||
/* 0x14 */ s16 unk_14; // collider radius before scaled
|
||||
/* 0x16 */ s16 lgtPtMaxRad; // light point max radius
|
||||
/* 0x18 */ f32 unk_18; // placement of light point between source and reflection point (pool point for windows,
|
||||
// player for mirrors)
|
||||
/* 0x1C */ Color_RGB8 color;
|
||||
/* 0x1F */ u8 params;
|
||||
} MirRayDataEntry; // size = 0x20
|
||||
|
||||
const ActorInit Mir_Ray_InitVars = {
|
||||
ACTOR_MIR_RAY,
|
||||
ACTORCAT_ITEMACTION,
|
||||
|
|
@ -28,64 +53,669 @@ const ActorInit Mir_Ray_InitVars = {
|
|||
(ActorFunc)MirRay_Draw,
|
||||
};
|
||||
|
||||
// static ColliderQuadInit sQuadInit = {
|
||||
static ColliderQuadInit D_808E3BF4 = {
|
||||
{ COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_QUAD, },
|
||||
{ ELEMTYPE_UNK0, { 0x00200000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, },
|
||||
u8 D_808E3BF0 = false;
|
||||
|
||||
static ColliderQuadInit sQuadInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_ON | AT_TYPE_PLAYER,
|
||||
AC_NONE,
|
||||
OC1_NONE,
|
||||
OC2_NONE,
|
||||
COLSHAPE_QUAD,
|
||||
},
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00200000, 0x00, 0x00 },
|
||||
{ 0xF7CFFFFF, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_NORMAL,
|
||||
BUMP_NONE,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } },
|
||||
};
|
||||
|
||||
// static ColliderJntSphElementInit sJntSphElementsInit[1] = {
|
||||
static ColliderJntSphElementInit D_808E3C44[1] = {
|
||||
static ColliderJntSphElementInit sJntSphElementsInit[1] = {
|
||||
{
|
||||
{ ELEMTYPE_UNK0, { 0x00200000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, },
|
||||
{
|
||||
ELEMTYPE_UNK0,
|
||||
{ 0x00200000, 0x00, 0x00 },
|
||||
{ 0x00000000, 0x00, 0x00 },
|
||||
TOUCH_ON | TOUCH_SFX_NORMAL,
|
||||
BUMP_NONE,
|
||||
OCELEM_NONE,
|
||||
},
|
||||
{ 0, { { 0, 0, 0 }, 50 }, 100 },
|
||||
},
|
||||
};
|
||||
|
||||
// static ColliderJntSphInit sJntSphInit = {
|
||||
static ColliderJntSphInit D_808E3C68 = {
|
||||
{ COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, },
|
||||
1, D_808E3C44, // sJntSphElementsInit,
|
||||
static ColliderJntSphInit sJntSphInit = {
|
||||
{
|
||||
COLTYPE_NONE,
|
||||
AT_ON | AT_TYPE_PLAYER,
|
||||
AC_NONE,
|
||||
OC1_NONE,
|
||||
OC2_NONE,
|
||||
COLSHAPE_JNTSPH,
|
||||
},
|
||||
1,
|
||||
sJntSphElementsInit,
|
||||
};
|
||||
|
||||
// static InitChainEntry sInitChain[] = {
|
||||
static InitChainEntry D_808E3DB8[] = {
|
||||
// Note: this data is unchanged from OoT and hardcoded for Spirit Temple, so the actor will not work at all without
|
||||
// modification.
|
||||
|
||||
MirRayDataEntry sMirRayData[] = {
|
||||
{
|
||||
{ -0x488, 0x2AE, -0x370 },
|
||||
{ -0x398, 0x1E0, -0x379 },
|
||||
30,
|
||||
50,
|
||||
1.0f,
|
||||
50,
|
||||
150,
|
||||
0.8f,
|
||||
{ 255, 255, 255 },
|
||||
2,
|
||||
},
|
||||
{
|
||||
{ -0x740, 0x444, -0xBE },
|
||||
{ -0x6A7, 0x349, -0xBA },
|
||||
30,
|
||||
70,
|
||||
0.88f,
|
||||
0x36,
|
||||
150,
|
||||
0.8f,
|
||||
{ 255, 255, 255 },
|
||||
2,
|
||||
},
|
||||
{
|
||||
{ 0x557, 0x2E2, -0x35C },
|
||||
{ 0x443, 0x1DC, -0x35C },
|
||||
30,
|
||||
0x55,
|
||||
0.0f,
|
||||
0,
|
||||
150,
|
||||
0.8f,
|
||||
{ 255, 255, 255 },
|
||||
0,
|
||||
},
|
||||
{
|
||||
{ 0x898, 0x44F, -0xDC },
|
||||
{ 0x7F8, 0x34B, -0xDC },
|
||||
30,
|
||||
60,
|
||||
0.0f,
|
||||
0,
|
||||
150,
|
||||
0.8f,
|
||||
{ 255, 255, 255 },
|
||||
1,
|
||||
},
|
||||
{
|
||||
{ -0x230, 0x879, -0x136 },
|
||||
{ -0x230, 0x6CF, -0x136 },
|
||||
30,
|
||||
70,
|
||||
0.0f,
|
||||
0,
|
||||
150,
|
||||
0.8f,
|
||||
{ 255, 255, 255 },
|
||||
0,
|
||||
},
|
||||
{
|
||||
{ 0x3C, 0x70A, -0x442 },
|
||||
{ 0x3C, 0x3CD, -0x442 },
|
||||
30,
|
||||
70,
|
||||
0.0f,
|
||||
0,
|
||||
150,
|
||||
0.9f,
|
||||
{ 255, 255, 255 },
|
||||
13,
|
||||
},
|
||||
{
|
||||
{ 0x474, 0x1E0, -0x35C },
|
||||
{ 0x474, 0x1E0, -0x35C },
|
||||
30,
|
||||
30,
|
||||
1.0f,
|
||||
10,
|
||||
100,
|
||||
0.9f,
|
||||
{ 255, 255, 255 },
|
||||
14,
|
||||
},
|
||||
{
|
||||
{ -0x230, 0x6CF, -0x136 },
|
||||
{
|
||||
-0x230,
|
||||
0x6CF,
|
||||
-0x136,
|
||||
},
|
||||
30,
|
||||
30,
|
||||
0.0f,
|
||||
0,
|
||||
100,
|
||||
0.94f,
|
||||
{ 255, 255, 255 },
|
||||
12,
|
||||
},
|
||||
{
|
||||
{ 0x3C, 0x6CF, -0x136 },
|
||||
{ 0x3C, 0x6CF, -0x136 },
|
||||
30,
|
||||
30,
|
||||
0.0f,
|
||||
0,
|
||||
100,
|
||||
0.94f,
|
||||
{ 255, 255, 255 },
|
||||
12,
|
||||
},
|
||||
{
|
||||
{ -0x496, 0x1C0, 0x4AA },
|
||||
{ -0x496, 0x94, 0x4AA },
|
||||
50,
|
||||
100,
|
||||
1.0f,
|
||||
50,
|
||||
150,
|
||||
0.8f,
|
||||
{ 255, 255, 255 },
|
||||
3,
|
||||
},
|
||||
};
|
||||
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 0, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
const char D_808E3DD0[] = "反射光 発生失敗";
|
||||
|
||||
void MirRay_SetupCollider(MirRay* this) {
|
||||
MirRayDataEntry* dataEntry = &sMirRayData[MIRRAY_LOCATION(&this->actor)];
|
||||
f32 x = (this->poolPt.x - this->sourcePt.x) * dataEntry->unk_10;
|
||||
f32 y = (this->poolPt.y - this->sourcePt.y) * dataEntry->unk_10;
|
||||
f32 z = (this->poolPt.z - this->sourcePt.z) * dataEntry->unk_10;
|
||||
|
||||
this->collider1.elements[0].dim.worldSphere.center.x = this->sourcePt.x + x;
|
||||
this->collider1.elements[0].dim.worldSphere.center.y = this->sourcePt.y + y;
|
||||
this->collider1.elements[0].dim.worldSphere.center.z = this->sourcePt.z + z;
|
||||
|
||||
this->collider1.elements[0].dim.worldSphere.radius = dataEntry->unk_14 * this->collider1.elements->dim.scale;
|
||||
}
|
||||
|
||||
// Set up a light point between source point and reflection point. Reflection point is the pool point (for windows) or
|
||||
// at the player position (for mirrors)
|
||||
void MirRay_MakeShieldLight(MirRay* this, GlobalContext* globalCtx) {
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
MirRayDataEntry* dataEntry = &sMirRayData[MIRRAY_LOCATION(&this->actor)];
|
||||
Vec3f reflectionPt;
|
||||
Vec3s lightPt;
|
||||
|
||||
if (MirRay_CheckInFrustum(&this->sourcePt, &this->poolPt, player->actor.world.pos.x,
|
||||
player->actor.world.pos.y + 30.0f, player->actor.world.pos.z, this->sourceEndRad,
|
||||
this->poolEndRad)) {
|
||||
if (dataEntry->params & 8) {
|
||||
Math_Vec3f_Diff(&player->actor.world.pos, &this->sourcePt, &reflectionPt);
|
||||
} else {
|
||||
Math_Vec3f_Diff(&this->poolPt, &this->sourcePt, &reflectionPt);
|
||||
}
|
||||
|
||||
lightPt.x = (dataEntry->unk_18 * reflectionPt.x) + this->sourcePt.x;
|
||||
lightPt.y = (dataEntry->unk_18 * reflectionPt.y) + this->sourcePt.y;
|
||||
lightPt.z = (dataEntry->unk_18 * reflectionPt.z) + this->sourcePt.z;
|
||||
|
||||
// Fade up
|
||||
Math_StepToS(&this->lightPointRad, dataEntry->lgtPtMaxRad, 6);
|
||||
Lights_PointNoGlowSetInfo(&this->lightInfo, lightPt.x, lightPt.y, lightPt.z, dataEntry->color.r,
|
||||
dataEntry->color.g, dataEntry->color.b, this->lightPointRad);
|
||||
} else {
|
||||
// Fade down
|
||||
Math_StepToS(&this->lightPointRad, 0, 6);
|
||||
Lights_PointSetColorAndRadius(&this->lightInfo, dataEntry->color.r, dataEntry->color.g, dataEntry->color.b,
|
||||
this->lightPointRad);
|
||||
}
|
||||
}
|
||||
|
||||
void MirRay_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
MirRay* this = THIS;
|
||||
MirRayDataEntry* dataEntry = &sMirRayData[MIRRAY_LOCATION(&this->actor)];
|
||||
|
||||
Actor_ProcessInitChain(&this->actor, sInitChain);
|
||||
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
|
||||
|
||||
if (MIRRAY_LOCATION(&this->actor) >= MIRRAY_MAX) {
|
||||
Actor_MarkForDeath(&this->actor);
|
||||
}
|
||||
|
||||
this->sourcePt.x = dataEntry->sourcePoint.x;
|
||||
this->sourcePt.y = dataEntry->sourcePoint.y;
|
||||
this->sourcePt.z = dataEntry->sourcePoint.z;
|
||||
this->sourceEndRad = dataEntry->sourceEndRadius;
|
||||
|
||||
this->poolPt.x = dataEntry->poolPoint.x;
|
||||
this->poolPt.y = dataEntry->poolPoint.y;
|
||||
this->poolPt.z = dataEntry->poolPoint.z;
|
||||
this->poolEndRad = dataEntry->poolEndRadius;
|
||||
|
||||
Lights_PointNoGlowSetInfo(&this->lightInfo, this->sourcePt.x, this->sourcePt.y, this->sourcePt.z, 255, 255, 255,
|
||||
100);
|
||||
this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo);
|
||||
|
||||
this->shieldCorners[0].x = -536.0f;
|
||||
this->shieldCorners[0].y = -939.0f;
|
||||
|
||||
this->shieldCorners[1].x = -1690.0f;
|
||||
this->shieldCorners[1].y = 0.0f;
|
||||
|
||||
this->shieldCorners[2].x = -536.0f;
|
||||
this->shieldCorners[2].y = 938.0f;
|
||||
|
||||
this->shieldCorners[3].x = 921.0f;
|
||||
this->shieldCorners[3].y = 0.0f;
|
||||
|
||||
this->shieldCorners[4].x = 758.0f;
|
||||
this->shieldCorners[4].y = 800.0f;
|
||||
|
||||
this->shieldCorners[5].x = 758.0f;
|
||||
this->shieldCorners[5].y = -800.0f;
|
||||
|
||||
if (dataEntry->params & 2) {
|
||||
Collider_InitJntSph(globalCtx, &this->collider1);
|
||||
Collider_SetJntSph(globalCtx, &this->collider1, &this->actor, &sJntSphInit, this->collider1Elements);
|
||||
if (!(dataEntry->params & 4)) { // Beams not from mirrors
|
||||
MirRay_SetupCollider(this);
|
||||
}
|
||||
}
|
||||
|
||||
Collider_InitQuad(globalCtx, &this->collider2);
|
||||
Collider_SetQuad(globalCtx, &this->collider2, &this->actor, &sQuadInit);
|
||||
|
||||
if ((MIRRAY_LOCATION(&this->actor) == MIRRAY_SPIRIT_TOPROOM_CEILINGMIRROR) ||
|
||||
(MIRRAY_LOCATION(&this->actor) == MIRRAY_SPIRIT_TOPROOM_COBRA1) ||
|
||||
(MIRRAY_LOCATION(&this->actor) == MIRRAY_SPIRIT_TOPROOM_COBRA2)) {
|
||||
this->actor.room = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void MirRay_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
MirRay* this = THIS;
|
||||
|
||||
LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode);
|
||||
|
||||
if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 2) {
|
||||
Collider_DestroyJntSph(globalCtx, &this->collider1);
|
||||
}
|
||||
|
||||
Collider_DestroyQuad(globalCtx, &this->collider2);
|
||||
}
|
||||
|
||||
void MirRay_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
MirRay* this = THIS;
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
|
||||
D_808E3BF0 = false;
|
||||
|
||||
if (!this->unLit) {
|
||||
if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 2) {
|
||||
if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 4) {
|
||||
MirRay_SetupCollider(this);
|
||||
}
|
||||
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base);
|
||||
}
|
||||
|
||||
if (this->reflectIntensity > 0.0f) {
|
||||
CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base);
|
||||
}
|
||||
|
||||
MirRay_MakeShieldLight(this, globalCtx);
|
||||
|
||||
if (this->reflectIntensity > 0.0f) {
|
||||
func_800B8F98(&player->actor, NA_SE_IT_SHIELD_BEAM - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MirRay_SetIntensity(MirRay* this, GlobalContext* globalCtx) {
|
||||
f32 sp4C[3];
|
||||
s32 pad[4];
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
MtxF* shieldMtx = &player->shieldMf;
|
||||
f32 temp_f0;
|
||||
f32 temp_f0_2;
|
||||
f32 temp_f2;
|
||||
|
||||
this->reflectIntensity = 0.0f;
|
||||
|
||||
if (MirRay_CheckInFrustum(&this->sourcePt, &this->poolPt, shieldMtx->wx, shieldMtx->wy, shieldMtx->wz,
|
||||
this->sourceEndRad, this->poolEndRad)) {
|
||||
temp_f0 = sqrtf(SQ(shieldMtx->zz) + (SQ(shieldMtx->zx) + SQ(shieldMtx->zy)));
|
||||
if (temp_f0 == 0.0f) {
|
||||
this->reflectRange = 1.0f;
|
||||
} else {
|
||||
this->reflectRange = 1.0f / temp_f0;
|
||||
}
|
||||
|
||||
if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 1) {
|
||||
this->reflectIntensity = 1.0f;
|
||||
} else {
|
||||
sp4C[0] = this->poolPt.x - this->sourcePt.x;
|
||||
sp4C[1] = this->poolPt.y - this->sourcePt.y;
|
||||
sp4C[2] = this->poolPt.z - this->sourcePt.z;
|
||||
|
||||
temp_f2 = (-shieldMtx->zx * sp4C[0]) - (shieldMtx->zy * sp4C[1]) - (shieldMtx->zz * sp4C[2]);
|
||||
|
||||
if (temp_f2 < 0.0f) {
|
||||
temp_f0_2 = sqrtf(SQ(sp4C[0]) + SQ(sp4C[1]) + SQ(sp4C[2]));
|
||||
if ((temp_f0 != 0.0f) && (temp_f0_2 != 0.0f)) {
|
||||
this->reflectIntensity = -temp_f2 / (temp_f0 * temp_f0_2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draws six images, one for each corner of the shield, by finding the intersection of a line segment from the corner
|
||||
// perpendicular to the shield with the nearest collision (if any).
|
||||
void MirRay_SetupReflectionPolys(MirRay* this, GlobalContext* globalCtx, MirRayShieldReflection* reflection) {
|
||||
s32 i;
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
MtxF* shieldMtx = &player->shieldMf;
|
||||
Vec3f posA;
|
||||
Vec3f posB;
|
||||
Vec3f sp70;
|
||||
CollisionPoly* outPoly;
|
||||
f32 sp60[3];
|
||||
|
||||
sp60[0] = -(shieldMtx->zx * this->reflectRange) * this->reflectIntensity * 400.0f;
|
||||
sp60[1] = -(shieldMtx->zy * this->reflectRange) * this->reflectIntensity * 400.0f;
|
||||
sp60[2] = -(shieldMtx->zz * this->reflectRange) * this->reflectIntensity * 400.0f;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(this->shieldCorners); i++) {
|
||||
posA.x =
|
||||
(shieldMtx->wx + (this->shieldCorners[i].x * shieldMtx->xx)) + (this->shieldCorners[i].y * (*shieldMtx).yx);
|
||||
posA.y =
|
||||
(shieldMtx->wy + (this->shieldCorners[i].x * shieldMtx->xy)) + (this->shieldCorners[i].y * (*shieldMtx).yy);
|
||||
posA.z =
|
||||
(shieldMtx->wz + (this->shieldCorners[i].x * shieldMtx->xz)) + (this->shieldCorners[i].y * (*shieldMtx).yz);
|
||||
|
||||
posB.x = sp60[0] + posA.x;
|
||||
posB.y = sp60[1] + posA.y;
|
||||
posB.z = sp60[2] + posA.z;
|
||||
|
||||
if (BgCheck_AnyLineTest1(&globalCtx->colCtx, &posA, &posB, &sp70, &outPoly, 1)) {
|
||||
reflection[i].reflectionPoly = outPoly;
|
||||
} else {
|
||||
reflection[i].reflectionPoly = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove reflections that are in the same position and are sufficiently near to the same plane
|
||||
void MirRay_RemoveSimilarReflections(MirRayShieldReflection* reflection) {
|
||||
s32 i, j;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
for (j = i + 1; j < 6; j++) {
|
||||
if ((reflection[i].reflectionPoly != NULL) && (reflection[j].reflectionPoly != NULL)) {
|
||||
if ((ABS(reflection[i].reflectionPoly->normal.x - reflection[j].reflectionPoly->normal.x) < 100) &&
|
||||
(ABS(reflection[i].reflectionPoly->normal.y - reflection[j].reflectionPoly->normal.y) < 100) &&
|
||||
(ABS(reflection[i].reflectionPoly->normal.z - reflection[j].reflectionPoly->normal.z) < 100) &&
|
||||
(reflection[i].reflectionPoly->dist == reflection[j].reflectionPoly->dist)) {
|
||||
reflection[j].reflectionPoly = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the reflected beam's collider (to interact with objects) and places and orients the shield images
|
||||
#ifdef NON_MATCHING
|
||||
// Beginning block re-ordered
|
||||
void MirRay_ReflectedBeam(MirRay* this, GlobalContext* globalCtx, MirRayShieldReflection* reflection) {
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
s32 i;
|
||||
f32 temp_f0;
|
||||
Vec3f vecB;
|
||||
Vec3f vecD;
|
||||
Vec3f sp118;
|
||||
Vec3f sp10C;
|
||||
Vec3f sp100;
|
||||
Vec3f intersection;
|
||||
f32 spE8[3];
|
||||
f32 normalVec[3];
|
||||
MtxF* shieldMtx = &player->shieldMf;
|
||||
Vec3f vecA;
|
||||
Vec3f vecC;
|
||||
|
||||
spE8[0] = -(shieldMtx->zx * this->reflectRange) * this->reflectIntensity * 400.0f;
|
||||
spE8[1] = -(shieldMtx->zy * this->reflectRange) * this->reflectIntensity * 400.0f;
|
||||
spE8[2] = -(shieldMtx->zz * this->reflectRange) * this->reflectIntensity * 400.0f;
|
||||
|
||||
vecB.x = shieldMtx->wx;
|
||||
vecB.y = shieldMtx->wy;
|
||||
vecB.z = shieldMtx->wz;
|
||||
|
||||
vecD.x = spE8[0] + vecB.x;
|
||||
vecD.y = spE8[1] + vecB.y;
|
||||
vecD.z = spE8[2] + vecB.z;
|
||||
|
||||
vecA.x = vecB.x + (shieldMtx->xx * 300.0f);
|
||||
vecA.y = vecB.y + (shieldMtx->xy * 300.0f);
|
||||
vecA.z = vecB.z + (shieldMtx->xz * 300.0f);
|
||||
|
||||
vecC.x = vecD.x + (shieldMtx->xx * 300.0f);
|
||||
vecC.y = vecD.y + (shieldMtx->xy * 300.0f);
|
||||
vecC.z = vecD.z + (shieldMtx->xz * 300.0f);
|
||||
|
||||
Collider_SetQuadVertices(&this->collider2, &vecA, &vecB, &vecC, &vecD);
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (reflection[i].reflectionPoly != NULL) {
|
||||
normalVec[0] = COLPOLY_GET_NORMAL(reflection[i].reflectionPoly->normal.x);
|
||||
normalVec[1] = COLPOLY_GET_NORMAL(reflection[i].reflectionPoly->normal.y);
|
||||
normalVec[2] = COLPOLY_GET_NORMAL(reflection[i].reflectionPoly->normal.z);
|
||||
|
||||
if (Math3D_LineSegVsPlane(normalVec[0], normalVec[1], normalVec[2], reflection[i].reflectionPoly->dist,
|
||||
&vecB, &vecD, &sp118, 1)) {
|
||||
|
||||
reflection[i].pos.x = sp118.x;
|
||||
reflection[i].pos.y = sp118.y;
|
||||
reflection[i].pos.z = sp118.z;
|
||||
|
||||
temp_f0 = sqrtf(SQ(sp118.x - vecB.x) + SQ(sp118.y - vecB.y) + SQ(sp118.z - vecB.z));
|
||||
|
||||
if (temp_f0 < (this->reflectIntensity * 600.0f)) {
|
||||
reflection[i].opacity = 200;
|
||||
} else {
|
||||
reflection[i].opacity = (s32)(800.0f - temp_f0);
|
||||
}
|
||||
|
||||
reflection[i].opacity = (s32)(reflection[i].opacity * 1.275f);
|
||||
|
||||
sp10C.x = (shieldMtx->xx * 100.0f) + vecB.x;
|
||||
sp10C.y = (shieldMtx->xy * 100.0f) + vecB.y;
|
||||
sp10C.z = (shieldMtx->xz * 100.0f) + vecB.z;
|
||||
|
||||
sp100.x = (spE8[0] * 4.0f) + sp10C.x;
|
||||
sp100.y = (spE8[1] * 4.0f) + sp10C.y;
|
||||
sp100.z = (spE8[2] * 4.0f) + sp10C.z;
|
||||
|
||||
reflection[i].mtx.xx = reflection[i].mtx.yy = reflection[i].mtx.zz = reflection[i].mtx.ww = 1.0f;
|
||||
|
||||
reflection[i].mtx.xy = reflection[i].mtx.xz = reflection[i].mtx.xw = reflection[i].mtx.yx =
|
||||
reflection[i].mtx.yz = reflection[i].mtx.yw = reflection[i].mtx.zx = reflection[i].mtx.zy =
|
||||
reflection[i].mtx.zw = reflection[i].mtx.wx = reflection[i].mtx.wy = reflection[i].mtx.wz =
|
||||
0.0f;
|
||||
|
||||
if (Math3D_LineSegVsPlane(normalVec[0], normalVec[1], normalVec[2], reflection[i].reflectionPoly->dist,
|
||||
&sp10C, &sp100, &intersection, 1)) {
|
||||
reflection[i].mtx.xx = intersection.x - sp118.x;
|
||||
reflection[i].mtx.xy = intersection.y - sp118.y;
|
||||
reflection[i].mtx.xz = intersection.z - sp118.z;
|
||||
}
|
||||
|
||||
sp10C.x = (shieldMtx->yx * 100.0f) + vecB.x;
|
||||
sp10C.y = (shieldMtx->yy * 100.0f) + vecB.y;
|
||||
sp10C.z = (shieldMtx->yz * 100.0f) + vecB.z;
|
||||
|
||||
sp100.x = (spE8[0] * 4.0f) + sp10C.x;
|
||||
sp100.y = (spE8[1] * 4.0f) + sp10C.y;
|
||||
sp100.z = (spE8[2] * 4.0f) + sp10C.z;
|
||||
|
||||
if (Math3D_LineSegVsPlane(normalVec[0], normalVec[1], normalVec[2], reflection[i].reflectionPoly->dist,
|
||||
&sp10C, &sp100, &intersection, 1)) {
|
||||
reflection[i].mtx.yx = intersection.x - sp118.x;
|
||||
reflection[i].mtx.yy = intersection.y - sp118.y;
|
||||
reflection[i].mtx.yz = intersection.z - sp118.z;
|
||||
}
|
||||
} else {
|
||||
reflection[i].reflectionPoly = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void MirRay_ReflectedBeam(MirRay* this, GlobalContext* globalCtx, MirRayShieldReflection* reflection);
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_ReflectedBeam.s")
|
||||
#endif
|
||||
|
||||
extern ColliderQuadInit D_808E3BF4;
|
||||
extern ColliderJntSphElementInit D_808E3C44[1];
|
||||
extern ColliderJntSphInit D_808E3C68;
|
||||
extern InitChainEntry D_808E3DB8[];
|
||||
void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
s32 pad;
|
||||
MirRay* this = THIS;
|
||||
Player* player = GET_PLAYER(globalCtx);
|
||||
MirRayShieldReflection reflection[6];
|
||||
s32 i;
|
||||
|
||||
extern UNK_TYPE D_060003F8;
|
||||
this->reflectIntensity = 0.0f;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/D_808E3DD0.s")
|
||||
if (!D_808E3BF0 && !this->unLit && func_80124088(globalCtx)) {
|
||||
Matrix_InsertMatrix(&player->shieldMf, MTXMODE_NEW);
|
||||
MirRay_SetIntensity(this, globalCtx);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2600.s")
|
||||
if (this->reflectIntensity <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E26C8.s")
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Init.s")
|
||||
func_8012C2DC(globalCtx->state.gfxCtx);
|
||||
Matrix_Scale(1.0f, 1.0f, this->reflectIntensity, MTXMODE_APPLY);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Destroy.s")
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(s8)(this->reflectIntensity * 100.0f));
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Update.s")
|
||||
AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_mir_ray_Matanimheader_0003F8));
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2C68.s")
|
||||
gSPDisplayList(POLY_XLU_DISP++, object_mir_ray_DL_000168);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2E1C.s")
|
||||
MirRay_SetupReflectionPolys(this, globalCtx, reflection);
|
||||
MirRay_RemoveSimilarReflections(reflection);
|
||||
MirRay_ReflectedBeam(this, globalCtx, reflection);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2FF8.s")
|
||||
if (reflection[0].reflectionPoly == NULL) {
|
||||
reflection[0].opacity = 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E30FC.s")
|
||||
for (i = 1; i < ARRAY_COUNT(reflection); i++) {
|
||||
if (reflection[i].reflectionPoly != NULL) {
|
||||
if (reflection[0].opacity < reflection[i].opacity) {
|
||||
reflection[0].opacity = reflection[i].opacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Draw.s")
|
||||
for (i = 0; i < ARRAY_COUNT(reflection); i++) {
|
||||
if (reflection[i].reflectionPoly != NULL) {
|
||||
Matrix_InsertTranslation(reflection[i].pos.x, reflection[i].pos.y, reflection[i].pos.z, MTXMODE_NEW);
|
||||
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);
|
||||
Matrix_InsertMatrix(&reflection[i].mtx, MTXMODE_APPLY);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E3984.s")
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_DECAL2);
|
||||
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, reflection[0].opacity);
|
||||
gSPDisplayList(POLY_XLU_DISP++, object_mir_ray_DL_0004B0);
|
||||
}
|
||||
}
|
||||
|
||||
D_808E3BF0 = true;
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
}
|
||||
}
|
||||
|
||||
// Computes if the Point (pointx, pointy, pointz) lies within the right conical frustum with one end centred at vecA
|
||||
// with radius radiusA, the other at vecB with radius radiusB
|
||||
s32 MirRay_CheckInFrustum(Vec3f* vecA, Vec3f* vecB, f32 pointx, f32 pointy, f32 pointz, s16 radiusA, s16 radiusB) {
|
||||
f32 coneRadius;
|
||||
f32 closestPtx;
|
||||
f32 closestPty;
|
||||
f32 closestPtz;
|
||||
Vec3f vecdiff;
|
||||
f32 dist;
|
||||
Vec3f sp5C;
|
||||
Vec3f sp50;
|
||||
Vec3f sp44;
|
||||
|
||||
vecdiff.x = vecB->x - vecA->x;
|
||||
vecdiff.y = vecB->y - vecA->y;
|
||||
vecdiff.z = vecB->z - vecA->z;
|
||||
if (1) {}
|
||||
|
||||
dist = SQ(vecdiff.x) + SQ(vecdiff.y) + SQ(vecdiff.z);
|
||||
|
||||
if (dist == 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dist =
|
||||
(((pointx - vecA->x) * vecdiff.x) + ((pointy - vecA->y) * vecdiff.y) + ((pointz - vecA->z) * vecdiff.z)) / dist;
|
||||
|
||||
// Closest point on line A-B to Point
|
||||
closestPtx = (vecdiff.x * dist) + vecA->x;
|
||||
closestPty = (vecdiff.y * dist) + vecA->y;
|
||||
closestPtz = (vecdiff.z * dist) + vecA->z;
|
||||
|
||||
// Diameter of the double cone on the perpendicular plane through the closest point
|
||||
coneRadius = ((radiusB - radiusA) * dist) + radiusA;
|
||||
|
||||
// If the Point is within the bounding double cone, check if it is in the frustum by checking whether it is between
|
||||
// the bounding planes
|
||||
if ((SQ(closestPtx - pointx) + SQ(closestPty - pointy) + SQ(closestPtz - pointz)) <= SQ(coneRadius)) {
|
||||
if (1) {}
|
||||
|
||||
// Stores the vector difference again
|
||||
Math_Vec3f_Diff(vecB, vecA, &sp5C);
|
||||
|
||||
sp50.x = pointx - vecA->x;
|
||||
sp50.y = pointy - vecA->y;
|
||||
sp50.z = pointz - vecA->z;
|
||||
|
||||
if (Math3D_Parallel(&sp5C, &sp50) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sp44.x = pointx - vecB->x;
|
||||
sp44.y = pointy - vecB->y;
|
||||
sp44.z = pointz - vecB->z;
|
||||
|
||||
if (Math3D_Parallel(&sp5C, &sp44) > 0.0f) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,39 @@
|
|||
|
||||
struct MirRay;
|
||||
|
||||
#define MIRRAY_LOCATION(thisx) ((thisx)->params)
|
||||
|
||||
// Locations of light beams in sMirRayData
|
||||
typedef enum {
|
||||
/* 0 */ MIRRAY_SPIRIT_BOMBCHUIWAROOM_DOWNLIGHT,
|
||||
/* 1 */ MIRRAY_SPIRIT_SUNBLOCKROOM_DOWNLIGHT,
|
||||
/* 2 */ MIRRAY_SPIRIT_SINGLECOBRAROOM_DOWNLIGHT,
|
||||
/* 3 */ MIRRAY_SPIRIT_ARMOSROOM_DOWNLIGHT,
|
||||
/* 4 */ MIRRAY_SPIRIT_TOPROOM_DOWNLIGHT,
|
||||
/* 5 */ MIRRAY_SPIRIT_TOPROOM_CEILINGMIRROR,
|
||||
/* 6 */ MIRRAY_SPIRIT_SINGLECOBRAROOM_COBRA,
|
||||
/* 7 */ MIRRAY_SPIRIT_TOPROOM_COBRA1,
|
||||
/* 8 */ MIRRAY_SPIRIT_TOPROOM_COBRA2,
|
||||
/* 9 */ MIRRAY_GANONSCASTLE_SPIRITTRIAL_DOWNLIGHT,
|
||||
/* 10 */ MIRRAY_MAX,
|
||||
} MirRayBeamLocations;
|
||||
|
||||
typedef struct MirRay {
|
||||
/* 0x000 */ Actor actor;
|
||||
/* 0x144 */ char unk_144[0x164];
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x0144 */ ColliderJntSph collider1;
|
||||
/* 0x0164 */ ColliderJntSphElement collider1Elements[1];
|
||||
/* 0x01A4 */ ColliderQuad collider2;
|
||||
/* 0x0224 */ f32 reflectIntensity; // Reflection occurs if it is positive, brightness depends on it
|
||||
/* 0x0228 */ Vec3f shieldCorners[6];
|
||||
/* 0x0270 */ f32 reflectRange;
|
||||
/* 0x0274 */ Vec3f sourcePt;
|
||||
/* 0x0280 */ Vec3f poolPt;
|
||||
/* 0x028C */ s16 sourceEndRad;
|
||||
/* 0x028E */ s16 poolEndRad;
|
||||
/* 0x0290 */ s16 lightPointRad;
|
||||
/* 0x0294 */ LightNode* lightNode;
|
||||
/* 0x0298 */ LightInfo lightInfo;
|
||||
/* 0x02A6 */ u8 unLit; // Conditioned on. set in Cobra?
|
||||
} MirRay; // size = 0x2A8
|
||||
|
||||
extern const ActorInit Mir_Ray_InitVars;
|
||||
|
|
|
|||
|
|
@ -6539,17 +6539,17 @@
|
|||
0x808E2444:("func_808E2444",),
|
||||
0x808E24B4:("BgCtowerRot_Update",),
|
||||
0x808E24D8:("BgCtowerRot_Draw",),
|
||||
0x808E2600:("func_808E2600",),
|
||||
0x808E26C8:("func_808E26C8",),
|
||||
0x808E2600:("MirRay_SetupCollider",),
|
||||
0x808E26C8:("MirRay_MakeShieldLight",),
|
||||
0x808E286C:("MirRay_Init",),
|
||||
0x808E2B04:("MirRay_Destroy",),
|
||||
0x808E2B7C:("MirRay_Update",),
|
||||
0x808E2C68:("func_808E2C68",),
|
||||
0x808E2E1C:("func_808E2E1C",),
|
||||
0x808E2FF8:("func_808E2FF8",),
|
||||
0x808E30FC:("func_808E30FC",),
|
||||
0x808E2C68:("MirRay_SetIntensity",),
|
||||
0x808E2E1C:("MirRay_SetupReflectionPolys",),
|
||||
0x808E2FF8:("MirRay_RemoveSimilarReflections",),
|
||||
0x808E30FC:("MirRay_ReflectedBeam",),
|
||||
0x808E36A4:("MirRay_Draw",),
|
||||
0x808E3984:("func_808E3984",),
|
||||
0x808E3984:("MirRay_CheckInFrustum",),
|
||||
0x808E3EF0:("EnSb_Init",),
|
||||
0x808E3FF0:("EnSb_Destroy",),
|
||||
0x808E401C:("EnSb_SpawnBubbles",),
|
||||
|
|
|
|||
|
|
@ -1975,12 +1975,6 @@ D_06000D94 = 0x06000D94;
|
|||
D_06007650 = 0x06007650;
|
||||
D_0600D658 = 0x0600D658;
|
||||
|
||||
// ovl_Mir_Ray
|
||||
|
||||
D_06000168 = 0x06000168;
|
||||
D_060003F8 = 0x060003F8;
|
||||
D_060004B0 = 0x060004B0;
|
||||
|
||||
// ovl_Mir_Ray3
|
||||
|
||||
D_06000168 = 0x06000168;
|
||||
|
|
|
|||
Loading…
Reference in New Issue