123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969 |
- /****************************************************************************
- Copyright (C) 2013 Henry van Merode. All rights reserved.
- Copyright (c) 2015-2017 Chukong Technologies Inc.
-
- http://www.cocos2d-x.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
- #include "CCPUEmitter.h"
- #include "extensions/Particle3D/PU/CCPUParticleSystem3D.h"
- #include "extensions/Particle3D/PU/CCPUUtil.h"
- NS_CC_BEGIN
- // Constants
- const bool PUEmitter::DEFAULT_ENABLED = true;
- const Vec3 PUEmitter::DEFAULT_POSITION(0, 0, 0);
- const bool PUEmitter::DEFAULT_KEEP_LOCAL = false;
- const Vec3 PUEmitter::DEFAULT_DIRECTION(0, 1, 0);
- const Quaternion PUEmitter::DEFAULT_ORIENTATION(1, 0, 0, 0);
- const Quaternion PUEmitter::DEFAULT_ORIENTATION_RANGE_START(1, 0, 0, 0);
- const Quaternion PUEmitter::DEFAULT_ORIENTATION_RANGE_END(1, 0, 0, 0);
- //const Particle::ParticleType PUEmitter::DEFAULT_EMITS = VisualParticle::PT_VISUAL;
- const unsigned short PUEmitter::DEFAULT_START_TEXTURE_COORDS = 0;
- const unsigned short PUEmitter::DEFAULT_END_TEXTURE_COORDS = 0;
- const unsigned short PUEmitter::DEFAULT_TEXTURE_COORDS = 0;
- const Vec4 PUEmitter::DEFAULT_START_COLOUR_RANGE(0, 0, 0, 1);
- const Vec4 PUEmitter::DEFAULT_END_COLOUR_RANGE(1, 1, 1, 1);
- const Vec4 PUEmitter::DEFAULT_COLOUR(1, 1, 1, 1);
- const bool PUEmitter::DEFAULT_AUTO_DIRECTION = false;
- const bool PUEmitter::DEFAULT_FORCE_EMISSION = false;
- const float PUEmitter::DEFAULT_EMISSION_RATE = 10.0f;
- const float PUEmitter::DEFAULT_TIME_TO_LIVE = 3.0f;
- const float PUEmitter::DEFAULT_MASS = 1.0f;
- const float PUEmitter::DEFAULT_VELOCITY = 100.0f;
- const float PUEmitter::DEFAULT_DURATION = 0.0f;
- const float PUEmitter::DEFAULT_REPEAT_DELAY = 0.0f;
- const float PUEmitter::DEFAULT_ANGLE = 20.0f;
- const float PUEmitter::DEFAULT_DIMENSIONS = 0.0f;
- const float PUEmitter::DEFAULT_WIDTH = 0.0f;
- const float PUEmitter::DEFAULT_HEIGHT = 0.0f;
- const float PUEmitter::DEFAULT_DEPTH = 0.0f;
- PUEmitter::PUEmitter()
- : //mEmitsType(DEFAULT_EMITS),
- //mEmitsName(StringUtil::BLANK),
- _emitterScale(Vec3::ONE),
- _particleDirection(DEFAULT_DIRECTION),
- _originalParticleDirection(DEFAULT_DIRECTION),
- //mParticleOrientation(Quaternion::IDENTITY),
- //mParticleOrientationRangeStart(Quaternion::IDENTITY),
- //mParticleOrientationRangeEnd(Quaternion::IDENTITY),
- _particleOrientationRangeSet(false),
- _dynParticleAllDimensionsSet(false),
- _dynParticleWidthSet(false),
- _dynParticleHeightSet(false),
- _dynParticleDepthSet(false),
- _remainder(0),
- _durationRemain(0),
- _dynDurationSet(false),
- _repeatDelayRemain(0),
- _dynRepeatDelaySet(false),
- _autoDirection(DEFAULT_AUTO_DIRECTION),
- _forceEmission(DEFAULT_FORCE_EMISSION),
- _originalForceEmission(false),
- _forceEmissionExecuted(false),
- _originalForceEmissionExecuted(false),
- //mName(StringUtil::BLANK),
- _particleColor(DEFAULT_COLOUR),
- _particleColorRangeStart(DEFAULT_START_COLOUR_RANGE),
- _particleColorRangeEnd(DEFAULT_END_COLOUR_RANGE),
- _particleColorRangeSet(false),
- _keepLocal(false),
- _particleTextureCoords(DEFAULT_TEXTURE_COORDS),
- _particleTextureCoordsRangeStart(DEFAULT_START_TEXTURE_COORDS),
- _particleTextureCoordsRangeEnd(DEFAULT_END_TEXTURE_COORDS),
- _particleTextureCoordsRangeSet(false),
- _originEnabled(true),
- _originEnabledSet(false),
- _emitsType(PUParticle3D::PT_VISUAL),
- _emitsEntity(nullptr),
- _isMarkedForEmission(false)
- {
- //particleType = PT_EMITTER;
- //mAliasType = AT_EMITTER;
- _dynEmissionRate = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynEmissionRate))->setValue(DEFAULT_EMISSION_RATE);
- _dynTotalTimeToLive = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynTotalTimeToLive))->setValue(DEFAULT_TIME_TO_LIVE);
- _dynParticleMass = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynParticleMass))->setValue(DEFAULT_MASS);
- _dynVelocity = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynVelocity))->setValue(DEFAULT_VELOCITY);
- _dynDuration = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynDuration))->setValue(DEFAULT_DURATION);
- _dynRepeatDelay = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynRepeatDelay))->setValue(DEFAULT_REPEAT_DELAY);
- _dynAngle = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynAngle))->setValue(DEFAULT_ANGLE);
- // Set the dimensions attributes to 0; the default is to use the default dimensions of the ParticleTechnique
- _dynParticleAllDimensions = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynParticleAllDimensions))->setValue(DEFAULT_DIMENSIONS);
- _dynParticleWidth = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynParticleWidth))->setValue(DEFAULT_WIDTH);
- _dynParticleHeight = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynParticleHeight))->setValue(DEFAULT_HEIGHT);
- _dynParticleDepth = new (std::nothrow) PUDynamicAttributeFixed();
- (static_cast<PUDynamicAttributeFixed*>(_dynParticleDepth))->setValue(DEFAULT_DEPTH);
- }
- PUEmitter::~PUEmitter()
- {
- _particleSystem = nullptr;
- if (_dynEmissionRate)
- delete _dynEmissionRate;
- if (_dynTotalTimeToLive)
- delete _dynTotalTimeToLive;
- if (_dynParticleMass)
- delete _dynParticleMass;
- if (_dynVelocity)
- delete _dynVelocity;
- if (_dynDuration)
- delete _dynDuration;
- if (_dynRepeatDelay)
- delete _dynRepeatDelay;
- if (_dynParticleAllDimensions)
- delete _dynParticleAllDimensions;
- if (_dynParticleWidth)
- delete _dynParticleWidth;
- if (_dynParticleHeight)
- delete _dynParticleHeight;
- if (_dynParticleDepth)
- delete _dynParticleDepth;
- //if (mEmissionRateCameraDependency)
- // mCameraDependencyFactory.destroy(mEmissionRateCameraDependency);
- if (_dynAngle)
- delete _dynAngle;
- }
- void PUEmitter::updateEmitter(Particle3D* /*particle*/, float /*deltaTime*/)
- {
-
- }
- void PUEmitter::emit(int /*count*/)
- {
-
- }
- void PUEmitter::initParticlePosition( PUParticle3D* particle )
- {
- particle->position = getDerivedPosition();
- particle->originalPosition = particle->position;
- particle->latestPosition = particle->position;
- }
- const Vec3& PUEmitter::getDerivedPosition()
- {
- if (_isMarkedForEmission){
- _derivedPosition = _position;
- }else {
- PUParticleSystem3D *ps = static_cast<PUParticleSystem3D *>(_particleSystem);
- Mat4 rotMat;
- Mat4::createRotation(ps->getDerivedOrientation(), &rotMat);
- _derivedPosition = ps->getDerivedPosition() + rotMat * Vec3(_position.x * _emitterScale.x, _position.y * _emitterScale.y, _position.z * _emitterScale.z);
- //_particleSystem->getNodeToWorldTransform().transformPoint(_position, &_derivedPosition);
- }
- return _derivedPosition;
- }
- void PUEmitter::initParticleOrientation( PUParticle3D* particle )
- {
- if (_particleOrientationRangeSet)
- {
- // Generate random orientation 'between' start en end.
- Quaternion::lerp(_particleOrientationRangeStart, _particleOrientationRangeEnd, CCRANDOM_0_1(), &particle->orientation);
- }
- else
- {
- particle->orientation = _particleOrientation;
- }
- // Set original orientation
- particle->originalOrientation = particle->orientation;
- }
- void PUEmitter::initParticleDirection( PUParticle3D* particle )
- {
- // Use the default way of initialising the particle direction
- float angle = 0.0f;
- generateAngle(angle);
- if (angle != 0.0f)
- {
- particle->direction = PUUtil::randomDeviant(_particleDirection, angle, _upVector);
- }
- else
- {
- particle->direction = _particleDirection;
- }
- particle->originalDirection = particle->direction;
- particle->originalDirectionLength = particle->direction.length();
- }
- void PUEmitter::generateAngle( float &angle )
- {
- float a = CC_DEGREES_TO_RADIANS(_dynamicAttributeHelper.calculate(_dynAngle, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart()));
- angle = a;
- if (_dynAngle->getType() == PUDynamicAttribute::DAT_FIXED)
- {
- // Make an exception here and don't use the fixed angle.
- angle = CCRANDOM_0_1() * angle;
- }
- }
- unsigned short PUEmitter::calculateRequestedParticles( float timeElapsed )
- {
- unsigned short requestedParticles = 0;
- //FIXME
- if (_isEnabled)
- {
- if (_dynEmissionRate)
- {
- float rate = _dynEmissionRate->getValue((static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- //if (_emissionRateCameraDependency)
- //{
- // // Affect the emission rate based on the camera distance
- // mEmissionRateCameraDependency->affect(rate, mParentTechnique->getCameraSquareDistance());
- //}
- if (_forceEmission)
- {
- if (_forceEmissionExecuted)
- {
- // It is a single-shot system, so there is nothing left anymore.
- requestedParticles = 0;
- }
- else
- {
- // Ignore the time. Just emit everything at once (if you absolutely need it).
- // The emitter cannot be disabled yet, because it needs to emit its particles first.
- requestedParticles = (unsigned short)rate;
- _forceEmissionExecuted = true;
- }
- }
- else
- {
- // Particle emission is time driven
- _remainder += rate * timeElapsed;
- requestedParticles = (unsigned short)_remainder;
- }
- _remainder -= requestedParticles;
- }
- // Determine whether the duration period has been exceeded.
- if (_dynDurationSet)
- {
- _durationRemain -= timeElapsed;
- if (_durationRemain <= 0)
- {
- setEnabled(false);
- }
- }
- }
- else if (_dynRepeatDelaySet)
- {
- _repeatDelayRemain -= timeElapsed;
- if (_repeatDelayRemain <= 0)
- {
- //// Initialise again (if stopfade isn't set)
- //if (mParentTechnique)
- //{
- // if (!mParentTechnique->isStopFade())
- // {
- // setEnabled(true);
- // }
- //}
- //else
- //{
- // setEnabled(true);
- //}
- setEnabled(true);
- }
- }
- return requestedParticles;
- }
- void PUEmitter::setEnabled( bool enabled )
- {
- _isEnabled = enabled;
- if (!_originEnabledSet){
- _originEnabled = enabled;
- _originEnabledSet = true;
- }
- initTimeBased();
- }
- bool PUEmitter::isEnabled( void ) const
- {
- return _isEnabled;
- }
- void PUEmitter::notifyStart()
- {
- _forceEmission = _originalForceEmission;
- _forceEmissionExecuted = _originalForceEmissionExecuted;
- _remainder = 0;
- _durationRemain = 0;
- _repeatDelayRemain = 0;
- setEnabled(_originEnabled); // Also calls _initTimeBased
- }
- void PUEmitter::notifyRescaled( const Vec3& scale )
- {
- _emitterScale = scale;
- }
- void PUEmitter::notifyStop()
- {
- }
- void PUEmitter::notifyPause()
- {
- }
- void PUEmitter::notifyResume()
- {
- }
- void PUEmitter::prepare()
- {
- if (!_emitsEntity){
- if (_emitsType == PUParticle3D::PT_EMITTER){
- auto emitter = static_cast<PUParticleSystem3D *>(_particleSystem)->getEmitter(_emitsName);
- if (emitter){
- emitter->setMarkedForEmission(true);
- _emitsEntity = emitter;
- }
- }
- else if (_emitsType == PUParticle3D::PT_TECHNIQUE){
- PUParticleSystem3D *system = static_cast<PUParticleSystem3D *>(_particleSystem)->getParentParticleSystem();
- if (system){
- auto children = system->getChildren();
- for (auto it : children){
- if (it->getName() == _emitsName)
- {
- static_cast<PUParticleSystem3D *>(it)->setMarkedForEmission(true);
- _emitsEntity = it;
- break;
- }
- }
- }
- }
- }
- _latestPosition = getDerivedPosition(); // V1.3.1
- }
- void PUEmitter::unPrepare()
- {
- setForceEmission(_forceEmission);
- }
- void PUEmitter::preUpdateEmitter( float /*deltaTime*/ )
- {
- }
- void PUEmitter::postUpdateEmitter( float /*deltaTime*/ )
- {
- Vec3 currentPos = getDerivedPosition();
- _latestPositionDiff = currentPos - _latestPosition;
- _latestPosition = currentPos;
- }
- //-----------------------------------------------------------------------
- bool PUEmitter::isKeepLocal(void) const
- {
- return _keepLocal;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setKeepLocal(bool keepLocal)
- {
- _keepLocal = keepLocal;
- }
- //-----------------------------------------------------------------------
- bool PUEmitter::makeParticleLocal(PUParticle3D* particle)
- {
- if (!particle)
- return true;
- if (!_keepLocal/* || hasEventFlags(PUParticle3D::PEF_EXPIRED)*/)
- return false;
- particle->position += _latestPositionDiff;
- return true;
- }
- //-----------------------------------------------------------------------
- const Vec4& PUEmitter::getParticleColor(void) const
- {
- return _particleColor;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleColor(const Vec4& particleColor)
- {
- _particleColor = particleColor;
- }
- //-----------------------------------------------------------------------
- const Vec4& PUEmitter::getParticleColorRangeStart(void) const
- {
- return _particleColorRangeStart;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleColorRangeStart(const Vec4& particleColorRangeStart)
- {
- _particleColorRangeStart = particleColorRangeStart;
- _particleColorRangeSet = true;
- }
- //-----------------------------------------------------------------------
- const Vec4& PUEmitter::getParticleColorRangeEnd(void) const
- {
- return _particleColorRangeEnd;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleColorRangeEnd(const Vec4& particleColorRangeEnd)
- {
- _particleColorRangeEnd = particleColorRangeEnd;
- _particleColorRangeSet = true;
- }
- //-----------------------------------------------------------------------
- const unsigned short& PUEmitter::getParticleTextureCoords(void) const
- {
- return _particleTextureCoords;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleTextureCoords(const unsigned short& particleTextureCoords)
- {
- _particleTextureCoords = particleTextureCoords;
- }
- //-----------------------------------------------------------------------
- const unsigned short& PUEmitter::getParticleTextureCoordsRangeStart(void) const
- {
- return _particleTextureCoordsRangeStart;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleTextureCoordsRangeStart(const unsigned short& particleTextureCoordsRangeStart)
- {
- _particleTextureCoordsRangeStart = particleTextureCoordsRangeStart;
- _particleTextureCoordsRangeSet = true;
- }
- //-----------------------------------------------------------------------
- const unsigned short& PUEmitter::getParticleTextureCoordsRangeEnd(void) const
- {
- return _particleTextureCoordsRangeEnd;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleTextureCoordsRangeEnd(const unsigned short& particleTextureCoordsRangeEnd)
- {
- _particleTextureCoordsRangeEnd = particleTextureCoordsRangeEnd;
- _particleTextureCoordsRangeSet = true;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setEmitsName(const std::string& emitsName)
- {
- _emitsName = emitsName;
- _emitsEntity = nullptr;
- //if (!_emitsName.empty())
- //{
- // markedForEmission = true;
- // if (mParentTechnique)
- // {
- // // Notify the Technique that something changed
- // mParentTechnique->_notifyEmissionChange();
- // }
- //}
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynEmissionRate(PUDynamicAttribute* dynEmissionRate)
- {
- if (_dynEmissionRate)
- delete _dynEmissionRate;
- _dynEmissionRate = dynEmissionRate;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynTotalTimeToLive(PUDynamicAttribute* dynTotalTimeToLive)
- {
- if (_dynTotalTimeToLive)
- delete _dynTotalTimeToLive;
- _dynTotalTimeToLive = dynTotalTimeToLive;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleMass(PUDynamicAttribute* dynParticleMass)
- {
- if (_dynParticleMass)
- delete _dynParticleMass;
- _dynParticleMass = dynParticleMass;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynAngle(PUDynamicAttribute* dynAngle)
- {
- if (_dynAngle)
- delete _dynAngle;
- _dynAngle = dynAngle;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynVelocity(PUDynamicAttribute* dynVelocity)
- {
- if (_dynVelocity)
- delete _dynVelocity;
- _dynVelocity = dynVelocity;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynDuration(PUDynamicAttribute* dynDuration)
- {
- if (_dynDuration)
- delete _dynDuration;
- _dynDuration = dynDuration;
- _dynDurationSet = true;
- initTimeBased();
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynDurationSet(bool durationSet)
- {
- _dynDurationSet = durationSet;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynRepeatDelay(PUDynamicAttribute* dynRepeatDelay)
- {
- if (_dynRepeatDelay)
- delete _dynRepeatDelay;
- _dynRepeatDelay = dynRepeatDelay;
- _dynRepeatDelaySet = true;
- initTimeBased();
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynRepeatDelaySet(bool repeatDelaySet)
- {
- _dynRepeatDelaySet = repeatDelaySet;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleAllDimensions(PUDynamicAttribute* dynParticleAllDimensions)
- {
- if (_dynParticleAllDimensions)
- delete _dynParticleAllDimensions;
- _dynParticleAllDimensions = dynParticleAllDimensions;
- _dynParticleAllDimensionsSet = true;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleAllDimensionsSet(bool particleAllDimensionsSet)
- {
- _dynParticleAllDimensionsSet = particleAllDimensionsSet;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleWidth(PUDynamicAttribute* dynParticleWidth)
- {
- if (_dynParticleWidth)
- delete _dynParticleWidth;
- _dynParticleWidth = dynParticleWidth;
- _dynParticleWidthSet = true;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleWidthSet(bool particleWidthSet)
- {
- _dynParticleWidthSet = particleWidthSet;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleHeight(PUDynamicAttribute* dynParticleHeight)
- {
- if (_dynParticleHeight)
- delete _dynParticleHeight;
- _dynParticleHeight = dynParticleHeight;
- _dynParticleHeightSet = true;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleHeightSet(bool particleHeightSet)
- {
- _dynParticleHeightSet = particleHeightSet;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleDepth(PUDynamicAttribute* dynParticleDepth)
- {
- if (_dynParticleDepth)
- delete _dynParticleDepth;
- _dynParticleDepth = dynParticleDepth;
- _dynParticleDepthSet = true;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setDynParticleDepthSet(bool particleDepthSet)
- {
- _dynParticleDepthSet = particleDepthSet;
- }
- //-----------------------------------------------------------------------
- const Vec3& PUEmitter::getParticleDirection(void)
- {
- return _particleDirection;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleDirection(const Vec3& direction)
- {
- _particleDirection = direction;
- _originalParticleDirection = direction;
- _particleDirection.normalize();
- _upVector = PUUtil::perpendicular(_particleDirection);
- _upVector.normalize();
- }
- //-----------------------------------------------------------------------
- const Vec3& PUEmitter::getOriginalParticleDirection(void) const
- {
- return _originalParticleDirection;
- }
- //-----------------------------------------------------------------------
- const Quaternion& PUEmitter::getParticleOrientation(void) const
- {
- return _particleOrientation;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleOrientation(const Quaternion& orientation)
- {
- _particleOrientation = orientation;
- }
- //-----------------------------------------------------------------------
- const Quaternion& PUEmitter::getParticleOrientationRangeStart(void) const
- {
- return _particleOrientationRangeStart;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleOrientationRangeStart(const Quaternion& orientationRangeStart)
- {
- _particleOrientationRangeStart = orientationRangeStart;
- _particleOrientationRangeSet = true;
- }
- //-----------------------------------------------------------------------
- const Quaternion& PUEmitter::getParticleOrientationRangeEnd(void) const
- {
- return _particleOrientationRangeEnd;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setParticleOrientationRangeEnd(const Quaternion& orientationRangeEnd)
- {
- _particleOrientationRangeEnd = orientationRangeEnd;
- _particleOrientationRangeSet = true;
- }
- //-----------------------------------------------------------------------
- bool PUEmitter::isAutoDirection(void) const
- {
- return _autoDirection;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setAutoDirection(bool autoDirection)
- {
- _autoDirection = autoDirection;
- }
- //-----------------------------------------------------------------------
- bool PUEmitter::isForceEmission(void) const
- {
- return _forceEmission;
- }
- //-----------------------------------------------------------------------
- void PUEmitter::setForceEmission(bool forceEmission)
- {
- _forceEmission = forceEmission;
- _originalForceEmission = forceEmission;
- _forceEmissionExecuted = false;
- _originalForceEmissionExecuted = false;
- }
- void PUEmitter::initTimeBased( void )
- {
- if (_isEnabled)
- {
- if (_dynDurationSet)
- {
- _durationRemain = _dynamicAttributeHelper.calculate(_dynDuration, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- }
- /** Determine whether duration must be used. If it is used, the emitter should at least be enabled.
- @remarks
- Note, that if the duration has been exceeded, the emitter is disabled. It makes perfect sense to enable
- the emitter again when the duration is initialised with a valid value (> 0).
- */
- if (_durationRemain > 0)
- {
- _isEnabled = true;
- _repeatDelayRemain = 0;
- }
- }
- else
- {
- if (_dynRepeatDelaySet)
- {
- _repeatDelayRemain = _dynamicAttributeHelper.calculate(_dynRepeatDelay, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- }
- }
- }
- void PUEmitter::initParticleForEmission( PUParticle3D* particle )
- {
- // Initialise the particle position (localspace)
- particle->parentEmitter = this;
- initParticlePosition(particle);
- initParticleDirection(particle);
- initParticleVelocity(particle);
- initParticleOrientation(particle);
- initParticleMass(particle);
- initParticleColor(particle);
- initParticleTextureCoords(particle);
- particle->totalTimeToLive = initParticleTimeToLive();
- particle->timeToLive = particle->totalTimeToLive;
- // Generate particles' own dimensions if defined.
- initParticleDimensions(particle);
- }
- void PUEmitter::initParticleVelocity( PUParticle3D* particle )
- {
- float scalar = _dynamicAttributeHelper.calculate(_dynVelocity, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart(), 1.0f);
- particle->direction *= scalar;
- particle->originalVelocity = scalar;
- particle->originalScaledDirectionLength = particle->direction.length();
- }
- void PUEmitter::initParticleMass( PUParticle3D* particle )
- {
- float mass = _dynamicAttributeHelper.calculate(_dynParticleMass, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart(), PUParticle3D::DEFAULT_MASS);
- particle->mass = mass;
- }
- void PUEmitter::initParticleColor( PUParticle3D* particle )
- {
- if (_particleColorRangeSet)
- {
- if (_particleColorRangeStart.x < _particleColorRangeEnd.x)
- particle->color.x = cocos2d::random(_particleColorRangeStart.x, _particleColorRangeEnd.x);
- else
- particle->color.x = cocos2d::random(_particleColorRangeEnd.x, _particleColorRangeStart.x);
- if (_particleColorRangeStart.y < _particleColorRangeEnd.y)
- particle->color.y = cocos2d::random(_particleColorRangeStart.y, _particleColorRangeEnd.y);
- else
- particle->color.y = cocos2d::random(_particleColorRangeEnd.y, _particleColorRangeStart.y);
- if (_particleColorRangeStart.z < _particleColorRangeEnd.z)
- particle->color.z = cocos2d::random(_particleColorRangeStart.z, _particleColorRangeEnd.z);
- else
- particle->color.z = cocos2d::random(_particleColorRangeEnd.z, _particleColorRangeStart.z);
- if (_particleColorRangeStart.w < _particleColorRangeEnd.w)
- particle->color.w = cocos2d::random(_particleColorRangeStart.w, _particleColorRangeEnd.w);
- else
- particle->color.w = cocos2d::random(_particleColorRangeEnd.w, _particleColorRangeStart.w);
- }
- else
- {
- particle->color = _particleColor;
- }
- // Set original colour
- particle->originalColor = particle->color;
- }
- void PUEmitter::initParticleTextureCoords( PUParticle3D* particle )
- {
- if (_particleTextureCoordsRangeSet)
- {
- particle->textureCoordsCurrent = (unsigned short)cocos2d::random((float)_particleTextureCoordsRangeStart, (float)_particleTextureCoordsRangeEnd + 0.999f);
- }
- else
- {
- particle->textureCoordsCurrent = _particleTextureCoords;
- }
- }
- float PUEmitter::initParticleTimeToLive()
- {
- return _dynamicAttributeHelper.calculate(_dynTotalTimeToLive, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart(), PUParticle3D::DEFAULT_TTL);
- }
- void PUEmitter::initParticleDimensions( PUParticle3D* particle )
- {
- // Only continue if one of them is set
- if (_dynParticleAllDimensionsSet || _dynParticleWidthSet || _dynParticleHeightSet || _dynParticleDepthSet)
- {
- // Set all dimensions equal ...
- float extend = 0;
- if (_dynParticleAllDimensionsSet && _dynParticleAllDimensions)
- {
- extend = _dynamicAttributeHelper.calculate(_dynParticleAllDimensions, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- particle->setOwnDimensions(_emitterScale.x * extend, _emitterScale.y * extend, _emitterScale.z * extend);
- return;
- }
- // ... or set the dimensions independent from each other
- float width = 0;
- float height = 0;
- float depth = 0;
- if (_dynParticleWidthSet && _dynParticleWidth)
- {
- width = _dynamicAttributeHelper.calculate(_dynParticleWidth, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- }
- if (_dynParticleHeightSet && _dynParticleHeight)
- {
- height = _dynamicAttributeHelper.calculate(_dynParticleHeight, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- }
- if (_dynParticleDepthSet && _dynParticleDepth)
- {
- depth = _dynamicAttributeHelper.calculate(_dynParticleDepth, (static_cast<PUParticleSystem3D *>(_particleSystem))->getTimeElapsedSinceStart());
- }
-
- /** Set the width, height and depth if at least one of them is set.
- @remarks
- If one of the dimensions is 0, it will be overridden by the default value later on.
- */
- if (_dynParticleWidthSet || _dynParticleHeightSet || _dynParticleDepthSet)
- {
- particle->setOwnDimensions(_emitterScale.x * width, _emitterScale.y * height, _emitterScale.z * depth);
- }
- }
- else
- {
- // Just set the width, height and depth, but these are just the default settings; the particle doesn't
- // have own dimensions. Recalculate the bounding sphere radius.
- particle->width = _emitterScale.x * (static_cast<PUParticleSystem3D *>(_particleSystem))->getDefaultWidth();
- particle->height = _emitterScale.y * (static_cast<PUParticleSystem3D *>(_particleSystem))->getDefaultHeight();
- particle->depth = _emitterScale.z * (static_cast<PUParticleSystem3D *>(_particleSystem))->getDefaultDepth();
- particle->calculateBoundingSphereRadius();
- }
- }
- bool PUEmitter::isEmitterDone() const
- {
- return !(_isEnabled || _dynRepeatDelaySet);
- }
- Ref* PUEmitter::getEmitsEntityPtr() const
- {
- return _emitsEntity;
- }
- void PUEmitter::copyAttributesTo( PUEmitter* emitter )
- {
- emitter->setName(_name);
- emitter->setEmitterType(_emitterType);
- emitter->setEmitsName(_emitsName);
- emitter->setEmitsType(_emitsType);
- emitter->_position = _position;
- emitter->_isEnabled = _isEnabled;
- emitter->_originEnabled = _originEnabled;
- emitter->_originEnabledSet = _originEnabledSet;
- emitter->_particleDirection = _particleDirection;
- emitter->_originalParticleDirection = _originalParticleDirection;
- emitter->_particleOrientation = _particleOrientation;
- emitter->_particleOrientationRangeStart = _particleOrientationRangeStart;
- emitter->_particleOrientationRangeEnd = _particleOrientationRangeEnd;
- emitter->_particleOrientationRangeSet = _particleOrientationRangeSet;
- emitter->_isMarkedForEmission = _isMarkedForEmission;
- emitter->_particleSystem = _particleSystem;
- emitter->_autoDirection = _autoDirection;
- emitter->setForceEmission(_forceEmission);
- emitter->_dynDurationSet = _dynDurationSet;
- emitter->_dynRepeatDelaySet = _dynRepeatDelaySet;
- emitter->_dynParticleAllDimensionsSet = _dynParticleAllDimensionsSet;
- emitter->_dynParticleWidthSet = _dynParticleWidthSet;
- emitter->_dynParticleHeightSet = _dynParticleHeightSet;
- emitter->_dynParticleDepthSet = _dynParticleDepthSet;
- emitter->_emitterScale = _emitterScale;
- emitter->_particleColor = _particleColor;
- emitter->_particleColorRangeStart = _particleColorRangeStart;
- emitter->_particleColorRangeEnd = _particleColorRangeEnd;
- emitter->_particleColorRangeSet = _particleColorRangeSet;
- emitter->_particleTextureCoords = _particleTextureCoords;
- emitter->_particleTextureCoordsRangeStart = _particleTextureCoordsRangeStart;
- emitter->_particleTextureCoordsRangeEnd = _particleTextureCoordsRangeEnd;
- emitter->_particleTextureCoordsRangeSet = _particleTextureCoordsRangeSet;
- emitter->_keepLocal = _keepLocal;
- // Copy Dyn. Emission rate if available
- emitter->setDynEmissionRate(getDynEmissionRate()->clone());
- // Copy Dyn. Total time to live if available
- emitter->setDynTotalTimeToLive(getDynTotalTimeToLive()->clone());
- // Copy Dyn. Velocity if available
- emitter->setDynVelocity(getDynVelocity()->clone());
- // Copy Dyn. Duration if available
- if (_dynDurationSet)
- {
- emitter->setDynDuration(getDynDuration()->clone());
- }
- // Copy Dyn. RepeatDelay if available
- if (_dynRepeatDelaySet)
- {
- emitter->setDynRepeatDelay(getDynRepeatDelay()->clone());
- }
- // Copy Dyn. Particle Mass if available
- emitter->setDynParticleMass(getDynParticleMass()->clone());
- // Copy Dyn. Angle if available
- emitter->setDynAngle(getDynAngle()->clone());
- // Copy Dyn. own width, height and depth if available
- if (_dynParticleAllDimensionsSet)
- {
- emitter->setDynParticleAllDimensions(getDynParticleAllDimensions()->clone());
- }
- if (_dynParticleWidthSet)
- {
- emitter->setDynParticleWidth(getDynParticleWidth()->clone());
- }
- if (_dynParticleHeightSet)
- {
- emitter->setDynParticleHeight(getDynParticleHeight()->clone());
- }
- if (_dynParticleDepthSet)
- {
- emitter->setDynParticleDepth(getDynParticleDepth()->clone());
- }
- }
- NS_CC_END
|