3、 粒子发射器
class CPemitter
{
public:
int m_iParticleType; //粒子的类型
void* m_lpParticleMesh;//粒子的实际使用元素,他可能是任意的可见元素
//(BILLBOARD或Point Sprites),因此我们把它设为
// void*类型
int m_iEmitterLife; //发射器的生存时间
float m_fWidth, m_fHeight; //发射器的长宽(这里建立的是一个矩形发射器)
int m_iMinParticleLife, m_iMaxParticleLife; //粒子的生命值范围
float m_fMinSpeed, m_fMaxSpeed;//粒子的速度范围
float m_fMinAngle, m_fMaxAngle;//粒子发散的角度范围
float m_fMinScale, m_fMaxScale;//粒子的大小变化范围
float m_fMinRotate, m_fMaxRotate;//粒子的旋转角度范围
float m_fAlphaStart, m_fAlphaEnd;//粒子的透明度范围
LPPARTICLENODE m_lpParticleNode;//粒子的渲染链表
MY_MATRIX m_TM;//发射器的世界变换矩阵
MyVector m_Speed3;//粒子发射的初始速度向量
MyVector m_Force3;//粒子受力
int m_iMaxParticle;//最大粒子数
CollisionMesh m_ParticleBoudingMesh;//粒子的包围盒子
public:
BOOL RenderEmitter();//渲染发射器的渲染链表中的每一个粒子
bool EmitterShoot();//发射粒子,在这个函数中,粒子发射器首先检查哪些粒子已经死//亡,并把死亡粒子从渲染链表m_lpParticleNode中删除,把死亡粒子对应的编号压入粒//子池所管理的空闲栈中。然后粒子发射器发射新的粒子(从空闲栈中取得),他从自己//的参数范围中取随机值赋给新生成的粒子,并将新粒子加入渲染链表中。
bool EmitterNextFrame();//这个函数处理每个在生存期内的粒子变换,包括位置,大小,//旋转,以及透明度的变化
};
下面是一些主要函数的部分代码:
bool CPemitter::EmitterNextFrame()
{
LPPARTICLENODE lpParticleNode = m_lpParticleNode;
while( 该粒子有效 )
{
if(该粒子在生存期内 )
{
粒子生命减少
粒子当前帧数增加;
粒子世界矩阵变换;
粒子透明度变换;
if( 粒子受力 )
{
粒子速度变化;
}
取得下一粒子
}
Else//如果粒子生命期结束
{
删除该粒子
粒子总数减少;
粒子池将死亡粒子放入空闲栈;
}
}
if(发射器寿命期内)
{
发射器寿命减少;
发射粒子;
}
Else
{
删除该发射器
}
return TRUE;
}
//产生新的粒子
bool CPemitter::EmitterShoot()
{
int iShootNum = ( DWORD )m_iMaxParticle - m_iParticleCount;//确保每次屏幕上的粒子//是最大数目(这样可以一次申请固定大小BUFFER)
for( int iPIndex = 0; iPIndex < iShootNum; iPIndex++ )
{
如果粒子总数大于最大粒子数则跳出
从粒子池中取得空闲粒子;
将该空闲粒子放入渲染链表头
粒子当前帧数为0;
初始化粒子世界矩阵
初始化粒子受力矩阵;
粒子寿命取发射器粒子寿命范围间的随机值
粒子透明度取基本透明度;
粒子透明度增量取发射器粒子透明度范围间的随机值;
粒子旋转角度取发射器粒子旋转角度范围间的随机值;
粒子位置取发射器范围内的随机值
粒子速度取发射器范围内的随机值
粒子大小取发射器粒子大小的随机值
粒子总数增加;
}
return TRUE;
}