aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Chris Xiong <chirs241097@gmail.com> 2016-05-18 00:00:11 +0800
committerGravatar Chris Xiong <chirs241097@gmail.com> 2016-05-18 00:00:11 +0800
commit473470054a4f67c67fb3f40a0438e87aff68703c (patch)
treef1e4644325cbb8eba4a1050ff5b69e31a0b6bb11
parent9b1dee8a2bed82df98d68001b9458f29a780c71e (diff)
downloadQMidiPlayer-473470054a4f67c67fb3f40a0438e87aff68703c.tar.xz
Fix bugs in the particle system.
Add particle look at option.
-rw-r--r--ChangeLog4
-rw-r--r--img/options4.pngbin31324 -> 30369 bytes
-rw-r--r--visualization/extrasmeltutils.cpp50
-rw-r--r--visualization/extrasmeltutils.hpp22
-rw-r--r--visualization/qmpvisualization.cpp27
-rw-r--r--visualization/qmpvisualization.hpp6
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
--- a/img/options4.png
+++ b/img/options4.png
Binary files 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 <cstdio>
#include <cstdarg>
-#include <ctime>
#include <algorithm>
+#include <smcolor.hpp>
#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()<psinfo.maxcount)
{
int ec=re.nextInt(psinfo.emissioncount-psinfo.ecvar,psinfo.emissioncount+psinfo.ecvar);
for(int i=0;i<ec;++i)
{
smParticle *p=new smParticle();
p->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 <ctime>
#include <vector>
#include <smelt.hpp>
#include <smmath.hpp>
@@ -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<smParticle*> 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()&&elb<pool.size()&&((double)ctk-pool[elb]->tce)*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<uint32_t> 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;