mirror of https://github.com/AxioDL/metaforce.git
Implement CFluidPlaneDoor and CScriptDamageableTrigger
This commit is contained in:
parent
02f8f77b57
commit
086ff76474
|
@ -2,7 +2,7 @@
|
||||||
<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">
|
<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" />
|
<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,-cppcoreguidelines-pro-type-vararg" />
|
||||||
</inspection_tool>
|
</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" />
|
||||||
|
|
|
@ -15,6 +15,9 @@ struct ITweakGame : ITweak
|
||||||
virtual float GetWavecapIntensityNormal() const = 0;
|
virtual float GetWavecapIntensityNormal() const = 0;
|
||||||
virtual float GetWavecapIntensityPoison() const = 0;
|
virtual float GetWavecapIntensityPoison() const = 0;
|
||||||
virtual float GetWavecapIntensityLava() const = 0;
|
virtual float GetWavecapIntensityLava() const = 0;
|
||||||
|
virtual float GetRippleIntensityNormal() const = 0;
|
||||||
|
virtual float GetRippleIntensityPoison() const = 0;
|
||||||
|
virtual float GetRippleIntensityLava() 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;
|
||||||
|
|
|
@ -17,38 +17,38 @@ struct DamageableTrigger : IScriptObject
|
||||||
Value<atVec3f> volume;
|
Value<atVec3f> volume;
|
||||||
HealthInfo healthInfo;
|
HealthInfo healthInfo;
|
||||||
DamageVulnerability damageVulnerabilty;
|
DamageVulnerability damageVulnerabilty;
|
||||||
Value<atUint32> unknown1;
|
Value<atUint32> faceFlag;
|
||||||
UniqueID32 texture1;
|
UniqueID32 patternTex1;
|
||||||
UniqueID32 texture2;
|
UniqueID32 patternTex2;
|
||||||
UniqueID32 texture3;
|
UniqueID32 colorTex;
|
||||||
Value<bool> lockOn;
|
Value<bool> lockOn;
|
||||||
Value<bool> active;
|
Value<bool> active;
|
||||||
VisorParameters visorParameters;
|
VisorParameters visorParameters;
|
||||||
|
|
||||||
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const
|
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const
|
||||||
{
|
{
|
||||||
if (texture1)
|
if (patternTex1)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternTex1);
|
||||||
ent->name = name + "_texture1";
|
ent->name = name + "_patternTex1";
|
||||||
}
|
}
|
||||||
if (texture2)
|
if (patternTex2)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternTex2);
|
||||||
ent->name = name + "_texture2";
|
ent->name = name + "_patternTex2";
|
||||||
}
|
}
|
||||||
if (texture3)
|
if (colorTex)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture3);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorTex);
|
||||||
ent->name = name + "_texture3";
|
ent->name = name + "_colorTex";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
|
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
|
||||||
{
|
{
|
||||||
g_curSpec->flattenDependencies(texture1, pathsOut);
|
g_curSpec->flattenDependencies(patternTex1, pathsOut);
|
||||||
g_curSpec->flattenDependencies(texture2, pathsOut);
|
g_curSpec->flattenDependencies(patternTex2, pathsOut);
|
||||||
g_curSpec->flattenDependencies(texture3, pathsOut);
|
g_curSpec->flattenDependencies(colorTex, pathsOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
|
zeus::CAABox getVISIAABB(hecl::BlenderToken& btok) const
|
||||||
|
|
|
@ -84,7 +84,7 @@ struct Water : IScriptObject
|
||||||
Value<float> fogBias;
|
Value<float> fogBias;
|
||||||
Value<float> fogMagnitude;
|
Value<float> fogMagnitude;
|
||||||
Value<float> fogSpeed;
|
Value<float> fogSpeed;
|
||||||
Value<atVec4f> fogColor; // CColor
|
Value<atVec4f> fogColor;
|
||||||
UniqueID32 lightmap;
|
UniqueID32 lightmap;
|
||||||
Value<float> unitsPerLightmapTexel;
|
Value<float> unitsPerLightmapTexel;
|
||||||
Value<float> alphaInTime;
|
Value<float> alphaInTime;
|
||||||
|
@ -116,52 +116,52 @@ struct Water : IScriptObject
|
||||||
if (patternMap1)
|
if (patternMap1)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap1);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap1);
|
||||||
ent->name = name + "_tex1";
|
ent->name = name + "_patternMap1";
|
||||||
}
|
}
|
||||||
if (patternMap2)
|
if (patternMap2)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap2);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap2);
|
||||||
ent->name = name + "_tex2";
|
ent->name = name + "_patternMap2";
|
||||||
}
|
}
|
||||||
if (colorMap)
|
if (colorMap)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorMap);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorMap);
|
||||||
ent->name = name + "_tex3";
|
ent->name = name + "_colorMap";
|
||||||
}
|
}
|
||||||
if (bumpMap)
|
if (bumpMap)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(bumpMap);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(bumpMap);
|
||||||
ent->name = name + "_tex4";
|
ent->name = name + "_bumpMap";
|
||||||
}
|
}
|
||||||
if (envMap)
|
if (envMap)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envMap);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envMap);
|
||||||
ent->name = name + "_tex5";
|
ent->name = name + "_envMap";
|
||||||
}
|
}
|
||||||
if (envBumpMap)
|
if (envBumpMap)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envBumpMap);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envBumpMap);
|
||||||
ent->name = name + "_tex6";
|
ent->name = name + "_envBumpMap";
|
||||||
}
|
}
|
||||||
if (lightmap)
|
if (lightmap)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(lightmap);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(lightmap);
|
||||||
ent->name = name + "_tex34";
|
ent->name = name + "_lightmap";
|
||||||
}
|
}
|
||||||
if (splashParticle1)
|
if (splashParticle1)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle1);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle1);
|
||||||
ent->name = name + "_part1";
|
ent->name = name + "_splashParticle1";
|
||||||
}
|
}
|
||||||
if (splashParticle2)
|
if (splashParticle2)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle2);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle2);
|
||||||
ent->name = name + "_part2";
|
ent->name = name + "_splashParticle2";
|
||||||
}
|
}
|
||||||
if (splashParticle3)
|
if (splashParticle3)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle3);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle3);
|
||||||
ent->name = name + "_part3";
|
ent->name = name + "_splashParticle3";
|
||||||
}
|
}
|
||||||
if (particle4)
|
if (particle4)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,9 +23,9 @@ struct CTweakGame : ITweakGame
|
||||||
Value<float> x34_wavecapIntensityNormal;
|
Value<float> x34_wavecapIntensityNormal;
|
||||||
Value<float> x38_wavecapIntensityPoison;
|
Value<float> x38_wavecapIntensityPoison;
|
||||||
Value<float> x3c_wavecapIntensityLava;
|
Value<float> x3c_wavecapIntensityLava;
|
||||||
Value<float> x40_unknown10;
|
Value<float> x40_rippleIntensityNormal;
|
||||||
Value<float> x44_unknown11;
|
Value<float> x44_rippleIntentityPoison;
|
||||||
Value<float> x48_unknown12;
|
Value<float> x48_rippleIntensityLava;
|
||||||
Value<float> x4c_fluidEnvBumpScale;
|
Value<float> x4c_fluidEnvBumpScale;
|
||||||
Value<float> x50_unknown14;
|
Value<float> x50_unknown14;
|
||||||
Value<float> x54_unknown15;
|
Value<float> x54_unknown15;
|
||||||
|
@ -41,6 +41,9 @@ struct CTweakGame : ITweakGame
|
||||||
float GetWavecapIntensityNormal() const { return x34_wavecapIntensityNormal; }
|
float GetWavecapIntensityNormal() const { return x34_wavecapIntensityNormal; }
|
||||||
float GetWavecapIntensityPoison() const { return x38_wavecapIntensityPoison; }
|
float GetWavecapIntensityPoison() const { return x38_wavecapIntensityPoison; }
|
||||||
float GetWavecapIntensityLava() const { return x3c_wavecapIntensityLava; }
|
float GetWavecapIntensityLava() const { return x3c_wavecapIntensityLava; }
|
||||||
|
float GetRippleIntensityNormal() const { return x40_rippleIntensityNormal; }
|
||||||
|
float GetRippleIntensityPoison() const { return x44_rippleIntentityPoison; }
|
||||||
|
float GetRippleIntensityLava() const { return x48_rippleIntensityLava; }
|
||||||
float GetFluidEnvBumpScale() const { return x4c_fluidEnvBumpScale; }
|
float GetFluidEnvBumpScale() const { return x4c_fluidEnvBumpScale; }
|
||||||
float GetHardModeDamageMultiplier() const { return x60_hardmodeDamageMult; }
|
float GetHardModeDamageMultiplier() const { return x60_hardmodeDamageMult; }
|
||||||
float GetHardModeWeaponMultiplier() const { return x64_hardmodeWeaponMult; }
|
float GetHardModeWeaponMultiplier() const { return x64_hardmodeWeaponMult; }
|
||||||
|
|
|
@ -1576,7 +1576,7 @@ void CStateManager::TestBombHittingWater(const CActor& damager, const zeus::CVec
|
||||||
{
|
{
|
||||||
float bombMag = powerBomb ? 1.f : 0.75f;
|
float bombMag = powerBomb ? 1.f : 0.75f;
|
||||||
float mag = 0.6f * bombMag + 0.4f * bombMag * std::sin(2.f * M_PIF * rippleFactor * 0.25f);
|
float mag = 0.6f * bombMag + 0.4f * bombMag * std::sin(2.f * M_PIF * rippleFactor * 0.25f);
|
||||||
water->GetFluidPlane().Ripple(mag, damager.GetUniqueId(), hitPos, *water, *this);
|
water->GetFluidPlane().AddRipple(mag, damager.GetUniqueId(), hitPos, *water, *this);
|
||||||
}
|
}
|
||||||
if (!powerBomb)
|
if (!powerBomb)
|
||||||
x87c_fluidPlaneManager->CreateSplash(damager.GetUniqueId(), *this, *water, hitPos, rippleFactor, true);
|
x87c_fluidPlaneManager->CreateSplash(damager.GetUniqueId(), *this, *water, hitPos, rippleFactor, true);
|
||||||
|
@ -1594,7 +1594,7 @@ void CStateManager::TestBombHittingWater(const CActor& damager, const zeus::CVec
|
||||||
{
|
{
|
||||||
// Not blocked by static geometry
|
// Not blocked by static geometry
|
||||||
float mag = 0.6f * bombMag + 0.4f * bombMag * std::sin(2.f * M_PIF * -delta / bombMag * 0.25f);
|
float mag = 0.6f * bombMag + 0.4f * bombMag * std::sin(2.f * M_PIF * -delta / bombMag * 0.25f);
|
||||||
water->GetFluidPlane().Ripple(mag, damager.GetUniqueId(), hitPos, *water, *this);
|
water->GetFluidPlane().AddRipple(mag, damager.GetUniqueId(), hitPos, *water, *this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,10 +74,25 @@ u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::IShaderPipeline* CFluidPlaneShader::Cache::GetOrBuildShader(const SFluidPlaneShaderInfo& info)
|
u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneDoorShaderInfo& info)
|
||||||
|
{
|
||||||
|
u16 ret = 0;
|
||||||
|
|
||||||
|
if (info.m_hasPatternTex1)
|
||||||
|
ret |= 1 << 0;
|
||||||
|
if (info.m_hasPatternTex2)
|
||||||
|
ret |= 1 << 1;
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
ret |= 1 << 2;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
boo::IShaderPipeline* CFluidPlaneShader::Cache::GetOrBuildShader(const T& info)
|
||||||
{
|
{
|
||||||
u16 key = MakeCacheKey(info);
|
u16 key = MakeCacheKey(info);
|
||||||
auto& slot = m_cache[key];
|
auto& slot = CacheSlot(info, key);
|
||||||
if (slot.second != nullptr)
|
if (slot.second != nullptr)
|
||||||
return slot.second;
|
return slot.second;
|
||||||
|
|
||||||
|
@ -116,6 +131,60 @@ boo::IShaderPipeline* CFluidPlaneShader::Cache::GetOrBuildShader(const SFluidPla
|
||||||
return slot.second;
|
return slot.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template boo::IShaderPipeline*
|
||||||
|
CFluidPlaneShader::Cache::GetOrBuildShader<SFluidPlaneShaderInfo>(const SFluidPlaneShaderInfo& info);
|
||||||
|
template boo::IShaderPipeline*
|
||||||
|
CFluidPlaneShader::Cache::GetOrBuildShader<SFluidPlaneDoorShaderInfo>(const SFluidPlaneDoorShaderInfo& info);
|
||||||
|
|
||||||
|
void CFluidPlaneShader::Cache::Clear()
|
||||||
|
{
|
||||||
|
for (auto& p : m_cache)
|
||||||
|
{
|
||||||
|
p.first.doDestroy();
|
||||||
|
p.second = nullptr;
|
||||||
|
}
|
||||||
|
for (auto& p : m_doorCache)
|
||||||
|
{
|
||||||
|
p.first.doDestroy();
|
||||||
|
p.second = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFluidPlaneShader::PrepareBinding(boo::IShaderPipeline* pipeline, u32 maxVertCount, bool door)
|
||||||
|
{
|
||||||
|
m_gfxTok = CGraphics::CommitResources(
|
||||||
|
[&](boo::IGraphicsDataFactory::Context& ctx)
|
||||||
|
{
|
||||||
|
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount);
|
||||||
|
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, 1024, 1);
|
||||||
|
|
||||||
|
switch (ctx.platform())
|
||||||
|
{
|
||||||
|
case boo::IGraphicsDataFactory::Platform::OpenGL:
|
||||||
|
m_dataBind = BuildBinding(static_cast<boo::GLDataFactory::Context&>(ctx), pipeline, door);
|
||||||
|
break;
|
||||||
|
#if _WIN32
|
||||||
|
case boo::IGraphicsDataFactory::Platform::D3D11:
|
||||||
|
case boo::IGraphicsDataFactory::Platform::D3D12:
|
||||||
|
m_dataBind = BuildBinding(static_cast<boo::ID3DDataFactory::Context&>(ctx), pipeline, door);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if BOO_HAS_METAL
|
||||||
|
case boo::IGraphicsDataFactory::Platform::Metal:
|
||||||
|
m_dataBind = BuildBinding(static_cast<boo::MetalDataFactory::Context&>(ctx), pipeline, door);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#if BOO_HAS_VULKAN
|
||||||
|
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
||||||
|
m_dataBind = BuildBinding(static_cast<boo::VulkanDataFactory::Context&>(ctx), pipeline, door);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
||||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||||
|
@ -143,54 +212,37 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
|
||||||
m_lightmap.operator bool(),
|
m_lightmap.operator bool(),
|
||||||
doubleLightmapBlend, additive);
|
doubleLightmapBlend, additive);
|
||||||
boo::IShaderPipeline* pipeline = _cache.GetOrBuildShader(shaderInfo);
|
boo::IShaderPipeline* pipeline = _cache.GetOrBuildShader(shaderInfo);
|
||||||
|
PrepareBinding(pipeline, maxVertCount, false);
|
||||||
m_gfxTok = CGraphics::CommitResources(
|
|
||||||
[&](boo::IGraphicsDataFactory::Context& ctx)
|
|
||||||
{
|
|
||||||
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount);
|
|
||||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, 1024, 1);
|
|
||||||
|
|
||||||
switch (ctx.platform())
|
|
||||||
{
|
|
||||||
case boo::IGraphicsDataFactory::Platform::OpenGL:
|
|
||||||
m_dataBind = BuildBinding(static_cast<boo::GLDataFactory::Context&>(ctx), pipeline);
|
|
||||||
break;
|
|
||||||
#if _WIN32
|
|
||||||
case boo::IGraphicsDataFactory::Platform::D3D11:
|
|
||||||
case boo::IGraphicsDataFactory::Platform::D3D12:
|
|
||||||
m_dataBind = BuildBinding(static_cast<boo::ID3DDataFactory::Context&>(ctx), pipeline);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if BOO_HAS_METAL
|
|
||||||
case boo::IGraphicsDataFactory::Platform::Metal:
|
|
||||||
m_dataBind = BuildBinding(static_cast<boo::MetalDataFactory::Context&>(ctx), pipeline);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#if BOO_HAS_VULKAN
|
|
||||||
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
|
||||||
m_dataBind = BuildBinding(static_cast<boo::VulkanDataFactory::Context&>(ctx), pipeline);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFluidPlaneShader::prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
|
CFluidPlaneShader::CFluidPlaneShader(const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||||
const std::vector<CLight>& lights, const zeus::CColor* kColors)
|
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||||
|
const std::experimental::optional<TLockedToken<CTexture>>& colorTex,
|
||||||
|
u32 maxVertCount)
|
||||||
|
: m_patternTex1(patternTex1),
|
||||||
|
m_patternTex2(patternTex2),
|
||||||
|
m_colorTex(colorTex)
|
||||||
|
{
|
||||||
|
SFluidPlaneDoorShaderInfo shaderInfo(m_patternTex1.operator bool(),
|
||||||
|
m_patternTex2.operator bool(),
|
||||||
|
m_colorTex.operator bool());
|
||||||
|
boo::IShaderPipeline* pipeline = _cache.GetOrBuildShader(shaderInfo);
|
||||||
|
PrepareBinding(pipeline, maxVertCount, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFluidPlaneShader::prepareDraw(const RenderSetupInfo& info)
|
||||||
{
|
{
|
||||||
Uniform& uni = *reinterpret_cast<Uniform*>(m_uniBuf->map(sizeof(Uniform)));
|
Uniform& uni = *reinterpret_cast<Uniform*>(m_uniBuf->map(sizeof(Uniform)));
|
||||||
uni.m_mv = CGraphics::g_GXModelView.toMatrix4f();
|
uni.m_mv = CGraphics::g_GXModelView.toMatrix4f();
|
||||||
uni.m_mvNorm = normMtx;
|
uni.m_mvNorm = info.normMtx;
|
||||||
uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true);
|
uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true);
|
||||||
for (int i=0 ; i<6 ; ++i)
|
for (int i=0 ; i<6 ; ++i)
|
||||||
uni.m_texMtxs[i] = texMtxs[i];
|
uni.m_texMtxs[i] = info.texMtxs[i];
|
||||||
uni.m_lighting.ActivateLights(lights);
|
uni.m_lighting.ActivateLights(info.lights);
|
||||||
for (int i=0 ; i<3 ; ++i)
|
for (int i=0 ; i<3 ; ++i)
|
||||||
uni.m_lighting.colorRegs[i] = kColors[i];
|
uni.m_lighting.colorRegs[i] = info.kColors[i];
|
||||||
uni.m_lighting.mulColor = kColors[3];
|
uni.m_lighting.mulColor = info.kColors[3];
|
||||||
uni.m_lighting.fog.m_rangeScale = indScale;
|
uni.m_lighting.fog.m_rangeScale = info.indScale;
|
||||||
m_uniBuf->unmap();
|
m_uniBuf->unmap();
|
||||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,17 @@ struct SFluidPlaneShaderInfo
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SFluidPlaneDoorShaderInfo
|
||||||
|
{
|
||||||
|
bool m_hasPatternTex1;
|
||||||
|
bool m_hasPatternTex2;
|
||||||
|
bool m_hasColorTex;
|
||||||
|
|
||||||
|
SFluidPlaneDoorShaderInfo(bool hasPatternTex1, bool hasPatternTex2, bool hasColorTex)
|
||||||
|
: m_hasPatternTex1(hasPatternTex1), m_hasPatternTex2(hasPatternTex2), m_hasColorTex(hasColorTex)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
class CFluidPlaneShader
|
class CFluidPlaneShader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -59,13 +70,30 @@ public:
|
||||||
: m_pos(position), m_norm(normal), m_binorm(binormal), m_tangent(tangent), m_color(color) {}
|
: m_pos(position), m_norm(normal), m_binorm(binormal), m_tangent(tangent), m_color(color) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RenderSetupInfo
|
||||||
|
{
|
||||||
|
zeus::CMatrix4f texMtxs[6];
|
||||||
|
zeus::CMatrix4f normMtx;
|
||||||
|
float indScale = 1.f;
|
||||||
|
zeus::CColor kColors[4];
|
||||||
|
std::vector<CLight> lights;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Cache
|
class Cache
|
||||||
{
|
{
|
||||||
std::pair<boo::GraphicsDataToken, boo::IShaderPipeline*> m_cache[1024] = {};
|
std::pair<boo::GraphicsDataToken, boo::IShaderPipeline*> m_cache[1024] = {};
|
||||||
|
std::pair<boo::GraphicsDataToken, boo::IShaderPipeline*> m_doorCache[8] = {};
|
||||||
|
std::pair<boo::GraphicsDataToken, boo::IShaderPipeline*>&
|
||||||
|
CacheSlot(const SFluidPlaneShaderInfo& info, int i) { return m_cache[i]; }
|
||||||
|
std::pair<boo::GraphicsDataToken, boo::IShaderPipeline*>&
|
||||||
|
CacheSlot(const SFluidPlaneDoorShaderInfo& info, int i) { return m_doorCache[i]; }
|
||||||
static u16 MakeCacheKey(const SFluidPlaneShaderInfo& info);
|
static u16 MakeCacheKey(const SFluidPlaneShaderInfo& info);
|
||||||
|
static u16 MakeCacheKey(const SFluidPlaneDoorShaderInfo& info);
|
||||||
public:
|
public:
|
||||||
boo::IShaderPipeline* GetOrBuildShader(const SFluidPlaneShaderInfo& info);
|
template<class T>
|
||||||
|
boo::IShaderPipeline* GetOrBuildShader(const T& info);
|
||||||
|
void Clear();
|
||||||
};
|
};
|
||||||
static Cache _cache;
|
static Cache _cache;
|
||||||
|
|
||||||
|
@ -91,20 +119,25 @@ private:
|
||||||
boo::IShaderDataBinding* m_dataBind;
|
boo::IShaderDataBinding* m_dataBind;
|
||||||
|
|
||||||
static boo::IShaderPipeline* BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
static boo::IShaderPipeline* BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
||||||
boo::IShaderDataBinding* BuildBinding(boo::GLDataFactory::Context& ctx, boo::IShaderPipeline* pipeline);
|
static boo::IShaderPipeline* BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info);
|
||||||
|
boo::IShaderDataBinding* BuildBinding(boo::GLDataFactory::Context& ctx, boo::IShaderPipeline* pipeline, bool door);
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
static boo::IShaderPipeline* BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
static boo::IShaderPipeline* BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
||||||
boo::IShaderDataBinding* BuildBinding(boo::ID3DDataFactory::Context& ctx, boo::IShaderPipeline* pipeline);
|
static boo::IShaderPipeline* BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info);
|
||||||
|
boo::IShaderDataBinding* BuildBinding(boo::ID3DDataFactory::Context& ctx, boo::IShaderPipeline* pipeline, bool door);
|
||||||
#endif
|
#endif
|
||||||
#if BOO_HAS_METAL
|
#if BOO_HAS_METAL
|
||||||
static boo::IShaderPipeline* BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
static boo::IShaderPipeline* BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
||||||
boo::IShaderDataBinding* BuildBinding(boo::MetalDataFactory::Context& ctx, boo::IShaderPipeline* pipeline);
|
static boo::IShaderPipeline* BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info);
|
||||||
|
boo::IShaderDataBinding* BuildBinding(boo::MetalDataFactory::Context& ctx, boo::IShaderPipeline* pipeline, bool door);
|
||||||
#endif
|
#endif
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
static boo::IShaderPipeline* BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
static boo::IShaderPipeline* BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info);
|
||||||
boo::IShaderDataBinding* BuildBinding(boo::VulkanDataFactory::Context& ctx, boo::IShaderPipeline* pipeline);
|
static boo::IShaderPipeline* BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info);
|
||||||
|
boo::IShaderDataBinding* BuildBinding(boo::VulkanDataFactory::Context& ctx, boo::IShaderPipeline* pipeline, bool door);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void PrepareBinding(boo::IShaderPipeline* pipeline, u32 maxVertCount, bool door);
|
||||||
public:
|
public:
|
||||||
CFluidPlaneShader(CFluidPlane::EFluidType type,
|
CFluidPlaneShader(CFluidPlane::EFluidType type,
|
||||||
const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||||
|
@ -115,9 +148,14 @@ public:
|
||||||
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
|
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
|
||||||
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
|
const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
|
||||||
bool doubleLightmapBlend, bool additive, u32 maxVertCount);
|
bool doubleLightmapBlend, bool additive, u32 maxVertCount);
|
||||||
void prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
|
CFluidPlaneShader(const std::experimental::optional<TLockedToken<CTexture>>& patternTex1,
|
||||||
const std::vector<CLight>& lights, const zeus::CColor* kColors);
|
const std::experimental::optional<TLockedToken<CTexture>>& patternTex2,
|
||||||
|
const std::experimental::optional<TLockedToken<CTexture>>& colorTex,
|
||||||
|
u32 maxVertCount);
|
||||||
|
void prepareDraw(const RenderSetupInfo& info);
|
||||||
void loadVerts(const std::vector<Vertex>& verts);
|
void loadVerts(const std::vector<Vertex>& verts);
|
||||||
|
|
||||||
|
static void Shutdown() { _cache.Clear(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,6 +115,28 @@ BOO_GLSL_BINDING_HEAD
|
||||||
"%s" // Combiner expression here
|
"%s" // Combiner expression here
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FSDoor =
|
||||||
|
"#version 330\n"
|
||||||
|
BOO_GLSL_BINDING_HEAD
|
||||||
|
"\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 mvPos;\n"
|
||||||
|
" vec4 mvNorm;\n"
|
||||||
|
" vec4 mvBinorm;\n"
|
||||||
|
" vec4 mvTangent;\n"
|
||||||
|
" vec4 color;\n"
|
||||||
|
" vec2 uvs[7];\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"SBINDING(0) in VertToFrag vtf;\n"
|
||||||
|
"layout(location=0) out vec4 colorOut;\n"
|
||||||
|
"%s" // Textures here
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
"%s" // Combiner expression here
|
||||||
|
"}\n";
|
||||||
|
|
||||||
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[7],
|
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[7],
|
||||||
const SFluidPlaneShaderInfo& info)
|
const SFluidPlaneShaderInfo& info)
|
||||||
{
|
{
|
||||||
|
@ -442,6 +464,51 @@ static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTe
|
||||||
finalFS = hecl::Format(FS, textures.c_str(), combiner.c_str());
|
finalFS = hecl::Format(FS, textures.c_str(), combiner.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _BuildShader(std::string& finalVS, std::string& finalFS, int& nextTex, const char* texNames[3],
|
||||||
|
const SFluidPlaneDoorShaderInfo& info)
|
||||||
|
{
|
||||||
|
std::string additionalTCGs;
|
||||||
|
std::string textures;
|
||||||
|
std::string combiner;
|
||||||
|
|
||||||
|
if (info.m_hasPatternTex1)
|
||||||
|
{
|
||||||
|
texNames[nextTex] = "patternTex1";
|
||||||
|
textures += hecl::Format("TBINDING%d uniform sampler2D patternTex1;\n", nextTex++);
|
||||||
|
}
|
||||||
|
if (info.m_hasPatternTex2)
|
||||||
|
{
|
||||||
|
texNames[nextTex] = "patternTex2";
|
||||||
|
textures += hecl::Format("TBINDING%d uniform sampler2D patternTex2;\n", nextTex++);
|
||||||
|
}
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
{
|
||||||
|
texNames[nextTex] = "colorTex";
|
||||||
|
textures += hecl::Format("TBINDING%d uniform sampler2D colorTex;\n", nextTex++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tex0 * kColor0 * Tex1 + Tex2
|
||||||
|
if (info.m_hasPatternTex1 && info.m_hasPatternTex2)
|
||||||
|
{
|
||||||
|
combiner += " colorOut = texture(patternTex1, vtf.uvs[0]) * kColor0 *\n"
|
||||||
|
" texture(patternTex2, vtf.uvs[1]);\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
combiner += " colorOut = vec4(0.0);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
{
|
||||||
|
combiner += " colorOut += texture(colorTex, vtf.uvs[2]);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
|
finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
||||||
|
finalFS = hecl::Format(FSDoor, textures.c_str(), combiner.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
boo::IShaderPipeline*
|
boo::IShaderPipeline*
|
||||||
CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
||||||
{
|
{
|
||||||
|
@ -457,6 +524,20 @@ CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPla
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::IShaderPipeline*
|
||||||
|
CFluidPlaneShader::BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info)
|
||||||
|
{
|
||||||
|
int nextTex = 0;
|
||||||
|
const char* texNames[3] = {};
|
||||||
|
std::string finalVS, finalFS;
|
||||||
|
_BuildShader(finalVS, finalFS, nextTex, texNames, info);
|
||||||
|
const char* uniNames[] = {"FluidPlaneUniform"};
|
||||||
|
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), size_t(nextTex), texNames, 1, uniNames,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
|
boo::CullMode::None);
|
||||||
|
}
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
static boo::IVertexFormat* s_vtxFmt = nullptr;
|
static boo::IVertexFormat* s_vtxFmt = nullptr;
|
||||||
|
|
||||||
|
@ -486,10 +567,36 @@ CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx, const SFlui
|
||||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::IShaderPipeline*
|
||||||
|
CFluidPlaneShader::BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info)
|
||||||
|
{
|
||||||
|
if (s_vtxFmt == nullptr)
|
||||||
|
{
|
||||||
|
boo::VertexElementDescriptor elements[] =
|
||||||
|
{
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 0},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 1},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 2},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Color}
|
||||||
|
};
|
||||||
|
s_vtxFmt = ctx.newVertexFormat(5, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextTex = 0;
|
||||||
|
const char* texNames[3] = {};
|
||||||
|
std::string finalVS, finalFS;
|
||||||
|
_BuildShader(finalVS, finalFS, nextTex, texNames, info);
|
||||||
|
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), s_vtxFmt,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
|
boo::CullMode::None);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::GLDataFactory::Context& ctx,
|
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::GLDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline* pipeline)
|
boo::IShaderPipeline* pipeline, bool door)
|
||||||
{
|
{
|
||||||
boo::VertexElementDescriptor elements[] =
|
boo::VertexElementDescriptor elements[] =
|
||||||
{
|
{
|
||||||
|
@ -521,13 +628,13 @@ boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::GLDataFactory::Con
|
||||||
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
||||||
if (m_lightmap)
|
if (m_lightmap)
|
||||||
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
||||||
return ctx.newShaderDataBinding(pipeline, vtxFmt, m_vbo, nullptr, nullptr, 1, ubufs, ubufStages, ubufOffs,
|
return ctx.newShaderDataBinding(pipeline, vtxFmt, m_vbo, nullptr, nullptr, door ? 1 : 3,
|
||||||
ubufSizes, texCount, texs, nullptr, nullptr);
|
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BOO_HAS_VULKAN
|
#if BOO_HAS_VULKAN
|
||||||
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::VulkanDataFactory::Context& ctx,
|
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::VulkanDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline* pipeline)
|
boo::IShaderPipeline* pipeline, bool door)
|
||||||
{
|
{
|
||||||
boo::IGraphicsBuffer* ubufs[] = { m_uniBuf, m_uniBuf, m_uniBuf };
|
boo::IGraphicsBuffer* ubufs[] = { m_uniBuf, m_uniBuf, m_uniBuf };
|
||||||
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
||||||
|
@ -550,8 +657,8 @@ boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::VulkanDataFactory:
|
||||||
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
||||||
if (m_lightmap)
|
if (m_lightmap)
|
||||||
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
||||||
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo, nullptr, nullptr, 1, ubufs, ubufStages, ubufOffs,
|
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo, nullptr, nullptr, door ? 1 : 3,
|
||||||
ubufSizes, texCount, texs, nullptr, nullptr);
|
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,27 @@ static const char* FS =
|
||||||
" return colorOut;\n"
|
" return colorOut;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FSDoor =
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 pos : SV_Position;\n"
|
||||||
|
" float4 mvPos : POSITION;\n"
|
||||||
|
" float4 mvNorm : NORMAL;\n"
|
||||||
|
" float4 mvBinorm : BINORMAL;\n"
|
||||||
|
" float4 mvTangent : TANGENT;\n"
|
||||||
|
" float4 color : COLOR;\n"
|
||||||
|
" float2 uvs[7] : UV;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"SamplerState samp : register(s0);\n"
|
||||||
|
"%s" // Textures here
|
||||||
|
"float4 main(in VertToFrag vtf)\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 colorOut;\n"
|
||||||
|
"%s" // Combiner expression here
|
||||||
|
" return colorOut;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
boo::IShaderPipeline*
|
boo::IShaderPipeline*
|
||||||
CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
||||||
{
|
{
|
||||||
|
@ -198,12 +219,12 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
// Output reg 2
|
// Output reg 2
|
||||||
// KColor 3
|
// KColor 3
|
||||||
// Tex * K2 + Lighting
|
// Tex * K2 + Lighting
|
||||||
combiner += " lighting += mix(lightMapTexel * lu.kColor2, lightMapTexel, lu.kColor3);\n";
|
combiner += " lighting += mix(lightMapTexel * kColor2, lightMapTexel, kColor3);\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// mix(Tex * K2, Tex, K3) + Lighting
|
// mix(Tex * K2, Tex, K3) + Lighting
|
||||||
combiner += " lighting += lightMapTexel * lu.kColor2;\n";
|
combiner += " lighting += lightMapTexel * kColor2;\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +245,7 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * lu.kColor0 + lighting) *\n"
|
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * kColor0 + lighting) *\n"
|
||||||
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = lighting * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = lighting * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
|
@ -239,7 +260,7 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
{
|
{
|
||||||
// Make previous stage indirect, mtx0
|
// Make previous stage indirect, mtx0
|
||||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
||||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
" float2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||||
combiner += " colorOut += colorTex.Sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.Sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
||||||
}
|
}
|
||||||
else if (info.m_hasEnvMap)
|
else if (info.m_hasEnvMap)
|
||||||
|
@ -253,8 +274,8 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
if (info.m_hasColorTex)
|
if (info.m_hasColorTex)
|
||||||
combiner += " colorOut += colorTex.Sample(samp, vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.Sample(samp, vtf.uvs[2]) * lighting;\n";
|
||||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
||||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
" float2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||||
combiner += hecl::Format(" colorOut = mix(colorOut, envMap.Sample(samp, indUvs + vtf.uvs[%d]), lu.kColor1);\n",
|
combiner += hecl::Format(" colorOut = mix(colorOut, envMap.Sample(samp, indUvs + vtf.uvs[%d]), kColor1);\n",
|
||||||
envMapUv);
|
envMapUv);
|
||||||
}
|
}
|
||||||
else if (info.m_hasColorTex)
|
else if (info.m_hasColorTex)
|
||||||
|
@ -279,12 +300,12 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
// Output reg 2
|
// Output reg 2
|
||||||
// KColor 3
|
// KColor 3
|
||||||
// Tex * K2 + Lighting
|
// Tex * K2 + Lighting
|
||||||
combiner += " lighting += mix(lightMapTexel * lu.kColor2, lightMapTexel, lu.kColor3);\n";
|
combiner += " lighting += mix(lightMapTexel * kColor2, lightMapTexel, kColor3);\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// mix(Tex * K2, Tex, K3) + Lighting
|
// mix(Tex * K2, Tex, K3) + Lighting
|
||||||
combiner += " lighting += lightMapTexel * lu.kColor2;\n";
|
combiner += " lighting += lightMapTexel * kColor2;\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +326,7 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * lu.kColor0 + lighting) *\n"
|
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * kColor0 + lighting) *\n"
|
||||||
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = lighting * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = lighting * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
|
@ -321,7 +342,7 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
{
|
{
|
||||||
// Make previous stage indirect, mtx0
|
// Make previous stage indirect, mtx0
|
||||||
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
combiner += hecl::Format(" float2 indUvs = (envBumpMap.Sample(samp, vtf.uvs[%d]).ra - float2(0.5, 0.5)) *\n"
|
||||||
" float2(lu.fog.indScale, -lu.fog.indScale);", envBumpMapUv);
|
" float2(fog.indScale, -fog.indScale);", envBumpMapUv);
|
||||||
combiner += " colorOut += colorTex.Sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
combiner += " colorOut += colorTex.Sample(samp, indUvs + vtf.uvs[2]) * lighting;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -350,7 +371,7 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * lu.kColor0 + vtf.color) *\n"
|
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * kColor0 + vtf.color) *\n"
|
||||||
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = vtf.color * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = vtf.color * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
|
@ -408,7 +429,7 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
if (info.m_hasPatternTex2)
|
if (info.m_hasPatternTex2)
|
||||||
{
|
{
|
||||||
if (info.m_hasPatternTex1)
|
if (info.m_hasPatternTex1)
|
||||||
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * lu.kColor0 + vtf.color) *\n"
|
combiner += " colorOut = (patternTex1.Sample(samp, vtf.uvs[0]) * kColor0 + vtf.color) *\n"
|
||||||
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
" patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
else
|
else
|
||||||
combiner += " colorOut = vtf.color * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
combiner += " colorOut = vtf.color * patternTex2.Sample(samp, vtf.uvs[1]) + vtf.color;\n";
|
||||||
|
@ -445,8 +466,63 @@ CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidP
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::IShaderPipeline*
|
||||||
|
CFluidPlaneShader::BuildShader(boo::ID3DDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info)
|
||||||
|
{
|
||||||
|
if (s_vtxFmt == nullptr)
|
||||||
|
{
|
||||||
|
boo::VertexElementDescriptor elements[] =
|
||||||
|
{
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 0},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 1},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 2},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Color}
|
||||||
|
};
|
||||||
|
s_vtxFmt = ctx.newVertexFormat(5, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string additionalTCGs;
|
||||||
|
std::string textures;
|
||||||
|
std::string combiner;
|
||||||
|
int nextTex = 0;
|
||||||
|
|
||||||
|
if (info.m_hasPatternTex1)
|
||||||
|
textures += hecl::Format("Texture2D patternTex1 : register(t%d)\n", nextTex++);
|
||||||
|
if (info.m_hasPatternTex2)
|
||||||
|
textures += hecl::Format("Texture2D patternTex2 : register(t%d)\n", nextTex++);
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
textures += hecl::Format("Texture2D colorTex : register(t%d)\n", nextTex++);
|
||||||
|
|
||||||
|
// Tex0 * kColor0 * Tex1 + Tex2
|
||||||
|
if (info.m_hasPatternTex1 && info.m_hasPatternTex2)
|
||||||
|
{
|
||||||
|
combiner += " colorOut = patternTex1.Sample(samp, vtf.uvs[0]) * kColor0 *\n"
|
||||||
|
" patternTex2.Sample(samp, vtf.uvs[1]);\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
combiner += " colorOut = float4(0.0);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
{
|
||||||
|
combiner += " colorOut += colorTex.Sample(samp, vtf.uvs[2]);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
|
std::string finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
||||||
|
std::string finalFS = hecl::Format(FSDoor, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
|
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), nullptr, nullptr, nullptr, s_vtxFmt,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
|
boo::CullMode::None);
|
||||||
|
}
|
||||||
|
|
||||||
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::ID3DDataFactory::Context& ctx,
|
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::ID3DDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline* pipeline)
|
boo::IShaderPipeline* pipeline, bool door)
|
||||||
{
|
{
|
||||||
boo::IGraphicsBuffer* ubufs[] = { m_uniBuf, m_uniBuf, m_uniBuf };
|
boo::IGraphicsBuffer* ubufs[] = { m_uniBuf, m_uniBuf, m_uniBuf };
|
||||||
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
||||||
|
@ -469,8 +545,8 @@ boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::ID3DDataFactory::C
|
||||||
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
||||||
if (m_lightmap)
|
if (m_lightmap)
|
||||||
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
||||||
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo, nullptr, nullptr, 1, ubufs, ubufStages, ubufOffs,
|
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo, nullptr, nullptr, door ? 1 : 3,
|
||||||
ubufSizes, texCount, texs, nullptr, nullptr);
|
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,6 +125,29 @@ static const char* FS =
|
||||||
" return colorOut;\n"
|
" return colorOut;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FSDoor =
|
||||||
|
"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"constexpr sampler samp(address::repeat, filter::linear);\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" float4 pos : [[ position ]];\n"
|
||||||
|
" float4 mvPos;\n"
|
||||||
|
" float4 mvNorm;\n"
|
||||||
|
" float4 mvBinorm;\n"
|
||||||
|
" float4 mvTangent;\n"
|
||||||
|
" float4 color;\n"
|
||||||
|
" float2 uvs[7];\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]]%s)\n" // Textures here
|
||||||
|
"{\n"
|
||||||
|
" float4 colorOut;\n"
|
||||||
|
"%s" // Combiner expression here
|
||||||
|
" return colorOut;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
boo::IShaderPipeline*
|
boo::IShaderPipeline*
|
||||||
CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info)
|
||||||
{
|
{
|
||||||
|
@ -451,8 +474,63 @@ CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluid
|
||||||
boo::CullMode::None);
|
boo::CullMode::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boo::IShaderPipeline*
|
||||||
|
CFluidPlaneShader::BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info)
|
||||||
|
{
|
||||||
|
if (s_vtxFmt == nullptr)
|
||||||
|
{
|
||||||
|
boo::VertexElementDescriptor elements[] =
|
||||||
|
{
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 0},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 1},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Normal4, 2},
|
||||||
|
{nullptr, nullptr, boo::VertexSemantic::Color}
|
||||||
|
};
|
||||||
|
s_vtxFmt = ctx.newVertexFormat(5, elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string additionalTCGs;
|
||||||
|
std::string textures;
|
||||||
|
std::string combiner;
|
||||||
|
int nextTex = 0;
|
||||||
|
|
||||||
|
if (info.m_hasPatternTex1)
|
||||||
|
textures += hecl::Format(",\ntexture2d<float> patternTex1 [[ texture(%d) ]]", nextTex++);
|
||||||
|
if (info.m_hasPatternTex2)
|
||||||
|
textures += hecl::Format(",\ntexture2d<float> patternTex2 [[ texture(%d) ]]", nextTex++);
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
textures += hecl::Format(",\ntexture2d<float> colorTex [[ texture(%d) ]]", nextTex++);
|
||||||
|
|
||||||
|
// Tex0 * kColor0 * Tex1 + Tex2
|
||||||
|
if (info.m_hasPatternTex1 && info.m_hasPatternTex2)
|
||||||
|
{
|
||||||
|
combiner += " colorOut = patternTex1.sample(samp, vtf.uvs[0]) * lu.kColor0 *\n"
|
||||||
|
" patternTex2.sample(samp, vtf.uvs[1]);\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
combiner += " colorOut = float4(0.0);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.m_hasColorTex)
|
||||||
|
{
|
||||||
|
combiner += " colorOut += colorTex.sample(samp, vtf.uvs[2]);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
combiner += " colorOut.a = kColor0.a;\n";
|
||||||
|
|
||||||
|
std::string finalVS = hecl::Format(VS, additionalTCGs.c_str());
|
||||||
|
std::string finalFS = hecl::Format(FSDoor, textures.c_str(), combiner.c_str());
|
||||||
|
|
||||||
|
return ctx.newShaderPipeline(finalVS.c_str(), finalFS.c_str(), s_vtxFmt, CGraphics::g_ViewportSamples,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
|
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true, false,
|
||||||
|
boo::CullMode::None);
|
||||||
|
}
|
||||||
|
|
||||||
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::MetalDataFactory::Context& ctx,
|
boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::MetalDataFactory::Context& ctx,
|
||||||
boo::IShaderPipeline* pipeline)
|
boo::IShaderPipeline* pipeline, bool door)
|
||||||
{
|
{
|
||||||
boo::IGraphicsBuffer* ubufs[] = { m_uniBuf, m_uniBuf, m_uniBuf };
|
boo::IGraphicsBuffer* ubufs[] = { m_uniBuf, m_uniBuf, m_uniBuf };
|
||||||
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
boo::PipelineStage ubufStages[] = { boo::PipelineStage::Vertex, boo::PipelineStage::Vertex,
|
||||||
|
@ -475,8 +553,8 @@ boo::IShaderDataBinding* CFluidPlaneShader::BuildBinding(boo::MetalDataFactory::
|
||||||
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
texs[texCount++] = (*m_envBumpMap)->GetBooTexture();
|
||||||
if (m_lightmap)
|
if (m_lightmap)
|
||||||
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
texs[texCount++] = (*m_lightmap)->GetBooTexture();
|
||||||
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo, nullptr, nullptr, 1, ubufs, ubufStages, ubufOffs,
|
return ctx.newShaderDataBinding(pipeline, s_vtxFmt, m_vbo, nullptr, nullptr, door ? 1 : 3,
|
||||||
ubufSizes, texCount, texs, nullptr, nullptr);
|
ubufs, ubufStages, ubufOffs, ubufSizes, texCount, texs, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "Graphics/Shaders/CPhazonSuitFilter.hpp"
|
#include "Graphics/Shaders/CPhazonSuitFilter.hpp"
|
||||||
#include "Graphics/Shaders/CScanLinesFilter.hpp"
|
#include "Graphics/Shaders/CScanLinesFilter.hpp"
|
||||||
#include "Graphics/Shaders/CRandomStaticFilter.hpp"
|
#include "Graphics/Shaders/CRandomStaticFilter.hpp"
|
||||||
|
#include "Graphics/Shaders/CFluidPlaneShader.hpp"
|
||||||
#include "Character/CCharLayoutInfo.hpp"
|
#include "Character/CCharLayoutInfo.hpp"
|
||||||
#include "Audio/CStreamAudioManager.hpp"
|
#include "Audio/CStreamAudioManager.hpp"
|
||||||
#include "CGBASupport.hpp"
|
#include "CGBASupport.hpp"
|
||||||
|
@ -369,6 +370,7 @@ void CMain::Shutdown()
|
||||||
TMultiBlendShader<CTextSupportShader>::Shutdown();
|
TMultiBlendShader<CTextSupportShader>::Shutdown();
|
||||||
TMultiBlendShader<CScanLinesFilter>::Shutdown();
|
TMultiBlendShader<CScanLinesFilter>::Shutdown();
|
||||||
TMultiBlendShader<CRandomStaticFilter>::Shutdown();
|
TMultiBlendShader<CRandomStaticFilter>::Shutdown();
|
||||||
|
CFluidPlaneShader::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
boo::IWindow* CMain::GetMainWindow() const
|
boo::IWindow* CMain::GetMainWindow() const
|
||||||
|
|
|
@ -79,9 +79,9 @@ protected:
|
||||||
public:
|
public:
|
||||||
enum class EFluidState
|
enum class EFluidState
|
||||||
{
|
{
|
||||||
Zero,
|
EnteredFluid,
|
||||||
One,
|
InFluid,
|
||||||
Two
|
LeftFluid
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class EScanState
|
enum class EScanState
|
||||||
|
@ -180,6 +180,7 @@ public:
|
||||||
float GetAverageAnimVelocity(int anim) const;
|
float GetAverageAnimVelocity(int anim) const;
|
||||||
u8 GetTargetableVisorFlags() const { return xe6_31_targetableVisorFlags; }
|
u8 GetTargetableVisorFlags() const { return xe6_31_targetableVisorFlags; }
|
||||||
bool GetIsTargetable() const { return xe7_31_targetable; }
|
bool GetIsTargetable() const { return xe7_31_targetable; }
|
||||||
|
void SetDrawFlags(const CModelFlags& flags) { xb4_drawFlags = flags; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include <Runtime/GameGlobalObjects.hpp>
|
#include <Runtime/GameGlobalObjects.hpp>
|
||||||
#include "CFluidPlane.hpp"
|
#include "CFluidPlane.hpp"
|
||||||
#include "CSimplePool.hpp"
|
#include "CSimplePool.hpp"
|
||||||
|
#include "CRipple.hpp"
|
||||||
|
#include "CScriptWater.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -18,14 +21,67 @@ CFluidPlane::CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId te
|
||||||
x30_texColor.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texColor}));
|
x30_texColor.emplace(g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), texColor}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFluidPlane::Ripple(float mag, TUniqueId rippler, const zeus::CVector3f& pos,
|
float CFluidPlane::ProjectRippleVelocity(float baseI, float velDot) const
|
||||||
|
{
|
||||||
|
float tmp = 0.5f * baseI * velDot * velDot;
|
||||||
|
if (tmp != 0.f)
|
||||||
|
tmp = std::sqrt(tmp);
|
||||||
|
if (tmp >= 160.f)
|
||||||
|
return 1.f;
|
||||||
|
return tmp / 160.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CFluidPlane::CalculateRippleIntensity(float baseI) const
|
||||||
|
{
|
||||||
|
float mul;
|
||||||
|
switch (x44_fluidType)
|
||||||
|
{
|
||||||
|
case EFluidType::NormalWater:
|
||||||
|
mul = g_tweakGame->GetRippleIntensityNormal();
|
||||||
|
break;
|
||||||
|
case EFluidType::PoisonWater:
|
||||||
|
mul = g_tweakGame->GetRippleIntensityPoison();
|
||||||
|
break;
|
||||||
|
case EFluidType::Lava:
|
||||||
|
mul = g_tweakGame->GetRippleIntensityLava();
|
||||||
|
break;
|
||||||
|
case EFluidType::Three:
|
||||||
|
case EFluidType::Four:
|
||||||
|
mul = 0.8f;
|
||||||
|
break;
|
||||||
|
case EFluidType::Five:
|
||||||
|
mul = 1.f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zeus::clamp(0.f, baseI * mul * (1.f - x48_rippleIntensity + 0.5f), 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFluidPlane::AddRipple(float mag, TUniqueId rippler, const zeus::CVector3f& center,
|
||||||
CScriptWater& water, CStateManager& mgr)
|
CScriptWater& water, CStateManager& mgr)
|
||||||
{
|
{
|
||||||
|
if (!water.CanRippleAtPoint(center))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mag = CalculateRippleIntensity(mag);
|
||||||
|
mgr.GetFluidPlaneManager()->RippleManager().AddRipple(CRipple(rippler, center, mag));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFluidPlane::Update()
|
void CFluidPlane::AddRipple(float intensity, TUniqueId rippler, const zeus::CVector3f& center,
|
||||||
|
const zeus::CVector3f& velocity, const CScriptWater& water, CStateManager& mgr,
|
||||||
|
const zeus::CVector3f& upVec)
|
||||||
{
|
{
|
||||||
|
if (!water.CanRippleAtPoint(center))
|
||||||
|
return;
|
||||||
|
|
||||||
|
intensity = CalculateRippleIntensity(ProjectRippleVelocity(intensity, upVec.dot(velocity)));
|
||||||
|
mgr.GetFluidPlaneManager()->RippleManager().AddRipple(CRipple(rippler, center, intensity));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFluidPlane::AddRipple(const CRipple& ripple, const CScriptWater& water, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
if (!water.CanRippleAtPoint(ripple.GetCenter()))
|
||||||
|
return;
|
||||||
|
mgr.GetFluidPlaneManager()->RippleManager().AddRipple(ripple);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ class CFluidUVMotion;
|
||||||
class CRippleManager;
|
class CRippleManager;
|
||||||
class CScriptWater;
|
class CScriptWater;
|
||||||
class CStateManager;
|
class CStateManager;
|
||||||
|
class CRipple;
|
||||||
class CFluidPlane
|
class CFluidPlane
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -38,17 +39,28 @@ protected:
|
||||||
EFluidType x44_fluidType;
|
EFluidType x44_fluidType;
|
||||||
float x48_rippleIntensity;
|
float x48_rippleIntensity;
|
||||||
CFluidUVMotion x4c_uvMotion;
|
CFluidUVMotion x4c_uvMotion;
|
||||||
|
float ProjectRippleVelocity(float baseI, float velDot) const;
|
||||||
|
float CalculateRippleIntensity(float baseI) const;
|
||||||
public:
|
public:
|
||||||
CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, float alpha,
|
CFluidPlane(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, float alpha,
|
||||||
EFluidType fluidType, float rippleIntensity, const CFluidUVMotion& motion);
|
EFluidType fluidType, float rippleIntensity, const CFluidUVMotion& motion);
|
||||||
|
|
||||||
virtual void Ripple(float mag, TUniqueId rippler, const zeus::CVector3f& pos,
|
// Called by CPlayer, CMorphBall, CWeapon, CPuddleSpore, CMagdolite
|
||||||
|
virtual void AddRipple(float mag, TUniqueId rippler, const zeus::CVector3f& center,
|
||||||
CScriptWater& water, CStateManager& mgr);
|
CScriptWater& water, CStateManager& mgr);
|
||||||
virtual void Update();
|
|
||||||
|
// Called by CAi
|
||||||
|
virtual void AddRipple(float intensity, TUniqueId rippler, const zeus::CVector3f& center,
|
||||||
|
const zeus::CVector3f& velocity, const CScriptWater& water, CStateManager& mgr,
|
||||||
|
const zeus::CVector3f& upVec);
|
||||||
|
|
||||||
|
virtual void AddRipple(const CRipple& ripple, const CScriptWater& water, CStateManager& mgr);
|
||||||
|
|
||||||
virtual void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
virtual void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||||
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||||
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const {}
|
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const {}
|
||||||
|
|
||||||
float GetAlpha() const { return x40_alpha; }
|
float GetAlpha() const { return x40_alpha; }
|
||||||
EFluidType GetFluidType() const { return x44_fluidType; }
|
EFluidType GetFluidType() const { return x44_fluidType; }
|
||||||
const CFluidUVMotion& GetUVMotion() const { return x4c_uvMotion; }
|
const CFluidUVMotion& GetUVMotion() const { return x4c_uvMotion; }
|
||||||
|
|
|
@ -43,9 +43,9 @@ CFluidPlaneCPU::CTurbulence::CTurbulence(float speed, float distance, float freq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFluidPlaneCPU::CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap,
|
CFluidPlaneCPU::CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap,
|
||||||
CAssetId envBumpMap, CAssetId lightMap, float unitsPerLightmapTexel, float tileSize,
|
CAssetId envMap, CAssetId envBumpMap, CAssetId lightMap, float unitsPerLightmapTexel,
|
||||||
u32 tileSubdivisions, EFluidType fluidType, float alpha,
|
float tileSize, 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,
|
||||||
float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax, float turbAmplitudeMin,
|
float turbPhaseMax, float turbPhaseMin, float turbAmplitudeMax, float turbAmplitudeMin,
|
||||||
|
@ -114,11 +114,11 @@ static const float* InitializeSineWave()
|
||||||
|
|
||||||
#define kEnableWaterBumpMaps true
|
#define kEnableWaterBumpMaps true
|
||||||
|
|
||||||
CFluidPlaneCPU::RenderSetupInfo
|
CFluidPlaneShader::RenderSetupInfo
|
||||||
CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf,
|
CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf,
|
||||||
const zeus::CTransform& areaXf, const zeus::CAABox& aabb, const CScriptWater* water) const
|
const zeus::CTransform& areaXf, const zeus::CAABox& aabb, const CScriptWater* water) const
|
||||||
{
|
{
|
||||||
RenderSetupInfo out;
|
CFluidPlaneShader::RenderSetupInfo out;
|
||||||
|
|
||||||
float uvT = mgr.GetFluidPlaneManager()->GetUVT();
|
float uvT = mgr.GetFluidPlaneManager()->GetUVT();
|
||||||
bool hasBumpMap = HasBumpMap() && kEnableWaterBumpMaps;
|
bool hasBumpMap = HasBumpMap() && kEnableWaterBumpMaps;
|
||||||
|
@ -283,110 +283,6 @@ CFluidPlaneCPU::RenderSetup(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CFluidPlaneCPURender
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum class NormalMode
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
NoNormals,
|
|
||||||
Normals,
|
|
||||||
NBT
|
|
||||||
};
|
|
||||||
|
|
||||||
static int numTilesInHField;
|
|
||||||
static int numSubdivisionsInTile;
|
|
||||||
static int numSubdivisionsInHField;
|
|
||||||
|
|
||||||
struct SPatchInfo
|
|
||||||
{
|
|
||||||
u8 x0_xSubdivs, x1_ySubdivs;
|
|
||||||
zeus::CVector2f x4_localMin, xc_globalMin;
|
|
||||||
float x14_tileSize;
|
|
||||||
float x18_rippleResolution;
|
|
||||||
float x1c_tileHypRadius;
|
|
||||||
float x20_ooTileSize;
|
|
||||||
float x24_ooRippleResolution;
|
|
||||||
u16 x28_tileX;
|
|
||||||
u16 x2a_gridDimX;
|
|
||||||
u16 x2c_gridDimY;
|
|
||||||
u16 x2e_tileY;
|
|
||||||
const bool* x30_gridFlags;
|
|
||||||
u8 x34_redShift;
|
|
||||||
u8 x35_greenShift;
|
|
||||||
u8 x36_blueShift;
|
|
||||||
NormalMode x37_normalMode;
|
|
||||||
float x38_wavecapIntensityScale;
|
|
||||||
public:
|
|
||||||
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
|
||||||
float rippleResolution, float tileSize, float wavecapIntensityScale, int numSubdivisionsInHField,
|
|
||||||
NormalMode normalMode, int redShift, int greenShift, int blueShift, 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 tileHypRadius = tileSize * tileSize * 2 * 0.25f;
|
|
||||||
x4_localMin.x = localMin.x;
|
|
||||||
x4_localMin.y = localMin.y;
|
|
||||||
xc_globalMin = x4_localMin + zeus::CVector2f(pos.x, pos.y);
|
|
||||||
x14_tileSize = tileSize;
|
|
||||||
x18_rippleResolution = rippleResolution;
|
|
||||||
if (tileHypRadius != 0.f)
|
|
||||||
tileHypRadius = std::sqrt(tileHypRadius);
|
|
||||||
x1c_tileHypRadius = tileHypRadius;
|
|
||||||
x20_ooTileSize = 1.f / x14_tileSize;
|
|
||||||
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_redShift = u8(redShift);
|
|
||||||
x35_greenShift = u8(greenShift);
|
|
||||||
x36_blueShift = u8(blueShift);
|
|
||||||
x37_normalMode = normalMode;
|
|
||||||
x38_wavecapIntensityScale = wavecapIntensityScale;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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 height;
|
|
||||||
s8 nx;
|
|
||||||
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};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
int CFluidPlaneCPURender::numTilesInHField;
|
int CFluidPlaneCPURender::numTilesInHField;
|
||||||
int CFluidPlaneCPURender::numSubdivisionsInTile;
|
int CFluidPlaneCPURender::numSubdivisionsInTile;
|
||||||
int CFluidPlaneCPURender::numSubdivisionsInHField;
|
int CFluidPlaneCPURender::numSubdivisionsInHField;
|
||||||
|
@ -963,7 +859,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
|
||||||
func(curTileX, curTileY + info.x18_rippleResolution, heights[curYDiv+1][i+v]);
|
func(curTileX, curTileY + info.x18_rippleResolution, heights[curYDiv+1][i+v]);
|
||||||
curTileX += info.x18_rippleResolution;
|
curTileX += info.x18_rippleResolution;
|
||||||
}
|
}
|
||||||
CGraphics::DrawArray(start, 4);
|
CGraphics::DrawArray(start, vOut.size() - start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1040,7 +936,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CGraphics::DrawArray(start, 4);
|
CGraphics::DrawArray(start, vOut.size() - start);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1145,7 +1041,7 @@ static void RenderStripWithRipples(float curY, const CFluidPlaneCPURender::SHFie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
|
void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
|
||||||
const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45],
|
const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45],
|
||||||
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
||||||
std::vector<CFluidPlaneShader::Vertex>& vOut)
|
std::vector<CFluidPlaneShader::Vertex>& vOut)
|
||||||
|
@ -1367,7 +1263,7 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const
|
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const
|
||||||
{
|
{
|
||||||
TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(waterId);
|
TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(waterId);
|
||||||
RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, areaXf, aabb, water.GetPtr());
|
CFluidPlaneShader::RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, areaXf, aabb, water.GetPtr());
|
||||||
|
|
||||||
CFluidPlaneCPURender::NormalMode normalMode;
|
CFluidPlaneCPURender::NormalMode normalMode;
|
||||||
if (xb0_bumpMap && kEnableWaterBumpMaps)
|
if (xb0_bumpMap && kEnableWaterBumpMaps)
|
||||||
|
@ -1435,8 +1331,7 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128;
|
u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128;
|
||||||
|
|
||||||
m_verts.clear();
|
m_verts.clear();
|
||||||
m_shader->prepareDraw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale,
|
m_shader->prepareDraw(setupInfo);
|
||||||
setupInfo.lights, setupInfo.kColors);
|
|
||||||
|
|
||||||
u32 tileY = 0;
|
u32 tileY = 0;
|
||||||
float curY = aabb.min.y;
|
float curY = aabb.min.y;
|
||||||
|
@ -1496,9 +1391,4 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
|
||||||
m_shader->loadVerts(m_verts);
|
m_shader->loadVerts(m_verts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFluidPlaneCPU::RenderCleanup() const
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,15 +61,6 @@ class CFluidPlaneCPU : public CFluidPlane
|
||||||
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
||||||
mutable bool m_cachedDoubleLightmapBlend;
|
mutable bool m_cachedDoubleLightmapBlend;
|
||||||
mutable bool m_cachedAdditive;
|
mutable bool m_cachedAdditive;
|
||||||
|
|
||||||
struct RenderSetupInfo
|
|
||||||
{
|
|
||||||
zeus::CMatrix4f texMtxs[6];
|
|
||||||
zeus::CMatrix4f normMtx;
|
|
||||||
float indScale = 1.f;
|
|
||||||
zeus::CColor kColors[4];
|
|
||||||
std::vector<CLight> lights;
|
|
||||||
};
|
|
||||||
public:
|
public:
|
||||||
CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap, CAssetId envBumpMap,
|
CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap, CAssetId envBumpMap,
|
||||||
CAssetId lightMap, float unitsPerLightmapTexel, float tileSize, u32 tileSubdivisions,
|
CAssetId lightMap, float unitsPerLightmapTexel, float tileSize, u32 tileSubdivisions,
|
||||||
|
@ -81,14 +72,13 @@ public:
|
||||||
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;
|
||||||
RenderSetupInfo RenderSetup(const CStateManager& mgr, float, const zeus::CTransform& xf,
|
CFluidPlaneShader::RenderSetupInfo RenderSetup(const CStateManager& mgr, float, const zeus::CTransform& xf,
|
||||||
const zeus::CTransform& areaXf, const zeus::CAABox& aabb,
|
const zeus::CTransform& areaXf, const zeus::CAABox& aabb,
|
||||||
const CScriptWater* water) const;
|
const CScriptWater* water) const;
|
||||||
void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||||
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||||
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||||
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const;
|
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const;
|
||||||
void RenderCleanup() const;
|
|
||||||
float GetReflectionBlend() const { return x114_reflectionBlend; }
|
float GetReflectionBlend() const { return x114_reflectionBlend; }
|
||||||
float GetSpecularMax() const { return x110_specularMax; }
|
float GetSpecularMax() const { return x110_specularMax; }
|
||||||
float GetSpecularMin() const { return x10c_specularMin; }
|
float GetSpecularMin() const { return x10c_specularMin; }
|
||||||
|
@ -111,6 +101,116 @@ public:
|
||||||
float GetOOTurbulenceSpeed() const { return x120_turbulence.GetOOSpeed(); }
|
float GetOOTurbulenceSpeed() const { return x120_turbulence.GetOOSpeed(); }
|
||||||
bool HasTurbulence() const { return x120_turbulence.HasTurbulence(); }
|
bool HasTurbulence() const { return x120_turbulence.HasTurbulence(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CFluidPlaneCPURender
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class NormalMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
NoNormals,
|
||||||
|
Normals,
|
||||||
|
NBT
|
||||||
|
};
|
||||||
|
|
||||||
|
static int numTilesInHField;
|
||||||
|
static int numSubdivisionsInTile;
|
||||||
|
static int numSubdivisionsInHField;
|
||||||
|
|
||||||
|
struct SPatchInfo
|
||||||
|
{
|
||||||
|
u8 x0_xSubdivs, x1_ySubdivs;
|
||||||
|
zeus::CVector2f x4_localMin, xc_globalMin;
|
||||||
|
float x14_tileSize;
|
||||||
|
float x18_rippleResolution;
|
||||||
|
float x1c_tileHypRadius;
|
||||||
|
float x20_ooTileSize;
|
||||||
|
float x24_ooRippleResolution;
|
||||||
|
u16 x28_tileX;
|
||||||
|
u16 x2a_gridDimX;
|
||||||
|
u16 x2c_gridDimY;
|
||||||
|
u16 x2e_tileY;
|
||||||
|
const bool* x30_gridFlags;
|
||||||
|
u8 x34_redShift;
|
||||||
|
u8 x35_greenShift;
|
||||||
|
u8 x36_blueShift;
|
||||||
|
NormalMode x37_normalMode;
|
||||||
|
float x38_wavecapIntensityScale;
|
||||||
|
public:
|
||||||
|
SPatchInfo(const zeus::CVector3f& localMin, const zeus::CVector3f& localMax, const zeus::CVector3f& pos,
|
||||||
|
float rippleResolution, float tileSize, float wavecapIntensityScale, int numSubdivisionsInHField,
|
||||||
|
NormalMode normalMode, int redShift, int greenShift, int blueShift, 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 tileHypRadius = tileSize * tileSize * 2 * 0.25f;
|
||||||
|
x4_localMin.x = localMin.x;
|
||||||
|
x4_localMin.y = localMin.y;
|
||||||
|
xc_globalMin = x4_localMin + zeus::CVector2f(pos.x, pos.y);
|
||||||
|
x14_tileSize = tileSize;
|
||||||
|
x18_rippleResolution = rippleResolution;
|
||||||
|
if (tileHypRadius != 0.f)
|
||||||
|
tileHypRadius = std::sqrt(tileHypRadius);
|
||||||
|
x1c_tileHypRadius = tileHypRadius;
|
||||||
|
x20_ooTileSize = 1.f / x14_tileSize;
|
||||||
|
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_redShift = u8(redShift);
|
||||||
|
x35_greenShift = u8(greenShift);
|
||||||
|
x36_blueShift = u8(blueShift);
|
||||||
|
x37_normalMode = normalMode;
|
||||||
|
x38_wavecapIntensityScale = wavecapIntensityScale;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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 height;
|
||||||
|
s8 nx;
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
|
||||||
|
const CFluidPlaneCPURender::SHFieldSample (&heights)[45][45],
|
||||||
|
const u8 (&flags)[9][9], bool noRipples, bool flagIs1,
|
||||||
|
std::vector<CFluidPlaneShader::Vertex>& vOut);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __URDE_CFLUIDPLANECPU_HPP__
|
#endif // __URDE_CFLUIDPLANECPU_HPP__
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include "CFluidPlaneDoor.hpp"
|
||||||
|
#include "CFluidPlaneCPU.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
|
||||||
|
namespace urde
|
||||||
|
{
|
||||||
|
|
||||||
|
CFluidPlaneDoor::CFluidPlaneDoor(CAssetId patternTex1, CAssetId patternTex2, CAssetId colorTex, float tileSize,
|
||||||
|
u32 tileSubdivisions, EFluidType fluidType, float alpha,
|
||||||
|
const CFluidUVMotion& uvMotion)
|
||||||
|
: CFluidPlane(patternTex1, patternTex2, colorTex, alpha, fluidType, 0.5f, uvMotion), xa0_tileSize(tileSize),
|
||||||
|
xa4_tileSubdivisions(tileSubdivisions & ~0x1), xa8_rippleResolution(xa0_tileSize / float(xa4_tileSubdivisions))
|
||||||
|
{}
|
||||||
|
|
||||||
|
CFluidPlaneShader::RenderSetupInfo
|
||||||
|
CFluidPlaneDoor::RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf,
|
||||||
|
const zeus::CAABox& aabb, bool noNormals) const
|
||||||
|
{
|
||||||
|
CFluidPlaneShader::RenderSetupInfo out;
|
||||||
|
|
||||||
|
float uvT = mgr.GetFluidPlaneManager()->GetUVT();
|
||||||
|
CGraphics::SetModelMatrix(xf);
|
||||||
|
|
||||||
|
float fluidUVs[3][2];
|
||||||
|
x4c_uvMotion.CalculateFluidTextureOffset(uvT, fluidUVs);
|
||||||
|
|
||||||
|
out.texMtxs[0][0][0] = out.texMtxs[0][1][1] = x4c_uvMotion.GetFluidLayers()[1].GetUVScale();
|
||||||
|
out.texMtxs[0][3][0] = fluidUVs[1][0];
|
||||||
|
out.texMtxs[0][3][1] = fluidUVs[1][1];
|
||||||
|
|
||||||
|
out.texMtxs[1][0][0] = out.texMtxs[1][1][1] = x4c_uvMotion.GetFluidLayers()[2].GetUVScale();
|
||||||
|
out.texMtxs[1][3][0] = fluidUVs[2][0];
|
||||||
|
out.texMtxs[1][3][1] = fluidUVs[2][1];
|
||||||
|
|
||||||
|
out.texMtxs[2][0][0] = out.texMtxs[2][1][1] = x4c_uvMotion.GetFluidLayers()[0].GetUVScale();
|
||||||
|
out.texMtxs[2][3][0] = fluidUVs[0][0];
|
||||||
|
out.texMtxs[2][3][1] = fluidUVs[0][1];
|
||||||
|
|
||||||
|
out.kColors[0] = zeus::CColor(1.f, alpha);
|
||||||
|
|
||||||
|
if (!m_shader)
|
||||||
|
{
|
||||||
|
auto gridDimX = u32((xa0_tileSize + aabb.max.x - aabb.min.x - 0.01f) / xa0_tileSize);
|
||||||
|
auto gridDimY = u32((xa0_tileSize + aabb.max.y - aabb.min.y - 0.01f) / xa0_tileSize);
|
||||||
|
u32 gridCellCount = (gridDimX + 1) * (gridDimY + 1);
|
||||||
|
u32 maxVerts = gridCellCount * ((std::max(2, xa4_tileSubdivisions) * 4 + 2) * 4);
|
||||||
|
m_shader.emplace(x10_texPattern1, x20_texPattern2, x30_texColor, maxVerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFluidPlaneDoor::Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||||
|
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||||
|
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||||
|
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const
|
||||||
|
{
|
||||||
|
CFluidPlaneShader::RenderSetupInfo setupInfo = RenderSetup(mgr, alpha, xf, aabb, noNormals);
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInTile = xa4_tileSubdivisions;
|
||||||
|
CFluidPlaneCPURender::numTilesInHField = 42 / xa4_tileSubdivisions;
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInHField = CFluidPlaneCPURender::numTilesInHField * xa4_tileSubdivisions;
|
||||||
|
zeus::CVector2f centerPlane(aabb.center().x, aabb.center().y);
|
||||||
|
float patchSize = xa8_rippleResolution * CFluidPlaneCPURender::numSubdivisionsInHField;
|
||||||
|
float ooSubdivSize = 1.f / xa8_rippleResolution;
|
||||||
|
|
||||||
|
m_verts.clear();
|
||||||
|
m_shader->prepareDraw(setupInfo);
|
||||||
|
|
||||||
|
for (float curX = aabb.min.x ; curX < aabb.max.x ; curX += patchSize)
|
||||||
|
{
|
||||||
|
float remSubdivsX = (aabb.max.x - curX) * ooSubdivSize;
|
||||||
|
for (float curY = aabb.min.y ; curY < aabb.max.y ; curY += patchSize)
|
||||||
|
{
|
||||||
|
float remSubdivsY = (aabb.max.y - curY) * ooSubdivSize;
|
||||||
|
int remSubdivsXi = std::min(CFluidPlaneCPURender::numSubdivisionsInHField, int(remSubdivsX));
|
||||||
|
int remSubdivsYi = std::min(CFluidPlaneCPURender::numSubdivisionsInHField, int(remSubdivsY));
|
||||||
|
zeus::CAABox aabb2(aabb.min, zeus::CVector3f(xa8_rippleResolution * remSubdivsXi + curX,
|
||||||
|
xa8_rippleResolution * remSubdivsYi + curY,
|
||||||
|
aabb.max.z));
|
||||||
|
if (frustum.aabbFrustumTest(aabb2.getTransformedAABox(xf)))
|
||||||
|
{
|
||||||
|
CFluidPlaneCPURender::SPatchInfo patchInfo(zeus::CVector3f(curX, curY, aabb.min.z),
|
||||||
|
aabb2.max, xf.origin, xa8_rippleResolution,
|
||||||
|
xa0_tileSize, 0.f,
|
||||||
|
CFluidPlaneCPURender::numSubdivisionsInHField,
|
||||||
|
CFluidPlaneCPURender::NormalMode::None,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, nullptr);
|
||||||
|
|
||||||
|
CFluidPlaneCPURender::SHFieldSample heights[45][45];
|
||||||
|
u8 flags[9][9] = {};
|
||||||
|
|
||||||
|
RenderPatch(patchInfo, heights, flags, true, true, m_verts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_shader->loadVerts(m_verts);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,12 +1,37 @@
|
||||||
#ifndef __URDE_CFLUIDPLANEDOOR_HPP__
|
#ifndef __URDE_CFLUIDPLANEDOOR_HPP__
|
||||||
#define __URDE_CFLUIDPLANEDOOR_HPP__
|
#define __URDE_CFLUIDPLANEDOOR_HPP__
|
||||||
|
|
||||||
#include "CFluidPlane.hpp
|
#include "CFluidPlane.hpp"
|
||||||
|
#include "Graphics/Shaders/CFluidPlaneShader.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
class CFluidPlaneDoor : public CFluidPlane
|
class CFluidPlaneDoor : public CFluidPlane
|
||||||
{
|
{
|
||||||
|
float xa0_tileSize;
|
||||||
|
int xa4_tileSubdivisions;
|
||||||
|
float xa8_rippleResolution;
|
||||||
|
|
||||||
|
mutable std::vector<CFluidPlaneShader::Vertex> m_verts;
|
||||||
|
mutable std::experimental::optional<CFluidPlaneShader> m_shader;
|
||||||
|
|
||||||
|
CFluidPlaneShader::RenderSetupInfo
|
||||||
|
RenderSetup(const CStateManager& mgr, float alpha, const zeus::CTransform& xf,
|
||||||
|
const zeus::CAABox& aabb, bool noNormals) const;
|
||||||
|
public:
|
||||||
|
CFluidPlaneDoor(CAssetId patternTex1, CAssetId patternTex2, CAssetId colorTex, float tileSize, u32 tileSubdivisions,
|
||||||
|
EFluidType fluidType, float alpha, const CFluidUVMotion& uvMotion);
|
||||||
|
void AddRipple(float mag, TUniqueId rippler, const zeus::CVector3f& center,
|
||||||
|
CScriptWater& water, CStateManager& mgr) {}
|
||||||
|
void AddRipple(float intensity, TUniqueId rippler, const zeus::CVector3f& center,
|
||||||
|
const zeus::CVector3f& velocity, const CScriptWater& water, CStateManager& mgr,
|
||||||
|
const zeus::CVector3f& upVec) {}
|
||||||
|
void AddRipple(const CRipple& ripple, const CScriptWater& water, CStateManager& mgr) {}
|
||||||
|
|
||||||
|
void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
|
||||||
|
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
|
||||||
|
const std::experimental::optional<CRippleManager>& rippleManager, TUniqueId waterId,
|
||||||
|
const bool* gridFlags, u32 gridDimX, u32 gridDimY, const zeus::CVector3f& areaCenter) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
const zeus::CVector3f& pos, float factor, bool);
|
const zeus::CVector3f& pos, float factor, bool);
|
||||||
rstl::reserved_vector<CSplashRecord, 32>& SplashRecords() { return x18_splashes; }
|
rstl::reserved_vector<CSplashRecord, 32>& SplashRecords() { return x18_splashes; }
|
||||||
const CRippleManager& GetRippleManager() const { return x0_rippleManager; }
|
const CRippleManager& GetRippleManager() const { return x0_rippleManager; }
|
||||||
|
CRippleManager& RippleManager() { return x0_rippleManager; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager
|
||||||
if (x2f8_morphTransState == EPlayerMorphBallState::Morphed)
|
if (x2f8_morphTransState == EPlayerMorphBallState::Morphed)
|
||||||
{
|
{
|
||||||
x768_morphball->FluidFXThink(state, water, mgr);
|
x768_morphball->FluidFXThink(state, water, mgr);
|
||||||
if (state == EFluidState::One)
|
if (state == EFluidState::InFluid)
|
||||||
x9c5_30_ = true;
|
x9c5_30_ = true;
|
||||||
}
|
}
|
||||||
else if (x2f8_morphTransState != EPlayerMorphBallState::Unmorphed)
|
else if (x2f8_morphTransState != EPlayerMorphBallState::Unmorphed)
|
||||||
|
@ -224,7 +224,7 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager
|
||||||
zeus::CVector3f position(x34_transform.origin);
|
zeus::CVector3f position(x34_transform.origin);
|
||||||
position.z = water.GetTriggerBoundsWR().max.z;
|
position.z = water.GetTriggerBoundsWR().max.z;
|
||||||
mgr.GetFluidPlaneManager()->CreateSplash(x8_uid, mgr, water, position, 0.1f,
|
mgr.GetFluidPlaneManager()->CreateSplash(x8_uid, mgr, water, position, 0.1f,
|
||||||
state == EFluidState::Zero);
|
state == EFluidState::EnteredFluid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -236,7 +236,7 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager
|
||||||
posOffset = posOffset.normalized() * zeus::CVector3f(1.2f, 1.2f, 0.f);
|
posOffset = posOffset.normalized() * zeus::CVector3f(1.2f, 1.2f, 0.f);
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case EFluidState::Zero:
|
case EFluidState::EnteredFluid:
|
||||||
{
|
{
|
||||||
bool doSplash = true;
|
bool doSplash = true;
|
||||||
if (x4fc_ > 12.5f)
|
if (x4fc_ > 12.5f)
|
||||||
|
@ -260,18 +260,18 @@ void CPlayer::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EFluidState::One:
|
case EFluidState::InFluid:
|
||||||
{
|
{
|
||||||
if (x138_velocity.magnitude() > 1.f &&
|
if (x138_velocity.magnitude() > 1.f &&
|
||||||
mgr.GetFluidPlaneManager()->GetLastRippleDeltaTime(x8_uid) >= 0.2f)
|
mgr.GetFluidPlaneManager()->GetLastRippleDeltaTime(x8_uid) >= 0.2f)
|
||||||
{
|
{
|
||||||
zeus::CVector3f position(x34_transform.origin);
|
zeus::CVector3f position(x34_transform.origin);
|
||||||
position.z = water.GetTriggerBoundsWR().max.z;
|
position.z = water.GetTriggerBoundsWR().max.z;
|
||||||
water.GetFluidPlane().Ripple(0.5f, x8_uid, position, water, mgr);
|
water.GetFluidPlane().AddRipple(0.5f, x8_uid, position, water, mgr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EFluidState::Two:
|
case EFluidState::LeftFluid:
|
||||||
{
|
{
|
||||||
zeus::CVector3f position = x34_transform.origin + posOffset;
|
zeus::CVector3f position = x34_transform.origin + posOffset;
|
||||||
position.z = water.GetTriggerBoundsWR().max.z;
|
position.z = water.GetTriggerBoundsWR().max.z;
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "CScriptDamageableTrigger.hpp"
|
#include "CScriptDamageableTrigger.hpp"
|
||||||
#include "CActorParameters.hpp"
|
#include "CActorParameters.hpp"
|
||||||
#include "TCastTo.hpp"
|
#include "TCastTo.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
#include "CWorld.hpp"
|
||||||
|
#include "CScriptActor.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -22,14 +25,52 @@ CMaterialList MakeDamageableTriggerMaterial(CScriptDamageableTrigger::ECanOrbit
|
||||||
|
|
||||||
|
|
||||||
CScriptDamageableTrigger::CScriptDamageableTrigger(TUniqueId uid, const std::string& name, const CEntityInfo& info,
|
CScriptDamageableTrigger::CScriptDamageableTrigger(TUniqueId uid, const std::string& name, const CEntityInfo& info,
|
||||||
const zeus::CVector3f& position, const zeus::CVector3f& extent, const CHealthInfo&,
|
const zeus::CVector3f& position, const zeus::CVector3f& extent,
|
||||||
const CDamageVulnerability&, u32, CAssetId, CAssetId, CAssetId,
|
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
|
||||||
CScriptDamageableTrigger::ECanOrbit canOrbit, bool active, const CVisorParameters& vParams)
|
u32 faceFlag, CAssetId patternTex1, CAssetId patternTex2,
|
||||||
|
CAssetId colorTex, ECanOrbit canOrbit, bool active,
|
||||||
|
const CVisorParameters& vParams)
|
||||||
: CActor(uid, active, name, info, zeus::CTransform::Translate(position), CModelData::CModelDataNull(),
|
: CActor(uid, active, name, info, zeus::CTransform::Translate(position), CModelData::CModelDataNull(),
|
||||||
MakeDamageableTriggerMaterial(canOrbit), MakeDamageableTriggerActorParms(CActorParameters::None(), vParams),
|
MakeDamageableTriggerMaterial(canOrbit), MakeDamageableTriggerActorParms(CActorParameters::None(), vParams),
|
||||||
kInvalidUniqueId),
|
kInvalidUniqueId),
|
||||||
x14c_bounds(-extent * 0.5f, extent * 0.5f)
|
x14c_bounds(-extent * 0.5f, extent * 0.5f),
|
||||||
|
x164_origHInfo(hInfo), x16c_hInfo(hInfo), x174_dVuln(dVuln), x1dc_faceFlag(faceFlag),
|
||||||
|
x254_fluidPlane(patternTex1, patternTex2, colorTex, 1.f, 2,
|
||||||
|
CFluidPlane::EFluidType::NormalWater, 1.f, CFluidUVMotion(6.f, 0.f))
|
||||||
{
|
{
|
||||||
|
x300_28_canOrbit = canOrbit == ECanOrbit::Orbit;
|
||||||
|
if (x1dc_faceFlag & 0x1)
|
||||||
|
{
|
||||||
|
x244_faceTranslate = zeus::CVector3f(0.f, x14c_bounds.max.y, 0.f);
|
||||||
|
x1e4_faceDir = zeus::CTransform::RotateX(-M_PIF / 2.f);
|
||||||
|
}
|
||||||
|
else if (x1dc_faceFlag & 0x2)
|
||||||
|
{
|
||||||
|
x244_faceTranslate = zeus::CVector3f(0.f, x14c_bounds.min.y, 0.f);
|
||||||
|
x1e4_faceDir = zeus::CTransform::RotateX(M_PIF / 2.f);
|
||||||
|
}
|
||||||
|
else if (x1dc_faceFlag & 0x4)
|
||||||
|
{
|
||||||
|
x244_faceTranslate = zeus::CVector3f(x14c_bounds.min.x, 0.f, 0.f);
|
||||||
|
x1e4_faceDir = zeus::CTransform::RotateY(-M_PIF / 2.f);
|
||||||
|
}
|
||||||
|
else if (x1dc_faceFlag & 0x8)
|
||||||
|
{
|
||||||
|
x244_faceTranslate = zeus::CVector3f(x14c_bounds.max.x, 0.f, 0.f);
|
||||||
|
x1e4_faceDir = zeus::CTransform::RotateY(M_PIF / 2.f);
|
||||||
|
}
|
||||||
|
else if (x1dc_faceFlag & 0x10)
|
||||||
|
{
|
||||||
|
x244_faceTranslate = zeus::CVector3f(0.f, 0.f, x14c_bounds.max.z);
|
||||||
|
x1e4_faceDir = zeus::CTransform::Identity();
|
||||||
|
}
|
||||||
|
else if (x1dc_faceFlag & 0x20)
|
||||||
|
{
|
||||||
|
x244_faceTranslate = zeus::CVector3f(0.f, 0.f, x14c_bounds.min.z);
|
||||||
|
x1e4_faceDir = zeus::CTransform::RotateY(M_PIF);
|
||||||
|
}
|
||||||
|
|
||||||
|
x214_faceDirInv = x1e4_faceDir.inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptDamageableTrigger::Accept(IVisitor& visitor)
|
void CScriptDamageableTrigger::Accept(IVisitor& visitor)
|
||||||
|
@ -37,4 +78,160 @@ void CScriptDamageableTrigger::Accept(IVisitor& visitor)
|
||||||
visitor.Visit(this);
|
visitor.Visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScriptDamageableTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case EScriptObjectMessage::Deactivate:
|
||||||
|
if (x30_24_active && x300_25_alphaOut)
|
||||||
|
return;
|
||||||
|
case EScriptObjectMessage::Activate:
|
||||||
|
if (!x30_24_active || x300_25_alphaOut)
|
||||||
|
{
|
||||||
|
x250_alphaTimer = 0.f;
|
||||||
|
x16c_hInfo = x164_origHInfo;
|
||||||
|
x300_25_alphaOut = false;
|
||||||
|
if (x300_28_canOrbit)
|
||||||
|
AddMaterial(EMaterialTypes::Orbit, mgr);
|
||||||
|
SetLinkedObjectAlpha(0.f, mgr);
|
||||||
|
x1e0_alpha = 0.f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EScriptObjectMessage::Damage:
|
||||||
|
if (x300_27_invulnerable)
|
||||||
|
x16c_hInfo = x164_origHInfo;
|
||||||
|
break;
|
||||||
|
case EScriptObjectMessage::Increment:
|
||||||
|
x300_27_invulnerable = true;
|
||||||
|
break;
|
||||||
|
case EScriptObjectMessage::Decrement:
|
||||||
|
x300_27_invulnerable = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CActor::AcceptScriptMsg(msg, sender, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
EWeaponCollisionResponseTypes
|
||||||
|
CScriptDamageableTrigger::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
|
const CWeaponMode& weapMode, int) const
|
||||||
|
{
|
||||||
|
return x174_dVuln.WeaponHurts(weapMode, false) ? EWeaponCollisionResponseTypes::Unknown13 :
|
||||||
|
EWeaponCollisionResponseTypes::Unknown15;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptDamageableTrigger::Render(const CStateManager& mgr) const
|
||||||
|
{
|
||||||
|
if (x30_24_active && x1dc_faceFlag != 0 && std::fabs(x1e0_alpha) >= 0.00001f)
|
||||||
|
{
|
||||||
|
zeus::CAABox aabb = x14c_bounds.getTransformedAABox(x214_faceDirInv);
|
||||||
|
zeus::CTransform xf = x34_transform * zeus::CTransform::Translate(x244_faceTranslate) * x1e4_faceDir;
|
||||||
|
x254_fluidPlane.Render(mgr, x1e0_alpha, aabb, xf, zeus::CTransform::Identity(), false,
|
||||||
|
xe8_frustum, {}, kInvalidUniqueId, nullptr, 0, 0, zeus::CVector3f::skZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
CActor::Render(mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptDamageableTrigger::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const
|
||||||
|
{
|
||||||
|
if (x300_26_outOfFrustum)
|
||||||
|
return;
|
||||||
|
EnsureRendered(mgr, GetTranslation() - x244_faceTranslate, GetSortingBounds(mgr));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptDamageableTrigger::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
|
||||||
|
{
|
||||||
|
x300_26_outOfFrustum = !frustum.aabbFrustumTest(x14c_bounds.getTransformedAABox(x34_transform));
|
||||||
|
if (!x300_26_outOfFrustum)
|
||||||
|
{
|
||||||
|
xe8_frustum = frustum;
|
||||||
|
CActor::PreRender(mgr, frustum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptDamageableTrigger::SetLinkedObjectAlpha(float a, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
for (const SConnection& conn : x20_conns)
|
||||||
|
{
|
||||||
|
if (conn.x0_state != EScriptObjectState::MaxReached ||
|
||||||
|
conn.x4_msg != EScriptObjectMessage::Activate)
|
||||||
|
continue;
|
||||||
|
if (TCastToPtr<CScriptActor> act = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId)))
|
||||||
|
{
|
||||||
|
if (!act->GetActive())
|
||||||
|
act->SetActive(true);
|
||||||
|
act->SetDrawFlags(CModelFlags(5, 0, 3, zeus::CColor(1.f, a)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float CScriptDamageableTrigger::GetPuddleAlphaScale() const
|
||||||
|
{
|
||||||
|
if (x250_alphaTimer <= 0.75f)
|
||||||
|
{
|
||||||
|
if (x300_25_alphaOut)
|
||||||
|
return 1.f - x250_alphaTimer / 0.75f;
|
||||||
|
return x250_alphaTimer / 0.75f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x300_25_alphaOut)
|
||||||
|
return 0.f;
|
||||||
|
return 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CScriptDamageableTrigger::Think(float dt, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
if (!x30_24_active)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(x4_areaId);
|
||||||
|
CGameArea::EOcclusionState occState =
|
||||||
|
area->IsPostConstructed() ? area->GetOcclusionState() : CGameArea::EOcclusionState::Occluded;
|
||||||
|
x300_24_notOccluded = occState == CGameArea::EOcclusionState::Visible;
|
||||||
|
|
||||||
|
if (x300_25_alphaOut)
|
||||||
|
{
|
||||||
|
if (x250_alphaTimer >= 0.75f)
|
||||||
|
{
|
||||||
|
SetActive(false);
|
||||||
|
for (const SConnection& conn : x20_conns)
|
||||||
|
{
|
||||||
|
if (conn.x0_state != EScriptObjectState::MaxReached ||
|
||||||
|
conn.x4_msg != EScriptObjectMessage::Activate)
|
||||||
|
continue;
|
||||||
|
if (TCastToPtr<CScriptActor> act = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId)))
|
||||||
|
act->SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetLinkedObjectAlpha(0.f, mgr);
|
||||||
|
x300_25_alphaOut = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (x16c_hInfo.GetHP() <= 0.f && x30_24_active)
|
||||||
|
{
|
||||||
|
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
|
||||||
|
RemoveMaterial(EMaterialTypes::Orbit, mgr);
|
||||||
|
x300_25_alphaOut = true;
|
||||||
|
x250_alphaTimer = 0.f;
|
||||||
|
}
|
||||||
|
if (x250_alphaTimer <= 0.75f)
|
||||||
|
x250_alphaTimer += dt;
|
||||||
|
float objAlpha = GetPuddleAlphaScale();
|
||||||
|
x1e0_alpha = 0.2f * objAlpha;
|
||||||
|
SetLinkedObjectAlpha(objAlpha, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rstl::optional_object<zeus::CAABox> CScriptDamageableTrigger::GetTouchBounds() const
|
||||||
|
{
|
||||||
|
if (!x30_24_active || !x300_24_notOccluded)
|
||||||
|
return {};
|
||||||
|
return {zeus::CAABox(x14c_bounds.min + GetTranslation(), x14c_bounds.max + GetTranslation())};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#define CSCRIPTDAMAGEABLETRIGGER_HPP
|
#define CSCRIPTDAMAGEABLETRIGGER_HPP
|
||||||
|
|
||||||
#include "CActor.hpp"
|
#include "CActor.hpp"
|
||||||
|
#include "CFluidPlaneDoor.hpp"
|
||||||
|
#include "CHealthInfo.hpp"
|
||||||
|
#include "CDamageVulnerability.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
@ -15,13 +18,51 @@ public:
|
||||||
Orbit,
|
Orbit,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
zeus::CFrustum xe8_frustum;
|
||||||
zeus::CAABox x14c_bounds;
|
zeus::CAABox x14c_bounds;
|
||||||
|
CHealthInfo x164_origHInfo;
|
||||||
|
CHealthInfo x16c_hInfo;
|
||||||
|
CDamageVulnerability x174_dVuln;
|
||||||
|
u32 x1dc_faceFlag;
|
||||||
|
float x1e0_alpha = 1.f;
|
||||||
|
zeus::CTransform x1e4_faceDir;
|
||||||
|
zeus::CTransform x214_faceDirInv;
|
||||||
|
zeus::CVector3f x244_faceTranslate;
|
||||||
|
float x250_alphaTimer = 0.f;
|
||||||
|
CFluidPlaneDoor x254_fluidPlane;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
bool x300_24_notOccluded : 1;
|
||||||
|
bool x300_25_alphaOut : 1;
|
||||||
|
bool x300_26_outOfFrustum : 1;
|
||||||
|
bool x300_27_invulnerable : 1;
|
||||||
|
bool x300_28_canOrbit : 1;
|
||||||
|
};
|
||||||
|
u32 _dummy = 0;
|
||||||
|
};
|
||||||
|
void SetLinkedObjectAlpha(float a, CStateManager& mgr);
|
||||||
|
float GetPuddleAlphaScale() const;
|
||||||
public:
|
public:
|
||||||
CScriptDamageableTrigger(TUniqueId, const std::string&, const CEntityInfo&, const zeus::CVector3f&, const zeus::CVector3f&,
|
CScriptDamageableTrigger(TUniqueId uid, const std::string& name, const CEntityInfo& info,
|
||||||
const CHealthInfo&, const CDamageVulnerability&, u32, CAssetId, CAssetId, CAssetId, ECanOrbit, bool,
|
const zeus::CVector3f& position, const zeus::CVector3f& extent,
|
||||||
const CVisorParameters&);
|
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
|
||||||
|
u32 faceFlag, CAssetId patternTex1, CAssetId patternTex2,
|
||||||
|
CAssetId colorTex, ECanOrbit canOrbit, bool active,
|
||||||
|
const CVisorParameters& vParams);
|
||||||
|
|
||||||
void Accept(IVisitor& visitor);
|
void Accept(IVisitor& visitor);
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
|
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
|
const CWeaponMode&, int) const;
|
||||||
|
void Render(const CStateManager& mgr) const;
|
||||||
|
void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const;
|
||||||
|
void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum);
|
||||||
|
const CDamageVulnerability* GetDamageVulnerability() const { return &x174_dVuln; }
|
||||||
|
CHealthInfo* HealthInfo() { return &x16c_hInfo; }
|
||||||
|
void Think(float, CStateManager&);
|
||||||
|
rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,41 @@ void CScriptWater::SetupGridClipping(CStateManager& mgr, int computeVerts)
|
||||||
|
|
||||||
void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr)
|
void CScriptWater::UpdateSplashInhabitants(CStateManager& mgr)
|
||||||
{
|
{
|
||||||
// TODO: Do
|
for (auto it = x1fc_waterInhabitants.begin() ; it != x1fc_waterInhabitants.end() ;)
|
||||||
|
{
|
||||||
|
auto& inhab = *it;
|
||||||
|
TCastToPtr<CActor> act = mgr.ObjectById(inhab.first);
|
||||||
|
bool intersects = false;
|
||||||
|
if (act)
|
||||||
|
{
|
||||||
|
if (auto tb = act->GetTouchBounds())
|
||||||
|
{
|
||||||
|
zeus::CAABox thisTb = GetTriggerBoundsWR();
|
||||||
|
if (tb->min.z <= thisTb.max.z && tb->max.z >= thisTb.max.z)
|
||||||
|
intersects = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (act && inhab.second)
|
||||||
|
{
|
||||||
|
if (intersects)
|
||||||
|
act->FluidFXThink(EFluidState::InFluid, *this, mgr);
|
||||||
|
mgr.SendScriptMsg(act.GetPtr(), GetUniqueId(), EScriptObjectMessage::UpdateSplashInhabitant);
|
||||||
|
inhab.second = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it = x1fc_waterInhabitants.erase(it);
|
||||||
|
if (act)
|
||||||
|
{
|
||||||
|
if (intersects)
|
||||||
|
act->FluidFXThink(EFluidState::LeftFluid, *this, mgr);
|
||||||
|
mgr.SendScriptMsg(act.GetPtr(), GetUniqueId(), EScriptObjectMessage::RemoveSplashInhabitant);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptWater::Think(float dt, CStateManager& mgr)
|
void CScriptWater::Think(float dt, CStateManager& mgr)
|
||||||
|
@ -486,7 +520,7 @@ void CScriptWater::Touch(CActor& otherAct, CStateManager& mgr)
|
||||||
x1fc_waterInhabitants.emplace_back(otherAct.GetUniqueId(), true);
|
x1fc_waterInhabitants.emplace_back(otherAct.GetUniqueId(), true);
|
||||||
float triggerMaxZ = GetTriggerBoundsWR().max.z;
|
float triggerMaxZ = GetTriggerBoundsWR().max.z;
|
||||||
if (touchBounds->min.z <= triggerMaxZ && touchBounds->max.z >= triggerMaxZ)
|
if (touchBounds->min.z <= triggerMaxZ && touchBounds->max.z >= triggerMaxZ)
|
||||||
otherAct.FluidFXThink(EFluidState::Zero, *this, mgr);
|
otherAct.FluidFXThink(EFluidState::EnteredFluid, *this, mgr);
|
||||||
|
|
||||||
mgr.SendScriptMsg(&otherAct, x8_uid, EScriptObjectMessage::AddSplashInhabitant);
|
mgr.SendScriptMsg(&otherAct, x8_uid, EScriptObjectMessage::AddSplashInhabitant);
|
||||||
}
|
}
|
||||||
|
@ -510,11 +544,7 @@ zeus::CAABox CScriptWater::GetSortingBounds(const CStateManager& mgr) const
|
||||||
}
|
}
|
||||||
|
|
||||||
EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
|
EWeaponCollisionResponseTypes CScriptWater::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
<<<<<<< HEAD
|
|
||||||
CWeaponMode&, int)
|
|
||||||
=======
|
|
||||||
const CWeaponMode&, int) const
|
const CWeaponMode&, int) const
|
||||||
>>>>>>> 11d4aad746973443508adbff80b9da9eb0b4c60c
|
|
||||||
{
|
{
|
||||||
return EWeaponCollisionResponseTypes::Water;
|
return EWeaponCollisionResponseTypes::Water;
|
||||||
}
|
}
|
||||||
|
@ -566,4 +596,20 @@ const CScriptWater* CScriptWater::GetNextConnectedWater(const CStateManager& mgr
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CScriptWater::CanRippleAtPoint(const zeus::CVector3f& point) const
|
||||||
|
{
|
||||||
|
if (!x2d8_tileIntersects)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto xTile = int((point.x - GetTriggerBoundsOR().min.x) / x2c0_tileSize);
|
||||||
|
if (xTile < 0 || xTile >= x2c4_gridDimX)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto yTile = int((point.y - GetTriggerBoundsOR().min.y) / x2c0_tileSize);
|
||||||
|
if (xTile < 0 || xTile >= x2c8_gridDimY)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return x2d8_tileIntersects[yTile * x2c4_gridDimX + xTile];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,30 +25,16 @@ private:
|
||||||
float x1f4_morphOutTime;
|
float x1f4_morphOutTime;
|
||||||
float x1f8_morphFactor = 0.f;
|
float x1f8_morphFactor = 0.f;
|
||||||
std::list<std::pair<TUniqueId, bool>> x1fc_waterInhabitants;
|
std::list<std::pair<TUniqueId, bool>> x1fc_waterInhabitants;
|
||||||
<<<<<<< HEAD
|
|
||||||
float x214_fogBias;
|
float x214_fogBias;
|
||||||
float x218_fogMagnitude;
|
float x218_fogMagnitude;
|
||||||
float x21c_origFogBias;
|
float x21c_origFogBias;
|
||||||
float x220_origFogMagnitude;
|
float x220_origFogMagnitude;
|
||||||
float x224_fogSpeed;
|
float x224_fogSpeed;
|
||||||
zeus::CColor x228_fogColor;
|
zeus::CColor x228_fogColor;
|
||||||
ResId x22c_splashParticle1Id;
|
|
||||||
ResId x230_splashParticle2Id;
|
|
||||||
ResId x234_splashParticle3Id;
|
|
||||||
ResId x238_particle4Id;
|
|
||||||
=======
|
|
||||||
u32 x210_;
|
|
||||||
float x214_;
|
|
||||||
float x218_;
|
|
||||||
float x21c_;
|
|
||||||
float x220_;
|
|
||||||
float x224_;
|
|
||||||
zeus::CColor x228_;
|
|
||||||
CAssetId x22c_splashParticle1Id;
|
CAssetId x22c_splashParticle1Id;
|
||||||
CAssetId x230_splashParticle2Id;
|
CAssetId x230_splashParticle2Id;
|
||||||
CAssetId x234_splashParticle3Id;
|
CAssetId x234_splashParticle3Id;
|
||||||
CAssetId x238_particle4Id;
|
CAssetId x238_particle4Id;
|
||||||
>>>>>>> 11d4aad746973443508adbff80b9da9eb0b4c60c
|
|
||||||
std::experimental::optional<TLockedToken<CGenDescription>> x23c_;
|
std::experimental::optional<TLockedToken<CGenDescription>> x23c_;
|
||||||
CAssetId x24c_particle5Id;
|
CAssetId x24c_particle5Id;
|
||||||
std::experimental::optional<TLockedToken<CGenDescription>> x250_visorRunoffEffect;
|
std::experimental::optional<TLockedToken<CGenDescription>> x250_visorRunoffEffect;
|
||||||
|
@ -117,8 +103,8 @@ public:
|
||||||
void Touch(CActor &, CStateManager &);
|
void Touch(CActor &, CStateManager &);
|
||||||
void CalculateRenderBounds();
|
void CalculateRenderBounds();
|
||||||
zeus::CAABox GetSortingBounds(const CStateManager&) const;
|
zeus::CAABox GetSortingBounds(const CStateManager&) const;
|
||||||
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, CWeaponMode&,
|
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
int);
|
const CWeaponMode&, int) const;
|
||||||
|
|
||||||
s16 GetSplashSound(float) const;
|
s16 GetSplashSound(float) const;
|
||||||
const std::experimental::optional<TLockedToken<CGenDescription>>& GetSplashEffect(float) const;
|
const std::experimental::optional<TLockedToken<CGenDescription>>& GetSplashEffect(float) const;
|
||||||
|
@ -141,6 +127,7 @@ public:
|
||||||
u8 GetPatchRenderFlags(int x, int y) const { return x2e0_patchIntersects[y * x2d0_patchDimX + x]; }
|
u8 GetPatchRenderFlags(int x, int y) const { return x2e0_patchIntersects[y * x2d0_patchDimX + x]; }
|
||||||
int GetPatchDimensionX() const { return x2d0_patchDimX; }
|
int GetPatchDimensionX() const { return x2d0_patchDimX; }
|
||||||
int GetPatchDimensionY() const { return x2d4_patchDimY; }
|
int GetPatchDimensionY() const { return x2d4_patchDimY; }
|
||||||
|
bool CanRippleAtPoint(const zeus::CVector3f& point) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1111,14 +1111,14 @@ CEntity* ScriptLoader::LoadDamageableTrigger(CStateManager& mgr, CInputStream& i
|
||||||
CDamageVulnerability dVuln(in);
|
CDamageVulnerability dVuln(in);
|
||||||
u32 triggerFlags = in.readUint32Big();
|
u32 triggerFlags = in.readUint32Big();
|
||||||
triggerFlags = TransformDamagableTriggerFlags(mgr, info.GetAreaId(), triggerFlags);
|
triggerFlags = TransformDamagableTriggerFlags(mgr, info.GetAreaId(), triggerFlags);
|
||||||
CAssetId w1 = in.readUint32Big();
|
CAssetId patternTex1 = in.readUint32Big();
|
||||||
CAssetId w2 = in.readUint32Big();
|
CAssetId patternTex2 = in.readUint32Big();
|
||||||
CAssetId w3 = in.readUint32Big();
|
CAssetId colorTex = in.readUint32Big();
|
||||||
CScriptDamageableTrigger::ECanOrbit canOrbit = CScriptDamageableTrigger::ECanOrbit(in.readBool());
|
CScriptDamageableTrigger::ECanOrbit canOrbit = CScriptDamageableTrigger::ECanOrbit(in.readBool());
|
||||||
bool active = in.readBool();
|
bool active = in.readBool();
|
||||||
CVisorParameters vParms = LoadVisorParameters(in);
|
CVisorParameters vParms = LoadVisorParameters(in);
|
||||||
return new CScriptDamageableTrigger(mgr.AllocateUniqueId(), name, info, position, volume, hInfo, dVuln,
|
return new CScriptDamageableTrigger(mgr.AllocateUniqueId(), name, info, position, volume, hInfo, dVuln,
|
||||||
triggerFlags, w1, w2, w3, canOrbit, active, vParms);
|
triggerFlags, patternTex1, patternTex2, colorTex, canOrbit, active, vParms);
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadDebris(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
CEntity* ScriptLoader::LoadDebris(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||||
|
|
Loading…
Reference in New Issue