// ParticleSystem - MainLoop void CCParticleSystem::update(ccTime dt) { if( m_bIsActive && m_fEmissionRate ) { float rate = 1.0f / m_fEmissionRate; m_fEmitCounter += dt; while( m_nParticleCount < m_nTotalParticles && m_fEmitCounter > rate ) { this->addParticle(); m_fEmitCounter -= rate; } m_fElapsed += dt; if(m_fDuration != -1 && m_fDuration < m_fElapsed) { this->stopSystem(); } } m_nParticleIdx = 0; #if CC_ENABLE_PROFILERS /// @todo CCProfilingBeginTimingBlock(_profilingTimer); #endif CGPoint currentPosition = CGPointZero; if( m_ePositionType == kCCPositionTypeFree ) { currentPosition = this->convertToWorldSpace(CGPointZero); currentPosition.x *= CC_CONTENT_SCALE_FACTOR(); currentPosition.y *= CC_CONTENT_SCALE_FACTOR(); } else if ( m_ePositionType == kCCPositionTypeRelative ) { currentPosition = m_tPosition; currentPosition.x *= CC_CONTENT_SCALE_FACTOR(); currentPosition.y *= CC_CONTENT_SCALE_FACTOR(); } while( m_nParticleIdx < m_nParticleCount ) { tCCParticle *p = &m_pParticles[m_nParticleIdx]; // life p->timeToLive -= dt; if( p->timeToLive > 0 ) { // Mode A: gravity, direction, tangential accel & radial accel if( m_nEmitterMode == kCCParticleModeGravity ) { CGPoint tmp, radial, tangential; radial = CGPointZero; // radial acceleration if(p->pos.x || p->pos.y) radial = ccpNormalize(p->pos); tangential = radial; radial = ccpMult(radial, p->modeA.radialAccel); // tangential acceleration float newy = tangential.x; tangential.x = -tangential.y; tangential.y = newy; tangential = ccpMult(tangential, p->modeA.tangentialAccel); // (gravity + radial + tangential) * dt tmp = ccpAdd( ccpAdd( radial, tangential), modeA.gravity); tmp = ccpMult( tmp, dt); p->modeA.dir = ccpAdd( p->modeA.dir, tmp); tmp = ccpMult(p->modeA.dir, dt); p->pos = ccpAdd( p->pos, tmp ); } // Mode B: radius movement else { // Update the angle and radius of the particle. p->modeB.angle += p->modeB.degreesPerSecond * dt; p->modeB.radius += p->modeB.deltaRadius * dt; p->pos.x = - cosf(p->modeB.angle) * p->modeB.radius; p->pos.y = - sinf(p->modeB.angle) * p->modeB.radius; } // color p->color.r += (p->deltaColor.r * dt); p->color.g += (p->deltaColor.g * dt); p->color.b += (p->deltaColor.b * dt); p->color.a += (p->deltaColor.a * dt); // size p->size += (p->deltaSize * dt); p->size = MAX( 0, p->size ); // angle p->rotation += (p->deltaRotation * dt); // // update values in quad // CGPoint newPos; if( m_ePositionType == kCCPositionTypeFree || m_ePositionType == kCCPositionTypeRelative ) { CGPoint diff = ccpSub( currentPosition, p->startPos ); newPos = ccpSub(p->pos, diff); } else { newPos = p->pos; } updateQuadWithParticle(p, newPos); //updateParticleImp(self, updateParticleSel, p, newPos); // update particle counter ++m_nParticleIdx; } else { // life < 0 if( m_nParticleIdx != m_nParticleCount-1 ) { m_pParticles[m_nParticleIdx] = m_pParticles[m_nParticleCount-1]; } --m_nParticleCount; if( m_nParticleCount == 0 && m_bIsAutoRemoveOnFinish ) { this->unscheduleUpdate(); m_pParent->removeChild(this, true); return; } } } #if CC_ENABLE_PROFILERS /// @todo CCProfilingEndTimingBlock(_profilingTimer); #endif //#ifdef CC_USES_VBO this->postStep(); //#endif }
void CCParticleSystemFrameQuad::update(float dt) { CC_PROFILER_START_CATEGORY(kCCProfilerCategoryParticles , "CCParticleSystemFrameQuad - update"); if (m_bIsActive && m_fEmissionRate) { float rate = 1.0f / m_fEmissionRate; //issue #1201, prevent bursts of particles, due to too high emitCounter if (m_uParticleCount < m_uTotalParticles) { m_fEmitCounter += dt; } while (m_uParticleCount < m_uTotalParticles && m_fEmitCounter > rate) { this->addParticle(); m_fEmitCounter -= rate; } m_fElapsed += dt; if (m_fDuration != -1 && m_fDuration < m_fElapsed) { this->stopSystem(); } } m_uParticleIdx = 0; CCPoint currentPosition = CCPointZero; if (m_ePositionType == kCCPositionTypeFree) { currentPosition = this->convertToWorldSpace(CCPointZero); } else if (m_ePositionType == kCCPositionTypeRelative) { currentPosition = m_obPosition; } if (m_bVisible) { while (m_uParticleIdx < m_uParticleCount) { tCCParticle *p = &m_pParticles[m_uParticleIdx]; // life p->timeToLive -= dt; if (p->timeToLive > 0) { // Mode A: gravity, direction, tangential accel & radial accel if (m_nEmitterMode == kCCParticleModeGravity) { CCPoint tmp, radial, tangential; radial = CCPointZero; // radial acceleration if (p->pos.x || p->pos.y) { radial = ccpNormalize(p->pos); } tangential = radial; radial = ccpMult(radial, p->modeA.radialAccel); // tangential acceleration float newy = tangential.x; tangential.x = -tangential.y; tangential.y = newy; tangential = ccpMult(tangential, p->modeA.tangentialAccel); // (gravity + radial + tangential) * dt tmp = ccpAdd( ccpAdd( radial, tangential), modeA.gravity); tmp = ccpMult( tmp, dt); p->modeA.dir = ccpAdd( p->modeA.dir, tmp); tmp = ccpMult(p->modeA.dir, dt); p->pos = ccpAdd( p->pos, tmp ); } // Mode B: radius movement else { // Update the angle and radius of the particle. p->modeB.angle += p->modeB.degreesPerSecond * dt; p->modeB.radius += p->modeB.deltaRadius * dt; p->pos.x = - cosf(p->modeB.angle) * p->modeB.radius; p->pos.y = - sinf(p->modeB.angle) * p->modeB.radius; } // color p->color.r += (p->deltaColor.r * dt); p->color.g += (p->deltaColor.g * dt); p->color.b += (p->deltaColor.b * dt); p->color.a += (p->deltaColor.a * dt); // size p->size += (p->deltaSize * dt); p->size = MAX( 0, p->size ); // angle p->rotation += (p->deltaRotation * dt); // // update values in quad // CCPoint newPos; if (m_ePositionType == kCCPositionTypeFree || m_ePositionType == kCCPositionTypeRelative) { CCPoint diff = ccpSub( currentPosition, p->startPos ); newPos = ccpSub(p->pos, diff); } else { newPos = p->pos; } // translate newPos to correct position, since matrix transform isn't performed in batchnode // don't update the particle with the new position information, it will interfere with the radius and tangential calculations if (m_pBatchNode) { newPos.x+=m_obPosition.x; newPos.y+=m_obPosition.y; } updateQuadWithParticle(p, newPos); //updateParticleImp(self, updateParticleSel, p, newPos); // update particle counter ++m_uParticleIdx; } else { // life < 0 int currentIndex = p->atlasIndex; if( m_uParticleIdx != m_uParticleCount-1 ) { m_pParticles[m_uParticleIdx] = m_pParticles[m_uParticleCount-1]; } if (m_pBatchNode) { //disable the switched particle m_pBatchNode->disableParticle(m_uAtlasIndex+currentIndex); //switch indexes m_pParticles[m_uParticleCount-1].atlasIndex = currentIndex; } else if( m_uParticleIdx != m_uParticleCount-1 ) { //switch quads texCoords ccV3F_C4B_T2F_Quad temp = m_pQuads[m_uParticleIdx]; m_pQuads[m_uParticleIdx] = m_pQuads[m_uParticleCount-1]; m_pQuads[m_uParticleCount-1] = temp; } --m_uParticleCount; if( m_uParticleCount == 0 && m_bIsAutoRemoveOnFinish ) { this->unscheduleUpdate(); m_pParent->removeChild(this, true); return; } } } //while m_bTransformSystemDirty = false; } if (! m_pBatchNode) { postStep(); } CC_PROFILER_STOP_CATEGORY(kCCProfilerCategoryParticles , "CCParticleSystemFrameQuad - update"); }
void BillboardParticleSystem::update(float dt) { if(_camera) { const Mat4& cameraViewMatrix = _camera->getViewMatrix().getInversed(); cameraViewMatrix.getRightVector(&_cameraRight); cameraViewMatrix.getUpVector(&_cameraUp); } const Mat4& WorldMat = getNodeToWorldTransform(); Quaternion rotation;; WorldMat.getRotation(&rotation); Mat4 roaMat; Mat4::createRotation(rotation,&roaMat); CC_PROFILER_START_CATEGORY(kProfilerCategoryParticles , "CCParticleSystem - update"); if (_isActive && _emissionRate) { float rate = 1.0f / _emissionRate; //issue #1201, prevent bursts of particles, due to too high emitCounter if (_particleCount < _totalParticles) { _emitCounter += dt; } while (_particleCount < _totalParticles && _emitCounter > rate) { this->addParticle(); _emitCounter -= rate; } _elapsed += dt; if (_duration != -1 && _duration < _elapsed) { this->stopSystem(); } } _particleIdx = 0; Vec3 currentPosition = Vec3::ZERO; if (_positionType == PositionType::FREE) { currentPosition = this->convertToWorldSpace3D(Vec3::ZERO); } else if (_positionType == PositionType::RELATIVE) { currentPosition.x = _position.x; currentPosition.y = _position.y; currentPosition.z = _positionZ; } { while (_particleIdx < _particleCount) { sBillboardParticle *p = &_particles[_particleIdx]; // life p->timeToLive -= dt; if (p->timeToLive > 0) { // Mode A: gravity, direction, tangential accel & radial accel if (_emitterMode == Mode::GRAVITY) { Vec2 tmp, radial, tangential; radial = Vec2::ZERO; // radial acceleration if (p->pos.x || p->pos.y) { radial = p->pos.getNormalized(); } tangential = radial; radial = radial * p->modeA.radialAccel; // tangential acceleration float newy = tangential.x; tangential.x = -tangential.y; tangential.y = newy; tangential = tangential * p->modeA.tangentialAccel; // (gravity + radial + tangential) * dt tmp = radial + tangential + modeA.gravity; tmp = tmp * dt; p->modeA.dir = p->modeA.dir + tmp; // this is cocos2d-x v3.0 // if (_configName.length()>0 && _yCoordFlipped != -1) // this is cocos2d-x v3.0 tmp = p->modeA.dir * dt * _yCoordFlipped; p->pos = p->pos + tmp; } // Mode B: radius movement else { // Update the angle and radius of the particle. p->modeB.angle += p->modeB.degreesPerSecond * dt; p->modeB.radius += p->modeB.deltaRadius * dt; p->pos.x = - cosf(p->modeB.angle) * p->modeB.radius; p->pos.y = - sinf(p->modeB.angle) * p->modeB.radius; p->pos.y *= _yCoordFlipped; } // color p->color.r += (p->deltaColor.r * dt); p->color.g += (p->deltaColor.g * dt); p->color.b += (p->deltaColor.b * dt); p->color.a += (p->deltaColor.a * dt); // size p->size += (p->deltaSize * dt); p->size = MAX( 0, p->size ); // angle p->rotation += (p->deltaRotation * dt); // // update values in quad // Vec3 newPos; Vec3 parPos(p->pos.x,p->pos.y,0); roaMat.transformVector(&parPos); if (_positionType == PositionType::FREE) { Vec3 diff = convertToNodeSpace3D(currentPosition) - convertToNodeSpace3D(p->startPos); //newPos.x = p->pos.x - diff.x; //newPos.y = p->pos.y - diff.y; //newPos.z = - diff.z; newPos = parPos-diff; } else if(_positionType == PositionType::RELATIVE) { Vec3 diff = currentPosition - p->startPos; newPos.x = p->pos.x - diff.x; newPos.y = p->pos.y - diff.y; newPos.z = - diff.z; } else { newPos.x = p->pos.x; newPos.y = p->pos.y; newPos.z = 0; } updateQuadWithParticle(p, newPos); //updateParticleImp(self, updateParticleSel, p, newPos); // update particle counter ++_particleIdx; } else { // life < 0 int currentIndex = p->atlasIndex; if( _particleIdx != _particleCount-1 ) { _particles[_particleIdx] = _particles[_particleCount-1]; } --_particleCount; if( _particleCount == 0 && _isAutoRemoveOnFinish ) { this->unscheduleUpdate(); _parent->removeChild(this, true); return; } } } //while _transformSystemDirty = false; } // only update gl buffer when visible if (_visible) { postStep(); } CC_PROFILER_STOP_CATEGORY(kProfilerCategoryParticles , "BillboardParticleSystem - update"); }
void ParticleSystem::update(fzFloat dt) { if( m_isActive && m_emissionRate ) { fzFloat rate = 1.0f / m_emissionRate; m_emitCounter += dt; while( m_particleCount < m_totalParticles && m_emitCounter > rate ) { addParticle(); m_emitCounter -= rate; } m_elapsed += dt; if(m_duration != -1 && m_duration < m_elapsed) stopSystem(); } m_particleIdx = 0; while( m_particleIdx < m_particleCount ) { fzParticle& p = p_particles[m_particleIdx]; // life p.timeToLive -= dt; if( p.timeToLive > 0 ) { // Mode A if( m_emitterMode == kFZParticleModeGravity ) { fzPoint tmp(p.pos); if(tmp != FZPointZero) { // calculate tangential fzPoint tangential(tmp.getPerp()); tangential.normalize(); tangential *= p.mode.A.tangentialAccel; // radial acceleration tmp *= p.mode.A.radialAccel; // radial + tangential tmp += tangential; } // (gravity + dir + radial + tangential) * dt tmp += mode.A.gravity; tmp += p.mode.A.dir; p.pos += tmp * dt; } // Mode B else { // Update the angle and radius of the particle. p.mode.B.angle += p.mode.B.degreesPerSecond * dt; p.mode.B.radius += p.mode.B.deltaRadius * dt; p.pos.x = -fzMath_cos(p.mode.B.angle) * p.mode.B.radius; p.pos.y = -fzMath_sin(p.mode.B.angle) * p.mode.B.radius; } // color p.color += p.deltaColor * dt; // size p.size += p.deltaSize * dt; p.size = p.size < 0 ? 0 : p.size; // angle p.rotation += p.deltaRotation * dt; // update values in quad updateQuadWithParticle(p); // update particle counter ++m_particleIdx; } else { // life < 0 --m_particleCount; if( m_particleIdx != m_particleCount ) memmove(&p_particles[m_particleIdx], &p_particles[m_particleCount], sizeof(fzParticle)); if( m_particleCount == 0 && m_autoRemoveOnFinish ) { unschedule(); removeFromParent(true); return; } } } if(m_particleCount) makeDirty(0); #if FZ_VBO_STREAMING postStep(); #endif }
void NParticleSystemQuad::update(float dt) { CC_PROFILER_START_CATEGORY(kProfilerCategoryParticles , "CCParticleSystem - update"); if (_isActive && _emissionRate) { float rate = 1.0f / _emissionRate; //issue #1201, prevent bursts of particles, due to too high emitCounter if (_particleCount < _totalParticles) { _emitCounter += dt; } while (_particleCount < _totalParticles && _emitCounter > rate) { this->addParticle(); _emitCounter -= rate; } _elapsed += dt; if (_duration != -1 && _duration < _elapsed) { this->stopSystem(); } } _particleIdx = 0; Vec2 currentPosition = Vec2::ZERO; if (_positionType == PositionType::FREE) { currentPosition = this->convertToWorldSpace(Vec2::ZERO); } else if (_positionType == PositionType::RELATIVE) { currentPosition = _position; } { while (_particleIdx < _particleCount) { tParticle *p = &_particles[_particleIdx]; // life p->timeToLive -= dt; if (p->timeToLive > 0) { // Mode A: gravity, direction, tangential accel & radial accel if (_emitterMode == Mode::GRAVITY) { Vec2 tmp, radial, tangential; radial = Vec2::ZERO; // radial acceleration if (p->pos.x || p->pos.y) { radial = p->pos.getNormalized(); } tangential = radial; radial = radial * p->modeA.radialAccel; // tangential acceleration float newy = tangential.x; tangential.x = -tangential.y; tangential.y = newy; tangential = tangential * p->modeA.tangentialAccel; // (gravity + radial + tangential) * dt tmp = radial + tangential + modeA.gravity; tmp = tmp * dt; p->modeA.dir = p->modeA.dir + tmp; // this is cocos2d-x v3.0 // if (_configName.length()>0 && _yCoordFlipped != -1) // this is cocos2d-x v3.0 tmp = p->modeA.dir * dt * _yCoordFlipped; p->pos = p->pos + tmp; } // Mode B: radius movement else { // Update the angle and radius of the particle. p->modeB.angle += p->modeB.degreesPerSecond * dt; p->modeB.radius += p->modeB.deltaRadius * dt; p->pos.x = - cosf(p->modeB.angle) * p->modeB.radius; p->pos.y = - sinf(p->modeB.angle) * p->modeB.radius; p->pos.y *= _yCoordFlipped; } // color p->color.r += (p->deltaColor.r * dt); p->color.g += (p->deltaColor.g * dt); p->color.b += (p->deltaColor.b * dt); p->color.a += (p->deltaColor.a * dt); // size p->size += (p->deltaSize * dt); p->size = MAX( 0, p->size ); // angle p->rotation += (p->deltaRotation * dt); // // update values in quad // Vec2 newPos; if (_positionType == PositionType::FREE || _positionType == PositionType::RELATIVE) { Vec2 diff = currentPosition - p->startPos; newPos = p->pos - diff; } else { newPos = p->pos; } // translate newPos to correct position, since matrix transform isn't performed in batchnode // don't update the particle with the new position information, it will interfere with the radius and tangential calculations if (_batchNode) { newPos.x+=_position.x; newPos.y+=_position.y; } updateQuadWithParticle(p, newPos); //updateParticleImp(self, updateParticleSel, p, newPos); // update particle counter ++_particleIdx; } else { // life < 0 int currentIndex = p->atlasIndex; if( _particleIdx != _particleCount-1 ) { _particles[_particleIdx] = _particles[_particleCount-1]; } if (_batchNode) { //disable the switched particle _batchNode->disableParticle(_atlasIndex+currentIndex); //switch indexes _particles[_particleCount-1].atlasIndex = currentIndex; } --_particleCount; if( _particleCount == 0 && _isAutoRemoveOnFinish ) { this->unscheduleUpdate(); _parent->removeChild(this, true); // 親から remove されるときにコールバック関数を呼ぶ if (onFinishListener) { onFinishListener(this); } return; } } } //while _transformSystemDirty = false; } // only update gl buffer when visible if (_visible && ! _batchNode) { postStep(); } CC_PROFILER_STOP_CATEGORY(kProfilerCategoryParticles , "CCParticleSystem - update"); }