mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-09 15:47:46 +00:00
Player reflection and other imps
This commit is contained in:
@@ -978,6 +978,14 @@ void CBooRenderer::BeginScene()
|
||||
void CBooRenderer::EndScene()
|
||||
{
|
||||
CGraphics::EndScene();
|
||||
if (x2dc_reflectionAge >= 2)
|
||||
{
|
||||
// Delete reflection tex x14c_
|
||||
}
|
||||
else
|
||||
{
|
||||
++x2dc_reflectionAge;
|
||||
}
|
||||
}
|
||||
|
||||
void CBooRenderer::SetAmbientColor(const zeus::CColor& color)
|
||||
@@ -994,6 +1002,24 @@ u32 CBooRenderer::GetFPS()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CBooRenderer::CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter)
|
||||
{
|
||||
if (!x318_24_refectionDirty)
|
||||
return;
|
||||
x318_24_refectionDirty = false;
|
||||
x2dc_reflectionAge = 0;
|
||||
|
||||
BindReflectionDrawTarget();
|
||||
SViewport backupVp = g_Viewport;
|
||||
SetViewport(0, 0, 256, 256);
|
||||
CGraphics::g_BooMainCommandQueue->clearTarget();
|
||||
cb(ctx, CBooModel::g_ReflectViewPos);
|
||||
boo::SWindowRect rect(0, 0, 256, 256);
|
||||
CGraphics::g_BooMainCommandQueue->resolveBindTexture(x14c_reflectionTex, rect, false, 0, true, false);
|
||||
BindMainDrawTarget();
|
||||
SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
|
||||
}
|
||||
|
||||
void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength)
|
||||
{
|
||||
m_spaceWarpFilter.setStrength(strength);
|
||||
|
||||
@@ -134,6 +134,7 @@ class CBooRenderer : public IRenderer
|
||||
std::list<CFogVolumeFilter> m_fogVolumeFilters;
|
||||
std::list<CFogVolumeFilter>::iterator m_nextFogVolumeFilter;
|
||||
std::list<std::pair<zeus::CVector3f, float>> x2c4_spaceWarps;
|
||||
u32 x2dc_reflectionAge = 2;
|
||||
zeus::CColor x2e0_ = zeus::CColor::skWhite;
|
||||
zeus::CVector3f x2e4_ = {0.f, 1.f, 0.f};
|
||||
|
||||
@@ -231,7 +232,7 @@ public:
|
||||
void SetAmbientColor(const zeus::CColor&);
|
||||
void DrawString(const char*, int, int);
|
||||
u32 GetFPS();
|
||||
//void CacheReflection(TReflectionCallback, void*, bool);
|
||||
void CacheReflection(TReflectionCallback, void*, bool);
|
||||
void DrawSpaceWarp(const zeus::CVector3f&, float);
|
||||
void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol);
|
||||
void DrawXRayOutline(const zeus::CAABox&);
|
||||
|
||||
@@ -178,8 +178,11 @@ public:
|
||||
static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;}
|
||||
|
||||
static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos);
|
||||
static void KillCachedViewDepState();
|
||||
|
||||
static zeus::CVector3f g_ReflectViewPos;
|
||||
static void KillCachedViewDepState();
|
||||
static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf,
|
||||
zeus::CMatrix4f*& mtxsOut, float& alphaOut);
|
||||
};
|
||||
|
||||
class CModel
|
||||
|
||||
@@ -46,6 +46,83 @@ void CBooModel::KillCachedViewDepState()
|
||||
g_LastModelCached = nullptr;
|
||||
}
|
||||
|
||||
zeus::CVector3f CBooModel::g_ReflectViewPos = {};
|
||||
|
||||
static const zeus::CMatrix4f ReflectBaseMtx =
|
||||
{
|
||||
0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f,
|
||||
0.f, 0.f, 0.f, 1.f
|
||||
};
|
||||
|
||||
void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf,
|
||||
zeus::CMatrix4f*& mtxsOut, float& alphaOut)
|
||||
{
|
||||
zeus::CVector3f modelToPlayer = g_PlayerPosition - CGraphics::g_GXModelMatrix.origin;
|
||||
zeus::CVector3f modelToPlayerLocal = CGraphics::g_GXModelMatrix.transposeRotate(modelToPlayer);
|
||||
|
||||
zeus::CVector3f surfPos;
|
||||
float surfSize = 0.f;
|
||||
if (surf)
|
||||
{
|
||||
zeus::CVector3f surfCenter(surf->m_data.centroid);
|
||||
zeus::CVector3f surfNormal(surf->m_data.reflectionNormal);
|
||||
float dotDelta = surfNormal.dot(modelToPlayerLocal) - surfCenter.dot(surfNormal);
|
||||
surfPos = modelToPlayerLocal - surfNormal * dotDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
surfPos = model.x20_aabb.center();
|
||||
surfSize = (model.x20_aabb.max.x - model.x20_aabb.min.x) + (model.x20_aabb.max.y - model.x20_aabb.min.y) * 0.5f;
|
||||
}
|
||||
|
||||
if (g_Renderer->x318_24_refectionDirty)
|
||||
{
|
||||
zeus::CVector3f playerToPos = g_ReflectViewPos - g_PlayerPosition;
|
||||
zeus::CVector3f vecToPos = surfPos - g_PlayerPosition;
|
||||
if (playerToPos.dot(playerToPos) < vecToPos.dot(vecToPos))
|
||||
g_ReflectViewPos = surfPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ReflectViewPos = surfPos;
|
||||
g_Renderer->x318_24_refectionDirty = true;
|
||||
}
|
||||
|
||||
zeus::CVector3f playerToSurf = surfPos - modelToPlayerLocal;
|
||||
float distance = std::max(-(0.5f * surfSize - playerToSurf.magnitude()), FLT_EPSILON);
|
||||
if (distance >= 5.f)
|
||||
{
|
||||
alphaOut = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
alphaOut = (5.f - distance) / 5.f;
|
||||
|
||||
/* Indirect map matrix */
|
||||
mtxsOut[0] = (CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix).toMatrix4f();
|
||||
|
||||
/* Reflection map matrix */
|
||||
zeus::CVector3f v1 = playerToSurf * (1.f / surfSize);
|
||||
zeus::CVector3f v2 = v1.cross(zeus::CVector3f::skUp);
|
||||
if (v2.canBeNormalized())
|
||||
v2.normalize();
|
||||
else
|
||||
v2 = zeus::CVector3f::skRight;
|
||||
|
||||
float timeScale = 0.32258067f * (0.02f * distance + 1.f);
|
||||
float f1 = timeScale * g_TransformedTime;
|
||||
float f2 = timeScale * g_TransformedTime2;
|
||||
mtxsOut[1] = ReflectBaseMtx;
|
||||
mtxsOut[1][0][0] = f1 * v2.x;
|
||||
mtxsOut[1][1][0] = f1 * v2.y;
|
||||
mtxsOut[1][3][0] = -surfPos.dot(v2) * f1 + 0.5f;
|
||||
mtxsOut[1][2][1] = f2;
|
||||
mtxsOut[1][3][1] = -modelToPlayerLocal.z * f2;
|
||||
}
|
||||
}
|
||||
|
||||
CBooModel::~CBooModel()
|
||||
{
|
||||
if (m_prev)
|
||||
@@ -162,11 +239,24 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||
uniBufSize += thisSz;
|
||||
}
|
||||
|
||||
/* Surface reflection texmatrix uniform with first identity slot */
|
||||
size_t reflectOff = uniBufSize;
|
||||
uniBufSize += 256;
|
||||
for (const CBooSurface& surf : *x0_surfaces)
|
||||
{
|
||||
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
|
||||
if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye())
|
||||
uniBufSize += 256;
|
||||
}
|
||||
|
||||
/* Allocate resident buffer */
|
||||
m_uniformDataSize = uniBufSize;
|
||||
newInst.m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer, newInst.m_uniformBuffer, newInst.m_uniformBuffer};
|
||||
boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer,
|
||||
newInst.m_uniformBuffer,
|
||||
newInst.m_uniformBuffer,
|
||||
newInst.m_uniformBuffer};
|
||||
|
||||
/* Binding for each surface */
|
||||
newInst.m_shaderDataBindings.reserve(x0_surfaces->size());
|
||||
@@ -175,14 +265,16 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||
boo::ITexture* mbShadowTexs[] = {g_Renderer->m_ballShadowId,
|
||||
g_Renderer->x220_sphereRamp,
|
||||
g_Renderer->m_ballFade};
|
||||
size_t thisOffs[3];
|
||||
size_t thisSizes[3];
|
||||
size_t thisOffs[4];
|
||||
size_t thisSizes[4];
|
||||
|
||||
static const boo::PipelineStage stages[3] = {boo::PipelineStage::Vertex,
|
||||
static const boo::PipelineStage stages[4] = {boo::PipelineStage::Vertex,
|
||||
boo::PipelineStage::Vertex,
|
||||
boo::PipelineStage::Fragment};
|
||||
boo::PipelineStage::Fragment,
|
||||
boo::PipelineStage::Vertex};
|
||||
|
||||
/* Enumerate surfaces and build data bindings */
|
||||
size_t curReflect = reflectOff + 256;
|
||||
for (const CBooSurface& surf : *x0_surfaces)
|
||||
{
|
||||
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
|
||||
@@ -193,6 +285,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||
TCachedToken<CTexture>& tex = x1c_textures[idx];
|
||||
texs[texCount++] = tex.GetObj()->GetBooTexture();
|
||||
}
|
||||
texs[6] = g_Renderer->x14c_reflectionTex;
|
||||
texs[7] = g_Renderer->x220_sphereRamp;
|
||||
|
||||
if (m_skinBankCount)
|
||||
@@ -212,6 +305,18 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||
thisOffs[2] = lightOff;
|
||||
thisSizes[2] = lightSz;
|
||||
|
||||
bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye();
|
||||
if (useReflection)
|
||||
{
|
||||
thisOffs[3] = curReflect;
|
||||
curReflect += 256;
|
||||
}
|
||||
else
|
||||
{
|
||||
thisOffs[3] = reflectOff;
|
||||
}
|
||||
thisSizes[3] = 256;
|
||||
|
||||
const std::shared_ptr<hecl::Runtime::ShaderPipelines>& pipelines = m_pipelines->at(surf.m_data.matIdx);
|
||||
|
||||
newInst.m_shaderDataBindings.emplace_back();
|
||||
@@ -233,6 +338,11 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||
texCount = 3;
|
||||
ltexs = mbShadowTexs;
|
||||
}
|
||||
else if (useReflection)
|
||||
{
|
||||
texCount = 7;
|
||||
ltexs = texs;
|
||||
}
|
||||
else
|
||||
{
|
||||
texCount = mat.textureIdxs.size();
|
||||
@@ -240,7 +350,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
|
||||
}
|
||||
extendeds.push_back(
|
||||
ctx.newShaderDataBinding(pipeline, m_vtxFmt,
|
||||
x8_vbo, nullptr, xc_ibo, 3, bufs, stages,
|
||||
x8_vbo, nullptr, xc_ibo, 4, bufs, stages,
|
||||
thisOffs, thisSizes, texCount, ltexs, nullptr, nullptr));
|
||||
++idx;
|
||||
}
|
||||
@@ -704,6 +814,26 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
|
||||
lightingOut.fog = CGraphics::g_Fog;
|
||||
}
|
||||
|
||||
dataCur += sizeof(CModelShaders::LightingUniform);
|
||||
dataCur = dataOut + ROUND_UP_256(dataCur - dataOut);
|
||||
|
||||
/* Reflection texmtx uniform */
|
||||
zeus::CMatrix4f* identMtxs = reinterpret_cast<zeus::CMatrix4f*>(dataCur);
|
||||
identMtxs[0] = zeus::CMatrix4f();
|
||||
identMtxs[1] = zeus::CMatrix4f();
|
||||
u8* curReflect = dataCur + 256;
|
||||
for (const CBooSurface& surf : *x0_surfaces)
|
||||
{
|
||||
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
|
||||
if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye())
|
||||
{
|
||||
zeus::CMatrix4f* mtxs = reinterpret_cast<zeus::CMatrix4f*>(curReflect);
|
||||
float& alpha = reinterpret_cast<float&>(mtxs[2]);
|
||||
curReflect += 256;
|
||||
EnsureViewDepStateCached(*this, mat.flags.samusReflectionSurfaceEye() ? &surf : nullptr, mtxs, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
inst->m_uniformBuffer->unmap();
|
||||
}
|
||||
|
||||
@@ -807,10 +937,17 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
|
||||
matSet.m_shaders.reserve(matSet.m_matSet.materials.size());
|
||||
for (const MaterialSet::Material& mat : matSet.m_matSet.materials)
|
||||
{
|
||||
hecl::Backend::ReflectionType reflectionType;
|
||||
if (mat.flags.samusReflectionIndirectTexture())
|
||||
reflectionType = hecl::Backend::ReflectionType::Indirect;
|
||||
else if (mat.flags.samusReflection())
|
||||
reflectionType = hecl::Backend::ReflectionType::Simple;
|
||||
else
|
||||
reflectionType = hecl::Backend::ReflectionType::None;
|
||||
hecl::Runtime::ShaderTag tag(mat.heclIr,
|
||||
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
|
||||
hmdlMeta.weightCount * 4, 8, boo::Primitive(hmdlMeta.topology),
|
||||
true, true, true);
|
||||
reflectionType, true, true, true);
|
||||
matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader
|
||||
(tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory));
|
||||
}
|
||||
|
||||
@@ -51,4 +51,7 @@ CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, ResId model,
|
||||
{
|
||||
}
|
||||
|
||||
CSkinnedModel::FPointGenerator CSkinnedModel::g_PointGenFunc = nullptr;
|
||||
void* CSkinnedModel::g_PointGenCtx = nullptr;
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,15 @@ public:
|
||||
const std::experimental::optional<CVertexMorphEffect>& morphEffect,
|
||||
const float* morphMagnitudes);
|
||||
void Draw(const CModelFlags& drawFlags) const;
|
||||
|
||||
typedef void(*FPointGenerator)(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
|
||||
static void SetPointGeneratorFunc(void* ctx, FPointGenerator func)
|
||||
{
|
||||
g_PointGenFunc = func;
|
||||
g_PointGenCtx = ctx;
|
||||
}
|
||||
static FPointGenerator g_PointGenFunc;
|
||||
static void* g_PointGenCtx;
|
||||
};
|
||||
|
||||
class CMorphableSkinnedModel : public CSkinnedModel
|
||||
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
virtual void SetAmbientColor(const zeus::CColor&)=0;
|
||||
virtual void DrawString(const char*, int, int)=0;
|
||||
virtual u32 GetFPS()=0;
|
||||
//virtual void CacheReflection(TReflectionCallback, void*, bool)=0;
|
||||
virtual void CacheReflection(TReflectionCallback, void*, bool)=0;
|
||||
virtual void DrawSpaceWarp(const zeus::CVector3f&, float)=0;
|
||||
virtual void DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&)=0;
|
||||
virtual void DrawXRayOutline(const zeus::CAABox&)=0;
|
||||
|
||||
Reference in New Issue
Block a user