Nearly finish CScriptWater

This commit is contained in:
Jack Andersen 2017-08-12 21:56:35 -10:00
parent e0efcc0e5c
commit e25d2a423d
29 changed files with 1059 additions and 372 deletions

View File

@ -16,134 +16,151 @@ struct Water : IScriptObject
Value<atVec3f> location;
Value<atVec3f> volume;
DamageInfo damageInfo;
Value<atVec3f> unknown1;
Value<atUint32> unknown2;
Value<bool> unknown3;
Value<bool> unknown4;
UniqueID32 texture1;
UniqueID32 texture2;
UniqueID32 texture3;
UniqueID32 texture4;
UniqueID32 texture5;
UniqueID32 texture6;
Value<atVec3f> unknown5;
Value<float> unknown6;
Value<float> unknown7;
Value<float> unknown8;
Value<bool> unknown9;
Value<atUint32> unknown10;
Value<bool> unknown11;
Value<float> unknown12;
Value<atVec3f> orientedForce;
Value<atUint32> triggerFlags;
Value<bool> thermalCold;
Value<bool> displaySurface;
UniqueID32 patternMap1;
UniqueID32 patternMap2;
UniqueID32 colorMap;
UniqueID32 bumpMap;
UniqueID32 envMap;
UniqueID32 envBumpMap;
Value<atVec3f> bumpLightDir;
Value<float> bumpScale;
Value<float> morphInTime;
Value<float> morphOutTime;
Value<bool> active;
Value<atUint32> fluidType;
Value<bool> unknownBool;
Value<float> alpha;
struct FluidUVMotion : BigYAML
{
DECL_YAML
struct FluidLayerMotion : BigYAML
{
DECL_YAML
Value<atUint32> unknown1;
Value<float> unknown2;
Value<float> unknown3;
Value<float> unknown4;
Value<float> unknown5;
Value<atUint32> motionType;
Value<float> timeToWrap;
Value<float> orientation;
Value<float> magnitude;
Value<float> uvMul;
};
/* BIG FAT WARNING: Do NOT re-order these, even if they seem incorrect */
FluidLayerMotion layer2;
FluidLayerMotion layer3;
FluidLayerMotion layer1;
Value<float> unknown1;
Value<float> unknown2;
FluidLayerMotion pattern1Layer;
FluidLayerMotion pattern2Layer;
FluidLayerMotion colorLayer;
Value<float> timeToWrap;
Value<float> orientation;
} fluidUVMotion;
Value<float> unknown13;
Value<float> unknown14;
Value<float> unknown15;
Value<float> unknown16;
Value<float> unknown17;
Value<float> unknown18;
Value<float> unknown19;
Value<float> unknown20;
Value<atVec4f> unknown21;
Value<atVec4f> unknown22;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 particle3;
Value<float> turbulenceSpeed;
Value<float> turbulenceDistance;
Value<float> turbulenceFrequencyMax;
Value<float> turbulenceFrequencyMin;
Value<float> turbulencePhaseMax;
Value<float> turbulencePhaseMin;
Value<float> turbulenceAmplitudeMax;
Value<float> turbulenceAmplitudeMin;
Value<atVec4f> splashColor;
Value<atVec4f> unkColor;
UniqueID32 splashParticle1;
UniqueID32 splashParticle2;
UniqueID32 splashParticle3;
UniqueID32 particle4;
UniqueID32 particle5;
Value<atUint32> soundID1; // needs verification
Value<atUint32> soundID2; // needs verification
Value<atUint32> soundID3; // needs verification
Value<atUint32> soundID4; // needs verification
Value<atUint32> soundID5; // needs verification
Value<float> unknown23;
Value<atUint32> unknown24;
Value<float> unknown25;
Value<float> unknown26;
Value<float> unknown27;
Value<float> unknown28;
Value<float> unknown29;
Value<float> unknown30;
Value<float> unknown31;
Value<float> unknown32;
Value<atVec4f> unknown33; // CColor
UniqueID32 texture34;
Value<float> unknown35;
Value<float> unknown36;
Value<float> unknown37;
Value<atUint32> unknown38;
Value<atUint32> unknown39;
Value<bool> unknown40;
Value<atUint32> unkSfx;
Value<atUint32> visorRunoffSfx;
Value<atUint32> splashSfx1;
Value<atUint32> splashSfx2;
Value<atUint32> splashSfx3;
Value<float> tileSize;
Value<atUint32> tileSubdivisions;
Value<float> specularMin;
Value<float> specularMax;
Value<float> reflectionSize;
Value<float> rippleIntensity;
Value<float> reflectionBlend;
Value<float> fogBias;
Value<float> fogMagnitude;
Value<float> fogSpeed;
Value<atVec4f> fogColor; // CColor
UniqueID32 lightmap;
Value<float> unitsPerLightmapTexel;
Value<float> alphaInTime;
Value<float> alphaOutTime;
Value<atUint32> unusedInt1;
Value<atUint32> unusedInt2;
struct UnusedBitset : BigYAML
{
Delete _d;
void read(athena::io::IStreamReader& in)
{
if (in.readBool())
{
atUint32 bitVal0 = in.readUint16Big();
atUint32 bitVal1 = in.readUint16Big();
atUint32 len = ((bitVal0 * bitVal1) + 31) / 31;
in.seek(len * 4);
}
}
void write(athena::io::IStreamWriter& out) const { out.writeBool(false); }
void read(athena::io::YAMLDocReader& reader) {}
void write(athena::io::YAMLDocWriter& writer) const {}
size_t binarySize(size_t __isz) const { return __isz + 1; }
} unusedBitset;
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const
{
if (texture1)
if (patternMap1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap1);
ent->name = name + "_tex1";
}
if (texture2)
if (patternMap2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap2);
ent->name = name + "_tex2";
}
if (texture3)
if (colorMap)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture3);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorMap);
ent->name = name + "_tex3";
}
if (texture4)
if (bumpMap)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture4);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(bumpMap);
ent->name = name + "_tex4";
}
if (texture5)
if (envMap)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture5);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envMap);
ent->name = name + "_tex5";
}
if (texture6)
if (envBumpMap)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture6);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envBumpMap);
ent->name = name + "_tex6";
}
if (texture34)
if (lightmap)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture34);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(lightmap);
ent->name = name + "_tex34";
}
if (particle1)
if (splashParticle1)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle1);
ent->name = name + "_part1";
}
if (particle2)
if (splashParticle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle2);
ent->name = name + "_part2";
}
if (particle3)
if (splashParticle3)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3);
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle3);
ent->name = name + "_part3";
}
if (particle4)
@ -160,16 +177,16 @@ struct Water : IScriptObject
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
g_curSpec->flattenDependencies(texture1, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
g_curSpec->flattenDependencies(texture3, pathsOut);
g_curSpec->flattenDependencies(texture4, pathsOut);
g_curSpec->flattenDependencies(texture5, pathsOut);
g_curSpec->flattenDependencies(texture6, pathsOut);
g_curSpec->flattenDependencies(texture34, pathsOut);
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(particle3, pathsOut);
g_curSpec->flattenDependencies(patternMap1, pathsOut);
g_curSpec->flattenDependencies(patternMap2, pathsOut);
g_curSpec->flattenDependencies(colorMap, pathsOut);
g_curSpec->flattenDependencies(bumpMap, pathsOut);
g_curSpec->flattenDependencies(envMap, pathsOut);
g_curSpec->flattenDependencies(envBumpMap, pathsOut);
g_curSpec->flattenDependencies(lightmap, pathsOut);
g_curSpec->flattenDependencies(splashParticle1, pathsOut);
g_curSpec->flattenDependencies(splashParticle2, pathsOut);
g_curSpec->flattenDependencies(splashParticle3, pathsOut);
g_curSpec->flattenDependencies(particle4, pathsOut);
g_curSpec->flattenDependencies(particle5, pathsOut);
}

View File

@ -709,7 +709,7 @@ void CStateManager::DrawWorld() const
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
if (const CActor* ent = static_cast<const CActor*>(GetObjectById(id)))
if (!thermal || ent->xe6_27_ & 0x2)
if (!thermal || ent->xe6_27_renderVisorFlags & 0x2)
ent->Render(*this);
bool morphingPlayerVisible = false;
@ -747,9 +747,9 @@ void CStateManager::DrawWorld() const
continue;
}
}
if (!thermal || actor->xe6_27_ & 0x2)
if (!thermal || actor->xe6_27_renderVisorFlags & 0x2)
actor->AddToRenderer(frustum, *this);
if (thermal && actor->xe6_27_ & 0x4)
if (thermal && actor->xe6_27_renderVisorFlags & 0x4)
thermalActorArr[thermalActorCount++] = actor.GetPtr();
}
}
@ -785,7 +785,7 @@ void CStateManager::DrawWorld() const
CGraphics::SetDepthRange(0.015625f, 0.03125f);
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
if (actor->xe6_27_ & 0x2)
if (actor->xe6_27_renderVisorFlags & 0x2)
actor->Render(*this);
CGraphics::SetDepthRange(0.125f, 1.f);
}
@ -793,7 +793,7 @@ void CStateManager::DrawWorld() const
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
if (actor->xe6_27_ & 0x4)
if (actor->xe6_27_renderVisorFlags & 0x4)
actor->Render(*this);
for (int i=areaCount-1 ; i>=0 ; --i)
@ -856,7 +856,7 @@ void CStateManager::DrawWorld() const
CGraphics::SetDepthRange(0.015625f, 0.03125f);
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
if (actor->xe6_27_ & 0x4)
if (actor->xe6_27_renderVisorFlags & 0x4)
actor->Render(*this);
CGraphics::SetDepthRange(0.125f, 1.f);
}
@ -2560,6 +2560,13 @@ void CStateManager::SetBossParams(TUniqueId bossId, float maxEnergy, u32 stringI
xf20_bossStringIdx = stringIdx;
}
float CStateManager::IntegrateVisorFog(float f) const
{
if (x8b8_playerState->GetActiveVisor(*this) == CPlayerState::EPlayerVisor::Scan)
return (1.f - x8b8_playerState->GetVisorTransitionFactor()) * f;
return f;
}
float CStateManager::g_EscapeShakeCountdown;
bool CStateManager::g_EscapeShakeCountdownInit = false;
}

View File

@ -461,6 +461,7 @@ public:
void SetViewportScale(const zeus::CVector2f& scale) { xf2c_viewportScale = scale; }
float GetThermalColdScale2() const { return xf28_thermColdScale2; }
void SetThermalColdScale2(float s) { xf28_thermColdScale2 = s; }
float IntegrateVisorFog(float f) const;
static float g_EscapeShakeCountdown;
static bool g_EscapeShakeCountdownInit;

View File

@ -77,7 +77,7 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt)
x34_transform = zeus::CTransform::Identity();
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
return;
}
@ -262,7 +262,7 @@ void CFirstPersonCamera::UpdateTransform(CStateManager& mgr, float dt)
xe4_27_ = true;
xe4_28_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
CActor::SetTranslation(x190_gunFollowXf.origin + player->GetTransform().rotate(bobXf.origin));
x190_gunFollowXf.orthonormalize();

View File

@ -84,8 +84,10 @@ public:
const zeus::CColor& GetAmbientColor() const { return x288_ambientColor; }
const CLight& GetLight(u32 idx) const;
u32 GetActiveLightCount() const;
int GetMaxAreaLights() const { return x2b8_maxAreaLights; }
const std::vector<CLight>& GetAreaLights() const { return x0_areaLights; }
const std::vector<CLight>& GetDynamicLights() const { return x144_dynamicLights; }
bool GetIsDirty() const { return x298_24_dirty; }
};
}

View File

@ -1146,8 +1146,11 @@ void CBooRenderer::SetWorldFog(ERglFogMode mode, float startz, float endz, const
CGraphics::SetFog(mode, startz, endz, color);
}
void CBooRenderer::RenderFogVolume(const zeus::CColor&, const zeus::CAABox&, const TLockedToken<CModel>*, const CSkinnedModel*)
void CBooRenderer::RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb,
const TLockedToken<CModel>* model, const CSkinnedModel* sModel)
{
if (!x318_28_disableFog)
x2ac_fogVolumes.emplace_back(CGraphics::g_GXModelMatrix, color, aabb, model, sModel);
}
void CBooRenderer::SetThermal(bool thermal, float level, const zeus::CColor& color)

View File

@ -124,7 +124,7 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
const std::experimental::optional<TLockedToken<CTexture>>& envMap,
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
bool doubleLightmapBlend, bool additive)
bool doubleLightmapBlend, bool additive, u32 maxVertCount)
: m_patternTex1(patternTex1),
m_patternTex2(patternTex2),
m_colorTex(colorTex),
@ -147,7 +147,7 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
m_gfxTok = CGraphics::CommitResources(
[&](boo::IGraphicsDataFactory::Context& ctx)
{
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), 999); // TODO: Figure out how many
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount);
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, 1024, 1);
switch (ctx.platform())

View File

@ -114,7 +114,7 @@ public:
const std::experimental::optional<TLockedToken<CTexture>>& envMap,
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
bool doubleLightmapBlend, bool additive);
bool doubleLightmapBlend, bool additive, u32 maxVertCount);
void prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
const std::vector<CLight>& lights, const zeus::CColor* kColors);
void loadVerts(const std::vector<Vertex>& verts);

View File

@ -14,7 +14,7 @@ CEnergyProjectile::CEnergyProjectile(bool active, const TToken<CWeaponDescriptio
x2ec_dir(xf.basis[1]), x2f8_mag(x2ec_dir.magnitude()),
x2fc_camShake(CCameraShakeData::BuildProjectileCameraShake(0.5f, 0.75f))
{
xe6_27_ = 2;
xe6_27_renderVisorFlags = 2;
}
}

View File

@ -288,7 +288,7 @@ void CActor::SetRotation(const zeus::CQuaternion &q)
x34_transform = q.toTransform(x34_transform.origin);
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
}
void CActor::SetTranslation(const zeus::CVector3f& tr)
@ -296,7 +296,7 @@ void CActor::SetTranslation(const zeus::CVector3f& tr)
x34_transform.origin = tr;
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
}
void CActor::SetTransform(const zeus::CTransform& tr)
@ -304,7 +304,7 @@ void CActor::SetTransform(const zeus::CTransform& tr)
x34_transform = tr;
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
}
void CActor::SetAddedToken(u32 tok) { xcc_addedToken = tok; }

View File

@ -55,8 +55,8 @@ protected:
u8 xe4_24_nextNonLoopingSfxHandle : 3;
bool xe4_27_ : 1;
bool xe4_28_ : 1;
bool xe4_29_ : 1;
bool xe4_30_ : 1;
bool xe4_29_actorLightsDirty : 1;
bool xe4_30_outOfFrustum : 1;
bool xe4_31_lightsDirty : 1;
bool xe5_24_ : 1;
bool xe5_25_ : 1;
@ -64,7 +64,7 @@ protected:
bool xe5_27_useInSortedLists : 1;
bool xe5_28_callTouch : 1;
u8 xe6_24_fluidCounter : 3;
u8 xe6_27_ : 3;
u8 xe6_27_renderVisorFlags : 3; // 2: thermal cold, 4: thermal hot
bool xe6_30_enablePitchBend : 1;
u8 xe6_31_targetableVisorFlags : 4;
bool xe7_29_ : 1;
@ -99,7 +99,7 @@ public:
{
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
xe7_29_ = true;
CEntity::SetActive(active);
}

View File

@ -15,7 +15,7 @@ CExplosion::CExplosion(const TLockedToken<CGenDescription>& particle, TUniqueId
xf4_24_ = flags & 0x4;
xf4_25_ = true;
xf4_26_ = flags & 0x8;
xe6_27_ = flags & 0x1 ? 1 : 2;
xe6_27_renderVisorFlags = flags & 0x1 ? 1 : 2;
xe8_particleGen->SetGlobalTranslation(xf.origin);
xe8_particleGen->SetOrientation(xf.getRotation());
xe8_particleGen->SetGlobalScale(scale);

View File

@ -6,9 +6,9 @@ namespace urde
{
CFluidPlane::CFluidPlane(ResId texPattern1, ResId texPattern2, ResId texColor, float alpha, EFluidType fluidType,
float f2, const CFluidUVMotion& motion)
float rippleIntensity, const CFluidUVMotion& motion)
: x4_texPattern1Id(texPattern1), x8_texPattern2Id(texPattern2), xc_texColorId(texColor), x40_alpha(alpha),
x44_fluidType(fluidType), x48_f2(f2), x4c_uvMotion(motion)
x44_fluidType(fluidType), x48_rippleIntensity(rippleIntensity), x4c_uvMotion(motion)
{
if (g_ResFactory->GetResourceTypeById(texPattern1) == FOURCC('TXTR'))
x10_texPattern1.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texPattern1}));

View File

@ -36,11 +36,11 @@ protected:
std::experimental::optional<TLockedToken<CTexture>> x30_texColor;
float x40_alpha;
EFluidType x44_fluidType;
float x48_f2;
float x48_rippleIntensity;
CFluidUVMotion x4c_uvMotion;
public:
CFluidPlane(ResId texPattern1, ResId texPattern2, ResId texColor, float alpha, EFluidType fluidType,
float f2, const CFluidUVMotion& motion);
float rippleIntensity, const CFluidUVMotion& motion);
virtual void Ripple(float mag, TUniqueId rippler, const zeus::CVector3f& pos,
CScriptWater& water, CStateManager& mgr);

View File

@ -50,8 +50,8 @@ CFluidPlaneCPU::CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texCo
float turbSpeed, float turbDistance, float turbFreqMax, float turbFreqMin,
float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax, float turbAmplitudeMin,
float specularMin, float specularMax, float reflectionBlend, float reflectionSize,
float fluidPlaneF2)
: CFluidPlane(texPattern1, texPattern2, texColor, alpha, fluidType, fluidPlaneF2, mot),
float rippleIntensity, u32 maxVertCount)
: CFluidPlane(texPattern1, texPattern2, texColor, alpha, fluidType, rippleIntensity, mot),
xa0_texIdBumpMap(bumpMap), xa4_texIdEnvMap(envMap), xa8_texIdEnvBumpMap(envBumpMap), xac_texId4(lightMap),
xf0_bumpLightDir(bumpLightDir), xfc_bumpScale(bumpScale), x100_tileSize(tileSize),
x104_tileSubdivisions(tileSubdivisions & ~0x1),
@ -59,7 +59,8 @@ CFluidPlaneCPU::CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texCo
x10c_specularMin(specularMin), x110_specularMax(specularMax), x114_reflectionBlend(reflectionBlend),
x118_reflectionSize(reflectionSize), x11c_unitsPerLightmapTexel(unitsPerLightmapTexel),
x120_turbulence(turbSpeed, turbDistance, turbFreqMax, turbFreqMin, turbPhaseMax,
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin)
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin),
m_maxVertCount(maxVertCount)
{
if (g_ResFactory->GetResourceTypeById(xa0_texIdBumpMap) == FOURCC('TXTR'))
xb0_bumpMap.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), xa0_texIdBumpMap}));
@ -223,7 +224,7 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(mgr.GetNextAreaId());
float lightLevel = area->GetPostConstructed()->x1128_worldLightingLevel;
const CScriptWater* nextWater = water->GetNextConnectedWater(mgr);
if (std::fabs(water->GetLightmapDoubleBlendFactor()) < 0.00001f || !nextWater ||
if (std::fabs(water->GetMorphFactor()) < 0.00001f || !nextWater ||
!nextWater->GetFluidPlane().HasLightMap())
{
lightmapId = curTex;
@ -233,7 +234,7 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
}
else if (nextWater && nextWater->GetFluidPlane().HasLightMap())
{
if (std::fabs(water->GetLightmapDoubleBlendFactor() - 1.f) < 0.00001f)
if (std::fabs(water->GetMorphFactor() - 1.f) < 0.00001f)
{
lightmapId = curTex;
// Load lightmap
@ -250,9 +251,9 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
CalculateLightmapMatrix(areaXf, xf, aabb, out.texMtxs[nextTexMtx++]);
// Next: GX_TG_MTX2x4 GX_TG_POS, mtxNext, false, GX_PTIDENTITY
float lum = lightLevel * water->GetLightmapDoubleBlendFactor();
float lum = lightLevel * water->GetMorphFactor();
out.kColors[3] = zeus::CColor(lum, 1.f);
lowLightBlend = (1.f - water->GetLightmapDoubleBlendFactor()) / (1.f - lum);
lowLightBlend = (1.f - water->GetMorphFactor()) / (1.f - lum);
doubleLightmapBlend = true;
}
}
@ -269,11 +270,15 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
zeus::CColor((1.f - waterPlaneOrthoDot) * (x110_specularMax - x10c_specularMin) + x10c_specularMin, alpha);
out.kColors[1] = zeus::CColor(x114_reflectionBlend, 1.f);
// TODO: Detect parameter changes and rebuild if needed
if (!m_shader)
if (!m_shader || m_cachedDoubleLightmapBlend != doubleLightmapBlend ||
m_cachedAdditive != (mgr.GetParticleFlags() == 0))
{
m_cachedDoubleLightmapBlend = doubleLightmapBlend;
m_cachedAdditive = mgr.GetParticleFlags() == 0;
m_shader.emplace(x44_fluidType,
x10_texPattern1, x20_texPattern2, x30_texColor, xb0_bumpMap, xc0_envMap, xd0_envBumpMap,
xe0_lightmap, doubleLightmapBlend, mgr.GetParticleFlags() == 0);
xe0_lightmap, m_cachedDoubleLightmapBlend, m_cachedAdditive, m_maxVertCount);
}
return out;
}
@ -369,6 +374,16 @@ public:
s8 ny;
s8 nz;
u8 wavecapIntensity;
zeus::CVector3f MakeNormal() const { return {nx / 63.f, ny / 63.f, nz / 63.f}; }
zeus::CVector3f MakeBinormal() const { return {nx / 63.f, nz / 63.f, -ny / 63.f}; }
zeus::CVector3f MakeTangent() const { return {nz / 63.f, ny / 63.f, -nx / 63.f}; }
zeus::CColor MakeColor(const CFluidPlaneCPURender::SPatchInfo& info) const
{
return {(wavecapIntensity >> info.x34_redShift) / 255.f,
(wavecapIntensity >> info.x35_greenShift) / 255.f,
(wavecapIntensity >> info.x36_blueShift) / 255.f};
}
};
};
@ -427,7 +442,8 @@ static void ApplyTurbulence(float t, CFluidPlaneCPURender::SHFieldSample (&heigh
float distFac = curX * curX + curYSq;
if (distFac != 0.f)
distFac = std::sqrt(distFac);
heights[i][j].height = fluidPane.GetTurbulenceHeight(fluidPane.GetOOTurbulenceDistance() * distFac + scaledT);
heights[i][j].height =
fluidPane.GetTurbulenceHeight(fluidPane.GetOOTurbulenceDistance() * distFac + scaledT);
curX += info.x18_rippleResolution;
}
curY += info.x18_rippleResolution;
@ -561,7 +577,8 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)])
{
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)];
}
else
{
@ -581,7 +598,6 @@ static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
curYDiv = nextYDiv;
curGridY += info.x2a_gridDimX;
}
}
static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRippleInfo, 32>& rippleInfos,
@ -600,7 +616,7 @@ static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRipp
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)[45][45], const u8 (&flags)[9][9],
const CFluidPlaneCPURender::SPatchInfo& info)
{
for (int i=1 ; i <= (info.x1_ySubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) /
@ -868,7 +884,265 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
const CFluidPlaneCPURender::SPatchInfo& info,
std::vector<CFluidPlaneShader::Vertex>& vOut)
{
int yTile = (startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile - 1) /
CFluidPlaneCPURender::numSubdivisionsInTile;
int endXTile = (info.x0_xSubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 4) /
CFluidPlaneCPURender::numSubdivisionsInTile;
int midDiv = CFluidPlaneCPURender::numSubdivisionsInTile / 2;
float tileMid = info.x18_rippleResolution * midDiv;
float yMin = curY;
float yMid = curY + tileMid;
float xMin = info.x4_localMin.x;
float curX = info.x4_localMin.x;
int gridCell = info.x28_tileX + info.x2a_gridDimX * (info.x2e_tileY + yTile - 1);
int xTile = 1;
int tileSpan;
for (int i = 1 ; i < info.x0_xSubdivs - 2 ;
i += CFluidPlaneCPURender::numSubdivisionsInTile * tileSpan, gridCell += tileSpan,
xTile += tileSpan, curX += info.x14_tileSize * tileSpan)
{
tileSpan = 1;
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell])
continue;
if ((flags[yTile][xTile] & 0x1f) == 0x1f)
{
for (; xTile+tileSpan<=endXTile ; ++tileSpan)
{
if ((flags[yTile][xTile+tileSpan] & 0x1f) != 0x1f)
break;
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell+tileSpan])
break;
}
int stripDivCount = tileSpan * CFluidPlaneCPURender::numSubdivisionsInTile + 1;
int remSubdivs = CFluidPlaneCPURender::numSubdivisionsInTile;
std::function<void(float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)> func;
switch (info.x37_normalMode)
{
case CFluidPlaneCPURender::NormalMode::None:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
vOut.emplace_back(zeus::CVector3f(x, y, samp.height));
};
break;
case CFluidPlaneCPURender::NormalMode::NoNormals:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeColor(info));
};
break;
case CFluidPlaneCPURender::NormalMode::Normals:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
samp.MakeColor(info));
};
break;
case CFluidPlaneCPURender::NormalMode::NBT:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
vOut.emplace_back(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
samp.MakeBinormal(), samp.MakeTangent(), samp.MakeColor(info));
};
break;
}
float curTileY = yMin;
int curYDiv = startYDiv;
for (; remSubdivs>0 ; --remSubdivs, ++curYDiv, curTileY+=info.x18_rippleResolution)
{
size_t start = vOut.size();
float curTileX = xMin;
for (int v=0 ; v<stripDivCount ; ++v)
{
func(curTileX, curTileY, heights[curYDiv][i+v]);
func(curTileX, curTileY + info.x18_rippleResolution, heights[curYDiv+1][i+v]);
curTileX += info.x18_rippleResolution;
}
CGraphics::DrawArray(start, 4);
}
}
else
{
bool r19 = (flags[yTile+1][xTile] & 0x2) != 0;
bool r16 = (flags[yTile][xTile-1] & 0x8) != 0;
bool r18 = (flags[yTile][xTile+1] & 0x4) != 0;
bool r17 = (flags[yTile-1][xTile] & 0x1) != 0;
int r6 = (r19 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) + 2;
r6 += r18 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1;
r6 += r17 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1;
r6 += r16 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1;
if (r6 == 6 && (info.x37_normalMode == CFluidPlaneCPURender::NormalMode::Normals ||
info.x37_normalMode == CFluidPlaneCPURender::NormalMode::NBT))
{
for (; xTile+tileSpan<=endXTile ; ++tileSpan)
{
if ((flags[yTile][xTile+tileSpan] & 0x1f) == 0x1f)
break;
if (info.x30_gridFlags && !info.x30_gridFlags[gridCell+tileSpan])
break;
if ((flags[yTile+1][xTile+tileSpan] & 0x2) != 0x0)
break;
if ((flags[yTile][xTile+tileSpan+1] & 0x4) != 0x0)
break;
if ((flags[yTile-1][xTile+tileSpan] & 0x1) != 0x0)
break;
}
int stripDivCount = tileSpan + 1;
size_t start = vOut.size();
switch (info.x37_normalMode)
{
case CFluidPlaneCPURender::NormalMode::Normals:
{
int curYDiv0 = startYDiv;
int curYDiv1 = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
float curTileX = xMin;
for (int v=0 ; v<stripDivCount ; ++v)
{
int curXDiv = v * CFluidPlaneCPURender::numSubdivisionsInTile + i;
const CFluidPlaneCPURender::SHFieldSample& samp0 = heights[curYDiv0][curXDiv];
const CFluidPlaneCPURender::SHFieldSample& samp1 = heights[curYDiv1][curXDiv];
vOut.emplace_back(zeus::CVector3f(curTileX, yMin, samp0.height),
samp0.MakeNormal(), samp0.MakeColor(info));
vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height),
samp1.MakeNormal(), samp1.MakeColor(info));
curTileX += info.x18_rippleResolution;
}
break;
}
case CFluidPlaneCPURender::NormalMode::NBT:
{
int curYDiv0 = startYDiv;
int curYDiv1 = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
float curTileX = xMin;
for (int v=0 ; v<stripDivCount ; ++v)
{
int curXDiv = v * CFluidPlaneCPURender::numSubdivisionsInTile + i;
const CFluidPlaneCPURender::SHFieldSample& samp0 = heights[curYDiv0][curXDiv];
const CFluidPlaneCPURender::SHFieldSample& samp1 = heights[curYDiv1][curXDiv];
vOut.emplace_back(zeus::CVector3f(curTileX, yMin, samp0.height),
samp0.MakeNormal(), samp0.MakeBinormal(), samp0.MakeTangent(),
samp0.MakeColor(info));
vOut.emplace_back(zeus::CVector3f(curTileX, yMin + info.x14_tileSize, samp1.height),
samp1.MakeNormal(), samp1.MakeBinormal(), samp1.MakeTangent(),
samp1.MakeColor(info));
curTileX += info.x18_rippleResolution;
}
break;
}
default:
break;
}
CGraphics::DrawArray(start, 4);
}
else
{
TriFanToStrip<CFluidPlaneShader::Vertex> toStrip(vOut);
std::function<void(float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)> func;
switch (info.x37_normalMode)
{
case CFluidPlaneCPURender::NormalMode::None:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height));
};
break;
case CFluidPlaneCPURender::NormalMode::NoNormals:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeColor(info));
};
break;
case CFluidPlaneCPURender::NormalMode::Normals:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
samp.MakeColor(info));
};
break;
case CFluidPlaneCPURender::NormalMode::NBT:
func = [&](float x, float y, const CFluidPlaneCPURender::SHFieldSample& samp)
{
toStrip.EmplaceVert(zeus::CVector3f(x, y, samp.height), samp.MakeNormal(),
samp.MakeBinormal(), samp.MakeTangent(), samp.MakeColor(info));
};
break;
}
func(tileMid + xMin, yMid, heights[startYDiv+midDiv][i+midDiv]);
int curXDiv = i;
int curYDiv = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
float curTileX = xMin;
float curTileY = yMin + info.x14_tileSize;
for (int v=0 ; v<(r19 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{
const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv][curXDiv+v];
func(curTileX, curTileY, samp);
curTileX += info.x18_rippleResolution;
}
curXDiv = i + CFluidPlaneCPURender::numSubdivisionsInTile;
curYDiv = startYDiv + CFluidPlaneCPURender::numSubdivisionsInTile;
curTileX = xMin + info.x14_tileSize;
curTileY = yMin + info.x14_tileSize;
for (int v=0 ; v<(r18 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{
const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv-v][curXDiv];
func(curTileX, curTileY, samp);
curTileY -= info.x18_rippleResolution;
}
curXDiv = i + CFluidPlaneCPURender::numSubdivisionsInTile;
curYDiv = startYDiv;
curTileX = xMin + info.x14_tileSize;
curTileY = yMin;
for (int v=0 ; v<(r17 ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{
const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv][curXDiv-v];
func(curTileX, curTileY, samp);
curTileX -= info.x18_rippleResolution;
}
curXDiv = i;
curYDiv = startYDiv;
curTileX = xMin;
curTileY = yMin;
if (r16)
{
for (int v=0 ; v<CFluidPlaneCPURender::numSubdivisionsInTile ; ++v)
{
const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv+v][curXDiv];
func(curTileX, curTileY, samp);
curTileY += info.x18_rippleResolution;
}
}
else
{
{
const CFluidPlaneCPURender::SHFieldSample& samp = heights[curYDiv][curXDiv];
func(curTileX, curTileY, samp);
}
curTileY += info.x14_tileSize;
{
const CFluidPlaneCPURender::SHFieldSample& samp =
heights[curYDiv+CFluidPlaneCPURender::numSubdivisionsInTile][curXDiv];
func(curTileX, curTileY, samp);
}
}
toStrip.Draw();
}
}
}
}
static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,

View File

@ -46,7 +46,7 @@ class CFluidPlaneCPU : public CFluidPlane
zeus::CVector3f xf0_bumpLightDir;
float xfc_bumpScale;
float x100_tileSize;
u32 x104_tileSubdivisions;
int x104_tileSubdivisions;
float x108_rippleResolution;
float x10c_specularMin;
float x110_specularMax;
@ -55,8 +55,12 @@ class CFluidPlaneCPU : public CFluidPlane
float x11c_unitsPerLightmapTexel;
CTurbulence x120_turbulence;
u32 m_maxVertCount;
mutable std::vector<CFluidPlaneShader::Vertex> m_verts;
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
mutable bool m_cachedDoubleLightmapBlend;
mutable bool m_cachedAdditive;
struct RenderSetupInfo
{
@ -73,7 +77,7 @@ public:
const CFluidUVMotion& mot, float turbSpeed, float turbDistance, float turbFreqMax,
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
float turbAmplitudeMin, float specularMin, float specularMax, float reflectionBlend,
float reflectionSize, float fluidPlaneF2);
float reflectionSize, float rippleIntensity, u32 maxVertCount);
void CreateRipple(const CRipple& ripple, CStateManager& mgr);
void CalculateLightmapMatrix(const zeus::CTransform& areaXf, const zeus::CTransform& xf,
const zeus::CAABox& aabb, zeus::CMatrix4f& mtxOut) const;
@ -100,7 +104,7 @@ public:
const CTexture& GetLightMap() const { return **xe0_lightmap; }
const zeus::CVector3f& GetBumpLightDir() const { return xf0_bumpLightDir; }
float GetTileSize() const { return x100_tileSize; }
u32 GetTileSubdivisions() const { return x104_tileSubdivisions; }
int GetTileSubdivisions() const { return x104_tileSubdivisions; }
float GetRippleResolution() const { return x108_rippleResolution; }
float GetTurbulenceHeight(float sel) const { return x120_turbulence.GetHeight(sel); }
float GetOOTurbulenceDistance() const { return x120_turbulence.GetOODistance(); }

View File

@ -48,6 +48,7 @@ public:
void CreateSplash(TUniqueId splasher, CStateManager& mgr, const CScriptWater& water,
const zeus::CVector3f& pos, float factor, bool);
rstl::reserved_vector<CSplashRecord, 32>& SplashRecords() { return x18_splashes; }
const CRippleManager& GetRippleManager() const { return x0_rippleManager; }
};
}

View File

@ -4,58 +4,69 @@
namespace urde
{
CFluidUVMotion::CFluidUVMotion(float a, float b, const CFluidUVMotion::SFluidLayerMotion& c,
const CFluidUVMotion::SFluidLayerMotion& d, const CFluidUVMotion::SFluidLayerMotion& e)
: x4c_(1.f/a)
, x50_(b)
CFluidUVMotion::CFluidUVMotion(float timeToWrap, float orientation,
const CFluidUVMotion::SFluidLayerMotion& colorLayer,
const CFluidUVMotion::SFluidLayerMotion& pattern1Layer,
const CFluidUVMotion::SFluidLayerMotion& pattern2Layer)
: x4c_ooTimeToWrap(1.f / timeToWrap)
, x50_orientation(orientation)
{
x0_fluidLayers.resize(3);
x0_fluidLayers[0] = c;
x0_fluidLayers[1] = d;
x0_fluidLayers[2] = e;
x0_fluidLayers[0] = colorLayer;
x0_fluidLayers[1] = pattern1Layer;
x0_fluidLayers[2] = pattern2Layer;
}
CFluidUVMotion::CFluidUVMotion(float, float)
{}
void CFluidUVMotion::CalculateFluidTextureOffset(float f31, float offsets[3][2]) const
CFluidUVMotion::CFluidUVMotion(float timeToWrap, float orientation)
: x4c_ooTimeToWrap(1.f / timeToWrap), x50_orientation(orientation)
{
float f28 = (f31 * x4c_) * zeus::fastCosF(x50_);
float f29 = (f31 * x4c_) / zeus::fastSinF(x50_);
x0_fluidLayers.resize(3);
x0_fluidLayers[0].x4_ooTimeToWrap = 0.001f;
x0_fluidLayers[1].x4_ooTimeToWrap = 0.33333334f;
x0_fluidLayers[2].x4_ooTimeToWrap = 0.2f;
x0_fluidLayers[2].x8_orientation = 0.78539819f;
}
void CFluidUVMotion::CalculateFluidTextureOffset(float t, float offsets[3][2]) const
{
float totalYOffset = (t * x4c_ooTimeToWrap) * zeus::fastCosF(x50_orientation);
float totalXOffset = (t * x4c_ooTimeToWrap) * zeus::fastSinF(x50_orientation);
for (u32 i = 0 ; i<x0_fluidLayers.size() ; ++i)
{
const SFluidLayerMotion& layer = x0_fluidLayers[i];
float f30 = f31 * layer.x4_a;
float f1 = f30 - std::floor(f30);
float f27;
float f26;
float speedT = t * layer.x4_ooTimeToWrap;
float cycleT = speedT - std::floor(speedT);
float localY;
float localX;
switch(layer.x0_motion)
{
case EFluidUVMotion::One:
{
f30 = (M_PIF * 2) * f1;
f27 = layer.xc_c * zeus::fastSinF(f30);
f26 = layer.xc_c * zeus::fastCosF(f30);
float angle = (M_PIF * 2) * cycleT;
localY = layer.xc_magnitude * zeus::fastSinF(angle);
localX = layer.xc_magnitude * zeus::fastCosF(angle);
}
break;
case EFluidUVMotion::Two:
{
f27 = 0.f;
f26 = layer.xc_c * zeus::fastCosF((M_PIF * 2) * f1);
localY = 0.f;
localX = layer.xc_magnitude * zeus::fastCosF((M_PIF * 2) * cycleT);
}
break;
default:
f27 = f26 = 0.f;
localY = localX = 0.f;
break;
}
float x = f26 * zeus::fastSinF(layer.x8_b) + (f27 * zeus::fastCosF(layer.x8_b) + f29);
float y = f27 * zeus::fastSinF(layer.x8_b) + (f26 * zeus::fastCosF(layer.x8_b) + f28);
float x = localX * zeus::fastSinF(layer.x8_orientation) +
localY * zeus::fastCosF(layer.x8_orientation) + totalXOffset;
float y = localY * zeus::fastSinF(layer.x8_orientation) +
localX * zeus::fastCosF(layer.x8_orientation) + totalYOffset;
offsets[i][0] = float(x - floor(x));
offsets[i][1] = float(y - floor(y));
offsets[i][0] = x - std::floor(x);
offsets[i][1] = y - std::floor(y);
}
}
}

View File

@ -19,15 +19,16 @@ public:
struct SFluidLayerMotion
{
EFluidUVMotion x0_motion = EFluidUVMotion::Zero;
float x4_a = 0.16666667f;
float x8_b = 0.f;
float xc_c = 1.f;
float x4_ooTimeToWrap = 0.16666667f;
float x8_orientation = 0.f;
float xc_magnitude = 1.f;
float x10_uvMul = 5.f;
float x14_uvScale = 0.2f;
SFluidLayerMotion() = default;
SFluidLayerMotion(EFluidUVMotion motion, float a, float b, float c, float uvMul)
: x0_motion(motion), x4_a(1.f / a), x8_b(b), xc_c(c), x10_uvMul(uvMul), x14_uvScale(1.f / uvMul)
SFluidLayerMotion(EFluidUVMotion motion, float timeToWrap, float orientation, float magnitude, float uvMul)
: x0_motion(motion), x4_ooTimeToWrap(1.f / timeToWrap), x8_orientation(orientation),
xc_magnitude(magnitude), x10_uvMul(uvMul), x14_uvScale(1.f / uvMul)
{
}
@ -36,15 +37,16 @@ public:
private:
rstl::reserved_vector<SFluidLayerMotion, 3> x0_fluidLayers;
float x4c_;
float x50_;
float x4c_ooTimeToWrap;
float x50_orientation;
public:
CFluidUVMotion(float a, float b, const SFluidLayerMotion& c, const SFluidLayerMotion& d, const SFluidLayerMotion& e);
CFluidUVMotion(float, float);
CFluidUVMotion(float timeToWrap, float orientation, const SFluidLayerMotion& colorLayer,
const SFluidLayerMotion& pattern1Layer, const SFluidLayerMotion& pattern2Layer);
CFluidUVMotion(float timeToWrap, float orientation);
const rstl::reserved_vector<SFluidLayerMotion, 3>& GetFluidLayers() const { return x0_fluidLayers; }
void GetOrientation() const;
void GetOOTimeToWrapTexPage() const;
float GetOrientation() const { return x50_orientation; }
float GetOOTimeToWrapTexPage() const { return x4c_ooTimeToWrap; }
void CalculateFluidTextureOffset(float, float[3][2]) const;
};
}

View File

@ -103,7 +103,7 @@ void CPhysicsActor::AddMotionState(const CMotionState& mst)
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
SetTranslation(x34_transform.origin + mst.x0_translation);
@ -123,7 +123,7 @@ void CPhysicsActor::SetMotionState(const CMotionState& mst)
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
SetTranslation(mst.x0_translation);
xfc_constantForce = mst.x1c_velocity;
@ -268,7 +268,7 @@ void CPhysicsActor::SetPhysicsState(const CPhysicsState& state)
x34_transform = zeus::CTransform(state.GetOrientation(), x34_transform.origin);
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
xfc_constantForce = state.GetConstantForceWR();
x108_angularMomentum = state.GetAngularMomentumWR();

View File

@ -2554,7 +2554,7 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f
zeus::CTransform(x3c0_grappleSwingAxis, swingForward, zeus::CVector3f::skUp, GetTranslation());
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
SetVelocityWR(pullVec);
if (!ValidateFPPosition(GetTranslation(), mgr))
@ -2563,7 +2563,7 @@ void CPlayer::ApplyGrappleForces(const CFinalInput& input, CStateManager& mgr, f
x34_transform = backupXf;
xe4_27_ = true;
xe4_28_ = true;
xe4_29_ = true;
xe4_29_actorLightsDirty = true;
SetVelocityWR(backupVel);
}
}

View File

@ -127,10 +127,10 @@ void CScriptActor::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
{
CActor::PreRender(mgr, frustum);
if (xe4_30_ && TCastToPtr<CCinematicCamera>(mgr.GetCameraManager()->GetCurrentCamera(mgr)))
xe4_30_ = false;
if (xe4_30_outOfFrustum && TCastToPtr<CCinematicCamera>(mgr.GetCameraManager()->GetCurrentCamera(mgr)))
xe4_30_outOfFrustum = false;
if (xe4_30_ && !x2e2_29_ && !x2e2_27_)
if (xe4_30_outOfFrustum && !x2e2_29_ && !x2e2_27_)
{
zeus::CColor col(1.f, 1.f, x2dc_xrayAlpha);
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)
@ -154,7 +154,7 @@ void CScriptActor::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
}
}
if (!x2e2_24_ && xe6_27_ == 2 &&
if (!x2e2_24_ && xe6_27_renderVisorFlags == 2 &&
mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)
{
xb4_drawFlags.x2_flags &= ~3;

View File

@ -79,7 +79,7 @@ void CScriptDoor::Think(float dt, CStateManager& mgr)
void CScriptDoor::AddToRenderer(const zeus::CFrustum& /*frustum*/, CStateManager &mgr)
{
if (!xe4_30_)
if (!xe4_30_outOfFrustum)
CPhysicsActor::Render(mgr);
}

View File

@ -44,7 +44,7 @@ void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS
if (msg == EScriptObjectMessage::Deactivate)
{
xe8_inhabitants.clear();
x148_25_ = false;
x148_25_camSubmerged = false;
}
if (x148_28_)

View File

@ -58,7 +58,7 @@ protected:
struct
{
bool x148_24_playerInside : 1;
bool x148_25_ : 1;
bool x148_25_camSubmerged : 1;
bool x148_26_deactivateOnEntered : 1;
bool x148_27_deactivateOnExited : 1;
bool x148_28_ : 1;
@ -84,6 +84,7 @@ public:
std::list<CObjectTracker>& GetInhabitants();
rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor &, CStateManager &);
const zeus::CAABox& GetTriggerBoundsOR() const { return x130_bounds; }
zeus::CAABox GetTriggerBoundsWR() const;
const CDamageInfo& GetDamageInfo() const { return x100_damageInfo; }
ETriggerFlags GetTriggerFlags() const { return x12c_flags; }

View File

@ -16,7 +16,7 @@ CScriptVisorFlare::CScriptVisorFlare(TUniqueId uid, const std::string& name, con
CMaterialList(EMaterialTypes::Unknown), CActorParameters::None(), kInvalidUniqueId),
xe8_flare(blendMode, b1, f1, f2, f3, w1, w2, flares)
{
xe6_27_ = 2;
xe6_27_renderVisorFlags = 2;
}
void CScriptVisorFlare::Accept(IVisitor& visitor)

View File

@ -3,6 +3,9 @@
#include "TCastTo.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "World/CWorld.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "Camera/CGameCamera.hpp"
namespace urde
{
@ -15,42 +18,49 @@ const float CScriptWater::kSplashScales[6] =
CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CVector3f& pos, const zeus::CAABox& box, const urde::CDamageInfo& dInfo,
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool b1, bool b2,
ResId patternMap1, ResId patternMap2, ResId colorMap, ResId bumpMap, ResId envMap,
ResId envBumpMap, ResId unusedMap, const zeus::CVector3f& bumpLightDir, float bumpScale,
float f2, float f3, bool active, CFluidPlane::EFluidType fluidType, bool b4, float alpha,
const CFluidUVMotion& uvMot, float turbSpeed, float turbDistance, float turbFreqMax,
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
float turbAmplitudeMin, const zeus::CColor& c1, const zeus::CColor& c2, ResId splashParticle1,
ResId splashParticle2, ResId splashParticle3, ResId particle4, ResId particle5, s32 i1,
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool thermalCold,
bool allowRender, ResId patternMap1, ResId patternMap2, ResId colorMap, ResId bumpMap,
ResId envMap, ResId envBumpMap, ResId unusedMap, const zeus::CVector3f& bumpLightDir,
float bumpScale, float morphInTime, float morphOutTime, bool active,
CFluidPlane::EFluidType fluidType, bool b4, float alpha, const CFluidUVMotion& uvMot,
float turbSpeed, float turbDistance, float turbFreqMax, float turbFreqMin,
float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax, float turbAmplitudeMin,
const zeus::CColor& splashColor, const zeus::CColor& unkColor, ResId splashParticle1,
ResId splashParticle2, ResId splashParticle3, ResId particle4, ResId particle5, s32 unkSfx,
s32 visorRunoffSfx, s32 splashSfx1, s32 splashSfx2, s32 splashSfx3, float tileSize,
u32 tileSubdivisions, float specularMin, float specularMax, float reflectionSize,
float fluidPlaneF2, float reflectionBlend, float slF6, float slF7, float slF8,
const zeus::CColor& c3, ResId lightmapId, float unitsPerLightmapTexel, float lF2, float lF3,
u32, u32, bool, s32, s32, std::unique_ptr<u32[]>&& u32Arr)
float rippleIntensity, float reflectionBlend, float fogBias, float fogMagnitude,
float fogSpeed, const zeus::CColor& fogColor, ResId lightmapId, float unitsPerLightmapTexel,
float alphaInTime, float alphaOutTime, u32, u32, bool, s32, s32,
std::unique_ptr<u32[]>&& u32Arr)
: CScriptTrigger(uid, name, info, pos, box, dInfo, orientedForce, triggerFlags, active, false, false),
x1b8_position(pos), x1c4_extent(box.max - box.min), x1d0_f2(f2), x1d4_position2(pos), x1e0_extent2(box.max - box.min),
x1ec_damage(dInfo.GetDamage()), x1f0_damage2(dInfo.GetDamage()), x1f4_(f3), x214_(slF6), x218_(slF7), x21c_(slF6),
x220_(slF7), x224_(slF8), x228_(c3), x22c_splashParticle1Id(splashParticle1), x230_splashParticle2Id(splashParticle2),
x1b8_positionMorphed(pos), x1c4_extentMorphed(box.max - box.min), x1d0_morphInTime(morphInTime), x1d4_positionOrig(pos),
x1e0_extentOrig(box.max - box.min), x1ec_damageOrig(dInfo.GetDamage()), x1f0_damageMorphed(dInfo.GetDamage()),
x1f4_morphOutTime(morphOutTime), x214_fogBias(fogBias), x218_fogMagnitude(fogMagnitude), x21c_origFogBias(fogBias),
x220_origFogMagnitude(fogMagnitude), x224_fogSpeed(fogSpeed), x228_fogColor(fogColor),
x22c_splashParticle1Id(splashParticle1), x230_splashParticle2Id(splashParticle2),
x234_splashParticle3Id(splashParticle3), x238_particle4Id(particle4), x24c_particle5Id(particle5),
x260_(CSfxManager::TranslateSFXID(i1)), x262_visorRunoffSfx(CSfxManager::TranslateSFXID(visorRunoffSfx)),
x2a4_c1(c1), x2a8_c2(c2), x2ac_lf2(lF2), x2b0_lf3(lF3), x2b4_((lF2 != 0.f) ? 1.f / lF2 : 0.f),
x2b8_((lF3 != 0.f) ? 1.f / lF3 : 0.f), x2bc_alpha(alpha), x2c0_tileSize(tileSize)
x260_unkSfx(CSfxManager::TranslateSFXID(unkSfx)), x262_visorRunoffSfx(CSfxManager::TranslateSFXID(visorRunoffSfx)),
x2a4_splashColor(splashColor), x2a8_unkColor(unkColor), x2ac_alphaInTime(alphaInTime), x2b0_alphaOutTime(alphaOutTime),
x2b4_alphaInRecip((alphaInTime != 0.f) ? 1.f / alphaInTime : 0.f),
x2b8_alphaOutRecip((alphaOutTime != 0.f) ? 1.f / alphaOutTime : 0.f), x2bc_alpha(alpha), x2c0_tileSize(tileSize)
{
zeus::CAABox triggerAABB = GetTriggerBoundsWR();
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);
x2cc_gridCellCount = (x2c4_gridDimX + 1) * (x2c8_gridDimY + 1);
x2e8_24_b4 = b4;
x2e8_27_b2 = b2;
x2e8_28 = true;
x2e8_27_allowRender = allowRender;
x2e8_28_recomputeClipping = true;
x1b4_fluidPlane = std::make_unique<CFluidPlaneCPU>(patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap,
lightmapId, unitsPerLightmapTexel, tileSize, tileSubdivisions,
fluidType, x2bc_alpha, bumpLightDir, bumpScale, uvMot,
turbSpeed, turbDistance, turbFreqMax, turbFreqMin, turbPhaseMax,
turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, specularMin,
specularMax, reflectionBlend, reflectionSize, fluidPlaneF2);
specularMax, reflectionBlend, reflectionSize, rippleIntensity,
x2cc_gridCellCount *
((std::max(u32(2), tileSubdivisions) * 4 + 2) * 4));
u32Arr.reset();
x264_splashEffects.resize(3);
if (x22c_splashParticle1Id != kInvalidResId)
@ -75,61 +85,410 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string&
x90_actorLights->SetFindNearestDynamicLights(true);
x148_24_playerInside = true;
CalculateRenderBounds();
xe6_27_ = u8(b1 ? 2 : 1);
xe6_27_renderVisorFlags = u8(thermalCold ? 2 : 1);
if (!x30_24_active)
{
x2bc_alpha = 0.f;
x214_ = 0.f;
x218_ = 0.f;
x214_fogBias = 0.f;
x218_fogMagnitude = 0.f;
}
SetupGrid(true);
}
void CScriptWater::SetupGrid(bool b)
void CScriptWater::SetupGrid(bool recomputeClipping)
{
zeus::CAABox triggerAABB = GetTriggerBoundsWR();
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);
x2e4_gridCellCount2 = x2cc_gridCellCount = (dimX + 1) * (dimY + 1);
x2dc_.reset();
if (!x2d8_gridFlags || dimX != x2c4_gridDimX || dimY != x2c8_gridDimY)
x2d8_gridFlags.reset(new bool[dimX * dimY]);
x2dc_vertIntersects.reset();
if (!x2d8_tileIntersects || dimX != x2c4_gridDimX || dimY != x2c8_gridDimY)
x2d8_tileIntersects.reset(new bool[dimX * dimY]);
x2c4_gridDimX = dimX;
x2c8_gridDimY = dimY;
for (int i=0 ; i<x2c8_gridDimY ; ++i)
for (int j=0 ; j<x2c4_gridDimX ; ++j)
x2d8_gridFlags[i * x2c4_gridDimX + j] = true;
if (!x2e0_patchFlags || x2d0_patchDimX != 0 || x2d4_patchDimY != 0)
x2e0_patchFlags.reset(new u8[32]);
x2d8_tileIntersects[i * x2c4_gridDimX + j] = true;
if (!x2e0_patchIntersects || x2d0_patchDimX != 0 || x2d4_patchDimY != 0)
x2e0_patchIntersects.reset(new u8[32]);
for (int i=0 ; i<32 ; ++i)
x2e0_patchFlags[i] = 1;
x2e0_patchIntersects[i] = 1;
x2d4_patchDimY = 0;
x2d0_patchDimX = 0;
x2e8_28 = b;
x2e8_28_recomputeClipping = recomputeClipping;
}
void CScriptWater::Think(float dt, CStateManager& mgr) { CScriptTrigger::Think(dt, mgr); }
static const CMaterialFilter SolidFilter = CMaterialFilter::MakeInclude({EMaterialTypes::Solid});
void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts)
{
if (x2e8_28_recomputeClipping)
{
x2e4_gridCellCount2 = 0;
x2dc_vertIntersects.reset();
x2e8_28_recomputeClipping = false;
}
if (x2e4_gridCellCount2 >= x2cc_gridCellCount)
return;
if (!x2dc_vertIntersects)
x2dc_vertIntersects.reset(new bool[(x2c4_gridDimX + 1) * (x2c8_gridDimY + 1)]);
zeus::CAABox triggerBounds = GetTriggerBoundsWR();
zeus::CVector3f basePos = triggerBounds.min;
basePos.z = triggerBounds.max.z + 0.8f;
auto gridDiv = std::div(int(x2e4_gridCellCount2), int(x2c4_gridDimX + 1));
float yOffset = x2c0_tileSize * gridDiv.quot;
float xOffset = x2c0_tileSize * gridDiv.rem;
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)
{
zeus::CVector3f pos = basePos;
pos.x += xOffset;
pos.y += yOffset;
x2dc_vertIntersects[i] = mgr.RayStaticIntersection(pos, zeus::CVector3f::skDown, mag, SolidFilter).IsValid();
gridDiv.rem += 1;
xOffset += x2c0_tileSize;
if (gridDiv.rem > x2c4_gridDimX)
{
yOffset += x2c0_tileSize;
xOffset = 0.f;
gridDiv.rem = 0;
}
}
x2e4_gridCellCount2 += computeVerts;
if (x2e4_gridCellCount2 < x2cc_gridCellCount)
return;
x2e4_gridCellCount2 = x2cc_gridCellCount;
x2d8_tileIntersects.reset(new bool[x2c4_gridDimX * x2c8_gridDimY]);
for (int i = 0; i < x2c8_gridDimY; ++i)
{
int rowBase = x2c4_gridDimX * i;
int nextRowBase = (x2c4_gridDimX + 1) * i;
for (int j = 0; j < x2c4_gridDimX; ++j)
{
x2d8_tileIntersects[rowBase + j] =
x2dc_vertIntersects[nextRowBase + j] ||
x2dc_vertIntersects[nextRowBase + j + 1] ||
x2dc_vertIntersects[nextRowBase + j + x2c4_gridDimX + 1] ||
x2dc_vertIntersects[nextRowBase + j + x2c4_gridDimX + 2];
}
}
int tilesPerPatch = std::min(42 / x1b4_fluidPlane->GetTileSubdivisions(), 7);
x2d0_patchDimX = (tilesPerPatch + x2c4_gridDimX - 1) / tilesPerPatch;
x2d4_patchDimY = (tilesPerPatch + x2c8_gridDimY - 1) / tilesPerPatch;
x2e0_patchIntersects.reset(new u8[x2d0_patchDimX * x2d4_patchDimY]);
int curTileY = 0;
int nextTileY;
for (int i=0 ; i<x2d4_patchDimY ; ++i, curTileY = nextTileY)
{
nextTileY = curTileY + tilesPerPatch;
int curTileX = 0;
int rowBase = x2d0_patchDimX * i;
for (int j=0 ; j<x2d0_patchDimX ; ++j)
{
int nextTileX = curTileX + tilesPerPatch;
bool allClear = true;
bool allIntersections = true;
for (int k=curTileY ; k<std::min(nextTileY, x2c8_gridDimY) ; ++k)
{
if (!allClear && !allIntersections)
break;
for (int l=curTileX ; l<std::min(nextTileX, x2c4_gridDimX) ; ++l)
{
if (x2d8_tileIntersects[k * x2c4_gridDimX + l])
{
allClear = false;
if (!allIntersections)
break;
}
else
{
allIntersections = false;
if (!allClear)
break;
}
}
}
u8 flag;
if (allIntersections)
flag = 1;
else if (allClear)
flag = 0;
else
flag = 2;
x2e0_patchIntersects[rowBase + j] = flag;
curTileX += tilesPerPatch;
}
}
x2dc_vertIntersects.reset();
}
void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr)
{
// TODO: Do
}
void CScriptWater::Think(float dt, CStateManager& mgr)
{
if (!x30_24_active)
return;
bool oldCamSubmerged = x148_25_camSubmerged;
CScriptTrigger::Think(dt, mgr);
CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
if (x148_25_camSubmerged && !oldCamSubmerged)
mgr.SendScriptMsg(curCam, x8_uid, EScriptObjectMessage::AddSplashInhabitant);
else if (!x148_25_camSubmerged && oldCamSubmerged)
mgr.SendScriptMsg(curCam, x8_uid, EScriptObjectMessage::RemoveSplashInhabitant);
UpdateSplashInhabitants(mgr);
if (x2e8_30_alphaOut)
{
x2bc_alpha -= x2b8_alphaOutRecip * dt * x1b4_fluidPlane->GetAlpha();
x214_fogBias -= x2b8_alphaOutRecip * dt * x21c_origFogBias;
x218_fogMagnitude -= x2b8_alphaOutRecip * dt * x220_origFogMagnitude;
if (x2bc_alpha <= 0.f)
{
x218_fogMagnitude = 0.f;
x214_fogBias = 0.f;
x2bc_alpha = 0.f;
x2e8_30_alphaOut = false;
}
}
else if (x2e8_29_alphaIn)
{
x2bc_alpha += x2b4_alphaInRecip * dt * x1b4_fluidPlane->GetAlpha();
x214_fogBias -= x2b4_alphaInRecip * dt * x21c_origFogBias;
x218_fogMagnitude -= x2b4_alphaInRecip * dt * x220_origFogMagnitude;
if (x2bc_alpha > x1b4_fluidPlane->GetAlpha())
{
x2bc_alpha = x1b4_fluidPlane->GetAlpha();
x214_fogBias = x21c_origFogBias;
x218_fogMagnitude = x220_origFogMagnitude;
x2e8_29_alphaIn = false;
}
}
if (x2e8_26_morphing)
{
bool stillMorphing = true;
if (x2e8_25_morphIn)
{
x1f8_morphFactor += dt / x1d0_morphInTime;
if (x1f8_morphFactor > 1.f)
{
x1f8_morphFactor = 1.f;
stillMorphing = false;
}
}
else
{
x1f8_morphFactor -= dt / x1f4_morphOutTime;
if (x1f8_morphFactor < 0.f)
{
x1f8_morphFactor = 0.f;
stillMorphing = false;
}
}
SetTranslation(zeus::CVector3f::lerp(x1d4_positionOrig, x1b8_positionMorphed, x1f8_morphFactor));
zeus::CVector3f lerpExtent = zeus::CVector3f::lerp(x1e0_extentOrig, x1c4_extentMorphed, x1f8_morphFactor);
x130_bounds = zeus::CAABox(lerpExtent * -0.5f, lerpExtent * 0.5f);
CalculateRenderBounds();
if (!stillMorphing)
SetMorphing(false);
else
SetupGrid(false);
}
SetupGridClipping(mgr, 4);
}
void CScriptWater::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId other, CStateManager& mgr)
{
switch (msg)
{
case EScriptObjectMessage::Next:
if (!x30_24_active)
break;
x2e8_25_morphIn = !x2e8_25_morphIn;
if (x2e8_25_morphIn)
{
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Play ||
conn.x4_msg != EScriptObjectMessage::Activate)
continue;
auto list = mgr.GetIdListForScript(conn.x8_objId);
if (list.first == mgr.GetIdListEnd())
continue;
if (TCastToConstPtr<CScriptTrigger> trig = mgr.GetObjectById(list.first->second))
{
x1b8_positionMorphed = trig->GetTranslation();
x1c4_extentMorphed = trig->GetTriggerBoundsOR().max - trig->GetTriggerBoundsOR().min;
x1f0_damageMorphed = trig->GetDamageInfo().GetDamage();
x1d4_positionOrig = GetTranslation();
x1e0_extentOrig = x130_bounds.max - x130_bounds.min;
x1ec_damageOrig = x100_damageInfo.GetDamage();
break;
}
}
}
SetMorphing(true);
break;
case EScriptObjectMessage::Activate:
x2e8_30_alphaOut = false;
if (std::fabs(x2ac_alphaInTime) < 0.00001f)
{
x2bc_alpha = x1b4_fluidPlane->GetAlpha();
x214_fogBias = x21c_origFogBias;
x218_fogMagnitude = x220_origFogMagnitude;
}
else
{
x2e8_29_alphaIn = true;
}
break;
case EScriptObjectMessage::Action:
x2e8_29_alphaIn = false;
if (std::fabs(x2b0_alphaOutTime) < 0.00001f)
{
x2bc_alpha = 0.f;
x214_fogBias = 0.f;
x218_fogMagnitude = 0.f;
}
else
{
x2e8_30_alphaOut = true;
}
break;
default:
break;
}
CScriptTrigger::AcceptScriptMsg(msg, other, mgr);
}
void CScriptWater::PreRender(CStateManager &, const zeus::CFrustum &) {}
void CScriptWater::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
{
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;
}
}
void CScriptWater::AddToRenderer(const zeus::CFrustum& /*frustum*/, const CStateManager& mgr) const
{
zeus::CPlane plane;
plane.vec = x34_transform.origin.normalized();
plane.d = x34_transform.origin.z + x130_bounds.max.z;
zeus::CAABox renderBounds = GetSortingBounds(mgr);
mgr.AddDrawableActorPlane(*this, plane, renderBounds);
if (!xe4_30_outOfFrustum)
{
zeus::CPlane plane;
plane.vec = x34_transform.origin.normalized();
plane.d = x34_transform.origin.z + x130_bounds.max.z;
zeus::CAABox renderBounds = GetSortingBounds(mgr);
mgr.AddDrawableActorPlane(*this, plane, renderBounds);
}
}
void CScriptWater::Render(const CStateManager&) const {}
void CScriptWater::Touch(CActor&, CStateManager&)
void CScriptWater::Render(const CStateManager& mgr) const
{
if (x30_24_active && !xe4_30_outOfFrustum)
{
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(-x34_transform.origin.x, -x34_transform.origin.y,
-x34_transform.origin.z - zOffset));
zeus::CTransform xf = x34_transform;
xf.origin.z += zOffset;
zeus::CVector3f areaCenter = mgr.GetWorld()->GetAreaAlways(mgr.GetNextAreaId())->GetAABB().center();
std::experimental::optional<CRippleManager> rippleMan(mgr.GetFluidPlaneManager()->GetRippleManager());
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, areaCenter);
if (x214_fogBias != 0.f)
{
if (mgr.GetPlayerState()->CanVisorSeeFog(mgr))
{
float fogLevel = mgr.IntegrateVisorFog(x218_fogMagnitude *
std::sin(x224_fogSpeed * CGraphics::GetSecondsMod900()) +
x214_fogBias);
if (fogLevel > 0.f)
{
zeus::CAABox fogBox = GetTriggerBoundsWR();
fogBox.min.z = fogBox.max.z;
fogBox.max.z += fogLevel;
zeus::CTransform modelXf = zeus::CTransform::Translate(fogBox.center()) *
zeus::CTransform::Scale((fogBox.max - fogBox.min) * 0.5f);
zeus::CAABox renderAABB(zeus::CVector3f::skNegOne, zeus::CVector3f::skOne);
CGraphics::SetModelMatrix(modelXf);
g_Renderer->SetAmbientColor(zeus::CColor::skWhite);
g_Renderer->RenderFogVolume(x228_fogColor, renderAABB, nullptr, nullptr);
}
}
}
CGraphics::DisableAllLights();
}
CActor::Render(mgr);
}
void CScriptWater::Touch(CActor& otherAct, CStateManager& mgr)
{
if (!x30_24_active)
return;
CScriptTrigger::Touch(otherAct, mgr);
if (otherAct.GetMaterialList().HasMaterial(EMaterialTypes::Trigger))
return;
for (auto& inhab : x1fc_waterInhabitants)
if (inhab.first == otherAct.GetUniqueId())
{
inhab.second = true;
return;
}
auto touchBounds = otherAct.GetTouchBounds();
if (!touchBounds)
return;
x1fc_waterInhabitants.emplace_back(otherAct.GetUniqueId(), true);
float triggerMaxZ = GetTriggerBoundsWR().max.z;
if (touchBounds->min.z <= triggerMaxZ && touchBounds->max.z >= triggerMaxZ)
otherAct.FluidFXThink(EFluidState::Zero, *this, mgr);
mgr.SendScriptMsg(&otherAct, x8_uid, EScriptObjectMessage::AddSplashInhabitant);
}
void CScriptWater::CalculateRenderBounds()
@ -143,12 +502,15 @@ void CScriptWater::CalculateRenderBounds()
x9c_renderBounds = zeus::CAABox(transAABBMin, transAABBMax);
}
zeus::CAABox CScriptWater::GetSortingBounds(const CStateManager&) const
zeus::CAABox CScriptWater::GetSortingBounds(const CStateManager& mgr) const
{
return {};
zeus::CVector3f max = x9c_renderBounds.max;
max.z = std::max(max.z, x9c_renderBounds.max.z - 1.f + x214_fogBias + x218_fogMagnitude);
return {x9c_renderBounds.min, max};
}
EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, CWeaponMode&, int)
EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
CWeaponMode&, int)
{
return EWeaponCollisionResponseTypes::Water;
}
@ -175,10 +537,18 @@ float CScriptWater::GetSplashEffectScale(float dt) const
u32 CScriptWater::GetSplashIndex(float dt) const
{
u32 idx = dt * 3.f;
auto idx = u32(dt * 3.f);
return (idx < 3 ? idx : idx - 1);
}
void CScriptWater::SetMorphing(bool m)
{
if (m == x2e8_26_morphing)
return;
x2e8_26_morphing = m;
SetupGrid(!m);
}
const CScriptWater* CScriptWater::GetNextConnectedWater(const CStateManager& mgr) const
{
for (const SConnection& conn : x20_conns)

View File

@ -15,23 +15,22 @@ private:
static const float kSplashScales[6];
zeus::CFrustum x150_frustum;
std::unique_ptr<CFluidPlaneCPU> x1b4_fluidPlane;
zeus::CVector3f x1b8_position;
zeus::CVector3f x1c4_extent;
float x1d0_f2;
zeus::CVector3f x1d4_position2;
zeus::CVector3f x1e0_extent2;
float x1ec_damage;
float x1f0_damage2;
float x1f4_;
float x1f8_lightmapDoubleBlendFactor = 0.f;
zeus::CVector3f x1b8_positionMorphed;
zeus::CVector3f x1c4_extentMorphed;
float x1d0_morphInTime;
zeus::CVector3f x1d4_positionOrig;
zeus::CVector3f x1e0_extentOrig;
float x1ec_damageOrig;
float x1f0_damageMorphed;
float x1f4_morphOutTime;
float x1f8_morphFactor = 0.f;
std::list<std::pair<TUniqueId, bool>> x1fc_waterInhabitants;
u32 x210_;
float x214_;
float x218_;
float x21c_;
float x220_;
float x224_;
zeus::CColor x228_;
float x214_fogBias;
float x218_fogMagnitude;
float x21c_origFogBias;
float x220_origFogMagnitude;
float x224_fogSpeed;
zeus::CColor x228_fogColor;
ResId x22c_splashParticle1Id;
ResId x230_splashParticle2Id;
ResId x234_splashParticle3Id;
@ -39,58 +38,60 @@ private:
std::experimental::optional<TLockedToken<CGenDescription>> x23c_;
ResId x24c_particle5Id;
std::experimental::optional<TLockedToken<CGenDescription>> x250_visorRunoffEffect;
u16 x260_;
u16 x260_unkSfx;
u16 x262_visorRunoffSfx;
rstl::reserved_vector<std::experimental::optional<TLockedToken<CGenDescription>>, 3> x264_splashEffects;
rstl::reserved_vector<u16, 3> x298_splashSounds;
zeus::CColor x2a4_c1;
zeus::CColor x2a8_c2;
float x2ac_lf2;
float x2b0_lf3;
float x2b4_;
float x2b8_;
zeus::CColor x2a4_splashColor;
zeus::CColor x2a8_unkColor;
float x2ac_alphaInTime;
float x2b0_alphaOutTime;
float x2b4_alphaInRecip;
float x2b8_alphaOutRecip;
float x2bc_alpha;
float x2c0_tileSize;
u32 x2c4_gridDimX = 0;
u32 x2c8_gridDimY = 0;
u32 x2cc_gridCellCount = 0;
u32 x2d0_patchDimX = 0;
u32 x2d4_patchDimY = 0;
std::unique_ptr<bool[]> x2d8_gridFlags;
std::unique_ptr<bool[]> x2dc_;
std::unique_ptr<u8[]> x2e0_patchFlags;
u32 x2e4_gridCellCount2 = 0;
int x2c4_gridDimX = 0;
int x2c8_gridDimY = 0;
int x2cc_gridCellCount = 0;
int x2d0_patchDimX = 0;
int x2d4_patchDimY = 0;
std::unique_ptr<bool[]> x2d8_tileIntersects;
std::unique_ptr<bool[]> x2dc_vertIntersects;
std::unique_ptr<u8[]> x2e0_patchIntersects; // 0: all clear, 1: all intersect, 2: partial intersect
int x2e4_gridCellCount2 = 0;
union
{
struct
{
bool x2e8_24_b4 : 1;
bool x2e8_25 : 1;
bool x2e8_26 : 1;
bool x2e8_27_b2 : 1;
bool x2e8_28 : 1;
bool x2e8_29 : 1;
bool x2e8_30 : 1;
bool x2e8_25_morphIn : 1;
bool x2e8_26_morphing : 1;
bool x2e8_27_allowRender : 1;
bool x2e8_28_recomputeClipping : 1;
bool x2e8_29_alphaIn : 1;
bool x2e8_30_alphaOut : 1;
};
u32 _dummy = 0;
};
void SetupGrid(bool b);
void SetupGrid(bool recomputeClipping);
void SetupGridClipping(CStateManager& mgr, int computeVerts);
void UpdateSplashInhabitants(CStateManager& mgr);
public:
CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CVector3f& pos, const zeus::CAABox& box, const urde::CDamageInfo& dInfo,
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool b1, bool b2,
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool thermalCold, bool allowRender,
ResId patternMap1, ResId patternMap2, ResId colorMap, ResId bumpMap, ResId envMap,
ResId envBumpMap, ResId unusedMap, const zeus::CVector3f& bumpLightDir, float bumpScale,
float f2, float f3, bool active, CFluidPlane::EFluidType fluidType, bool b4, float alpha,
const CFluidUVMotion& uvMot, float turbSpeed, float turbDistance, float turbFreqMax,
float morphInTime, float morphOutTime, bool active, CFluidPlane::EFluidType fluidType, bool b4,
float alpha, const CFluidUVMotion& uvMot, float turbSpeed, float turbDistance, float turbFreqMax,
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
float turbAmplitudeMin, const zeus::CColor& c1, const zeus::CColor& c2, ResId splashParticle1,
ResId splashParticle2, ResId splashParticle3, ResId particle4, ResId particle5, s32 i1,
s32 visorRunoffSfx, s32 splashSfx1, s32 splashSfx2, s32 splashSfx3, float tileSize,
float turbAmplitudeMin, const zeus::CColor& splashColor, const zeus::CColor& unkColor,
ResId splashParticle1, ResId splashParticle2, ResId splashParticle3, ResId particle4, ResId particle5,
s32 unkSfx, s32 visorRunoffSfx, s32 splashSfx1, s32 splashSfx2, s32 splashSfx3, float tileSize,
u32 tileSubdivisions, float specularMin, float specularMax, float reflectionSize,
float fluidPlaneF2, float reflectionBlend, float slF6, float slF7, float slF8,
const zeus::CColor& c3, ResId lightmapId, float unitsPerLightmapTexel, float lF2, float lF3,
u32, u32, bool, s32, s32, std::unique_ptr<u32[]>&& u32Arr);
float rippleIntensity, float reflectionBlend, float fogBias, float fogMagnitude, float fogSpeed,
const zeus::CColor& fogColor, ResId lightmapId, float unitsPerLightmapTexel, float alphaInTime,
float alphaOutTime, u32, u32, bool, s32, s32, std::unique_ptr<u32[]>&& u32Arr);
void Think(float, CStateManager&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
@ -100,32 +101,30 @@ public:
void Touch(CActor &, CStateManager &);
void CalculateRenderBounds();
zeus::CAABox GetSortingBounds(const CStateManager&) const;
void RenderSurface();
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, CWeaponMode&,
int);
void UpdateSplashInhabitants(CStateManager&);
s16 GetSplashSound(float) const;
const std::experimental::optional<TLockedToken<CGenDescription>>& GetSplashEffect(float) const;
float GetSplashEffectScale(float) const;
u32 GetSplashIndex(float) const;
void FluidPlane();
CFluidPlaneCPU& FluidPlane() { return *x1b4_fluidPlane; }
zeus::CPlane GetWRSurfacePlane() const;
float GetSurfaceZ() const;
bool IsMorphing() const;
bool IsMorphing() const { return x2e8_26_morphing; }
void SetMorphing(bool);
zeus::CColor GetSplashColor() const;
void SetFrustumPlanes(const zeus::CFrustum& frustum);
const zeus::CFrustum& GetFrustumPlanes() const;
float GetMorphFactor() const { return x1f8_morphFactor; }
zeus::CColor GetSplashColor() const { return x2a4_splashColor; }
void SetFrustumPlanes(const zeus::CFrustum& frustum) { x150_frustum = frustum; }
const zeus::CFrustum& GetFrustumPlanes() const { return x150_frustum; }
CFluidPlaneCPU& GetFluidPlane() const { return *x1b4_fluidPlane; }
const std::experimental::optional<TLockedToken<CGenDescription>>& GetVisorRunoffEffect() const
{ return x250_visorRunoffEffect; }
u16 GetVisorRunoffSfx() const { return x262_visorRunoffSfx; }
const CScriptWater* GetNextConnectedWater(const CStateManager& mgr) const;
float GetLightmapDoubleBlendFactor() const { return x1f8_lightmapDoubleBlendFactor; }
u8 GetPatchRenderFlags(int x, int y) const { return x2e0_patchFlags[y * x2d0_patchDimX + x]; }
u32 GetPatchDimensionX() const { return x2d0_patchDimX; }
u32 GetPatchDimensionY() const { return x2d4_patchDimY; }
u8 GetPatchRenderFlags(int x, int y) const { return x2e0_patchIntersects[y * x2d0_patchDimX + x]; }
int GetPatchDimensionX() const { return x2d0_patchDimX; }
int GetPatchDimensionY() const { return x2d4_patchDimY; }
};
}

View File

@ -327,20 +327,13 @@ CAnimationParameters ScriptLoader::LoadAnimationParameters(CInputStream& in)
CFluidUVMotion ScriptLoader::LoadFluidUVMotion(CInputStream& in)
{
/* NOTE: DO NOT RE-ORDER THIS FUNCTION
* For some inexplicable reason Retro stores the layers in this order.
* Changing it will change the behavior of CFluidUVMotion,
* which is something we don't want.
* - Phil
* P.S: If you do change it, I'll hunt you down and put pink lipstick on your dog.
*/
CFluidUVMotion::EFluidUVMotion motion = CFluidUVMotion::EFluidUVMotion(in.readUint32Big());
auto motion = CFluidUVMotion::EFluidUVMotion(in.readUint32Big());
float a = in.readFloatBig();
float b = in.readFloatBig();
b = zeus::degToRad(b) - M_PIF;
float c = in.readFloatBig();
float d = in.readFloatBig();
CFluidUVMotion::SFluidLayerMotion layerMotion2(motion, a, b, c, d);
CFluidUVMotion::SFluidLayerMotion pattern1Layer(motion, a, b, c, d);
motion = CFluidUVMotion::EFluidUVMotion(in.readUint32Big());
a = in.readFloatBig();
@ -348,7 +341,7 @@ CFluidUVMotion ScriptLoader::LoadFluidUVMotion(CInputStream& in)
b = zeus::degToRad(b) - M_PIF;
c = in.readFloatBig();
d = in.readFloatBig();
CFluidUVMotion::SFluidLayerMotion layerMotion3(motion, a, b, c, d);
CFluidUVMotion::SFluidLayerMotion pattern2Layer(motion, a, b, c, d);
motion = CFluidUVMotion::EFluidUVMotion(in.readUint32Big());
a = in.readFloatBig();
@ -356,14 +349,14 @@ CFluidUVMotion ScriptLoader::LoadFluidUVMotion(CInputStream& in)
b = zeus::degToRad(b) - M_PIF;
c = in.readFloatBig();
d = in.readFloatBig();
CFluidUVMotion::SFluidLayerMotion layerMotion1(motion, a, b, c, d);
CFluidUVMotion::SFluidLayerMotion colorLayer(motion, a, b, c, d);
a = in.readFloatBig();
b = in.readFloatBig();
b = zeus::degToRad(b) - M_PIF;
return CFluidUVMotion(a, b, layerMotion1, layerMotion2, layerMotion3);
return CFluidUVMotion(a, b, colorLayer, pattern1Layer, pattern2Layer);
}
zeus::CTransform ScriptLoader::ConvertEditorEulerToTransform4f(const zeus::CVector3f& orientation,
@ -1206,68 +1199,68 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
ETriggerFlags::DetectProjectiles4 | ETriggerFlags::DetectBombs |
ETriggerFlags::DetectPowerBombs | ETriggerFlags::DetectProjectiles5 |
ETriggerFlags::DetectProjectiles6 | ETriggerFlags::DetectProjectiles7;
bool b1 = in.readBool();
bool thermalCold = in.readBool();
bool displaySurface = in.readBool();
ResId textureId1 = in.readUint32Big();
ResId textureId2 = in.readUint32Big();
ResId textureId3 = in.readUint32Big();
ResId textureId4 = in.readUint32Big();
ResId textureId5 = in.readUint32Big();
ResId textureId6 = in.readUint32Big();
zeus::CVector3f v2;
v2.readBig(in);
ResId patternMap1 = in.readUint32Big();
ResId patternMap2 = in.readUint32Big();
ResId colorMap = in.readUint32Big();
ResId bumpMap = in.readUint32Big();
ResId _envMap = in.readUint32Big();
ResId _envBumpMap = in.readUint32Big();
zeus::CVector3f _bumpLightDir;
_bumpLightDir.readBig(in);
zeus::CVector3f otherV2 = v2;
if (otherV2.canBeNormalized())
otherV2.assign(0.f, 0.f, -1.f);
zeus::CVector3f bumpLightDir = _bumpLightDir;
if (!bumpLightDir.canBeNormalized())
bumpLightDir.assign(0.f, 0.f, -1.f);
float f1 = 1.f / in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
float bumpScale = 1.f / in.readFloatBig();
float morphInTime = in.readFloatBig();
float morphOutTime = in.readFloatBig();
bool active = in.readBool();
CFluidPlane::EFluidType fluidType = CFluidPlane::EFluidType(in.readUint32Big());
auto fluidType = CFluidPlane::EFluidType(in.readUint32Big());
bool b4 = in.readBool();
float f4 = in.readFloatBig();
CFluidUVMotion fluidMotion = LoadFluidUVMotion(in);
float alpha = in.readFloatBig();
CFluidUVMotion uvMotion = LoadFluidUVMotion(in);
float f5 = in.readFloatBig();
float f6 = in.readFloatBig();
float f7 = in.readFloatBig();
float f8 = in.readFloatBig();
float f9 = zeus::degToRad(in.readFloatBig());
float f10 = zeus::degToRad(in.readFloatBig());
float f11 = in.readFloatBig();
float f12 = in.readFloatBig();
zeus::CColor c1;
c1.readRGBABig(in);
zeus::CColor c2;
c2.readRGBABig(in);
ResId enterParticle = in.readUint32Big();
ResId partId2 = in.readUint32Big();
ResId partId3 = in.readUint32Big();
ResId partId4 = in.readUint32Big();
ResId partId5 = in.readUint32Big();
u32 soundId1 = in.readUint32Big();
u32 soundId2 = in.readUint32Big();
u32 soundId3 = in.readUint32Big();
u32 soundId4 = in.readUint32Big();
u32 soundId5 = in.readUint32Big();
float f13 = in.readFloatBig();
u32 w19 = in.readUint32Big();
float f14 = in.readFloatBig();
float f15 = in.readFloatBig();
float f16 = in.readFloatBig();
float f17 = in.readFloatBig();
float f18 = in.readFloatBig();
float f19 = in.readFloatBig();
float heatWaveHeight = in.readFloatBig();
float heatWaveSpeed = in.readFloatBig();
zeus::CColor heatWaveColor;
heatWaveColor.readRGBABig(in);
float turbSpeed = in.readFloatBig();
float turbDistance = in.readFloatBig();
float turbFreqMax = in.readFloatBig();
float turbFreqMin = in.readFloatBig();
float turbPhaseMax = zeus::degToRad(in.readFloatBig());
float turbPhaseMin = zeus::degToRad(in.readFloatBig());
float turbAmplitudeMax = in.readFloatBig();
float turbAmplitudeMin = in.readFloatBig();
zeus::CColor splashColor;
splashColor.readRGBABig(in);
zeus::CColor unkColor;
unkColor.readRGBABig(in);
ResId splashParticle1 = in.readUint32Big();
ResId splashParticle2 = in.readUint32Big();
ResId splashParticle3 = in.readUint32Big();
ResId particle4 = in.readUint32Big();
ResId particle5 = in.readUint32Big();
u32 unkSfx = in.readUint32Big();
u32 visorRunoffSfx = in.readUint32Big();
u32 splashSfx1 = in.readUint32Big();
u32 splashSfx2 = in.readUint32Big();
u32 splashSfx3 = in.readUint32Big();
float tileSize = in.readFloatBig();
u32 tileSubdivisions = in.readUint32Big();
float specularMin = in.readFloatBig();
float specularMax = in.readFloatBig();
float reflectionSize = in.readFloatBig();
float rippleIntensity = in.readFloatBig();
float reflectionBlend = in.readFloatBig();
float fogBias = in.readFloatBig();
float fogMagnitude = in.readFloatBig();
float fogSpeed = in.readFloatBig();
zeus::CColor fogColor;
fogColor.readRGBABig(in);
ResId lightmap = in.readUint32Big();
float f22 = in.readFloatBig();
float f23 = in.readFloatBig();
float f24 = in.readFloatBig();
float unitsPerLightmapTexel = in.readFloatBig();
float alphaInTime = in.readFloatBig();
float alphaOutTime = in.readFloatBig();
u32 w21 = in.readUint32Big();
u32 w22 = in.readUint32Big();
bool b5 = in.readBool();
@ -1287,21 +1280,23 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
zeus::CAABox box(-extent * 0.5f, extent * 0.5f);
ResId realTextureId6 = -1;
if (textureId4 == -1)
realTextureId6 = textureId6;
ResId envBumpMap = -1;
if (bumpMap == -1)
envBumpMap = _envBumpMap;
ResId realTextureId5 = -1;
if (textureId4 == -1)
realTextureId5 = textureId5;
ResId envMap = -1;
if (bumpMap == -1)
envMap = _envMap;
return new CScriptWater(
mgr, mgr.AllocateUniqueId(), name, info, position, box, dInfo, orientedForce, triggerFlags, b1, displaySurface,
textureId1, textureId2, textureId3, textureId4, realTextureId5, realTextureId6, -1, otherV2, f1, f2, f3, active,
fluidType, b4, f4, fluidMotion, f5, f6, f7, f8, f9, f10, f11, f12, c1, c2, enterParticle, partId2, partId3,
partId4, partId5, soundId1, soundId2, soundId3, soundId4, soundId5, f13, w19, f14, f15, f16, f17, f18, f19,
heatWaveHeight, heatWaveSpeed, heatWaveColor, lightmap, f22, f23, f24, w21, w22, b5, bitVal0, bitVal1,
std::move(bitset));
mgr, mgr.AllocateUniqueId(), name, info, position, box, dInfo, orientedForce, triggerFlags, thermalCold,
displaySurface, patternMap1, patternMap2, colorMap, bumpMap, envMap, envBumpMap, -1, bumpLightDir, bumpScale,
morphInTime, morphOutTime, active, fluidType, b4, alpha, uvMotion, turbSpeed, turbDistance, turbFreqMax,
turbFreqMin, turbPhaseMax, turbPhaseMin, turbAmplitudeMax, turbAmplitudeMin, splashColor, unkColor,
splashParticle1, splashParticle2, splashParticle3, particle4, particle5, unkSfx, visorRunoffSfx, splashSfx1,
splashSfx2, splashSfx3, tileSize, tileSubdivisions, specularMin, specularMax, reflectionSize, rippleIntensity,
reflectionBlend, fogBias, fogMagnitude, fogSpeed, fogColor, lightmap, unitsPerLightmapTexel, alphaInTime,
alphaOutTime, w21, w22, b5, bitVal0, bitVal1, std::move(bitset));
}
CEntity* ScriptLoader::LoadWarWasp(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)