Implement water rippling and fix CFluidPlane memory access errors

This commit is contained in:
Jack Andersen 2018-06-03 15:56:21 -10:00
parent 40fdfde691
commit e63102e180
12 changed files with 86 additions and 81 deletions

View File

@ -1043,8 +1043,10 @@ void CBooRenderer::AddParticleGen(const CParticleGen& gen)
void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type) void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type)
{ {
float closeDist = xb0_viewPlane.pointToPlaneDist(aabb.closestPointAlongVector(xb0_viewPlane.normal())); zeus::CVector3f closePoint = aabb.closestPointAlongVector(xb0_viewPlane.normal());
float farDist = xb0_viewPlane.pointToPlaneDist(aabb.furthestPointAlongVector(xb0_viewPlane.normal())); zeus::CVector3f farPoint = aabb.furthestPointAlongVector(xb0_viewPlane.normal());
float closeDist = xb0_viewPlane.pointToPlaneDist(closePoint);
float farDist = xb0_viewPlane.pointToPlaneDist(farPoint);
if (closeDist >= 0.f || farDist >= 0.f) if (closeDist >= 0.f || farDist >= 0.f)
{ {
bool zOnly = plane.normal().isZero(); bool zOnly = plane.normal().isZero();

View File

@ -382,9 +382,8 @@ public:
++m_added; ++m_added;
if (m_added > 3 && (m_added & 1) == 0) if (m_added > 3 && (m_added & 1) == 0)
{ {
const VTX& last = m_vec.back();
m_vec.reserve(m_vec.size() + 3); m_vec.reserve(m_vec.size() + 3);
m_vec.push_back(last); m_vec.push_back(m_vec.back());
m_vec.push_back(m_vec[m_start]); m_vec.push_back(m_vec[m_start]);
} }
m_vec.push_back(vert); m_vec.push_back(vert);
@ -396,9 +395,8 @@ public:
++m_added; ++m_added;
if (m_added > 3 && (m_added & 1) == 0) if (m_added > 3 && (m_added & 1) == 0)
{ {
const VTX& last = m_vec.back();
m_vec.reserve(m_vec.size() + 3); m_vec.reserve(m_vec.size() + 3);
m_vec.push_back(last); m_vec.push_back(m_vec.back());
m_vec.push_back(m_vec[m_start]); m_vec.push_back(m_vec[m_start]);
} }
m_vec.emplace_back(std::forward<_Args>(args)...); m_vec.emplace_back(std::forward<_Args>(args)...);

View File

@ -200,6 +200,7 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
// Load GX_TEXMTX3 with identity // Load GX_TEXMTX3 with identity
zeus::CMatrix4f& texMtx = out.texMtxs[nextTexMtx++]; zeus::CMatrix4f& texMtx = out.texMtxs[nextTexMtx++];
texMtx[0][0] = texMtx[1][1] = pttScale; texMtx[0][0] = texMtx[1][1] = pttScale;
texMtx[3][0] = texMtx[3][1] = 0.5f;
// Load GX_PTTEXMTX0 with scale of pttScale // Load GX_PTTEXMTX0 with scale of pttScale
// Next: GX_TG_MTX2x4 GX_TG_NRM, GX_TEXMTX3, true, GX_PTTEXMTX0 // Next: GX_TG_MTX2x4 GX_TG_NRM, GX_TEXMTX3, true, GX_PTTEXMTX0
@ -314,7 +315,7 @@ static bool PrepareRipple(const CRipple& ripple, const CFluidPlaneCPURender::SPa
return !(rippleOut.x14_gfromX > rippleOut.x18_gtoX || rippleOut.x1c_gfromY > rippleOut.x20_gtoY); return !(rippleOut.x14_gfromX > rippleOut.x18_gtoX || rippleOut.x1c_gfromY > rippleOut.x20_gtoY);
} }
static void ApplyTurbulence(float t, CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const u8 (&flags)[9][9], static void ApplyTurbulence(float t, CFluidPlaneCPURender::SHFieldSample (&heights)[46][46], const u8 (&flags)[9][9],
const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info, const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info,
const CFluidPlaneCPU& fluidPane, const zeus::CVector3f& areaCenter) const CFluidPlaneCPU& fluidPane, const zeus::CVector3f& areaCenter)
{ {
@ -348,7 +349,7 @@ static void ApplyTurbulence(float t, CFluidPlaneCPURender::SHFieldSample (&heigh
} }
static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo, static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], CFluidPlaneCPURender::SHFieldSample (&heights)[46][46],
u8 (&flags)[9][9], const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info) u8 (&flags)[9][9], const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info)
{ {
float lookupT = 256.f * (1.f - rippleInfo.x0_ripple.GetTime() * rippleInfo.x0_ripple.GetOOTimeFalloff() * float lookupT = 256.f * (1.f - rippleInfo.x0_ripple.GetTime() * rippleInfo.x0_ripple.GetOOTimeFalloff() *
@ -421,7 +422,7 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)]) if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)])
{ {
heights[k][l].height += val * rippleInfo.x0_ripple.GetAmplitude() * heights[k][l].height += val * rippleInfo.x0_ripple.GetAmplitude() *
sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + lookupT)]; sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + lookupT) & 0xff];
} }
else else
{ {
@ -475,7 +476,7 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
{ {
heights[k][l].height += val * rippleInfo.x0_ripple.GetAmplitude() * heights[k][l].height += val * rippleInfo.x0_ripple.GetAmplitude() *
sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() +
lookupT)]; lookupT) & 0xff];
} }
else else
{ {
@ -498,7 +499,7 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
} }
static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRippleInfo, 32>& rippleInfos, static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRippleInfo, 32>& rippleInfos,
CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], u8 (&flags)[9][9], CFluidPlaneCPURender::SHFieldSample (&heights)[46][46], u8 (&flags)[9][9],
const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info) const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info)
{ {
for (const CFluidPlaneCPURender::SRippleInfo& rippleInfo : rippleInfos) for (const CFluidPlaneCPURender::SRippleInfo& rippleInfo : rippleInfos)
@ -513,7 +514,7 @@ static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRipp
flags[CFluidPlaneCPURender::numTilesInHField+1][i+1] |= 2; flags[CFluidPlaneCPURender::numTilesInHField+1][i+1] |= 2;
} }
static void UpdatePatchNoNormals(CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const u8 (&flags)[9][9], static void UpdatePatchNoNormals(CFluidPlaneCPURender::SHFieldSample (&heights)[46][46], const u8 (&flags)[9][9],
const CFluidPlaneCPURender::SPatchInfo& info) const CFluidPlaneCPURender::SPatchInfo& info)
{ {
for (int i=1 ; i <= (info.x1_ySubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) / for (int i=1 ; i <= (info.x1_ySubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) /
@ -587,7 +588,7 @@ static void UpdatePatchNoNormals(CFluidPlaneCPURender::SHFieldSample (&heights)[
} }
} }
static void UpdatePatchWithNormals(CFluidPlaneCPURender::SHFieldSample (& heights)[45][45], const u8 (& flags)[9][9], static void UpdatePatchWithNormals(CFluidPlaneCPURender::SHFieldSample (& heights)[46][46], const u8 (& flags)[9][9],
const CFluidPlaneCPURender::SPatchInfo& info) const CFluidPlaneCPURender::SPatchInfo& info)
{ {
float normalScale = -(2.f * info.x18_rippleResolution); float normalScale = -(2.f * info.x18_rippleResolution);
@ -745,7 +746,7 @@ static void UpdatePatchWithNormals(CFluidPlaneCPURender::SHFieldSample (& height
} }
static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info, static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info,
CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], u8 (&flags)[9][9], CFluidPlaneCPURender::SHFieldSample (&heights)[46][46], u8 (&flags)[9][9],
const CFluidPlaneCPU& fluidPane, const zeus::CVector3f& areaCenter, const CFluidPlaneCPU& fluidPane, const zeus::CVector3f& areaCenter,
const std::experimental::optional<CRippleManager>& rippleManager, const std::experimental::optional<CRippleManager>& rippleManager,
int fromX, int toX, int fromY, int toY) int fromX, int toX, int fromY, int toY)
@ -776,7 +777,7 @@ static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info
return false; return false;
} }
static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFieldSample (&heights)[46][46],
const u8 (&flags)[9][9], int startYDiv, const u8 (&flags)[9][9], int startYDiv,
const CFluidPlaneCPURender::SPatchInfo& info, const CFluidPlaneCPURender::SPatchInfo& info,
std::vector<CFluidPlaneShader::Vertex>& vOut) std::vector<CFluidPlaneShader::Vertex>& vOut)
@ -790,7 +791,6 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
float tileMid = info.x18_rippleResolution * midDiv; float tileMid = info.x18_rippleResolution * midDiv;
float yMin = curY; float yMin = curY;
float yMid = curY + tileMid; float yMid = curY + tileMid;
float xMin = info.x4_localMin.x;
float curX = info.x4_localMin.x; float curX = info.x4_localMin.x;
int gridCell = info.x28_tileX + info.x2a_gridDimX * (info.x2e_tileY + yTile - 1); int gridCell = info.x28_tileX + info.x2a_gridDimX * (info.x2e_tileY + yTile - 1);
@ -853,7 +853,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
for (; remSubdivs>0 ; --remSubdivs, ++curYDiv, curTileY+=info.x18_rippleResolution) for (; remSubdivs>0 ; --remSubdivs, ++curYDiv, curTileY+=info.x18_rippleResolution)
{ {
size_t start = vOut.size(); size_t start = vOut.size();
float curTileX = xMin; float curTileX = curX;
for (int v=0 ; v<stripDivCount ; ++v) for (int v=0 ; v<stripDivCount ; ++v)
{ {
func(curTileX, curTileY, heights[curYDiv][i+v]); func(curTileX, curTileY, heights[curYDiv][i+v]);
@ -900,7 +900,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
{ {
int curYDiv0 = startYDiv; int curYDiv0 = startYDiv;
int curYDiv1 = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile; int curYDiv1 = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
float curTileX = xMin; float curTileX = curX;
for (int v=0 ; v<stripDivCount ; ++v) for (int v=0 ; v<stripDivCount ; ++v)
{ {
int curXDiv = v * CFluidPlaneCPURender::numSubdivisionsInTile + i; int curXDiv = v * CFluidPlaneCPURender::numSubdivisionsInTile + i;
@ -910,7 +910,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
samp0.MakeNormal(), samp0.MakeColor(info)); samp0.MakeNormal(), samp0.MakeColor(info));
vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height), vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height),
samp1.MakeNormal(), samp1.MakeColor(info)); samp1.MakeNormal(), samp1.MakeColor(info));
curTileX += info.x18_rippleResolution; curTileX += info.x14_tileSize;
} }
break; break;
} }
@ -918,7 +918,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
{ {
int curYDiv0 = startYDiv; int curYDiv0 = startYDiv;
int curYDiv1 = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile; int curYDiv1 = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
float curTileX = xMin; float curTileX = curX;
for (int v=0 ; v<stripDivCount ; ++v) for (int v=0 ; v<stripDivCount ; ++v)
{ {
int curXDiv = v * CFluidPlaneCPURender::numSubdivisionsInTile + i; int curXDiv = v * CFluidPlaneCPURender::numSubdivisionsInTile + i;
@ -930,7 +930,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height), vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height),
samp1.MakeNormal(), samp1.MakeBinormal(), samp1.MakeTangent(), samp1.MakeNormal(), samp1.MakeBinormal(), samp1.MakeTangent(),
samp1.MakeColor(info)); samp1.MakeColor(info));
curTileX += info.x18_rippleResolution; curTileX += info.x14_tileSize;
} }
break; break;
} }
@ -974,11 +974,11 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
break; break;
} }
func(tileMid + xMin, yMid, heights[startYDiv+midDiv][i+midDiv]); func(tileMid + curX, yMid, heights[startYDiv+midDiv][i+midDiv]);
int curXDiv = i; int curXDiv = i;
int curYDiv = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile; int curYDiv = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
float curTileX = xMin; float curTileX = curX;
float curTileY = yMin + info.x14_tileSize; float curTileY = yMin + info.x14_tileSize;
for (int v=0 ; v<(r19 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) for (int v=0 ; v<(r19 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
@ -989,7 +989,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
curXDiv = i + CFluidPlaneCPURender::numSubdivisionsInTile; curXDiv = i + CFluidPlaneCPURender::numSubdivisionsInTile;
curYDiv = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile; curYDiv = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
curTileX = xMin + info.x14_tileSize; curTileX = curX + info.x14_tileSize;
curTileY = yMin + info.x14_tileSize; curTileY = yMin + info.x14_tileSize;
for (int v=0 ; v<(r18 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) for (int v=0 ; v<(r18 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
@ -1000,7 +1000,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
curXDiv = i + CFluidPlaneCPURender::numSubdivisionsInTile; curXDiv = i + CFluidPlaneCPURender::numSubdivisionsInTile;
curYDiv = startYDiv; curYDiv = startYDiv;
curTileX = xMin + info.x14_tileSize; curTileX = curX + info.x14_tileSize;
curTileY = yMin; curTileY = yMin;
for (int v=0 ; v<(r17 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) for (int v=0 ; v<(r17 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
@ -1011,11 +1011,11 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
curXDiv = i; curXDiv = i;
curYDiv = startYDiv; curYDiv = startYDiv;
curTileX = xMin; curTileX = curX;
curTileY = yMin; curTileY = yMin;
if (r16) if (r16)
{ {
for (int v=0 ; v<CFluidPlaneCPURender::numSubdivisionsInTile ; ++v) for (int v=0 ; v<CFluidPlaneCPURender::numSubdivisionsInTile+1 ; ++v)
{ {
const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv+v][curXDiv]; const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv+v][curXDiv];
func(curTileX, curTileY, samp); func(curTileX, curTileY, samp);
@ -1043,7 +1043,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
} }
void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const CFluidPlaneCPURender::SHFieldSample (&heights)[46][46],
const u8 (&flags)[9][9], bool noRipples, bool flagIs1, const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
std::vector<CFluidPlaneShader::Vertex>& vOut) std::vector<CFluidPlaneShader::Vertex>& vOut)
{ {
@ -1153,9 +1153,10 @@ void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
size_t start = vOut.size(); size_t start = vOut.size();
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v) for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack);
vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f), vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f),
zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
xMax += info.x14_tileSize; xMax += info.x14_tileSize;
} }
CGraphics::DrawArray(start, vOut.size() - start); CGraphics::DrawArray(start, vOut.size() - start);
@ -1259,6 +1260,11 @@ void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
} }
} }
/* Used to be part of locked cache
* These are too big for stack allocation */
static CFluidPlaneCPURender::SHFieldSample lc_heights[46][46] = {};
static u8 lc_flags[9][9] = {};
void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf, void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum, const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId, const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
@ -1375,12 +1381,9 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
else else
toY = info.x1_ySubdivs; toY = info.x1_ySubdivs;
CFluidPlaneCPURender::SHFieldSample heights[45][45]; bool noRipples = UpdatePatch(mgr.GetFluidPlaneManager()->GetUVT(), info, lc_heights, lc_flags,
u8 flags[9][9] = {};
bool noRipples = UpdatePatch(mgr.GetFluidPlaneManager()->GetUVT(), info, heights, flags,
*this, areaCenter, rippleManager, fromX, toX, fromY, toY); *this, areaCenter, rippleManager, fromX, toX, fromY, toY);
RenderPatch(info, heights, flags, noRipples, renderFlags == 1, m_verts); RenderPatch(info, lc_heights, lc_flags, noRipples, renderFlags == 1, m_verts);
} }
} }
curX += ripplePitch.x; curX += ripplePitch.x;

View File

@ -207,7 +207,7 @@ public:
}; };
void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const CFluidPlaneCPURender::SHFieldSample (&heights)[46][46],
const u8 (&flags)[9][9], bool noRipples, bool flagIs1, const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
std::vector<CFluidPlaneShader::Vertex>& vOut); std::vector<CFluidPlaneShader::Vertex>& vOut);

View File

@ -50,6 +50,11 @@ CFluidPlaneDoor::RenderSetup(const CStateManager& mgr, float alpha, const zeus::
return out; return out;
} }
/* Used to be part of locked cache
* These are too big for stack allocation */
static CFluidPlaneCPURender::SHFieldSample lc_heights[46][46] = {};
static u8 lc_flags[9][9] = {};
void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf, void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum, const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId, const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
@ -86,10 +91,7 @@ void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::
CFluidPlaneCPURender::NormalMode::None, CFluidPlaneCPURender::NormalMode::None,
0, 0, 0, 0, 0, 0, 0, nullptr); 0, 0, 0, 0, 0, 0, 0, nullptr);
CFluidPlaneCPURender::SHFieldSample heights[45][45]; RenderPatch(patchInfo, lc_heights, lc_flags, true, true, m_verts);
u8 flags[9][9] = {};
RenderPatch(patchInfo, heights, flags, true, true, m_verts);
} }
} }
} }

View File

@ -15,8 +15,8 @@ CRipple::CRipple(TUniqueId id, const zeus::CVector3f& center, float intensity)
x14_timeFalloff = 0.5f * tmp + 1.5f; x14_timeFalloff = 0.5f * tmp + 1.5f;
x18_distFalloff = 4.f * tmp + 8.f; x18_distFalloff = 4.f * tmp + 8.f;
x1c_frequency = 2.f + tmp; x1c_frequency = 2.f + tmp;
x20_ = 0.15f * tmp + 0.1f; x20_preAmplitude = 0.15f * tmp + 0.1f;
x24_amplitude = x20_ / 255.f; x24_amplitude = x20_preAmplitude / 255.f;
} }
x28_ooTimeFalloff = 1.f / x14_timeFalloff; x28_ooTimeFalloff = 1.f / x14_timeFalloff;

View File

@ -15,7 +15,7 @@ private:
float x14_timeFalloff = 2.f; float x14_timeFalloff = 2.f;
float x18_distFalloff = 12.f; float x18_distFalloff = 12.f;
float x1c_frequency = 3.f; float x1c_frequency = 3.f;
float x20_ = 0.25f; float x20_preAmplitude = 0.25f;
float x24_amplitude = 0.00098039221f; float x24_amplitude = 0.00098039221f;
float x28_ooTimeFalloff = 0.f; float x28_ooTimeFalloff = 0.f;
float x2c_ooDistFalloff = 0.f; float x2c_ooDistFalloff = 0.f;

View File

@ -3,8 +3,8 @@
namespace urde namespace urde
{ {
CRippleManager::CRippleManager(int maxRipples, float f1) CRippleManager::CRippleManager(int maxRipples, float alpha)
: x14_(f1) : x14_alpha(alpha)
{ {
Init(maxRipples); Init(maxRipples);
} }
@ -16,11 +16,6 @@ void CRippleManager::Init(int maxRipples)
r.SetTime(9999.f); r.SetTime(9999.f);
} }
void CRippleManager::SetTime(float)
{
}
void CRippleManager::Update(float dt) void CRippleManager::Update(float dt)
{ {
for (CRipple& ripple : x4_ripples) for (CRipple& ripple : x4_ripples)
@ -43,17 +38,20 @@ float CRippleManager::GetLastRippleDeltaTime(TUniqueId rippler) const
void CRippleManager::AddRipple(const CRipple& ripple) void CRippleManager::AddRipple(const CRipple& ripple)
{ {
float maxTime = 0.f;
auto oldestRipple = x4_ripples.end();
for (auto it = x4_ripples.begin() ; it != x4_ripples.end() ; ++it)
if (it->GetTime() > maxTime)
{
oldestRipple = it;
maxTime = it->GetTime();
}
} if (oldestRipple != x4_ripples.end())
{
void CRippleManager::SetMaxTimeFalloff(float time) *oldestRipple = ripple;
{ x0_maxTimeFalloff = std::max(x0_maxTimeFalloff, ripple.GetTimeFalloff());
}
}
float CRippleManager::GetMaxTimeFalloff() const
{
return 0.f;
} }
} }

View File

@ -9,20 +9,21 @@ namespace urde
class CRippleManager class CRippleManager
{ {
float x0_ = 0.f; float x0_maxTimeFalloff = 0.f;
std::vector<CRipple> x4_ripples; std::vector<CRipple> x4_ripples;
float x14_; float x14_alpha;
public: public:
CRippleManager(int maxRipples, float); CRippleManager(int maxRipples, float alpha);
void Init(int maxRipples); void Init(int maxRipples);
void SetTime(float);
std::vector<CRipple>& Ripples() { return x4_ripples; } std::vector<CRipple>& Ripples() { return x4_ripples; }
const std::vector<CRipple>& GetRipples() const { return x4_ripples; } const std::vector<CRipple>& GetRipples() const { return x4_ripples; }
void Update(float dt); void Update(float dt);
float GetLastRippleDeltaTime(TUniqueId rippler) const; float GetLastRippleDeltaTime(TUniqueId rippler) const;
void AddRipple(const CRipple& ripple); void AddRipple(const CRipple& ripple);
void SetMaxTimeFalloff(float time); void SetMaxTimeFalloff(float time) { x0_maxTimeFalloff = time; }
float GetMaxTimeFalloff() const; float GetMaxTimeFalloff() const { return x0_maxTimeFalloff; }
void SetAlpha(float a) { x14_alpha = a; }
float GetAlpha() const { return x14_alpha; }
}; };
} }

View File

@ -103,10 +103,10 @@ void CScriptWater::SetupGrid(bool recomputeClipping)
zeus::CAABox triggerAABB = GetTriggerBoundsWR(); zeus::CAABox triggerAABB = GetTriggerBoundsWR();
auto dimX = u32((triggerAABB.max.x - triggerAABB.min.x + x2c0_tileSize) / x2c0_tileSize); auto dimX = u32((triggerAABB.max.x - triggerAABB.min.x + x2c0_tileSize) / x2c0_tileSize);
auto dimY = u32((triggerAABB.max.y - triggerAABB.min.y + x2c0_tileSize) / x2c0_tileSize); auto dimY = u32((triggerAABB.max.y - triggerAABB.min.y + x2c0_tileSize) / x2c0_tileSize);
x2e4_gridCellCount2 = x2cc_gridCellCount = (dimX + 1) * (dimY + 1); x2e4_computedGridCellCount = x2cc_gridCellCount = (dimX + 1) * (dimY + 1);
x2dc_vertIntersects.reset(); x2dc_vertIntersects.reset();
if (!x2d8_tileIntersects || dimX != x2c4_gridDimX || dimY != x2c8_gridDimY) if (!x2d8_tileIntersects || dimX != x2c4_gridDimX || dimY != x2c8_gridDimY)
x2d8_tileIntersects.reset(new bool[dimX * dimY]); x2d8_tileIntersects.reset(new bool[x2cc_gridCellCount]);
x2c4_gridDimX = dimX; x2c4_gridDimX = dimX;
x2c8_gridDimY = dimY; x2c8_gridDimY = dimY;
for (int i=0 ; i<x2c8_gridDimY ; ++i) for (int i=0 ; i<x2c8_gridDimY ; ++i)
@ -127,12 +127,12 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts)
{ {
if (x2e8_28_recomputeClipping) if (x2e8_28_recomputeClipping)
{ {
x2e4_gridCellCount2 = 0; x2e4_computedGridCellCount = 0;
x2dc_vertIntersects.reset(); x2dc_vertIntersects.reset();
x2e8_28_recomputeClipping = false; x2e8_28_recomputeClipping = false;
} }
if (x2e4_gridCellCount2 >= x2cc_gridCellCount) if (x2e4_computedGridCellCount >= x2cc_gridCellCount)
return; return;
if (!x2dc_vertIntersects) if (!x2dc_vertIntersects)
@ -140,11 +140,12 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts)
zeus::CAABox triggerBounds = GetTriggerBoundsWR(); zeus::CAABox triggerBounds = GetTriggerBoundsWR();
zeus::CVector3f basePos = triggerBounds.min; zeus::CVector3f basePos = triggerBounds.min;
basePos.z = triggerBounds.max.z + 0.8f; basePos.z = triggerBounds.max.z + 0.8f;
auto gridDiv = std::div(int(x2e4_gridCellCount2), int(x2c4_gridDimX + 1)); auto gridDiv = std::div(int(x2e4_computedGridCellCount), int(x2c4_gridDimX + 1));
float yOffset = x2c0_tileSize * gridDiv.quot; float yOffset = x2c0_tileSize * gridDiv.quot;
float xOffset = x2c0_tileSize * gridDiv.rem; float xOffset = x2c0_tileSize * gridDiv.rem;
float mag = std::min(120.f, 2.f * (x130_bounds.max.z - x130_bounds.min.z) + 0.8f); float mag = std::min(120.f, 2.f * (x130_bounds.max.z - x130_bounds.min.z) + 0.8f);
for (int i = x2e4_gridCellCount2; i < std::min(x2e4_gridCellCount2 + computeVerts, x2cc_gridCellCount); ++i) for (int i = x2e4_computedGridCellCount;
i < std::min(x2e4_computedGridCellCount + computeVerts, x2cc_gridCellCount); ++i)
{ {
zeus::CVector3f pos = basePos; zeus::CVector3f pos = basePos;
pos.x += xOffset; pos.x += xOffset;
@ -159,12 +160,12 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts)
gridDiv.rem = 0; gridDiv.rem = 0;
} }
} }
x2e4_gridCellCount2 += computeVerts; x2e4_computedGridCellCount += computeVerts;
if (x2e4_gridCellCount2 < x2cc_gridCellCount) if (x2e4_computedGridCellCount < x2cc_gridCellCount)
return; return;
x2e4_gridCellCount2 = x2cc_gridCellCount; x2e4_computedGridCellCount = x2cc_gridCellCount;
x2d8_tileIntersects.reset(new bool[x2c4_gridDimX * x2c8_gridDimY]); x2d8_tileIntersects.reset(new bool[x2cc_gridCellCount]);
for (int i = 0; i < x2c8_gridDimY; ++i) for (int i = 0; i < x2c8_gridDimY; ++i)
{ {
@ -608,12 +609,12 @@ bool CScriptWater::CanRippleAtPoint(const zeus::CVector3f& point) const
if (!x2d8_tileIntersects) if (!x2d8_tileIntersects)
return true; return true;
auto xTile = int((point.x - GetTriggerBoundsOR().min.x) / x2c0_tileSize); auto xTile = int((point.x - GetTriggerBoundsWR().min.x) / x2c0_tileSize);
if (xTile < 0 || xTile >= x2c4_gridDimX) if (xTile < 0 || xTile >= x2c4_gridDimX)
return false; return false;
auto yTile = int((point.y - GetTriggerBoundsOR().min.y) / x2c0_tileSize); auto yTile = int((point.y - GetTriggerBoundsWR().min.y) / x2c0_tileSize);
if (xTile < 0 || xTile >= x2c8_gridDimY) if (yTile < 0 || yTile >= x2c8_gridDimY)
return false; return false;
return x2d8_tileIntersects[yTile * x2c4_gridDimX + xTile]; return x2d8_tileIntersects[yTile * x2c4_gridDimX + xTile];

View File

@ -58,7 +58,7 @@ private:
std::unique_ptr<bool[]> x2d8_tileIntersects; std::unique_ptr<bool[]> x2d8_tileIntersects;
std::unique_ptr<bool[]> x2dc_vertIntersects; std::unique_ptr<bool[]> x2dc_vertIntersects;
std::unique_ptr<u8[]> x2e0_patchIntersects; // 0: all clear, 1: all intersect, 2: partial intersect std::unique_ptr<u8[]> x2e0_patchIntersects; // 0: all clear, 1: all intersect, 2: partial intersect
int x2e4_gridCellCount2 = 0; int x2e4_computedGridCellCount = 0;
union union
{ {
struct struct

@ -1 +1 @@
Subproject commit b2185695f53c20dac3c1353852f8a4979859c1cd Subproject commit ef3219dae294c3a83f6089a41ee4d37a491459c3