123
This commit is contained in:
395
Cry3DEngine/ParticleEffect.cpp
Normal file
395
Cry3DEngine/ParticleEffect.cpp
Normal file
@@ -0,0 +1,395 @@
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Engine Source File.
|
||||
// Copyright (C), Crytek Studios, 2002.
|
||||
// -------------------------------------------------------------------------
|
||||
// File name: particleeffect.cpp
|
||||
// Version: v1.00
|
||||
// Created: 10/7/2003 by Timur.
|
||||
// Compilers: Visual Studio.NET
|
||||
// Description:
|
||||
// -------------------------------------------------------------------------
|
||||
// History:
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "ParticleEffect.h"
|
||||
#include "ParticleEmitter.h"
|
||||
#include "PartMan.h"
|
||||
#include "3DEngine.h"
|
||||
#include "ISound.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CParticleEffect::CParticleEffect( CPartManager *pPartManager )
|
||||
{
|
||||
assert( pPartManager );
|
||||
m_pPartManager = pPartManager;
|
||||
m_bLoaded = false;
|
||||
m_bEnabled = true;
|
||||
|
||||
m_soundVolume = 100;
|
||||
m_soundMinRadius = 1;
|
||||
m_soundMaxRadius = 10;
|
||||
m_bSoundLoop = true;
|
||||
m_bOnEverySpawn = false;
|
||||
|
||||
m_bAnimatedTexture[0] = false;
|
||||
m_bAnimatedTexture[1] = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CParticleEffect::~CParticleEffect()
|
||||
{
|
||||
UnloadResources();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::SetName( const char *sName )
|
||||
{
|
||||
m_pPartManager->RenameEffect( this,sName );
|
||||
|
||||
m_name = sName;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::SetTexture( int process,const char *s )
|
||||
{
|
||||
if (m_texture[process] != s)
|
||||
{
|
||||
UnloadResources(false);
|
||||
m_texture[process] = s;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::SetGeometry( int process,const char *s )
|
||||
{
|
||||
if (m_geometry[process] != s)
|
||||
{
|
||||
UnloadResources(false);
|
||||
m_geometry[process] = s;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CParticleEffect::GetChildCount() const
|
||||
{
|
||||
return (int)m_childs.size();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
IParticleEffect* CParticleEffect::GetChild( int index ) const
|
||||
{
|
||||
assert( index >= 0 && index < (int)m_childs.size() );
|
||||
return m_childs[index];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::AddChild( IParticleEffect *pEffect )
|
||||
{
|
||||
assert( pEffect );
|
||||
m_childs.push_back(pEffect);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::RemoveChild( IParticleEffect *pEffect )
|
||||
{
|
||||
assert( pEffect );
|
||||
stl::find_and_erase( m_childs,pEffect );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::ClearChilds()
|
||||
{
|
||||
m_childs.clear();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::InsertChild( int slot,IParticleEffect *pEffect )
|
||||
{
|
||||
if (slot < 0)
|
||||
slot = 0;
|
||||
if (slot > (int)m_childs.size())
|
||||
slot = (int)m_childs.size();
|
||||
|
||||
assert( pEffect );
|
||||
m_childs.insert( m_childs.begin() + slot,pEffect );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
int CParticleEffect::FindChild( IParticleEffect *pEffect ) const
|
||||
{
|
||||
for (int i = 0; i < (int)m_childs.size(); i++)
|
||||
{
|
||||
if (m_childs[i] == pEffect)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::LoadResources( bool bRecursive )
|
||||
{
|
||||
if (m_bLoaded)
|
||||
return;
|
||||
m_bLoaded = true;
|
||||
|
||||
for (int i = 0; i < NUM_PARTICLE_PROCESSES; i++)
|
||||
{
|
||||
if (!m_material[i].empty() && !m_pMaterials[i])
|
||||
AssignMaterial( i );
|
||||
|
||||
bool bNeedAnimatedTex = m_particleParams[i].nTexAnimFramesCount > 0;
|
||||
// First unload what is loaded.
|
||||
if (m_particleParams[i].nTexId != 0)
|
||||
{
|
||||
GetRenderer()->RemoveTexture( m_particleParams[i].nTexId );
|
||||
m_particleParams[i].nTexId = 0;
|
||||
if(m_particleParams[i].pAnimTex)
|
||||
GetRenderer()->RemoveAnimatedTexture(m_particleParams[i].pAnimTex);
|
||||
m_particleParams[i].pAnimTex = 0;
|
||||
}
|
||||
if (m_particleParams[i].pStatObj)
|
||||
{
|
||||
Get3DEngine()->ReleaseObject( m_particleParams[i].pStatObj );
|
||||
m_particleParams[i].pStatObj = 0;
|
||||
}
|
||||
|
||||
// Load textures.
|
||||
if (!m_texture[i].empty())
|
||||
{
|
||||
if (bNeedAnimatedTex)
|
||||
{
|
||||
int texid = GetRenderer()->LoadAnimatedTexture( m_texture[i].c_str(),m_particleParams[i].nTexAnimFramesCount );
|
||||
m_particleParams[i].nTexId = texid;
|
||||
m_particleParams[i].pAnimTex = GetRenderer()->GetAnimTexInfoFromId(texid);
|
||||
if(!m_particleParams[i].pAnimTex)
|
||||
{
|
||||
#if !defined(LINUX)
|
||||
Warning( 0,0,"ParticleEffect %s, Use Invalid Animated Texture Id %d",m_name.c_str(),texid );
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(NULL_RENDERER)
|
||||
m_particleParams[i].nTexId = 0;
|
||||
#else
|
||||
m_particleParams[i].nTexId = GetRenderer()->LoadTexture( m_texture[i].c_str() );
|
||||
#endif
|
||||
m_particleParams[i].pAnimTex = 0;
|
||||
}
|
||||
m_bAnimatedTexture[i] = bNeedAnimatedTex;
|
||||
}
|
||||
// Load geometry.
|
||||
if (!m_geometry[i].empty())
|
||||
{
|
||||
m_particleParams[i].pStatObj = Get3DEngine()->MakeObject( m_geometry[i].c_str() );
|
||||
}
|
||||
}
|
||||
if (bRecursive)
|
||||
{
|
||||
for (int i = 0; i < (int)m_childs.size(); i++)
|
||||
{
|
||||
IParticleEffect *pChild = m_childs[i];
|
||||
((CParticleEffect*)pChild)->LoadResources( bRecursive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::UnloadResources( bool bRecursive )
|
||||
{
|
||||
if (!m_bLoaded)
|
||||
return;
|
||||
m_bLoaded = false;
|
||||
|
||||
for (int i = 0; i < NUM_PARTICLE_PROCESSES; i++)
|
||||
{
|
||||
if (m_particleParams[i].nTexId != 0)
|
||||
{
|
||||
GetRenderer()->RemoveTexture( m_particleParams[i].nTexId );
|
||||
m_particleParams[i].nTexId = 0;
|
||||
if(m_particleParams[i].pAnimTex)
|
||||
GetRenderer()->RemoveAnimatedTexture(m_particleParams[i].pAnimTex);
|
||||
m_particleParams[i].pAnimTex = 0;
|
||||
}
|
||||
if (m_particleParams[i].pStatObj)
|
||||
{
|
||||
Get3DEngine()->ReleaseObject( m_particleParams[i].pStatObj );
|
||||
m_particleParams[i].pStatObj = 0;
|
||||
}
|
||||
}
|
||||
if (bRecursive)
|
||||
{
|
||||
for (int i = 0; i < (int)m_childs.size(); i++)
|
||||
{
|
||||
IParticleEffect *pChild = m_childs[i];
|
||||
((CParticleEffect*)pChild)->UnloadResources( bRecursive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::SetSoundParams( const SoundParams ¶ms )
|
||||
{
|
||||
m_sound = params.szSound;
|
||||
m_soundVolume = params.volume;
|
||||
m_soundMinRadius = params.minRadius;
|
||||
m_soundMaxRadius = params.maxRadius;
|
||||
m_bSoundLoop = params.bLoop;
|
||||
m_bOnEverySpawn = params.bOnEverySpawn;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::GetSoundParams( SoundParams ¶ms ) const
|
||||
{
|
||||
params.szSound = m_sound.c_str();
|
||||
params.volume = m_soundVolume;
|
||||
params.minRadius = m_soundMinRadius;
|
||||
params.maxRadius = m_soundMaxRadius;
|
||||
params.bLoop = m_bSoundLoop;
|
||||
params.bOnEverySpawn = m_bOnEverySpawn;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::Spawn( const Vec3 &pos,const Vec3 &dir,float fScale )
|
||||
{
|
||||
if (m_bEnabled)
|
||||
{
|
||||
// Spawn emitter for this particle.
|
||||
if (!IsResourcesLoaded())
|
||||
{
|
||||
LoadResources();
|
||||
}
|
||||
if (m_particleParams[1].nCount > 0)
|
||||
{
|
||||
m_particleParams[0].pChild = &m_particleParams[1];
|
||||
}
|
||||
else
|
||||
m_particleParams[0].pChild = 0;
|
||||
|
||||
m_particleParams[0].pEntity = 0;
|
||||
m_particleParams[1].pEntity = 0;
|
||||
|
||||
// Spawn particle system emitter.
|
||||
CParticleEmitter *pEmitter = new CParticleEmitter(m_pPartManager);
|
||||
pEmitter->m_bPermament = false;
|
||||
pEmitter->AssignEffect( this,false );
|
||||
pEmitter->SetPos( pos,dir,fScale );
|
||||
}
|
||||
// Spawn child effects.
|
||||
for (int i = 0; i < (int)m_childs.size(); i++)
|
||||
{
|
||||
m_childs[i]->Spawn( pos,dir,fScale );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CParticleEffect::PrepareSpawn( const Vec3 &pos )
|
||||
{
|
||||
if (!m_bEnabled)
|
||||
return false;
|
||||
|
||||
if (!IsResourcesLoaded())
|
||||
{
|
||||
LoadResources();
|
||||
}
|
||||
|
||||
/*
|
||||
// Play sound if not looped.
|
||||
if (!m_bSoundLoop && !m_sound.empty())
|
||||
{
|
||||
ISound *pSound = GetSystem()->GetISoundSystem()->LoadSound( m_sound.c_str(),FLAG_SOUND_3D );
|
||||
if (pSound)
|
||||
{
|
||||
pSound->SetVolume( (int)m_soundVolume );
|
||||
pSound->SetMinMaxDistance( m_soundMinRadius,m_soundMaxRadius );
|
||||
pSound->SetPosition(pos);
|
||||
pSound->Play();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Init child process pointer.
|
||||
if (m_particleParams[1].nCount > 0)
|
||||
m_particleParams[0].pChild = &m_particleParams[1];
|
||||
else
|
||||
m_particleParams[0].pChild = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
bool CParticleEffect::IsResourcesLoaded()
|
||||
{
|
||||
bool bAnimatedTex0 = m_particleParams[0].nTexAnimFramesCount > 0;
|
||||
bool bAnimatedTex1 = m_particleParams[1].nTexAnimFramesCount > 0;
|
||||
if (bAnimatedTex0 != m_bAnimatedTexture[0] || bAnimatedTex1 != m_bAnimatedTexture[1])
|
||||
{
|
||||
UnloadResources(false);
|
||||
}
|
||||
|
||||
return m_bLoaded;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::SetMaterial( int process,IMatInfo *pMaterial )
|
||||
{
|
||||
assert( process >= 0 && process < NUM_PARTICLE_PROCESSES );
|
||||
m_pMaterials[process] = pMaterial;
|
||||
if (pMaterial)
|
||||
pMaterial->SetFlags(pMaterial->GetFlags()|MIF_WASUSED);
|
||||
m_particleParams[process].pMaterial = pMaterial;
|
||||
if (pMaterial)
|
||||
{
|
||||
m_material[process] = pMaterial->GetName();
|
||||
}
|
||||
else
|
||||
m_material[process] = "";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::SetMaterialName( int process,const char *sMtlName )
|
||||
{
|
||||
assert( process >= 0 && process < NUM_PARTICLE_PROCESSES );
|
||||
m_material[process] = sMtlName;
|
||||
AssignMaterial( process );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
const char* CParticleEffect::GetMaterialName( int process ) const
|
||||
{
|
||||
assert( process >= 0 && process < NUM_PARTICLE_PROCESSES );
|
||||
return m_material[process].c_str();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CParticleEffect::AssignMaterial( int process )
|
||||
{
|
||||
assert( process >= 0 && process < NUM_PARTICLE_PROCESSES );
|
||||
IMatInfo *pMtl = 0;
|
||||
if (m_material[process].empty())
|
||||
{
|
||||
pMtl = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pMtl = Get3DEngine()->FindMaterial( m_material[process].c_str() );
|
||||
if (!pMtl)
|
||||
{
|
||||
#if !defined(LINUX)
|
||||
Warning( 0,0,"ParticleEffect %s material assign failed, Material %s not found",m_name.c_str(),m_material[process].c_str() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(pMtl)
|
||||
pMtl->SetFlags(pMtl->GetFlags()|MIF_WASUSED);
|
||||
m_pMaterials[process] = pMtl;
|
||||
m_particleParams[process].pMaterial = pMtl;
|
||||
}
|
||||
Reference in New Issue
Block a user