2018-10-07 03:42:33 +00:00
|
|
|
#pragma once
|
2016-04-20 05:44:08 +00:00
|
|
|
|
2019-09-22 21:52:05 +00:00
|
|
|
#include <algorithm>
|
2020-04-12 13:52:36 +00:00
|
|
|
#include <array>
|
2019-09-22 21:52:05 +00:00
|
|
|
#include <cmath>
|
|
|
|
#include <optional>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "Runtime/CToken.hpp"
|
|
|
|
#include "Runtime/RetroTypes.hpp"
|
|
|
|
#include "Runtime/Graphics/CTexture.hpp"
|
|
|
|
#include "Runtime/Graphics/Shaders/CFluidPlaneShader.hpp"
|
|
|
|
#include "Runtime/World/CFluidUVMotion.hpp"
|
|
|
|
|
|
|
|
#include <zeus/CAABox.hpp>
|
|
|
|
#include <zeus/CColor.hpp>
|
|
|
|
#include <zeus/CFrustum.hpp>
|
|
|
|
#include <zeus/CVector2f.hpp>
|
2017-08-06 07:15:42 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce {
|
2016-11-20 21:53:15 +00:00
|
|
|
class CFluidUVMotion;
|
2019-09-22 21:52:05 +00:00
|
|
|
class CRipple;
|
2016-11-20 21:53:15 +00:00
|
|
|
class CRippleManager;
|
2017-03-30 22:36:18 +00:00
|
|
|
class CScriptWater;
|
|
|
|
class CStateManager;
|
2018-06-07 04:43:26 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CFluidPlaneRender {
|
2016-04-20 05:44:08 +00:00
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
enum class NormalMode { None, NoNormals, Normals, NBT };
|
|
|
|
|
|
|
|
static int numTilesInHField;
|
|
|
|
static int numSubdivisionsInTile;
|
|
|
|
static int numSubdivisionsInHField;
|
|
|
|
|
|
|
|
struct SPatchInfo {
|
|
|
|
u8 x0_xSubdivs, x1_ySubdivs;
|
|
|
|
zeus::CVector2f x4_localMin, xc_globalMin;
|
|
|
|
float x14_tileSize;
|
|
|
|
float x18_rippleResolution;
|
|
|
|
float x1c_tileHypRadius;
|
|
|
|
float x20_ooTileSize;
|
|
|
|
float x24_ooRippleResolution;
|
|
|
|
u16 x28_tileX;
|
|
|
|
u16 x2a_gridDimX;
|
|
|
|
u16 x2c_gridDimY;
|
|
|
|
u16 x2e_tileY;
|
|
|
|
const bool* x30_gridFlags;
|
|
|
|
u8 x34_redShift;
|
|
|
|
u8 x35_greenShift;
|
|
|
|
u8 x36_blueShift;
|
|
|
|
NormalMode x37_normalMode;
|
|
|
|
float x38_wavecapIntensityScale;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
|
|
|
float rippleResolution, float tileSize, float wavecapIntensityScale, int numSubdivisionsInHField,
|
|
|
|
NormalMode normalMode, int redShift, int greenShift, int blueShift, u32 tileX, u32 gridDimX,
|
|
|
|
u32 gridDimY, u32 tileY, const bool* gridFlags) {
|
|
|
|
x0_xSubdivs = std::min(s16((localMax.x() - localMin.x()) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
|
|
|
numSubdivisionsInHField + 2);
|
|
|
|
x1_ySubdivs = std::min(s16((localMax.y() - localMin.y()) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
|
|
|
numSubdivisionsInHField + 2);
|
|
|
|
float tileHypRadius = tileSize * tileSize * 2 * 0.25f;
|
|
|
|
x4_localMin = localMin.toVec2f();
|
|
|
|
xc_globalMin = x4_localMin + pos.toVec2f();
|
|
|
|
x14_tileSize = tileSize;
|
|
|
|
x18_rippleResolution = rippleResolution;
|
|
|
|
if (tileHypRadius != 0.f)
|
|
|
|
tileHypRadius = std::sqrt(tileHypRadius);
|
|
|
|
x1c_tileHypRadius = tileHypRadius;
|
|
|
|
x20_ooTileSize = 1.f / x14_tileSize;
|
|
|
|
x24_ooRippleResolution = 1.f / x18_rippleResolution;
|
|
|
|
x28_tileX = u16(tileX);
|
|
|
|
x2a_gridDimX = u16(gridDimX);
|
|
|
|
x2c_gridDimY = u16(gridDimY);
|
|
|
|
x2e_tileY = u16(tileY);
|
|
|
|
x30_gridFlags = gridFlags;
|
|
|
|
x34_redShift = u8(redShift);
|
|
|
|
x35_greenShift = u8(greenShift);
|
|
|
|
x36_blueShift = u8(blueShift);
|
|
|
|
x37_normalMode = normalMode;
|
|
|
|
x38_wavecapIntensityScale = wavecapIntensityScale;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SRippleInfo {
|
|
|
|
const CRipple& x0_ripple;
|
2020-04-13 20:25:34 +00:00
|
|
|
int x4_fromX = 0;
|
|
|
|
int x8_toX = 0;
|
|
|
|
int xc_fromY = 0;
|
|
|
|
int x10_toY = 0;
|
2018-12-08 05:30:43 +00:00
|
|
|
int x14_gfromX;
|
|
|
|
int x18_gtoX;
|
|
|
|
int x1c_gfromY;
|
|
|
|
int x20_gtoY;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SRippleInfo(const CRipple& ripple, int fromX, int toX, int fromY, int toY)
|
|
|
|
: x0_ripple(ripple), x14_gfromX(fromX), x18_gtoX(toX), x1c_gfromY(fromY), x20_gtoY(toY) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SHFieldSample {
|
|
|
|
float height;
|
|
|
|
s8 nx;
|
|
|
|
s8 ny;
|
|
|
|
s8 nz;
|
|
|
|
u8 wavecapIntensity;
|
|
|
|
|
|
|
|
zeus::CVector3f MakeNormal() const { return zeus::CVector3f{nx / 63.f, ny / 63.f, nz / 63.f}.normalized(); }
|
|
|
|
zeus::CVector3f MakeBinormal() const { return zeus::CVector3f{nx / 63.f, nz / 63.f, -ny / 63.f}.normalized(); }
|
|
|
|
zeus::CVector3f MakeTangent() const { return zeus::CVector3f{nz / 63.f, ny / 63.f, -nx / 63.f}.normalized(); }
|
|
|
|
zeus::CColor MakeColor(const CFluidPlaneRender::SPatchInfo& info) const {
|
|
|
|
return {(wavecapIntensity >> info.x34_redShift) / 255.f, (wavecapIntensity >> info.x35_greenShift) / 255.f,
|
|
|
|
(wavecapIntensity >> info.x36_blueShift) / 255.f};
|
|
|
|
}
|
|
|
|
};
|
2018-06-07 04:43:26 +00:00
|
|
|
};
|
2016-11-20 21:53:15 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CFluidPlane {
|
2020-04-12 13:52:36 +00:00
|
|
|
public:
|
|
|
|
using Flags = std::array<std::array<u8, 9>, 9>;
|
|
|
|
using Heights = std::array<std::array<CFluidPlaneRender::SHFieldSample, 46>, 46>;
|
|
|
|
|
2017-08-08 06:03:57 +00:00
|
|
|
protected:
|
2018-12-08 05:30:43 +00:00
|
|
|
CAssetId x4_texPattern1Id;
|
|
|
|
CAssetId x8_texPattern2Id;
|
|
|
|
CAssetId xc_texColorId;
|
|
|
|
TLockedToken<CTexture> x10_texPattern1;
|
|
|
|
TLockedToken<CTexture> x20_texPattern2;
|
|
|
|
TLockedToken<CTexture> x30_texColor;
|
|
|
|
float x40_alpha;
|
|
|
|
EFluidType x44_fluidType;
|
|
|
|
float x48_rippleIntensity;
|
|
|
|
CFluidUVMotion x4c_uvMotion;
|
|
|
|
|
2020-04-06 06:15:37 +00:00
|
|
|
std::vector<CFluidPlaneShader::Vertex> m_verts;
|
|
|
|
std::vector<CFluidPlaneShader::PatchVertex> m_pVerts;
|
|
|
|
std::optional<CFluidPlaneShader> m_shader;
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
float ProjectRippleVelocity(float baseI, float velDot) const;
|
|
|
|
float CalculateRippleIntensity(float baseI) const;
|
|
|
|
|
2020-04-12 13:52:36 +00:00
|
|
|
virtual void RenderStripWithRipples(float curY, const Heights& heights, const Flags& flags, int startYDiv,
|
|
|
|
const CFluidPlaneRender::SPatchInfo& info,
|
2018-12-08 05:30:43 +00:00
|
|
|
std::vector<CFluidPlaneShader::Vertex>& vOut,
|
2020-04-06 09:29:05 +00:00
|
|
|
std::vector<CFluidPlaneShader::PatchVertex>& pvOut);
|
2020-04-12 13:52:36 +00:00
|
|
|
void RenderPatch(const CFluidPlaneRender::SPatchInfo& info, const Heights& heights, const Flags& flags,
|
|
|
|
bool noRipples, bool flagIs1, std::vector<CFluidPlaneShader::Vertex>& vOut,
|
2020-04-06 09:29:05 +00:00
|
|
|
std::vector<CFluidPlaneShader::PatchVertex>& pvOut);
|
2018-06-07 04:43:26 +00:00
|
|
|
|
2016-11-20 21:53:15 +00:00
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
virtual ~CFluidPlane() = default;
|
|
|
|
CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, float alpha, EFluidType fluidType,
|
|
|
|
float rippleIntensity, const CFluidUVMotion& motion);
|
|
|
|
|
|
|
|
// Called by CPlayer, CMorphBall, CWeapon, CPuddleSpore, CMagdolite
|
|
|
|
virtual void AddRipple(float mag, TUniqueId rippler, const zeus::CVector3f& center, CScriptWater& water,
|
|
|
|
CStateManager& mgr);
|
|
|
|
|
|
|
|
// Called by CAi
|
|
|
|
virtual void AddRipple(float intensity, TUniqueId rippler, const zeus::CVector3f& center,
|
|
|
|
const zeus::CVector3f& velocity, const CScriptWater& water, CStateManager& mgr,
|
|
|
|
const zeus::CVector3f& upVec);
|
|
|
|
|
|
|
|
virtual void AddRipple(const CRipple& ripple, const CScriptWater& water, CStateManager& mgr);
|
|
|
|
|
|
|
|
virtual void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
|
|
|
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
2019-06-12 02:05:17 +00:00
|
|
|
const std::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
2020-04-06 06:15:37 +00:00
|
|
|
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) {}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
float GetAlpha() const { return x40_alpha; }
|
|
|
|
EFluidType GetFluidType() const { return x44_fluidType; }
|
|
|
|
const CFluidUVMotion& GetUVMotion() const { return x4c_uvMotion; }
|
|
|
|
const CTexture& GetColorTexture() const { return *x30_texColor; }
|
2020-04-12 12:52:21 +00:00
|
|
|
bool HasColorTexture() const { return x30_texColor.HasReference(); }
|
2018-12-08 05:30:43 +00:00
|
|
|
const CTexture& GetTexturePattern1() const { return *x10_texPattern1; }
|
2020-04-12 12:52:21 +00:00
|
|
|
bool HasTexturePattern1() const { return x10_texPattern1.HasReference(); }
|
2018-12-08 05:30:43 +00:00
|
|
|
const CTexture& GetTexturePattern2() const { return *x20_texPattern2; }
|
2020-04-12 12:52:21 +00:00
|
|
|
bool HasTexturePattern2() const { return x20_texPattern2.HasReference(); }
|
2016-04-20 05:44:08 +00:00
|
|
|
};
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce
|