📄 simpleparticlesystem.cpp
字号:
#include "StdAfx.h"
#include "Game/Camera.h"
#include "GenericParticleProjectile.h"
#include "GlobalStuff.h"
#include "Rendering/GL/VertexArray.h"
#include "Rendering/Textures/ColorMap.h"
#include "SimpleParticleSystem.h"
#include "Sim/Projectiles/ProjectileHandler.h"
#include "mmgr.h"
CR_BIND_DERIVED(CSimpleParticleSystem, CProjectile, );
CR_REG_METADATA(CSimpleParticleSystem,
(
CR_MEMBER_BEGINFLAG(CM_Config),
CR_MEMBER(emitVector),
CR_MEMBER(emitMul),
CR_MEMBER(gravity),
CR_MEMBER(colorMap),
CR_MEMBER(texture),
CR_MEMBER(airdrag),
CR_MEMBER(particleLife),
CR_MEMBER(particleLifeSpread),
CR_MEMBER(numParticles),
CR_MEMBER(particleSpeed),
CR_MEMBER(particleSpeedSpread),
CR_MEMBER(particleSize),
CR_MEMBER(particleSizeSpread),
CR_MEMBER(emitRot),
CR_MEMBER(emitRotSpread),
CR_MEMBER(directional),
CR_MEMBER(sizeGrowth),
CR_MEMBER(sizeMod),
CR_MEMBER_ENDFLAG(CM_Config),
CR_MEMBER(particles),
CR_RESERVED(16)
));
CR_BIND(CSimpleParticleSystem::Particle, );
CR_REG_METADATA_SUB(CSimpleParticleSystem, Particle,
(
CR_MEMBER(pos),
CR_MEMBER(life),
CR_MEMBER(speed),
CR_MEMBER(decayrate),
CR_MEMBER(size),
CR_MEMBER(sizeGrowth),
CR_MEMBER(sizeMod),
CR_RESERVED(8)
));
CSimpleParticleSystem::CSimpleParticleSystem(void)
{
deleteMe=false;
checkCol=false;
useAirLos=true;
synced=false;
particles=0;
emitMul = float3(1,1,1);
}
CSimpleParticleSystem::~CSimpleParticleSystem(void)
{
if(particles)
delete [] particles;
}
void CSimpleParticleSystem::Draw()
{
inArray=true;
if(directional)
{
for(int i=0; i<numParticles; i++)
{
if(particles[i].life<1.0f)
{
float3 dif(particles[i].pos-camera->pos);
float camDist=dif.Length();
dif/=camDist;
float3 dir1(dif.cross(particles[i].speed));
dir1.Normalize();
float3 dir2(dif.cross(dir1));
unsigned char color[4];
colorMap->GetColor(color, particles[i].life);
float3 interPos=particles[i].pos+particles[i].speed*gu->timeOffset;
float size = particles[i].size;
va->AddVertexTC(interPos-dir1*size-dir2*size,texture->xstart,texture->ystart,color);
va->AddVertexTC(interPos-dir1*size+dir2*size,texture->xend ,texture->ystart,color);
va->AddVertexTC(interPos+dir1*size+dir2*size,texture->xend ,texture->yend ,color);
va->AddVertexTC(interPos+dir1*size-dir2*size,texture->xstart,texture->yend ,color);
}
}
}
else
{
for(int i=0; i<numParticles; i++)
{
if(particles[i].life<1.0f)
{
unsigned char color[4];
colorMap->GetColor(color, particles[i].life);
float3 interPos=particles[i].pos+particles[i].speed*gu->timeOffset;
float size = particles[i].size;
va->AddVertexTC(interPos-camera->right*size-camera->up*size,texture->xstart,texture->ystart,color);
va->AddVertexTC(interPos+camera->right*size-camera->up*size,texture->xend ,texture->ystart,color);
va->AddVertexTC(interPos+camera->right*size+camera->up*size,texture->xend ,texture->yend ,color);
va->AddVertexTC(interPos-camera->right*size+camera->up*size,texture->xstart,texture->yend ,color);
}
}
}
}
void CSimpleParticleSystem::Update()
{
deleteMe = true;
for(int i=0; i<numParticles; i++)
{
if(particles[i].life<1.0f)
{
particles[i].pos += particles[i].speed;
particles[i].life += particles[i].decayrate;
particles[i].speed += gravity;
particles[i].speed *= airdrag;
particles[i].size = particles[i].size*sizeMod + sizeGrowth;
deleteMe = false;
}
}
}
void CSimpleParticleSystem::Init(const float3& explosionPos, CUnit *owner)
{
CProjectile::Init(explosionPos, owner);
particles = new Particle[numParticles];
float3 up = emitVector;
float3 right = up.cross(float3(up.y,up.z,-up.x));
float3 forward = up.cross(right);
for(int i=0; i<numParticles; i++)
{
float az = gu->usRandFloat()*2*PI;
float ay = (emitRot + emitRotSpread*gu->usRandFloat())*(PI/180.0);
particles[i].decayrate = 1.0f/(particleLife + gu->usRandFloat()*particleLifeSpread);
particles[i].life = 0;
particles[i].size = particleSize + gu->usRandFloat()*particleSizeSpread;
particles[i].pos = pos;
particles[i].speed = ((up*emitMul.y)*cos(ay)-((right*emitMul.x)*cos(az)-(forward*emitMul.z)*sin(az))*sin(ay)) * (particleSpeed + gu->usRandFloat()*particleSpeedSpread);
}
drawRadius = (particleSpeed+particleSpeedSpread)*(particleLife*particleLifeSpread);
}
CR_BIND_DERIVED(CSphereParticleSpawner, CSimpleParticleSystem, );
CR_REG_METADATA(CSphereParticleSpawner,
(
CR_MEMBER_BEGINFLAG(CM_Config),
CR_MEMBER_ENDFLAG(CM_Config)
));
CSphereParticleSpawner::CSphereParticleSpawner()
{
}
CSphereParticleSpawner::~CSphereParticleSpawner()
{
}
void CSphereParticleSpawner::Init(const float3& explosionPos, CUnit *owner)
{
float3 up = emitVector;
float3 right = up.cross(float3(up.y,up.z,-up.x));
float3 forward = up.cross(right);
for(int i=0; i<numParticles; i++)
{
float az = gu->usRandFloat()*2*PI;
float ay = (emitRot + emitRotSpread*gu->usRandFloat())*(PI/180.0);
float3 pspeed = ((up*emitMul.y)*cos(ay)-((right*emitMul.x)*cos(az)-(forward*emitMul.z)*sin(az))*sin(ay)) * (particleSpeed + gu->usRandFloat()*particleSpeedSpread);
CGenericParticleProjectile *particle = new CGenericParticleProjectile(pos+explosionPos, pspeed, owner);
particle->decayrate = 1.0f/(particleLife + gu->usRandFloat()*particleLifeSpread);
particle->life = 0;
particle->size = particleSize + gu->usRandFloat()*particleSizeSpread;
particle->texture = texture;
particle->colorMap = colorMap;
particle->airdrag = airdrag;
particle->sizeGrowth = sizeGrowth;
particle->sizeMod = sizeMod;
particle->gravity = gravity;
particle->directional = directional;
particle->SetRadius(particle->size + sizeGrowth*particleLife);
}
deleteMe = true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -