diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 88e1c8d919..d6406b18ca 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -15,7 +15,7 @@ var box, particles, particleExample = -1, - NUM_PARTICLE_EXAMPLES = 7, + NUM_PARTICLE_EXAMPLES = 8, PARTICLE_RADIUS = 0.04; function onClickDownOnEntity(entityID) { @@ -35,10 +35,7 @@ case 1: print("Velocity spread"); Entities.editEntity(particles, { - velocitySpread: { x: 0.1, y: 0.0, z: 0.1 }, - accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, - radiusSpread: 0.0, - animationIsPlaying: true + velocitySpread: { x: 0.1, y: 0.0, z: 0.1 } }); break; case 2: @@ -46,49 +43,43 @@ Entities.editEntity(particles, { velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, accelerationSpread: { x: 0.0, y: 0.1, z: 0.0 }, - radiusSpread: 0.0, - animationIsPlaying: true }); break; case 3: print("Radius spread"); Entities.editEntity(particles, { - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, - radiusSpread: 0.035, - animationIsPlaying: true + radiusSpread: 0.035 }); break; case 4: print("Radius start and finish"); Entities.editEntity(particles, { - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, - accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, - radiusStart: 0.0, - radiusFinish: 0.0, radiusSpread: 0.0, - animationIsPlaying: true + radiusStart: 0.0, + radiusFinish: 0.0 }); break; case 5: print("Alpha 0.5"); Entities.editEntity(particles, { - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, - accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, radiusStart: PARTICLE_RADIUS, radiusFinish: PARTICLE_RADIUS, - alpha: 0.5, - animationIsPlaying: true + alpha: 0.5 }); break; case 6: + print("Alpha spread"); + Entities.editEntity(particles, { + alpha: 0.5, + alphaSpread: 0.5 + }); + break; + case 7: print("Stop emitting"); Entities.editEntity(particles, { - velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, - accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, - radiusStart: PARTICLE_RADIUS, - radiusFinish: PARTICLE_RADIUS, alpha: 1.0, + alphaSpread: 0.0, animationIsPlaying: false }); break; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index f838b7a17e..d633ed787a 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -56,6 +56,7 @@ CONSTRUCT_PROPERTY(scriptTimestamp, ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP), CONSTRUCT_PROPERTY(collisionSoundURL, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL), CONSTRUCT_PROPERTY(color, ), CONSTRUCT_PROPERTY(alpha, ENTITY_ITEM_DEFAULT_ALPHA), +CONSTRUCT_PROPERTY(alphaSpread, ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD), CONSTRUCT_PROPERTY(modelURL, ""), CONSTRUCT_PROPERTY(compoundShapeURL, ""), CONSTRUCT_PROPERTY(animationURL, ""), @@ -333,6 +334,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL); CHECK_PROPERTY_CHANGE(PROP_COLOR, color); CHECK_PROPERTY_CHANGE(PROP_ALPHA, alpha); + CHECK_PROPERTY_CHANGE(PROP_ALPHA_SPREAD, alphaSpread); CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, animationURL); @@ -448,6 +450,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(visible); COPY_PROPERTY_TO_QSCRIPTVALUE(color); COPY_PROPERTY_TO_QSCRIPTVALUE(alpha); + COPY_PROPERTY_TO_QSCRIPTVALUE(alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL); COPY_PROPERTY_TO_QSCRIPTVALUE(compoundShapeURL); COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL); @@ -582,6 +585,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible); COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor); COPY_PROPERTY_FROM_QSCRIPTVALUE(alpha, float, setAlpha); + COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(animationURL, QString, setAnimationURL); @@ -869,6 +873,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, properties.getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, properties.getRadiusFinish()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread()); } if (properties.getType() == EntityTypes::Zone) { @@ -1147,6 +1152,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_START, float, setRadiusStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_FINISH, float, setRadiusFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_SPREAD, float, setRadiusSpread); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); } if (properties.getType() == EntityTypes::Zone) { @@ -1290,6 +1296,7 @@ void EntityItemProperties::markAllChanged() { _radiusStartChanged = true; _radiusFinishChanged = true; _radiusSpreadChanged = true; + _alphaSpreadChanged = true; _marketplaceIDChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 520e2c1224..6cd735149e 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -104,6 +104,7 @@ public: DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString); DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor); DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float); + DEFINE_PROPERTY(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float); DEFINE_PROPERTY_REF(PROP_MODEL_URL, ModelURL, modelURL, QString); DEFINE_PROPERTY_REF(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString); DEFINE_PROPERTY_REF(PROP_ANIMATION_URL, AnimationURL, animationURL, QString); @@ -296,6 +297,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, CollisionSoundURL, collisionSoundURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Color, color, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Alpha, alpha, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaSpread, alphaSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ModelURL, modelURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CompoundShapeURL, compoundShapeURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationURL, animationURL, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index bfef04ab57..e8763cf565 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -153,6 +153,9 @@ enum EntityPropertyList { PROP_ALPHA, // Supported by some derived classes + //Used by particles + PROP_ALPHA_SPREAD, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index b3859f10f0..8ab31aa0c4 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -43,6 +43,7 @@ #include "ParticleEffectEntityItem.h" const xColor ParticleEffectEntityItem::DEFAULT_COLOR = { 255, 255, 255 }; +const float ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD = 0.0f; const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FRAME_INDEX = 0.0f; const bool ParticleEffectEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false; const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f; @@ -79,6 +80,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStart(DEFAULT_RADIUS_START), _radiusFinish(DEFAULT_RADIUS_FINISH), _radiusSpread(DEFAULT_RADIUS_SPREAD), + _alphaSpread(DEFAULT_ALPHA_SPREAD), _lastAnimated(usecTimestampNow()), _animationLoop(), _animationSettings(), @@ -175,6 +177,7 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusStart, getRadiusStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusFinish, getRadiusFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusSpread, getRadiusSpread); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaSpread, getAlphaSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); return properties; @@ -202,6 +205,7 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusStart, setRadiusStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusFinish, setRadiusFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusSpread, setRadiusSpread); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaSpread, setAlphaSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); if (somethingChanged) { @@ -304,6 +308,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_RADIUS_START; requestedProperties += PROP_RADIUS_FINISH; requestedProperties += PROP_ALPHA; + requestedProperties += PROP_ALPHA_SPREAD; return requestedProperties; } @@ -586,7 +591,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _radiusMiddles[i] =_particleRadius; _radiusFinishes[i] = getRadiusFinish(); } else { - float spreadMultiplier = 1.0 + (2.0f * randFloat() - 1) * _radiusSpread / _particleRadius; + float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1) * _radiusSpread / _particleRadius; _radiusStarts[i] = spreadMultiplier * getRadiusStart(); _radiusMiddles[i] = spreadMultiplier * _particleRadius; _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); @@ -613,7 +618,12 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { extendBounds(_particlePositions[i]); // Alpha - _particleAlphas[i] = _alpha; + if (_alphaSpread == 0.0f) { + _particleAlphas[i] = _alpha; + + } else { + _particleAlphas[i] = glm::clamp(_alpha + (2.0f * randFloat() - 1) * _alphaSpread, 0.0f, 1.0f); + } _particleTailIndex = (_particleTailIndex + 1) % _maxParticles; diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 5d751d7b1c..55ae724fe6 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -59,6 +59,10 @@ public: void setAlpha(float alpha) { _alpha = alpha; } float getAlpha() const { return _alpha; } + static const float DEFAULT_ALPHA_SPREAD; + void setAlphaSpread(float alphaSpread) { _alphaSpread = alphaSpread; } + float getAlphaSpread() const { return _alphaSpread; } + void updateShapeType(ShapeType type); virtual ShapeType getShapeType() const { return _shapeType; } @@ -164,6 +168,7 @@ protected: // the properties of this entity rgbColor _color; float _alpha; + float _alphaSpread; quint32 _maxParticles; float _lifespan; float _emitRate;