From 473470054a4f67c67fb3f40a0438e87aff68703c Mon Sep 17 00:00:00 2001 From: Chris Xiong Date: Wed, 18 May 2016 00:00:11 +0800 Subject: Fix bugs in the particle system. Add particle look at option. --- ChangeLog | 4 +++ img/options4.png | Bin 31324 -> 30369 bytes visualization/extrasmeltutils.cpp | 50 ++++++++++++++++++++++++++----------- visualization/extrasmeltutils.hpp | 22 ++++++++++++---- visualization/qmpvisualization.cpp | 27 +++++++++++++++++++- visualization/qmpvisualization.hpp | 6 +++-- 6 files changed, 87 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d7ed6a..4cede60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2016-05-17 0.8.1 alpha +Fix bugs in the particle system. +Add particle look at option. + 2016-05-16 0.8.1 alpha Finish the particle system. It should become a part of SMELT someday. diff --git a/img/options4.png b/img/options4.png index 3cd0faa..1cf39c8 100644 Binary files a/img/options4.png and b/img/options4.png differ diff --git a/visualization/extrasmeltutils.cpp b/visualization/extrasmeltutils.cpp index a2ccf2c..dc12c8c 100644 --- a/visualization/extrasmeltutils.cpp +++ b/visualization/extrasmeltutils.cpp @@ -1,6 +1,7 @@ +#include #include -#include #include +#include #include "extrasmeltutils.hpp" SMELT* smEntity3DBuffer::sm=NULL; SMELT* smParticle::sm=NULL; @@ -64,7 +65,7 @@ void smEntity3DBuffer::drawBatch() vertices.clear();indices.clear(); } smParticle::smParticle() -{sm=smGetInterface(SMELT_APILEVEL);dead=false;lifespan=0;} +{sm=smGetInterface(SMELT_APILEVEL);dead=false;clifespan=0;} smParticle::~smParticle(){sm->smRelease();} void smParticle::render() {sm->smRenderQuad(&q);} @@ -73,19 +74,22 @@ void smParticle::update() clifespan+=sm->smGetDelta();if(clifespan>lifespan){dead=true;return;} vel=vel+accel;pos=pos+vel;rotv=rotv+rota;rot=rot+rotv; size=clifespan/lifespan*(finalsize-initsize)+initsize; - color=ARGB( - (DWORD)(clifespan/lifespan*(GETA(finalcolor)-GETA(initcolor)+GETA(initcolor))), - (DWORD)(clifespan/lifespan*(GETR(finalcolor)-GETR(initcolor)+GETR(initcolor))), - (DWORD)(clifespan/lifespan*(GETG(finalcolor)-GETG(initcolor)+GETG(initcolor))), - (DWORD)(clifespan/lifespan*(GETB(finalcolor)-GETB(initcolor)+GETB(initcolor)))); + smColorRGBA fc(finalcolor),ic(initcolor),cc; + cc.a=clifespan/lifespan*(fc.a-ic.a)+ic.a; + cc.r=clifespan/lifespan*(fc.r-ic.r)+ic.r; + cc.g=clifespan/lifespan*(fc.g-ic.g)+ic.g; + cc.b=clifespan/lifespan*(fc.b-ic.b)+ic.b; + color=cc.getHWColor(); for(int i=0;i<4;++i)q.v[i].col=color; - smMatrix m;m.loadIdentity();m.rotate(rot.x,1,0,0);m.rotate(rot.y,0,1,0);m.rotate(rot.z,0,0,1); + smMatrix m;m.loadIdentity(); + if(lookat)m.lookat(pos,lookatpos,smvec3d(0,0,1));else + {m.rotate(rot.x,1,0,0);m.rotate(rot.y,0,1,0);m.rotate(rot.z,0,0,1);} smvec3d v0=m*smvec3d(-size,-size,0),v1=m*smvec3d(size,-size,0); smvec3d v2=m*smvec3d(size,size,0),v3=m*smvec3d(-size,size,0); - q.v[0].x=v0.x;q.v[0].y=v0.y;q.v[0].z=v0.z; - q.v[1].x=v1.x;q.v[1].y=v1.y;q.v[1].z=v1.z; - q.v[2].x=v2.x;q.v[2].y=v2.y;q.v[2].z=v2.z; - q.v[3].x=v3.x;q.v[3].y=v3.y;q.v[3].z=v3.z; + q.v[0].x=v0.x+pos.x;q.v[0].y=v0.y+pos.y;q.v[0].z=v0.z+pos.z; + q.v[1].x=v1.x+pos.x;q.v[1].y=v1.y+pos.y;q.v[1].z=v1.z+pos.z; + q.v[2].x=v2.x+pos.x;q.v[2].y=v2.y+pos.y;q.v[2].z=v2.z+pos.z; + q.v[3].x=v3.x+pos.x;q.v[3].y=v3.y+pos.y;q.v[3].z=v3.z+pos.z; } smParticleSystem::smParticleSystem() {sm=smGetInterface(SMELT_APILEVEL);particles.clear();posGenerator=NULL;} @@ -96,6 +100,8 @@ void smParticleSystem::setParticleSystemInfo(smParticleSystemInfo _psinfo) void smParticleSystem::setPos(smvec3d _pos){pos=_pos;} void smParticleSystem::setPSEmissionPosGen(smPSEmissionPositionGenerator *_gen) {posGenerator=_gen;} +void smParticleSystem::setPSLookAt(smvec3d at){lookat=true;lookatpos=at;} +void smParticleSystem::unsetPSLookAt(){lookat=false;} void smParticleSystem::startPS() {active=true;nemdelay=0;re.setSeed(time(NULL));} void smParticleSystem::stopPS() @@ -103,14 +109,30 @@ void smParticleSystem::stopPS() void smParticleSystem::updatePS() { cemdelay+=sm->smGetDelta(); - if(cemdelay>nemdelay) + if(cemdelay>nemdelay&&(int)particles.size()pos=pos+(posGenerator?posGenerator->genPos():smvec3d(0,0,0)); - p->rot=smvec3d(0,0,0); + p->vel=smvec3d( + re.nextDouble(psinfo.vel.x-psinfo.velvar.x,psinfo.vel.x+psinfo.velvar.x), + re.nextDouble(psinfo.vel.y-psinfo.velvar.y,psinfo.vel.y+psinfo.velvar.y), + re.nextDouble(psinfo.vel.z-psinfo.velvar.z,psinfo.vel.z+psinfo.velvar.z)); + p->accel=smvec3d( + re.nextDouble(psinfo.acc.x-psinfo.accvar.x,psinfo.acc.x+psinfo.accvar.x), + re.nextDouble(psinfo.acc.y-psinfo.accvar.y,psinfo.acc.y+psinfo.accvar.y), + re.nextDouble(psinfo.acc.z-psinfo.accvar.z,psinfo.acc.z+psinfo.accvar.z)); + p->rotv=smvec3d( + re.nextDouble(psinfo.rotv.x-psinfo.rotvvar.x,psinfo.rotv.x+psinfo.rotvvar.x), + re.nextDouble(psinfo.rotv.y-psinfo.rotvvar.y,psinfo.rotv.y+psinfo.rotvvar.y), + re.nextDouble(psinfo.rotv.z-psinfo.rotvvar.z,psinfo.rotv.z+psinfo.rotvvar.z)); + p->rota=smvec3d( + re.nextDouble(psinfo.rota.x-psinfo.rotavar.x,psinfo.rota.x+psinfo.rotavar.x), + re.nextDouble(psinfo.rota.y-psinfo.rotavar.y,psinfo.rota.y+psinfo.rotavar.y), + re.nextDouble(psinfo.rota.z-psinfo.rotavar.z,psinfo.rota.z+psinfo.rotavar.z)); + p->rot=smvec3d(0,0,0);if(lookat)p->lookat=true,p->lookatpos=lookatpos;else p->lookat=false; p->lifespan=re.nextDouble(psinfo.lifespan-psinfo.lifespanvar,psinfo.lifespan+psinfo.lifespanvar); p->initsize=re.nextDouble(psinfo.initsize-psinfo.initsizevar,psinfo.initsize+psinfo.initsizevar); p->finalsize=re.nextDouble(psinfo.finalsize-psinfo.finalsizevar,psinfo.finalsize+psinfo.finalsizevar); diff --git a/visualization/extrasmeltutils.hpp b/visualization/extrasmeltutils.hpp index bd103b0..08868a7 100644 --- a/visualization/extrasmeltutils.hpp +++ b/visualization/extrasmeltutils.hpp @@ -1,5 +1,6 @@ #ifndef EXTRASMELTUTILS_H #define EXTRASMELTUTILS_H +#include #include #include #include @@ -33,7 +34,16 @@ class smEntity3DBuffer class smPSEmissionPositionGenerator { public: - virtual smvec3d genPos(); + virtual smvec3d genPos(){return smvec3d(0,0,0);} +}; +class smXLinePSGenerator:public smPSEmissionPositionGenerator +{ + private: + smRandomEngine re; + double var; + public: + smXLinePSGenerator(double _var){re.setSeed(time(NULL));var=_var;} + smvec3d genPos(){return smvec3d(re.nextDouble(-var,var),0,0);} }; class smParticleSystemInfo { @@ -54,13 +64,13 @@ class smParticle friend class smParticleSystem; private: static SMELT* sm; - smvec3d pos,rot; + smvec3d pos,rot,lookatpos; smvec3d vel,accel,rotv,rota; double lifespan,clifespan; double initsize,finalsize,size; DWORD color,initcolor,finalcolor; smQuad q; - bool dead; + bool dead,lookat; public: smParticle(); ~smParticle(); @@ -73,10 +83,10 @@ class smParticleSystem static SMELT* sm; std::vector particles; smParticleSystemInfo psinfo; - smvec3d pos; + smvec3d pos,lookatpos; smRandomEngine re; smPSEmissionPositionGenerator* posGenerator; - bool active; + bool active,lookat; double cemdelay,nemdelay; public: smParticleSystem(); @@ -84,6 +94,8 @@ class smParticleSystem void setParticleSystemInfo(smParticleSystemInfo _psinfo); void setPos(smvec3d _pos); void setPSEmissionPosGen(smPSEmissionPositionGenerator* _gen); + void setPSLookAt(smvec3d at); + void unsetPSLookAt(); void startPS(); void stopPS(); void updatePS(); diff --git a/visualization/qmpvisualization.cpp b/visualization/qmpvisualization.cpp index 607b2ea..8c4f9db 100644 --- a/visualization/qmpvisualization.cpp +++ b/visualization/qmpvisualization.cpp @@ -73,11 +73,24 @@ void qmpVisualization::showThread() sm->smTextureOpt(TPOT_POT,TFLT_LINEAR); chequer=sm->smTextureLoad("chequerboard.png");if(!chequer) chequer=sm->smTextureLoad("/usr/share/qmidiplayer/img/chequerboard.png"); + particletex=sm->smTextureLoad("particle.png"); bgtex=sm->smTextureLoad(api->getOptionString("Visualization/background").c_str()); + smParticleSystemInfo psinfo; + psinfo.acc=smvec3d(0,0,-0.05);psinfo.accvar=smvec3d(0,0,0.005); + psinfo.vel=smvec3d(0,0,0.5);psinfo.velvar=smvec3d(0.1,0.1,0.2); + psinfo.rotv=psinfo.rota=psinfo.rotavar=smvec3d(0,0,0);psinfo.rotvvar=smvec3d(0.04,0.04,0.04); + psinfo.lifespan=1;psinfo.lifespanvar=0.5;psinfo.maxcount=1000;psinfo.emissioncount=5;psinfo.ecvar=2; + psinfo.emissiondelay=0.1;psinfo.edvar=0;psinfo.initsize=0.8;psinfo.initsizevar=0.1; + psinfo.finalsize=0.1;psinfo.finalsizevar=0.05;psinfo.initcolor=0xFFFFFFFF;psinfo.finalcolor=0x00FFFFFF; + psinfo.initcolorvar=psinfo.finalcolorvar=0;psinfo.texture=particletex;psinfo.blend=BLEND_ALPHAADD; + test=new smParticleSystem();test->setPos(smvec3d(0,0,16)); + psepg=new smXLinePSGenerator(.75);test->setParticleSystemInfo(psinfo); + test->setPSEmissionPosGen(psepg);test->startPS(); if(showpiano)for(int i=0;i<16;++i)p3d[i]=new qmpVirtualPiano3D(); memset(traveld,0,sizeof(traveld)); if(noteappearance==1)nebuf=new smEntity3DBuffer();else nebuf=NULL; tdscn=sm->smTargetCreate(wwidth*wsupersample,wheight*wsupersample,wmultisample); + tdparticles=sm->smTargetCreate(wwidth*wsupersample,wheight*wsupersample,wmultisample); if(!font.loadTTF("/usr/share/fonts/truetype/freefont/FreeMono.ttf",16)) if(!font.loadTTF("/usr/share/fonts/gnu-free-fonts/FreeMono.otf",16)) printf("W: Font load failed.\n"); @@ -115,6 +128,7 @@ void qmpVisualization::close() }else return; if(showpiano)for(int i=0;i<16;++i)delete p3d[i]; + delete test; if(noteappearance==1)delete nebuf; sm->smFinale(); if(savevp) @@ -130,8 +144,10 @@ void qmpVisualization::close() font2.releaseTTF(); fonthdpi.releaseTTF(); sm->smTextureFree(chequer); + sm->smTextureFree(particletex); if(bgtex)sm->smTextureFree(bgtex); sm->smTargetFree(tdscn); + sm->smTargetFree(tdparticles); sm->smRelease(); } void qmpVisualization::reset() @@ -157,7 +173,7 @@ bool qmpVisualization::update() q.v[0].y=q.v[1].y=-120;q.v[2].y=q.v[3].y=120; q.v[0].tx=q.v[3].tx=0;q.v[1].tx=q.v[2].tx=30; q.v[0].ty=q.v[1].ty=0;q.v[2].ty=q.v[3].ty=30; - sm->smRenderBegin3D(fov,tdscn); + sm->smRenderBegin3D(fov,true,tdscn); sm->sm3DCamera6f2v(pos,rot); sm->smClrscr(0,1,1); sm->smRenderQuad(&q); @@ -233,6 +249,13 @@ bool qmpVisualization::update() if(playing)ctk+=(int)(1e6/(api->getRawTempo()/api->getDivision())*sm->smGetDelta()); while(pool.size()&&elbtce)*lpt>viewdist*2)++elb; sm->smRenderEnd(); + sm->smRenderBegin3D(fov,false,tdparticles); + sm->sm3DCamera6f2v(pos,rot); + sm->smClrscr(0,1,1); + test->setPSLookAt(smvec3d(pos[0],pos[1],pos[2])); + //!!Test only. + //test->updatePS();test->renderPS(); + sm->smRenderEnd(); sm->smRenderBegin2D(); sm->smClrscr(0xFF666666);q.blend=BLEND_ALPHABLEND; for(int i=0;i<4;++i){q.v[i].col=0xFFFFFFFF;q.v[i].z=0;} @@ -251,6 +274,8 @@ bool qmpVisualization::update() q.v[0].x=q.v[1].x=0;q.v[2].x=q.v[3].x=wwidth; q.v[0].y=q.v[3].y=0;q.v[1].y=q.v[2].y=wheight; sm->smRenderQuad(&q); + q.tex=sm->smTargetTexture(tdparticles); + sm->smRenderQuad(&q); wchar_t ws[1024];memset(ws,0,sizeof(ws)); mbstowcs(ws,api->getTitle().c_str(),1024); font2.updateString(L"Title: %ls",ws); diff --git a/visualization/qmpvisualization.hpp b/visualization/qmpvisualization.hpp index 3305f4f..6c1e578 100644 --- a/visualization/qmpvisualization.hpp +++ b/visualization/qmpvisualization.hpp @@ -47,11 +47,13 @@ class qmpVisualization:public qmpPluginIntf smHandler *h,*closeh; std::stack pendingt[16][128],pendingv[16][128]; SMELT *sm; - SMTRG tdscn; - SMTEX chequer,bgtex; + SMTRG tdscn,tdparticles; + SMTEX chequer,bgtex,particletex; smTTFont font,font2,fonthdpi; qmpVirtualPiano3D* p3d[16]; smEntity3DBuffer* nebuf; + smParticleSystem* test; + smPSEmissionPositionGenerator* psepg; float pos[3],rot[3],lastx,lasty; uint32_t ctc,ctk,fintk,elb; double etps; -- cgit v1.2.3