mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of https://github.com/AxioDL/urde
This commit is contained in:
commit
86212f1d8f
|
@ -1,6 +1,9 @@
|
||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="ClangTidyInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="clangTidyChecks" value="*,-cert-env33-c,-cppcoreguidelines-no-malloc,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-cstyle-cast,-cppcoreguidelines-pro-type-union-access,-google-*,google-default-arguments,google-explicit-constructor,google-runtime-member-string-references,google-runtime-memset,google-runtime-operator,-llvm-*,-readability-simplify-boolean-expr,-readability-braces-around-statements,-readability-identifier-naming,-readability-function-size,-misc-bool-pointer-implicit-conversion,-misc-unused-parameters,-modernize-use-using,-safety-no-assembler,-clang-diagnostic-*,-clang-analyzer-*,-cert-flp30-c" />
|
||||||
|
</inspection_tool>
|
||||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
<option name="processCode" value="true" />
|
<option name="processCode" value="true" />
|
||||||
<option name="processLiterals" value="true" />
|
<option name="processLiterals" value="true" />
|
||||||
|
|
|
@ -12,6 +12,9 @@ struct ITweakGame : ITweak
|
||||||
virtual bool GetSplashScreensDisabled() const = 0;
|
virtual bool GetSplashScreensDisabled() const = 0;
|
||||||
virtual float GetFirstPersonFOV() const = 0;
|
virtual float GetFirstPersonFOV() const = 0;
|
||||||
virtual float GetPressStartDelay() const = 0;
|
virtual float GetPressStartDelay() const = 0;
|
||||||
|
virtual float GetRippleSideLengthNormal() const = 0;
|
||||||
|
virtual float GetRippleSideLengthPoison() const = 0;
|
||||||
|
virtual float GetRippleSideLengthLava() const = 0;
|
||||||
virtual float GetFluidEnvBumpScale() const = 0;
|
virtual float GetFluidEnvBumpScale() const = 0;
|
||||||
virtual float GetHardModeDamageMultiplier() const = 0;
|
virtual float GetHardModeDamageMultiplier() const = 0;
|
||||||
virtual float GetHardModeWeaponMultiplier() const = 0;
|
virtual float GetHardModeWeaponMultiplier() const = 0;
|
||||||
|
|
|
@ -19,10 +19,10 @@ struct CTweakGame : ITweakGame
|
||||||
Value<bool> x2a_unknown3;
|
Value<bool> x2a_unknown3;
|
||||||
Value<bool> x2b_splashScreensDisabled;
|
Value<bool> x2b_splashScreensDisabled;
|
||||||
Value<float> x2c_unknown5;
|
Value<float> x2c_unknown5;
|
||||||
Value<float> x30_presStartDelay;
|
Value<float> x30_pressStartDelay;
|
||||||
Value<float> x34_unknown7;
|
Value<float> x34_rippleSideLenNormal;
|
||||||
Value<float> x38_unknown8;
|
Value<float> x38_rippleSideLenPoison;
|
||||||
Value<float> x3c_unknown9;
|
Value<float> x3c_rippleSideLenLava;
|
||||||
Value<float> x40_unknown10;
|
Value<float> x40_unknown10;
|
||||||
Value<float> x44_unknown11;
|
Value<float> x44_unknown11;
|
||||||
Value<float> x48_unknown12;
|
Value<float> x48_unknown12;
|
||||||
|
@ -34,13 +34,16 @@ struct CTweakGame : ITweakGame
|
||||||
Value<float> x60_hardmodeDamageMult;
|
Value<float> x60_hardmodeDamageMult;
|
||||||
Value<float> x64_hardmodeWeaponMult;
|
Value<float> x64_hardmodeWeaponMult;
|
||||||
|
|
||||||
virtual const std::string& GetWorldPrefix() const { return x4_worldPrefix; }
|
const std::string& GetWorldPrefix() const { return x4_worldPrefix; }
|
||||||
virtual bool GetSplashScreensDisabled() const { return x2b_splashScreensDisabled; }
|
bool GetSplashScreensDisabled() const { return x2b_splashScreensDisabled; }
|
||||||
virtual float GetFirstPersonFOV() const { return x24_fov; }
|
float GetFirstPersonFOV() const { return x24_fov; }
|
||||||
virtual float GetPressStartDelay() const { return x30_presStartDelay; }
|
float GetPressStartDelay() const { return x30_pressStartDelay; }
|
||||||
virtual float GetFluidEnvBumpScale() const { return x4c_fluidEnvBumpScale; }
|
float GetRippleSideLengthNormal() const { return x34_rippleSideLenNormal; }
|
||||||
virtual float GetHardModeDamageMultiplier() const { return x60_hardmodeDamageMult; }
|
float GetRippleSideLengthPoison() const { return x38_rippleSideLenPoison; }
|
||||||
virtual float GetHardModeWeaponMultiplier() const { return x64_hardmodeWeaponMult; }
|
float GetRippleSideLengthLava() const { return x3c_rippleSideLenLava; }
|
||||||
|
float GetFluidEnvBumpScale() const { return x4c_fluidEnvBumpScale; }
|
||||||
|
float GetHardModeDamageMultiplier() const { return x60_hardmodeDamageMult; }
|
||||||
|
float GetHardModeWeaponMultiplier() const { return x64_hardmodeWeaponMult; }
|
||||||
CTweakGame() = default;
|
CTweakGame() = default;
|
||||||
CTweakGame(athena::io::IStreamReader& in)
|
CTweakGame(athena::io::IStreamReader& in)
|
||||||
{
|
{
|
||||||
|
|
|
@ -457,7 +457,7 @@ void CActorLights::BuildDynamicLightList(const CStateManager& mgr, const zeus::C
|
||||||
x299_26_ = false;
|
x299_26_ = false;
|
||||||
x144_dynamicLights.clear();
|
x144_dynamicLights.clear();
|
||||||
|
|
||||||
if (!x29a_)
|
if (!x29a_findNearestDynamicLights)
|
||||||
{
|
{
|
||||||
for (const CLight& light : mgr.GetDynamicLightList())
|
for (const CLight& light : mgr.GetDynamicLightList())
|
||||||
{
|
{
|
||||||
|
@ -555,6 +555,13 @@ void CActorLights::ActivateLights(CBooModel& model) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CActorLights::DisableAreaLights()
|
||||||
|
{
|
||||||
|
x2b8_maxAreaLights = 0;
|
||||||
|
x298_26_hasAreaLights = false;
|
||||||
|
x298_28_inArea = false;
|
||||||
|
}
|
||||||
|
|
||||||
const CLight& CActorLights::GetLight(u32 idx) const
|
const CLight& CActorLights::GetLight(u32 idx) const
|
||||||
{
|
{
|
||||||
if (x298_28_inArea)
|
if (x298_28_inArea)
|
||||||
|
|
|
@ -39,7 +39,7 @@ class CActorLights
|
||||||
};
|
};
|
||||||
u16 _dummy = 0;
|
u16 _dummy = 0;
|
||||||
};
|
};
|
||||||
bool x29a_ = false;
|
bool x29a_findNearestDynamicLights = false;
|
||||||
u32 x29c_shadowLightValIdx = -1;
|
u32 x29c_shadowLightValIdx = -1;
|
||||||
u32 x2a0_shadowLightIdx = -1;
|
u32 x2a0_shadowLightIdx = -1;
|
||||||
u32 x2a4_lastUpdateFrame = 0;
|
u32 x2a4_lastUpdateFrame = 0;
|
||||||
|
@ -75,6 +75,10 @@ public:
|
||||||
void ActivateLights(CBooModel& model) const;
|
void ActivateLights(CBooModel& model) const;
|
||||||
void SetCastShadows(bool v) { x298_25_castShadows = v; }
|
void SetCastShadows(bool v) { x298_25_castShadows = v; }
|
||||||
void SetFindShadowLight(bool v) { x298_27_findShadowLight = v; }
|
void SetFindShadowLight(bool v) { x298_27_findShadowLight = v; }
|
||||||
|
void SetAmbientChannelOverflow(bool v) { x298_29_ambientChannelOverflow = v; }
|
||||||
|
void DisableAreaLights();
|
||||||
|
void SetMaxDynamicLights(int l) { x2bc_maxDynamicLights = l; }
|
||||||
|
void SetFindNearestDynamicLights(bool v) { x29a_findNearestDynamicLights = v; }
|
||||||
|
|
||||||
void SetAmbientColor(const zeus::CColor& color) { x288_ambientColor = color; }
|
void SetAmbientColor(const zeus::CColor& color) { x288_ambientColor = color; }
|
||||||
const zeus::CColor& GetAmbientColor() const { return x288_ambientColor; }
|
const zeus::CColor& GetAmbientColor() const { return x288_ambientColor; }
|
||||||
|
|
|
@ -31,26 +31,32 @@ class CLight
|
||||||
friend class CGameLight;
|
friend class CGameLight;
|
||||||
|
|
||||||
zeus::CVector3f x0_pos;
|
zeus::CVector3f x0_pos;
|
||||||
zeus::CVector3f xc_dir;
|
zeus::CVector3f xc_dir = zeus::CVector3f::skDown;
|
||||||
zeus::CColor x18_color;
|
zeus::CColor x18_color = zeus::CColor::skClear;
|
||||||
ELightType x1c_type;
|
ELightType x1c_type = ELightType::Custom;
|
||||||
float x20_spotCutoff;
|
float x20_spotCutoff = 0.f;
|
||||||
float x24_distC;
|
float x24_distC = 1.f;
|
||||||
float x28_distL;
|
float x28_distL = 0.f;
|
||||||
float x2c_distQ;
|
float x2c_distQ = 0.f;
|
||||||
float x30_angleC;
|
float x30_angleC = 1.f;
|
||||||
float x34_angleL;
|
float x34_angleL = 0.f;
|
||||||
float x38_angleQ;
|
float x38_angleQ = 0.f;
|
||||||
u32 x3c_priority = 0;
|
u32 x3c_priority = 0;
|
||||||
u32 x40_lightId = 0; // Serves as unique key
|
u32 x40_lightId = 0; // Serves as unique key
|
||||||
float x44_cachedRadius;
|
float x44_cachedRadius = 0.f;
|
||||||
float x48_cachedIntensity;
|
float x48_cachedIntensity = 0.f;
|
||||||
bool x4c_24_intensityDirty : 1;
|
bool x4c_24_intensityDirty : 1;
|
||||||
bool x4c_25_radiusDirty : 1;
|
bool x4c_25_radiusDirty : 1;
|
||||||
|
|
||||||
float CalculateLightRadius() const;
|
float CalculateLightRadius() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CLight()
|
||||||
|
{
|
||||||
|
x4c_24_intensityDirty = true;
|
||||||
|
x4c_25_radiusDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
CLight(const zeus::CVector3f& pos,
|
CLight(const zeus::CVector3f& pos,
|
||||||
const zeus::CVector3f& dir,
|
const zeus::CVector3f& dir,
|
||||||
const zeus::CColor& color,
|
const zeus::CColor& color,
|
||||||
|
|
|
@ -96,9 +96,9 @@ void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMana
|
||||||
void CActor::CalculateRenderBounds()
|
void CActor::CalculateRenderBounds()
|
||||||
{
|
{
|
||||||
if (x64_modelData && (x64_modelData->AnimationData() || x64_modelData->GetNormalModel()))
|
if (x64_modelData && (x64_modelData->AnimationData() || x64_modelData->GetNormalModel()))
|
||||||
x9c_aabox = x64_modelData->GetBounds(x34_transform);
|
x9c_renderBounds = x64_modelData->GetBounds(x34_transform);
|
||||||
else
|
else
|
||||||
x9c_aabox = zeus::CAABox(x34_transform.origin, x34_transform.origin);
|
x9c_renderBounds = zeus::CAABox(x34_transform.origin, x34_transform.origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHealthInfo* CActor::HealthInfo() { return nullptr; }
|
CHealthInfo* CActor::HealthInfo() { return nullptr; }
|
||||||
|
@ -167,7 +167,7 @@ void CActor::OnScanStateChanged(EScanState state, CStateManager& mgr)
|
||||||
SendScriptMsgs(EScriptObjectState::ScanDone, mgr, EScriptObjectMessage::None);
|
SendScriptMsgs(EScriptObjectState::ScanDone, mgr, EScriptObjectMessage::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CAABox CActor::GetSortingBounds(const CStateManager&) const { return x9c_aabox; }
|
zeus::CAABox CActor::GetSortingBounds(const CStateManager&) const { return x9c_renderBounds; }
|
||||||
|
|
||||||
void CActor::DoUserAnimEvent(CStateManager&, CInt32POINode&, EUserEventType, float dt) {}
|
void CActor::DoUserAnimEvent(CStateManager&, CInt32POINode&, EUserEventType, float dt) {}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ protected:
|
||||||
std::unique_ptr<CActorLights> x90_actorLights;
|
std::unique_ptr<CActorLights> x90_actorLights;
|
||||||
std::unique_ptr<CSimpleShadow> x94_simpleShadow;
|
std::unique_ptr<CSimpleShadow> x94_simpleShadow;
|
||||||
std::unique_ptr<TToken<CScannableObjectInfo>> x98_scanObjectInfo;
|
std::unique_ptr<TToken<CScannableObjectInfo>> x98_scanObjectInfo;
|
||||||
zeus::CAABox x9c_aabox;
|
zeus::CAABox x9c_renderBounds;
|
||||||
CModelFlags xb4_drawFlags;
|
CModelFlags xb4_drawFlags;
|
||||||
float xbc_time = 0.f;
|
float xbc_time = 0.f;
|
||||||
float xc0_pitchBend = 0.f;
|
float xc0_pitchBend = 0.f;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "CWorld.hpp"
|
#include "CWorld.hpp"
|
||||||
#include "World/CScriptWater.hpp"
|
#include "World/CScriptWater.hpp"
|
||||||
#include "TCastTo.hpp"
|
#include "TCastTo.hpp"
|
||||||
|
#include "Camera/CGameCamera.hpp"
|
||||||
|
|
||||||
#define kTableSize 2048
|
#define kTableSize 2048
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ CFluidPlaneCPU::CTurbulence::CTurbulence(float speed, float distance, float freq
|
||||||
}
|
}
|
||||||
|
|
||||||
CFluidPlaneCPU::CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texColor, ResId bumpMap, ResId envMap,
|
CFluidPlaneCPU::CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texColor, ResId bumpMap, ResId envMap,
|
||||||
ResId envBumpMap, ResId unkMap, float unitsPerLightmapTexel, float tileSize,
|
ResId envBumpMap, ResId lightMap, float unitsPerLightmapTexel, float tileSize,
|
||||||
u32 tileSubdivisions, EFluidType fluidType, float alpha,
|
u32 tileSubdivisions, EFluidType fluidType, float alpha,
|
||||||
const zeus::CVector3f& bumpLightDir, float bumpScale, const CFluidUVMotion& mot,
|
const zeus::CVector3f& bumpLightDir, float bumpScale, const CFluidUVMotion& mot,
|
||||||
float turbSpeed, float turbDistance, float turbFreqMax, float turbFreqMin,
|
float turbSpeed, float turbDistance, float turbFreqMax, float turbFreqMin,
|
||||||
|
@ -51,7 +52,7 @@ CFluidPlaneCPU::CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texCo
|
||||||
float specularMin, float specularMax, float reflectionBlend, float reflectionSize,
|
float specularMin, float specularMax, float reflectionBlend, float reflectionSize,
|
||||||
float fluidPlaneF2)
|
float fluidPlaneF2)
|
||||||
: CFluidPlane(texPattern1, texPattern2, texColor, alpha, fluidType, fluidPlaneF2, mot),
|
: CFluidPlane(texPattern1, texPattern2, texColor, alpha, fluidType, fluidPlaneF2, mot),
|
||||||
xa0_texIdBumpMap(bumpMap), xa4_texIdEnvMap(envMap), xa8_texIdEnvBumpMap(envBumpMap), xac_texId4(unkMap),
|
xa0_texIdBumpMap(bumpMap), xa4_texIdEnvMap(envMap), xa8_texIdEnvBumpMap(envBumpMap), xac_texId4(lightMap),
|
||||||
xf0_bumpLightDir(bumpLightDir), xfc_bumpScale(bumpScale), x100_tileSize(tileSize),
|
xf0_bumpLightDir(bumpLightDir), xfc_bumpScale(bumpScale), x100_tileSize(tileSize),
|
||||||
x104_tileSubdivisions(tileSubdivisions & ~0x1),
|
x104_tileSubdivisions(tileSubdivisions & ~0x1),
|
||||||
x108_rippleResolution(x100_tileSize / float(x104_tileSubdivisions)),
|
x108_rippleResolution(x100_tileSize / float(x104_tileSubdivisions)),
|
||||||
|
@ -98,6 +99,18 @@ void CFluidPlaneCPU::CalculateLightmapMatrix(const zeus::CTransform& areaXf, con
|
||||||
zeus::CVector3f(offX, offY, 0.f)) * toLocal).toMatrix4f();
|
zeus::CVector3f(offX, offY, 0.f)) * toLocal).toMatrix4f();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sSineWaveInitialized = false;
|
||||||
|
static float sGlobalSineWave[256] = {};
|
||||||
|
static const float* InitializeSineWave()
|
||||||
|
{
|
||||||
|
if (sSineWaveInitialized)
|
||||||
|
return sGlobalSineWave;
|
||||||
|
for (int i=0 ; i<256 ; ++i)
|
||||||
|
sGlobalSineWave[i] = std::sin(2.f * M_PIF * (i / 256.f));
|
||||||
|
sSineWaveInitialized = true;
|
||||||
|
return sGlobalSineWave;
|
||||||
|
}
|
||||||
|
|
||||||
#define kEnableWaterBumpMaps true
|
#define kEnableWaterBumpMaps true
|
||||||
|
|
||||||
CFluidPlaneCPU::RenderSetupInfo
|
CFluidPlaneCPU::RenderSetupInfo
|
||||||
|
@ -111,6 +124,7 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
bool doubleLightmapBlend = false;
|
bool doubleLightmapBlend = false;
|
||||||
bool hasEnvMap = mgr.GetCameraManager()->GetFluidCounter() == 0 && HasEnvMap();
|
bool hasEnvMap = mgr.GetCameraManager()->GetFluidCounter() == 0 && HasEnvMap();
|
||||||
bool hasEnvBumpMap = HasEnvBumpMap();
|
bool hasEnvBumpMap = HasEnvBumpMap();
|
||||||
|
InitializeSineWave();
|
||||||
CGraphics::SetModelMatrix(xf);
|
CGraphics::SetModelMatrix(xf);
|
||||||
|
|
||||||
if (hasBumpMap)
|
if (hasBumpMap)
|
||||||
|
@ -118,38 +132,14 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
// Build 50% grey directional light with xf0_bumpLightDir and load into LIGHT_3
|
// Build 50% grey directional light with xf0_bumpLightDir and load into LIGHT_3
|
||||||
// Light 3 in channel 1
|
// Light 3 in channel 1
|
||||||
// Vertex colors in channel 0
|
// Vertex colors in channel 0
|
||||||
|
out.lights.resize(4);
|
||||||
|
out.lights[3] = CLight::BuildDirectional(xf0_bumpLightDir, zeus::CColor::skGrey);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal light mask in channel 1
|
// Normal light mask in channel 1
|
||||||
// Vertex colors in channel 0
|
// Vertex colors in channel 0
|
||||||
}
|
out.lights = water->GetActorLights()->BuildLightVector();
|
||||||
|
|
||||||
if (x10_texPattern1)
|
|
||||||
{
|
|
||||||
// Load into 0
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Load black tex into 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x20_texPattern2)
|
|
||||||
{
|
|
||||||
// Load into 1
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Load black tex into 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x30_texColor)
|
|
||||||
{
|
|
||||||
// Load into 2
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Load black tex into 2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int curTex = 3;
|
int curTex = 3;
|
||||||
|
@ -284,11 +274,443 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
m_shader.emplace(x44_fluidType,
|
m_shader.emplace(x44_fluidType,
|
||||||
x10_texPattern1, x20_texPattern2, x30_texColor, xb0_bumpMap, xc0_envMap, xd0_envBumpMap,
|
x10_texPattern1, x20_texPattern2, x30_texColor, xb0_bumpMap, xc0_envMap, xd0_envBumpMap,
|
||||||
xe0_lightmap, doubleLightmapBlend, mgr.GetParticleFlags() == 0);
|
xe0_lightmap, doubleLightmapBlend, mgr.GetParticleFlags() == 0);
|
||||||
out.lights = water->GetActorLights()->BuildLightVector();
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CFluidPlaneCPURender
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class RenderMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Normal,
|
||||||
|
Subdivided,
|
||||||
|
BumpMapped
|
||||||
|
};
|
||||||
|
|
||||||
|
static int numTilesInHField;
|
||||||
|
static int numSubdivisionsInTile;
|
||||||
|
static int numSubdivisionsInHField;
|
||||||
|
|
||||||
|
struct SPatchInfo
|
||||||
|
{
|
||||||
|
u8 x0_xSubdivs, x1_ySubdivs;
|
||||||
|
zeus::CVector2f x4_localMin, xc_globalMin;
|
||||||
|
float x14_rippleSideLen;
|
||||||
|
float x18_rippleResolution;
|
||||||
|
float x1c_rippleHypRadius;
|
||||||
|
float x20_ooRippleSideLen;
|
||||||
|
float x24_ooRippleResolution;
|
||||||
|
u16 x28_tileX;
|
||||||
|
u16 x2a_gridDimX;
|
||||||
|
u16 x2c_gridDimY;
|
||||||
|
u16 x2e_tileY;
|
||||||
|
const bool* x30_gridFlags;
|
||||||
|
bool x34_r14;
|
||||||
|
u8 x35_r22;
|
||||||
|
u8 x36_r23;
|
||||||
|
RenderMode x37_renderMode;
|
||||||
|
float x38_tileSize;
|
||||||
|
public:
|
||||||
|
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
||||||
|
float rippleResolution, float rippleSideLen, float tileSize, int numSubdivisionsInHField,
|
||||||
|
RenderMode renderMode, bool r14, int r22, int r23, u32 tileX, u32 gridDimX, u32 gridDimY,
|
||||||
|
u32 tileY, const bool* gridFlags)
|
||||||
|
{
|
||||||
|
x0_xSubdivs = std::min(s16((localMax.x - localMin.x) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||||
|
numSubdivisionsInHField + 2);
|
||||||
|
x1_ySubdivs = std::min(s16((localMax.y - localMin.y) / rippleResolution + 1.f - FLT_EPSILON) + 2,
|
||||||
|
numSubdivisionsInHField + 2);
|
||||||
|
float rippleHypRadius = rippleSideLen * rippleSideLen * 2 * 0.25f;
|
||||||
|
x4_localMin.x = localMin.x;
|
||||||
|
x4_localMin.y = localMin.y;
|
||||||
|
xc_globalMin = x4_localMin + zeus::CVector2f(pos.x, pos.y);
|
||||||
|
x14_rippleSideLen = rippleSideLen;
|
||||||
|
x18_rippleResolution = rippleResolution;
|
||||||
|
if (rippleHypRadius != 0.f)
|
||||||
|
rippleHypRadius = std::sqrt(rippleHypRadius);
|
||||||
|
x1c_rippleHypRadius = rippleHypRadius;
|
||||||
|
x20_ooRippleSideLen = 1.f / x14_rippleSideLen;
|
||||||
|
x24_ooRippleResolution = 1.f / x18_rippleResolution;
|
||||||
|
x28_tileX = u16(tileX);
|
||||||
|
x2a_gridDimX = u16(gridDimX);
|
||||||
|
x2c_gridDimY = u16(gridDimY);
|
||||||
|
x2e_tileY = u16(tileY);
|
||||||
|
x30_gridFlags = gridFlags;
|
||||||
|
x34_r14 = r14;
|
||||||
|
x35_r22 = u8(r22);
|
||||||
|
x36_r23 = u8(r23);
|
||||||
|
x37_renderMode = renderMode;
|
||||||
|
x38_tileSize = tileSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SRippleInfo
|
||||||
|
{
|
||||||
|
const CRipple& x0_ripple;
|
||||||
|
int x4_fromX;
|
||||||
|
int x8_toX;
|
||||||
|
int xc_fromY;
|
||||||
|
int x10_toY;
|
||||||
|
int x14_gfromX;
|
||||||
|
int x18_gtoX;
|
||||||
|
int x1c_gfromY;
|
||||||
|
int x20_gtoY;
|
||||||
|
public:
|
||||||
|
SRippleInfo(const CRipple& ripple, int fromX, int toX, int fromY, int toY)
|
||||||
|
: x0_ripple(ripple), x14_gfromX(fromX), x18_gtoX(toX), x1c_gfromY(fromY), x20_gtoY(toY) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHFieldSample
|
||||||
|
{
|
||||||
|
float f1;
|
||||||
|
u8 f2;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
int CFluidPlaneCPURender::numTilesInHField;
|
||||||
|
int CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
int CFluidPlaneCPURender::numSubdivisionsInHField;
|
||||||
|
|
||||||
|
static bool PrepareRipple(const CRipple& ripple, const CFluidPlaneCPURender::SPatchInfo& info,
|
||||||
|
CFluidPlaneCPURender::SRippleInfo& rippleOut)
|
||||||
|
{
|
||||||
|
auto lifeIdx = int((1.f - (ripple.GetTimeFalloff() - ripple.GetTime()) / ripple.GetTimeFalloff()) * 64.f);
|
||||||
|
float dist = CFluidPlaneManager::RippleMaxs[lifeIdx] * (ripple.GetDistanceFalloff() / 256.f);
|
||||||
|
dist *= dist;
|
||||||
|
if (dist != 0)
|
||||||
|
dist = std::sqrt(dist);
|
||||||
|
dist = info.x24_ooRippleResolution * dist + 1.f;
|
||||||
|
float centerX = info.x24_ooRippleResolution * (ripple.GetCenter().x - info.xc_globalMin.x);
|
||||||
|
float centerY = info.x24_ooRippleResolution * (ripple.GetCenter().y - info.xc_globalMin.y);
|
||||||
|
int fromX = int(centerX - dist) - 1;
|
||||||
|
int toX = int(centerX + dist) + 1;
|
||||||
|
int fromY = int(centerY - dist) - 1;
|
||||||
|
int toY = int(centerY + dist) + 1;
|
||||||
|
rippleOut.x4_fromX = std::max(0, fromX);
|
||||||
|
rippleOut.x8_toX = std::min(int(info.x0_xSubdivs), toX);
|
||||||
|
rippleOut.xc_fromY = std::max(0, fromY);
|
||||||
|
rippleOut.x10_toY = std::min(int(info.x1_ySubdivs), toY);
|
||||||
|
rippleOut.x14_gfromX = std::max(rippleOut.x14_gfromX, fromX);
|
||||||
|
rippleOut.x18_gtoX = std::min(rippleOut.x18_gtoX, toX);
|
||||||
|
rippleOut.x1c_gfromY = std::max(rippleOut.x1c_gfromY, fromY);
|
||||||
|
rippleOut.x20_gtoY = std::min(rippleOut.x20_gtoY, toY);
|
||||||
|
return !(rippleOut.x14_gfromX > rippleOut.x18_gtoX || rippleOut.x1c_gfromY > rippleOut.x20_gtoY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyTurbulence(float t, CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const u8 (&flags)[9][9],
|
||||||
|
const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info,
|
||||||
|
const CFluidPlaneCPU& fluidPane, const zeus::CVector3f& areaCenter)
|
||||||
|
{
|
||||||
|
if (!fluidPane.HasTurbulence())
|
||||||
|
{
|
||||||
|
memset(&heights, 0, sizeof(heights));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float scaledT = t * fluidPane.GetOOTurbulenceSpeed();
|
||||||
|
float curY = info.x4_localMin.y - info.x18_rippleResolution - areaCenter.y;
|
||||||
|
int xDivs = (info.x0_xSubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 4) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile * CFluidPlaneCPURender::numSubdivisionsInTile + 2;
|
||||||
|
int yDivs = (info.x1_ySubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 4) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile * CFluidPlaneCPURender::numSubdivisionsInTile + 2;
|
||||||
|
for (int i=0 ; i<=yDivs ; ++i)
|
||||||
|
{
|
||||||
|
float curYSq = curY * curY;
|
||||||
|
float curX = info.x4_localMin.x - info.x18_rippleResolution - areaCenter.x;
|
||||||
|
for (int j=0 ; j<=xDivs ; ++j)
|
||||||
|
{
|
||||||
|
float distFac = curX * curX + curYSq;
|
||||||
|
if (distFac != 0.f)
|
||||||
|
distFac = std::sqrt(distFac);
|
||||||
|
heights[i][j].f1 = fluidPane.GetTurbulenceHeight(fluidPane.GetOOTurbulenceDistance() * distFac + scaledT);
|
||||||
|
curX += info.x18_rippleResolution;
|
||||||
|
}
|
||||||
|
curY += info.x18_rippleResolution;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyRipple(const CFluidPlaneCPURender::SRippleInfo& rippleInfo,
|
||||||
|
CFluidPlaneCPURender::SHFieldSample (&heights)[45][45],
|
||||||
|
u8 (&flags)[9][9], const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info)
|
||||||
|
{
|
||||||
|
float lookupT = 256.f * (1.f - rippleInfo.x0_ripple.GetTime() * rippleInfo.x0_ripple.GetOOTimeFalloff() *
|
||||||
|
rippleInfo.x0_ripple.GetOOTimeFalloff()) * rippleInfo.x0_ripple.GetFrequency();
|
||||||
|
auto lifeIdx = int(64.f * rippleInfo.x0_ripple.GetTime() * rippleInfo.x0_ripple.GetOOTimeFalloff());
|
||||||
|
float distMul = rippleInfo.x0_ripple.GetDistanceFalloff() / 255.f;
|
||||||
|
float minDist = CFluidPlaneManager::RippleMins[lifeIdx] * distMul;
|
||||||
|
float minDistSq = minDist * minDist;
|
||||||
|
if (minDistSq != 0.f)
|
||||||
|
minDist = std::sqrt(minDistSq);
|
||||||
|
float maxDist = CFluidPlaneManager::RippleMaxs[lifeIdx] * distMul;
|
||||||
|
float maxDistSq = maxDist * maxDist;
|
||||||
|
if (maxDistSq != 0.f)
|
||||||
|
maxDist = std::sqrt(maxDistSq);
|
||||||
|
int fromY = (rippleInfo.x1c_gfromY + CFluidPlaneCPURender::numSubdivisionsInTile - 1) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
int fromX = (rippleInfo.x14_gfromX + CFluidPlaneCPURender::numSubdivisionsInTile - 1) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
int toY = (rippleInfo.x20_gtoY + CFluidPlaneCPURender::numSubdivisionsInTile - 1) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
int toX = (rippleInfo.x18_gtoX + CFluidPlaneCPURender::numSubdivisionsInTile - 1) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
|
||||||
|
float curY = rippleInfo.x0_ripple.GetCenter().y - info.xc_globalMin.y -
|
||||||
|
(0.5f * info.x14_rippleSideLen + (fromY - 1) * info.x14_rippleSideLen);
|
||||||
|
int curGridY = info.x2a_gridDimX * (info.x2e_tileY + fromY - 1);
|
||||||
|
int startGridX = (info.x28_tileX + fromX - 1);
|
||||||
|
int gridCells = info.x2a_gridDimX * info.x2c_gridDimY;
|
||||||
|
float f11 = 64.f * rippleInfo.x0_ripple.GetOODistanceFalloff();
|
||||||
|
int curYDiv = rippleInfo.xc_fromY;
|
||||||
|
|
||||||
|
for (int i=fromY ; i<=toY ; ++i, curY -= info.x14_rippleSideLen)
|
||||||
|
{
|
||||||
|
int nextYDiv = (i+1) * CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
float curYSq = curY * curY;
|
||||||
|
int curGridX = startGridX;
|
||||||
|
int curXDiv = rippleInfo.x4_fromX;
|
||||||
|
float curX = rippleInfo.x0_ripple.GetCenter().x - info.xc_globalMin.x -
|
||||||
|
(0.5f * info.x14_rippleSideLen + (fromX - 1) * info.x14_rippleSideLen);
|
||||||
|
for (int j=fromX ; j<=toX ; ++j, curX -= info.x14_rippleSideLen, ++curGridX)
|
||||||
|
{
|
||||||
|
float dist = curX * curX + curYSq;
|
||||||
|
if (dist != 0.f)
|
||||||
|
dist = std::sqrt(dist);
|
||||||
|
if (maxDist < dist - info.x1c_rippleHypRadius || minDist > dist + info.x1c_rippleHypRadius)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool addedRipple = false;
|
||||||
|
int nextXDiv = (j+1) * CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
float curXMod =
|
||||||
|
(rippleInfo.x0_ripple.GetCenter().x - info.xc_globalMin.x) - info.x18_rippleResolution * curXDiv;
|
||||||
|
float curYMod =
|
||||||
|
(rippleInfo.x0_ripple.GetCenter().y - info.xc_globalMin.y) - info.x18_rippleResolution * curYDiv;
|
||||||
|
|
||||||
|
if (!info.x30_gridFlags || (info.x30_gridFlags && curGridY >= 0 && curGridY < gridCells && curGridX >= 0 &&
|
||||||
|
curGridX < info.x2a_gridDimX && info.x30_gridFlags[curGridX + curGridY]))
|
||||||
|
{
|
||||||
|
for (int k=curYDiv ; k<=std::min(rippleInfo.x10_toY, nextYDiv-1) ; ++k,
|
||||||
|
curYMod -= info.x18_rippleResolution)
|
||||||
|
{
|
||||||
|
float tmpXMod = curXMod;
|
||||||
|
float curYModSq = curYMod * curYMod;
|
||||||
|
for (int l=curXDiv ; l<=std::min(rippleInfo.x8_toX, nextXDiv-1) ; ++l,
|
||||||
|
tmpXMod -= info.x18_rippleResolution)
|
||||||
|
{
|
||||||
|
float divDistSq = tmpXMod * tmpXMod + curYModSq;
|
||||||
|
if (divDistSq < minDistSq || divDistSq > maxDistSq)
|
||||||
|
continue;
|
||||||
|
float divDist = (divDistSq != 0.f) ? std::sqrt(divDistSq) : 0.f;
|
||||||
|
if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)])
|
||||||
|
{
|
||||||
|
heights[k][l].f1 += val * rippleInfo.x0_ripple.GetAmplitude() *
|
||||||
|
sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + lookupT)];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
heights[k][l].f1 += 0.f;
|
||||||
|
}
|
||||||
|
addedRipple = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addedRipple)
|
||||||
|
flags[i][j] = 0x1f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int yMin = nextYDiv - 1;
|
||||||
|
int yMax = nextYDiv - CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||||
|
int xMin = nextXDiv - 1;
|
||||||
|
int xMax = nextXDiv - CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||||
|
|
||||||
|
if (curGridX >= 0.f && curGridX < info.x2a_gridDimX && curGridY - info.x2a_gridDimX >= 0 &&
|
||||||
|
!info.x30_gridFlags[curGridX + curGridY - info.x2a_gridDimX])
|
||||||
|
yMax -= 2;
|
||||||
|
|
||||||
|
if (curGridX >= 0.f && curGridX < info.x2a_gridDimX && curGridY + info.x2a_gridDimX < gridCells &&
|
||||||
|
!info.x30_gridFlags[curGridX + info.x2a_gridDimX])
|
||||||
|
yMin += 2;
|
||||||
|
|
||||||
|
if (curGridY >= 0 && curGridY < info.x2c_gridDimY && curGridX > 0 &&
|
||||||
|
!info.x30_gridFlags[curGridX - 1])
|
||||||
|
xMax -= 2;
|
||||||
|
|
||||||
|
if (curGridY >= 0 && curGridY < info.x2c_gridDimY && curGridX + 1 < info.x2a_gridDimX &&
|
||||||
|
!info.x30_gridFlags[curGridX + 1])
|
||||||
|
xMin += 2;
|
||||||
|
|
||||||
|
for (int k=curYDiv ; k<=std::min(rippleInfo.x10_toY, nextYDiv-1) ; ++k,
|
||||||
|
curYMod -= info.x18_rippleResolution)
|
||||||
|
{
|
||||||
|
float tmpXMod = curXMod;
|
||||||
|
float curYModSq = curYMod * curYMod;
|
||||||
|
for (int l=curXDiv ; l<=std::min(rippleInfo.x8_toX, nextXDiv-1) ; ++l,
|
||||||
|
tmpXMod -= info.x18_rippleResolution)
|
||||||
|
{
|
||||||
|
if (k <= yMax || k >= yMin || l <= xMax || l >= xMin)
|
||||||
|
{
|
||||||
|
float divDistSq = tmpXMod * tmpXMod + curYModSq;
|
||||||
|
if (divDistSq < minDistSq || divDistSq > maxDistSq)
|
||||||
|
continue;
|
||||||
|
float divDist = (divDistSq != 0.f) ? std::sqrt(divDistSq) : 0.f;
|
||||||
|
if (u8 val = CFluidPlaneManager::RippleValues[lifeIdx][int(divDist * f11)])
|
||||||
|
{
|
||||||
|
heights[k][l].f1 += val * rippleInfo.x0_ripple.GetAmplitude() *
|
||||||
|
sineWave[int(divDist * rippleInfo.x0_ripple.GetLookupPhase() + lookupT)];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
heights[k][l].f1 += 0.f;
|
||||||
|
}
|
||||||
|
addedRipple = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addedRipple)
|
||||||
|
flags[i][j] = 0xf;
|
||||||
|
}
|
||||||
|
curXDiv = nextXDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
curYDiv = nextYDiv;
|
||||||
|
curGridY += info.x2a_gridDimX;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ApplyRipples(const rstl::reserved_vector<CFluidPlaneCPURender::SRippleInfo, 32>& rippleInfos,
|
||||||
|
CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], u8 (&flags)[9][9],
|
||||||
|
const float sineWave[256], const CFluidPlaneCPURender::SPatchInfo& info)
|
||||||
|
{
|
||||||
|
for (const CFluidPlaneCPURender::SRippleInfo& rippleInfo : rippleInfos)
|
||||||
|
ApplyRipple(rippleInfo, heights, flags, sineWave, info);
|
||||||
|
for (int i=0 ; i<CFluidPlaneCPURender::numTilesInHField ; ++i)
|
||||||
|
flags[0][i+1] |= 1;
|
||||||
|
for (int i=0 ; i<CFluidPlaneCPURender::numTilesInHField ; ++i)
|
||||||
|
flags[i+1][0] |= 8;
|
||||||
|
for (int i=0 ; i<CFluidPlaneCPURender::numTilesInHField ; ++i)
|
||||||
|
flags[i+1][CFluidPlaneCPURender::numTilesInHField+1] |= 4;
|
||||||
|
for (int i=0 ; i<CFluidPlaneCPURender::numTilesInHField ; ++i)
|
||||||
|
flags[CFluidPlaneCPURender::numTilesInHField+1][i+1] |= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdatePatchNormal(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) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile ; ++i)
|
||||||
|
{
|
||||||
|
int r10 = i * CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||||
|
int r9 = std::max(0, r10 - CFluidPlaneCPURender::numSubdivisionsInTile);
|
||||||
|
int x24 = std::min(r10, info.x1_ySubdivs + 1);
|
||||||
|
for (int j=1 ; j <= (info.x0_xSubdivs + CFluidPlaneCPURender::numSubdivisionsInTile - 2) /
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile ; ++j)
|
||||||
|
{
|
||||||
|
int r29 = j * CFluidPlaneCPURender::numSubdivisionsInTile + 1;
|
||||||
|
int r11 = std::max(0, r29 - CFluidPlaneCPURender::numSubdivisionsInTile);
|
||||||
|
int x28 = std::min(r29, info.x0_xSubdivs + 1);
|
||||||
|
if ((flags[i][j] & 0x1f) == 0x1f)
|
||||||
|
{
|
||||||
|
for (int k=r9 ; k<x24 ; ++k)
|
||||||
|
{
|
||||||
|
for (int l=r11 ; l<x28 ; ++l)
|
||||||
|
{
|
||||||
|
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][l];
|
||||||
|
if (sample.f1 > 0.f)
|
||||||
|
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||||
|
else
|
||||||
|
sample.f2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i > 0 && i < CFluidPlaneCPURender::numTilesInHField + 1 &&
|
||||||
|
r10 > 0 && r10 < CFluidPlaneCPURender::numTilesInHField + 1)
|
||||||
|
{
|
||||||
|
int halfSubdivs = CFluidPlaneCPURender::numSubdivisionsInTile / 2;
|
||||||
|
CFluidPlaneCPURender::SHFieldSample& sample = heights[halfSubdivs + r9][halfSubdivs + r11];
|
||||||
|
if (sample.f1 > 0.f)
|
||||||
|
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||||
|
else
|
||||||
|
sample.f2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
for (int k=r11 ; k<x28 ; ++k)
|
||||||
|
{
|
||||||
|
CFluidPlaneCPURender::SHFieldSample& sample = heights[i][k];
|
||||||
|
if (sample.f1 > 0.f)
|
||||||
|
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||||
|
else
|
||||||
|
sample.f2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j != 0)
|
||||||
|
{
|
||||||
|
for (int k=r9+1 ; k<x24 ; ++k)
|
||||||
|
{
|
||||||
|
CFluidPlaneCPURender::SHFieldSample& sample = heights[k][r11];
|
||||||
|
if (sample.f1 > 0.f)
|
||||||
|
sample.f2 = u8(std::min(255, int(info.x38_tileSize * sample.f1)));
|
||||||
|
else
|
||||||
|
sample.f2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdatePatchSubdivided(const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45], const u8 (&flags)[9][9],
|
||||||
|
const CFluidPlaneCPURender::SPatchInfo& info)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool UpdatePatch(float time, const CFluidPlaneCPURender::SPatchInfo& info, const CFluidPlaneCPU& fluidPane,
|
||||||
|
const zeus::CVector3f& areaCenter,
|
||||||
|
const std::experimental::optional<CRippleManager>& rippleManager,
|
||||||
|
int fromX, int toX, int fromY, int toY)
|
||||||
|
{
|
||||||
|
rstl::reserved_vector<CFluidPlaneCPURender::SRippleInfo, 32> rippleInfos;
|
||||||
|
if (rippleManager)
|
||||||
|
{
|
||||||
|
for (const CRipple& ripple : rippleManager->GetRipples())
|
||||||
|
{
|
||||||
|
if (ripple.GetTime() >= ripple.GetTimeFalloff())
|
||||||
|
continue;
|
||||||
|
CFluidPlaneCPURender::SRippleInfo rippleInfo(ripple, fromX, toX, fromY, toY);
|
||||||
|
if (PrepareRipple(ripple, info, rippleInfo))
|
||||||
|
rippleInfos.push_back(rippleInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rippleInfos.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
CFluidPlaneCPURender::SHFieldSample heights[45][45];
|
||||||
|
u8 flags[9][9] = {};
|
||||||
|
ApplyTurbulence(time, heights, flags, sGlobalSineWave, info, fluidPane, areaCenter);
|
||||||
|
ApplyRipples(rippleInfos, heights, flags, sGlobalSineWave, info);
|
||||||
|
if (info.x37_renderMode == CFluidPlaneCPURender::RenderMode::Normal)
|
||||||
|
UpdatePatchNormal(heights, flags, info);
|
||||||
|
else
|
||||||
|
UpdatePatchSubdivided(heights, flags, info);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, bool updateResult)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||||
const zeus::CTransform& areaXf, bool noSubdiv, const zeus::CFrustum& frustum,
|
const zeus::CTransform& areaXf, bool noSubdiv, const zeus::CFrustum& frustum,
|
||||||
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||||
|
@ -296,7 +718,123 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
{
|
{
|
||||||
TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(waterId);
|
TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(waterId);
|
||||||
RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, areaXf, aabb, water.GetPtr());
|
RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, areaXf, aabb, water.GetPtr());
|
||||||
m_shader->draw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale, setupInfo.lights, setupInfo.kColors);
|
|
||||||
|
CFluidPlaneCPURender::RenderMode renderMode;
|
||||||
|
if (xb0_bumpMap && kEnableWaterBumpMaps)
|
||||||
|
renderMode = CFluidPlaneCPURender::RenderMode::BumpMapped;
|
||||||
|
else if (!noSubdiv)
|
||||||
|
renderMode = CFluidPlaneCPURender::RenderMode::Subdivided;
|
||||||
|
else
|
||||||
|
renderMode = CFluidPlaneCPURender::RenderMode::Normal;
|
||||||
|
|
||||||
|
// Set Position and color format
|
||||||
|
|
||||||
|
switch (renderMode)
|
||||||
|
{
|
||||||
|
case CFluidPlaneCPURender::RenderMode::BumpMapped:
|
||||||
|
// Set NBT format
|
||||||
|
break;
|
||||||
|
case CFluidPlaneCPURender::RenderMode::Subdivided:
|
||||||
|
// Set Normal format
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rippleResolutionRecip = 1.f / x108_rippleResolution;
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile = x104_tileSubdivisions;
|
||||||
|
CFluidPlaneCPURender::numTilesInHField = std::min(7, 42 / CFluidPlaneCPURender::numSubdivisionsInTile);
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInHField =
|
||||||
|
CFluidPlaneCPURender::numTilesInHField * CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
|
|
||||||
|
zeus::CVector3f aabbCenter = aabb.center();
|
||||||
|
zeus::CVector2f center2D(aabbCenter.x, aabbCenter.y);
|
||||||
|
zeus::CVector2f ripplePitch(x108_rippleResolution * CFluidPlaneCPURender::numSubdivisionsInHField);
|
||||||
|
|
||||||
|
bool r14 = false;
|
||||||
|
int r22 = 0;
|
||||||
|
int r23 = 0;
|
||||||
|
float rippleSideLen = g_tweakGame->GetRippleSideLengthNormal();
|
||||||
|
switch (x44_fluidType)
|
||||||
|
{
|
||||||
|
case EFluidType::PoisonWater:
|
||||||
|
rippleSideLen = g_tweakGame->GetRippleSideLengthPoison();
|
||||||
|
r14 = true;
|
||||||
|
r23 = 1;
|
||||||
|
break;
|
||||||
|
case EFluidType::Lava:
|
||||||
|
case EFluidType::Five:
|
||||||
|
rippleSideLen = g_tweakGame->GetRippleSideLengthLava();
|
||||||
|
r23 = 8;
|
||||||
|
r22 = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (water)
|
||||||
|
{
|
||||||
|
float cameraPenetration =
|
||||||
|
mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation().dot(zeus::CVector3f::skUp) -
|
||||||
|
water->GetTriggerBoundsWR().max.z;
|
||||||
|
rippleSideLen *= (cameraPenetration >= 0.5f || cameraPenetration < 0.f) ? 1.f : 2.f * cameraPenetration;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 patchDimX = (water && water->GetPatchDimensionX()) ? water->GetPatchDimensionX() : 128;
|
||||||
|
u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128;
|
||||||
|
|
||||||
|
u32 tileY = 0;
|
||||||
|
float curY = aabb.min.y;
|
||||||
|
for (int i=0 ; curY < aabb.max.y && i<patchDimY ; ++i)
|
||||||
|
{
|
||||||
|
u32 tileX = 0;
|
||||||
|
float curX = aabb.min.x;
|
||||||
|
float _remDivsY = (aabb.max.y - curY) * rippleResolutionRecip;
|
||||||
|
for (int j=0 ; curX < aabb.max.x && j<patchDimX ; ++j)
|
||||||
|
{
|
||||||
|
if (water->CanRenderPatch(j, i))
|
||||||
|
{
|
||||||
|
s16 remDivsX = std::min(s16((aabb.max.x - curX) * rippleResolutionRecip),
|
||||||
|
s16(CFluidPlaneCPURender::numSubdivisionsInHField));
|
||||||
|
s16 remDivsY = std::min(s16(_remDivsY), s16(CFluidPlaneCPURender::numSubdivisionsInHField));
|
||||||
|
zeus::CVector3f localMax(x108_rippleResolution * remDivsX + curX,
|
||||||
|
x108_rippleResolution * remDivsY + curY, aabb.max.z);
|
||||||
|
zeus::CVector3f localMin(curX, curY, aabb.min.z);
|
||||||
|
zeus::CAABox testaabb(localMin + xf.origin, localMax + xf.origin);
|
||||||
|
if (frustum.aabbFrustumTest(testaabb))
|
||||||
|
{
|
||||||
|
CFluidPlaneCPURender::SPatchInfo info(localMin, localMax, xf.origin, x108_rippleResolution,
|
||||||
|
rippleSideLen, x100_tileSize,
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInHField, renderMode,
|
||||||
|
r14, r22, r23, tileX, gridDimX, gridDimY, tileY, gridFlags);
|
||||||
|
|
||||||
|
int fromX = tileX != 0 ? (2 - CFluidPlaneCPURender::numSubdivisionsInTile) : 0;
|
||||||
|
int toX;
|
||||||
|
if (tileX != gridDimX - 1)
|
||||||
|
toX = info.x0_xSubdivs + (CFluidPlaneCPURender::numSubdivisionsInTile - 2);
|
||||||
|
else
|
||||||
|
toX = info.x0_xSubdivs;
|
||||||
|
|
||||||
|
int fromY = tileY != 0 ? (2 - CFluidPlaneCPURender::numSubdivisionsInTile) : 0;
|
||||||
|
int toY;
|
||||||
|
if (tileY != gridDimY - 1)
|
||||||
|
toY = info.x1_ySubdivs + (CFluidPlaneCPURender::numSubdivisionsInTile - 2);
|
||||||
|
else
|
||||||
|
toY = info.x1_ySubdivs;
|
||||||
|
|
||||||
|
bool result = UpdatePatch(mgr.GetFluidPlaneManager()->GetUVT(), info, *this, areaCenter,
|
||||||
|
rippleManager, fromX, toX, fromY, toY);
|
||||||
|
RenderPatch(info, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curX += ripplePitch.x;
|
||||||
|
tileX += CFluidPlaneCPURender::numTilesInHField;
|
||||||
|
}
|
||||||
|
curY += ripplePitch.y;
|
||||||
|
tileY += CFluidPlaneCPURender::numTilesInHField;
|
||||||
|
}
|
||||||
|
|
||||||
|
//m_shader->draw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale, setupInfo.lights, setupInfo.kColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFluidPlaneCPU::RenderCleanup() const
|
void CFluidPlaneCPU::RenderCleanup() const
|
||||||
|
|
|
@ -66,11 +66,12 @@ class CFluidPlaneCPU : public CFluidPlane
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texColor, ResId bumpMap, ResId envMap, ResId envBumpMap,
|
CFluidPlaneCPU(ResId texPattern1, ResId texPattern2, ResId texColor, ResId bumpMap, ResId envMap, ResId envBumpMap,
|
||||||
ResId unkMap, float unitsPerLightmapTexel, float tileSize, u32 tileSubdivisions, EFluidType fluidType, float alpha,
|
ResId lightMap, float unitsPerLightmapTexel, float tileSize, u32 tileSubdivisions,
|
||||||
const zeus::CVector3f& bumpLightDir, float bumpScale, const CFluidUVMotion& mot, float turbSpeed,
|
EFluidType fluidType, float alpha, const zeus::CVector3f& bumpLightDir, float bumpScale,
|
||||||
float turbDistance, float turbFreqMax, float turbFreqMin, float turbPhaseMax, float turbPhaseMin,
|
const CFluidUVMotion& mot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||||
float turbAmplitudeMax, float turbAmplitudeMin, float specularMin, float specularMax,
|
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
|
||||||
float reflectionBlend, float reflectionSize, float fluidPlaneF2);
|
float turbAmplitudeMin, float specularMin, float specularMax, float reflectionBlend,
|
||||||
|
float reflectionSize, float fluidPlaneF2);
|
||||||
void CreateRipple(const CRipple& ripple, CStateManager& mgr);
|
void CreateRipple(const CRipple& ripple, CStateManager& mgr);
|
||||||
void CalculateLightmapMatrix(const zeus::CTransform& areaXf, const zeus::CTransform& xf,
|
void CalculateLightmapMatrix(const zeus::CTransform& areaXf, const zeus::CTransform& xf,
|
||||||
const zeus::CAABox& aabb, zeus::CMatrix4f& mtxOut) const;
|
const zeus::CAABox& aabb, zeus::CMatrix4f& mtxOut) const;
|
||||||
|
|
|
@ -878,7 +878,7 @@ void CPlayer::CalculateRenderBounds()
|
||||||
if (x2f8_morphTransState == EPlayerMorphBallState::Morphed)
|
if (x2f8_morphTransState == EPlayerMorphBallState::Morphed)
|
||||||
{
|
{
|
||||||
float rad = x768_morphball->GetBallRadius();
|
float rad = x768_morphball->GetBallRadius();
|
||||||
x9c_aabox = zeus::CAABox(GetTranslation() - zeus::CVector3f(rad, rad, 0.f),
|
x9c_renderBounds = zeus::CAABox(GetTranslation() - zeus::CVector3f(rad, rad, 0.f),
|
||||||
GetTranslation() + zeus::CVector3f(rad, rad, rad * 2.f));
|
GetTranslation() + zeus::CVector3f(rad, rad, rad * 2.f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,5 +1,28 @@
|
||||||
#include "CRipple.hpp"
|
#include "CRipple.hpp"
|
||||||
|
#include "CRandom16.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
CRipple::CRipple(TUniqueId, const zeus::CVector3f&, float) {}
|
static CRandom16 sRippleRandom(0xABBA);
|
||||||
|
|
||||||
|
CRipple::CRipple(TUniqueId id, const zeus::CVector3f& center, float intensity)
|
||||||
|
: x0_id(id), x8_center(center)
|
||||||
|
{
|
||||||
|
if (intensity >= 0.f && intensity <= 1.f)
|
||||||
|
{
|
||||||
|
float tmp =
|
||||||
|
2.f * std::min(1.f, std::max(0.f, intensity * (sRippleRandom.Float() - 0.5f) * 2.f * 0.1f + intensity));
|
||||||
|
x14_timeFalloff = 0.5f * tmp + 1.5f;
|
||||||
|
x18_distFalloff = 4.f * tmp + 8.f;
|
||||||
|
x1c_frequency = 2.f + tmp;
|
||||||
|
x20_ = 0.15f * tmp + 0.1f;
|
||||||
|
x24_amplitude = x20_ / 255.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
x28_ooTimeFalloff = 1.f / x14_timeFalloff;
|
||||||
|
x2c_ooDistFalloff = 1.f / x18_distFalloff;
|
||||||
|
x30_ooPhase = x18_distFalloff / 2.5f;
|
||||||
|
x34_phase = 1.f / x30_ooPhase;
|
||||||
|
x38_lookupPhase = 256.f * x34_phase;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,26 +11,33 @@ class CRipple
|
||||||
private:
|
private:
|
||||||
TUniqueId x0_id;
|
TUniqueId x0_id;
|
||||||
float x4_time = 0.f;
|
float x4_time = 0.f;
|
||||||
zeus::CVector3f x8_;
|
zeus::CVector3f x8_center;
|
||||||
float x14_ = 2.f;
|
float x14_timeFalloff = 2.f;
|
||||||
float x18_ = 12.f;
|
float x18_distFalloff = 12.f;
|
||||||
float x1c_ = 3.f;
|
float x1c_frequency = 3.f;
|
||||||
float x20_ = 0.25f;
|
float x20_ = 0.25f;
|
||||||
float x24_ = 0.00098039221f;
|
float x24_amplitude = 0.00098039221f;
|
||||||
|
float x28_ooTimeFalloff = 0.f;
|
||||||
|
float x2c_ooDistFalloff = 0.f;
|
||||||
|
float x30_ooPhase = 0.f;
|
||||||
|
float x34_phase = 0.f;
|
||||||
|
float x38_lookupPhase = 0.f;
|
||||||
|
u32 x3c_ = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRipple(TUniqueId, const zeus::CVector3f&, float);
|
CRipple(TUniqueId id, const zeus::CVector3f& center, float intensity);
|
||||||
|
|
||||||
void SetTime(float t) { x4_time = t; }
|
void SetTime(float t) { x4_time = t; }
|
||||||
float GetTime() const { return x4_time; }
|
float GetTime() const { return x4_time; }
|
||||||
float GetTimeFalloff() const;
|
float GetTimeFalloff() const { return x14_timeFalloff; }
|
||||||
TUniqueId GetUniqueId() const { return x0_id; }
|
TUniqueId GetUniqueId() const { return x0_id; }
|
||||||
float GetFequency() const;
|
float GetFrequency() const { return x1c_frequency; }
|
||||||
float GetAmplitude() const;
|
float GetAmplitude() const { return x24_amplitude; }
|
||||||
float GetOODistanceFalloff() const;
|
float GetOODistanceFalloff() const { return x2c_ooDistFalloff; }
|
||||||
float GetDistanceFalloff() const;
|
float GetDistanceFalloff() const { return x18_distFalloff; }
|
||||||
zeus::CVector3f GetCenter() const;
|
const zeus::CVector3f& GetCenter() const { return x8_center; }
|
||||||
float GetOOTimeFalloff() const;
|
float GetOOTimeFalloff() const { return x28_ooTimeFalloff; }
|
||||||
|
float GetLookupPhase() const { return x38_lookupPhase; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif // __URDE_CRIPPLE_HPP__
|
#endif // __URDE_CRIPPLE_HPP__
|
||||||
|
|
|
@ -21,16 +21,6 @@ void CRippleManager::SetTime(float)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRippleManager::Ripples()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRippleManager::GetRipples() const
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRippleManager::Update(float dt)
|
void CRippleManager::Update(float dt)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ public:
|
||||||
CRippleManager(int maxRipples, float);
|
CRippleManager(int maxRipples, float);
|
||||||
void Init(int maxRipples);
|
void Init(int maxRipples);
|
||||||
void SetTime(float);
|
void SetTime(float);
|
||||||
void Ripples();
|
std::vector<CRipple>& Ripples() { return x4_ripples; }
|
||||||
void GetRipples() const;
|
const std::vector<CRipple>& GetRipples() const { return x4_ripples; }
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
float GetLastRippleDeltaTime(TUniqueId rippler) const;
|
float GetLastRippleDeltaTime(TUniqueId rippler) const;
|
||||||
void AddRipple(const CRipple& ripple);
|
void AddRipple(const CRipple& ripple);
|
||||||
|
@ -26,5 +26,5 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
;
|
||||||
#endif // __URDE_CRIPPLEMANAGER_HPP__
|
#endif // __URDE_CRIPPLEMANAGER_HPP__
|
||||||
|
|
|
@ -45,7 +45,7 @@ void CScriptPointOfInterest::CalculateRenderBounds()
|
||||||
if (xe8_pointSize == 0.f)
|
if (xe8_pointSize == 0.f)
|
||||||
CActor::CalculateRenderBounds();
|
CActor::CalculateRenderBounds();
|
||||||
else
|
else
|
||||||
x9c_aabox = zeus::CAABox(x34_transform.origin - xe8_pointSize, x34_transform.origin + xe8_pointSize);
|
x9c_renderBounds = zeus::CAABox(x34_transform.origin - xe8_pointSize, x34_transform.origin + xe8_pointSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
rstl::optional_object<zeus::CAABox> CScriptPointOfInterest::GetTouchBounds() const
|
rstl::optional_object<zeus::CAABox> CScriptPointOfInterest::GetTouchBounds() const
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "CScriptWater.hpp"
|
#include "CScriptWater.hpp"
|
||||||
#include "CStateManager.hpp"
|
#include "CStateManager.hpp"
|
||||||
#include "TCastTo.hpp"
|
#include "TCastTo.hpp"
|
||||||
|
#include "GameGlobalObjects.hpp"
|
||||||
|
#include "CSimplePool.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -13,15 +15,97 @@ const float CScriptWater::kSplashScales[6] =
|
||||||
|
|
||||||
CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string& name, const CEntityInfo& info,
|
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,
|
const zeus::CVector3f& pos, const zeus::CAABox& box, const urde::CDamageInfo& dInfo,
|
||||||
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool b1, bool b2, ResId, ResId, ResId,
|
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool b1, bool b2,
|
||||||
ResId, ResId, ResId, ResId, const zeus::CVector3f&, float, float, float, bool active,
|
ResId patternMap1, ResId patternMap2, ResId colorMap, ResId bumpMap, ResId envMap,
|
||||||
CFluidPlane::EFluidType, bool, float, const CFluidUVMotion&, float, float, float, float,
|
ResId envBumpMap, ResId unusedMap, const zeus::CVector3f& bumpLightDir, float bumpScale,
|
||||||
float, float, float, float, const zeus::CColor&, const zeus::CColor&, ResId, ResId, ResId,
|
float f2, float f3, bool active, CFluidPlane::EFluidType fluidType, bool b4, float alpha,
|
||||||
ResId, ResId, s32, s32, s32, s32, s32, float, u32, float, float, float, float, float, float,
|
const CFluidUVMotion& uvMot, float turbSpeed, float turbDistance, float turbFreqMax,
|
||||||
float, float, const zeus::CColor&, urde::ResId, float, float, float, u32, u32, bool, s32,
|
float turbFreqMin, float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax,
|
||||||
s32, const u32*)
|
float turbAmplitudeMin, const zeus::CColor& c1, const zeus::CColor& c2, ResId splashParticle1,
|
||||||
: CScriptTrigger(uid, name, info, pos, box, dInfo, orientedForce, triggerFlags, active, false, false)
|
ResId splashParticle2, ResId splashParticle3, ResId particle4, ResId particle5, s32 i1,
|
||||||
|
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)
|
||||||
|
: 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),
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
u32Arr.reset();
|
||||||
|
x264_splashEffects.resize(3);
|
||||||
|
if (x22c_splashParticle1Id != kInvalidResId)
|
||||||
|
x264_splashEffects[0].emplace(g_SimplePool->GetObj({FOURCC('PART'), x22c_splashParticle1Id}));
|
||||||
|
if (x230_splashParticle2Id != kInvalidResId)
|
||||||
|
x264_splashEffects[1].emplace(g_SimplePool->GetObj({FOURCC('PART'), x230_splashParticle2Id}));
|
||||||
|
if (x234_splashParticle3Id != kInvalidResId)
|
||||||
|
x264_splashEffects[2].emplace(g_SimplePool->GetObj({FOURCC('PART'), x234_splashParticle3Id}));
|
||||||
|
if (x238_particle4Id != kInvalidResId)
|
||||||
|
x23c_.emplace(g_SimplePool->GetObj({FOURCC('PART'), x238_particle4Id}));
|
||||||
|
if (x24c_particle5Id != kInvalidResId)
|
||||||
|
x250_visorRunoffEffect.emplace(g_SimplePool->GetObj({FOURCC('PART'), x24c_particle5Id}));
|
||||||
|
x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx1));
|
||||||
|
x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx2));
|
||||||
|
x298_splashSounds.push_back(CSfxManager::TranslateSFXID(splashSfx3));
|
||||||
|
SetCalculateLighting(true);
|
||||||
|
if (lightmapId != kInvalidResId)
|
||||||
|
x90_actorLights->DisableAreaLights();
|
||||||
|
x90_actorLights->SetMaxDynamicLights(4);
|
||||||
|
x90_actorLights->SetCastShadows(false);
|
||||||
|
x90_actorLights->SetAmbientChannelOverflow(false);
|
||||||
|
x90_actorLights->SetFindNearestDynamicLights(true);
|
||||||
|
x148_24_playerInside = true;
|
||||||
|
CalculateRenderBounds();
|
||||||
|
xe6_27_ = u8(b1 ? 2 : 1);
|
||||||
|
if (!x30_24_active)
|
||||||
|
{
|
||||||
|
x2bc_alpha = 0.f;
|
||||||
|
x214_ = 0.f;
|
||||||
|
x218_ = 0.f;
|
||||||
|
}
|
||||||
|
SetupGrid(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptWater::SetupGrid(bool b)
|
||||||
|
{
|
||||||
|
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]);
|
||||||
|
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 bool[32]);
|
||||||
|
for (int i=0 ; i<32 ; ++i)
|
||||||
|
x2e0_patchFlags[i] = true;
|
||||||
|
x2d4_patchDimY = 0;
|
||||||
|
x2d0_patchDimX = 0;
|
||||||
|
x2e8_28 = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptWater::Think(float dt, CStateManager& mgr) { CScriptTrigger::Think(dt, mgr); }
|
void CScriptWater::Think(float dt, CStateManager& mgr) { CScriptTrigger::Think(dt, mgr); }
|
||||||
|
@ -50,7 +134,13 @@ void CScriptWater::Touch(CActor&, CStateManager&)
|
||||||
|
|
||||||
void CScriptWater::CalculateRenderBounds()
|
void CScriptWater::CalculateRenderBounds()
|
||||||
{
|
{
|
||||||
|
zeus::CVector3f aabbMin = x130_bounds.min;
|
||||||
|
aabbMin.z = x130_bounds.max.z - 1.f;
|
||||||
|
zeus::CVector3f aabbMax = x130_bounds.max;
|
||||||
|
aabbMax.z += 1.f;
|
||||||
|
zeus::CVector3f transAABBMin = aabbMin + GetTranslation();
|
||||||
|
zeus::CVector3f transAABBMax = aabbMax + GetTranslation();
|
||||||
|
x9c_renderBounds = zeus::CAABox(transAABBMin, transAABBMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CAABox CScriptWater::GetSortingBounds(const CStateManager&) const
|
zeus::CAABox CScriptWater::GetSortingBounds(const CStateManager&) const
|
||||||
|
@ -65,12 +155,12 @@ EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus:
|
||||||
|
|
||||||
s16 CScriptWater::GetSplashSound(float dt) const
|
s16 CScriptWater::GetSplashSound(float dt) const
|
||||||
{
|
{
|
||||||
return x29c_splashSounds[GetSplashIndex(dt)];
|
return x298_splashSounds[GetSplashIndex(dt)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const TLockedToken<CParticleGen>& CScriptWater::GetSplashEffect(float dt) const
|
const std::experimental::optional<TLockedToken<CGenDescription>>& CScriptWater::GetSplashEffect(float dt) const
|
||||||
{
|
{
|
||||||
return x268_splashEffects[GetSplashIndex(dt)];
|
return x264_splashEffects[GetSplashIndex(dt)];
|
||||||
}
|
}
|
||||||
|
|
||||||
float CScriptWater::GetSplashEffectScale(float dt) const
|
float CScriptWater::GetSplashEffectScale(float dt) const
|
||||||
|
|
|
@ -13,12 +13,17 @@ class CScriptWater : public CScriptTrigger
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static const float kSplashScales[6];
|
static const float kSplashScales[6];
|
||||||
u32 x150_ = 0;
|
zeus::CFrustum x150_frustum;
|
||||||
std::unique_ptr<CFluidPlaneCPU> x1b4_fluidPlane;
|
std::unique_ptr<CFluidPlaneCPU> x1b4_fluidPlane;
|
||||||
zeus::CVector3f x1b8_;
|
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 x1f4_;
|
||||||
float x1f8_lightmapDoubleBlendFactor = 0.f;
|
float x1f8_lightmapDoubleBlendFactor = 0.f;
|
||||||
zeus::CVector3f x1d4_;
|
|
||||||
std::list<std::pair<TUniqueId, bool>> x1fc_waterInhabitants;
|
std::list<std::pair<TUniqueId, bool>> x1fc_waterInhabitants;
|
||||||
u32 x210_;
|
u32 x210_;
|
||||||
float x214_;
|
float x214_;
|
||||||
|
@ -27,46 +32,65 @@ private:
|
||||||
float x220_;
|
float x220_;
|
||||||
float x224_;
|
float x224_;
|
||||||
zeus::CColor x228_;
|
zeus::CColor x228_;
|
||||||
u32 x22c_;
|
ResId x22c_splashParticle1Id;
|
||||||
u32 x230_;
|
ResId x230_splashParticle2Id;
|
||||||
u32 x234_;
|
ResId x234_splashParticle3Id;
|
||||||
u32 x238_;
|
ResId x238_particle4Id;
|
||||||
u32 x248_;
|
std::experimental::optional<TLockedToken<CGenDescription>> x23c_;
|
||||||
u32 x24c_;
|
ResId x24c_particle5Id;
|
||||||
std::experimental::optional<TLockedToken<CGenDescription>> x250_visorRunoffEffect;
|
std::experimental::optional<TLockedToken<CGenDescription>> x250_visorRunoffEffect;
|
||||||
u16 x260_;
|
u16 x260_;
|
||||||
u16 x262_visorRunoffSfx;
|
u16 x262_visorRunoffSfx;
|
||||||
u32 x264_ = 0;
|
rstl::reserved_vector<std::experimental::optional<TLockedToken<CGenDescription>>, 3> x264_splashEffects;
|
||||||
TLockedToken<CParticleGen> x268_splashEffects[5];
|
rstl::reserved_vector<u16, 3> x298_splashSounds;
|
||||||
u16 x29c_splashSounds[5];
|
zeus::CColor x2a4_c1;
|
||||||
u32 x2c0_tesselationSize;
|
zeus::CColor x2a8_c2;
|
||||||
|
float x2ac_lf2;
|
||||||
|
float x2b0_lf3;
|
||||||
|
float x2b4_;
|
||||||
|
float x2b8_;
|
||||||
|
float x2bc_alpha;
|
||||||
|
float x2c0_tileSize;
|
||||||
u32 x2c4_gridDimX = 0;
|
u32 x2c4_gridDimX = 0;
|
||||||
u32 x2c8_gridDimY = 0;
|
u32 x2c8_gridDimY = 0;
|
||||||
u32 x2cc_gridCellCount = 0;
|
u32 x2cc_gridCellCount = 0;
|
||||||
|
u32 x2d0_patchDimX = 0;
|
||||||
|
u32 x2d4_patchDimY = 0;
|
||||||
std::unique_ptr<bool[]> x2d8_gridFlags;
|
std::unique_ptr<bool[]> x2d8_gridFlags;
|
||||||
std::unique_ptr<bool[]> x2e0_;
|
std::unique_ptr<bool[]> x2dc_;
|
||||||
|
std::unique_ptr<bool[]> x2e0_patchFlags;
|
||||||
u32 x2e4_gridCellCount2 = 0;
|
u32 x2e4_gridCellCount2 = 0;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
bool x2e8_24 : 1;
|
bool x2e8_24_b4 : 1;
|
||||||
bool x2e8_25 : 1;
|
bool x2e8_25 : 1;
|
||||||
bool x2e8_26 : 1;
|
bool x2e8_26 : 1;
|
||||||
bool x2e8_27 : 1;
|
bool x2e8_27_b2 : 1;
|
||||||
bool x2e8_28 : 1;
|
bool x2e8_28 : 1;
|
||||||
|
bool x2e8_29 : 1;
|
||||||
|
bool x2e8_30 : 1;
|
||||||
};
|
};
|
||||||
u32 _dummy = 0;
|
u32 _dummy = 0;
|
||||||
};
|
};
|
||||||
void SetupGrid(bool b);
|
void SetupGrid(bool b);
|
||||||
public:
|
public:
|
||||||
CScriptWater(CStateManager&, TUniqueId, const std::string& name, const CEntityInfo&, const zeus::CVector3f&,
|
CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string& name, const CEntityInfo& info,
|
||||||
const zeus::CAABox&, CDamageInfo const&, zeus::CVector3f&, ETriggerFlags, bool, bool, ResId, ResId, ResId, ResId,
|
const zeus::CVector3f& pos, const zeus::CAABox& box, const urde::CDamageInfo& dInfo,
|
||||||
ResId, ResId, ResId, const zeus::CVector3f&, float, float, float, bool, CFluidPlane::EFluidType, bool,
|
zeus::CVector3f& orientedForce, ETriggerFlags triggerFlags, bool b1, bool b2,
|
||||||
float, const CFluidUVMotion&, float, float, float, float, float, float, float, float,
|
ResId patternMap1, ResId patternMap2, ResId colorMap, ResId bumpMap, ResId envMap,
|
||||||
const zeus::CColor&, const zeus::CColor&, ResId, ResId, ResId, ResId, ResId, s32, s32, s32, s32, s32,
|
ResId envBumpMap, ResId unusedMap, const zeus::CVector3f& bumpLightDir, float bumpScale,
|
||||||
float, u32, float, float, float, float, float, float, float, float, const zeus::CColor&, ResId, float,
|
float f2, float f3, bool active, CFluidPlane::EFluidType fluidType, bool b4, float alpha,
|
||||||
float, float, u32, u32, bool, s32, s32, const u32*);
|
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,
|
||||||
|
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);
|
||||||
|
|
||||||
void Think(float, CStateManager&);
|
void Think(float, CStateManager&);
|
||||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
|
@ -82,7 +106,7 @@ public:
|
||||||
|
|
||||||
void UpdateSplashInhabitants(CStateManager&);
|
void UpdateSplashInhabitants(CStateManager&);
|
||||||
s16 GetSplashSound(float) const;
|
s16 GetSplashSound(float) const;
|
||||||
const TLockedToken<CParticleGen>& GetSplashEffect(float) const;
|
const std::experimental::optional<TLockedToken<CGenDescription>>& GetSplashEffect(float) const;
|
||||||
float GetSplashEffectScale(float) const;
|
float GetSplashEffectScale(float) const;
|
||||||
u32 GetSplashIndex(float) const;
|
u32 GetSplashIndex(float) const;
|
||||||
void FluidPlane();
|
void FluidPlane();
|
||||||
|
@ -99,6 +123,9 @@ public:
|
||||||
u16 GetVisorRunoffSfx() const { return x262_visorRunoffSfx; }
|
u16 GetVisorRunoffSfx() const { return x262_visorRunoffSfx; }
|
||||||
const CScriptWater* GetNextConnectedWater(const CStateManager& mgr) const;
|
const CScriptWater* GetNextConnectedWater(const CStateManager& mgr) const;
|
||||||
float GetLightmapDoubleBlendFactor() const { return x1f8_lightmapDoubleBlendFactor; }
|
float GetLightmapDoubleBlendFactor() const { return x1f8_lightmapDoubleBlendFactor; }
|
||||||
|
bool CanRenderPatch(int x, int y) const { return x2e0_patchFlags[y * x2d0_patchDimX + x]; }
|
||||||
|
u32 GetPatchDimensionX() const { return x2d0_patchDimX; }
|
||||||
|
u32 GetPatchDimensionY() const { return x2d4_patchDimY; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1272,7 +1272,7 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
|
||||||
u32 w22 = in.readUint32Big();
|
u32 w22 = in.readUint32Big();
|
||||||
bool b5 = in.readBool();
|
bool b5 = in.readBool();
|
||||||
|
|
||||||
u32* bitset = nullptr;
|
std::unique_ptr<u32[]> bitset;
|
||||||
u32 bitVal0 = 0;
|
u32 bitVal0 = 0;
|
||||||
u32 bitVal1 = 0;
|
u32 bitVal1 = 0;
|
||||||
|
|
||||||
|
@ -1281,8 +1281,8 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
|
||||||
bitVal0 = in.readUint16Big();
|
bitVal0 = in.readUint16Big();
|
||||||
bitVal1 = in.readUint16Big();
|
bitVal1 = in.readUint16Big();
|
||||||
u32 len = ((bitVal0 * bitVal1) + 31) / 31;
|
u32 len = ((bitVal0 * bitVal1) + 31) / 31;
|
||||||
bitset = new u32[len];
|
bitset.reset(new u32[len]);
|
||||||
in.readBytesToBuf(&bitset, len * 4);
|
in.readBytesToBuf(bitset.get(), len * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CAABox box(-extent * 0.5f, extent * 0.5f);
|
zeus::CAABox box(-extent * 0.5f, extent * 0.5f);
|
||||||
|
@ -1300,7 +1300,8 @@ CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propC
|
||||||
textureId1, textureId2, textureId3, textureId4, realTextureId5, realTextureId6, -1, otherV2, f1, f2, f3, active,
|
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,
|
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,
|
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, bitset);
|
heatWaveHeight, heatWaveSpeed, heatWaveColor, lightmap, f22, f23, f24, w21, w22, b5, bitVal0, bitVal1,
|
||||||
|
std::move(bitset));
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadWarWasp(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
CEntity* ScriptLoader::LoadWarWasp(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||||
|
|
Loading…
Reference in New Issue