/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "Rain_precompiled.h" #include "Rain.h" #include "IActorSystem.h" #include "RainComponentBus.h" namespace LYGame { DECLARE_DEFAULT_COMPONENT_FACTORY(CRain, CRain) CRain::CRain() : m_bEnabled(false) { } CRain::~CRain() { for (TTextureList::iterator it = m_Textures.begin(), itEnd = m_Textures.end(); it != itEnd; ++it) { (*it)->Release(); } } //------------------------------------------------------------------------ bool CRain::Init(IGameObject* pGameObject) { SetGameObject(pGameObject); #if !defined(NULL_RENDERER) PreloadTextures(); #endif return Reset(); } //------------------------------------------------------------------------ void CRain::PreloadTextures() { uint32 nDefaultFlags = FT_DONT_STREAM; XmlNodeRef root = GetISystem()->LoadXmlFromFile("@assets@/raintextures.xml"); if (root) { for (int i = 0; i < root->getChildCount(); i++) { XmlNodeRef entry = root->getChild(i); if (!entry->isTag("entry")) { continue; } uint32 nFlags = nDefaultFlags; // check attributes to modify the loading flags int nNoMips = 0; if (entry->getAttr("nomips", nNoMips) && nNoMips) { nFlags |= FT_NOMIPS; } ITexture* pTexture = gEnv->pRenderer->EF_LoadTexture(entry->getContent(), nFlags); if (pTexture) { m_Textures.push_back(pTexture); } } } } //------------------------------------------------------------------------ void CRain::PostInit(IGameObject* pGameObject) { GetGameObject()->EnableUpdateSlot(this, 0); } //------------------------------------------------------------------------ bool CRain::ReloadExtension(IGameObject* pGameObject, const SEntitySpawnParams& params) { ResetGameObject(); CRY_ASSERT_MESSAGE(false, "CRain::ReloadExtension not implemented"); return false; } //------------------------------------------------------------------------ bool CRain::GetEntityPoolSignature(TSerialize signature) { CRY_ASSERT_MESSAGE(false, "CRain::GetEntityPoolSignature not implemented"); return true; } //------------------------------------------------------------------------ void CRain::FullSerialize(TSerialize ser) { ser.Value("bEnabled", m_bEnabled); ser.Value("bIgnoreVisareas", m_params.bIgnoreVisareas); ser.Value("bDisableOcclusion", m_params.bDisableOcclusion); ser.Value("fRadius", m_params.fRadius); ser.Value("fAmount", m_params.fAmount); ser.Value("fDiffuseDarkening", m_params.fDiffuseDarkening); ser.Value("fRainDropsAmount", m_params.fRainDropsAmount); ser.Value("fRainDropsSpeed", m_params.fRainDropsSpeed); ser.Value("fRainDropsLighting", m_params.fRainDropsLighting); ser.Value("fPuddlesAmount", m_params.fPuddlesAmount); ser.Value("fPuddlesMaskAmount", m_params.fPuddlesMaskAmount); ser.Value("fPuddlesRippleAmount", m_params.fPuddlesRippleAmount); ser.Value("fSplashesAmount", m_params.fSplashesAmount); } //------------------------------------------------------------------------ void CRain::Update(SEntityUpdateContext& ctx, int updateSlot) { if (GetISystem()->GetIGame()->GetIGameFramework()->IsEditing()) { return; } if (Reset()) { const Vec3 vCamPos = gEnv->pRenderer->GetCamera().GetPosition(); const Vec3 worldPos = GetEntity()->GetWorldPos(); const Vec3 diff = worldPos - vCamPos; Vec3 vR = (diff) / max(m_params.fRadius, 1e-3f); float fAttenAmount = max(0.f, 1.0f - vR.dot(vR)); fAttenAmount *= m_params.fAmount; // Force set if current values not valid SRainParams currRainParams; bool bSet = !gEnv->p3DEngine->GetRainParams(currRainParams); // Set if stronger bSet |= fAttenAmount > currRainParams.fCurrentAmount; if (bSet) { m_params.vWorldPos = GetEntity()->GetWorldPos(); m_params.qRainRotation = GetEntity()->GetWorldRotation(); m_params.fCurrentAmount = fAttenAmount; // Remove Z axis rotation as it solely affects occlusion quality (not in a good way!) Ang3 rainRot(m_params.qRainRotation); rainRot.z = 0.0f; m_params.qRainRotation.SetRotationXYZ(rainRot); m_params.qRainRotation.NormalizeSafe(); gEnv->p3DEngine->SetRainParams(m_params); } } } //------------------------------------------------------------------------ void CRain::HandleEvent(const SGameObjectEvent& event) { } //------------------------------------------------------------------------ void CRain::ProcessEvent(SEntityEvent& event) { switch (event.event) { case ENTITY_EVENT_RESET: Reset(); break; case ENTITY_EVENT_HIDE: case ENTITY_EVENT_DONE: if (gEnv && gEnv->p3DEngine) { static const Vec3 vZero(ZERO); SRainParams rainParams; rainParams.fAmount = 0.f; rainParams.vWorldPos = vZero; gEnv->p3DEngine->SetRainParams(rainParams); //If any other rain components exist, broadcast to them that they should re-update the rain params //This is useful if two rain components exist and one is deleted; some other component's rain params sould //still be applied. This is just for preview in-editor. Rain::RainComponentRequestBus::Broadcast(&Rain::RainComponentRequestBus::Events::UpdateRain); } break; } } //------------------------------------------------------------------------ void CRain::SetAuthority(bool auth) { } //------------------------------------------------------------------------ bool CRain::Reset() { //Initialize default values before (in case ScriptTable fails) m_bEnabled = false; m_params.bIgnoreVisareas = false; m_params.bDisableOcclusion = false; m_params.fRadius = 10000.f; m_params.fAmount = 1.f; m_params.fDiffuseDarkening = 0.5f; m_params.fPuddlesAmount = 1.5f; m_params.fPuddlesMaskAmount = 1.0f; m_params.fPuddlesRippleAmount = 2.0f; m_params.fRainDropsAmount = 0.5f; m_params.fRainDropsSpeed = 1.f; m_params.fRainDropsLighting = 1.f; m_params.fSplashesAmount = 1.3f; SmartScriptTable props; IScriptTable* pScriptTable = GetEntity()->GetScriptTable(); if (!pScriptTable || !pScriptTable->GetValue("Properties", props)) { return false; } props->GetValue("bIgnoreVisareas", m_params.bIgnoreVisareas); props->GetValue("bDisableOcclusion", m_params.bDisableOcclusion); props->GetValue("fRadius", m_params.fRadius); props->GetValue("fAmount", m_params.fAmount); props->GetValue("fDiffuseDarkening", m_params.fDiffuseDarkening); props->GetValue("fRainDropsAmount", m_params.fRainDropsAmount); props->GetValue("fRainDropsSpeed", m_params.fRainDropsSpeed); props->GetValue("fRainDropsLighting", m_params.fRainDropsLighting); props->GetValue("fPuddlesAmount", m_params.fPuddlesAmount); props->GetValue("fPuddlesMaskAmount", m_params.fPuddlesMaskAmount); props->GetValue("fPuddlesRippleAmount", m_params.fPuddlesRippleAmount); props->GetValue("fSplashesAmount", m_params.fSplashesAmount); props->GetValue("bEnabled", m_bEnabled); if (!m_bEnabled && !gEnv->IsEditorSimulationMode() && !gEnv->IsEditorGameMode()) { m_params.fAmount = 0; } return true; } } // LYGame