CScriptWater: Brace conditionals where applicable

This commit is contained in:
Lioncash 2020-05-07 11:26:09 -04:00
parent c81d6632bb
commit 717d422fc4
1 changed files with 143 additions and 98 deletions

View File

@ -64,50 +64,57 @@ CScriptWater::CScriptWater(
, x2c0_tileSize(tileSize) , x2c0_tileSize(tileSize)
, x2e8_24_b4(b4) , x2e8_24_b4(b4)
, x2e8_27_allowRender(allowRender) { , x2e8_27_allowRender(allowRender) {
zeus::CAABox triggerAABB = GetTriggerBoundsWR(); const zeus::CAABox triggerAABB = GetTriggerBoundsWR();
x2c4_gridDimX = u32((x2c0_tileSize + triggerAABB.max.x() - triggerAABB.min.x() - 0.01f) / x2c0_tileSize); x2c4_gridDimX = u32((x2c0_tileSize + triggerAABB.max.x() - triggerAABB.min.x() - 0.01f) / x2c0_tileSize);
x2c8_gridDimY = u32((x2c0_tileSize + triggerAABB.max.y() - triggerAABB.min.y() - 0.01f) / x2c0_tileSize); x2c8_gridDimY = u32((x2c0_tileSize + triggerAABB.max.y() - triggerAABB.min.y() - 0.01f) / x2c0_tileSize);
x2cc_gridCellCount = (x2c4_gridDimX + 1) * (x2c8_gridDimY + 1); x2cc_gridCellCount = (x2c4_gridDimX + 1) * (x2c8_gridDimY + 1);
uint32_t maxPatchSize; uint32_t maxPatchSize;
if (CGraphics::g_BooFactory->isTessellationSupported(maxPatchSize)) if (CGraphics::g_BooFactory->isTessellationSupported(maxPatchSize)) {
x1b4_fluidPlane = std::make_unique<CFluidPlaneGPU>( x1b4_fluidPlane = std::make_unique<CFluidPlaneGPU>(
patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap, lightmapId, unitsPerLightmapTexel, tileSize, patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap, lightmapId, unitsPerLightmapTexel, tileSize,
tileSubdivisions * 2, fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot, turbSpeed, turbDistance, tileSubdivisions * 2, fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot, turbSpeed, turbDistance,
turbFreqMax, turbFreqMin, turbPhaseMax, turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin, turbFreqMax, turbFreqMin, turbPhaseMax, turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin,
specularMax, reflectionBlend, reflectionSize, rippleIntensity, specularMax, reflectionBlend, reflectionSize, rippleIntensity,
x2cc_gridCellCount * ((std::max(u32(2), tileSubdivisions * 2) * 4 + 2) * 4)); x2cc_gridCellCount * ((std::max(u32(2), tileSubdivisions * 2) * 4 + 2) * 4));
else } else {
x1b4_fluidPlane = std::make_unique<CFluidPlaneCPU>( x1b4_fluidPlane = std::make_unique<CFluidPlaneCPU>(
patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap, lightmapId, unitsPerLightmapTexel, tileSize, patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap, lightmapId, unitsPerLightmapTexel, tileSize,
tileSubdivisions, fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot, turbSpeed, turbDistance, turbFreqMax, tileSubdivisions, fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot, turbSpeed, turbDistance, turbFreqMax,
turbFreqMin, turbPhaseMax, turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin, specularMax, turbFreqMin, turbPhaseMax, turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin, specularMax,
reflectionBlend, reflectionSize, rippleIntensity, reflectionBlend, reflectionSize, rippleIntensity,
x2cc_gridCellCount * ((std::max(u32(2), tileSubdivisions) * 4 + 2) * 4)); x2cc_gridCellCount * ((std::max(u32(2), tileSubdivisions) * 4 + 2) * 4));
}
u32Arr.reset(); u32Arr.reset();
x264_splashEffects.resize(3); x264_splashEffects.resize(3);
if (x22c_splashParticle1Id.IsValid()) if (x22c_splashParticle1Id.IsValid()) {
x264_splashEffects[0].emplace(g_SimplePool->GetObj({FOURCC('PART'), x22c_splashParticle1Id})); x264_splashEffects[0].emplace(g_SimplePool->GetObj({FOURCC('PART'), x22c_splashParticle1Id}));
if (x230_splashParticle2Id.IsValid()) }
if (x230_splashParticle2Id.IsValid()) {
x264_splashEffects[1].emplace(g_SimplePool->GetObj({FOURCC('PART'), x230_splashParticle2Id})); x264_splashEffects[1].emplace(g_SimplePool->GetObj({FOURCC('PART'), x230_splashParticle2Id}));
if (x234_splashParticle3Id.IsValid()) }
if (x234_splashParticle3Id.IsValid()) {
x264_splashEffects[2].emplace(g_SimplePool->GetObj({FOURCC('PART'), x234_splashParticle3Id})); x264_splashEffects[2].emplace(g_SimplePool->GetObj({FOURCC('PART'), x234_splashParticle3Id}));
if (x238_visorRunoffParticleId.IsValid()) }
if (x238_visorRunoffParticleId.IsValid()) {
x23c_visorRunoffEffect.emplace(g_SimplePool->GetObj({FOURCC('PART'), x238_visorRunoffParticleId})); x23c_visorRunoffEffect.emplace(g_SimplePool->GetObj({FOURCC('PART'), x238_visorRunoffParticleId}));
if (x24c_unmorphVisorRunoffParticleId.IsValid()) }
if (x24c_unmorphVisorRunoffParticleId.IsValid()) {
x250_unmorphVisorRunoffEffect.emplace(g_SimplePool->GetObj({FOURCC('PART'), x24c_unmorphVisorRunoffParticleId})); x250_unmorphVisorRunoffEffect.emplace(g_SimplePool->GetObj({FOURCC('PART'), x24c_unmorphVisorRunoffParticleId}));
}
x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx1)); x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx1));
x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx2)); x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx2));
x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx3)); x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx3));
SetCalculateLighting(true); SetCalculateLighting(true);
if (lightmapId.IsValid()) if (lightmapId.IsValid()) {
x90_actorLights->DisableAreaLights(); x90_actorLights->DisableAreaLights();
}
x90_actorLights->SetMaxDynamicLights(4); x90_actorLights->SetMaxDynamicLights(4);
x90_actorLights->SetCastShadows(false); x90_actorLights->SetCastShadows(false);
x90_actorLights->SetAmbienceGenerated(false); x90_actorLights->SetAmbienceGenerated(false);
x90_actorLights->SetFindNearestDynamicLights(true); x90_actorLights->SetFindNearestDynamicLights(true);
x148_24_detectCamera = true; x148_24_detectCamera = true;
CalculateRenderBounds(); CScriptWater::CalculateRenderBounds();
xe6_27_thermalVisorFlags = u8(thermalCold ? 2 : 1); xe6_27_thermalVisorFlags = u8(thermalCold ? 2 : 1);
if (!x30_24_active) { if (!x30_24_active) {
x2bc_alpha = 0.f; x2bc_alpha = 0.f;
@ -118,22 +125,27 @@ CScriptWater::CScriptWater(
} }
void CScriptWater::SetupGrid(bool recomputeClipping) { void CScriptWater::SetupGrid(bool recomputeClipping) {
zeus::CAABox triggerAABB = GetTriggerBoundsWR(); const zeus::CAABox triggerAABB = GetTriggerBoundsWR();
auto dimX = u32((triggerAABB.max.x() - triggerAABB.min.x() + x2c0_tileSize) / x2c0_tileSize); const 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); const auto dimY = u32((triggerAABB.max.y() - triggerAABB.min.y() + x2c0_tileSize) / x2c0_tileSize);
x2e4_computedGridCellCount = 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[x2cc_gridCellCount]); 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) {
for (int j = 0; j < x2c4_gridDimX; ++j) for (int j = 0; j < x2c4_gridDimX; ++j) {
x2d8_tileIntersects[i * x2c4_gridDimX + j] = true; x2d8_tileIntersects[i * x2c4_gridDimX + j] = true;
if (!x2e0_patchIntersects || x2d0_patchDimX != 0 || x2d4_patchDimY != 0) }
}
if (!x2e0_patchIntersects || x2d0_patchDimX != 0 || x2d4_patchDimY != 0) {
x2e0_patchIntersects.reset(new u8[32]); x2e0_patchIntersects.reset(new u8[32]);
for (int i = 0; i < 32; ++i) }
for (int i = 0; i < 32; ++i) {
x2e0_patchIntersects[i] = 1; x2e0_patchIntersects[i] = 1;
}
x2d4_patchDimY = 0; x2d4_patchDimY = 0;
x2d0_patchDimX = 0; x2d0_patchDimX = 0;
x2e8_28_recomputeClipping = recomputeClipping; x2e8_28_recomputeClipping = recomputeClipping;
@ -148,12 +160,15 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts) {
x2e8_28_recomputeClipping = false; x2e8_28_recomputeClipping = false;
} }
if (x2e4_computedGridCellCount >= x2cc_gridCellCount) if (x2e4_computedGridCellCount >= x2cc_gridCellCount) {
return; return;
}
if (!x2dc_vertIntersects) if (!x2dc_vertIntersects) {
x2dc_vertIntersects.reset(new bool[(x2c4_gridDimX + 1) * (x2c8_gridDimY + 1)]); x2dc_vertIntersects.reset(new bool[(x2c4_gridDimX + 1) * (x2c8_gridDimY + 1)]);
zeus::CAABox triggerBounds = GetTriggerBoundsWR(); }
const 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(x2e4_computedGridCellCount, x2c4_gridDimX + 1); auto gridDiv = std::div(x2e4_computedGridCellCount, x2c4_gridDimX + 1);
@ -175,15 +190,16 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts) {
} }
} }
x2e4_computedGridCellCount += computeVerts; x2e4_computedGridCellCount += computeVerts;
if (x2e4_computedGridCellCount < x2cc_gridCellCount) if (x2e4_computedGridCellCount < x2cc_gridCellCount) {
return; return;
}
x2e4_computedGridCellCount = x2cc_gridCellCount; x2e4_computedGridCellCount = x2cc_gridCellCount;
x2d8_tileIntersects.reset(new bool[x2cc_gridCellCount]); x2d8_tileIntersects.reset(new bool[x2cc_gridCellCount]);
for (int i = 0; i < x2c8_gridDimY; ++i) { for (int i = 0; i < x2c8_gridDimY; ++i) {
int rowBase = x2c4_gridDimX * i; const int rowBase = x2c4_gridDimX * i;
int nextRowBase = (x2c4_gridDimX + 1) * i; const int nextRowBase = (x2c4_gridDimX + 1) * i;
for (int j = 0; j < x2c4_gridDimX; ++j) { for (int j = 0; j < x2c4_gridDimX; ++j) {
x2d8_tileIntersects[rowBase + j] = x2dc_vertIntersects[nextRowBase + j] || x2d8_tileIntersects[rowBase + j] = x2dc_vertIntersects[nextRowBase + j] ||
x2dc_vertIntersects[nextRowBase + j + 1] || x2dc_vertIntersects[nextRowBase + j + 1] ||
@ -192,43 +208,47 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts) {
} }
} }
int tilesPerPatch = std::min(42 / x1b4_fluidPlane->GetTileSubdivisions(), 7); const int tilesPerPatch = std::min(42 / x1b4_fluidPlane->GetTileSubdivisions(), 7);
x2d0_patchDimX = (tilesPerPatch + x2c4_gridDimX - 1) / tilesPerPatch; x2d0_patchDimX = (tilesPerPatch + x2c4_gridDimX - 1) / tilesPerPatch;
x2d4_patchDimY = (tilesPerPatch + x2c8_gridDimY - 1) / tilesPerPatch; x2d4_patchDimY = (tilesPerPatch + x2c8_gridDimY - 1) / tilesPerPatch;
x2e0_patchIntersects.reset(new u8[x2d0_patchDimX * x2d4_patchDimY]); x2e0_patchIntersects.reset(new u8[x2d0_patchDimX * x2d4_patchDimY]);
int curTileY = 0; int curTileY = 0;
int nextTileY; int nextTileY;
for (int i = 0; i < x2d4_patchDimY; ++i, curTileY = nextTileY) { for (int i = 0; i < x2d4_patchDimY; ++i, curTileY = nextTileY) {
nextTileY = curTileY + tilesPerPatch; nextTileY = curTileY + tilesPerPatch;
int curTileX = 0; int curTileX = 0;
int rowBase = x2d0_patchDimX * i; const int rowBase = x2d0_patchDimX * i;
for (int j = 0; j < x2d0_patchDimX; ++j) { for (int j = 0; j < x2d0_patchDimX; ++j) {
int nextTileX = curTileX + tilesPerPatch; int nextTileX = curTileX + tilesPerPatch;
bool allClear = true; bool allClear = true;
bool allIntersections = true; bool allIntersections = true;
for (int k = curTileY; k < std::min(nextTileY, x2c8_gridDimY); ++k) { for (int k = curTileY; k < std::min(nextTileY, x2c8_gridDimY); ++k) {
if (!allClear && !allIntersections) if (!allClear && !allIntersections) {
break; break;
}
for (int l = curTileX; l < std::min(nextTileX, x2c4_gridDimX); ++l) { for (int l = curTileX; l < std::min(nextTileX, x2c4_gridDimX); ++l) {
if (x2d8_tileIntersects[k * x2c4_gridDimX + l]) { if (x2d8_tileIntersects[k * x2c4_gridDimX + l]) {
allClear = false; allClear = false;
if (!allIntersections) if (!allIntersections) {
break; break;
}
} else { } else {
allIntersections = false; allIntersections = false;
if (!allClear) if (!allClear) {
break; break;
}
} }
} }
} }
u8 flag; u8 flag = 2;
if (allIntersections) if (allIntersections) {
flag = 1; flag = 1;
else if (allClear) } else if (allClear) {
flag = 0; flag = 0;
else }
flag = 2;
x2e0_patchIntersects[rowBase + j] = flag; x2e0_patchIntersects[rowBase + j] = flag;
curTileX += tilesPerPatch; curTileX += tilesPerPatch;
} }
@ -240,26 +260,29 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts) {
void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr) { void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr) {
for (auto it = x1fc_waterInhabitants.begin(); it != x1fc_waterInhabitants.end();) { for (auto it = x1fc_waterInhabitants.begin(); it != x1fc_waterInhabitants.end();) {
auto& inhab = *it; auto& inhab = *it;
TCastToPtr<CActor> act = mgr.ObjectById(inhab.first); const TCastToPtr<CActor> act = mgr.ObjectById(inhab.first);
bool intersects = false; bool intersects = false;
if (act) { if (act) {
if (auto tb = act->GetTouchBounds()) { if (const auto tb = act->GetTouchBounds()) {
zeus::CAABox thisTb = GetTriggerBoundsWR(); const zeus::CAABox thisTb = GetTriggerBoundsWR();
if (tb->min.z() <= thisTb.max.z() && tb->max.z() >= thisTb.max.z()) if (tb->min.z() <= thisTb.max.z() && tb->max.z() >= thisTb.max.z()) {
intersects = true; intersects = true;
}
} }
} }
if (act && inhab.second) { if (act && inhab.second) {
if (intersects) if (intersects) {
act->FluidFXThink(EFluidState::InFluid, *this, mgr); act->FluidFXThink(EFluidState::InFluid, *this, mgr);
}
mgr.SendScriptMsg(act.GetPtr(), GetUniqueId(), EScriptObjectMessage::UpdateSplashInhabitant); mgr.SendScriptMsg(act.GetPtr(), GetUniqueId(), EScriptObjectMessage::UpdateSplashInhabitant);
inhab.second = false; inhab.second = false;
} else { } else {
it = x1fc_waterInhabitants.erase(it); it = x1fc_waterInhabitants.erase(it);
if (act) { if (act) {
if (intersects) if (intersects) {
act->FluidFXThink(EFluidState::LeftFluid, *this, mgr); act->FluidFXThink(EFluidState::LeftFluid, *this, mgr);
}
mgr.SendScriptMsg(act.GetPtr(), GetUniqueId(), EScriptObjectMessage::RemoveSplashInhabitant); mgr.SendScriptMsg(act.GetPtr(), GetUniqueId(), EScriptObjectMessage::RemoveSplashInhabitant);
} }
continue; continue;
@ -271,17 +294,19 @@ void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr) {
void CScriptWater::Accept(IVisitor& visitor) { visitor.Visit(this); } void CScriptWater::Accept(IVisitor& visitor) { visitor.Visit(this); }
void CScriptWater::Think(float dt, CStateManager& mgr) { void CScriptWater::Think(float dt, CStateManager& mgr) {
if (!x30_24_active) if (!x30_24_active) {
return; return;
}
bool oldCamSubmerged = x148_25_camSubmerged; const bool oldCamSubmerged = x148_25_camSubmerged;
CScriptTrigger::Think(dt, mgr); CScriptTrigger::Think(dt, mgr);
CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
if (x148_25_camSubmerged && !oldCamSubmerged) if (x148_25_camSubmerged && !oldCamSubmerged) {
mgr.SendScriptMsg(curCam, x8_uid, EScriptObjectMessage::AddSplashInhabitant); mgr.SendScriptMsg(curCam, x8_uid, EScriptObjectMessage::AddSplashInhabitant);
else if (!x148_25_camSubmerged && oldCamSubmerged) } else if (!x148_25_camSubmerged && oldCamSubmerged) {
mgr.SendScriptMsg(curCam, x8_uid, EScriptObjectMessage::RemoveSplashInhabitant); mgr.SendScriptMsg(curCam, x8_uid, EScriptObjectMessage::RemoveSplashInhabitant);
}
UpdateSplashInhabitants(mgr); UpdateSplashInhabitants(mgr);
@ -324,14 +349,15 @@ void CScriptWater::Think(float dt, CStateManager& mgr) {
} }
SetTranslation(zeus::CVector3f::lerp(x1d4_positionOrig, x1b8_positionMorphed, x1f8_morphFactor)); SetTranslation(zeus::CVector3f::lerp(x1d4_positionOrig, x1b8_positionMorphed, x1f8_morphFactor));
zeus::CVector3f lerpExtent = zeus::CVector3f::lerp(x1e0_extentOrig, x1c4_extentMorphed, x1f8_morphFactor); const zeus::CVector3f lerpExtent = zeus::CVector3f::lerp(x1e0_extentOrig, x1c4_extentMorphed, x1f8_morphFactor);
x130_bounds = zeus::CAABox(lerpExtent * -0.5f, lerpExtent * 0.5f); x130_bounds = zeus::CAABox(lerpExtent * -0.5f, lerpExtent * 0.5f);
CalculateRenderBounds(); CalculateRenderBounds();
if (!stillMorphing) if (!stillMorphing) {
SetMorphing(false); SetMorphing(false);
else } else {
SetupGrid(false); SetupGrid(false);
}
} }
SetupGridClipping(mgr, 4); SetupGridClipping(mgr, 4);
@ -340,17 +366,20 @@ void CScriptWater::Think(float dt, CStateManager& mgr) {
void CScriptWater::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CStateManager& mgr) { void CScriptWater::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CStateManager& mgr) {
switch (msg) { switch (msg) {
case EScriptObjectMessage::Next: case EScriptObjectMessage::Next:
if (!x30_24_active) if (!x30_24_active) {
break; break;
}
x2e8_25_morphIn = !x2e8_25_morphIn; x2e8_25_morphIn = !x2e8_25_morphIn;
if (x2e8_25_morphIn) { if (x2e8_25_morphIn) {
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) {
continue; continue;
auto list = mgr.GetIdListForScript(conn.x8_objId); }
if (list.first == mgr.GetIdListEnd()) const auto list = mgr.GetIdListForScript(conn.x8_objId);
if (list.first == mgr.GetIdListEnd()) {
continue; continue;
if (TCastToConstPtr<CScriptTrigger> trig = mgr.GetObjectById(list.first->second)) { }
if (const TCastToConstPtr<CScriptTrigger> trig = mgr.GetObjectById(list.first->second)) {
x1b8_positionMorphed = trig->GetTranslation(); x1b8_positionMorphed = trig->GetTranslation();
x1c4_extentMorphed = trig->GetTriggerBoundsOR().max - trig->GetTriggerBoundsOR().min; x1c4_extentMorphed = trig->GetTriggerBoundsOR().max - trig->GetTriggerBoundsOR().min;
x1f0_damageMorphed = trig->GetDamageInfo().GetDamage(); x1f0_damageMorphed = trig->GetDamageInfo().GetDamage();
@ -391,25 +420,28 @@ void CScriptWater::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CS
} }
void CScriptWater::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { void CScriptWater::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
if (x2e8_27_allowRender) { if (!x2e8_27_allowRender) {
zeus::CAABox aabb = GetSortingBounds(mgr);
xe4_30_outOfFrustum = !frustum.aabbFrustumTest(aabb);
if (!xe4_30_outOfFrustum) {
if (x4_areaId != kInvalidAreaId) {
if (x90_actorLights->GetMaxAreaLights() && (xe4_29_actorLightsDirty || x90_actorLights->GetIsDirty())) {
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
if (area->IsPostConstructed()) {
x90_actorLights->BuildAreaLightList(mgr, *area, GetTriggerBoundsWR());
xe4_29_actorLightsDirty = false;
}
}
x90_actorLights->BuildDynamicLightList(mgr, GetTriggerBoundsWR());
}
x150_frustum = frustum;
}
} else {
xe4_30_outOfFrustum = true; xe4_30_outOfFrustum = true;
return;
} }
const zeus::CAABox aabb = GetSortingBounds(mgr);
xe4_30_outOfFrustum = !frustum.aabbFrustumTest(aabb);
if (xe4_30_outOfFrustum) {
return;
}
if (x4_areaId != kInvalidAreaId) {
if (x90_actorLights->GetMaxAreaLights() && (xe4_29_actorLightsDirty || x90_actorLights->GetIsDirty())) {
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
if (area->IsPostConstructed()) {
x90_actorLights->BuildAreaLightList(mgr, *area, GetTriggerBoundsWR());
xe4_29_actorLightsDirty = false;
}
}
x90_actorLights->BuildDynamicLightList(mgr, GetTriggerBoundsWR());
}
x150_frustum = frustum;
} }
void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager& mgr) { void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager& mgr) {
@ -424,27 +456,27 @@ void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManage
void CScriptWater::Render(CStateManager& mgr) { void CScriptWater::Render(CStateManager& mgr) {
if (x30_24_active && !xe4_30_outOfFrustum) { if (x30_24_active && !xe4_30_outOfFrustum) {
float zOffset = 0.5f * (x9c_renderBounds.max.z() + x9c_renderBounds.min.z()) - x34_transform.origin.z(); const float zOffset = 0.5f * (x9c_renderBounds.max.z() + x9c_renderBounds.min.z()) - x34_transform.origin.z();
zeus::CAABox aabb = x9c_renderBounds.getTransformedAABox(zeus::CTransform::Translate( const zeus::CAABox aabb = x9c_renderBounds.getTransformedAABox(zeus::CTransform::Translate(
-x34_transform.origin.x(), -x34_transform.origin.y(), -x34_transform.origin.z() - zOffset)); -x34_transform.origin.x(), -x34_transform.origin.y(), -x34_transform.origin.z() - zOffset));
zeus::CTransform xf = x34_transform; zeus::CTransform xf = x34_transform;
xf.origin.z() += zOffset; xf.origin.z() += zOffset;
zeus::CVector3f areaCenter = mgr.GetWorld()->GetAreaAlways(mgr.GetNextAreaId())->GetAABB().center(); const zeus::CVector3f areaCenter = mgr.GetWorld()->GetAreaAlways(mgr.GetNextAreaId())->GetAABB().center();
std::optional<CRippleManager> rippleMan(mgr.GetFluidPlaneManager()->GetRippleManager()); const std::optional<CRippleManager> rippleMan(mgr.GetFluidPlaneManager()->GetRippleManager());
x1b4_fluidPlane->Render(mgr, x2bc_alpha, aabb, xf, mgr.GetWorld()->GetAreaAlways(x4_areaId)->GetTransform(), false, x1b4_fluidPlane->Render(mgr, x2bc_alpha, aabb, xf, mgr.GetWorld()->GetAreaAlways(x4_areaId)->GetTransform(), false,
x150_frustum, rippleMan, x8_uid, x2d8_tileIntersects.get(), x2c4_gridDimX, x2c8_gridDimY, x150_frustum, rippleMan, x8_uid, x2d8_tileIntersects.get(), x2c4_gridDimX, x2c8_gridDimY,
areaCenter); areaCenter);
if (x214_fogBias != 0.f) { if (x214_fogBias != 0.f) {
if (mgr.GetPlayerState()->CanVisorSeeFog(mgr)) { if (mgr.GetPlayerState()->CanVisorSeeFog(mgr)) {
float fogLevel = mgr.IntegrateVisorFog( const float fogLevel = mgr.IntegrateVisorFog(
x218_fogMagnitude * std::sin(x224_fogSpeed * CGraphics::GetSecondsMod900()) + x214_fogBias); x218_fogMagnitude * std::sin(x224_fogSpeed * CGraphics::GetSecondsMod900()) + x214_fogBias);
if (fogLevel > 0.f) { if (fogLevel > 0.f) {
zeus::CAABox fogBox = GetTriggerBoundsWR(); zeus::CAABox fogBox = GetTriggerBoundsWR();
fogBox.min.z() = float(fogBox.max.z()); fogBox.min.z() = float(fogBox.max.z());
fogBox.max.z() += fogLevel; fogBox.max.z() += fogLevel;
zeus::CTransform modelXf = const zeus::CTransform modelXf =
zeus::CTransform::Translate(fogBox.center()) * zeus::CTransform::Scale((fogBox.max - fogBox.min) * 0.5f); zeus::CTransform::Translate(fogBox.center()) * zeus::CTransform::Scale((fogBox.max - fogBox.min) * 0.5f);
zeus::CAABox renderAABB(zeus::skNegOne3f, zeus::skOne3f); const zeus::CAABox renderAABB(zeus::skNegOne3f, zeus::skOne3f);
CGraphics::SetModelMatrix(modelXf); CGraphics::SetModelMatrix(modelXf);
g_Renderer->SetAmbientColor(zeus::skWhite); g_Renderer->SetAmbientColor(zeus::skWhite);
g_Renderer->RenderFogVolume(x228_fogColor, renderAABB, nullptr, nullptr); g_Renderer->RenderFogVolume(x228_fogColor, renderAABB, nullptr, nullptr);
@ -457,12 +489,14 @@ void CScriptWater::Render(CStateManager& mgr) {
} }
void CScriptWater::Touch(CActor& otherAct, CStateManager& mgr) { void CScriptWater::Touch(CActor& otherAct, CStateManager& mgr) {
if (!x30_24_active) if (!x30_24_active) {
return; return;
}
CScriptTrigger::Touch(otherAct, mgr); CScriptTrigger::Touch(otherAct, mgr);
if (otherAct.GetMaterialList().HasMaterial(EMaterialTypes::Trigger)) if (otherAct.GetMaterialList().HasMaterial(EMaterialTypes::Trigger)) {
return; return;
}
for (auto& inhab : x1fc_waterInhabitants) for (auto& inhab : x1fc_waterInhabitants)
if (inhab.first == otherAct.GetUniqueId()) { if (inhab.first == otherAct.GetUniqueId()) {
@ -470,14 +504,16 @@ void CScriptWater::Touch(CActor& otherAct, CStateManager& mgr) {
return; return;
} }
auto touchBounds = otherAct.GetTouchBounds(); const auto touchBounds = otherAct.GetTouchBounds();
if (!touchBounds) if (!touchBounds) {
return; return;
}
x1fc_waterInhabitants.emplace_back(otherAct.GetUniqueId(), true); x1fc_waterInhabitants.emplace_back(otherAct.GetUniqueId(), true);
float triggerMaxZ = GetTriggerBoundsWR().max.z(); const float triggerMaxZ = GetTriggerBoundsWR().max.z();
if (touchBounds->min.z() <= triggerMaxZ && touchBounds->max.z() >= triggerMaxZ) if (touchBounds->min.z() <= triggerMaxZ && touchBounds->max.z() >= triggerMaxZ) {
otherAct.FluidFXThink(EFluidState::EnteredFluid, *this, mgr); otherAct.FluidFXThink(EFluidState::EnteredFluid, *this, mgr);
}
mgr.SendScriptMsg(&otherAct, x8_uid, EScriptObjectMessage::AddSplashInhabitant); mgr.SendScriptMsg(&otherAct, x8_uid, EScriptObjectMessage::AddSplashInhabitant);
} }
@ -487,8 +523,8 @@ void CScriptWater::CalculateRenderBounds() {
aabbMin.z() = x130_bounds.max.z() - 1.f; aabbMin.z() = x130_bounds.max.z() - 1.f;
zeus::CVector3f aabbMax = x130_bounds.max; zeus::CVector3f aabbMax = x130_bounds.max;
aabbMax.z() += 1.f; aabbMax.z() += 1.f;
zeus::CVector3f transAABBMin = aabbMin + GetTranslation(); const zeus::CVector3f transAABBMin = aabbMin + GetTranslation();
zeus::CVector3f transAABBMax = aabbMax + GetTranslation(); const zeus::CVector3f transAABBMax = aabbMax + GetTranslation();
x9c_renderBounds = zeus::CAABox(transAABBMin, transAABBMax); x9c_renderBounds = zeus::CAABox(transAABBMin, transAABBMax);
} }
@ -510,49 +546,58 @@ const std::optional<TLockedToken<CGenDescription>>& CScriptWater::GetSplashEffec
} }
float CScriptWater::GetSplashEffectScale(float dt) const { float CScriptWater::GetSplashEffectScale(float dt) const {
if (std::fabs(dt - 1.f) < 0.00001f) if (std::fabs(dt - 1.f) < 0.00001f) {
return kSplashScales[5]; return kSplashScales[5];
}
u32 idx = GetSplashIndex(dt); const u32 idx = GetSplashIndex(dt);
float s = dt - std::floor(dt * 3.f); const float s = dt - std::floor(dt * 3.f);
return ((1.f - s) * (s * kSplashScales[idx * 2])) + kSplashScales[idx]; return ((1.f - s) * (s * kSplashScales[idx * 2])) + kSplashScales[idx];
} }
u32 CScriptWater::GetSplashIndex(float mag) const { u32 CScriptWater::GetSplashIndex(float mag) const {
auto idx = u32(mag * 3.f); const auto idx = u32(mag * 3.f);
return (idx < 3 ? idx : idx - 1); return (idx < 3 ? idx : idx - 1);
} }
void CScriptWater::SetMorphing(bool m) { void CScriptWater::SetMorphing(bool m) {
if (m == x2e8_26_morphing) if (m == x2e8_26_morphing) {
return; return;
}
x2e8_26_morphing = m; x2e8_26_morphing = m;
SetupGrid(!m); SetupGrid(!m);
} }
const CScriptWater* CScriptWater::GetNextConnectedWater(const CStateManager& mgr) const { const CScriptWater* CScriptWater::GetNextConnectedWater(const CStateManager& mgr) const {
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) {
continue; continue;
auto its = mgr.GetIdListForScript(conn.x8_objId); }
if (its.first != mgr.GetIdListEnd()) const auto its = mgr.GetIdListForScript(conn.x8_objId);
if (TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(its.first->second)) if (its.first != mgr.GetIdListEnd()) {
if (const TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(its.first->second)) {
return water.GetPtr(); return water.GetPtr();
}
}
} }
return nullptr; return nullptr;
} }
bool CScriptWater::CanRippleAtPoint(const zeus::CVector3f& point) const { bool CScriptWater::CanRippleAtPoint(const zeus::CVector3f& point) const {
if (!x2d8_tileIntersects) if (!x2d8_tileIntersects) {
return true; return true;
}
auto xTile = int((point.x() - GetTriggerBoundsWR().min.x()) / x2c0_tileSize); const 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() - GetTriggerBoundsWR().min.y()) / x2c0_tileSize); const auto yTile = int((point.y() - GetTriggerBoundsWR().min.y()) / x2c0_tileSize);
if (yTile < 0 || yTile >= 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];
} }