mirror of https://github.com/PrimeDecomp/prime.git
Add CSimpleShadow
This commit is contained in:
parent
181f0435d2
commit
19877f6fa2
|
@ -191,8 +191,8 @@ GetBounds__13CSimpleShadowCFv:
|
|||
/* 80105CE8 00102C48 38 21 00 30 */ addi r1, r1, 0x30
|
||||
/* 80105CEC 00102C4C 4E 80 00 20 */ blr
|
||||
|
||||
.global sub_80105cf0
|
||||
sub_80105cf0:
|
||||
.global SetAlwaysCalculateRadius__13CSimpleShadowFb
|
||||
SetAlwaysCalculateRadius__13CSimpleShadowFb:
|
||||
/* 80105CF0 00102C50 88 03 00 48 */ lbz r0, 0x48(r3)
|
||||
/* 80105CF4 00102C54 50 80 36 72 */ rlwimi r0, r4, 6, 0x19, 0x19
|
||||
/* 80105CF8 00102C58 98 03 00 48 */ stb r0, 0x48(r3)
|
||||
|
|
|
@ -2251,7 +2251,7 @@ lbl_800A2DE4:
|
|||
/* 800A30C0 000A0020 4B FA FC AD */ bl CreateShadow__6CActorFb
|
||||
/* 800A30C4 000A0024 80 7F 00 94 */ lwz r3, 0x94(r31)
|
||||
/* 800A30C8 000A0028 38 80 00 00 */ li r4, 0
|
||||
/* 800A30CC 000A002C 48 06 2C 25 */ bl sub_80105cf0
|
||||
/* 800A30CC 000A002C 48 06 2C 25 */ bl SetAlwaysCalculateRadius__13CSimpleShadowFb
|
||||
lbl_800A30D0:
|
||||
/* 800A30D0 000A0030 80 9F 00 90 */ lwz r4, 0x90(r31)
|
||||
/* 800A30D4 000A0034 28 04 00 00 */ cmplwi r4, 0
|
||||
|
|
|
@ -625,7 +625,7 @@ sub_801ad790:
|
|||
/* 801AD7E0 001AA740 4B EA 55 8D */ bl CreateShadow__6CActorFb
|
||||
/* 801AD7E4 001AA744 80 7F 00 94 */ lwz r3, 0x94(r31)
|
||||
/* 801AD7E8 001AA748 38 80 00 00 */ li r4, 0
|
||||
/* 801AD7EC 001AA74C 4B F5 85 05 */ bl sub_80105cf0
|
||||
/* 801AD7EC 001AA74C 4B F5 85 05 */ bl SetAlwaysCalculateRadius__13CSimpleShadowFb
|
||||
/* 801AD7F0 001AA750 7F E3 FB 78 */ mr r3, r31
|
||||
/* 801AD7F4 001AA754 38 80 00 02 */ li r4, 2
|
||||
/* 801AD7F8 001AA758 4B EC F9 19 */ bl BuildBodyController__10CPatternedF9EBodyType
|
||||
|
|
|
@ -156,7 +156,7 @@ LIBS = [
|
|||
["MetroidPrime/CDamageVulnerability", False],
|
||||
"MetroidPrime/CActorLights",
|
||||
["MetroidPrime/Enemies/CPatternedInfo", True],
|
||||
"MetroidPrime/CSimpleShadow",
|
||||
["MetroidPrime/CSimpleShadow", False],
|
||||
["MetroidPrime/CActorParameters", False],
|
||||
"MetroidPrime/CInGameGuiManager",
|
||||
"MetroidPrime/Enemies/CWarWasp",
|
||||
|
|
|
@ -31,6 +31,8 @@ public:
|
|||
return CMaterialFilter(include, exclude, kFT_IncludeExclude);
|
||||
}
|
||||
|
||||
static const CMaterialFilter& GetPassEverything() { return skPassEverything; }
|
||||
|
||||
bool Passes(const CMaterialList& other) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
// TODO: figure out what's going on here
|
||||
bool IsInvalid() const { return x20_valid == kI_Invalid; }
|
||||
// GetPlane__14CRayCastResultCFv
|
||||
const CPlane& GetPlane() const { return x10_plane; }
|
||||
const CVector3f& GetPoint() const { return x4_point; }
|
||||
// GetMaterial__14CRayCastResultCFv
|
||||
// Transform__14CRayCastResultFRC12CTransform4f
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
static void EndScene();
|
||||
static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass);
|
||||
static void StreamBegin(ERglPrimitive primitive);
|
||||
static void StreamColor(uint color);
|
||||
static void StreamColor(const CColor& color);
|
||||
static void StreamTexcoord(float u, float v);
|
||||
static void StreamVertex(float, float, float);
|
||||
|
|
|
@ -96,7 +96,5 @@ public:
|
|||
};
|
||||
|
||||
extern CTevCombiners::CTevPass CTevPass_805a5ebc;
|
||||
// TODO move to CGraphics
|
||||
extern CTevCombiners::CTevPass* PTR_skPassThru_805a8828;
|
||||
|
||||
#endif // _CTEVCOMBINERS
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
|
||||
class CAreaCollisionCache;
|
||||
class CCollisionInfo;
|
||||
class CCollisionPrimitive;
|
||||
|
@ -30,6 +32,9 @@ public:
|
|||
TUniqueId&, CCollisionInfo&, double&);
|
||||
static CRayCastResult RayStaticIntersection(const CStateManager&, const CVector3f&,
|
||||
const CVector3f&, float, const CMaterialFilter&);
|
||||
static CRayCastResult RayDynamicIntersection(const CStateManager& mgr, TUniqueId& idOut, const CVector3f& pos,
|
||||
const CVector3f& dir, float mag, const CMaterialFilter& filter,
|
||||
const TEntityList& nearList);
|
||||
|
||||
static void Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const TEntityList*);
|
||||
};
|
||||
|
|
|
@ -3,20 +3,39 @@
|
|||
|
||||
#include "types.h"
|
||||
|
||||
#include "Kyoto/Math/CTransform4f.hpp"
|
||||
#include "Kyoto/TToken.hpp"
|
||||
|
||||
class CAABox;
|
||||
class CStateManager;
|
||||
class CTransform4f;
|
||||
class CTexture;
|
||||
|
||||
class CSimpleShadow {
|
||||
public:
|
||||
CAABox GetBounds() const;
|
||||
const CTransform4f& GetTransform() const;
|
||||
CAABox GetMaxShadowBox(const CAABox& bounds) const;
|
||||
CSimpleShadow(float scale, float userAlpha, float maxObjHeight, float displacement);
|
||||
|
||||
void Calculate(const CAABox& bounds, const CTransform4f& xf, const CStateManager& mgr);
|
||||
void Render(const CTexture* tex) const;
|
||||
const CTransform4f& GetTransform() const;
|
||||
void SetUserAlpha(float);
|
||||
float GetMaxObjectHeight() const;
|
||||
|
||||
void SetAlwaysCalculateRadius(bool);
|
||||
CAABox GetBounds() const;
|
||||
CAABox GetMaxShadowBox(const CAABox& bounds) const;
|
||||
bool Valid() const;
|
||||
|
||||
private:
|
||||
// TODO
|
||||
CTransform4f x0_xf;
|
||||
float x30_scale;
|
||||
float x34_radius;
|
||||
float x38_userAlpha;
|
||||
float x3c_heightAlpha;
|
||||
float x40_maxObjHeight;
|
||||
float x44_displacement;
|
||||
bool x48_24_collision : 1;
|
||||
bool x48_25_alwaysCalculateRadius : 1;
|
||||
bool x48_26_radiusCalculated : 1;
|
||||
};
|
||||
|
||||
#endif // _CSIMPLESHADOW
|
||||
|
|
|
@ -139,6 +139,9 @@ public:
|
|||
const CActor*) const;
|
||||
bool RayCollideWorld(const CVector3f& start, const CVector3f& end, const TEntityList& nearList,
|
||||
const CMaterialFilter& filter, const CActor* damagee) const;
|
||||
|
||||
CRayCastResult RayStaticIntersection(const CVector3f& pos, const CVector3f& dir, float length,
|
||||
const CMaterialFilter& filter) const;
|
||||
CRayCastResult RayWorldIntersection(TUniqueId& idOut, const CVector3f& pos, const CVector3f& dir,
|
||||
float length, const CMaterialFilter& filter,
|
||||
const TEntityList& list) const;
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
#include "MetroidPrime/CSimpleShadow.hpp"
|
||||
|
||||
#include "MetroidPrime/CGameCollision.hpp"
|
||||
#include "MetroidPrime/CStateManager.hpp"
|
||||
|
||||
#include "Collision/CMaterialFilter.hpp"
|
||||
#include "Collision/CRayCastResult.hpp"
|
||||
|
||||
#include "MetaRender/CCubeRenderer.hpp"
|
||||
#include "Kyoto/Graphics/CColor.hpp"
|
||||
#include "Kyoto/Graphics/CGraphics.hpp"
|
||||
#include "Kyoto/Graphics/CTexture.hpp"
|
||||
#include "Kyoto/Math/CAABox.hpp"
|
||||
|
||||
CSimpleShadow::CSimpleShadow(float scale, float userAlpha, float maxObjHeight, float displacement)
|
||||
: x0_xf(CTransform4f::Identity())
|
||||
, x30_scale(scale)
|
||||
, x34_radius(1.f)
|
||||
, x38_userAlpha(userAlpha)
|
||||
, x3c_heightAlpha(1.f)
|
||||
, x40_maxObjHeight(maxObjHeight)
|
||||
, x44_displacement(displacement)
|
||||
, x48_24_collision(false)
|
||||
, x48_25_alwaysCalculateRadius(true)
|
||||
, x48_26_radiusCalculated(false) {}
|
||||
|
||||
void CSimpleShadow::Calculate(const CAABox& aabb, const CTransform4f& xf,
|
||||
const CStateManager& mgr) {
|
||||
x48_24_collision = false;
|
||||
float halfHeight = (aabb.GetMaxPoint().GetZ() - aabb.GetMinPoint().GetZ()) * 0.5f;
|
||||
float xExtent = aabb.GetMaxPoint().GetX() - aabb.GetMinPoint().GetX();
|
||||
float yExtent = aabb.GetMaxPoint().GetY() - aabb.GetMinPoint().GetY();
|
||||
|
||||
CVector3f pos = xf.GetTranslation() + CVector3f(0.f, 0.f, halfHeight);
|
||||
CVector3f dir(0.0f, 0.0f, -1.0f);
|
||||
CRayCastResult res =
|
||||
mgr.RayStaticIntersection(pos, dir, x40_maxObjHeight,
|
||||
CMaterialFilter::MakeExclude(CMaterialList(kMT_SeeThrough)));
|
||||
float height = x40_maxObjHeight;
|
||||
if (res.IsValid()) {
|
||||
x48_24_collision = true;
|
||||
height = res.GetTime();
|
||||
}
|
||||
CVector3f resPoint = res.GetPoint();
|
||||
CUnitVector3f resPlaneNormal = res.GetPlane().GetNormal();
|
||||
|
||||
if (height > 0.1f + halfHeight) {
|
||||
TEntityList nearList;
|
||||
mgr.BuildNearList(nearList, pos, dir, x40_maxObjHeight, CMaterialFilter::MakeInclude(CMaterialList(kMT_Floor)), nullptr);
|
||||
|
||||
TUniqueId cid = kInvalidUniqueId;
|
||||
CRayCastResult resD =
|
||||
CGameCollision::RayDynamicIntersection(mgr, cid, pos, dir, x40_maxObjHeight,
|
||||
CMaterialFilter::GetPassEverything(), nearList);
|
||||
if (resD.IsValid() && resD.GetTime() < height) {
|
||||
resPoint = resD.GetPoint();
|
||||
resPlaneNormal = resD.GetPlane().GetNormal();
|
||||
x48_24_collision = true;
|
||||
height = resD.GetTime();
|
||||
}
|
||||
}
|
||||
|
||||
if (x48_24_collision) {
|
||||
x3c_heightAlpha = 1.f - height / x40_maxObjHeight;
|
||||
CVector3f normalVector = resPlaneNormal;
|
||||
x0_xf = CTransform4f::LookAt(normalVector, CVector3f::Zero());
|
||||
x0_xf.SetTranslation(resPoint + x44_displacement * normalVector);
|
||||
if (x48_25_alwaysCalculateRadius || !x48_26_radiusCalculated) {
|
||||
x34_radius = sqrtf(xExtent * xExtent + yExtent * yExtent) * 0.5f;
|
||||
x48_26_radiusCalculated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSimpleShadow::Render(const CTexture* tex) const {
|
||||
if (!x48_24_collision)
|
||||
return;
|
||||
|
||||
CGraphics::DisableAllLights();
|
||||
gpRender->SetModelMatrix(x0_xf);
|
||||
tex->Load(GX_TEXMAP0, CTexture::kCM_Repeat);
|
||||
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate);
|
||||
CGraphics::SetTevOp(kTS_Stage1, CGraphics::kEnvPassthru);
|
||||
CGraphics::SetAlphaCompare(kAF_Always, 0, kAO_And, kAF_Always, 0);
|
||||
CGraphics::SetDepthWriteMode(true, kE_LEqual, false);
|
||||
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_InvSrcAlpha, kLO_Clear);
|
||||
float radius = x34_radius * x30_scale;
|
||||
CGraphics::StreamBegin(kP_Quads);
|
||||
CGraphics::StreamColor(CCast::ToUint8((x3c_heightAlpha * x38_userAlpha) * 255.f) - 0x100);
|
||||
CGraphics::StreamTexcoord(0.f, 0.f);
|
||||
CGraphics::StreamVertex(CVector3f(-radius, 0.f, -radius));
|
||||
CGraphics::StreamTexcoord(0.f, 1.f);
|
||||
CGraphics::StreamVertex(CVector3f(radius, 0.f, -radius));
|
||||
CGraphics::StreamTexcoord(1.f, 1.f);
|
||||
CGraphics::StreamVertex(CVector3f(radius, 0.f, radius));
|
||||
CGraphics::StreamTexcoord(1.f, 0.f);
|
||||
CGraphics::StreamVertex(CVector3f(-radius, 0.f, radius));
|
||||
CGraphics::StreamEnd();
|
||||
}
|
||||
|
||||
const CTransform4f& CSimpleShadow::GetTransform() const { return x0_xf; }
|
||||
|
||||
void CSimpleShadow::SetUserAlpha(float alpha) { x38_userAlpha = alpha; }
|
||||
|
||||
float CSimpleShadow::GetMaxObjectHeight() const { return x40_maxObjHeight; }
|
||||
|
||||
void CSimpleShadow::SetAlwaysCalculateRadius(bool b) { x48_25_alwaysCalculateRadius = b; }
|
||||
|
||||
CAABox CSimpleShadow::GetBounds() const {
|
||||
const CVector3f& translation = x0_xf.GetTranslation();
|
||||
float extent = x34_radius * x30_scale;
|
||||
return CAABox(translation - CVector3f(extent, extent, extent),
|
||||
translation + CVector3f(extent, extent, extent));
|
||||
}
|
||||
|
||||
CAABox CSimpleShadow::GetMaxShadowBox(const CAABox& aabb) const {
|
||||
float extent = x34_radius * x30_scale;
|
||||
CVector3f center = aabb.GetCenterPoint();
|
||||
CAABox expandedAABB = aabb;
|
||||
expandedAABB.AccumulateBounds(center + CVector3f(extent, extent, -GetMaxObjectHeight()));
|
||||
expandedAABB.AccumulateBounds(center + CVector3f(-extent, -extent, -GetMaxObjectHeight()));
|
||||
return expandedAABB;
|
||||
}
|
||||
|
||||
bool CSimpleShadow::Valid() const { return x48_24_collision; }
|
|
@ -191,7 +191,7 @@ void CCameraFilterPass::DrawWideScreen(const CColor& color, const CTexture* tex,
|
|||
tex->Load(GX_TEXMAP0, CTexture::kCM_Repeat);
|
||||
}
|
||||
CGraphics::SetTevOp(kTS_Stage0, CTevPass_805a5ebc);
|
||||
CGraphics::SetTevOp(kTS_Stage1, *PTR_skPassThru_805a8828);
|
||||
CGraphics::SetTevOp(kTS_Stage1, CGraphics::kEnvPassthru);
|
||||
|
||||
{
|
||||
CGraphics::StreamBegin(kP_TriangleStrip);
|
||||
|
|
Loading…
Reference in New Issue