mirror of https://github.com/AxioDL/metaforce.git
Finish CSamusDoll
This commit is contained in:
parent
4ff1475f0e
commit
b2d375a1d7
|
@ -22,6 +22,7 @@ struct ITweakGuiColors : BigYAML
|
|||
const zeus::CColor& shadow;
|
||||
};
|
||||
|
||||
virtual const zeus::CColor& GetInvPhazonSuitFilterMod() const=0;
|
||||
virtual const zeus::CColor& GetRadarStuffColor() const=0;
|
||||
virtual const zeus::CColor& GetRadarPlayerPaintColor() const=0;
|
||||
virtual const zeus::CColor& GetRadarEnemyPaintColor() const=0;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace DNAMP1
|
|||
struct CTweakGuiColors : public ITweakGuiColors
|
||||
{
|
||||
DECL_YAML
|
||||
DNAColor x4_;
|
||||
DNAColor x4_invPhazonSuitFilterMod;
|
||||
DNAColor x8_radarStuffColor;
|
||||
DNAColor xc_radarPlayerPaintColor;
|
||||
DNAColor x10_radarEnemyPaintColor;
|
||||
|
@ -140,6 +140,7 @@ struct CTweakGuiColors : public ITweakGuiColors
|
|||
CTweakGuiColors() = default;
|
||||
CTweakGuiColors(athena::io::IStreamReader& r) { this->read(r); }
|
||||
|
||||
const zeus::CColor& GetInvPhazonSuitFilterMod() const { return x4_invPhazonSuitFilterMod; }
|
||||
const zeus::CColor& GetRadarStuffColor() const { return x8_radarStuffColor; }
|
||||
const zeus::CColor& GetRadarPlayerPaintColor() const { return xc_radarPlayerPaintColor; }
|
||||
const zeus::CColor& GetRadarEnemyPaintColor() const { return x10_radarEnemyPaintColor; }
|
||||
|
|
|
@ -813,4 +813,10 @@ zeus::CAABox CAnimData::GetBoundingBox() const
|
|||
return search->second;
|
||||
}
|
||||
|
||||
void CAnimData::SubstituteModelData(const TCachedToken<CSkinnedModel>& model)
|
||||
{
|
||||
xd8_modelData = model;
|
||||
x108_aabb = xd8_modelData->GetModel()->GetAABB();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "CAdditiveAnimPlayback.hpp"
|
||||
#include "CCharLayoutInfo.hpp"
|
||||
#include "CAnimPlaybackParms.hpp"
|
||||
#include "IAnimReader.hpp"
|
||||
#include <set>
|
||||
|
||||
enum class EUserEventType
|
||||
|
@ -219,6 +220,7 @@ public:
|
|||
CSegId GetLocatorSegId(const std::string& name) const;
|
||||
zeus::CAABox GetBoundingBox(const zeus::CTransform& xf) const;
|
||||
zeus::CAABox GetBoundingBox() const;
|
||||
void SubstituteModelData(const TCachedToken<CSkinnedModel>& model);
|
||||
static void FreeCache();
|
||||
static void InitializeCache();
|
||||
const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; }
|
||||
|
|
|
@ -379,4 +379,54 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
|
|||
}
|
||||
}
|
||||
|
||||
void CModelData::InvSuitDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights,
|
||||
const zeus::CColor& alphaColor, const zeus::CColor& additiveColor)
|
||||
{
|
||||
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale));
|
||||
if (x10_animData)
|
||||
{
|
||||
CSkinnedModel& model = PickAnimatedModel(which);
|
||||
model.GetModelInst()->DisableAllLights();
|
||||
CModelFlags flags = {};
|
||||
|
||||
/* Z-prime */
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
x10_animData->Render(model, flags, {}, nullptr);
|
||||
|
||||
/* Normal Blended */
|
||||
lights->ActivateLights(*model.GetModelInst());
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = alphaColor;
|
||||
x10_animData->Render(model, flags, {}, nullptr);
|
||||
|
||||
/* Selection Additive */
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = additiveColor;
|
||||
x10_animData->Render(model, flags, {}, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
CBooModel& model = *PickStaticModel(which);
|
||||
model.DisableAllLights();
|
||||
CModelFlags flags = {};
|
||||
|
||||
/* Z-prime */
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
model.Draw(flags, nullptr, nullptr);
|
||||
|
||||
/* Normal Blended */
|
||||
lights->ActivateLights(model);
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = alphaColor;
|
||||
model.Draw(flags, nullptr, nullptr);
|
||||
|
||||
/* Selection Additive */
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = additiveColor;
|
||||
model.Draw(flags, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -139,6 +139,9 @@ public:
|
|||
void Render(EWhichModel, const zeus::CTransform& xf,
|
||||
const CActorLights* lights, const CModelFlags& drawFlags);
|
||||
|
||||
void InvSuitDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights,
|
||||
const zeus::CColor& color0, const zeus::CColor& color1);
|
||||
|
||||
CAnimData* AnimationData() { return x10_animData.get(); }
|
||||
const CAnimData* GetAnimationData() const { return x10_animData.get(); }
|
||||
const TLockedToken<CModel>& GetNormalModel() const { return x1c_normalModel; }
|
||||
|
|
|
@ -865,6 +865,14 @@ void CBooRenderer::DrawStaticGeometry(int modelCount, int mask, int targetMask)
|
|||
DrawSortedGeometry(modelCount, mask, targetMask);
|
||||
}
|
||||
|
||||
void CBooRenderer::DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly)
|
||||
{
|
||||
model.GetInstance().DrawFlat(unsortedOnly ?
|
||||
CBooModel::ESurfaceSelection::UnsortedOnly :
|
||||
CBooModel::ESurfaceSelection::All,
|
||||
flags.m_extendedShader);
|
||||
}
|
||||
|
||||
void CBooRenderer::PostRenderFogs()
|
||||
{
|
||||
for (const auto& warp : x2c4_spaceWarps)
|
||||
|
@ -974,6 +982,14 @@ void CBooRenderer::BeginScene()
|
|||
CGraphics::SetViewport(0, 0, g_Viewport.x8_width, g_Viewport.xc_height);
|
||||
CGraphics::SetPerspective(75.f, CGraphics::g_ProjAspect, 1.f, 4096.f);
|
||||
CGraphics::SetModelMatrix(zeus::CTransform::Identity());
|
||||
#if 0
|
||||
if (x310_phazonSuitMaskCountdown != 0)
|
||||
{
|
||||
--x310_phazonSuitMaskCountdown;
|
||||
if (x310_phazonSuitMaskCountdown == 0)
|
||||
x314_phazonSuitMask.reset();
|
||||
}
|
||||
#endif
|
||||
x318_27_currentRGBA6 = x318_26_requestRGBA6;
|
||||
if (!x318_31_persistRGBA6)
|
||||
x318_26_requestRGBA6 = false;
|
||||
|
@ -1175,6 +1191,53 @@ void CBooRenderer::SetWorldLightFadeLevel(float level)
|
|||
x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f);
|
||||
}
|
||||
|
||||
void CBooRenderer::ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, /*const CTexture& maskTex,*/
|
||||
const CTexture& indTex, const zeus::CColor& modColor,
|
||||
float scale, float offX, float offY)
|
||||
{
|
||||
m_phazonSuitFilter.draw(modColor, scale, offX * scale, offY * scale);
|
||||
}
|
||||
|
||||
void CBooRenderer::ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor /*, const CTexture& maskTex*/)
|
||||
{
|
||||
m_phazonSuitFilter.draw(modColor, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
void CBooRenderer::DoPhazonSuitIndirectAlphaBlur(float blurRadius /*, float f2*/, const TLockedToken<CTexture>& indTex)
|
||||
{
|
||||
m_phazonSuitFilter.drawBlurPasses(blurRadius, indTex.IsLoaded() ? indTex.GetObj() : nullptr);
|
||||
}
|
||||
|
||||
void CBooRenderer::DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod, const TLockedToken<CTexture>& indTex,
|
||||
const zeus::CColor& indirectMod, float blurRadius,
|
||||
float scale, float offX, float offY)
|
||||
{
|
||||
/* Indirect background already in binding 0 */
|
||||
|
||||
/* Resolve alpha channel of just-drawn phazon suit into binding 1 */
|
||||
SClipScreenRect rect;
|
||||
rect.x4_left = g_Viewport.x0_left;
|
||||
rect.x8_top = g_Viewport.x4_top;
|
||||
rect.xc_width = g_Viewport.x8_width;
|
||||
rect.x10_height = g_Viewport.xc_height;
|
||||
CGraphics::ResolveSpareTexture(rect, 1);
|
||||
|
||||
/* Perform blur filter and resolve into binding 2 */
|
||||
DoPhazonSuitIndirectAlphaBlur(blurRadius, indTex);
|
||||
|
||||
/* Draw effect; subtracting binding 1 from binding 2 for the filter 'cutout' */
|
||||
if (indTex && indTex.IsLoaded())
|
||||
ReallyDrawPhazonSuitIndirectEffect(zeus::CColor::skWhite, *indTex, indirectMod, scale, offX, offY);
|
||||
else
|
||||
ReallyDrawPhazonSuitEffect(nonIndirectMod);
|
||||
}
|
||||
|
||||
void CBooRenderer::AllocatePhazonSuitMaskTexture()
|
||||
{
|
||||
x318_26_requestRGBA6 = true;
|
||||
x310_phazonSuitMaskCountdown = 2;
|
||||
}
|
||||
|
||||
void CBooRenderer::FindOverlappingWorldModels(std::vector<u32>& modelBits, const zeus::CAABox& aabb) const
|
||||
{
|
||||
u32 bitmapWords = 0;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Shaders/CSpaceWarpFilter.hpp"
|
||||
#include "Shaders/CFogVolumePlaneShader.hpp"
|
||||
#include "Shaders/CFogVolumeFilter.hpp"
|
||||
#include "Shaders/CPhazonSuitFilter.hpp"
|
||||
#include "CRandom16.hpp"
|
||||
#include "CPVSVisSet.hpp"
|
||||
#include "zeus/CRectangle.hpp"
|
||||
|
@ -149,6 +150,10 @@ class CBooRenderer : public IRenderer
|
|||
|
||||
std::vector<CLight> x300_dynamicLights;
|
||||
|
||||
u32 x310_phazonSuitMaskCountdown = 0;
|
||||
//std::unique_ptr<CTexture> x314_phazonSuitMask;
|
||||
CPhazonSuitFilter m_phazonSuitFilter;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
|
@ -182,6 +187,12 @@ class CBooRenderer : public IRenderer
|
|||
CFogVolumePlaneShader* fvs);
|
||||
void SetupRendererStates() const;
|
||||
|
||||
void ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, /*const CTexture& maskTex,*/
|
||||
const CTexture& indTex, const zeus::CColor& modColor,
|
||||
float scale, float offX, float offY);
|
||||
void ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor /*, const CTexture& maskTex*/);
|
||||
void DoPhazonSuitIndirectAlphaBlur(float blurRadius /*, float f2*/, const TLockedToken<CTexture>& indTex);
|
||||
|
||||
public:
|
||||
CBooRenderer(IObjectStore& store, IFactory& resFac);
|
||||
|
||||
|
@ -196,6 +207,7 @@ public:
|
|||
void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask);
|
||||
void DrawSortedGeometry(int areaIdx, int mask, int targetMask);
|
||||
void DrawStaticGeometry(int areaIdx, int mask, int targetMask);
|
||||
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly);
|
||||
void PostRenderFogs();
|
||||
void AddParticleGen(const CParticleGen&);
|
||||
void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int);
|
||||
|
@ -248,6 +260,10 @@ public:
|
|||
void PrepareDynamicLights(const std::vector<CLight>& lights);
|
||||
void SetWorldLightMultiplyColor(const zeus::CColor& color);
|
||||
void SetWorldLightFadeLevel(float level);
|
||||
void DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod, const TLockedToken<CTexture>& indTex,
|
||||
const zeus::CColor& indirectMod, float blurRadius,
|
||||
float indScale, float indOffX, float indOffY);
|
||||
void AllocatePhazonSuitMaskTexture();
|
||||
|
||||
void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb,
|
||||
const CModel* model, const CSkinnedModel* sModel);
|
||||
|
|
|
@ -14,7 +14,8 @@ if(WIN32)
|
|||
Shaders/CFogVolumeFilterHLSL.cpp
|
||||
Shaders/CEnergyBarShaderHLSL.cpp
|
||||
Shaders/CRadarPaintShaderHLSL.cpp
|
||||
Shaders/CMapSurfaceShaderHLSL.cpp)
|
||||
Shaders/CMapSurfaceShaderHLSL.cpp
|
||||
Shaders/CPhazonSuitFilterHLSL.cpp)
|
||||
elseif(BOO_HAS_METAL)
|
||||
set(PLAT_SRCS
|
||||
Shaders/CLineRendererShadersMetal.cpp
|
||||
|
@ -31,7 +32,8 @@ elseif(BOO_HAS_METAL)
|
|||
Shaders/CFogVolumeFilterMetal.cpp
|
||||
Shaders/CEnergyBarShaderMetal.cpp
|
||||
Shaders/CRadarPaintShaderMetal.cpp
|
||||
Shaders/CMapSurfaceShaderMetal.cpp)
|
||||
Shaders/CMapSurfaceShaderMetal.cpp
|
||||
Shaders/CPhazonSuitFilterMetal.cpp)
|
||||
endif()
|
||||
|
||||
set(GRAPHICS_SOURCES
|
||||
|
@ -70,6 +72,7 @@ set(GRAPHICS_SOURCES
|
|||
Shaders/CEnergyBarShader.hpp Shaders/CEnergyBarShader.cpp Shaders/CEnergyBarShaderGLSL.cpp
|
||||
Shaders/CRadarPaintShader.hpp Shaders/CRadarPaintShader.cpp Shaders/CRadarPaintShaderGLSL.cpp
|
||||
Shaders/CMapSurfaceShader.hpp Shaders/CMapSurfaceShader.cpp Shaders/CMapSurfaceShaderGLSL.cpp
|
||||
Shaders/CPhazonSuitFilter.hpp Shaders/CPhazonSuitFilter.cpp Shaders/CPhazonSuitFilterGLSL.cpp
|
||||
${PLAT_SRCS})
|
||||
|
||||
runtime_add_list(Graphics GRAPHICS_SOURCES)
|
||||
|
|
|
@ -23,7 +23,7 @@ class CModel;
|
|||
|
||||
struct CModelFlags
|
||||
{
|
||||
u8 x0_blendMode = 0; /* Blend state 3/5 enable additive */
|
||||
u8 x0_blendMode = 0; /* >6: additive, >4: blend, else opaque */
|
||||
u8 x1_matSetIdx = 0;
|
||||
EExtendedShader m_extendedShader = EExtendedShader::Flat;
|
||||
u16 x2_flags = 0; /* Flags */
|
||||
|
@ -36,6 +36,8 @@ struct CModelFlags
|
|||
: x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {}
|
||||
|
||||
/* Flags
|
||||
0x1: depth equal
|
||||
0x2: depth update
|
||||
0x4: render without texture lock
|
||||
0x8: depth greater
|
||||
0x10: depth non-inclusive
|
||||
|
@ -79,6 +81,13 @@ public:
|
|||
void UnlockTextures();
|
||||
};
|
||||
|
||||
enum class ESurfaceSelection
|
||||
{
|
||||
UnsortedOnly,
|
||||
SortedOnly,
|
||||
All
|
||||
};
|
||||
|
||||
private:
|
||||
CBooModel* m_next = nullptr;
|
||||
CBooModel* m_prev = nullptr;
|
||||
|
@ -148,6 +157,7 @@ public:
|
|||
|
||||
bool IsOpaque() const {return x3c_firstSortedSurface == nullptr;}
|
||||
void ActivateLights(const std::vector<CLight>& lights);
|
||||
void DisableAllLights();
|
||||
void RemapMaterialData(SShader& shader);
|
||||
bool TryLockTextures() const;
|
||||
void UnlockTextures() const;
|
||||
|
@ -165,6 +175,8 @@ public:
|
|||
void Draw(const CModelFlags& flags,
|
||||
const CSkinRules* cskr,
|
||||
const CPoseAsTransforms* pose) const;
|
||||
void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const;
|
||||
|
||||
|
||||
const MaterialSet::Material& GetMaterialByIndex(int idx) const
|
||||
{
|
||||
|
@ -217,6 +229,7 @@ public:
|
|||
void DrawUnsortedParts(const CModelFlags& flags) const;
|
||||
void Draw(const CModelFlags& flags) const;
|
||||
bool IsLoaded(int shaderIdx) const;
|
||||
void Touch(int shaderIdx) { x28_modelInst->Touch(shaderIdx); }
|
||||
|
||||
const zeus::CAABox& GetAABB() const {return m_aabb;}
|
||||
CBooModel& GetInstance() {return *x28_modelInst;}
|
||||
|
|
|
@ -425,6 +425,19 @@ void CBooModel::ActivateLights(const std::vector<CLight>& lights)
|
|||
}
|
||||
}
|
||||
|
||||
void CBooModel::DisableAllLights()
|
||||
{
|
||||
m_lightingData.ambient = zeus::CColor::skBlack;
|
||||
|
||||
for (size_t curLight = 0 ; curLight<URDE_MAX_LIGHTS ; ++curLight)
|
||||
{
|
||||
CModelShaders::Light& lightOut = m_lightingData.lights[curLight];
|
||||
lightOut.color = zeus::CColor::skClear;
|
||||
lightOut.linAtt[0] = 1.f;
|
||||
lightOut.angAtt[0] = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::RemapMaterialData(SShader& shader)
|
||||
{
|
||||
x4_matSet = &shader.m_matSet;
|
||||
|
@ -461,6 +474,33 @@ void CBooModel::UnlockTextures() const
|
|||
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
|
||||
}
|
||||
|
||||
void CBooModel::DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const
|
||||
{
|
||||
const CBooSurface* surf;
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = extendedIdx;
|
||||
|
||||
if (sel != ESurfaceSelection::SortedOnly)
|
||||
{
|
||||
surf = x38_firstUnsortedSurface;
|
||||
while (surf)
|
||||
{
|
||||
DrawSurface(*surf, flags);
|
||||
surf = surf->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (sel != ESurfaceSelection::UnsortedOnly)
|
||||
{
|
||||
surf = x3c_firstSortedSurface;
|
||||
while (surf)
|
||||
{
|
||||
DrawSurface(*surf, flags);
|
||||
surf = surf->m_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBooModel::DrawAlphaSurfaces(const CModelFlags& flags) const
|
||||
{
|
||||
const CBooSurface* surf = x3c_firstSortedSurface;
|
||||
|
|
|
@ -21,6 +21,7 @@ class CModel;
|
|||
class CSkinnedModel;
|
||||
class CPVSVisSet;
|
||||
struct CAreaRenderOctTree;
|
||||
class CModelFlags;
|
||||
|
||||
class IRenderer
|
||||
{
|
||||
|
@ -51,6 +52,7 @@ public:
|
|||
virtual void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask)=0;
|
||||
virtual void DrawSortedGeometry(int areaIdx, int mask, int targetMask)=0;
|
||||
virtual void DrawStaticGeometry(int areaIdx, int mask, int targetMask)=0;
|
||||
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly)=0;
|
||||
virtual void PostRenderFogs()=0;
|
||||
virtual void AddParticleGen(const CParticleGen&)=0;
|
||||
virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0;
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
#include "CPhazonSuitFilter.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CPhazonSuitFilter::drawBlurPasses(float radius, const CTexture* indTex)
|
||||
{
|
||||
if (!m_dataBind || indTex != m_indTex)
|
||||
{
|
||||
m_indTex = indTex;
|
||||
m_gfxTok = CGraphics::CommitResources(
|
||||
[this](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
m_uniBufBlurX = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f), 1);
|
||||
m_uniBufBlurY = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f), 1);
|
||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f) * 2, 1);
|
||||
|
||||
struct BlurVert
|
||||
{
|
||||
zeus::CVector3f pos;
|
||||
zeus::CVector2f uv;
|
||||
} blurVerts[4] =
|
||||
{
|
||||
{{-1.f, 1.f, 0.f}, {0.f, 1.f}},
|
||||
{{-1.f, -1.f, 0.f}, {0.f, 0.f}},
|
||||
{{ 1.f, 1.f, 0.f}, {1.f, 1.f}},
|
||||
{{ 1.f, -1.f, 0.f}, {1.f, 0.f}}
|
||||
};
|
||||
m_blurVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, blurVerts, sizeof(BlurVert), 4);
|
||||
|
||||
struct Vert
|
||||
{
|
||||
zeus::CVector3f pos;
|
||||
zeus::CVector2f screenUv;
|
||||
zeus::CVector2f indUv;
|
||||
zeus::CVector2f maskUv;
|
||||
} verts[4] =
|
||||
{
|
||||
{{-1.f, 1.f, 0.f}, {0.01f, 0.99f}, {0.f, 1.f}, {0.f, 1.f}},
|
||||
{{-1.f, -1.f, 0.f}, {0.01f, 0.01f}, {0.f, 1.f}, {0.f, 1.f}},
|
||||
{{ 1.f, 1.f, 0.f}, {0.99f, 0.99f}, {0.f, 1.f}, {0.f, 1.f}},
|
||||
{{ 1.f, -1.f, 0.f}, {0.99f, 0.01f}, {0.f, 1.f}, {0.f, 1.f}}
|
||||
};
|
||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4);
|
||||
|
||||
m_dataBind = TShader<CPhazonSuitFilter>::BuildShaderDataBinding(ctx, *this);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
SClipScreenRect rect;
|
||||
rect.x4_left = g_Viewport.x0_left;
|
||||
rect.x8_top = g_Viewport.x4_top;
|
||||
rect.xc_width = g_Viewport.x8_width;
|
||||
rect.x10_height = g_Viewport.xc_height;
|
||||
|
||||
/* X Pass */
|
||||
zeus::CVector4f blurDir = zeus::CVector4f{2.f * radius / g_Viewport.x8_width, 0.f, 0.f, 0.f};
|
||||
m_uniBufBlurX->load(&blurDir, sizeof(zeus::CVector4f));
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBindBlurX);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
CGraphics::ResolveSpareTexture(rect, 2);
|
||||
|
||||
/* Y Pass */
|
||||
blurDir = zeus::CVector4f{0.f, 2.f * radius / g_Viewport.xc_height, 0.f, 0.f};
|
||||
m_uniBufBlurY->load(&blurDir, sizeof(zeus::CVector4f));
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBindBlurY);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
CGraphics::ResolveSpareTexture(rect, 2);
|
||||
}
|
||||
|
||||
void CPhazonSuitFilter::draw(const zeus::CColor& color,
|
||||
float indScale, float indOffX, float indOffY)
|
||||
{
|
||||
struct Uniform
|
||||
{
|
||||
zeus::CColor color;
|
||||
zeus::CVector4f indScaleOff;
|
||||
} uniform =
|
||||
{
|
||||
color,
|
||||
zeus::CVector4f(indScale, indScale, indOffX, indOffY)
|
||||
};
|
||||
|
||||
m_uniBuf->load(&uniform, sizeof(Uniform));
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
}
|
||||
|
||||
void CPhazonSuitFilter::Shutdown() {}
|
||||
|
||||
URDE_SPECIALIZE_SHADER(CPhazonSuitFilter)
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __URDE_CPHAZONSUITFILTER_HPP__
|
||||
#define __URDE_CPHAZONSUITFILTER_HPP__
|
||||
|
||||
#include "TShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CTexture;
|
||||
|
||||
class CPhazonSuitFilter
|
||||
{
|
||||
friend struct CPhazonSuitFilterGLDataBindingFactory;
|
||||
friend struct CPhazonSuitFilterVulkanDataBindingFactory;
|
||||
friend struct CPhazonSuitFilterMetalDataBindingFactory;
|
||||
friend struct CPhazonSuitFilterD3DDataBindingFactory;
|
||||
|
||||
boo::GraphicsDataToken m_gfxTok;
|
||||
boo::IGraphicsBufferD* m_uniBufBlurX;
|
||||
boo::IGraphicsBufferD* m_uniBufBlurY;
|
||||
boo::IGraphicsBufferD* m_uniBuf;
|
||||
boo::IGraphicsBufferS* m_blurVbo;
|
||||
boo::IGraphicsBufferS* m_vbo;
|
||||
const CTexture* m_indTex = nullptr;
|
||||
boo::IShaderDataBinding* m_dataBindBlurX = nullptr;
|
||||
boo::IShaderDataBinding* m_dataBindBlurY = nullptr;
|
||||
boo::IShaderDataBinding* m_dataBind = nullptr;
|
||||
|
||||
public:
|
||||
void drawBlurPasses(float radius, const CTexture* indTex);
|
||||
void draw(const zeus::CColor& color,
|
||||
float indScale, float indOffX, float indOffY);
|
||||
|
||||
using _CLS = CPhazonSuitFilter;
|
||||
#include "TShaderDecl.hpp"
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CPHAZONSUITFILTER_HPP__
|
|
@ -0,0 +1,340 @@
|
|||
#include "CPhazonSuitFilter.hpp"
|
||||
#include "TShader.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"layout(location=0) in vec4 posIn;\n"
|
||||
"layout(location=1) in vec4 screenUvIn;\n"
|
||||
"layout(location=2) in vec4 indUvIn;\n"
|
||||
"layout(location=3) in vec4 maskUvIn;\n"
|
||||
"\n"
|
||||
"UBINDING0 uniform PhazonSuitUniform\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 indScaleOff;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 indScaleOff;\n"
|
||||
" vec2 screenUv;\n"
|
||||
" vec2 indUv;\n"
|
||||
" vec2 maskUv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vtf.color = color;\n"
|
||||
" vtf.indScaleOff = indScaleOff;\n"
|
||||
" vtf.screenUv = screenUvIn.xy;\n"
|
||||
" vtf.indUv = indUvIn.xy;\n"
|
||||
" vtf.maskUv = maskUvIn.xy;\n"
|
||||
" gl_Position = vec4(posIn.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* IndFS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 indScaleOff;\n"
|
||||
" vec2 screenUv;\n"
|
||||
" vec2 indUv;\n"
|
||||
" vec2 maskUv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"TBINDING0 uniform sampler2D screenTex;\n"
|
||||
"TBINDING1 uniform sampler2D indTex;\n"
|
||||
"TBINDING2 uniform sampler2D maskTex;\n"
|
||||
"TBINDING3 uniform sampler2D maskTexBlur;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec2 indUv = (texture(indTex, vtf.indUv).rg - vec2(0.5, 0.5)) * \n"
|
||||
" vtf.indScaleOff.xy + vtf.indScaleOff.zw;\n"
|
||||
" colorOut = vtf.color * texture(screenTex, indUv + vtf.screenUv) * \n"
|
||||
" (texture(maskTexBlur, vtf.maskUv).a - texture(maskTex, vtf.maskUv).a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
" vec4 indScaleOff;\n"
|
||||
" vec2 screenUv;\n"
|
||||
" vec2 indUv;\n"
|
||||
" vec2 maskUv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"TBINDING0 uniform sampler2D screenTex;\n"
|
||||
"TBINDING1 uniform sampler2D maskTex;\n"
|
||||
"TBINDING2 uniform sampler2D maskTexBlur;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color * texture(screenTex, vtf.screenUv) * \n"
|
||||
" (texture(maskTexBlur, vtf.maskUv).a - texture(maskTex, vtf.maskUv).a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* BlurVS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"layout(location=0) in vec4 posIn;\n"
|
||||
"layout(location=3) in vec4 uvIn;\n"
|
||||
"\n"
|
||||
"UBINDING0 uniform PhazonSuitBlurUniform\n"
|
||||
"{\n"
|
||||
" vec4 blurDir;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec2 uv;\n"
|
||||
" vec2 blurDir;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vtf.uv = uvIn.xy;\n"
|
||||
" vtf.blurDir = blurDir.xy;\n"
|
||||
" gl_Position = vec4(posIn.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* BlurFS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec2 uv;\n"
|
||||
" vec2 blurDir;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"TBINDING0 uniform sampler2D maskTex;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" //this will be our alpha sum\n"
|
||||
" float sum = 0.0;\n"
|
||||
"\n"
|
||||
" //apply blurring, using a 9-tap filter with predefined gaussian weights\n"
|
||||
"\n"
|
||||
" sum += texture(maskTex, vtf.uv - 4.0 * vtf.blurDir).a * 0.0162162162;\n"
|
||||
" sum += texture(maskTex, vtf.uv - 3.0 * vtf.blurDir).a * 0.0540540541;\n"
|
||||
" sum += texture(maskTex, vtf.uv - 2.0 * vtf.blurDir).a * 0.1216216216;\n"
|
||||
" sum += texture(maskTex, vtf.uv - 1.0 * vtf.blurDir).a * 0.1945945946;\n"
|
||||
"\n"
|
||||
" sum += texture(maskTex, vtf.uv).a * 0.2270270270;\n"
|
||||
"\n"
|
||||
" sum += texture(maskTex, vtf.uv - 1.0 * vtf.blurDir).a * 0.1945945946;\n"
|
||||
" sum += texture(maskTex, vtf.uv - 2.0 * vtf.blurDir).a * 0.1216216216;\n"
|
||||
" sum += texture(maskTex, vtf.uv - 3.0 * vtf.blurDir).a * 0.0540540541;\n"
|
||||
" sum += texture(maskTex, vtf.uv - 4.0 * vtf.blurDir).a * 0.0162162162;\n"
|
||||
"\n"
|
||||
" colorOut = vec4(1.0, 1.0, 1.0, sum);\n"
|
||||
"}\n";
|
||||
|
||||
URDE_DECL_SPECIALIZE_SHADER(CPhazonSuitFilter)
|
||||
|
||||
static boo::IVertexFormat* s_VtxFmt = nullptr;
|
||||
static boo::IVertexFormat* s_BlurVtxFmt = nullptr;
|
||||
static boo::IShaderPipeline* s_IndPipeline = nullptr;
|
||||
static boo::IShaderPipeline* s_Pipeline = nullptr;
|
||||
static boo::IShaderPipeline* s_BlurPipeline = nullptr;
|
||||
|
||||
struct CPhazonSuitFilterGLDataBindingFactory : TShader<CPhazonSuitFilter>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CPhazonSuitFilter& filter)
|
||||
{
|
||||
boo::GLDataFactory::Context& cctx = static_cast<boo::GLDataFactory::Context&>(ctx);
|
||||
|
||||
const boo::VertexElementDescriptor BlurVtxVmt[] =
|
||||
{
|
||||
{filter.m_blurVbo, nullptr, boo::VertexSemantic::Position4},
|
||||
{filter.m_blurVbo, nullptr, boo::VertexSemantic::UV4}
|
||||
};
|
||||
boo::IVertexFormat* blurVtxFmt = ctx.newVertexFormat(2, BlurVtxVmt);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBufBlurX};
|
||||
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
|
||||
boo::ITexture* texs[4];
|
||||
int texBindIdxs[4];
|
||||
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 1;
|
||||
filter.m_dataBindBlurX = cctx.newShaderDataBinding(s_BlurPipeline,
|
||||
blurVtxFmt, filter.m_blurVbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, 1, texs, texBindIdxs, nullptr);
|
||||
|
||||
bufs[0] = filter.m_uniBufBlurY;
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 2;
|
||||
filter.m_dataBindBlurY = cctx.newShaderDataBinding(s_BlurPipeline,
|
||||
blurVtxFmt, filter.m_blurVbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, 1, texs, texBindIdxs, nullptr);
|
||||
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{filter.m_vbo, nullptr, boo::VertexSemantic::Position4},
|
||||
{filter.m_vbo, nullptr, boo::VertexSemantic::UV4, 0},
|
||||
{filter.m_vbo, nullptr, boo::VertexSemantic::UV4, 1},
|
||||
{filter.m_vbo, nullptr, boo::VertexSemantic::UV4, 2}
|
||||
};
|
||||
boo::IVertexFormat* vtxFmt = ctx.newVertexFormat(4, VtxVmt);
|
||||
|
||||
bufs[0] = filter.m_uniBuf;
|
||||
size_t texCount;
|
||||
if (filter.m_indTex)
|
||||
{
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 0;
|
||||
texs[1] = filter.m_indTex->GetBooTexture();
|
||||
texBindIdxs[1] = 0;
|
||||
texs[2] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[2] = 1;
|
||||
texs[3] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[3] = 2;
|
||||
texCount = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 0;
|
||||
texs[1] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[1] = 1;
|
||||
texs[2] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[2] = 2;
|
||||
texCount = 3;
|
||||
}
|
||||
|
||||
return cctx.newShaderDataBinding(filter.m_indTex ? s_IndPipeline : s_Pipeline,
|
||||
vtxFmt, filter.m_vbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, texCount, texs, texBindIdxs, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
struct CPhazonSuitFilterVulkanDataBindingFactory : TShader<CPhazonSuitFilter>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CPhazonSuitFilter& filter)
|
||||
{
|
||||
boo::VulkanDataFactory::Context& cctx = static_cast<boo::VulkanDataFactory::Context&>(ctx);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBufBlurX};
|
||||
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
|
||||
boo::ITexture* texs[4];
|
||||
int texBindIdxs[4];
|
||||
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 1;
|
||||
filter.m_dataBindBlurX = cctx.newShaderDataBinding(s_BlurPipeline,
|
||||
s_BlurVtxFmt, filter.m_blurVbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, 1, texs, texBindIdxs, nullptr);
|
||||
|
||||
bufs[0] = filter.m_uniBufBlurY;
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 2;
|
||||
filter.m_dataBindBlurY = cctx.newShaderDataBinding(s_BlurPipeline,
|
||||
s_BlurVtxFmt, filter.m_blurVbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, 1, texs, texBindIdxs, nullptr);
|
||||
|
||||
bufs[0] = filter.m_uniBuf;
|
||||
size_t texCount;
|
||||
if (filter.m_indTex)
|
||||
{
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 0;
|
||||
texs[1] = filter.m_indTex->GetBooTexture();
|
||||
texBindIdxs[1] = 0;
|
||||
texs[2] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[2] = 1;
|
||||
texs[3] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[3] = 2;
|
||||
texCount = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 0;
|
||||
texs[1] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[1] = 1;
|
||||
texs[2] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[2] = 2;
|
||||
texCount = 3;
|
||||
}
|
||||
|
||||
return cctx.newShaderDataBinding(filter.m_indTex ? s_IndPipeline : s_Pipeline,
|
||||
s_VtxFmt, filter.m_vbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, texCount, texs, texBindIdxs, nullptr);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
TShader<CPhazonSuitFilter>::IDataBindingFactory*
|
||||
CPhazonSuitFilter::Initialize(boo::GLDataFactory::Context& ctx)
|
||||
{
|
||||
const char* uniNames[] = {"PhazonSuitUniform"};
|
||||
const char* texNames[] = {"screenTex", "indTex", "maskTex", "maskTexBlur"};
|
||||
s_IndPipeline = ctx.newShaderPipeline(VS, IndFS, 4, texNames, 1, uniNames, boo::BlendFactor::One,
|
||||
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, true, false, boo::CullMode::None);
|
||||
texNames[1] = "maskTex";
|
||||
texNames[2] = "maskTexBlur";
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, 3, texNames, 1, uniNames, boo::BlendFactor::One,
|
||||
boo::BlendFactor::One, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, true, false, boo::CullMode::None);
|
||||
uniNames[0] = "PhazonSuitBlurUniform";
|
||||
texNames[0] = "maskTex";
|
||||
s_BlurPipeline = ctx.newShaderPipeline(BlurVS, BlurFS, 1, texNames, 1, uniNames, boo::BlendFactor::One,
|
||||
boo::BlendFactor::Zero, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, false, true, boo::CullMode::None);
|
||||
return new CPhazonSuitFilterGLDataBindingFactory;
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
TShader<CPhazonSuitFilter>::IDataBindingFactory*
|
||||
CPhazonSuitFilter::Initialize(boo::VulkanDataFactory::Context& ctx)
|
||||
{
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 2}
|
||||
};
|
||||
s_VtxFmt = ctx.newVertexFormat(4, VtxVmt);
|
||||
const boo::VertexElementDescriptor BlurVtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4}
|
||||
};
|
||||
s_BlurVtxFmt = ctx.newVertexFormat(2, BlurVtxVmt);
|
||||
s_IndPipeline = ctx.newShaderPipeline(VS, IndFS, s_VtxFmt, boo::BlendFactor::One,
|
||||
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, true, false, boo::CullMode::None);
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, boo::BlendFactor::One,
|
||||
boo::BlendFactor::One, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, true, false, boo::CullMode::None);
|
||||
s_BlurPipeline = ctx.newShaderPipeline(BlurVS, BlurFS, s_BlurVtxFmt, boo::BlendFactor::One,
|
||||
boo::BlendFactor::Zero, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, false, true, boo::CullMode::None);
|
||||
return new CPhazonSuitFilterVulkanDataBindingFactory;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,255 @@
|
|||
#include "CPhazonSuitFilter.hpp"
|
||||
#include "TShader.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn [[ attribute(0) ]];\n"
|
||||
" float4 screenUvIn [[ attribute(1) ]];\n"
|
||||
" float4 indUvIn [[ attribute(2) ]];\n"
|
||||
" float4 maskUvIn [[ attribute(3) ]];\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct PhazonSuitUniform\n"
|
||||
"{\n"
|
||||
" float4 color;\n"
|
||||
" float4 indScaleOff;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
" float4 indScaleOff;\n"
|
||||
" float2 screenUv;\n"
|
||||
" float2 indUv;\n"
|
||||
" float2 maskUv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant PhazonSuitUniform& psu [[ buffer(2) ]])\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" vtf.color = psu.color;\n"
|
||||
" vtf.indScaleOff = psu.indScaleOff;\n"
|
||||
" vtf.screenUv = v.screenUvIn.xy;\n"
|
||||
" vtf.indUv = v.indUvIn.xy;\n"
|
||||
" vtf.maskUv = v.maskUvIn.xy;\n"
|
||||
" vtf.position = float4(v.posIn.xyz, 1.0);\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* IndFS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
" float4 indScaleOff;\n"
|
||||
" float2 screenUv;\n"
|
||||
" float2 indUv;\n"
|
||||
" float2 maskUv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||
" texture2d<float> screenTex [[ texture(0) ]],\n"
|
||||
" texture2d<float> indTex [[ texture(1) ]],\n"
|
||||
" texture2d<float> maskTex [[ texture(2) ]],\n"
|
||||
" texture2d<float> maskTexBlur [[ texture(3) ]])\n"
|
||||
"{\n"
|
||||
" float2 indUv = (indTex.sample(samp, vtf.indUv).rg - float2(0.5, 0.5)) * \n"
|
||||
" vtf.indScaleOff.xy + vtf.indScaleOff.zw;\n"
|
||||
" return vtf.color * screenTex.sample(samp, indUv + vtf.screenUv) * \n"
|
||||
" (maskTexBlur.sample(samp, vtf.maskUv).a - maskTex.sample(samp, vtf.maskUv).a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 color;\n"
|
||||
" float4 indScaleOff;\n"
|
||||
" float2 screenUv;\n"
|
||||
" float2 indUv;\n"
|
||||
" float2 maskUv;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||
" texture2d<float> screenTex [[ texture(0) ]],\n"
|
||||
" texture2d<float> maskTex [[ texture(1) ]],\n"
|
||||
" texture2d<float> maskTexBlur [[ texture(2) ]])\n"
|
||||
"{\n"
|
||||
" return vtf.color * screenTex.sample(samp, vtf.screenUv) * \n"
|
||||
" (maskTexBlur.sample(samp, vtf.maskUv).a - maskTex.sample(samp, vtf.maskUv).a);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* BlurVS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn [[ attribute(0) ]];\n"
|
||||
" float4 uvIn [[ attribute(1) ]];\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct PhazonSuitBlurUniform\n"
|
||||
"{\n"
|
||||
" float4 blurDir;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float2 uv;\n"
|
||||
" float2 blurDir;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant PhazonSuitBlurUniform& psu [[ buffer(2) ]])\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" vtf.uv = uvIn.xy;\n"
|
||||
" vtf.blurDir = blurDir.xy;\n"
|
||||
" vtf.position = float4(posIn.xyz, 1.0);\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* BlurFS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float2 uv;\n"
|
||||
" float2 blurDir;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]],\n"
|
||||
" texture2d<float> maskTex [[ texture(0) ]])\n"
|
||||
"{\n"
|
||||
" //this will be our alpha sum\n"
|
||||
" float sum = 0.0;\n"
|
||||
"\n"
|
||||
" //apply blurring, using a 9-tap filter with predefined gaussian weights\n"
|
||||
"\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 4.0 * vtf.blurDir).a * 0.0162162162;\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 3.0 * vtf.blurDir).a * 0.0540540541;\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 2.0 * vtf.blurDir).a * 0.1216216216;\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 1.0 * vtf.blurDir).a * 0.1945945946;\n"
|
||||
"\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv).a * 0.2270270270;\n"
|
||||
"\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 1.0 * vtf.blurDir).a * 0.1945945946;\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 2.0 * vtf.blurDir).a * 0.1216216216;\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 3.0 * vtf.blurDir).a * 0.0540540541;\n"
|
||||
" sum += maskTex.sample(samp, vtf.uv - 4.0 * vtf.blurDir).a * 0.0162162162;\n"
|
||||
"\n"
|
||||
" return float4(1.0, 1.0, 1.0, sum);\n"
|
||||
"}\n";
|
||||
|
||||
URDE_DECL_SPECIALIZE_SHADER(CPhazonSuitFilter)
|
||||
|
||||
static boo::IVertexFormat* s_VtxFmt = nullptr;
|
||||
static boo::IVertexFormat* s_BlurVtxFmt = nullptr;
|
||||
static boo::IShaderPipeline* s_IndPipeline = nullptr;
|
||||
static boo::IShaderPipeline* s_Pipeline = nullptr;
|
||||
static boo::IShaderPipeline* s_BlurPipeline = nullptr;
|
||||
|
||||
struct CPhazonSuitFilterMetalDataBindingFactory : TShader<CPhazonSuitFilter>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CPhazonSuitFilter& filter)
|
||||
{
|
||||
boo::MetalDataFactory::Context& cctx = static_cast<boo::MetalDataFactory::Context&>(ctx);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBufBlurX};
|
||||
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
|
||||
boo::ITexture* texs[4];
|
||||
int texBindIdxs[4];
|
||||
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 1;
|
||||
filter.m_dataBindBlurX = cctx.newShaderDataBinding(s_BlurPipeline,
|
||||
s_BlurVtxFmt, filter.m_blurVbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, 1, texs, texBindIdxs, nullptr);
|
||||
|
||||
bufs[0] = filter.m_uniBufBlurY;
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 2;
|
||||
filter.m_dataBindBlurY = cctx.newShaderDataBinding(s_BlurPipeline,
|
||||
s_BlurVtxFmt, filter.m_blurVbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, 1, texs, texBindIdxs, nullptr);
|
||||
|
||||
bufs[0] = filter.m_uniBuf;
|
||||
size_t texCount;
|
||||
if (filter.m_indTex)
|
||||
{
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 0;
|
||||
texs[1] = filter.m_indTex->GetBooTexture();
|
||||
texBindIdxs[1] = 0;
|
||||
texs[2] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[2] = 1;
|
||||
texs[3] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[3] = 2;
|
||||
texCount = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
texs[0] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[0] = 0;
|
||||
texs[1] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[1] = 1;
|
||||
texs[2] = CGraphics::g_SpareTexture;
|
||||
texBindIdxs[2] = 2;
|
||||
texCount = 3;
|
||||
}
|
||||
|
||||
return cctx.newShaderDataBinding(filter.m_indTex ? s_IndPipeline : s_Pipeline,
|
||||
s_VtxFmt, filter.m_vbo, nullptr, nullptr,
|
||||
1, bufs, stages, nullptr, nullptr, texCount, texs, texBindIdxs, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
TShader<CPhazonSuitFilter>::IDataBindingFactory*
|
||||
CPhazonSuitFilter::Initialize(boo::MetalDataFactory::Context& ctx)
|
||||
{
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 0},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 1},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4, 2}
|
||||
};
|
||||
s_VtxFmt = ctx.newVertexFormat(4, VtxVmt);
|
||||
const boo::VertexElementDescriptor BlurVtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||
{nullptr, nullptr, boo::VertexSemantic::UV4}
|
||||
};
|
||||
s_BlurVtxFmt = ctx.newVertexFormat(2, BlurVtxVmt);
|
||||
s_IndPipeline = ctx.newShaderPipeline(VS, IndFS, s_VtxFmt,
|
||||
CGraphics::g_ViewportSamples, boo::BlendFactor::One,
|
||||
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, true, false, boo::CullMode::None);
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt,
|
||||
CGraphics::g_ViewportSamples, boo::BlendFactor::One,
|
||||
boo::BlendFactor::One, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, true, false, boo::CullMode::None);
|
||||
s_BlurPipeline = ctx.newShaderPipeline(BlurVS, BlurFS, s_BlurVtxFmt,
|
||||
CGraphics::g_ViewportSamples, boo::BlendFactor::One,
|
||||
boo::BlendFactor::Zero, boo::Primitive::TriStrips,
|
||||
boo::ZTest::None, false, false, true, boo::CullMode::None);
|
||||
return new CPhazonSuitFilterMetalDataBindingFactory;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,71 @@
|
|||
#include "CInventoryScreen.hpp"
|
||||
#include "GuiSys/CGuiTableGroup.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
namespace MP1
|
||||
{
|
||||
|
||||
struct SInventoryItem
|
||||
{
|
||||
u32 idx;
|
||||
u32 nameStrIdx;
|
||||
u32 entryStrIdx;
|
||||
};
|
||||
|
||||
static const SInventoryItem ArmCannonItems[] =
|
||||
{
|
||||
{0, 0x24, 0x46}, // Power Beam
|
||||
{1, 0x25, 0x48}, // Ice Beam
|
||||
{2, 0x26, 0x4a}, // Wave Beam
|
||||
{3, 0x27, 0x4c}, // Plasma Beam
|
||||
{4, 0x28, 0x4e}, // Phazon Beam
|
||||
};
|
||||
|
||||
static const SInventoryItem MorphballItems[] =
|
||||
{
|
||||
{5, 0x2e, 0x57}, // Morph Ball
|
||||
{6, 0x2f, 0x58}, // Boost Ball
|
||||
{7, 0x30, 0x59}, // Spider Ball
|
||||
{8, 0x31, 0x5a}, // Morph Ball Bomb
|
||||
{9, 0x32, 0x5b}, // Power Bomb
|
||||
};
|
||||
|
||||
static const SInventoryItem SuitItems[] =
|
||||
{
|
||||
{10, 0x33, 0x52}, // Power Suit
|
||||
{11, 0x34, 0x53}, // Varia Suit
|
||||
{12, 0x35, 0x54}, // Gravity Suit
|
||||
{13, 0x36, 0x55}, // Phazon Suit
|
||||
{14, 0x37, 0x56}, // Energy Tank
|
||||
};
|
||||
|
||||
static const SInventoryItem VisorItems[] =
|
||||
{
|
||||
{15, 0x38, 0x42}, // Combat Visor
|
||||
{16, 0x39, 0x43}, // Scan Visor
|
||||
{17, 0x3a, 0x44}, // X-Ray Visor
|
||||
{18, 0x3b, 0x45}, // Thermal Visor
|
||||
};
|
||||
|
||||
static const SInventoryItem SecondaryItems[] =
|
||||
{
|
||||
{19, 0x3c, 0x4f}, // Space Jump Boots
|
||||
{20, 0x3d, 0x50}, // Grapple Beam
|
||||
{21, 0x3e, 0x51}, // Missile Launcher
|
||||
{22, 0x3f, 0x5c}, // Charge Beam
|
||||
{23, 0x40, 0x5d}, // Beam Combo
|
||||
};
|
||||
|
||||
static const std::pair<u32, const SInventoryItem*> InventoryRegistry[] =
|
||||
{
|
||||
{5, ArmCannonItems},
|
||||
{5, MorphballItems},
|
||||
{5, SuitItems},
|
||||
{4, VisorItems},
|
||||
{5, SecondaryItems},
|
||||
};
|
||||
|
||||
CInventoryScreen::CInventoryScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg,
|
||||
const CDependencyGroup& suitDgrp, const CDependencyGroup& ballDgrp)
|
||||
: CPauseScreenBase(mgr, frame, pauseStrg)
|
||||
|
@ -96,5 +157,38 @@ void CInventoryScreen::UpdateRightLogHighlight(bool active, int idx,
|
|||
|
||||
}
|
||||
|
||||
void CInventoryScreen::UpdateSamusDollPulses()
|
||||
{
|
||||
bool pulseSuit = false;
|
||||
bool pulseBeam = false;
|
||||
bool pulseGrapple = false;
|
||||
bool pulseBoots = false;
|
||||
bool pulseVisor = false;
|
||||
int userSel = x70_tablegroup_leftlog->GetUserSelection();
|
||||
|
||||
if (x10_mode == EMode::RightTable)
|
||||
{
|
||||
if (userSel == 2)
|
||||
pulseSuit = true;
|
||||
else if (userSel == 0)
|
||||
pulseBeam = true;
|
||||
else if (userSel == 3)
|
||||
pulseVisor = true;
|
||||
else if (userSel == 4)
|
||||
{
|
||||
pulseGrapple = SecondaryItems[x1c_rightSel].idx == 20;
|
||||
pulseBoots = SecondaryItems[x1c_rightSel].idx == 19;
|
||||
if (SecondaryItems[x1c_rightSel].idx == 21)
|
||||
pulseBeam = true;
|
||||
}
|
||||
}
|
||||
|
||||
x19c_samusDoll->SetPulseSuit(pulseSuit);
|
||||
x19c_samusDoll->SetPulseBeam(pulseBeam);
|
||||
x19c_samusDoll->SetPulseGrapple(pulseGrapple);
|
||||
x19c_samusDoll->SetPulseBoots(pulseBoots);
|
||||
x19c_samusDoll->SetPulseVisor(pulseVisor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
bool IsRightLogDynamic() const;
|
||||
void UpdateRightLogColors(bool active, const zeus::CColor& activeColor, const zeus::CColor& inactiveColor);
|
||||
void UpdateRightLogHighlight(bool active, int idx, const zeus::CColor& activeColor, const zeus::CColor& inactiveColor);
|
||||
void UpdateSamusDollPulses();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ void CPauseScreenBase::ChangeMode(EMode mode)
|
|||
x70_tablegroup_leftlog->SetIsActive(true);
|
||||
UpdateSideTable(x70_tablegroup_leftlog);
|
||||
x18_ = 0;
|
||||
x1c_ = 0;
|
||||
x1c_rightSel = 0;
|
||||
x84_tablegroup_rightlog->SetUserSelection(1);
|
||||
UpdateSideTable(x84_tablegroup_rightlog);
|
||||
break;
|
||||
|
@ -171,11 +171,11 @@ void CPauseScreenBase::UpdateSideTable(CGuiTableGroup* table)
|
|||
|
||||
if (table == x84_tablegroup_rightlog)
|
||||
{
|
||||
int sel = x1c_ - x18_;
|
||||
int sel = x1c_rightSel - x18_;
|
||||
x8c_model_righthighlight->SetLocalTransform(
|
||||
x8c_model_righthighlight->GetTransform() * zeus::CTransform::Translate(0.f, 0.f, x38_ * sel));
|
||||
x8c_model_righthighlight->SetVisibility(x10_mode == EMode::RightTable, ETraversalMode::Children);
|
||||
int selInView = x1c_ % 5;
|
||||
int selInView = x1c_rightSel % 5;
|
||||
if (IsRightLogDynamic())
|
||||
{
|
||||
UpdateRightLogHighlight(tableActive, selInView, selColor, deselColor);
|
||||
|
@ -249,7 +249,7 @@ void CPauseScreenBase::Draw(float mainAlpha, float frameAlpha, float yOff)
|
|||
void CPauseScreenBase::UpdateRightTable()
|
||||
{
|
||||
x18_ = 0;
|
||||
x1c_ = 0;
|
||||
x1c_rightSel = 0;
|
||||
x84_tablegroup_rightlog->SetUserSelection(1);
|
||||
UpdateSideTable(x84_tablegroup_rightlog);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
|||
EMode x10_mode = EMode::Invalid;
|
||||
float x14_alpha = 0.f;
|
||||
u32 x18_ = 0;
|
||||
u32 x1c_ = 0;
|
||||
u32 x1c_rightSel = 0;
|
||||
zeus::CVector3f x20_;
|
||||
zeus::CVector3f x2c_;
|
||||
float x38_ = 0.f;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "CDependencyGroup.hpp"
|
||||
#include "zeus/CEulerAngles.hpp"
|
||||
#include "Collision/CollisionUtil.hpp"
|
||||
#include "Graphics/CBooRenderer.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -113,6 +114,45 @@ static const u32 Character2and3Idxs[8][2] =
|
|||
{30, 31}
|
||||
};
|
||||
|
||||
static const u8 BallGlowColors[9][3] =
|
||||
{
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xd5, 0x19},
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xff, 0xff},
|
||||
{0xff, 0xff, 0xff},
|
||||
};
|
||||
|
||||
static const u8 BallTransFlashColors[9][3] =
|
||||
{
|
||||
{0xc2, 0x7e, 0x10},
|
||||
{0x66, 0xc4, 0xff},
|
||||
{0x60, 0xff, 0x90},
|
||||
{0x33, 0x33, 0xff},
|
||||
{0xff, 0x20, 0x20},
|
||||
{0x0, 0x9d, 0xb6},
|
||||
{0xd3, 0xf1, 0x0},
|
||||
{0xa6, 0x86, 0xd8},
|
||||
{0xfb, 0x98, 0x21}
|
||||
};
|
||||
|
||||
static const u8 BallAuxGlowColors[9][3] =
|
||||
{
|
||||
{0xc2, 0x7e, 0x10},
|
||||
{0x66, 0xc4, 0xff},
|
||||
{0x6c, 0xff, 0x61},
|
||||
{0x33, 0x33, 0xff},
|
||||
{0xff, 0x20, 0x20},
|
||||
{0x0, 0x9d, 0xb6},
|
||||
{0xd3, 0xf1, 0x0},
|
||||
{0xa6, 0x86, 0xd8},
|
||||
{0xfb, 0x98, 0x21}
|
||||
};
|
||||
|
||||
CSamusDoll::CSamusDoll(const CDependencyGroup& suitDgrp, const CDependencyGroup& ballDgrp,
|
||||
CPlayerState::EPlayerSuit suit, CPlayerState::EBeamId beam,
|
||||
bool hasSpiderBall, bool hasGrappleBeam)
|
||||
|
@ -166,7 +206,7 @@ bool CSamusDoll::IsLoaded() const
|
|||
return false;
|
||||
if (x218_invFins && !x218_invFins.IsLoaded())
|
||||
return false;
|
||||
return xc8_suitModel1.operator bool();
|
||||
return xc8_suitModel0.operator bool();
|
||||
}
|
||||
|
||||
CModelData CSamusDoll::BuildSuitModelData1(CPlayerState::EPlayerSuit suit)
|
||||
|
@ -196,7 +236,7 @@ bool CSamusDoll::CheckLoadComplete()
|
|||
if (!tok.IsLoaded())
|
||||
return false;
|
||||
|
||||
xc8_suitModel1.emplace(BuildSuitModelData1(x44_suit));
|
||||
xc8_suitModel0.emplace(BuildSuitModelData1(x44_suit));
|
||||
for (int i=0 ; i<2 ; ++i)
|
||||
{
|
||||
CAnimRes res(g_ResFactory->GetResourceIdByName("ANCS_ItemScreenSamus")->id,
|
||||
|
@ -222,55 +262,448 @@ bool CSamusDoll::CheckLoadComplete()
|
|||
|
||||
void CSamusDoll::Update(float dt, CRandom16& rand)
|
||||
{
|
||||
if (x1f4_invBeam.IsLoaded())
|
||||
x1f4_invBeam->Touch(0);
|
||||
if (x200_invVisor.IsLoaded())
|
||||
x200_invVisor->Touch(0);
|
||||
if (x20c_invGrappleBeam.IsLoaded())
|
||||
x20c_invGrappleBeam->Touch(0);
|
||||
if (x1d4_spiderBallGlass.IsLoaded())
|
||||
x1d4_spiderBallGlass->Touch(0);
|
||||
if (x218_invFins.IsLoaded())
|
||||
x218_invFins->Touch(0);
|
||||
|
||||
if (!CheckLoadComplete())
|
||||
return;
|
||||
|
||||
x40_alphaIn = std::min(x40_alphaIn + 2.f * dt, 1.f);
|
||||
if (x54_remTransitionTime > 0.f)
|
||||
{
|
||||
float oldRemTransTime = x54_remTransitionTime;
|
||||
x54_remTransitionTime = std::max(0.f, x54_remTransitionTime - dt);
|
||||
if (!x4c_completedMorphball && x4d_selectedMorphball &&
|
||||
oldRemTransTime >= x50_totalTransitionTime - 0.5f &&
|
||||
x54_remTransitionTime < x50_totalTransitionTime - 0.5f)
|
||||
{
|
||||
x238_ballTransitionFlashGen = std::make_unique<CElementGen>(x230_ballTransitionFlash,
|
||||
CElementGen::EModelOrientationType::Normal,
|
||||
CElementGen::EOptionalSystemFlags::One);
|
||||
x238_ballTransitionFlashGen->SetGlobalScale(zeus::CVector3f(0.625f));
|
||||
}
|
||||
|
||||
if (x54_remTransitionTime == 0.f)
|
||||
{
|
||||
x4c_completedMorphball = x4d_selectedMorphball;
|
||||
if (!x4d_selectedMorphball)
|
||||
{
|
||||
xc8_suitModel0->AnimationData()->SetAnimation(CAnimPlaybackParms(2, -1, 1.f, true), false);
|
||||
x134_suitModelBoots->AnimationData()->SetAnimation(CAnimPlaybackParms(2, -1, 1.f, true), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (x270_26_pulseSuit)
|
||||
x58_suitPulseFactor = std::min(x58_suitPulseFactor + 2.f * dt, 1.f);
|
||||
else
|
||||
x58_suitPulseFactor = std::max(x58_suitPulseFactor - 2.f * dt, 0.f);
|
||||
|
||||
if (x270_27_pulseBeam)
|
||||
x5c_beamPulseFactor = std::min(x5c_beamPulseFactor + 2.f * dt, 1.f);
|
||||
else
|
||||
x5c_beamPulseFactor = std::max(x5c_beamPulseFactor - 2.f * dt, 0.f);
|
||||
|
||||
if (x270_28_pulseGrapple)
|
||||
x60_grapplePulseFactor = std::min(x60_grapplePulseFactor + 2.f * dt, 1.f);
|
||||
else
|
||||
x60_grapplePulseFactor = std::max(x60_grapplePulseFactor - 2.f * dt, 0.f);
|
||||
|
||||
if (x270_29_pulseBoots)
|
||||
x64_bootsPulseFactor = std::min(x64_bootsPulseFactor + 2.f * dt, 1.f);
|
||||
else
|
||||
x64_bootsPulseFactor = std::max(x64_bootsPulseFactor - 2.f * dt, 0.f);
|
||||
|
||||
if (x270_30_pulseVisor)
|
||||
x68_visorPulseFactor = std::min(x68_visorPulseFactor + 2.f * dt, 1.f);
|
||||
else
|
||||
x68_visorPulseFactor = std::max(x68_visorPulseFactor - 2.f * dt, 0.f);
|
||||
|
||||
if (x4c_completedMorphball)
|
||||
x6c_ballPulseFactor = std::min(x6c_ballPulseFactor + 2.f * dt, 1.f);
|
||||
else
|
||||
x6c_ballPulseFactor = std::max(x6c_ballPulseFactor - 2.f * dt, 0.f);
|
||||
|
||||
if (x44_suit == CPlayerState::EPlayerSuit::Phazon)
|
||||
{
|
||||
if (!x250_phazonIndirectTexture)
|
||||
x250_phazonIndirectTexture = g_SimplePool->GetObj("PhazonIndirectTexture");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x250_phazonIndirectTexture)
|
||||
x250_phazonIndirectTexture = TLockedToken<CTexture>();
|
||||
}
|
||||
|
||||
if (x250_phazonIndirectTexture)
|
||||
{
|
||||
x260_phazonOffsetAngle += 0.03f;
|
||||
g_Renderer->AllocatePhazonSuitMaskTexture();
|
||||
}
|
||||
|
||||
xc8_suitModel0->AdvanceAnimationIgnoreParticles(dt, rand, true);
|
||||
x134_suitModelBoots->AdvanceAnimationIgnoreParticles(dt, rand, true);
|
||||
x184_ballModelData->AdvanceAnimationIgnoreParticles(dt, rand, true);
|
||||
|
||||
SetupLights();
|
||||
|
||||
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_xf.origin);
|
||||
x22c_ballInnerGlowGen->Update(dt);
|
||||
|
||||
if (x238_ballTransitionFlashGen)
|
||||
{
|
||||
if (x238_ballTransitionFlashGen->IsSystemDeletable())
|
||||
x238_ballTransitionFlashGen.reset();
|
||||
if (x238_ballTransitionFlashGen)
|
||||
{
|
||||
x22c_ballInnerGlowGen->SetGlobalTranslation(x10_xf.origin);
|
||||
x22c_ballInnerGlowGen->Update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
if (xc4_viewInterp != 0.f && xc4_viewInterp != 1.f)
|
||||
{
|
||||
if (xc4_viewInterp < 0.f)
|
||||
xc4_viewInterp = std::min(xc4_viewInterp + 3.f * dt, 0.f);
|
||||
else
|
||||
xc4_viewInterp = std::min(xc4_viewInterp + 3.f * dt, 1.f);
|
||||
|
||||
float interp = std::fabs(xc4_viewInterp);
|
||||
float oneMinusInterp = 1.f - interp;
|
||||
xa4_offset = x84_interpStartOffset * interp + skInitialOffset * oneMinusInterp;
|
||||
|
||||
xb0_userRot = zeus::CQuaternion::slerpShort(x70_fixedRot, x90_userInterpRot, interp);
|
||||
|
||||
if (xc4_viewInterp <= 0.f) // Zoom out
|
||||
xc0_userZoom = x80_fixedZoom * oneMinusInterp + xa0_userInterpZoom * interp;
|
||||
else // Zoom in
|
||||
xc0_userZoom = x80_fixedZoom * interp + xa0_userInterpZoom * oneMinusInterp;
|
||||
}
|
||||
}
|
||||
|
||||
void CSamusDoll::Draw(const CStateManager& mgr, float alpha)
|
||||
{
|
||||
if (!IsLoaded())
|
||||
return;
|
||||
|
||||
alpha *= x40_alphaIn;
|
||||
|
||||
float itemPulse = zeus::clamp(0.f, (std::sin(5.f * CGraphics::GetSecondsMod900()) + 1.f) * 0.5f, 1.f) *
|
||||
(1.f - std::fabs(xc4_viewInterp));
|
||||
|
||||
g_Renderer->SetPerspective(55.f, g_Viewport.x8_width, g_Viewport.xc_height, 0.2f, 4096.f);
|
||||
|
||||
CGraphics::SetViewPointMatrix(zeus::CTransform(xb0_userRot, xa4_offset) *
|
||||
zeus::CTransform::Translate(0.f, xc0_userZoom, 0.f));
|
||||
|
||||
zeus::CTransform gunXf = xc8_suitModel0->GetScaledLocatorTransform("GUN_LCTR");
|
||||
zeus::CTransform visorXf = xc8_suitModel0->GetScaledLocatorTransform("VISOR_LCTR");
|
||||
zeus::CTransform grappleXf = xc8_suitModel0->GetScaledLocatorTransform("GRAPPLE_LCTR");
|
||||
|
||||
if (!x4c_completedMorphball || !x4d_selectedMorphball)
|
||||
{
|
||||
float suitPulse = itemPulse * x58_suitPulseFactor;
|
||||
float bootsPulse = std::max(suitPulse, itemPulse * x64_bootsPulseFactor);
|
||||
|
||||
bool phazonSuit = x44_suit == CPlayerState::EPlayerSuit::Phazon;
|
||||
// Enable dst alpha 1.0
|
||||
|
||||
for (int i=0 ; i<=x118_suitModel1and2.size() ; ++i)
|
||||
{
|
||||
TCachedToken<CSkinnedModel> backupModelData = xc8_suitModel0->GetAnimationData()->GetModelData();
|
||||
if (i < x118_suitModel1and2.size())
|
||||
xc8_suitModel0->AnimationData()->SubstituteModelData(x118_suitModel1and2[i]);
|
||||
xc8_suitModel0->InvSuitDraw(CModelData::EWhichModel::Normal, zeus::CTransform::Identity(),
|
||||
x24c_actorLights.get(), zeus::CColor(1.f, alpha),
|
||||
zeus::CColor(1.f, alpha * suitPulse));
|
||||
xc8_suitModel0->AnimationData()->SubstituteModelData(backupModelData);
|
||||
}
|
||||
|
||||
x134_suitModelBoots->InvSuitDraw(CModelData::EWhichModel::Normal, zeus::CTransform::Identity(),
|
||||
x24c_actorLights.get(), zeus::CColor(1.f, alpha),
|
||||
zeus::CColor(1.f, alpha * bootsPulse));
|
||||
|
||||
{
|
||||
CGraphics::SetModelMatrix(gunXf);
|
||||
x1f4_invBeam->GetInstance().ActivateLights(x23c_lights);
|
||||
CModelFlags flags = {};
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
x1f4_invBeam->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha);
|
||||
x1f4_invBeam->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha * itemPulse * x5c_beamPulseFactor);
|
||||
x1f4_invBeam->Draw(flags);
|
||||
}
|
||||
|
||||
{
|
||||
CGraphics::SetModelMatrix(visorXf);
|
||||
|
||||
float visorT = std::fmod(CGraphics::GetSecondsMod900(), 1.f) * (1.f - std::fabs(xc4_viewInterp));
|
||||
float alphaBlend = (visorT < 0.25f) ? 1.f - 2.f * visorT : (visorT < 0.5f) ? 2.f * (visorT - 0.25f) + 0.5f : 1.f;
|
||||
float addBlend = (visorT > 0.75f) ? 1.f - 4.f * (visorT - 0.75f) : (visorT > 0.5f) ? 4.f * (visorT - 0.5f) : 0.f;
|
||||
|
||||
x200_invVisor->GetInstance().ActivateLights(x23c_lights);
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor::lerp(zeus::CColor(1.f, alpha), zeus::CColor(alphaBlend, alpha), x68_visorPulseFactor);
|
||||
x200_invVisor->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha * addBlend * x68_visorPulseFactor);
|
||||
x200_invVisor->Draw(flags);
|
||||
}
|
||||
|
||||
if (x270_25_hasGrappleBeam)
|
||||
{
|
||||
CGraphics::SetModelMatrix(grappleXf);
|
||||
|
||||
x20c_invGrappleBeam->GetInstance().ActivateLights(x23c_lights);
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha);
|
||||
x20c_invGrappleBeam->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha * itemPulse * x60_grapplePulseFactor);
|
||||
x20c_invGrappleBeam->Draw(flags);
|
||||
}
|
||||
else if (x44_suit >= CPlayerState::EPlayerSuit::FusionPower)
|
||||
{
|
||||
CGraphics::SetModelMatrix(grappleXf);
|
||||
|
||||
x218_invFins->GetInstance().ActivateLights(x23c_lights);
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha);
|
||||
x218_invFins->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor(1.f, alpha * suitPulse);
|
||||
x218_invFins->Draw(flags);
|
||||
}
|
||||
|
||||
if (x54_remTransitionTime > 0.f)
|
||||
{
|
||||
float ballT = 1.f - x54_remTransitionTime / x50_totalTransitionTime;
|
||||
|
||||
float ballAlpha = 0.f;
|
||||
if (x4d_selectedMorphball)
|
||||
ballAlpha = 1.f - std::min(x54_remTransitionTime / 0.25f, 1.f);
|
||||
else if (x4c_completedMorphball)
|
||||
ballAlpha = std::max(0.f, (x54_remTransitionTime - (x50_totalTransitionTime - 0.25f)) / 0.25f);
|
||||
|
||||
if (ballAlpha > 0.f)
|
||||
{
|
||||
CModelFlags flags = {};
|
||||
flags.x1_matSetIdx = x1e0_ballMatIdx;
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = alpha * ballAlpha;
|
||||
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = x6c_ballPulseFactor * alpha * ballAlpha * itemPulse;
|
||||
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
|
||||
}
|
||||
|
||||
if (x4d_selectedMorphball && ballT > 0.5f)
|
||||
{
|
||||
float ballEndT = (ballT - 0.5f) / 0.5f;
|
||||
float oneMinusBallEndT = 1.f - ballEndT;
|
||||
|
||||
float spinScale = 0.75f * oneMinusBallEndT + 1.f;
|
||||
float spinAlpha;
|
||||
if (ballEndT < 0.1f)
|
||||
spinAlpha = 0.f;
|
||||
else if (ballEndT < 0.2f)
|
||||
spinAlpha = (ballEndT - 0.1f) / 0.1f;
|
||||
else if (ballEndT < 0.9f)
|
||||
spinAlpha = 1.f;
|
||||
else
|
||||
spinAlpha = 1.f - (ballT - 0.9f) / 0.1f;
|
||||
|
||||
zeus::CRelAngle spinAngle = zeus::degToRad(360.f * oneMinusBallEndT);
|
||||
spinAlpha *= 0.5f;
|
||||
if (spinAlpha > 0.f)
|
||||
{
|
||||
CModelFlags flags = {};
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x1_matSetIdx = x1e0_ballMatIdx;
|
||||
flags.x4_color = zeus::CColor(1.f, spinAlpha * alpha);
|
||||
x184_ballModelData->Render(mgr, x10_xf * zeus::CTransform::RotateZ(spinAngle) * zeus::CTransform::Scale(spinScale),
|
||||
x24c_actorLights.get(), flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (x270_24_hasSpiderBall)
|
||||
{
|
||||
CGraphics::SetModelMatrix(x10_xf);
|
||||
CModelFlags flags = {};
|
||||
flags.x1_matSetIdx = x1e4_glassMatIdx;
|
||||
x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
x1d4_spiderBallGlass->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = alpha;
|
||||
x1d4_spiderBallGlass->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = x6c_ballPulseFactor * alpha * itemPulse;
|
||||
x1d4_spiderBallGlass->Draw(flags);
|
||||
}
|
||||
|
||||
if (phazonSuit && alpha > 0.1f)
|
||||
{
|
||||
float radius = zeus::clamp(0.2f, (10.f - (xc0_userZoom >= 0.f ? xc0_userZoom : -xc0_userZoom)) / 20.f, 1.f);
|
||||
float offset = std::sin(x260_phazonOffsetAngle);
|
||||
zeus::CColor color = g_tweakGuiColors->GetInvPhazonSuitFilterMod();
|
||||
color.a = alpha;
|
||||
g_Renderer->DrawPhazonSuitIndirectEffect(zeus::CColor(0.1f, alpha), x250_phazonIndirectTexture,
|
||||
color, radius, 0.1f, offset, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CModelFlags flags = {};
|
||||
flags.x1_matSetIdx = x1e0_ballMatIdx;
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = alpha;
|
||||
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = x6c_ballPulseFactor * alpha * itemPulse;
|
||||
x184_ballModelData->Render(mgr, x10_xf, x24c_actorLights.get(), flags);
|
||||
|
||||
const u8* c = BallGlowColors[x1e8_ballGlowColorIdx];
|
||||
zeus::CColor color = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, alpha};
|
||||
x22c_ballInnerGlowGen->SetModulationColor(color);
|
||||
|
||||
if (alpha > 0.f)
|
||||
{
|
||||
if (x22c_ballInnerGlowGen->GetNumActiveChildParticles() > 0)
|
||||
{
|
||||
const u8* c = BallTransFlashColors[x1e8_ballGlowColorIdx];
|
||||
zeus::CColor color = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, alpha};
|
||||
x22c_ballInnerGlowGen->GetActiveChildParticle(0).SetModulationColor(color);
|
||||
|
||||
if (x22c_ballInnerGlowGen->GetNumActiveChildParticles() > 1)
|
||||
{
|
||||
const u8* c = BallAuxGlowColors[x1e8_ballGlowColorIdx];
|
||||
zeus::CColor color = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, alpha};
|
||||
x22c_ballInnerGlowGen->GetActiveChildParticle(1).SetModulationColor(color);
|
||||
}
|
||||
}
|
||||
x22c_ballInnerGlowGen->Render();
|
||||
}
|
||||
|
||||
if (x270_24_hasSpiderBall)
|
||||
{
|
||||
CGraphics::SetModelMatrix(x10_xf);
|
||||
CModelFlags flags = {};
|
||||
flags.x1_matSetIdx = x1e4_glassMatIdx;
|
||||
x1d4_spiderBallGlass->GetInstance().ActivateLights(x23c_lights);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
x1d4_spiderBallGlass->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::Lighting;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = alpha;
|
||||
x1d4_spiderBallGlass->Draw(flags);
|
||||
|
||||
flags.m_extendedShader = EExtendedShader::ForcedAdditive;
|
||||
flags.x4_color = zeus::CColor::skWhite;
|
||||
flags.x4_color.a = x6c_ballPulseFactor * alpha * itemPulse;
|
||||
x1d4_spiderBallGlass->Draw(flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (x238_ballTransitionFlashGen)
|
||||
{
|
||||
const u8* c = BallTransFlashColors[x1e8_ballGlowColorIdx];
|
||||
zeus::CColor color = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, 1.f};
|
||||
x238_ballTransitionFlashGen->SetModulationColor(color);
|
||||
x238_ballTransitionFlashGen->Render();
|
||||
}
|
||||
|
||||
CGraphics::DisableAllLights();
|
||||
}
|
||||
|
||||
void CSamusDoll::Touch()
|
||||
{
|
||||
if (!CheckLoadComplete())
|
||||
return;
|
||||
xc8_suitModel1->AnimationData()->PreRender();
|
||||
xc8_suitModel0->AnimationData()->PreRender();
|
||||
x134_suitModelBoots->AnimationData()->PreRender();
|
||||
x184_ballModelData->AnimationData()->PreRender();
|
||||
xc8_suitModel1->Touch(CModelData::EWhichModel::Normal, 0);
|
||||
xc8_suitModel0->Touch(CModelData::EWhichModel::Normal, 0);
|
||||
x134_suitModelBoots->Touch(CModelData::EWhichModel::Normal, 0);
|
||||
x184_ballModelData->Touch(CModelData::EWhichModel::Normal, 0);
|
||||
}
|
||||
|
||||
void CSamusDoll::SetupLights()
|
||||
{
|
||||
x23c_lights[0] = CLight::BuildDirectional(xb0_rot.toTransform().basis[1], zeus::CColor(0.75f, 1.f));
|
||||
x23c_lights[0] = CLight::BuildDirectional(xb0_userRot.toTransform().basis[1], zeus::CColor(0.75f, 1.f));
|
||||
x24c_actorLights->BuildFakeLightList(x23c_lights, zeus::CColor::skBlack);
|
||||
}
|
||||
|
||||
void CSamusDoll::CheckTransition(bool morphballComplete)
|
||||
void CSamusDoll::SetInMorphball(bool morphball)
|
||||
{
|
||||
if (x54_ > 0.f)
|
||||
if (x54_remTransitionTime > 0.f)
|
||||
return;
|
||||
if (x4d_morphballComplete == morphballComplete)
|
||||
if (x4d_selectedMorphball == morphball)
|
||||
return;
|
||||
x4d_morphballComplete = morphballComplete;
|
||||
x4d_selectedMorphball = morphball;
|
||||
SetTransitionAnimation();
|
||||
}
|
||||
|
||||
void CSamusDoll::SetTransitionAnimation()
|
||||
{
|
||||
if (!x4c_intoBallComplete)
|
||||
if (!x4c_completedMorphball)
|
||||
{
|
||||
xc8_suitModel1->AnimationData()->SetAnimation(CAnimPlaybackParms{0, -1, 1.f, true}, false);
|
||||
/* Into morphball */
|
||||
xc8_suitModel0->AnimationData()->SetAnimation(CAnimPlaybackParms{0, -1, 1.f, true}, false);
|
||||
x134_suitModelBoots->AnimationData()->SetAnimation(CAnimPlaybackParms{0, -1, 1.f, true}, false);
|
||||
x50_ = x54_ = xc8_suitModel1->GetAnimationData()->GetAnimationDuration(0);
|
||||
x50_totalTransitionTime = x54_remTransitionTime = xc8_suitModel0->GetAnimationData()->GetAnimationDuration(0);
|
||||
}
|
||||
else if (!x4d_morphballComplete)
|
||||
else if (!x4d_selectedMorphball)
|
||||
{
|
||||
xc8_suitModel1->AnimationData()->SetAnimation(CAnimPlaybackParms{1, -1, 1.f, true}, false);
|
||||
/* Outta morphball */
|
||||
xc8_suitModel0->AnimationData()->SetAnimation(CAnimPlaybackParms{1, -1, 1.f, true}, false);
|
||||
x134_suitModelBoots->AnimationData()->SetAnimation(CAnimPlaybackParms{1, -1, 1.f, true}, false);
|
||||
x50_ = x54_ = xc8_suitModel1->GetAnimationData()->GetAnimationDuration(1);
|
||||
x50_totalTransitionTime = x54_remTransitionTime = xc8_suitModel0->GetAnimationData()->GetAnimationDuration(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,7 +757,7 @@ void CSamusDoll::SetRotation(float xDelta, float zDelta, float f3)
|
|||
if (xc4_viewInterp != 0.f && xc4_viewInterp != 1.f)
|
||||
return;
|
||||
SetRotationSfxPlaying(xDelta != 0.f || zDelta != 0.f);
|
||||
zeus::CEulerAngles angles(xb0_rot);
|
||||
zeus::CEulerAngles angles(xb0_userRot);
|
||||
|
||||
zeus::CRelAngle angX(angles.x);
|
||||
zeus::CRelAngle angZ(angles.z);
|
||||
|
@ -345,7 +778,7 @@ void CSamusDoll::SetRotation(float xDelta, float zDelta, float f3)
|
|||
zeus::CQuaternion quat;
|
||||
quat.rotateZ(angZ);
|
||||
quat.rotateX(angX);
|
||||
xb0_rot = quat;
|
||||
xb0_userRot = quat;
|
||||
}
|
||||
|
||||
void CSamusDoll::SetOffset(const zeus::CVector3f& offset, float sfxThreshold)
|
||||
|
@ -353,13 +786,13 @@ void CSamusDoll::SetOffset(const zeus::CVector3f& offset, float sfxThreshold)
|
|||
if (xc4_viewInterp != 0.f && xc4_viewInterp != 1.f)
|
||||
return;
|
||||
zeus::CVector3f oldOffset = xa4_offset;
|
||||
zeus::CMatrix3f rotMtx = xb0_rot.toTransform().basis;
|
||||
zeus::CMatrix3f rotMtx = xb0_userRot.toTransform().basis;
|
||||
xa4_offset += rotMtx * zeus::CVector3f(offset.x, 0.f, offset.z);
|
||||
SetOffsetSfxPlaying((oldOffset - xa4_offset).magnitude() > sfxThreshold);
|
||||
float oldZoom = xc0_zoom;
|
||||
xc0_zoom = zeus::clamp(-4.f, xc0_zoom + offset.y, -2.2f);
|
||||
bool zoomSfx = std::fabs(xc0_zoom - oldZoom) > sfxThreshold;
|
||||
float zoomDelta = offset.y - (xc0_zoom - oldZoom);
|
||||
float oldZoom = xc0_userZoom;
|
||||
xc0_userZoom = zeus::clamp(-4.f, xc0_userZoom + offset.y, -2.2f);
|
||||
bool zoomSfx = std::fabs(xc0_userZoom - oldZoom) > sfxThreshold;
|
||||
float zoomDelta = offset.y - (xc0_userZoom - oldZoom);
|
||||
zeus::CVector3f newOffset = rotMtx[1] * zoomDelta + xa4_offset;
|
||||
zeus::CVector3f delta = newOffset - xa4_offset;
|
||||
oldOffset = xa4_offset;
|
||||
|
@ -388,7 +821,7 @@ void CSamusDoll::SetOffset(const zeus::CVector3f& offset, float sfxThreshold)
|
|||
xa4_offset = delta.normalized() + skInitialOffset;
|
||||
}
|
||||
|
||||
void CSamusDoll::BeginViewInterpolate(bool zoomOut)
|
||||
void CSamusDoll::BeginViewInterpolate(bool zoomIn)
|
||||
{
|
||||
if (xc4_viewInterp == 0.f)
|
||||
{
|
||||
|
@ -402,12 +835,11 @@ void CSamusDoll::BeginViewInterpolate(bool zoomOut)
|
|||
CSfxManager::SfxStart(1441, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
|
||||
}
|
||||
|
||||
xc4_viewInterp = zoomOut ? FLT_EPSILON : (-1.f + FLT_EPSILON);
|
||||
xc4_viewInterp = zoomIn ? FLT_EPSILON : (-1.f + FLT_EPSILON);
|
||||
x84_interpStartOffset = xa4_offset;
|
||||
x90_interpStartRot = xb0_rot;
|
||||
xa0_interpStartZoom = xc0_zoom;
|
||||
|
||||
x80_ = zoomOut ? -2.2f : -3.6f;
|
||||
x90_userInterpRot = xb0_userRot;
|
||||
xa0_userInterpZoom = xc0_userZoom;
|
||||
x80_fixedZoom = zoomIn ? -2.2f : -3.6f;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,34 +18,33 @@ namespace MP1
|
|||
class CSamusDoll
|
||||
{
|
||||
std::vector<CToken> x0_depToks;
|
||||
zeus::CTransform x10_;
|
||||
float x40_ = 0.f;
|
||||
zeus::CTransform x10_xf;
|
||||
float x40_alphaIn = 0.f;
|
||||
CPlayerState::EPlayerSuit x44_suit;
|
||||
CPlayerState::EBeamId x48_beam;
|
||||
bool x4c_intoBallComplete = false;
|
||||
bool x4d_morphballComplete = false;
|
||||
float x50_ = 1.f;
|
||||
float x54_ = 0.f;
|
||||
float x58_ = 0.f;
|
||||
float x5c_ = 0.f;
|
||||
float x60_ = 0.f;
|
||||
float x64_ = 0.f;
|
||||
float x68_ = 0.f;
|
||||
float x6c_ = 0.f;
|
||||
zeus::CQuaternion x70_;
|
||||
float x80_ = -3.6f;
|
||||
bool x4c_completedMorphball = false;
|
||||
bool x4d_selectedMorphball = false;
|
||||
float x50_totalTransitionTime = 1.f;
|
||||
float x54_remTransitionTime = 0.f;
|
||||
float x58_suitPulseFactor = 0.f;
|
||||
float x5c_beamPulseFactor = 0.f;
|
||||
float x60_grapplePulseFactor = 0.f;
|
||||
float x64_bootsPulseFactor = 0.f;
|
||||
float x68_visorPulseFactor = 0.f;
|
||||
float x6c_ballPulseFactor = 0.f;
|
||||
zeus::CQuaternion x70_fixedRot;
|
||||
float x80_fixedZoom = -3.6f;
|
||||
zeus::CVector3f x84_interpStartOffset = skInitialOffset;
|
||||
zeus::CQuaternion x90_interpStartRot;
|
||||
float xa0_interpStartZoom = -3.6f;
|
||||
zeus::CQuaternion x90_userInterpRot;
|
||||
float xa0_userInterpZoom = -3.6f;
|
||||
zeus::CVector3f xa4_offset = skInitialOffset;
|
||||
zeus::CQuaternion xb0_rot;
|
||||
float xc0_zoom = -3.6f;
|
||||
zeus::CQuaternion xb0_userRot;
|
||||
float xc0_userZoom = -3.6f;
|
||||
float xc4_viewInterp = 0.f;
|
||||
std::experimental::optional<CModelData> xc8_suitModel1;
|
||||
std::experimental::optional<CModelData> xc8_suitModel0;
|
||||
rstl::reserved_vector<TCachedToken<CSkinnedModel>, 2> x118_suitModel1and2;
|
||||
std::experimental::optional<CModelData> x134_suitModelBoots;
|
||||
std::experimental::optional<CModelData> x184_ballModelData;
|
||||
bool x1d0_ = false;
|
||||
TLockedToken<CModel> x1d4_spiderBallGlass;
|
||||
u32 x1e0_ballMatIdx;
|
||||
u32 x1e4_glassMatIdx;
|
||||
|
@ -58,10 +57,11 @@ class CSamusDoll
|
|||
TLockedToken<CGenDescription> x224_ballInnerGlow;
|
||||
std::unique_ptr<CElementGen> x22c_ballInnerGlowGen;
|
||||
TLockedToken<CGenDescription> x230_ballTransitionFlash;
|
||||
std::unique_ptr<CElementGen> x238_ballTransitionFlashGen;
|
||||
std::vector<CLight> x23c_lights;
|
||||
std::unique_ptr<CActorLights> x24c_actorLights;
|
||||
bool x25c_ = false;
|
||||
float x260_ = 0.f;
|
||||
TLockedToken<CTexture> x250_phazonIndirectTexture; // Used to be optional
|
||||
zeus::CRelAngle x260_phazonOffsetAngle;
|
||||
CSfxHandle x264_offsetSfx;
|
||||
CSfxHandle x268_rotateSfx;
|
||||
CSfxHandle x26c_zoomSfx;
|
||||
|
@ -71,11 +71,11 @@ class CSamusDoll
|
|||
{
|
||||
bool x270_24_hasSpiderBall : 1;
|
||||
bool x270_25_hasGrappleBeam : 1;
|
||||
bool x270_26_ : 1;
|
||||
bool x270_27_ : 1;
|
||||
bool x270_28_ : 1;
|
||||
bool x270_29_ : 1;
|
||||
bool x270_30_ : 1;
|
||||
bool x270_26_pulseSuit : 1;
|
||||
bool x270_27_pulseBeam : 1;
|
||||
bool x270_28_pulseGrapple : 1;
|
||||
bool x270_29_pulseBoots : 1;
|
||||
bool x270_30_pulseVisor : 1;
|
||||
bool x270_31_loaded : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
|
@ -98,10 +98,15 @@ public:
|
|||
void Update(float dt, CRandom16& rand);
|
||||
void Draw(const CStateManager& mgr, float alpha);
|
||||
void Touch();
|
||||
void CheckTransition(bool morphballComplete);
|
||||
void SetInMorphball(bool morphballComplete);
|
||||
void SetRotation(float xDelta, float zDelta, float);
|
||||
void SetOffset(const zeus::CVector3f& offset, float sfxThreshold);
|
||||
void BeginViewInterpolate(bool zoomOut);
|
||||
void SetPulseSuit(bool b) { x270_26_pulseSuit = b; }
|
||||
void SetPulseVisor(bool b) { x270_30_pulseVisor = b; }
|
||||
void SetPulseBoots(bool b) { x270_29_pulseBoots = b; }
|
||||
void SetPulseGrapple(bool b) { x270_28_pulseGrapple = b; }
|
||||
void SetPulseBeam(bool b) { x270_27_pulseBeam = b; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Graphics/Shaders/CEnergyBarShader.hpp"
|
||||
#include "Graphics/Shaders/CRadarPaintShader.hpp"
|
||||
#include "Graphics/Shaders/CMapSurfaceShader.hpp"
|
||||
#include "Graphics/Shaders/CPhazonSuitFilter.hpp"
|
||||
#include "Character/CCharLayoutInfo.hpp"
|
||||
#include "Audio/CStreamAudioManager.hpp"
|
||||
#include "CGBASupport.hpp"
|
||||
|
@ -29,6 +30,7 @@ URDE_DECL_SPECIALIZE_SHADER(CFogVolumeFilter)
|
|||
URDE_DECL_SPECIALIZE_SHADER(CEnergyBarShader)
|
||||
URDE_DECL_SPECIALIZE_SHADER(CRadarPaintShader)
|
||||
URDE_DECL_SPECIALIZE_SHADER(CMapSurfaceShader)
|
||||
URDE_DECL_SPECIALIZE_SHADER(CPhazonSuitFilter)
|
||||
URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CColoredQuadFilter)
|
||||
URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilter)
|
||||
URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilterAlpha)
|
||||
|
@ -222,6 +224,7 @@ CMain::BooSetter::BooSetter(boo::IGraphicsDataFactory* factory,
|
|||
TShader<CEnergyBarShader>::Initialize();
|
||||
TShader<CRadarPaintShader>::Initialize();
|
||||
TShader<CMapSurfaceShader>::Initialize();
|
||||
TShader<CPhazonSuitFilter>::Initialize();
|
||||
TMultiBlendShader<CColoredQuadFilter>::Initialize();
|
||||
TMultiBlendShader<CTexturedQuadFilter>::Initialize();
|
||||
TMultiBlendShader<CTexturedQuadFilterAlpha>::Initialize();
|
||||
|
@ -354,6 +357,7 @@ void CMain::Shutdown()
|
|||
TShader<CEnergyBarShader>::Shutdown();
|
||||
TShader<CRadarPaintShader>::Shutdown();
|
||||
TShader<CMapSurfaceShader>::Shutdown();
|
||||
TShader<CPhazonSuitFilter>::Shutdown();
|
||||
TMultiBlendShader<CColoredQuadFilter>::Shutdown();
|
||||
TMultiBlendShader<CTexturedQuadFilter>::Shutdown();
|
||||
TMultiBlendShader<CTexturedQuadFilterAlpha>::Shutdown();
|
||||
|
|
|
@ -283,7 +283,7 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
EModelOrientationType orientType,
|
||||
EOptionalSystemFlags flags)
|
||||
: x1c_genDesc(gen), x28_orientType(orientType),
|
||||
x226_enableOPTS((flags & EOptionalSystemFlags::Two) != EOptionalSystemFlags::None), x230_randState(x74_randomSeed)
|
||||
x226_enableOPTS((flags & EOptionalSystemFlags::Two) != EOptionalSystemFlags::None), x27c_randState(x94_randomSeed)
|
||||
{
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
|
||||
|
@ -297,9 +297,9 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
{
|
||||
int seedVal;
|
||||
seedElem->GetValue(x50_curFrame, seedVal);
|
||||
x74_randomSeed = seedVal;
|
||||
x94_randomSeed = seedVal;
|
||||
}
|
||||
x230_randState.SetSeed(x74_randomSeed);
|
||||
x27c_randState.SetSeed(x94_randomSeed);
|
||||
++g_ParticleSystemAliveCount;
|
||||
x224_25_LIT_ = desc->x44_29_x30_29_LIT_;
|
||||
x224_26_AAPH = desc->x44_26_x30_26_AAPH;
|
||||
|
@ -318,7 +318,7 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
|
||||
CIntElement* cssdElem = desc->xa0_x8c_CSSD.get();
|
||||
if (cssdElem)
|
||||
cssdElem->GetValue(0, x244_CSSD);
|
||||
cssdElem->GetValue(0, x2a0_CSSD);
|
||||
|
||||
SChildGeneratorDesc& idts = desc->xa4_x90_IDTS;
|
||||
if (idts.m_found)
|
||||
|
@ -342,34 +342,52 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
CIntElement* pisyElem = desc->xc8_xb4_PISY.get();
|
||||
if (pisyElem)
|
||||
{
|
||||
pisyElem->GetValue(0, x25c_PISY);
|
||||
if (x25c_PISY <= 0)
|
||||
x25c_PISY = 1;
|
||||
pisyElem->GetValue(0, x2a8_PISY);
|
||||
if (x2a8_PISY <= 0)
|
||||
x2a8_PISY = 1;
|
||||
}
|
||||
|
||||
CIntElement* sisyElem = desc->xcc_xb8_SISY.get();
|
||||
if (sisyElem)
|
||||
pisyElem->GetValue(0, x258_SISY);
|
||||
pisyElem->GetValue(0, x2a4_SISY);
|
||||
|
||||
CIntElement* sssdElem = desc->xe4_xd0_SSSD.get();
|
||||
if (sssdElem)
|
||||
sssdElem->GetValue(0, x270_SSSD);
|
||||
sssdElem->GetValue(0, x2ac_SSSD);
|
||||
|
||||
CVectorElement* sspoElem = desc->xe8_xd4_SSPO.get();
|
||||
if (sspoElem)
|
||||
sspoElem->GetValue(0, x274_SSPO);
|
||||
{
|
||||
sspoElem->GetValue(0, x2b0_SSPO);
|
||||
if (!sspoElem->IsFastConstant())
|
||||
x26c_24_ = true;
|
||||
}
|
||||
|
||||
CIntElement* sesdElem = desc->xf8_xe4_SESD.get();
|
||||
if (sesdElem)
|
||||
sesdElem->GetValue(0, x290_SESD);
|
||||
sesdElem->GetValue(0, x2bc_SESD);
|
||||
|
||||
CVectorElement* sepoElem = desc->xfc_xe8_SEPO.get();
|
||||
if (sepoElem)
|
||||
sepoElem->GetValue(0, x294_SEPO);
|
||||
{
|
||||
sepoElem->GetValue(0, x2c0_SEPO);
|
||||
if (!sepoElem->IsFastConstant())
|
||||
x26c_24_ = true;
|
||||
}
|
||||
|
||||
CVectorElement* pofsElem = desc->x18_xc_POFS.get();
|
||||
if (pofsElem)
|
||||
{
|
||||
pofsElem->GetValue(x50_curFrame, xf4_POFS);
|
||||
if (!pofsElem->IsFastConstant())
|
||||
x26c_24_ = true;
|
||||
}
|
||||
|
||||
CIntElement* psltElem = desc->xc_x0_PSLT.get();
|
||||
if (psltElem)
|
||||
psltElem->GetValue(0, x214_PSLT);
|
||||
psltElem->GetValue(0, x268_PSLT);
|
||||
else
|
||||
x268_PSLT = INT_MAX;
|
||||
|
||||
/* Removed from retail
|
||||
CVectorElement* psivElem = desc->x0_PSIV.get();
|
||||
|
@ -379,21 +397,17 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
|
||||
CIntElement* maxpElem = desc->x28_x1c_MAXP.get();
|
||||
if (maxpElem)
|
||||
maxpElem->GetValue(x50_curFrame, x70_MAXP);
|
||||
maxpElem->GetValue(x50_curFrame, x90_MAXP);
|
||||
|
||||
x2c_particleLists.reserve(x70_MAXP);
|
||||
x30_particleLists.reserve(x90_MAXP);
|
||||
if (x28_orientType == EModelOrientationType::One)
|
||||
{
|
||||
x3c_parentMatrices.insert(x3c_parentMatrices.end(), x70_MAXP,
|
||||
x60_parentMatrices.insert(x60_parentMatrices.end(), x90_MAXP,
|
||||
zeus::CMatrix3f::skIdentityMatrix3f);
|
||||
}
|
||||
|
||||
x225_26_LINE = desc->x44_24_x30_24_LINE;
|
||||
x225_27_FXLL = desc->x44_25_x30_25_FXLL;
|
||||
|
||||
CVectorElement* pofsElem = desc->x18_xc_POFS.get();
|
||||
if (pofsElem)
|
||||
pofsElem->GetValue(x50_curFrame, x94_POFS);
|
||||
x26c_31_LINE = desc->x44_24_x30_24_LINE;
|
||||
x26d_24_FXLL = desc->x44_25_x30_25_FXLL;
|
||||
|
||||
CIntElement* ltypElem = desc->x100_xec_LTYP.get();
|
||||
if (ltypElem)
|
||||
|
@ -404,16 +418,16 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
{
|
||||
case LightType::None:
|
||||
default:
|
||||
x2dc_lightType = LightType::None;
|
||||
x308_lightType = LightType::None;
|
||||
break;
|
||||
case LightType::Directional:
|
||||
x2dc_lightType = LightType::Directional;
|
||||
x308_lightType = LightType::Directional;
|
||||
break;
|
||||
case LightType::Custom:
|
||||
x2dc_lightType = LightType::Custom;
|
||||
x308_lightType = LightType::Custom;
|
||||
break;
|
||||
case LightType::Spot:
|
||||
x2dc_lightType = LightType::Spot;
|
||||
x308_lightType = LightType::Spot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -426,32 +440,32 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
|||
switch (EFalloffType(lfot))
|
||||
{
|
||||
case EFalloffType::Constant:
|
||||
x300_falloffType = EFalloffType::Constant;
|
||||
x32c_falloffType = EFalloffType::Constant;
|
||||
break;
|
||||
case EFalloffType::Linear:
|
||||
default:
|
||||
x300_falloffType = EFalloffType::Linear;
|
||||
x32c_falloffType = EFalloffType::Linear;
|
||||
break;
|
||||
case EFalloffType::Quadratic:
|
||||
x300_falloffType = EFalloffType::Quadratic;
|
||||
x32c_falloffType = EFalloffType::Quadratic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x225_26_LINE)
|
||||
if (x26c_31_LINE)
|
||||
{
|
||||
CUVElement* texr = desc->x54_x40_TEXR.get();
|
||||
boo::ITexture* tex = nullptr;
|
||||
if (texr)
|
||||
tex = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||
int maxVerts = (x70_MAXP == 0 ? 256 : x70_MAXP);
|
||||
int maxVerts = (x90_MAXP == 0 ? 256 : x90_MAXP);
|
||||
m_lineRenderer.reset(new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines,
|
||||
maxVerts * 2, tex, x224_26_AAPH));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_shaderClass = CElementGenShaders::GetShaderClass(*this);
|
||||
size_t maxInsts = x224_29_MBLR ? (m_maxMBSP * x70_MAXP) : x70_MAXP;
|
||||
size_t maxInsts = x224_29_MBLR ? (m_maxMBSP * x90_MAXP) : x90_MAXP;
|
||||
maxInsts = (maxInsts == 0 ? 256 : maxInsts);
|
||||
m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
|
@ -494,7 +508,7 @@ void CElementGen::Update(double t)
|
|||
|
||||
bool CElementGen::InternalUpdate(double dt)
|
||||
{
|
||||
CGlobalRandom gr(x230_randState);
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
|
||||
double dt1 = 1.0 / 60.0;
|
||||
|
@ -533,7 +547,7 @@ bool CElementGen::InternalUpdate(double dt)
|
|||
CRealElement* grteElem = desc->x2c_x20_GRTE.get();
|
||||
if (grteElem->GetValue(x50_curFrame, grte))
|
||||
{
|
||||
x2c_particleLists.clear();
|
||||
x30_particleLists.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -542,16 +556,16 @@ bool CElementGen::InternalUpdate(double dt)
|
|||
int genCount = floorf(x6c_generatorRemainder);
|
||||
x6c_generatorRemainder = x6c_generatorRemainder - genCount;
|
||||
|
||||
if (!x68_particleEmission || x50_curFrame >= x214_PSLT)
|
||||
if (!x68_particleEmission || x50_curFrame >= x268_PSLT)
|
||||
genCount = 0;
|
||||
|
||||
CIntElement* maxpElem = desc->x28_x1c_MAXP.get();
|
||||
if (maxpElem)
|
||||
maxpElem->GetValue(x50_curFrame, x70_MAXP);
|
||||
maxpElem->GetValue(x50_curFrame, x90_MAXP);
|
||||
|
||||
UpdateExistingParticles();
|
||||
|
||||
CParticleGlobals::SetParticleLifetime(x214_PSLT);
|
||||
CParticleGlobals::SetParticleLifetime(x268_PSLT);
|
||||
bool oldBoolVal = s_inCreateNewParticles;
|
||||
s_inCreateNewParticles = true;
|
||||
CreateNewParticles(genCount);
|
||||
|
@ -560,7 +574,7 @@ bool CElementGen::InternalUpdate(double dt)
|
|||
UpdatePSTranslationAndOrientation();
|
||||
UpdateChildParticleSystems(1 / 60.0);
|
||||
|
||||
if (x2dc_lightType != LightType::None)
|
||||
if (x308_lightType != LightType::None)
|
||||
UpdateLightParameters();
|
||||
|
||||
++frameUpdateCount;
|
||||
|
@ -598,8 +612,8 @@ void CElementGen::UpdateExistingParticles()
|
|||
|
||||
x208_activeParticleCount = 0;
|
||||
CParticleGlobals::SetEmitterTime(x50_curFrame);
|
||||
for (std::vector<CParticleListItem>::iterator p = x2c_particleLists.begin();
|
||||
p != x2c_particleLists.end();)
|
||||
for (std::vector<CParticleListItem>::iterator p = x30_particleLists.begin();
|
||||
p != x30_particleLists.end();)
|
||||
{
|
||||
CElementGen::CParticle& particle = g_StaticParticleList[p->x0_partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
@ -607,21 +621,21 @@ void CElementGen::UpdateExistingParticles()
|
|||
if (particle.x0_endFrame < x50_curFrame)
|
||||
{
|
||||
g_StaticFreeList[++g_FreeIndex] = p->x0_partIdx;
|
||||
if (p+1 == x2c_particleLists.end())
|
||||
if (p+1 == x30_particleLists.end())
|
||||
{
|
||||
x2c_particleLists.pop_back();
|
||||
x30_particleLists.pop_back();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = *(x2c_particleLists.end()-1);
|
||||
*p = *(x30_particleLists.end()-1);
|
||||
if (x28_orientType == EModelOrientationType::One)
|
||||
{
|
||||
size_t i = p - x2c_particleLists.begin();
|
||||
x3c_parentMatrices[i] = x3c_parentMatrices[x2c_particleLists.size()-1];
|
||||
size_t i = p - x30_particleLists.begin();
|
||||
x60_parentMatrices[i] = x60_parentMatrices[x30_particleLists.size()-1];
|
||||
}
|
||||
x2c_particleLists.pop_back();
|
||||
if (p != x2c_particleLists.end())
|
||||
x30_particleLists.pop_back();
|
||||
if (p != x30_particleLists.end())
|
||||
if (particle.x0_endFrame < x50_curFrame)
|
||||
continue;
|
||||
}
|
||||
|
@ -706,7 +720,7 @@ void CElementGen::UpdateExistingParticles()
|
|||
}
|
||||
}
|
||||
|
||||
if (x225_26_LINE)
|
||||
if (x26c_31_LINE)
|
||||
{
|
||||
CRealElement* leng = desc->x20_x14_LENG.get();
|
||||
if (leng)
|
||||
|
@ -743,13 +757,13 @@ void CElementGen::CreateNewParticles(int count)
|
|||
|
||||
if (!g_StaticListInitialized)
|
||||
Initialize();
|
||||
if (!count || x2c_particleLists.size() >= x70_MAXP)
|
||||
if (!count || x30_particleLists.size() >= x90_MAXP)
|
||||
return;
|
||||
|
||||
if (count + x2c_particleLists.size() > x70_MAXP)
|
||||
count = x70_MAXP - x2c_particleLists.size();
|
||||
CGlobalRandom gr(x230_randState);
|
||||
x2c_particleLists.reserve(x70_MAXP);
|
||||
if (count + x30_particleLists.size() > x90_MAXP)
|
||||
count = x90_MAXP - x30_particleLists.size();
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
x30_particleLists.reserve(x90_MAXP);
|
||||
|
||||
for (int i=0 ; i<count ; ++i)
|
||||
{
|
||||
|
@ -757,10 +771,10 @@ void CElementGen::CreateNewParticles(int count)
|
|||
return;
|
||||
|
||||
s16 staticIdx = g_StaticFreeList[g_FreeIndex];
|
||||
x2c_particleLists.emplace_back(staticIdx);
|
||||
x30_particleLists.emplace_back(staticIdx);
|
||||
++x208_activeParticleCount;
|
||||
if (x28_orientType == EModelOrientationType::One)
|
||||
x3c_parentMatrices[x2c_particleLists.size()-1] = x178_orientation.buildMatrix3f();
|
||||
x60_parentMatrices[x30_particleLists.size()-1] = x178_orientation.buildMatrix3f();
|
||||
|
||||
CElementGen::CParticle& particle = g_StaticParticleList[staticIdx];
|
||||
particle.x28_startFrame = x50_curFrame;
|
||||
|
@ -783,18 +797,18 @@ void CElementGen::CreateNewParticles(int count)
|
|||
emtr->GetValue(x210_curEmitterFrame, particle.x4_pos, particle.x1c_vel);
|
||||
zeus::CVector3f compXf1 = (xdc_globalScaleTransformInverse * x148_localScaleTransformInverse) * x7c_translation;
|
||||
zeus::CVector3f compXf2 = x178_orientation * particle.x4_pos;
|
||||
particle.x4_pos = compXf1 + compXf2 + x94_POFS;
|
||||
particle.x4_pos = compXf1 + compXf2 + xf4_POFS;
|
||||
particle.x1c_vel = x178_orientation * particle.x1c_vel;
|
||||
}
|
||||
else
|
||||
{
|
||||
zeus::CVector3f compXf1 = (xdc_globalScaleTransformInverse * x148_localScaleTransformInverse) * x7c_translation;
|
||||
particle.x4_pos = compXf1 + x94_POFS;
|
||||
particle.x4_pos = compXf1 + xf4_POFS;
|
||||
particle.x1c_vel.zeroOut();
|
||||
}
|
||||
particle.x10_prevPos = particle.x4_pos;
|
||||
|
||||
if (x225_26_LINE)
|
||||
if (x26c_31_LINE)
|
||||
{
|
||||
CRealElement* leng = desc->x20_x14_LENG.get();
|
||||
if (leng)
|
||||
|
@ -834,8 +848,8 @@ void CElementGen::UpdatePSTranslationAndOrientation()
|
|||
{
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
|
||||
CGlobalRandom gr(x230_randState);
|
||||
if (x214_PSLT < x50_curFrame)
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
if (x268_PSLT < x50_curFrame)
|
||||
return;
|
||||
|
||||
/* Removed from retail
|
||||
|
@ -871,15 +885,15 @@ void CElementGen::UpdatePSTranslationAndOrientation()
|
|||
|
||||
CVectorElement* pofs = desc->x18_xc_POFS.get();
|
||||
if (pofs)
|
||||
pofs->GetValue(x50_curFrame, x94_POFS);
|
||||
pofs->GetValue(x50_curFrame, xf4_POFS);
|
||||
|
||||
CVectorElement* sspo = desc->xe8_xd4_SSPO.get();
|
||||
if (sspo)
|
||||
sspo->GetValue(x50_curFrame, x274_SSPO);
|
||||
sspo->GetValue(x50_curFrame, x2b0_SSPO);
|
||||
|
||||
CVectorElement* sepo = desc->xfc_xe8_SEPO.get();
|
||||
if (sepo)
|
||||
sspo->GetValue(x50_curFrame, x294_SEPO);
|
||||
sspo->GetValue(x50_curFrame, x2c0_SEPO);
|
||||
}
|
||||
|
||||
CElementGen* CElementGen::ConstructChildParticleSystem(const TToken<CGenDescription>& desc)
|
||||
|
@ -901,9 +915,9 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
{
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
|
||||
CGlobalRandom gr(x230_randState);
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
SChildGeneratorDesc& icts = desc->x8c_x78_ICTS;
|
||||
if (icts.m_found && x64_prevFrame != x50_curFrame && x244_CSSD == x50_curFrame)
|
||||
if (icts.m_found && x64_prevFrame != x50_curFrame && x2a0_CSSD == x50_curFrame)
|
||||
{
|
||||
int ncsyVal = 1;
|
||||
CIntElement* ncsy = desc->x9c_x88_NCSY.get();
|
||||
|
@ -913,47 +927,47 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
CGenDescription* ictsDesc = icts.m_token.GetObj();
|
||||
if (!(x226_enableOPTS && ictsDesc->x45_31_x32_25_OPTS))
|
||||
{
|
||||
x234_activePartChildren.reserve(ncsyVal + x234_activePartChildren.size());
|
||||
x290_activePartChildren.reserve(ncsyVal + x290_activePartChildren.size());
|
||||
for (int i=0 ; i<ncsyVal ; ++i)
|
||||
{
|
||||
CElementGen* chGen = ConstructChildParticleSystem(icts.m_token);
|
||||
x234_activePartChildren.emplace_back(chGen);
|
||||
x290_activePartChildren.emplace_back(chGen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SChildGeneratorDesc& iits = desc->xb8_xa4_IITS;
|
||||
if (iits.m_found && x64_prevFrame != x50_curFrame && x50_curFrame < x214_PSLT &&
|
||||
x68_particleEmission == 1 && x50_curFrame >= x258_SISY &&
|
||||
((x50_curFrame - x258_SISY) % x25c_PISY) == 0)
|
||||
if (iits.m_found && x64_prevFrame != x50_curFrame && x50_curFrame < x268_PSLT &&
|
||||
x68_particleEmission == 1 && x50_curFrame >= x2a4_SISY &&
|
||||
((x50_curFrame - x2a4_SISY) % x2a8_PISY) == 0)
|
||||
{
|
||||
CGenDescription* iitsDesc = iits.m_token.GetObj();
|
||||
if (!(x226_enableOPTS && iitsDesc->x45_31_x32_25_OPTS))
|
||||
{
|
||||
CElementGen* chGen = ConstructChildParticleSystem(iits.m_token);
|
||||
x234_activePartChildren.emplace_back(chGen);
|
||||
x290_activePartChildren.emplace_back(chGen);
|
||||
}
|
||||
}
|
||||
|
||||
CSpawnSystemKeyframeData* kssm = desc->xd0_xbc_KSSM.get();
|
||||
if (kssm && x64_prevFrame != x50_curFrame && x50_curFrame < x214_PSLT)
|
||||
if (kssm && x64_prevFrame != x50_curFrame && x50_curFrame < x268_PSLT)
|
||||
{
|
||||
std::vector<CSpawnSystemKeyframeData::CSpawnSystemKeyframeInfo>& systems =
|
||||
kssm->GetSpawnedSystemsAtFrame(x50_curFrame);
|
||||
x234_activePartChildren.reserve(x234_activePartChildren.size() + systems.size());
|
||||
x290_activePartChildren.reserve(x290_activePartChildren.size() + systems.size());
|
||||
for (CSpawnSystemKeyframeData::CSpawnSystemKeyframeInfo& system : systems)
|
||||
{
|
||||
TLockedToken<CGenDescription>& token = system.GetToken();
|
||||
if (!(x226_enableOPTS && token.GetObj()->x45_31_x32_25_OPTS))
|
||||
{
|
||||
CElementGen* chGen = ConstructChildParticleSystem(token);
|
||||
x234_activePartChildren.emplace_back(chGen);
|
||||
x290_activePartChildren.emplace_back(chGen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SSwooshGeneratorDesc& sswh = desc->xd4_xc0_SSWH;
|
||||
if (sswh.m_found && x64_prevFrame != x50_curFrame && x50_curFrame == x270_SSSD)
|
||||
if (sswh.m_found && x64_prevFrame != x50_curFrame && x50_curFrame == x2ac_SSSD)
|
||||
{
|
||||
CParticleSwoosh* sswhGen = new CParticleSwoosh(sswh.m_token, 0);
|
||||
sswhGen->SetGlobalTranslation(x88_globalTranslation);
|
||||
|
@ -965,7 +979,7 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
}
|
||||
|
||||
SElectricGeneratorDesc& selc = desc->xec_xd8_SELC;
|
||||
if (selc.m_found && x64_prevFrame != x50_curFrame && x50_curFrame == x290_SESD)
|
||||
if (selc.m_found && x64_prevFrame != x50_curFrame && x50_curFrame == x2bc_SESD)
|
||||
{
|
||||
CParticleElectric* selcGen = new CParticleElectric(selc.m_token);
|
||||
selcGen->SetGlobalTranslation(x88_globalTranslation);
|
||||
|
@ -976,7 +990,7 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
x280_elscChildren.emplace_back(selcGen);
|
||||
}
|
||||
|
||||
for (auto p = x234_activePartChildren.begin() ; p != x234_activePartChildren.end() ;)
|
||||
for (auto p = x290_activePartChildren.begin() ; p != x290_activePartChildren.end() ;)
|
||||
{
|
||||
std::unique_ptr<CElementGen>& ch = *p;
|
||||
|
||||
|
@ -989,7 +1003,7 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
ch->Update(dt);
|
||||
if (ch->IsSystemDeletable())
|
||||
{
|
||||
p = x234_activePartChildren.erase(p);
|
||||
p = x290_activePartChildren.erase(p);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1000,9 +1014,9 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
{
|
||||
std::unique_ptr<CElementGen>& ch = *p;
|
||||
|
||||
if (x214_PSLT <= x50_curFrame)
|
||||
if (x268_PSLT <= x50_curFrame)
|
||||
{
|
||||
if (x214_PSLT == x50_curFrame && x64_prevFrame != x50_curFrame)
|
||||
if (x268_PSLT == x50_curFrame && x64_prevFrame != x50_curFrame)
|
||||
{
|
||||
ch->SetTranslation(x7c_translation);
|
||||
ch->SetOrientation(x178_orientation);
|
||||
|
@ -1023,9 +1037,9 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
{
|
||||
std::unique_ptr<CParticleSwoosh>& ch = *p;
|
||||
|
||||
if ((x50_curFrame == x270_SSSD || x224_24_translationDirty) && x64_prevFrame != x50_curFrame)
|
||||
if ((x50_curFrame == x2ac_SSSD || x224_24_translationDirty) && x64_prevFrame != x50_curFrame)
|
||||
{
|
||||
zeus::CVector3f trans = x7c_translation + x274_SSPO;
|
||||
zeus::CVector3f trans = x7c_translation + x2b0_SSPO;
|
||||
ch->SetTranslation(trans);
|
||||
ch->SetOrientation(x178_orientation);
|
||||
}
|
||||
|
@ -1044,9 +1058,9 @@ void CElementGen::UpdateChildParticleSystems(double dt)
|
|||
{
|
||||
std::unique_ptr<CParticleElectric>& ch = *p;
|
||||
|
||||
if ((x50_curFrame == x290_SESD || x224_24_translationDirty) && x64_prevFrame != x50_curFrame)
|
||||
if ((x50_curFrame == x2bc_SESD || x224_24_translationDirty) && x64_prevFrame != x50_curFrame)
|
||||
{
|
||||
zeus::CVector3f trans = x7c_translation + x294_SEPO;
|
||||
zeus::CVector3f trans = x7c_translation + x2c0_SEPO;
|
||||
ch->SetTranslation(trans);
|
||||
ch->SetOrientation(x178_orientation);
|
||||
}
|
||||
|
@ -1076,7 +1090,7 @@ void CElementGen::UpdateLightParameters()
|
|||
if (lint)
|
||||
lint->GetValue(x50_curFrame, x2e4_LINT);
|
||||
|
||||
switch (x2dc_lightType)
|
||||
switch (x308_lightType)
|
||||
{
|
||||
default:
|
||||
case LightType::None:
|
||||
|
@ -1091,7 +1105,7 @@ void CElementGen::UpdateLightParameters()
|
|||
if (lfor)
|
||||
lfor->GetValue(x50_curFrame, x304_LFOR);
|
||||
|
||||
if (x2dc_lightType == LightType::Spot)
|
||||
if (x308_lightType == LightType::Spot)
|
||||
{
|
||||
CRealElement* lsla = desc->x11c_x108_LSLA.get();
|
||||
if (lsla)
|
||||
|
@ -1100,7 +1114,7 @@ void CElementGen::UpdateLightParameters()
|
|||
}
|
||||
case LightType::Directional:
|
||||
{
|
||||
if (x2dc_lightType != LightType::Custom)
|
||||
if (x308_lightType != LightType::Custom)
|
||||
{
|
||||
CVectorElement* ldir = desc->x110_xfc_LDIR.get();
|
||||
if (ldir)
|
||||
|
@ -1114,7 +1128,7 @@ u32 CElementGen::GetParticleCountAllInternal() const
|
|||
{
|
||||
u32 ret = x208_activeParticleCount;
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ret += ch->GetParticleCountAll();
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -1125,8 +1139,8 @@ u32 CElementGen::GetParticleCountAllInternal() const
|
|||
|
||||
void CElementGen::EndLifetime()
|
||||
{
|
||||
x214_PSLT = 0;
|
||||
for (std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
x268_PSLT = 0;
|
||||
for (std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->EndLifetime();
|
||||
for (std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
ch->EndLifetime();
|
||||
|
@ -1152,7 +1166,7 @@ void CElementGen::BuildParticleSystemBounds()
|
|||
zeus::CAABox aabb;
|
||||
bool accumulated = false;
|
||||
|
||||
for (std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
{
|
||||
auto chBounds = ch->GetBounds();
|
||||
if (chBounds)
|
||||
|
@ -1212,7 +1226,7 @@ void CElementGen::BuildParticleSystemBounds()
|
|||
u32 CElementGen::GetSystemCount()
|
||||
{
|
||||
u32 ret = 0;
|
||||
for (const std::unique_ptr<CElementGen>& child : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& child : x290_activePartChildren)
|
||||
ret += child->GetSystemCount();
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& child : x248_finishPartChildren)
|
||||
|
@ -1231,10 +1245,10 @@ void CElementGen::Render()
|
|||
x22c_backupLightActive = CGraphics::g_LightActive;
|
||||
CGraphics::DisableAllLights();
|
||||
|
||||
for (std::unique_ptr<CElementGen>& child : x234_activePartChildren)
|
||||
for (std::unique_ptr<CElementGen>& child : x290_activePartChildren)
|
||||
child->Render();
|
||||
|
||||
if (x214_PSLT <= x50_curFrame)
|
||||
if (x268_PSLT <= x50_curFrame)
|
||||
for (std::unique_ptr<CElementGen>& child : x248_finishPartChildren)
|
||||
child->Render();
|
||||
|
||||
|
@ -1244,13 +1258,13 @@ void CElementGen::Render()
|
|||
for (std::unique_ptr<CParticleElectric>& child : x280_elscChildren)
|
||||
child->Render();
|
||||
|
||||
if (x2c_particleLists.size())
|
||||
if (x30_particleLists.size())
|
||||
{
|
||||
SParticleModel& pmdl = desc->x5c_x48_PMDL;
|
||||
if (pmdl.m_found || desc->x45_24_x31_26_PMUS)
|
||||
RenderModels();
|
||||
|
||||
if (x225_26_LINE)
|
||||
if (x26c_31_LINE)
|
||||
RenderLines();
|
||||
else
|
||||
RenderParticles();
|
||||
|
@ -1265,7 +1279,7 @@ void CElementGen::RenderModels()
|
|||
|
||||
if (x225_29_modelsUseLights)
|
||||
CGraphics::SetLightState(x22c_backupLightActive);
|
||||
CGlobalRandom gr(x230_randState);
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
|
||||
SUVElementSet uvs = {0.f, 0.f, 1.f, 1.f};
|
||||
CUVElement* texr = desc->x54_x40_TEXR.get();
|
||||
|
@ -1296,7 +1310,7 @@ void CElementGen::RenderModels()
|
|||
|
||||
if (texr)
|
||||
{
|
||||
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||
CParticle& target = g_StaticParticleList[x30_particleLists[0].x0_partIdx];
|
||||
int partFrame = x50_curFrame - target.x28_startFrame;
|
||||
cachedTex = texr->GetValueTexture(partFrame).GetObj();
|
||||
cachedTex->Load(0, CTexture::EClampMode::One);
|
||||
|
@ -1338,8 +1352,8 @@ void CElementGen::RenderModels()
|
|||
zeus::CColor col = {1.f, 1.f, 1.f, 1.f};
|
||||
|
||||
zeus::CVector3f pmopVec;
|
||||
auto matrixIt = x3c_parentMatrices.begin();
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
auto matrixIt = x60_parentMatrices.begin();
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
@ -1454,7 +1468,7 @@ void CElementGen::RenderModels()
|
|||
void CElementGen::RenderLines()
|
||||
{
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
CGlobalRandom gr(x230_randState);
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
|
||||
zeus::CTransform systemViewPointMatrix(CGraphics::g_ViewMatrix);
|
||||
systemViewPointMatrix.origin.zeroOut();
|
||||
|
@ -1488,7 +1502,7 @@ void CElementGen::RenderLines()
|
|||
zeus::CColor moduColor = zeus::CColor::skWhite;
|
||||
if (texr)
|
||||
{
|
||||
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||
CParticle& target = g_StaticParticleList[x30_particleLists[0].x0_partIdx];
|
||||
int partFrame = x50_curFrame - target.x28_startFrame;
|
||||
cachedTex = texr->GetValueTexture(partFrame).GetObj();
|
||||
cachedTex->Load(0, CTexture::EClampMode::One);
|
||||
|
@ -1515,7 +1529,7 @@ void CElementGen::RenderLines()
|
|||
|
||||
m_lineRenderer->Reset();
|
||||
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
@ -1536,7 +1550,7 @@ void CElementGen::RenderLines()
|
|||
texr->GetValueUV(partFrame, uvs);
|
||||
|
||||
zeus::CVector3f dVec = particle.x4_pos - particle.x10_prevPos;
|
||||
if (x225_27_FXLL)
|
||||
if (x26d_24_FXLL)
|
||||
if (dVec.magSquared() >= 0.f)
|
||||
dVec.normalize();
|
||||
|
||||
|
@ -1564,7 +1578,7 @@ void CElementGen::RenderLines()
|
|||
void CElementGen::RenderParticles()
|
||||
{
|
||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||
CGlobalRandom gr(x230_randState);
|
||||
CGlobalRandom gr(x27c_randState);
|
||||
|
||||
CUVElement* texr = desc->x54_x40_TEXR.get();
|
||||
CUVElement* tind = desc->x58_x44_TIND.get();
|
||||
|
@ -1608,7 +1622,7 @@ void CElementGen::RenderParticles()
|
|||
|
||||
if (texr)
|
||||
{
|
||||
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||
CParticle& target = g_StaticParticleList[x30_particleLists[0].x0_partIdx];
|
||||
int partFrame = x50_curFrame - target.x28_startFrame;
|
||||
cachedTex = texr->GetValueTexture(partFrame).GetObj();
|
||||
cachedTex->Load(0, CTexture::EClampMode::One);
|
||||
|
@ -1628,13 +1642,13 @@ void CElementGen::RenderParticles()
|
|||
|
||||
if (desc->x44_28_x30_28_SORT)
|
||||
{
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
item.x4_viewPoint = systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) * x60_timeDeltaScale + particle.x10_prevPos);
|
||||
}
|
||||
|
||||
std::sort(x2c_particleLists.begin(), x2c_particleLists.end(),
|
||||
std::sort(x30_particleLists.begin(), x30_particleLists.end(),
|
||||
[](const CParticleListItem& a, const CParticleListItem& b) -> bool
|
||||
{return a.x4_viewPoint[1] >= b.x4_viewPoint[1];});
|
||||
}
|
||||
|
@ -1657,17 +1671,17 @@ void CElementGen::RenderParticles()
|
|||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
g_instTexData.clear();
|
||||
g_instTexData.reserve(x2c_particleLists.size());
|
||||
g_instTexData.reserve(x30_particleLists.size());
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
g_instNoTexData.clear();
|
||||
g_instNoTexData.reserve(x2c_particleLists.size());
|
||||
g_instNoTexData.reserve(x30_particleLists.size());
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, "unexpected particle shader class");
|
||||
break;
|
||||
}
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
@ -1788,18 +1802,18 @@ void CElementGen::RenderParticles()
|
|||
{
|
||||
case CElementGenShaders::EShaderClass::Tex:
|
||||
g_instTexData.clear();
|
||||
g_instTexData.reserve(x2c_particleLists.size() * mbspVal);
|
||||
g_instTexData.reserve(x30_particleLists.size() * mbspVal);
|
||||
break;
|
||||
case CElementGenShaders::EShaderClass::NoTex:
|
||||
g_instNoTexData.clear();
|
||||
g_instNoTexData.reserve(x2c_particleLists.size() * mbspVal);
|
||||
g_instNoTexData.reserve(x30_particleLists.size() * mbspVal);
|
||||
break;
|
||||
default:
|
||||
Log.report(logvisor::Fatal, "unexpected particle shader class");
|
||||
break;
|
||||
}
|
||||
float mbspFac = 1.f / float(mbspVal);
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
@ -1956,7 +1970,7 @@ void CElementGen::RenderParticlesIndirectTexture()
|
|||
}
|
||||
|
||||
CUVElement* texr = desc->x54_x40_TEXR.get();
|
||||
CParticle& firstParticle = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||
CParticle& firstParticle = g_StaticParticleList[x30_particleLists[0].x0_partIdx];
|
||||
int partFrame = x50_curFrame - firstParticle.x28_startFrame;
|
||||
CTexture* cachedTex = texr->GetValueTexture(partFrame).GetObj();
|
||||
cachedTex->Load(0, CTexture::EClampMode::One);
|
||||
|
@ -1977,21 +1991,21 @@ void CElementGen::RenderParticlesIndirectTexture()
|
|||
|
||||
if (desc->x44_28_x30_28_SORT)
|
||||
{
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
item.x4_viewPoint = systemCameraMatrix * ((particle.x4_pos - particle.x10_prevPos) * x60_timeDeltaScale + particle.x10_prevPos);
|
||||
}
|
||||
|
||||
std::sort(x2c_particleLists.begin(), x2c_particleLists.end(),
|
||||
std::sort(x30_particleLists.begin(), x30_particleLists.end(),
|
||||
[](const CParticleListItem& a, const CParticleListItem& b) -> bool
|
||||
{return a.x4_viewPoint[1] >= b.x4_viewPoint[1];});
|
||||
}
|
||||
|
||||
g_instIndTexData.clear();
|
||||
g_instIndTexData.reserve(x2c_particleLists.size());
|
||||
g_instIndTexData.reserve(x30_particleLists.size());
|
||||
|
||||
for (CParticleListItem& item : x2c_particleLists)
|
||||
for (CParticleListItem& item : x30_particleLists)
|
||||
{
|
||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||
g_currentParticle = &particle;
|
||||
|
@ -2066,7 +2080,7 @@ void CElementGen::SetOrientation(const zeus::CTransform& orientation)
|
|||
x178_orientation = orientation;
|
||||
x1a8_orientationInverse = x178_orientation.inverse();
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetOrientation(orientation);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2083,24 +2097,24 @@ void CElementGen::SetTranslation(const zeus::CVector3f& translation)
|
|||
{
|
||||
x7c_translation = translation;
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetTranslation(translation);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
ch->SetTranslation(translation);
|
||||
|
||||
for (const std::unique_ptr<CParticleSwoosh>& ch : x260_swhcChildren)
|
||||
ch->SetTranslation(translation + x274_SSPO);
|
||||
ch->SetTranslation(translation + x2b0_SSPO);
|
||||
|
||||
for (const std::unique_ptr<CParticleElectric>& ch : x280_elscChildren)
|
||||
ch->SetTranslation(translation + x294_SEPO);
|
||||
ch->SetTranslation(translation + x2c0_SEPO);
|
||||
}
|
||||
|
||||
void CElementGen::SetGlobalOrientation(const zeus::CTransform& rotation)
|
||||
{
|
||||
x1d8_globalOrientation.setRotation(rotation);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetGlobalOrientation(x1d8_globalOrientation);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2114,7 +2128,7 @@ void CElementGen::SetGlobalTranslation(const zeus::CVector3f& translation)
|
|||
{
|
||||
x88_globalTranslation = translation;
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetGlobalTranslation(translation);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2133,7 +2147,7 @@ void CElementGen::SetGlobalScale(const zeus::CVector3f& scale)
|
|||
xac_globalScaleTransform = zeus::CTransform::Scale(scale);
|
||||
xdc_globalScaleTransformInverse = zeus::CTransform::Scale(zeus::CVector3f::skOne / scale);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetGlobalScale(scale);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2152,7 +2166,7 @@ void CElementGen::SetLocalScale(const zeus::CVector3f& scale)
|
|||
x118_localScaleTransform = zeus::CTransform::Scale(scale);
|
||||
x148_localScaleTransformInverse = zeus::CTransform::Scale(zeus::CVector3f::skOne / scale);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetLocalScale(scale);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2163,7 +2177,7 @@ void CElementGen::SetParticleEmission(bool enabled)
|
|||
{
|
||||
x68_particleEmission = enabled;
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetParticleEmission(enabled);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2180,7 +2194,7 @@ void CElementGen::SetModulationColor(const zeus::CColor& color)
|
|||
{
|
||||
x30c_moduColor = color;
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->SetModulationColor(color);
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2225,7 +2239,7 @@ const zeus::CColor& CElementGen::GetModulationColor() const
|
|||
|
||||
bool CElementGen::IsSystemDeletable() const
|
||||
{
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
if (!ch->IsSystemDeletable())
|
||||
return false;
|
||||
|
||||
|
@ -2241,7 +2255,7 @@ bool CElementGen::IsSystemDeletable() const
|
|||
if (!ch->IsSystemDeletable())
|
||||
return false;
|
||||
|
||||
if (x214_PSLT < x50_curFrame && x208_activeParticleCount == 0)
|
||||
if (x268_PSLT < x50_curFrame && x208_activeParticleCount == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -2262,12 +2276,12 @@ u32 CElementGen::GetParticleCount() const
|
|||
|
||||
bool CElementGen::SystemHasLight() const
|
||||
{
|
||||
return x2dc_lightType != LightType::None;
|
||||
return x308_lightType != LightType::None;
|
||||
}
|
||||
|
||||
CLight CElementGen::GetLight() const
|
||||
{
|
||||
switch (x2dc_lightType)
|
||||
switch (x308_lightType)
|
||||
{
|
||||
case LightType::Directional:
|
||||
return CLight::BuildDirectional(x2f4_LDIR.normalized(), x2e0_LCLR * x2e4_LINT);
|
||||
|
@ -2275,9 +2289,9 @@ CLight CElementGen::GetLight() const
|
|||
return CLight::BuildSpot(x2e8_LOFF, x2f4_LDIR.normalized(), x2e0_LCLR * x2e4_LINT, x308_LSLA);
|
||||
default:
|
||||
{
|
||||
float quad = x300_falloffType == EFalloffType::Quadratic ? x304_LFOR : 0.f;
|
||||
float linear = x300_falloffType == EFalloffType::Linear ? x304_LFOR : 0.f;
|
||||
float constant = x300_falloffType == EFalloffType::Constant ? 1.f : 0.f;
|
||||
float quad = x32c_falloffType == EFalloffType::Quadratic ? x304_LFOR : 0.f;
|
||||
float linear = x32c_falloffType == EFalloffType::Linear ? x304_LFOR : 0.f;
|
||||
float constant = x32c_falloffType == EFalloffType::Constant ? 1.f : 0.f;
|
||||
return CLight::BuildCustom(x2e8_LOFF, {1.f, 0.f, 0.f}, x2e0_LCLR,
|
||||
constant, linear, quad, x2e4_LINT, 0.f, 0.f);
|
||||
}
|
||||
|
@ -2291,16 +2305,16 @@ bool CElementGen::GetParticleEmission() const
|
|||
|
||||
void CElementGen::DestroyParticles()
|
||||
{
|
||||
for (CParticleListItem& p : x2c_particleLists)
|
||||
for (CParticleListItem& p : x30_particleLists)
|
||||
{
|
||||
g_StaticFreeList[++g_FreeIndex] = p.x0_partIdx;
|
||||
g_StaticParticleList[p.x0_partIdx].x0_endFrame = -1;
|
||||
}
|
||||
|
||||
x2c_particleLists.clear();
|
||||
x3c_parentMatrices.clear();
|
||||
x30_particleLists.clear();
|
||||
x60_parentMatrices.clear();
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x234_activePartChildren)
|
||||
for (const std::unique_ptr<CElementGen>& ch : x290_activePartChildren)
|
||||
ch->DestroyParticles();
|
||||
|
||||
for (const std::unique_ptr<CElementGen>& ch : x248_finishPartChildren)
|
||||
|
@ -2309,9 +2323,9 @@ void CElementGen::DestroyParticles()
|
|||
|
||||
void CElementGen::Reset()
|
||||
{
|
||||
x2c_particleLists.clear();
|
||||
x3c_parentMatrices.clear();
|
||||
x234_activePartChildren.clear();;
|
||||
x30_particleLists.clear();
|
||||
x60_parentMatrices.clear();
|
||||
x290_activePartChildren.clear();
|
||||
x248_finishPartChildren.clear();
|
||||
x280_elscChildren.clear();
|
||||
x260_swhcChildren.clear();
|
||||
|
|
|
@ -78,8 +78,8 @@ private:
|
|||
friend class CElementGenShaders;
|
||||
TLockedToken<CGenDescription> x1c_genDesc;
|
||||
EModelOrientationType x28_orientType;
|
||||
std::vector<CParticleListItem> x2c_particleLists;
|
||||
std::vector<zeus::CMatrix3f> x3c_parentMatrices;
|
||||
std::vector<CParticleListItem> x30_particleLists;
|
||||
std::vector<zeus::CMatrix3f> x60_parentMatrices;
|
||||
u32 x4c_internalStartFrame = 0;
|
||||
u32 x50_curFrame = 0;
|
||||
double x58_curSeconds = 0.f;
|
||||
|
@ -87,12 +87,12 @@ private:
|
|||
u32 x64_prevFrame = -1;
|
||||
bool x68_particleEmission = true;
|
||||
float x6c_generatorRemainder = 0.f;
|
||||
int x70_MAXP = 0;
|
||||
u16 x74_randomSeed = 99;
|
||||
int x90_MAXP = 0;
|
||||
u16 x94_randomSeed = 99;
|
||||
float x78_generatorRate = 1.f;
|
||||
zeus::CVector3f x7c_translation;
|
||||
zeus::CVector3f x88_globalTranslation;
|
||||
zeus::CVector3f x94_POFS;
|
||||
zeus::CVector3f xf4_POFS;
|
||||
zeus::CVector3f xa0_globalScale = {1.f, 1.f, 1.f};
|
||||
zeus::CTransform xac_globalScaleTransform = zeus::CTransform::Identity();
|
||||
zeus::CTransform xdc_globalScaleTransformInverse = zeus::CTransform::Identity();
|
||||
|
@ -105,7 +105,7 @@ private:
|
|||
u32 x208_activeParticleCount = 0;
|
||||
u32 x20c_recursiveParticleCount = 0;
|
||||
u32 x210_curEmitterFrame = 0;
|
||||
int x214_PSLT = 90;//0x7fffff;
|
||||
int x268_PSLT = 90;//0x7fffff;
|
||||
zeus::CVector3f x218_PSIV;
|
||||
bool x224_24_translationDirty = false;
|
||||
bool x224_25_LIT_;
|
||||
|
@ -117,38 +117,48 @@ private:
|
|||
bool x224_31_VMD2;
|
||||
bool x225_24_VMD3;
|
||||
bool x225_25_VMD4;
|
||||
bool x225_26_LINE;
|
||||
bool x225_27_FXLL;
|
||||
bool x225_28_warmedUp = false;
|
||||
bool x225_29_modelsUseLights = false;
|
||||
bool x226_enableOPTS;
|
||||
int x228_MBSP = 0; int m_maxMBSP = 0;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x26c_24_ : 1;
|
||||
bool x26c_31_LINE : 1;
|
||||
bool x26d_24_FXLL : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
|
||||
ERglLightBits x22c_backupLightActive = ERglLightBits::None;
|
||||
CRandom16 x230_randState;
|
||||
std::vector<std::unique_ptr<CElementGen>> x234_activePartChildren;
|
||||
int x244_CSSD = 0;
|
||||
CRandom16 x27c_randState;
|
||||
std::vector<std::unique_ptr<CElementGen>> x290_activePartChildren;
|
||||
int x2a0_CSSD = 0;
|
||||
std::vector<std::unique_ptr<CElementGen>> x248_finishPartChildren;
|
||||
int x258_SISY = 16;
|
||||
int x25c_PISY = 16;
|
||||
int x2a4_SISY = 16;
|
||||
int x2a8_PISY = 16;
|
||||
u32 x260_cumulativeParticles = 0; /* Retail */
|
||||
std::vector<std::unique_ptr<CParticleSwoosh>> x260_swhcChildren;
|
||||
int x270_SSSD = 0;
|
||||
zeus::CVector3f x274_SSPO;
|
||||
int x2ac_SSSD = 0;
|
||||
zeus::CVector3f x2b0_SSPO;
|
||||
std::vector<std::unique_ptr<CParticleElectric>> x280_elscChildren;
|
||||
int x290_SESD = 0;
|
||||
zeus::CVector3f x294_SEPO;
|
||||
int x2bc_SESD = 0;
|
||||
zeus::CVector3f x2c0_SEPO;
|
||||
float x2a0 = 0.f;
|
||||
float x2a4 = 0.f;
|
||||
zeus::CVector3f x2a8_aabbMin;
|
||||
zeus::CVector3f x2b4_aabbMax;
|
||||
float x2c0_maxSize = 0.f;
|
||||
zeus::CAABox x2c4_systemBounds = zeus::CAABox::skInvertedBox;
|
||||
LightType x2dc_lightType;
|
||||
LightType x308_lightType;
|
||||
zeus::CColor x2e0_LCLR = zeus::CColor::skWhite;
|
||||
float x2e4_LINT = 1.f;
|
||||
zeus::CVector3f x2e8_LOFF;
|
||||
zeus::CVector3f x2f4_LDIR = {1.f, 0.f, 0.f};
|
||||
EFalloffType x300_falloffType = EFalloffType::Linear;
|
||||
EFalloffType x32c_falloffType = EFalloffType::Linear;
|
||||
float x304_LFOR = 1.f;
|
||||
float x308_LSLA = 45.f;
|
||||
zeus::CColor x30c_moduColor = {1.f, 1.f, 1.f, 1.f};
|
||||
|
@ -185,7 +195,7 @@ public:
|
|||
else
|
||||
x78_generatorRate = 0.0f;
|
||||
|
||||
for (std::unique_ptr<CElementGen>& child : x234_activePartChildren)
|
||||
for (std::unique_ptr<CElementGen>& child : x290_activePartChildren)
|
||||
child->SetGeneratorRateScalar(x78_generatorRate);
|
||||
|
||||
for (std::unique_ptr<CElementGen>& child : x248_finishPartChildren)
|
||||
|
@ -241,6 +251,8 @@ public:
|
|||
bool GetParticleEmission() const;
|
||||
void DestroyParticles();
|
||||
void Reset();
|
||||
size_t GetNumActiveChildParticles() const { return x290_activePartChildren.size(); }
|
||||
CElementGen& GetActiveChildParticle(size_t idx) const { return *x290_activePartChildren[idx]; }
|
||||
|
||||
static void SetMoveRedToAlphaBuffer(bool);
|
||||
};
|
||||
|
|
2
specter
2
specter
|
@ -1 +1 @@
|
|||
Subproject commit f5f78fdeefd8a0d1a708ca31df8dc2cb2adc8482
|
||||
Subproject commit 2faf7c87ed0548cd9152de4d1acd0791ba118308
|
Loading…
Reference in New Issue