370 lines
13 KiB
C++
370 lines
13 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2002.
|
|
// -------------------------------------------------------------------------
|
|
// File name: particleexporter.cpp
|
|
// Version: v1.00
|
|
// Created: 12/9/2003 by Timur.
|
|
// Compilers: Visual Studio.NET
|
|
// Description:
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "StdAfx.h"
|
|
#include "ParticleExporter.h"
|
|
|
|
#include "Util\PakFile.h"
|
|
|
|
#include "Particles\ParticleItem.h"
|
|
#include "Particles\ParticleLibrary.h"
|
|
#include "Particles\ParticleManager.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Signatures for particles.lst file.
|
|
#define PARTICLES_FILE_TYPE 2
|
|
#define PARTICLES_FILE_VERSION 4
|
|
#define PARTICLES_FILE_SIGNATURE "CRY"
|
|
|
|
#define PARTICLES_FILE "particles.lst"
|
|
|
|
#define EFFECTS_PAK_FILE "FCData\\Effects.pak"
|
|
#define EFFECTS_FOLDER "Effects\\"
|
|
|
|
#pragma pack(push,1)
|
|
//////////////////////////////////////////////////////////////////////////
|
|
struct SExportedParticlesHeader
|
|
{
|
|
char signature[3]; // File signature.
|
|
int filetype; // File type.
|
|
int version; // File version.
|
|
};
|
|
|
|
struct SExportParticleSound
|
|
{
|
|
enum {
|
|
LOOP = 0x01,
|
|
EVERY_SPAWN = 0x02,
|
|
};
|
|
char soundfile[64];
|
|
float volume;
|
|
float minRadius;
|
|
float maxRadius;
|
|
char nSoundFlags;
|
|
};
|
|
|
|
enum EParticleExportFlags
|
|
{
|
|
PARTICLE_EFFECT_DISABLED = 0x01
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//! Particle system parameters
|
|
struct SExportParticleParams
|
|
{
|
|
Vec3 vPosition; // spawn position
|
|
Vec3 vDirection; // initial direction (normalization not important)
|
|
float fFocus; // if 0 - particles go in all directions, if more than 20 - particles go mostly in vDirection
|
|
Vec3 vColorStart; // initial color
|
|
Vec3 vColorEnd; // final color
|
|
FloatVariant fSpeed; // initial speed ( +- 25% random factor applyed, m/sec )
|
|
float fSpeedFadeOut; // Time in which before end of life time speed decreases from normal to 0.
|
|
float fSpeedAccel; // Constant speed acceleration along particle heading.
|
|
float fAirResistance; // Coefficient of Air Resistance.
|
|
Vec3Variant vRotation; // rotation speed (degree/sec)
|
|
Vec3Variant vInitAngles; // initial rotation
|
|
int nCount; // number of particles to spawn
|
|
FloatVariant fSize; // initial size of particles
|
|
float fSizeSpeed; // particles will grow with this speed
|
|
float fSizeFadeIn; // Time in which at the begning of life time size goes from 0 to fSize.
|
|
float fSizeFadeOut; // Time in which at the end of life time size goes from fSize to 0.
|
|
float fThickness; // lying thickness - for physicalized particles only
|
|
FloatVariant fLifeTime; // time of life of particle
|
|
float fFadeInTime; // particle will fade in slowly during this time
|
|
int nTexAnimFramesCount; // number of frames in animated texture ( 0 if no animation )
|
|
ParticleBlendType eBlendType; // see ParticleBlendType
|
|
float fTailLenght; // delay of tail ( 0 - no tail, 1 meter if speed is 1 meter/sec )
|
|
float fStretch; // Stretch particles into moving direction.
|
|
int nParticleFlags; // see particle system flags
|
|
bool bRealPhysics; // use physics engine to control particles
|
|
float fChildSpawnPeriod; // if more than 0 - run child process every x seconds, if 0 - run it at collision
|
|
float fChildSpawnTime; // if more then 0, Spawn child process for max this ammount of time.
|
|
int nDrawLast; // add this element into second list and draw this list last
|
|
float fBouncenes; // if 0 - particle will not bounce from the ground, 0.5 is good in most cases
|
|
float fTurbulenceSize; // radius of turbulence
|
|
float fTurbulenceSpeed; // speed of rotation
|
|
float fDirVecScale; //the game need to store this(Alberto)
|
|
float fPosRandomOffset; // maximum distance of random offset from original position
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// New parameters, used by Particle effects.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//! Spawn Position offset from effect spawn position.
|
|
Vec3 vPositionOffset;
|
|
//! Random offset of particle relative to spawn position.
|
|
Vec3 vRandomPositionOffset;
|
|
//! Delay actual spawn time by this ammount.
|
|
FloatVariant fSpawnDelay;
|
|
//! Life time of emitter.
|
|
FloatVariant fEmitterLifeTime;
|
|
//! When using emitter, spawn time between between 2 particle bursts.
|
|
float fSpawnPeriod;
|
|
|
|
//! Global effect scale. (0 ignored)
|
|
float fScale;
|
|
//! Object scale, multiplied with fSize to give scale adjustment between object and texture.
|
|
//! 0 not affect fSize.
|
|
float fObjectScale;
|
|
|
|
Vec3 vNormal; // lying normal - for physicalized particles only
|
|
int iPhysMat; // material for physicalized particles
|
|
Vec3 vGravity; // gravity(wind) vector
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
unsigned short nTailSteps;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Reserve space for new members.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
char reserve[126];
|
|
};
|
|
|
|
struct SExportParticleEffect
|
|
{
|
|
char name[64];
|
|
char texture[2][64];
|
|
char geometry[2][64];
|
|
char material[2][64];
|
|
SExportParticleParams params[2]; // Primary and Child params.
|
|
SExportParticleSound sound;
|
|
int parent; // Index of parent particle.
|
|
int flags; // General flags.
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define PATICLEPARAMS_COPY_HELPER( inparam,outparam,name ) outparam.name = inparam.name;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
static void ParticleParamsToExportData( const ParticleParams &inp,SExportParticleParams &outp )
|
|
{
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vPosition );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vDirection );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fFocus );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vColorStart );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vColorEnd );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSpeed );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSpeedFadeOut );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSpeedAccel );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fAirResistance );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vRotation );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vInitAngles );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,nCount );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSize );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSizeSpeed );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSizeFadeIn );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSizeFadeOut );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fThickness );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fLifeTime );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fFadeInTime );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,nTexAnimFramesCount );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,eBlendType );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fTailLenght );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,nTailSteps );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fStretch );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,nParticleFlags );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,bRealPhysics );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fChildSpawnPeriod );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fChildSpawnTime );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,nDrawLast );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fBouncenes );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fTurbulenceSize );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fTurbulenceSpeed );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fDirVecScale );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fPosRandomOffset );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vPositionOffset );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vRandomPositionOffset );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSpawnDelay );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fEmitterLifeTime );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fSpawnPeriod );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fScale );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,fObjectScale );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vNormal );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,iPhysMat );
|
|
PATICLEPARAMS_COPY_HELPER( inp,outp,vGravity );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CParticlesExporter::AddParticleExportItem( std::vector<SExportParticleEffect> &effects,CParticleItem *pItem,int parent )
|
|
{
|
|
SExportParticleEffect exportData;
|
|
ZeroStruct(exportData);
|
|
|
|
exportData.parent = parent;
|
|
|
|
strncpy( exportData.name,pItem->GetFullName(),sizeof(exportData.name) );
|
|
exportData.name[sizeof(exportData.name)-1] = 0;
|
|
|
|
IParticleEffect *pEffect = pItem->GetEffect();
|
|
if (!pEffect)
|
|
return;
|
|
for (int p = 0; p < IParticleEffect::NUM_PARTICLE_PROCESSES; p++)
|
|
{
|
|
ParticleParamsToExportData( pEffect->GetParticleParams(p),exportData.params[p] );
|
|
|
|
strncpy( exportData.texture[p],pEffect->GetTexture(p),sizeof(exportData.texture[0])-1 );
|
|
strncpy( exportData.geometry[p],pEffect->GetGeometry(p),sizeof(exportData.geometry[0])-1 );
|
|
if (pEffect->GetMaterial(p))
|
|
{
|
|
strncpy( exportData.material[p],pEffect->GetMaterial(p)->GetName(),sizeof(exportData.material[0])-1 );
|
|
}
|
|
}
|
|
|
|
if (!pEffect->IsEnabled())
|
|
exportData.flags |= PARTICLE_EFFECT_DISABLED;
|
|
|
|
IParticleEffect::SoundParams sndParams;
|
|
pEffect->GetSoundParams(sndParams);
|
|
strncpy( exportData.sound.soundfile,sndParams.szSound,sizeof(exportData.sound.soundfile) );
|
|
exportData.sound.soundfile[sizeof(exportData.sound.soundfile)-1] = 0;
|
|
exportData.sound.volume = sndParams.volume;
|
|
exportData.sound.minRadius = sndParams.minRadius;
|
|
exportData.sound.maxRadius = sndParams.maxRadius;
|
|
exportData.sound.nSoundFlags = 0;
|
|
exportData.sound.nSoundFlags |= (sndParams.bLoop) ? SExportParticleSound::LOOP : 0;
|
|
exportData.sound.nSoundFlags |= (sndParams.bOnEverySpawn) ? SExportParticleSound::EVERY_SPAWN : 0;
|
|
|
|
effects.push_back( exportData );
|
|
int currentId = effects.size()-1;
|
|
for (int i = 0; i < pItem->GetChildCount(); i++)
|
|
{
|
|
AddParticleExportItem( effects,pItem->GetChild(i),currentId );
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CParticlesExporter::ExportParticleLib( CParticleLibrary *pLib,CFile &file )
|
|
{
|
|
std::vector<SExportParticleEffect> effects;
|
|
effects.reserve( pLib->GetItemCount() );
|
|
|
|
int i;
|
|
for (i = 0; i < pLib->GetItemCount(); i++)
|
|
{
|
|
CParticleItem *pItem = (CParticleItem*)pLib->GetItem(i);
|
|
if (!pItem->GetParent())
|
|
AddParticleExportItem( effects,pItem,-1 );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Write particles file header.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
SExportedParticlesHeader header;
|
|
memcpy( header.signature,PARTICLES_FILE_SIGNATURE,3 );
|
|
header.filetype = PARTICLES_FILE_TYPE;
|
|
header.version = PARTICLES_FILE_VERSION;
|
|
file.Write( &header,sizeof(header) );
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Write particles data.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
int numItems = effects.size();
|
|
// Write number of particles in file.
|
|
file.Write( &numItems,sizeof(numItems) );
|
|
// Write actual particles data.
|
|
if (!effects.empty())
|
|
file.Write( &effects[0],numItems*sizeof(SExportParticleEffect) );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CParticlesExporter::ExportParticles( const CString &path,const CString &levelName,CPakFile &levelPakFile )
|
|
{
|
|
CParticleManager *pPartManager = GetIEditor()->GetParticleManager();
|
|
if (pPartManager->GetLibraryCount() == 0)
|
|
return;
|
|
|
|
ISystem *pISystem = GetIEditor()->GetSystem();
|
|
|
|
// If have more then onle library save them into shared Effects.pak
|
|
bool bNeedEffectsPak = pPartManager->GetLibraryCount() > 1;
|
|
|
|
bool bEffectsPak = true;
|
|
|
|
CString pakFilename = EFFECTS_PAK_FILE;
|
|
CPakFile effectsPak;
|
|
|
|
if (bNeedEffectsPak)
|
|
{
|
|
// Close main game pak file if open.
|
|
if (!pISystem->GetIPak()->ClosePack( pakFilename ))
|
|
{
|
|
CLogFile::FormatLine( "Cannot close Pak file %s",(const char*)pakFilename );
|
|
bEffectsPak = false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (CFileUtil::OverwriteFile(pakFilename))
|
|
{
|
|
// Delete old pak file.
|
|
if (!effectsPak.Open( pakFilename,false ))
|
|
{
|
|
CLogFile::FormatLine( "Cannot open Pak file for Writing %s",(const char*)pakFilename );
|
|
bEffectsPak = false;
|
|
}
|
|
}
|
|
else
|
|
bEffectsPak = false;
|
|
}
|
|
|
|
// Effects pack.
|
|
int i;
|
|
for (i = 0; i < pPartManager->GetLibraryCount(); i++)
|
|
{
|
|
CParticleLibrary *pLib = (CParticleLibrary*)pPartManager->GetLibrary(i);
|
|
if (pLib->IsLevelLibrary())
|
|
{
|
|
CMemFile file;
|
|
ExportParticleLib( pLib,file );
|
|
CString filename = Path::Make( path,PARTICLES_FILE );
|
|
levelPakFile.UpdateFile( filename,file );
|
|
}
|
|
else
|
|
{
|
|
if (bEffectsPak)
|
|
{
|
|
CMemFile file;
|
|
CString filename = Path::Make( EFFECTS_FOLDER,pLib->GetName() + ".prt" );
|
|
ExportParticleLib( pLib,file );
|
|
effectsPak.UpdateFile( filename,file );
|
|
}
|
|
|
|
/*
|
|
bool bNotExist = false;
|
|
CString filename = Path::Make( EFFECTS_FOLDER,pLib->GetName() + ".prt" );
|
|
{
|
|
CFile tempFile;
|
|
if (!tempFile.Open( filename,CFile::modeRead ))
|
|
{
|
|
bNotExist = true;
|
|
}
|
|
}
|
|
if (pLib->IsModified() || bNotExist)
|
|
{
|
|
if (!CFileUtil::OverwriteFile(filename))
|
|
return;
|
|
|
|
CFile file;
|
|
if (file.Open( filename,CFile::modeCreate|CFile::modeWrite ))
|
|
{
|
|
ExportParticleLib( pLib,file );
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
// Open Pak, which was closed before.
|
|
pISystem->GetIPak()->OpenPack( pakFilename );
|
|
} |