2017-03-30 22:36:18 +00:00
|
|
|
#include "CFluidPlaneManager.hpp"
|
2018-02-01 23:19:34 +00:00
|
|
|
#include "CScriptWater.hpp"
|
|
|
|
#include "CExplosion.hpp"
|
|
|
|
#include "CStateManager.hpp"
|
2017-03-30 22:36:18 +00:00
|
|
|
|
|
|
|
namespace urde
|
|
|
|
{
|
|
|
|
|
|
|
|
CFluidPlaneManager::CFluidProfile CFluidPlaneManager::sProfile = {};
|
|
|
|
|
|
|
|
CFluidPlaneManager::CFluidPlaneManager()
|
|
|
|
: x0_rippleManager(20, 0.5f)
|
|
|
|
{
|
2017-08-08 06:03:57 +00:00
|
|
|
sProfile.Clear();
|
|
|
|
SetupRippleMap();
|
2017-03-30 22:36:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CFluidPlaneManager::CFluidProfile::Clear()
|
|
|
|
{
|
2018-02-01 23:19:34 +00:00
|
|
|
x0_ = 0.f;
|
|
|
|
x4_ = 0.f;
|
|
|
|
x8_ = 0.f;
|
|
|
|
xc_ = 0.f;
|
|
|
|
x10_ = 0.f;
|
2017-03-30 22:36:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CFluidPlaneManager::StartFrame(bool b)
|
|
|
|
{
|
|
|
|
x121_ = b;
|
|
|
|
sProfile.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CFluidPlaneManager::Update(float dt)
|
|
|
|
{
|
2018-02-01 23:19:34 +00:00
|
|
|
x11c_uvT += dt;
|
|
|
|
x0_rippleManager.Update(dt);
|
|
|
|
for (CSplashRecord& record : x18_splashes)
|
|
|
|
{
|
|
|
|
record.SetTime(record.GetTime() + dt);
|
|
|
|
if (record.GetTime() > 9999.f)
|
|
|
|
record.SetTime(9999.f);
|
|
|
|
}
|
2017-03-30 22:36:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float CFluidPlaneManager::GetLastRippleDeltaTime(TUniqueId rippler) const
|
|
|
|
{
|
|
|
|
return x0_rippleManager.GetLastRippleDeltaTime(rippler);
|
|
|
|
}
|
|
|
|
|
2017-07-05 18:34:12 +00:00
|
|
|
float CFluidPlaneManager::GetLastSplashDeltaTime(TUniqueId splasher) const
|
|
|
|
{
|
2018-02-01 23:19:34 +00:00
|
|
|
float newestTime = 9999.f;
|
|
|
|
for (const CSplashRecord& record : x18_splashes)
|
|
|
|
if (record.GetUniqueId() == splasher && newestTime > record.GetTime())
|
|
|
|
newestTime = record.GetTime();
|
|
|
|
return newestTime;
|
2017-07-05 18:34:12 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 22:36:18 +00:00
|
|
|
void CFluidPlaneManager::CreateSplash(TUniqueId splasher, CStateManager& mgr, const CScriptWater& water,
|
2018-02-01 23:19:34 +00:00
|
|
|
const zeus::CVector3f& pos, float factor, bool sfx)
|
2017-03-30 22:36:18 +00:00
|
|
|
{
|
2018-02-01 23:19:34 +00:00
|
|
|
if (water.CanRippleAtPoint(pos))
|
|
|
|
{
|
|
|
|
float oldestTime = 0.f;
|
|
|
|
CSplashRecord* oldestRecord = nullptr;
|
|
|
|
for (CSplashRecord& record : x18_splashes)
|
|
|
|
{
|
|
|
|
if (record.GetTime() > oldestTime)
|
|
|
|
{
|
|
|
|
oldestRecord = &record;
|
|
|
|
oldestTime = record.GetTime();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (oldestRecord)
|
|
|
|
*oldestRecord = CSplashRecord(0.f, splasher);
|
|
|
|
else
|
|
|
|
x18_splashes.emplace_back(0.f, splasher);
|
|
|
|
float splashScale = water.GetSplashEffectScale(factor);
|
|
|
|
if (water.GetSplashEffect(factor))
|
|
|
|
{
|
|
|
|
CExplosion* expl = new CExplosion(*water.GetSplashEffect(factor), mgr.AllocateUniqueId(), true,
|
|
|
|
CEntityInfo(water.GetAreaIdAlways(), CEntity::NullConnectionList),
|
|
|
|
"Splash", zeus::CTransform(zeus::CMatrix3f::skIdentityMatrix3f, pos),
|
|
|
|
1, zeus::CVector3f{splashScale}, water.GetSplashColor());
|
|
|
|
mgr.AddObject(expl);
|
|
|
|
}
|
|
|
|
if (sfx)
|
|
|
|
{
|
|
|
|
CSfxManager::AddEmitter(water.GetSplashSound(factor), pos, zeus::CVector3f::skUp,
|
|
|
|
true, false, 0x7f, kInvalidAreaId);
|
|
|
|
}
|
|
|
|
}
|
2017-03-30 22:36:18 +00:00
|
|
|
}
|
|
|
|
|
2018-06-07 04:43:26 +00:00
|
|
|
static bool g_RippleMapSetup = false;
|
2017-08-08 06:03:57 +00:00
|
|
|
u8 CFluidPlaneManager::RippleValues[64][64] = {};
|
|
|
|
u8 CFluidPlaneManager::RippleMins[64] = {};
|
|
|
|
u8 CFluidPlaneManager::RippleMaxs[64] = {};
|
2018-06-07 04:43:26 +00:00
|
|
|
boo::ObjToken<boo::ITextureS> CFluidPlaneManager::RippleMapTex;
|
2017-08-08 06:03:57 +00:00
|
|
|
|
|
|
|
void CFluidPlaneManager::SetupRippleMap()
|
|
|
|
{
|
2018-06-07 04:43:26 +00:00
|
|
|
if (g_RippleMapSetup)
|
|
|
|
return;
|
|
|
|
g_RippleMapSetup = true;
|
|
|
|
|
2017-08-08 06:03:57 +00:00
|
|
|
float curX = 0.f;
|
|
|
|
for (int i=0 ; i<64 ; ++i)
|
|
|
|
{
|
|
|
|
float curY = 0.f;
|
|
|
|
float minY = 1.f;
|
|
|
|
float maxY = 0.f;
|
|
|
|
for (int j=0 ; j<64 ; ++j)
|
|
|
|
{
|
|
|
|
float rVal = 1.f - curY;
|
|
|
|
float minX = curY;
|
|
|
|
float maxX = 1.25f * (0.25f * rVal + 0.1f) + curY;
|
|
|
|
if (curY < 0.f)
|
|
|
|
minX = 0.f;
|
|
|
|
else if (maxX > 1.f)
|
|
|
|
maxX = 1.f;
|
|
|
|
|
|
|
|
float val = 0.f;
|
|
|
|
if (curX >= minX && curX <= maxX)
|
|
|
|
{
|
|
|
|
float t = (curX - minX) / (maxX - minX);
|
|
|
|
if (t < 0.4f)
|
|
|
|
val = 2.5f * t;
|
|
|
|
else if (t > 0.75f)
|
|
|
|
val = 4.f * (1.f - t);
|
|
|
|
else
|
|
|
|
val = 1.f;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto valA = u8(std::max(int(255.f * val * rVal * rVal) - 1, 0));
|
|
|
|
RippleValues[i][j] = valA;
|
|
|
|
if (valA != 0 && curY < minY)
|
|
|
|
minY = curY;
|
|
|
|
if (valA != 0 && curY > maxY)
|
|
|
|
maxY = curY;
|
|
|
|
|
|
|
|
curY += (1.f / 63.f);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto valB = u8(std::max(int(255.f * minY) - 1, 0));
|
|
|
|
auto valC = u8(std::min(int(255.f * maxY) + 1, 255));
|
|
|
|
RippleMins[i] = valB;
|
|
|
|
RippleMaxs[i] = valC;
|
|
|
|
curX += (1.f / 63.f);
|
|
|
|
}
|
2018-06-07 04:43:26 +00:00
|
|
|
|
|
|
|
CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx)
|
|
|
|
{
|
|
|
|
RippleMapTex = ctx.newStaticTexture(64, 64, 1, boo::TextureFormat::I8,
|
|
|
|
boo::TextureClampMode::ClampToBlack, RippleValues, 64 * 64);
|
|
|
|
return true;
|
|
|
|
} BooTrace);
|
2017-08-08 06:03:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-30 22:36:18 +00:00
|
|
|
}
|