void ComParticle::UpdateFire() { for (size_t i = 0; i < m_vecParticles.size(); ++i) { Attribute* att = m_vecParticles[i]; att->age += CClock::GetInstance()->GetFrameDuration(); att->position.x += att->velocity.x; att->position.z -= att->velocity.z; att->position.y += att->velocity.y; //att->color.r += 0.01f; att->color.g -= 0.01f; att->color.b -= 0.01f; if (att->position.x > 1.0f || att->position.x < -1.0f) InitParticle(att); if (att->position.z > 2.0f || att->position.z < -2.0f) InitParticle(att); if (att->position.y > 2.0f) InitParticle(att); //if (att->color.g <= 0) // att->color.g = 1.0f; //if (att->color.b <= 0) // att->color.b = 153 / 255.0f; } }
void render() { int i, active_particles = 0; //Clear color buffer glClear( GL_COLOR_BUFFER_BIT ); glBegin(GL_POINTS); for(i=0;i<NUM_PARTICLES;i++) { if(particles[i].lifetime) { active_particles++; particles[i].veloc_y -= GRAVITY; particles[i].x += particles[i].veloc_x; particles[i].y += particles[i].veloc_y; particles[i].lifetime--; glVertex3f( particles[i].x, particles[i].y, 0.0f); // draw pixel } } glEnd(); if(!active_particles) InitParticle(1); }
void ParticleSystem::Update(ulong frame, float dt, Vector gravity) { //avoid multiple updates within the same frame if (frame != m_frame) { //update all particles for (uint i = 0; i < m_count; ++i) { Particle &particle = m_aParticles[i]; //reduce particle life particle.life -= particle.fade * dt; if (particle.life < 0.0f) { //respawn dead particle InitParticle(particle, true); } else { //update particle position particle.pX += particle.vX * dt; particle.pY += particle.vY * dt; particle.pZ += particle.vZ * dt; //update particle velocity //particles are not afected by world gravity in y-direction particle.vX += (m_aX + gravity[CX]) * dt; particle.vY += m_aY * dt; particle.vZ += (m_aZ + gravity[CZ]) * dt; } } //update current frame m_frame = frame; } }
void ParticleSystem::Reset(bool random) { for (uint i = 0; i < m_count; ++i) { InitParticle(m_aParticles[i], random); } }
int ParticleSystem::InitGL(GLvoid) { //texture = LoadGLTextures("Data\\Particle.png"); glShadeModel(GL_SMOOTH); // Enable Smooth Shading glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); //glDisable(GL_DEPTH_TEST); //glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); glEnable(GL_TEXTURE_2D); //glEnable(GL_CULL_FACE); //glCullFace(GL_BACK); float perColorIndex = 12.0 / MAX_PARTICLES; for (int loop = 0; loop < MAX_PARTICLES; loop++) { particles[loop].active = true; // Make All The Particles Active InitParticle(particles[loop]); particles[loop].grav = Vector(0.0f, -1.98f, 0.0f); } return TRUE; }
void CParticleSystem::Update(const float dt, const uint32_t ticks, const vec3_t& ownerpos) { const float gravity = GetGravity(); std::vector<particle_t>::iterator iter; for(iter = m_particles.begin();iter != m_particles.end(); ++iter) { if(iter->lifetime < 0.0f) { if(iter->respawn) { InitParticle(*iter, ownerpos); } else { continue; } } iter->origin = iter->origin + iter->vel*dt - vec3_t(0,dt*dt*0.5f*gravity,0); iter->vel.y -= gravity*dt; iter->lifetime -= dt; const float f = iter->lifetime / iter->totallifetime; const float scale = sin(f * lynxmath::PI); iter->alpha = iter->startalpha * scale; iter->size = scale * iter->startsize + 0.1f; } }
void SplitterSystem::UpdateEmitter(const float dt) { for (int particleIndex = 0; particleIndex < emitter.mParticleCount; ++particleIndex) { Particle *part = emitter.mParticles + particleIndex; part->mTime -= dt; //Game physics! part->mAcc += { 10.f, 10.f }; part->mPos.y -= 2.5f; if (part->mDir.x > 0) { part->mPos.x -= part->mDir.x; } else { part->mPos.x -= part->mDir.x; } part->mVel += part->mAcc * dt; part->mOrientation += part->mAngularVelocity; part->mScale += { .02f, .02f }; //Recycling particles(resetting values). if (part->mTime < 0) { getParams(); InitParticle(part); } } }
void Particles::Init() { glBindVertexArray(arrayObject); InitParams(); InitMemory(); InitParticle(); glBindVertexArray(0); }
HRESULT CPartEmitter::UpdateInternal(uint32 CurrentTime, uint32 TimerDelta) { int NumLive = 0; for (int i = 0; i < m_Particles.GetSize(); i++) { m_Particles[i]->Update(this, CurrentTime, TimerDelta); if (!m_Particles[i]->m_IsDead) NumLive++; } // we're understaffed if (NumLive < m_MaxParticles) { bool NeedsSort = false; if (CurrentTime - m_LastGenTime > m_GenInterval) { m_LastGenTime = CurrentTime; m_BatchesGenerated++; if (m_MaxBatches > 0 && m_BatchesGenerated > m_MaxBatches) { return S_OK; } int ToGen = std::min(m_GenAmount, m_MaxParticles - NumLive); while (ToGen > 0) { int FirstDeadIndex = -1; for (int i = 0; i < m_Particles.GetSize(); i++) { if (m_Particles[i]->m_IsDead) { FirstDeadIndex = i; break; } } CPartParticle *Particle; if (FirstDeadIndex >= 0) Particle = m_Particles[FirstDeadIndex]; else { Particle = new CPartParticle(Game); m_Particles.Add(Particle); } InitParticle(Particle, CurrentTime, TimerDelta); NeedsSort = true; ToGen--; } } if (NeedsSort && (m_ScaleZBased || m_VelocityZBased || m_LifeTimeZBased)) SortParticlesByZ(); // we actually generated some particles and we're not in fast-forward mode if (NeedsSort && m_OverheadTime == 0) { if (m_Owner && m_EmitEvent) m_Owner->ApplyEvent(m_EmitEvent); } } return S_OK; }
particle* ParticleType::CreateParticle(ParticleSystem *pSys)//particle *pPart) { if (!pSys) return NULL; particle *pPart = pSys->ActivateParticle(); if (!pPart) return NULL; pPart->age = 0.0; pPart->age_death = m_Life.GetInstance(); InitParticle(pPart, pSys); return pPart; }
ToolbarPanel::ToolbarPanel(wxWindow* parent, ee::LibraryPanel* library, StagePanel* stage) : ee::ToolbarPanel(parent, stage->GetStageImpl()) , m_stage(stage) , m_image(NULL) { SetScrollbars(1,1, 200, 100, 0, 0); SetSizer(InitLayout()); InitParticle(); SetDropTarget(new DropTarget(library, stage, this)); RegistSubject(ee::ClearPanelSJ::Instance()); }
//------------------------------------------------------------------------ // Purpose : Add particle //------------------------------------------------------------------------ void ParticleSystem::AddParticle() { // check if we have any dead particles if (m_DeadParticles.size() > 0) { // Reinitialize a particle Particle* p = m_DeadParticles.back(); InitParticle(*p); // Now its not dead m_DeadParticles.pop_back(); m_AliveParticles.push_back(p); } }
void ParticleEngine( double t, float dt ) { int i; float dt2; // Update particles (iterated several times per frame if dt is too // large) while( dt > 0.0f ) { // Calculate delta time for this iteration dt2 = dt < MIN_DELTA_T ? dt : MIN_DELTA_T; // Update particles for( i = 0; i < MAX_PARTICLES; i ++ ) { UpdateParticle( &particles[ i ], dt2 ); } // Increase minimum age min_age += dt2; // Should we create any new particle(s)? while( min_age >= BIRTH_INTERVAL ) { min_age -= BIRTH_INTERVAL; // Find a dead particle to replace with a new one for( i = 0; i < MAX_PARTICLES; i ++ ) { if( !particles[ i ].active ) { InitParticle( &particles[ i ], t + min_age ); UpdateParticle( &particles[ i ], min_age ); break; } } } // Decrease frame delta time dt -= dt2; } }
void ParticleSystem::Draw(void) { glBindTexture(GL_TEXTURE_2D, texture); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //std::ofstream fout("out.txt", std::ios_base::trunc); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)modeviewMatrix); for (int loop = 0;loop < MAX_PARTICLES; loop++) { if (particles[loop].active) { float x = particles[loop].pos.x; float y = particles[loop].pos.y; float z = particles[loop].pos.z; // Draw The Particle Using Our RGB Values, Fade The Particle Based On It's Life //glColor4f(particles[loop].color.r, particles[loop].color.g, particles[loop].color.b, particles[loop].life); //glBegin(GL_TRIANGLE_STRIP); //glTexCoord2d(1, 1); glVertex3f(x + parSize, y + parSize, z); // 右上 //glTexCoord2d(0, 1); glVertex3f(x - parSize, y + parSize, z); // 左上 //glTexCoord2d(1, 0); glVertex3f(x + parSize, y - parSize, z); // 右下 //glTexCoord2d(0, 0); glVertex3f(x - parSize, y - parSize, z); // 左下 //glEnd(); //std::cout << x << " " << y << " " << z << std::endl; particles[loop].pos += particles[loop].speed / (slowdown * 1000); particles[loop].speed += (particles[loop].grav - particles[loop].speed * airFric); particles[loop].life -= particles[loop].fade; if (particles[loop].life < 0.0f) // 当一个粒子生命周期到了时,重新给它赋值 { InitParticle(particles[loop]); } } } //fout.close(); }
CParticleSystemBlood::CParticleSystemBlood(const PROPERTYMAP& properties, CResourceManager* resman, const vec3_t& ownerpos) { const int particles = 8; m_particles.reserve(particles); m_texture = resman->GetTexture(CLynx::GetBaseDirFX() + "blood.tga"); GetProperty(properties, "dx", &m_dir.x, 0); GetProperty(properties, "dy", &m_dir.y, 0); GetProperty(properties, "dz", &m_dir.z, -1.0f); GetProperty(properties, "size", &m_size, 4.8f); if(m_dir.AbsSquared() > 0.1f) // dir might be zero m_dir = m_dir.Normalized() * 6.0f; for(int i=0;i<particles;i++) { particle_t p; InitParticle(p, ownerpos); m_particles.push_back(p); } }
void CDisintegrationEffect::OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick) // OnUpdate // // Update the effect { int i; // See if the effect has faded out m_iTick++; if (m_iTick >= LIFETIME) { Destroy(removedFromSystem, CDamageSource()); return; } // Otherwise, update the particles SParticle *pParticle = m_pParticles; for (i = 0; i < m_iParticleCount; i++, pParticle++) { pParticle->iTicksLeft--; pParticle->x += pParticle->xV; pParticle->y += pParticle->yV; if (m_iTick < DISPERSE_POINT) { if (pParticle->iTicksLeft <= 0) InitParticle(pParticle); } } // If we're moving, slow down SetVel(CVector(GetVel().GetX() * g_SpaceDragFactor, GetVel().GetY() * g_SpaceDragFactor)); }
void Emitter::Play() { if(particles.empty() && maxParticles > 0) return; for(int i = 0; i < emissionRate && (!particles.empty() || maxParticles == 0); i++) { ParticlePtr particle; if(maxParticles > 0) { particle = particles.front(); particles.pop_front(); } else { particle = ParticlePtr(new Particle()); } InitParticle(particle); emittedParticles.push_front(particle); particle->SetIsVisible(true); } }
void SplitterSystem::InitEmitter(float metersToPixels, float screenH, float screenW) { emitter.mPosition.x = screenW / 2; emitter.mPosition.y = screenH - 10; emitter.mParams = params; emitter.mParticleCapacity = params.mMaxParticles; emitter.mParticles = DBG_NEW Particle[emitter.mParticleCapacity]; emitter.mParticleCount = emitter.mParams.mMinParticles; emitter.mMetersToPixels = metersToPixels; //set number of particles. int numberOfParticles = InRange(emitter.mParams.mMinParticles, emitter.mParams.mMaxParticles); //set particle lifetime. float lifetime = InRange(emitter.mParams.mMinLifeTimeMs, emitter.mParams.mMaxLifeTimeMs); // create particles. for (int i = 0; i != numberOfParticles; ++i) { emitter.mParticles[i].mTime = lifetime; InitParticle(emitter.mParticles + i); } }
void dfParticleSystem::CreateParticle() { ParticleInfo p; InitParticle(p); if(sInfo.useSpawnRect) { p.pos = vec2( (dfRand() * sInfo.spawnRect.width) + sInfo.spawnRect.left, (dfRand() * sInfo.spawnRect.height) + sInfo.spawnRect.top); } else { p.pos = vec2(sInfo.spawnPoint.x, sInfo.spawnPoint.y); } p.acc = sInfo.minAcc + (dfRand() * (sInfo.maxAcc - sInfo.minAcc)); int colorIndex = rand() % sInfo.startColors.size(); p.startColor = sInfo.startColors[colorIndex]; p.color = p.startColor; p.dead = false; p.maxSize = sInfo.minParticleSize + (dfRand() * (sInfo.maxParticleSize - sInfo.minParticleSize)); p.w = p.maxSize; p.h = p.maxSize; p.lifespan = sInfo.minLifespan + (dfRand() * (sInfo.maxLifespan - sInfo.minLifespan)); p.lifetime = 0; p.rotation = sInfo.minStartRotation + (dfRand() * (sInfo.maxStartRotation - sInfo.minStartRotation)); p.rotationSpd = sInfo.minRotationSpd + (dfRand() * (sInfo.maxRotationSpd - sInfo.minRotationSpd)); float newVeloc = dfRand() * (sInfo.maxVeloc - sInfo.minVeloc); float xComp = cos((Pi32 / 180.f) * p.rotation) * newVeloc; float yComp = sin((Pi32 / 180.f) * p.rotation) * newVeloc; p.veloc = vec2(xComp, yComp); dfAssert(sInfo.textures.size() > 0); // need a texture to attatch to particle, dawg! int textureIndex = rand() % sInfo.textures.size(); //p.texture = textures[textureIndex]; p.renderRect = new Rect(); RectSet(p.pos.x - (p.w / 2.f), p.pos.y - (p.h / 2.f), p.w, p.h, p.renderRect); for(int i = 0; i < currentParticleCap + 1 < MAX_PARTICLES ? currentParticleCap + 1 : MAX_PARTICLES; i++) { if(particles[i].dead) { particles[i] = p; particleRenderers[i].renderRect = p.renderRect; particleRenderers[i].SetTexture(sInfo.textures[textureIndex]); particleRenderers[i].renderInfo.active = true; particleRenderers[i].renderInfo.depth = layer; for(int cIndex = 0; cIndex < particleRenderers[i].renderInfo.uniforms.size(); cIndex++) { if(dfStrCmp("rect", particleRenderers[i].renderInfo.uniforms[cIndex].name)) { particleRenderers[i].renderInfo.uniforms[cIndex].valueRect = p.renderRect; break; } } numParticles++; if(i == currentParticleCap) currentParticleCap++; return; } } dfWarn("Could not create particle. Max particles!"); }
__private_extern__ void DrawParticle(Particle *p) // the math was easier in 2D - so 2D it is { float screenx = (p->x * info->sys_glWidth / p->z) + info->sys_glWidth * 0.5f; float screeny = (p->y * info->sys_glWidth / p->z) + info->sys_glHeight * 0.5f; float oldscreenx = (p->oldx * info->sys_glWidth / p->oldz) + info->sys_glWidth * 0.5f; float oldscreeny = (p->oldy * info->sys_glWidth / p->oldz) + info->sys_glHeight * 0.5f; // near clip if(p->z < 100.0f) { InitParticle(p); return; } // side clip if(screenx > info->sys_glWidth + 100.0f || screenx < -100.0f) { InitParticle(p); return; } // vertical clip if(screeny > info->sys_glHeight + 100.0f || screeny < -100.0f) { InitParticle(p); return; } info->starfieldColor[info->starfieldColorIndex++] = p->r; info->starfieldColor[info->starfieldColorIndex++] = p->g; info->starfieldColor[info->starfieldColorIndex++] = p->b; info->starfieldColor[info->starfieldColorIndex++] = 1.0f; info->starfieldColor[info->starfieldColorIndex++] = p->r; info->starfieldColor[info->starfieldColorIndex++] = p->g; info->starfieldColor[info->starfieldColorIndex++] = p->b; info->starfieldColor[info->starfieldColorIndex++] = 1.0f; info->starfieldColor[info->starfieldColorIndex++] = p->r; info->starfieldColor[info->starfieldColorIndex++] = p->g; info->starfieldColor[info->starfieldColorIndex++] = p->b; info->starfieldColor[info->starfieldColorIndex++] = 1.0f; info->starfieldColor[info->starfieldColorIndex++] = p->r; info->starfieldColor[info->starfieldColorIndex++] = p->g; info->starfieldColor[info->starfieldColorIndex++] = p->b; info->starfieldColor[info->starfieldColorIndex++] = 1.0f; p->animFrame++; if (p->animFrame == 64) { p->animFrame = 0; } { float dx = (screenx-oldscreenx); float dy = (screeny-oldscreeny); float m = FastDistance2D(dx, dy); float u0 = (p->animFrame&&7) * 0.125f; float v0 = (p->animFrame>>3) * 0.125f; float u1 = u0 + 0.125f; float v1 = v0 + 0.125f; float size = (3500.0f*(info->sys_glWidth/1024.0f)); float w = max(1.5f,size/p->z); float ow = max(1.5f,size/p->oldz); float d = FastDistance2D(dx, dy); float s, os, dxs, dys, dxos, dyos, dxm, dym; if(d) { s = w/d; } else { s = 0.0f; } if(d) { os = ow/d; } else { os = 0.0f; } m = 2.0f + s; dxs = dx*s; dys = dy*s; dxos = dx*os; dyos = dy*os; dxm = dx*m; dym = dy*m; info->starfieldTextures[info->starfieldTexturesIndex++] = u0; info->starfieldTextures[info->starfieldTexturesIndex++] = v0; info->starfieldVertices[info->starfieldVerticesIndex++] = screenx+dxm-dys; info->starfieldVertices[info->starfieldVerticesIndex++] = screeny+dym+dxs; info->starfieldTextures[info->starfieldTexturesIndex++] = u0; info->starfieldTextures[info->starfieldTexturesIndex++] = v1; info->starfieldVertices[info->starfieldVerticesIndex++] = screenx+dxm+dys; info->starfieldVertices[info->starfieldVerticesIndex++] = screeny+dym-dxs; info->starfieldTextures[info->starfieldTexturesIndex++] = u1; info->starfieldTextures[info->starfieldTexturesIndex++] = v1; info->starfieldVertices[info->starfieldVerticesIndex++] = oldscreenx-dxm+dyos; info->starfieldVertices[info->starfieldVerticesIndex++] = oldscreeny-dym-dxos; info->starfieldTextures[info->starfieldTexturesIndex++] = u1; info->starfieldTextures[info->starfieldTexturesIndex++] = v0; info->starfieldVertices[info->starfieldVerticesIndex++] = oldscreenx-dxm-dyos; info->starfieldVertices[info->starfieldVerticesIndex++] = oldscreeny-dym+dxos; } }
void CreateDistribution (cluster_type cluster, model_type model) { particle *particle_array; int global_num_particles; particle *new_particle; char particle_state[RANDOM_SIZE]; real charge; real r_scale; real v_scale; vector r_sum; vector v_sum; int end_limit; int i; int j; real temp_r; real radius; real x_vel; real y_vel; real vel; real offset; particle *twin_particle; particle_array = (particle *) G_MALLOC(Total_Particles * sizeof(particle)); Particle_List = (particle **) G_MALLOC(Total_Particles * sizeof(particle *)); for (i = 0; i < Total_Particles; i++) Particle_List[i] = &particle_array[i]; r_scale = 3 * M_PI / 16; v_scale = (real) sqrt(1.0 / (double) r_scale); r_sum.x = (real) 0.0; r_sum.y = (real) 0.0; v_sum.x = (real) 0.0; v_sum.y = (real) 0.0; initstate(0, particle_state, RANDOM_SIZE); switch (cluster) { case ONE_CLUSTER: end_limit = Total_Particles; switch (model) { case UNIFORM: printf("Creating a one cluster, uniform distribution for %d ", Total_Particles); printf("particles\n"); break; case PLUMMER: printf("Creating a one cluster, non uniform distribution for %d ", Total_Particles); printf("particles\n"); break; } break; case TWO_CLUSTER: end_limit = (Total_Particles / 2) + (Total_Particles & 0x1); switch (model) { case UNIFORM: printf("Creating a two cluster, uniform distribution for %d ", Total_Particles); printf("particles\n"); break; case PLUMMER: printf("Creating a two cluster, non uniform distribution for %d ", Total_Particles); printf("particles\n"); break; } break; } setstate(particle_state); global_num_particles = 0; charge = 1.0 / Total_Particles; charge /= Total_Particles; for (i = 0; i < end_limit; i++) { new_particle = InitParticle(charge, charge); switch (model) { case UNIFORM: do { new_particle->pos.x = XRand(-1.0, 1.0); new_particle->pos.y = XRand(-1.0, 1.0); temp_r = DOT_PRODUCT((new_particle->pos), (new_particle->pos)); } while (temp_r > (real) 1.0); radius = sqrt(temp_r); break; case PLUMMER: do radius = (real) 1.0 / (real) sqrt(pow(XRand(0.0, MAX_FRAC), -2.0/3.0) - 1); while (radius > 9.0); PickShell(&(new_particle->pos), r_scale * radius); break; } VECTOR_ADD(r_sum, r_sum, (new_particle->pos)); do { x_vel = XRand(0.0, 1.0); y_vel = XRand(0.0, 0.1); } while (y_vel > x_vel * x_vel * (real) pow(1.0 - (x_vel * x_vel), 3.5)); vel = (real) sqrt(2.0) * x_vel / pow(1.0 + (radius * radius), 0.25); PickShell(&(new_particle->vel), v_scale * vel); VECTOR_ADD(v_sum, v_sum, (new_particle->vel)); } if (cluster == TWO_CLUSTER) { switch (model) { case UNIFORM: offset = 1.5; break; case PLUMMER: offset = 2.0; break; } for (i = end_limit; i < Total_Particles; i++) { new_particle = InitParticle(charge, charge); twin_particle = Particle_List[i - end_limit]; new_particle->pos.x = twin_particle->pos.x + offset; new_particle->pos.y = twin_particle->pos.y + offset; VECTOR_ADD(r_sum, r_sum, (new_particle->pos)); new_particle->vel.x = twin_particle->vel.x; new_particle->vel.y = twin_particle->vel.y; VECTOR_ADD(v_sum, v_sum, (new_particle->vel)); } } VECTOR_DIV(r_sum, r_sum, (real) Total_Particles); VECTOR_DIV(v_sum, v_sum, (real) Total_Particles); for (i = 0; i < Total_Particles; i++) { new_particle = Particle_List[i]; VECTOR_SUB((new_particle->pos), (new_particle->pos), r_sum); VECTOR_SUB((new_particle->vel), (new_particle->vel), v_sum); } }