西昌.何雨锋
[emitter 发射器] [Attractor 引起注意的人] [billboard 广告栏] [Sprite 小精灵] [gravity 重力]
1、65的粒子系统与62最大的区别就是在于65采用了存读系统,一个粒子系统可以保存为TVP文件,然后采用load方法就可以在程序中读出。这样做的最大好处就在于,如果你在程序中不改变粒子,那么你就可以直接读取从粒子编辑器中得到的粒子文件。
2、粒子系统文件一般都需要一个dds文件支持,所以,一定要把dds文件拷到tvpj文件所在的文件夹,然后用粒子编辑器编辑好了以后,导出成为不能再编辑的TVP文件,同时将dds文件一起复制到TVP文件所在目录,就可以在3实际中使用了。
3、粒子系统构成是这样的:
首先具有一个发射器Emitter
其属性有:
a、两个方向:
1个主方向miandirection:xyz,这里的xyz都是相对于发射器源点的相对位置,如0,1,0就是向正上方;属性power就是发射的力量,越大越快飞得越远。
1个随机方向randomDirectionFactor:xyz,这个方向一般都只向x,z方向飞,而且值都比较小,一般小于1
b重力:
usegravity=true,表示会接受重力。
x,y,z三者,一般都只改y的值,当为负值时才有重力,否则就是升力。当有重力时,就象瀑布,没有就象烟雾
billboard:
就是一个粒子,如果改变billboardsize,那么就可以创造出很大一个的粒子。
maxparticals:
最大的粒子数量
speed:
产生粒子的速度。
lifetime:
生命周期的秒数
loop:
循环产生,只有当循环产生的时候,粒子才会源源不断的产生而不会消失。
3、方法如下:
CTVParticleSystem* par1;
cTV_3DVECTOR par_pos;
par1=scene1->CreateParticleSystem("par1");
par1->Load("..//..//media//test1.tvp");
par1->SetEmitterPosition(0,&par_pos); //可以将粒子系统的发射点移动到par_pos位置。
par1->ResetAll();
4、弹雾的形成:
a、首先用粒子编辑器画出基于billboard的emmiter的弹雾,注意粒子不能设置太多,否则影响速度。
b、在游戏中载入弹雾后,弹雾并不能正常显示,因为纹理的位置无法正确从tvp文件中得到。
c、所以要先载入纹理:fac1->LoadTexture("tvp//armo3.dds","armo3",-1,-1,cTV_COLORKEY_USE_ALPHA_CHANNEL);
fac1->LoadTexture("tvp//asmoke1.dds","asmoke1",-1,-1,cTV_COLORKEY_USE_ALPHA_CHANNEL );
fac1->LoadTexture("tvp//armo5.dds","armo5",-1,-1,cTV_COLORKEY_USE_ALPHA_CHANNEL );
注意最后一个参数,是cTV_COLORKEY_USE_ALPHA_CHANNEL ,这样才能载入使用alpha通道的纹理。
d、当你载入tvp文件时,emmiter的数量就已经定下来的了,方向等都没有问题。但是当你设置纹理时,有可能就连billboard大小等都改变了,所以设置时候要注意:
SetBillboard(int iEmitter, int iTexture, float fDefaultWidth = 1.0f, float fDefaultHeight = 1.0f);
第一个参数是设置哪个emitter序号,第二个是纹理,后两个实际就是billboard的大小
t_par1->SetBillboard(0,global1->GetTex("armo3"),8,8);
t_par1->SetBillboard(1,global1->GetTex("asmoke1"),9,9);
t_par1->SetBillboard(2,global1->GetTex("armo5"),16,16);
这样就不仅设置了三个emitter的纹理,而且连大小也设置好了,这里的大小倍数设置来跟粒子编辑器中的相同就行了。
4、其他函数:
bool Load(char* sBinaryDataSource);
//读一个TVP文件
bool Save(char* sBinaryDataPlace, bool bSaveTextures = true);
//将粒子系统存为一个TVP文件
int GetEmitterCount();
//得到发射点总数
int GetAttractorCount();
//得到活跃点总数
int GetGlobalParticleCount();
//得到粒子系统总数
int GetEmitterParticleCount(int iEmitter);
int CreateEmitter(cCONST_TV_EMITTERTYPE eEmitterType = cTV_EMITTER_POINTSPRITE, int iMaxParticles = 64);
//建立一个发射点
void SetBillboard(int iEmitter, int iTexture, float fDefaultWidth = 1.0f, float fDefaultHeight = 1.0f);
void SetBillboardShader(int iEmitter, CTVShader* pShader);
void SetMiniMesh(int iEmitter, CTVMiniMesh* pMiniMesh);
void SetPointSprite(int iEmitter, int iTexture, float fDefaultSize = 32, bool bAutoScale = true, float fScaleA = 0.0f, float fScaleB = 0.0f, float fScaleC = 1.0f);
void SetEmitterShape(int iEmitter, cCONST_TV_EMITTERSHAPE eShape = cTV_EMITTERSHAPE_POINT);
void SetEmitterBoxSize(int iEmitter, cTV_3DVECTOR* bSize);
void SetEmitterSphereRadius(int iEmitter, float fRadius );
void SetEmitterDirection(int iEmitter, bool bEnableMainDirection, cTV_3DVECTOR* vMainDirection, cTV_3DVECTOR* vRandomDirectionFactor);
void SetEmitterPower(int iEmitter, float fPower, float fParticleLifeTime);
void SetEmitterSpeed(int iEmitter, float fGenerationSpeedMS);
void SetEmitterKeyFrames(int iEmitter, int eEmitterKeyUsage, int iNumKeyFrames, cTV_PARTICLEEMITTER_KEYFRAME* pFirstKeyFrameArray);
void SetParticleKeyFrames(int iEmitter, int eParticleKeyUsage, int iNumKeyFrames, cTV_PARTICLE_KEYFRAME* pFirstKeyFrameArray);
void SetEmitterAlphaBlending(int iEmitter, cCONST_TV_PARTICLECHANGE eChange = cTV_CHANGE_ALPHA, cCONST_TV_BLENDINGMODE eBlending = cTV_BLEND_ALPHA );
void SetEmitterAlphaTest(int iEmitter, bool bAlphaTest, int iAlphaRef = 8, bool bDepthWrite = false);
void MoveEmitter(int iEmitter, cTV_3DVECTOR* vEmitterPosition);
void SetEmitterMatrix(int iEmitter, cTV_3DMATRIX* mMatrix);
void SetParticleDefaultColor(int iEmitter, cTV_COLOR* cColor);
void SetEmitterGravity(int iEmitter, bool bUseGravity, cTV_3DVECTOR* vGravityVector);
void Update();
void Render();
// attractor support.
int CreateAttractor(bool bDirectionalField = false);
void SetAttractorFieldDirection(int iAttractor, cTV_3DVECTOR* vDirection);
void SetAttractorParameters(int iAttractor, float fAttractionRepulsionConstant, cCONST_TV_ATTRACTORVELOCITYPOWER eVelocityDependency = cTV_ATTRACTORPOWER_CONSTANT);
void SetAttractorAttenuation(int iAttractor, cTV_3DVECTOR* vAttenuationVector);
void SetAttractorEnable(int iAttractor, bool bEnable);
void SetAttractorPosition(int iAttractor, cTV_3DVECTOR* vAttractorPosition);
void SetAttractorRadius(int iAttractor, float fRadius);
void Destroy();
void AttachTo(int iEmitter, cCONST_TV_NODETYPE eObjectType, int iObjectIndex, int iSubIndex, bool bKeepMatrix = true);
void SetParent(int iEmitter, cCONST_TV_NODETYPE eObjectType, int iObjectIndex, int iSubIndex);
void SetParentEx(int iEmitter, cCONST_TV_NODETYPE eObjectType, int iObjectIndex, int iSubIndex, float fTranslationOffsetX = 0.0f, float fTranslationOffsetY = 0.0f, float fTranslationOffsetZ = 0.0f, float fRotationOffsetX = 0.0f, float fRotationOffsetY = 0.0f, float fRotationOffsetZ = 0.0f);
void SetEmitterPosition(int iEmitter, cTV_3DVECTOR* vPosition);
void SetEmitterEnable(int iEmitter, bool bEnable);
void DestroyEmitter(int iEmitterIndex);
void DestroyAttractor(int iAttractor);
void SetEmitterLooping(int iEmitter, bool bLooping);
void ResetEmitter(int iEmitter);
void ResetAll();
cTV_3DVECTOR GetEmitterPosition(int iEmitter);
cTV_3DVECTOR GetEmitterDirection(int iEmitter);
void UpdateEx(int iEmitter, float fTimeSeconds);
void PreGenerate(int iEmitter,int iNumParticles);
void SetEmitterDirectionCubeMask(int iEmitter,bool bEnableCubeTextureMask, int iCubeTextureMask);
cTV_3DVECTOR GetAttractorPosition(int iAttractor);
cTV_3DVECTOR GetAttractorAttenuation(int iAttractor);
float GetAttractorRadius(int iAttractor);
cTV_COLOR GetEmitterDefaultColor(int iEmitter);
cCONST_TV_EMITTERTYPE GetEmitterType(int iEmitter);
cTV_2DVECTOR GetEmitterDefaultBillboardSize(int iEmitter);
void SetEmitterDirectionRandomFactor(int iEmitter, cTV_3DVECTOR* vRandomDirectionFactor);
//设置某一粒子发生器随机方向
void SetGlobalPosition(float fX, float fY, float fZ);
void SetGlobalRotation(float fAngleX, float fAngleY, float fAngleZ);
void SetGlobalMatrix(cTV_3DMATRIX* mMatrix);
cTV_3DVECTOR GetGlobalPosition();
cTV_3DMATRIX GetGlobalMatrix();
bool GetParent(int iEmitter, int* retNodeType, int* retObjectIndex, int* retSubIndex);
int GetEmitterTexture(int iEmitter);
CTVShader* GetBillboardShader(int iEmitter);
char* GetName();
void SetName(const char* sNewName);
CTVParticleSystem* Duplicate(char* sNewName= NULL);
//复制出另一个一样的粒子系统。
CTVShader* GetShader(int iEmitter);
void GetEmitterBoundingBox(int iEmitter, cTV_3DVECTOR* retBoundingBoxMax, cTV_3DVECTOR* retBoundingBoxMin, bool bWorldspace);
void GetEmitterBoundingSphere(int iEmitter, cTV_3DVECTOR* retBoundingSphereCenter, float* retSphereRadius, bool bWorldspace);
char* GetTag();
int GetUserData();
void SetUserData(int i32bitsData);
void SetTag(const char* sTag);
void Enable(bool bEnable);
float GetEmitterKeyFrame(int iEmitter);
cTV_3DVECTOR GetGlobalRotation();
void SetBillboardRotation (int iEmitter, bool bEnable, float fAngularSpeed, float fAngularSpeedRandom = 0.0f, float fAirFriction = 0.0f, float fStartAngle = 0.0f, float fStartAngleRandom = 0.0f);