From 45ff118249e1f60eb7b538d00b38447d5bbc6ec4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Sep 2015 12:43:36 -0700 Subject: [PATCH 01/15] Add new radiusSpread entity particle property --- .../RenderableParticleEffectEntityItem.cpp | 47 ++++++++++++------- .../entities/src/EntityItemProperties.cpp | 8 +++- libraries/entities/src/EntityItemProperties.h | 2 + libraries/entities/src/EntityPropertyFlags.h | 1 + .../entities/src/ParticleEffectEntityItem.cpp | 28 ++++++++--- .../entities/src/ParticleEffectEntityItem.h | 10 ++-- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 8 files changed, 69 insertions(+), 30 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index f683083ed1..146dea8ea0 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -168,52 +168,63 @@ void RenderableParticleEffectEntityItem::update(const quint64& now) { updateRenderItem(); } -static glm::vec3 zSortAxis; -static bool zSort(const glm::vec3& rhs, const glm::vec3& lhs) { - return glm::dot(rhs, ::zSortAxis) > glm::dot(lhs, ::zSortAxis); -} - uint32_t toRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return ((uint32_t)r | (uint32_t)g << 8 | (uint32_t)b << 16 | (uint32_t)a << 24); } +class PositionAndRadius { +public: + PositionAndRadius(glm::vec3 position, float radius) : position(position), radius(radius) { } + + glm::vec3 position; + float radius; +}; + +static glm::vec3 zSortAxis; +static bool zSort(const PositionAndRadius& rhs, const PositionAndRadius& lhs) { + return glm::dot(rhs.position, ::zSortAxis) > glm::dot(lhs.position, ::zSortAxis); +} + void RenderableParticleEffectEntityItem::updateRenderItem() { if (!_scene) { return; } - float particleRadius = getParticleRadius(); + //float particleRadius = _particleRadiuses[i]; auto xcolor = getXColor(); auto alpha = (uint8_t)(glm::clamp(getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); - // make a copy of each particle position - std::vector positions; - positions.reserve(getLivingParticleCount()); + // make a copy of each particle position and radius + std::vector positionsAndRadiuses; + positionsAndRadiuses.reserve(getLivingParticleCount()); for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) { - positions.push_back(_particlePositions[i]); + positionsAndRadiuses.push_back(PositionAndRadius(_particlePositions[i], _particleRadiuses[i])); } // sort particles back to front // NOTE: this is view frustum might be one frame out of date. auto frustum = AbstractViewStateInterface::instance()->getCurrentViewFrustum(); ::zSortAxis = frustum->getDirection(); - qSort(positions.begin(), positions.end(), zSort); + qSort(positionsAndRadiuses.begin(), positionsAndRadiuses.end(), zSort); // allocate vertices _vertices.clear(); // build vertices from particle positions - const glm::vec3 upOffset = frustum->getUp() * particleRadius; - const glm::vec3 rightOffset = frustum->getRight() * particleRadius; - for (auto&& pos : positions) { + const glm::vec3 up = frustum->getUp(); + const glm::vec3 right = frustum->getRight(); + for (auto&& particle : positionsAndRadiuses) { + glm::vec3 upOffset = up * particle.radius; + glm::vec3 rightOffset = right * particle.radius; // generate corners of quad aligned to face the camera. - _vertices.emplace_back(pos + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), rgba); - _vertices.emplace_back(pos - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), rgba); - _vertices.emplace_back(pos - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), rgba); - _vertices.emplace_back(pos + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), rgba); + _vertices.emplace_back(particle.position + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), rgba); + _vertices.emplace_back(particle.position - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), rgba); + _vertices.emplace_back(particle.position - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), rgba); + _vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), rgba); } + render::PendingChanges pendingChanges; pendingChanges.updateItem(_renderItemId, [this](ParticlePayload& payload) { // update vertex buffer diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index c6c02f248c..e7204e33d8 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -89,6 +89,7 @@ CONSTRUCT_PROPERTY(velocitySpread, ParticleEffectEntityItem::DEFAULT_VELOCITY_SP CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION), CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), +CONSTRUCT_PROPERTY(radiusSpread, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD), CONSTRUCT_PROPERTY(marketplaceID, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), CONSTRUCT_PROPERTY(keyLightColor, ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR), CONSTRUCT_PROPERTY(keyLightIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY), @@ -355,6 +356,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration); CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); + CHECK_PROPERTY_CHANGE(PROP_RADIUS_SPREAD, radiusSpread); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); CHECK_PROPERTY_CHANGE(PROP_NAME, name); CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor); @@ -458,6 +460,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration); COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); + COPY_PROPERTY_TO_QSCRIPTVALUE(radiusSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID); COPY_PROPERTY_TO_QSCRIPTVALUE(name); COPY_PROPERTY_TO_QSCRIPTVALUE(collisionSoundURL); @@ -579,6 +582,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration); COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius); + COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID); COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL); @@ -821,7 +825,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); - + APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread()); } if (properties.getType() == EntityTypes::Zone) { @@ -1091,6 +1095,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_SPREAD, float, setRadiusSpread); } if (properties.getType() == EntityTypes::Zone) { @@ -1223,6 +1228,7 @@ void EntityItemProperties::markAllChanged() { _emitAccelerationChanged = true; _accelerationSpreadChanged = true; _particleRadiusChanged = true; + _radiusSpreadChanged = true; _marketplaceIDChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6d95faa9b1..0c4d963fc5 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -136,6 +136,7 @@ public: DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); + DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor); DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float); @@ -316,6 +317,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusSpread, radiusSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index abb8241d8f..8d1ad12a8d 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -138,6 +138,7 @@ enum EntityPropertyList { // used by particles PROP_VELOCITY_SPREAD, PROP_ACCELERATION_SPREAD, + PROP_RADIUS_SPREAD, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 7dab825adc..202bb82051 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -54,6 +54,7 @@ const glm::vec3 ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD(3.0f, 0.0f, 3. const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; +const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f; const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; @@ -72,6 +73,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _emitAcceleration(DEFAULT_EMIT_ACCELERATION), _accelerationSpread(DEFAULT_ACCELERATION_SPREAD), _particleRadius(DEFAULT_PARTICLE_RADIUS), + _radiusSpread(DEFAULT_RADIUS_SPREAD), _lastAnimated(usecTimestampNow()), _animationLoop(), _animationSettings(), @@ -82,6 +84,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleAccelerations(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), + _particleRadiuses(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _timeUntilNextEmit(0.0f), _particleHeadIndex(0), _particleTailIndex(0), @@ -111,7 +114,6 @@ void ParticleEffectEntityItem::setVelocitySpread(const glm::vec3& velocitySpread computeAndUpdateDimensions(); } - void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) { _emitAcceleration = emitAcceleration; computeAndUpdateDimensions(); @@ -126,6 +128,10 @@ void ParticleEffectEntityItem::setParticleRadius(float particleRadius) { _particleRadius = particleRadius; } +void ParticleEffectEntityItem::setRadiusSpread(float radiusSpread) { + _radiusSpread = radiusSpread; +} + void ParticleEffectEntityItem::computeAndUpdateDimensions() { const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error @@ -163,9 +169,9 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRate, getEmitRate); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitVelocity, getEmitVelocity); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusSpread, getRadiusSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); return properties; @@ -185,11 +191,12 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRate, setEmitRate); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitVelocity, setEmitVelocity); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocitySpread, setVelocitySpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusSpread, setRadiusSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocitySpread, setVelocitySpread); if (somethingChanged) { bool wantDebug = false; @@ -257,6 +264,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); } + if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD) { + READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread); + } + return bytesRead; } @@ -280,6 +291,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_PARTICLE_RADIUS; requestedProperties += PROP_TEXTURES; requestedProperties += PROP_VELOCITY_SPREAD; + requestedProperties += PROP_RADIUS_SPREAD; return requestedProperties; } @@ -308,6 +320,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, getParticleRadius()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, getVelocitySpread()); + APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, getRadiusSpread()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { @@ -514,7 +527,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } } - // emit new particles, but only if animaiton is playing + // emit new particles, but only if animation is playing if (getAnimationIsPlaying()) { float timeLeftInFrame = deltaTime; @@ -527,12 +540,12 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { quint32 i = _particleTailIndex; _particleLifetimes[i] = _lifespan; - + _particleRadiuses[i] = _particleRadius + (2.0f * randFloat() - 1) * _radiusSpread; + glm::vec3 spreadOffset; spreadOffset.x = -_velocitySpread.x + randFloat() * (_velocitySpread.x * 2.0f); spreadOffset.y = -_velocitySpread.y + randFloat() * (_velocitySpread.y * 2.0f); spreadOffset.z = -_velocitySpread.z + randFloat() * (_velocitySpread.z * 2.0f); - // set initial conditions _particlePositions[i] = getPosition(); @@ -571,8 +584,9 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { _particleLifetimes.resize(_maxParticles); _particlePositions.resize(_maxParticles); _particleVelocities.resize(_maxParticles); + _particleRadiuses.resize(_maxParticles); - // effectivly clear all particles and start emitting new ones from scratch. + // effectively clear all particles and start emitting new ones from scratch. _particleHeadIndex = 0; _particleTailIndex = 0; _timeUntilNextEmit = 0.0f; diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 4ed9216e85..844348a667 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -102,12 +102,10 @@ public: void setEmitVelocity(const glm::vec3& emitVelocity); const glm::vec3& getEmitVelocity() const { return _emitVelocity; } - static const glm::vec3 DEFAULT_VELOCITY_SPREAD; void setVelocitySpread(const glm::vec3& velocitySpread); const glm::vec3& getVelocitySpread() const { return _velocitySpread; } - static const glm::vec3 DEFAULT_EMIT_ACCELERATION; void setEmitAcceleration(const glm::vec3& emitAcceleration); const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; } @@ -119,7 +117,11 @@ public: static const float DEFAULT_PARTICLE_RADIUS; void setParticleRadius(float particleRadius); float getParticleRadius() const { return _particleRadius; } - + + static const float DEFAULT_RADIUS_SPREAD; + void setRadiusSpread(float radiusSpread); + float getRadiusSpread() const { return _radiusSpread; } + void computeAndUpdateDimensions(); @@ -155,6 +157,7 @@ protected: glm::vec3 _emitAcceleration; glm::vec3 _accelerationSpread; float _particleRadius; + float _radiusSpread; quint64 _lastAnimated; AnimationLoop _animationLoop; QString _animationSettings; @@ -167,6 +170,7 @@ protected: QVector _particlePositions; QVector _particleVelocities; QVector _particleAccelerations; + QVector _particleRadiuses; float _timeUntilNextEmit; // particle arrays are a ring buffer, use these indicies diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index ac72f1bd68..da84a7cec8 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) { case EntityAdd: case EntityEdit: case EntityData: - return VERSION_ENTITIES_PARTICLE_MODIFICATIONS; + return VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD; case AvatarData: return 13; default: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index fa6178b627..ce58273f43 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -144,5 +144,6 @@ const PacketVersion VERSION_POLYVOX_TEXTURES = 36; const PacketVersion VERSION_ENTITIES_POLYLINE = 37; const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38; const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39; +const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD = 40; #endif // hifi_PacketHeaders_h \ No newline at end of file From 2bc2582797de5d8ef4a0bc8daceb902b53282bf4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Sep 2015 12:44:13 -0700 Subject: [PATCH 02/15] Fix missing entity property gets for velocity and acceleration spread --- libraries/entities/src/ParticleEffectEntityItem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 202bb82051..da19f64361 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -169,7 +169,9 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRate, getEmitRate); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitVelocity, getEmitVelocity); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocitySpread, getVelocitySpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(accelerationSpread, getAccelerationSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusSpread, getRadiusSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); From 341e1dcf684f88c6ce203684c61f0f4d5c136c2b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Sep 2015 12:44:29 -0700 Subject: [PATCH 03/15] Add particleTest.js script to demo / test entity particle properties --- examples/example/entities/particlesTest.js | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 examples/example/entities/particlesTest.js diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js new file mode 100644 index 0000000000..f2c80b6895 --- /dev/null +++ b/examples/example/entities/particlesTest.js @@ -0,0 +1,117 @@ +// +// particlesTest.js +// examples/example/entities +// +// Created by David Rowe on 2 Sep 2015. +// Copyright 2015 High Fidelity, Inc. +// +// Click on the box entity to display different particle effects. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function () { + var box, + particles, + particleExample = -1, + NUM_PARTICLE_EXAMPLES = 4; + + function onClickDownOnEntity(entityID) { + if (entityID === box || entityID === particles) { + particleExample = (particleExample + 1) % NUM_PARTICLE_EXAMPLES; + + switch (particleExample) { + case 0: + print("Simple animation"); + 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.0, + animationIsPlaying: true + }); + break; + 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 + }); + break; + case 2: + print("Acceleration spread"); + 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 + }); + break; + } + } + } + + function setUp() { + var spawnPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))), + animation = { + fps: 30, + frameIndex: 0, + running: true, + firstFrame: 0, + lastFrame: 30, + loop: true + }; + + box = Entities.addEntity({ + type: "Box", + position: spawnPoint, + dimensions: { x: 0.3, y: 0.3, z: 0.3 }, + color: { red: 128, green: 128, blue: 128 }, + lifetime: 3600 // 1 hour; just in case + }); + + particles = Entities.addEntity({ + type: "ParticleEffect", + position: spawnPoint, + particleRadius: 0.04, + particleRadiusSpread: 0.0, + emitRate: 2.0, + emitVelocity: { x: 0.0, y: 1.0, z: 0.0 }, + velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, + emitAcceleration: { x: 0.0, y: -0.3, z: 0.0 }, + accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, + textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", + color: { red: 255, green: 255, blue: 255 }, + lifespan: 5.0, + visible: true, + locked: false, + animationSettings: animation, + animationIsPlaying: false, + lifetime: 3600 // 1 hour; just in case + }); + + Entities.clickDownOnEntity.connect(onClickDownOnEntity); + + print("Click on the box to cycle through particle examples"); + } + + function tearDown() { + Entities.clickDownOnEntity.disconnect(onClickDownOnEntity); + Entities.deleteEntity(particles); + Entities.deleteEntity(box); + } + + setUp(); + Script.scriptEnding.connect(tearDown); +}()); \ No newline at end of file From c910da7179ae225a1964588a1f50451db12ad924 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 4 Sep 2015 12:27:18 -0700 Subject: [PATCH 04/15] Add radiusStart and radiusFinish entity particle properties --- examples/example/entities/particlesTest.js | 28 ++++++++- .../RenderableParticleEffectEntityItem.cpp | 4 +- .../entities/src/EntityItemProperties.cpp | 14 +++++ libraries/entities/src/EntityItemProperties.h | 4 ++ libraries/entities/src/EntityPropertyFlags.h | 2 + .../entities/src/ParticleEffectEntityItem.cpp | 62 ++++++++++++++----- .../entities/src/ParticleEffectEntityItem.h | 28 +++++++-- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 2 +- 9 files changed, 120 insertions(+), 26 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index f2c80b6895..e23e64677f 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -15,7 +15,8 @@ var box, particles, particleExample = -1, - NUM_PARTICLE_EXAMPLES = 4; + NUM_PARTICLE_EXAMPLES = 6, + PARTICLE_RADIUS = 0.04; function onClickDownOnEntity(entityID) { if (entityID === box || entityID === particles) { @@ -58,6 +59,27 @@ animationIsPlaying: true }); 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 + }); + break; + case 5: + print("Stop animation"); + 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, + animationIsPlaying: false + }); + break; } } } @@ -84,8 +106,8 @@ particles = Entities.addEntity({ type: "ParticleEffect", position: spawnPoint, - particleRadius: 0.04, - particleRadiusSpread: 0.0, + particleRadius: PARTICLE_RADIUS, + radiusSpread: 0.0, emitRate: 2.0, emitVelocity: { x: 0.0, y: 1.0, z: 0.0 }, velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 146dea8ea0..424ea2b810 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -190,7 +190,6 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { return; } - //float particleRadius = _particleRadiuses[i]; auto xcolor = getXColor(); auto alpha = (uint8_t)(glm::clamp(getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); @@ -211,7 +210,7 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { // allocate vertices _vertices.clear(); - // build vertices from particle positions + // build vertices from particle positions and radiuses const glm::vec3 up = frustum->getUp(); const glm::vec3 right = frustum->getRight(); for (auto&& particle : positionsAndRadiuses) { @@ -224,7 +223,6 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { _vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), rgba); } - render::PendingChanges pendingChanges; pendingChanges.updateItem(_renderItemId, [this](ParticlePayload& payload) { // update vertex buffer diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index e7204e33d8..0d7d7852f2 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -89,6 +89,8 @@ CONSTRUCT_PROPERTY(velocitySpread, ParticleEffectEntityItem::DEFAULT_VELOCITY_SP CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION), CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), +CONSTRUCT_PROPERTY(radiusStart, ParticleEffectEntityItem::DEFAULT_RADIUS_START), +CONSTRUCT_PROPERTY(radiusFinish, ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH), CONSTRUCT_PROPERTY(radiusSpread, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD), CONSTRUCT_PROPERTY(marketplaceID, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), CONSTRUCT_PROPERTY(keyLightColor, ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR), @@ -356,6 +358,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration); CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); + CHECK_PROPERTY_CHANGE(PROP_RADIUS_START, radiusStart); + CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish); CHECK_PROPERTY_CHANGE(PROP_RADIUS_SPREAD, radiusSpread); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); CHECK_PROPERTY_CHANGE(PROP_NAME, name); @@ -460,6 +464,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration); COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); + COPY_PROPERTY_TO_QSCRIPTVALUE(radiusStart); + COPY_PROPERTY_TO_QSCRIPTVALUE(radiusFinish); COPY_PROPERTY_TO_QSCRIPTVALUE(radiusSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID); COPY_PROPERTY_TO_QSCRIPTVALUE(name); @@ -582,6 +588,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration); COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius); + COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID); COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); @@ -825,6 +833,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); + APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, properties.getRadiusStart()); + APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, properties.getRadiusFinish()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread()); } @@ -1095,6 +1105,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); + 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); } @@ -1228,6 +1240,8 @@ void EntityItemProperties::markAllChanged() { _emitAccelerationChanged = true; _accelerationSpreadChanged = true; _particleRadiusChanged = true; + _radiusStartChanged = true; + _radiusFinishChanged = true; _radiusSpreadChanged = true; _marketplaceIDChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 0c4d963fc5..bcdfbd0289 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -136,6 +136,8 @@ public: DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); + DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float); + DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float); DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor); @@ -317,6 +319,8 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusStart, radiusStart, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusFinish, radiusFinish, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusSpread, radiusSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 8d1ad12a8d..7eafc25427 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -139,6 +139,8 @@ enum EntityPropertyList { PROP_VELOCITY_SPREAD, PROP_ACCELERATION_SPREAD, PROP_RADIUS_SPREAD, + PROP_RADIUS_START, + PROP_RADIUS_FINISH, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index da19f64361..ff534ff03b 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -54,6 +54,9 @@ const glm::vec3 ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD(3.0f, 0.0f, 3. const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; +const float ParticleEffectEntityItem::RADIUS_UNINITIALIZED = -1.0f; +const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = RADIUS_UNINITIALIZED; +const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = RADIUS_UNINITIALIZED; const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f; const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; @@ -73,6 +76,8 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _emitAcceleration(DEFAULT_EMIT_ACCELERATION), _accelerationSpread(DEFAULT_ACCELERATION_SPREAD), _particleRadius(DEFAULT_PARTICLE_RADIUS), + _radiusStart(DEFAULT_RADIUS_START), + _radiusFinish(DEFAULT_RADIUS_FINISH), _radiusSpread(DEFAULT_RADIUS_SPREAD), _lastAnimated(usecTimestampNow()), _animationLoop(), @@ -85,6 +90,9 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleAccelerations(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleRadiuses(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _timeUntilNextEmit(0.0f), _particleHeadIndex(0), _particleTailIndex(0), @@ -100,10 +108,6 @@ ParticleEffectEntityItem::~ParticleEffectEntityItem() { } -void ParticleEffectEntityItem::setLifespan(float lifespan) { - _lifespan = lifespan; -} - void ParticleEffectEntityItem::setEmitVelocity(const glm::vec3& emitVelocity) { _emitVelocity = emitVelocity; computeAndUpdateDimensions(); @@ -124,14 +128,6 @@ void ParticleEffectEntityItem::setAccelerationSpread(const glm::vec3& accelerati computeAndUpdateDimensions(); } -void ParticleEffectEntityItem::setParticleRadius(float particleRadius) { - _particleRadius = particleRadius; -} - -void ParticleEffectEntityItem::setRadiusSpread(float radiusSpread) { - _radiusSpread = radiusSpread; -} - void ParticleEffectEntityItem::computeAndUpdateDimensions() { const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error @@ -173,6 +169,8 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); COPY_ENTITY_PROPERTY_TO_PROPERTIES(accelerationSpread, getAccelerationSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); + 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(textures, getTextures); @@ -197,6 +195,8 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius); + 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(textures, setTextures); @@ -266,8 +266,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); } - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD) { + if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_ADDITIONS) { READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread); + READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); + READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); } return bytesRead; @@ -294,6 +296,8 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_TEXTURES; requestedProperties += PROP_VELOCITY_SPREAD; requestedProperties += PROP_RADIUS_SPREAD; + requestedProperties += PROP_RADIUS_START; + requestedProperties += PROP_RADIUS_FINISH; return requestedProperties; } @@ -323,6 +327,8 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, getVelocitySpread()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, getRadiusSpread()); + APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart()); + APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { @@ -492,6 +498,15 @@ QString ParticleEffectEntityItem::getAnimationSettings() const { return jsonByteString; } +void ParticleEffectEntityItem::updateRadius(quint32 index) { + float age = 2.0f * (1.0f - _particleLifetimes[index] / _lifespan); // 0.0 .. 2.0 + if (age < 1.0f) { + _particleRadiuses[index] = cosineInterpolate(_radiusStarts[index], _radiusMiddles[index], age); + } else { + _particleRadiuses[index] = cosineInterpolate(_radiusMiddles[index], _radiusFinishes[index], age - 1.0f); + } +} + void ParticleEffectEntityItem::extendBounds(const glm::vec3& point) { _particleMinBound.x = glm::min(_particleMinBound.x, point.x); _particleMinBound.y = glm::min(_particleMinBound.y, point.y); @@ -524,6 +539,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _particleHeadIndex = (_particleHeadIndex + 1) % _maxParticles; } else { + updateRadius(i); integrateParticle(i, deltaTime); extendBounds(_particlePositions[i]); } @@ -542,8 +558,14 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { quint32 i = _particleTailIndex; _particleLifetimes[i] = _lifespan; - _particleRadiuses[i] = _particleRadius + (2.0f * randFloat() - 1) * _radiusSpread; + // Radius + float spreadMultiplier = 1.0 + (2.0f * randFloat() - 1) * _radiusSpread / _particleRadius; + _radiusStarts[i] = spreadMultiplier * getRadiusStart(); + _radiusMiddles[i] = spreadMultiplier * _particleRadius; + _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); + updateRadius(i); + // Velocity and acceleration glm::vec3 spreadOffset; spreadOffset.x = -_velocitySpread.x + randFloat() * (_velocitySpread.x * 2.0f); spreadOffset.y = -_velocitySpread.y + randFloat() * (_velocitySpread.y * 2.0f); @@ -587,6 +609,9 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { _particlePositions.resize(_maxParticles); _particleVelocities.resize(_maxParticles); _particleRadiuses.resize(_maxParticles); + _radiusStarts.resize(_maxParticles); + _radiusMiddles.resize(_maxParticles); + _radiusFinishes.resize(_maxParticles); // effectively clear all particles and start emitting new ones from scratch. _particleHeadIndex = 0; @@ -603,3 +628,12 @@ quint32 ParticleEffectEntityItem::getLivingParticleCount() const { return (_maxParticles - _particleHeadIndex) + _particleTailIndex; } } + +float ParticleEffectEntityItem::cosineInterpolate(float y1, float y2, float u) { + if (y1 == y2) { + return y1; + } + + float uy = (1 - cos(u * PI)) / 2; + return y1 * (1 - uy) + y2 * uy; +} diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 844348a667..cac0af39a4 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -91,7 +91,7 @@ public: quint32 getMaxParticles() const { return _maxParticles; } static const float DEFAULT_LIFESPAN; - void setLifespan(float lifespan); + void setLifespan(float lifespan) { _lifespan = lifespan; } float getLifespan() const { return _lifespan; } static const float DEFAULT_EMIT_RATE; @@ -115,11 +115,21 @@ public: const glm::vec3& getAccelerationSpread() const { return _accelerationSpread; } static const float DEFAULT_PARTICLE_RADIUS; - void setParticleRadius(float particleRadius); + void setParticleRadius(float particleRadius) { _particleRadius = particleRadius; } float getParticleRadius() const { return _particleRadius; } + static const float RADIUS_UNINITIALIZED; + + static const float DEFAULT_RADIUS_START; + void setRadiusStart(float radiusStart) { _radiusStart = radiusStart; } + float getRadiusStart() const { return _radiusStart == RADIUS_UNINITIALIZED ? _particleRadius : _radiusStart; } + + static const float DEFAULT_RADIUS_FINISH; + void setRadiusFinish(float radiusFinish) { _radiusFinish = radiusFinish; } + float getRadiusFinish() const { return _radiusFinish == RADIUS_UNINITIALIZED ? _particleRadius : _radiusFinish; } + static const float DEFAULT_RADIUS_SPREAD; - void setRadiusSpread(float radiusSpread); + void setRadiusSpread(float radiusSpread) { _radiusSpread = radiusSpread; } float getRadiusSpread() const { return _radiusSpread; } void computeAndUpdateDimensions(); @@ -143,6 +153,7 @@ protected: bool isAnimatingSomething() const; void stepSimulation(float deltaTime); + void updateRadius(quint32 index); void extendBounds(const glm::vec3& point); void integrateParticle(quint32 index, float deltaTime); quint32 getLivingParticleCount() const; @@ -157,6 +168,8 @@ protected: glm::vec3 _emitAcceleration; glm::vec3 _accelerationSpread; float _particleRadius; + float _radiusStart; + float _radiusFinish; float _radiusSpread; quint64 _lastAnimated; AnimationLoop _animationLoop; @@ -171,9 +184,13 @@ protected: QVector _particleVelocities; QVector _particleAccelerations; QVector _particleRadiuses; + QVector _radiusStarts; + QVector _radiusMiddles; + QVector _radiusFinishes; + float _timeUntilNextEmit; - // particle arrays are a ring buffer, use these indicies + // particle arrays are a ring buffer, use these indices // to keep track of the living particles. quint32 _particleHeadIndex; quint32 _particleTailIndex; @@ -181,6 +198,9 @@ protected: // bounding volume glm::vec3 _particleMaxBound; glm::vec3 _particleMinBound; + +private: + float cosineInterpolate(float y1, float y2, float u); }; #endif // hifi_ParticleEffectEntityItem_h diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index da84a7cec8..8ac183da6f 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) { case EntityAdd: case EntityEdit: case EntityData: - return VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD; + return VERSION_ENTITIES_PARTICLE_RADIUS_ADDITIONS; case AvatarData: return 13; default: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index ce58273f43..00bce90c9a 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -144,6 +144,6 @@ const PacketVersion VERSION_POLYVOX_TEXTURES = 36; const PacketVersion VERSION_ENTITIES_POLYLINE = 37; const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38; const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39; -const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD = 40; +const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_ADDITIONS = 40; #endif // hifi_PacketHeaders_h \ No newline at end of file From e86581ab64b17d9ed809a6484d562452b0b6c136 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 4 Sep 2015 13:51:25 -0700 Subject: [PATCH 05/15] Update scripts to use HiFi smoke particle --- examples/example/entities/particlesTest.js | 2 +- examples/particles.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index e23e64677f..48d5ca246a 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -113,7 +113,7 @@ velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, emitAcceleration: { x: 0.0, y: -0.3, z: 0.0 }, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, - textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", color: { red: 255, green: 255, blue: 255 }, lifespan: 5.0, visible: true, diff --git a/examples/particles.js b/examples/particles.js index fc1a936a72..ad232dd781 100644 --- a/examples/particles.js +++ b/examples/particles.js @@ -43,7 +43,7 @@ emitVelocity: {x: 0, y: 5, z: 0}, velocitySpread: {x: 2, y: 0, z: 2}, emitAcceleration: {x: 0, y: -9.8, z: 0}, - textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", color: color, lifespan: 1.0, visible: true, From c9cf426dba909010a8e55d0778ce40ac923d7600 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 4 Sep 2015 15:31:21 -0700 Subject: [PATCH 06/15] Fix EntityPropertyList merge --- libraries/entities/src/EntityPropertyFlags.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 4cf8b4064a..7ea471d851 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -138,9 +138,6 @@ enum EntityPropertyList { // used by particles PROP_VELOCITY_SPREAD, PROP_ACCELERATION_SPREAD, - PROP_RADIUS_SPREAD, - PROP_RADIUS_START, - PROP_RADIUS_FINISH, PROP_X_N_NEIGHBOR_ID, // used by PolyVox PROP_Y_N_NEIGHBOR_ID, // used by PolyVox @@ -149,6 +146,11 @@ enum EntityPropertyList { PROP_Y_P_NEIGHBOR_ID, // used by PolyVox PROP_Z_P_NEIGHBOR_ID, // used by PolyVox + // Used by particles + PROP_RADIUS_SPREAD, + PROP_RADIUS_START, + PROP_RADIUS_FINISH, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, From 12b8a5a1d52c478feb6c88b2eb308e15e948f6e9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 Sep 2015 10:23:27 -0700 Subject: [PATCH 07/15] Add alpha property support to ParticleEffect entities Add at same "level" as color so that it's available for other entity types to use in the future. --- examples/example/entities/particlesTest.js | 18 +++++++++-- .../RenderableParticleEffectEntityItem.cpp | 32 +++++++++---------- .../entities/src/EntityItemProperties.cpp | 8 ++++- libraries/entities/src/EntityItemProperties.h | 2 ++ .../src/EntityItemPropertiesDefaults.h | 1 + libraries/entities/src/EntityPropertyFlags.h | 2 ++ .../entities/src/ParticleEffectEntityItem.cpp | 13 +++++++- .../entities/src/ParticleEffectEntityItem.h | 5 +++ .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 3 +- 10 files changed, 63 insertions(+), 23 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 48d5ca246a..88e1c8d919 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 = 6, + NUM_PARTICLE_EXAMPLES = 7, PARTICLE_RADIUS = 0.04; function onClickDownOnEntity(entityID) { @@ -24,7 +24,7 @@ switch (particleExample) { case 0: - print("Simple animation"); + print("Simple emitter"); Entities.editEntity(particles, { velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, accelerationSpread: { x: 0.0, y: 0.0, z: 0.0 }, @@ -71,12 +71,24 @@ }); break; case 5: - print("Stop animation"); + 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 + }); + break; + case 6: + 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, animationIsPlaying: false }); break; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 424ea2b810..be9c28a80d 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -172,16 +172,17 @@ uint32_t toRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return ((uint32_t)r | (uint32_t)g << 8 | (uint32_t)b << 16 | (uint32_t)a << 24); } -class PositionAndRadius { +class ParticleDetails { public: - PositionAndRadius(glm::vec3 position, float radius) : position(position), radius(radius) { } + ParticleDetails(glm::vec3 position, float radius, uint32_t rgba) : position(position), radius(radius), rgba(rgba) { } glm::vec3 position; float radius; + uint32_t rgba; }; static glm::vec3 zSortAxis; -static bool zSort(const PositionAndRadius& rhs, const PositionAndRadius& lhs) { +static bool zSort(const ParticleDetails& rhs, const ParticleDetails& lhs) { return glm::dot(rhs.position, ::zSortAxis) > glm::dot(lhs.position, ::zSortAxis); } @@ -190,22 +191,21 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { return; } + // make a copy of each particle's details + std::vector particleDetails; + particleDetails.reserve(getLivingParticleCount()); auto xcolor = getXColor(); - auto alpha = (uint8_t)(glm::clamp(getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); - auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); - - // make a copy of each particle position and radius - std::vector positionsAndRadiuses; - positionsAndRadiuses.reserve(getLivingParticleCount()); for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) { - positionsAndRadiuses.push_back(PositionAndRadius(_particlePositions[i], _particleRadiuses[i])); + auto alpha = (uint8_t)(glm::clamp(_particleAlphas[i] * getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); + auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); + particleDetails.push_back(ParticleDetails(_particlePositions[i], _particleRadiuses[i], rgba)); } // sort particles back to front // NOTE: this is view frustum might be one frame out of date. auto frustum = AbstractViewStateInterface::instance()->getCurrentViewFrustum(); ::zSortAxis = frustum->getDirection(); - qSort(positionsAndRadiuses.begin(), positionsAndRadiuses.end(), zSort); + qSort(particleDetails.begin(), particleDetails.end(), zSort); // allocate vertices _vertices.clear(); @@ -213,14 +213,14 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { // build vertices from particle positions and radiuses const glm::vec3 up = frustum->getUp(); const glm::vec3 right = frustum->getRight(); - for (auto&& particle : positionsAndRadiuses) { + for (auto&& particle : particleDetails) { glm::vec3 upOffset = up * particle.radius; glm::vec3 rightOffset = right * particle.radius; // generate corners of quad aligned to face the camera. - _vertices.emplace_back(particle.position + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), rgba); - _vertices.emplace_back(particle.position - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), rgba); - _vertices.emplace_back(particle.position - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), rgba); - _vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), rgba); + _vertices.emplace_back(particle.position + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), particle.rgba); + _vertices.emplace_back(particle.position - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), particle.rgba); + _vertices.emplace_back(particle.position - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), particle.rgba); + _vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), particle.rgba); } render::PendingChanges pendingChanges; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index a07eaacdb9..f838b7a17e 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -55,6 +55,7 @@ CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT), 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(modelURL, ""), CONSTRUCT_PROPERTY(compoundShapeURL, ""), CONSTRUCT_PROPERTY(animationURL, ""), @@ -331,6 +332,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp); CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL); CHECK_PROPERTY_CHANGE(PROP_COLOR, color); + CHECK_PROPERTY_CHANGE(PROP_ALPHA, alpha); CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_URL, animationURL); @@ -445,6 +447,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(angularDamping); COPY_PROPERTY_TO_QSCRIPTVALUE(visible); COPY_PROPERTY_TO_QSCRIPTVALUE(color); + COPY_PROPERTY_TO_QSCRIPTVALUE(alpha); COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL); COPY_PROPERTY_TO_QSCRIPTVALUE(compoundShapeURL); COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL); @@ -578,6 +581,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping); 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(modelURL, QString, setModelURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(animationURL, QString, setAnimationURL); @@ -915,11 +919,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths()); } - APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID()); APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL()); APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, properties.getActionData()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha()); } if (propertyCount > 0) { int endOfEntityItemData = packetData->getUncompressedByteOffset(); @@ -1192,6 +1196,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACTION_DATA, QByteArray, setActionData); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha); return valid; } @@ -1248,6 +1253,7 @@ void EntityItemProperties::markAllChanged() { _nameChanged = true; _visibleChanged = true; _colorChanged = true; + _alphaChanged = true; _modelURLChanged = true; _compoundShapeURLChanged = true; _animationURLChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 95f9757f20..520e2c1224 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -103,6 +103,7 @@ public: DEFINE_PROPERTY(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64); 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_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); @@ -294,6 +295,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ScriptTimestamp, scriptTimestamp, ""); 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, ModelURL, modelURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CompoundShapeURL, compoundShapeURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AnimationURL, animationURL, ""); diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index 0cdfe73040..a4aca0b344 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -27,6 +27,7 @@ const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString(""); const QString ENTITY_ITEM_DEFAULT_MARKETPLACE_ID = QString(""); const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid(); +const float ENTITY_ITEM_DEFAULT_ALPHA = 1.0f; const float ENTITY_ITEM_DEFAULT_LOCAL_RENDER_ALPHA = 1.0f; const float ENTITY_ITEM_DEFAULT_GLOW_LEVEL = 0.0f; const bool ENTITY_ITEM_DEFAULT_VISIBLE = true; diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 7ea471d851..bfef04ab57 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -151,6 +151,8 @@ enum EntityPropertyList { PROP_RADIUS_START, PROP_RADIUS_FINISH, + PROP_ALPHA, // Supported by some derived classes + //////////////////////////////////////////////////////////////////////////////////////////////////// // 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 ff534ff03b..0f8df954bf 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -85,6 +85,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _textures(DEFAULT_TEXTURES), _texturesChangedFlag(false), _shapeType(SHAPE_TYPE_NONE), + _alpha(ENTITY_ITEM_DEFAULT_ALPHA), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), @@ -93,6 +94,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _particleAlphas(DEFAULT_MAX_PARTICLES, ENTITY_ITEM_DEFAULT_ALPHA), _timeUntilNextEmit(0.0f), _particleHeadIndex(0), _particleTailIndex(0), @@ -155,6 +157,7 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getXColor); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha); COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationIsPlaying, getAnimationIsPlaying); COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFrameIndex, getAnimationFrameIndex); COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS); @@ -181,6 +184,7 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha); SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationIsPlaying, setAnimationIsPlaying); SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex); SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS); @@ -266,10 +270,11 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); } - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_ADDITIONS) { + if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES) { READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread); READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); + READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); } return bytesRead; @@ -298,6 +303,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_RADIUS_SPREAD; requestedProperties += PROP_RADIUS_START; requestedProperties += PROP_RADIUS_FINISH; + requestedProperties += PROP_ALPHA; return requestedProperties; } @@ -329,6 +335,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, getRadiusSpread()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { @@ -584,6 +591,9 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { integrateParticle(i, timeLeftInFrame); extendBounds(_particlePositions[i]); + // Alpha + _particleAlphas[i] = _alpha; + _particleTailIndex = (_particleTailIndex + 1) % _maxParticles; // overflow! move head forward by one. @@ -612,6 +622,7 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { _radiusStarts.resize(_maxParticles); _radiusMiddles.resize(_maxParticles); _radiusFinishes.resize(_maxParticles); + _particleAlphas.resize(_maxParticles); // effectively clear all particles and start emitting new ones from scratch. _particleHeadIndex = 0; diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index cac0af39a4..81d88e5a41 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -56,6 +56,9 @@ public: _color[BLUE_INDEX] = value.blue; } + void setAlpha(float alpha) { _alpha = alpha; } + float getAlpha() const { return _alpha; } + void updateShapeType(ShapeType type); virtual ShapeType getShapeType() const { return _shapeType; } @@ -160,6 +163,7 @@ protected: // the properties of this entity rgbColor _color; + float _alpha; quint32 _maxParticles; float _lifespan; float _emitRate; @@ -187,6 +191,7 @@ protected: QVector _radiusStarts; QVector _radiusMiddles; QVector _radiusFinishes; + QVector _particleAlphas; float _timeUntilNextEmit; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 8ac183da6f..3a2013d367 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) { case EntityAdd: case EntityEdit: case EntityData: - return VERSION_ENTITIES_PARTICLE_RADIUS_ADDITIONS; + return VERSION_ENTITIES_PARTICLE_ALPHA_PROPERTIES; case AvatarData: return 13; default: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index a68d3adbad..e63f7f410b 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -145,6 +145,7 @@ const PacketVersion VERSION_ENTITIES_POLYLINE = 37; const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38; const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39; const PacketVersion VERSION_ENTITIES_POLYVOX_NEIGHBORS = 40; -const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_ADDITIONS = 41; +const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; +const PacketVersion VERSION_ENTITIES_PARTICLE_ALPHA_PROPERTIES = 42; #endif // hifi_PacketHeaders_h From 8d85309925fd5d04b06dcc664bc268a628b26e82 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 Sep 2015 10:50:05 -0700 Subject: [PATCH 08/15] Use cubic interpolation instead of cosine --- .../entities/src/ParticleEffectEntityItem.cpp | 29 ++++++++++++++----- .../entities/src/ParticleEffectEntityItem.h | 2 +- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 0f8df954bf..1b58e92ef1 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -507,11 +507,22 @@ QString ParticleEffectEntityItem::getAnimationSettings() const { void ParticleEffectEntityItem::updateRadius(quint32 index) { float age = 2.0f * (1.0f - _particleLifetimes[index] / _lifespan); // 0.0 .. 2.0 + float y0, y1, y2, y3; + if (age < 1.0f) { - _particleRadiuses[index] = cosineInterpolate(_radiusStarts[index], _radiusMiddles[index], age); + y1 = _radiusStarts[index]; + y2 = _radiusMiddles[index]; + y3 = _radiusFinishes[index]; + y0 = 2.0f * y1 - y2; } else { - _particleRadiuses[index] = cosineInterpolate(_radiusMiddles[index], _radiusFinishes[index], age - 1.0f); + y0 = _radiusStarts[index]; + y1 = _radiusMiddles[index]; + y2 = _radiusFinishes[index]; + 2.0f * y2 - y1; + age -= 1.0f; } + + _particleRadiuses[index] = cubicInterpolate(y0, y1, y2, y3, age); } void ParticleEffectEntityItem::extendBounds(const glm::vec3& point) { @@ -640,11 +651,13 @@ quint32 ParticleEffectEntityItem::getLivingParticleCount() const { } } -float ParticleEffectEntityItem::cosineInterpolate(float y1, float y2, float u) { - if (y1 == y2) { - return y1; - } +float ParticleEffectEntityItem::cubicInterpolate(float y0, float y1, float y2, float y3, float u) { + float a0, a1, a2, a3, uu; + uu = u * u; + a0 = y3 - y2 - y0 + y1; + a1 = y0 - y1 - a0; + a2 = y2 - y0; + a3 = y1; - float uy = (1 - cos(u * PI)) / 2; - return y1 * (1 - uy) + y2 * uy; + return (a0 * u * uu + a1 * uu + a2 * u + a3); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 81d88e5a41..5d751d7b1c 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -205,7 +205,7 @@ protected: glm::vec3 _particleMinBound; private: - float cosineInterpolate(float y1, float y2, float u); + float cubicInterpolate(float y0, float y1, float y2, float y3, float u); }; #endif // hifi_ParticleEffectEntityItem_h From 8b296f53e612a95be36467c8c2c83693b5ccee4d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 Sep 2015 11:13:48 -0700 Subject: [PATCH 09/15] Short-circuit radius values and interpolation when can --- .../entities/src/ParticleEffectEntityItem.cpp | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 1b58e92ef1..b3859f10f0 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -506,23 +506,27 @@ QString ParticleEffectEntityItem::getAnimationSettings() const { } void ParticleEffectEntityItem::updateRadius(quint32 index) { - float age = 2.0f * (1.0f - _particleLifetimes[index] / _lifespan); // 0.0 .. 2.0 - float y0, y1, y2, y3; - - if (age < 1.0f) { - y1 = _radiusStarts[index]; - y2 = _radiusMiddles[index]; - y3 = _radiusFinishes[index]; - y0 = 2.0f * y1 - y2; + if (_radiusStarts[index] == _radiusMiddles[index] && _radiusMiddles[index] == _radiusFinishes[index]) { + _particleRadiuses[index] = _radiusMiddles[index]; } else { - y0 = _radiusStarts[index]; - y1 = _radiusMiddles[index]; - y2 = _radiusFinishes[index]; - 2.0f * y2 - y1; - age -= 1.0f; - } + float age = 2.0f * (1.0f - _particleLifetimes[index] / _lifespan); // 0.0 .. 2.0 + float y0, y1, y2, y3; - _particleRadiuses[index] = cubicInterpolate(y0, y1, y2, y3, age); + if (age < 1.0f) { + y1 = _radiusStarts[index]; + y2 = _radiusMiddles[index]; + y3 = _radiusFinishes[index]; + y0 = 2.0f * y1 - y2; + } else { + y0 = _radiusStarts[index]; + y1 = _radiusMiddles[index]; + y2 = _radiusFinishes[index]; + y3 = 2.0f * y2 - y1; + age -= 1.0f; + } + + _particleRadiuses[index] = cubicInterpolate(y0, y1, y2, y3, age); + } } void ParticleEffectEntityItem::extendBounds(const glm::vec3& point) { @@ -577,10 +581,16 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _particleLifetimes[i] = _lifespan; // Radius - float spreadMultiplier = 1.0 + (2.0f * randFloat() - 1) * _radiusSpread / _particleRadius; - _radiusStarts[i] = spreadMultiplier * getRadiusStart(); - _radiusMiddles[i] = spreadMultiplier * _particleRadius; - _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); + if (_radiusSpread == 0.0f) { + _radiusStarts[i] = getRadiusStart(); + _radiusMiddles[i] =_particleRadius; + _radiusFinishes[i] = getRadiusFinish(); + } else { + float spreadMultiplier = 1.0 + (2.0f * randFloat() - 1) * _radiusSpread / _particleRadius; + _radiusStarts[i] = spreadMultiplier * getRadiusStart(); + _radiusMiddles[i] = spreadMultiplier * _particleRadius; + _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); + } updateRadius(i); // Velocity and acceleration From 1b3d125cb33ebdcfe9dc7937e07e03426335afb1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 Sep 2015 14:39:10 -0700 Subject: [PATCH 10/15] Add alphaSpread entity particle property --- examples/example/entities/particlesTest.js | 37 +++++++------------ .../entities/src/EntityItemProperties.cpp | 7 ++++ libraries/entities/src/EntityItemProperties.h | 2 + libraries/entities/src/EntityPropertyFlags.h | 3 ++ .../entities/src/ParticleEffectEntityItem.cpp | 14 ++++++- .../entities/src/ParticleEffectEntityItem.h | 5 +++ 6 files changed, 43 insertions(+), 25 deletions(-) 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; From 042384b5b08b8fb5e283f048ffa36b86acf535e2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 Sep 2015 14:51:48 -0700 Subject: [PATCH 11/15] Tidy and finish alpha and alphaSpread --- libraries/entities/src/ParticleEffectEntityItem.cpp | 9 ++++++--- libraries/entities/src/ParticleEffectEntityItem.h | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 8ab31aa0c4..4e0ece15fc 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 = 1.0f; 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; @@ -80,14 +81,14 @@ 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(), _textures(DEFAULT_TEXTURES), _texturesChangedFlag(false), _shapeType(SHAPE_TYPE_NONE), - _alpha(ENTITY_ITEM_DEFAULT_ALPHA), + _alpha(DEFAULT_ALPHA), + _alphaSpread(DEFAULT_ALPHA_SPREAD), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), @@ -96,7 +97,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), - _particleAlphas(DEFAULT_MAX_PARTICLES, ENTITY_ITEM_DEFAULT_ALPHA), + _particleAlphas(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _timeUntilNextEmit(0.0f), _particleHeadIndex(0), _particleTailIndex(0), @@ -279,6 +280,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); + READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); } return bytesRead; @@ -341,6 +343,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, getAlphaSpread()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 55ae724fe6..ad8ed8b386 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -56,6 +56,7 @@ public: _color[BLUE_INDEX] = value.blue; } + static const float DEFAULT_ALPHA; void setAlpha(float alpha) { _alpha = alpha; } float getAlpha() const { return _alpha; } From 47b27a32808196027704d923dc1ef237da92531b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 5 Sep 2015 16:30:01 -0700 Subject: [PATCH 12/15] Add alphaStart and alphaFinish entity particle properties --- examples/example/entities/particlesTest.js | 16 +++- .../entities/src/EntityItemProperties.cpp | 14 +++ libraries/entities/src/EntityItemProperties.h | 4 + libraries/entities/src/EntityPropertyFlags.h | 2 + .../entities/src/ParticleEffectEntityItem.cpp | 89 +++++++++++++------ .../entities/src/ParticleEffectEntityItem.h | 19 +++- 6 files changed, 114 insertions(+), 30 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index d6406b18ca..f1ae210373 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 = 8, + NUM_PARTICLE_EXAMPLES = 9, PARTICLE_RADIUS = 0.04; function onClickDownOnEntity(entityID) { @@ -42,7 +42,7 @@ print("Acceleration spread"); Entities.editEntity(particles, { velocitySpread: { x: 0.0, y: 0.0, z: 0.0 }, - accelerationSpread: { x: 0.0, y: 0.1, z: 0.0 }, + accelerationSpread: { x: 0.0, y: 0.1, z: 0.0 } }); break; case 3: @@ -76,10 +76,20 @@ }); break; case 7: + print("Alpha start and finish"); + Entities.editEntity(particles, { + alphaSpread: 0.0, + alpha: 1.0, + alphaStart: 0.0, + alphaFinish: 0.0 + }); + break; + case 8: print("Stop emitting"); Entities.editEntity(particles, { alpha: 1.0, - alphaSpread: 0.0, + alphaStart: 1.0, + alphaFinish: 1.0, animationIsPlaying: false }); break; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index d633ed787a..6d68483388 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -56,6 +56,8 @@ 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(alphaStart, ParticleEffectEntityItem::DEFAULT_ALPHA_START), +CONSTRUCT_PROPERTY(alphaFinish, ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH), CONSTRUCT_PROPERTY(alphaSpread, ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD), CONSTRUCT_PROPERTY(modelURL, ""), CONSTRUCT_PROPERTY(compoundShapeURL, ""), @@ -334,6 +336,8 @@ 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_START, alphaStart); + CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish); CHECK_PROPERTY_CHANGE(PROP_ALPHA_SPREAD, alphaSpread); CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); @@ -450,6 +454,8 @@ 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(alphaStart); + COPY_PROPERTY_TO_QSCRIPTVALUE(alphaFinish); COPY_PROPERTY_TO_QSCRIPTVALUE(alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL); COPY_PROPERTY_TO_QSCRIPTVALUE(compoundShapeURL); @@ -585,6 +591,8 @@ 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(alphaStart, float, setAlphaStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL); @@ -873,6 +881,8 @@ 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_START, properties.getAlphaStart()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread()); } @@ -1152,6 +1162,8 @@ 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_START, float, setAlphaStart); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); } @@ -1296,6 +1308,8 @@ void EntityItemProperties::markAllChanged() { _radiusStartChanged = true; _radiusFinishChanged = true; _radiusSpreadChanged = true; + _alphaStartChanged = true; + _alphaFinishChanged = true; _alphaSpreadChanged = true; _marketplaceIDChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6cd735149e..3721e0d9ca 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -104,6 +104,8 @@ 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_START, AlphaStart, alphaStart, float); + DEFINE_PROPERTY(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, 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); @@ -297,6 +299,8 @@ 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, AlphaStart, alphaStart, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaFinish, alphaFinish, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaSpread, alphaSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ModelURL, modelURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CompoundShapeURL, compoundShapeURL, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index e8763cf565..146f4126a7 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -155,6 +155,8 @@ enum EntityPropertyList { //Used by particles PROP_ALPHA_SPREAD, + PROP_ALPHA_START, + PROP_ALPHA_FINISH, //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 4e0ece15fc..a85a83a4ac 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -44,6 +44,9 @@ const xColor ParticleEffectEntityItem::DEFAULT_COLOR = { 255, 255, 255 }; const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; +const float ParticleEffectEntityItem::ALPHA_UNINITIALIZED = -1.0f; +const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = ALPHA_UNINITIALIZED; +const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = ALPHA_UNINITIALIZED; 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; @@ -88,6 +91,8 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _texturesChangedFlag(false), _shapeType(SHAPE_TYPE_NONE), _alpha(DEFAULT_ALPHA), + _alphaStart(DEFAULT_ALPHA_START), + _alphaFinish(DEFAULT_ALPHA_FINISH), _alphaSpread(DEFAULT_ALPHA_SPREAD), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), @@ -97,6 +102,9 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _alphaStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), + _alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _particleAlphas(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _timeUntilNextEmit(0.0f), _particleHeadIndex(0), @@ -178,6 +186,8 @@ 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(alphaStart, getAlphaStart); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaSpread, getAlphaSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); @@ -206,6 +216,8 @@ 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(alphaStart, setAlphaStart); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaSpread, setAlphaSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); @@ -281,6 +293,8 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); + READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart); + READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish); } return bytesRead; @@ -311,6 +325,8 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_RADIUS_FINISH; requestedProperties += PROP_ALPHA; requestedProperties += PROP_ALPHA_SPREAD; + requestedProperties += PROP_ALPHA_START; + requestedProperties += PROP_ALPHA_FINISH; return requestedProperties; } @@ -344,6 +360,8 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, getAlphaSpread()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, getAlphaStart()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, getAlphaFinish()); } bool ParticleEffectEntityItem::isAnimatingSomething() const { @@ -513,28 +531,13 @@ QString ParticleEffectEntityItem::getAnimationSettings() const { return jsonByteString; } -void ParticleEffectEntityItem::updateRadius(quint32 index) { - if (_radiusStarts[index] == _radiusMiddles[index] && _radiusMiddles[index] == _radiusFinishes[index]) { - _particleRadiuses[index] = _radiusMiddles[index]; - } else { - float age = 2.0f * (1.0f - _particleLifetimes[index] / _lifespan); // 0.0 .. 2.0 - float y0, y1, y2, y3; +void ParticleEffectEntityItem::updateRadius(quint32 index, float age) { + _particleRadiuses[index] = interpolate(_radiusStarts[index], _radiusMiddles[index], _radiusFinishes[index], age); +} - if (age < 1.0f) { - y1 = _radiusStarts[index]; - y2 = _radiusMiddles[index]; - y3 = _radiusFinishes[index]; - y0 = 2.0f * y1 - y2; - } else { - y0 = _radiusStarts[index]; - y1 = _radiusMiddles[index]; - y2 = _radiusFinishes[index]; - y3 = 2.0f * y2 - y1; - age -= 1.0f; - } - - _particleRadiuses[index] = cubicInterpolate(y0, y1, y2, y3, age); - } +void ParticleEffectEntityItem::updateAlpha(quint32 index, float age) { + _particleAlphas[index] = glm::clamp(interpolate(_alphaStarts[index], _alphaMiddles[index], _alphaFinishes[index], age), + 0.0f, 1.0f); } void ParticleEffectEntityItem::extendBounds(const glm::vec3& point) { @@ -569,7 +572,9 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _particleHeadIndex = (_particleHeadIndex + 1) % _maxParticles; } else { - updateRadius(i); + float age = (1.0f - _particleLifetimes[i] / _lifespan); // 0.0 .. 1.0 + updateRadius(i, age); + updateAlpha(i, age); integrateParticle(i, deltaTime); extendBounds(_particlePositions[i]); } @@ -599,7 +604,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _radiusMiddles[i] = spreadMultiplier * _particleRadius; _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); } - updateRadius(i); + updateRadius(i, 0.0f); // Velocity and acceleration glm::vec3 spreadOffset; @@ -622,11 +627,16 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { // Alpha if (_alphaSpread == 0.0f) { - _particleAlphas[i] = _alpha; - + _alphaStarts[i] = getAlphaStart(); + _alphaMiddles[i] = _alpha; + _alphaFinishes[i] = getAlphaFinish(); } else { - _particleAlphas[i] = glm::clamp(_alpha + (2.0f * randFloat() - 1) * _alphaSpread, 0.0f, 1.0f); + float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1) * _alphaSpread / _alpha; + _alphaStarts[i] = spreadMultiplier * getAlphaStart(); + _alphaMiddles[i] = spreadMultiplier * _alpha; + _alphaFinishes[i] = spreadMultiplier * getAlphaFinish(); } + updateAlpha(i, 0.0f); _particleTailIndex = (_particleTailIndex + 1) % _maxParticles; @@ -657,6 +667,9 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { _radiusMiddles.resize(_maxParticles); _radiusFinishes.resize(_maxParticles); _particleAlphas.resize(_maxParticles); + _alphaStarts.resize(_maxParticles); + _alphaMiddles.resize(_maxParticles); + _alphaFinishes.resize(_maxParticles); // effectively clear all particles and start emitting new ones from scratch. _particleHeadIndex = 0; @@ -684,3 +697,27 @@ float ParticleEffectEntityItem::cubicInterpolate(float y0, float y1, float y2, f return (a0 * u * uu + a1 * uu + a2 * u + a3); } + +float ParticleEffectEntityItem::interpolate(float start, float middle, float finish, float age) { + if (start == middle && middle == finish) { + return middle; + } else { + float y0, y1, y2, y3, u; + + if (age <= 0.5f) { + y1 = start; + y2 = middle; + y3 = finish; + y0 = 2.0f * y1 - y2; + u = 2.0f * age; + } else { + y0 = start; + y1 = middle; + y2 = finish; + y3 = 2.0f * y2 - y1; + u = 2.0f * age - 1.0f; + } + + return cubicInterpolate(y0, y1, y2, y3, u); + } +} diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index ad8ed8b386..efdedc715d 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -60,6 +60,16 @@ public: void setAlpha(float alpha) { _alpha = alpha; } float getAlpha() const { return _alpha; } + static const float ALPHA_UNINITIALIZED; + + static const float DEFAULT_ALPHA_START; + void setAlphaStart(float alphaStart) { _alphaStart = alphaStart; } + float getAlphaStart() const { return _alphaStart == ALPHA_UNINITIALIZED ? _alpha : _alphaStart; } + + static const float DEFAULT_ALPHA_FINISH; + void setAlphaFinish(float alphaFinish) { _alphaFinish = alphaFinish; } + float getAlphaFinish() const { return _alphaFinish == ALPHA_UNINITIALIZED ? _alpha : _alphaFinish; } + static const float DEFAULT_ALPHA_SPREAD; void setAlphaSpread(float alphaSpread) { _alphaSpread = alphaSpread; } float getAlphaSpread() const { return _alphaSpread; } @@ -161,7 +171,8 @@ protected: bool isAnimatingSomething() const; void stepSimulation(float deltaTime); - void updateRadius(quint32 index); + void updateRadius(quint32 index, float age); + void updateAlpha(quint32 index, float age); void extendBounds(const glm::vec3& point); void integrateParticle(quint32 index, float deltaTime); quint32 getLivingParticleCount() const; @@ -169,6 +180,8 @@ protected: // the properties of this entity rgbColor _color; float _alpha; + float _alphaStart; + float _alphaFinish; float _alphaSpread; quint32 _maxParticles; float _lifespan; @@ -198,6 +211,9 @@ protected: QVector _radiusMiddles; QVector _radiusFinishes; QVector _particleAlphas; + QVector _alphaStarts; + QVector _alphaMiddles; + QVector _alphaFinishes; float _timeUntilNextEmit; @@ -212,6 +228,7 @@ protected: private: float cubicInterpolate(float y0, float y1, float y2, float y3, float u); + float interpolate(float start, float middle, float finish, float age); }; #endif // hifi_ParticleEffectEntityItem_h From cb9468c311ba542649bf266fa0c67df658e5bc92 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 7 Sep 2015 16:27:42 -0700 Subject: [PATCH 13/15] Add colorSpread entity particle property --- examples/example/entities/particlesTest.js | 14 +++++++++- .../RenderableParticleEffectEntityItem.cpp | 2 +- .../entities/src/EntityItemProperties.cpp | 7 +++++ libraries/entities/src/EntityItemProperties.h | 2 ++ libraries/entities/src/EntityPropertyFlags.h | 1 + .../entities/src/ParticleEffectEntityItem.cpp | 26 ++++++++++++++++++- .../entities/src/ParticleEffectEntityItem.h | 6 +++++ .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 2 +- 9 files changed, 57 insertions(+), 5 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index f1ae210373..5c0a13c371 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 = 9, + NUM_PARTICLE_EXAMPLES = 10, PARTICLE_RADIUS = 0.04; function onClickDownOnEntity(entityID) { @@ -85,11 +85,23 @@ }); break; case 8: + print("Color spread"); + Entities.editEntity(particles, { + alpha: 1.0, + alphaStart: 1.0, + alphaFinish: 1.0, + color: { red: 128, green: 128, blue: 128 }, + colorSpread: { red: 128, green: 0, blue: 0 } + }); + break; + case 9: print("Stop emitting"); Entities.editEntity(particles, { alpha: 1.0, alphaStart: 1.0, alphaFinish: 1.0, + color: { red: 255, green: 255, blue: 255 }, + colorSpread: { red: 0, green: 0, blue: 0 }, animationIsPlaying: false }); break; diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index be9c28a80d..40648fe26f 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -194,8 +194,8 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { // make a copy of each particle's details std::vector particleDetails; particleDetails.reserve(getLivingParticleCount()); - auto xcolor = getXColor(); for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) { + auto xcolor = _particleColors[i]; auto alpha = (uint8_t)(glm::clamp(_particleAlphas[i] * getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); particleDetails.push_back(ParticleDetails(_particlePositions[i], _particleRadiuses[i], rgba)); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 6d68483388..99008c5da0 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -55,6 +55,7 @@ CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT), CONSTRUCT_PROPERTY(scriptTimestamp, ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP), CONSTRUCT_PROPERTY(collisionSoundURL, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL), CONSTRUCT_PROPERTY(color, ), +CONSTRUCT_PROPERTY(colorSpread, ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD), CONSTRUCT_PROPERTY(alpha, ENTITY_ITEM_DEFAULT_ALPHA), CONSTRUCT_PROPERTY(alphaStart, ParticleEffectEntityItem::DEFAULT_ALPHA_START), CONSTRUCT_PROPERTY(alphaFinish, ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH), @@ -335,6 +336,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp); CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL); CHECK_PROPERTY_CHANGE(PROP_COLOR, color); + CHECK_PROPERTY_CHANGE(PROP_COLOR_SPREAD, colorSpread); CHECK_PROPERTY_CHANGE(PROP_ALPHA, alpha); CHECK_PROPERTY_CHANGE(PROP_ALPHA_START, alphaStart); CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish); @@ -453,6 +455,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(angularDamping); COPY_PROPERTY_TO_QSCRIPTVALUE(visible); COPY_PROPERTY_TO_QSCRIPTVALUE(color); + COPY_PROPERTY_TO_QSCRIPTVALUE(colorSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(alpha); COPY_PROPERTY_TO_QSCRIPTVALUE(alphaStart); COPY_PROPERTY_TO_QSCRIPTVALUE(alphaFinish); @@ -590,6 +593,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping); COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible); COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(alpha, float, setAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish); @@ -881,6 +885,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_COLOR_SPREAD, properties.getColorSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, properties.getAlphaStart()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread()); @@ -1162,6 +1167,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_COLOR_SPREAD, xColor, setColorSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); @@ -1308,6 +1314,7 @@ void EntityItemProperties::markAllChanged() { _radiusStartChanged = true; _radiusFinishChanged = true; _radiusSpreadChanged = true; + _colorSpreadChanged = true; _alphaStartChanged = true; _alphaFinishChanged = true; _alphaSpreadChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 3721e0d9ca..43573c0744 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -103,6 +103,7 @@ public: DEFINE_PROPERTY(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64); DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString); DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor); + DEFINE_PROPERTY(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor); DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float); DEFINE_PROPERTY(PROP_ALPHA_START, AlphaStart, alphaStart, float); DEFINE_PROPERTY(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float); @@ -298,6 +299,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ScriptTimestamp, scriptTimestamp, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CollisionSoundURL, collisionSoundURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Color, color, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorSpread, colorSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Alpha, alpha, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaStart, alphaStart, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaFinish, alphaFinish, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 146f4126a7..4bd6a1cd96 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -154,6 +154,7 @@ enum EntityPropertyList { PROP_ALPHA, // Supported by some derived classes //Used by particles + PROP_COLOR_SPREAD, PROP_ALPHA_SPREAD, PROP_ALPHA_START, PROP_ALPHA_FINISH, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index a85a83a4ac..9ae80f098b 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 xColor ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; const float ParticleEffectEntityItem::ALPHA_UNINITIALIZED = -1.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = ALPHA_UNINITIALIZED; @@ -90,6 +91,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _textures(DEFAULT_TEXTURES), _texturesChangedFlag(false), _shapeType(SHAPE_TYPE_NONE), + _colorSpread(DEFAULT_COLOR_SPREAD), _alpha(DEFAULT_ALPHA), _alphaStart(DEFAULT_ALPHA_START), _alphaFinish(DEFAULT_ALPHA_FINISH), @@ -102,7 +104,8 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), - _alphaStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _particleColors(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), + _alphaStarts(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _particleAlphas(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), @@ -186,6 +189,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(colorSpread, getColorSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaStart, getAlphaStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaSpread, getAlphaSpread); @@ -216,6 +220,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(colorSpread, setColorSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaStart, setAlphaStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaSpread, setAlphaSpread); @@ -291,6 +296,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread); READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); + } + + if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES) { + READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread); READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart); @@ -323,6 +332,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_RADIUS_SPREAD; requestedProperties += PROP_RADIUS_START; requestedProperties += PROP_RADIUS_FINISH; + requestedProperties += PROP_COLOR_SPREAD; requestedProperties += PROP_ALPHA; requestedProperties += PROP_ALPHA_SPREAD; requestedProperties += PROP_ALPHA_START; @@ -358,6 +368,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, getRadiusSpread()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); + APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, getColorSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, getAlphaSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, getAlphaStart()); @@ -625,6 +636,18 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { integrateParticle(i, timeLeftInFrame); extendBounds(_particlePositions[i]); + // Color + if (_colorSpread == xColor(xColor{ 0, 0, 0 })) { + _particleColors[i] = getXColor(); + } else { + float spread = 2.0f * randFloat() - 1.0f; + xColor color = getXColor(); + color.red = (int)glm::clamp((float)color.red + spread * (float)_colorSpread.red, 0.0f, 255.0f); + color.green = (int)glm::clamp((float)color.green + spread * (float)_colorSpread.green, 0.0f, 255.0f); + color.blue = (int)glm::clamp((float)color.blue + spread * (float)_colorSpread.blue, 0.0f, 255.0f); + _particleColors[i] = color; + } + // Alpha if (_alphaSpread == 0.0f) { _alphaStarts[i] = getAlphaStart(); @@ -666,6 +689,7 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { _radiusStarts.resize(_maxParticles); _radiusMiddles.resize(_maxParticles); _radiusFinishes.resize(_maxParticles); + _particleColors.resize(_maxParticles); _particleAlphas.resize(_maxParticles); _alphaStarts.resize(_maxParticles); _alphaMiddles.resize(_maxParticles); diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index efdedc715d..7f117ca5cd 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -56,6 +56,10 @@ public: _color[BLUE_INDEX] = value.blue; } + static const xColor DEFAULT_COLOR_SPREAD; + void setColorSpread(const xColor colorSpread) { _colorSpread = colorSpread; } + xColor getColorSpread() const { return _colorSpread; } + static const float DEFAULT_ALPHA; void setAlpha(float alpha) { _alpha = alpha; } float getAlpha() const { return _alpha; } @@ -179,6 +183,7 @@ protected: // the properties of this entity rgbColor _color; + xColor _colorSpread; float _alpha; float _alphaStart; float _alphaFinish; @@ -210,6 +215,7 @@ protected: QVector _radiusStarts; QVector _radiusMiddles; QVector _radiusFinishes; + QVector _particleColors; QVector _particleAlphas; QVector _alphaStarts; QVector _alphaMiddles; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 3a2013d367..bb120ce198 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) { case EntityAdd: case EntityEdit: case EntityData: - return VERSION_ENTITIES_PARTICLE_ALPHA_PROPERTIES; + return VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES; case AvatarData: return 13; default: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index e63f7f410b..eb48bc8019 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -146,6 +146,6 @@ const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38; const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39; const PacketVersion VERSION_ENTITIES_POLYVOX_NEIGHBORS = 40; const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; -const PacketVersion VERSION_ENTITIES_PARTICLE_ALPHA_PROPERTIES = 42; +const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42; #endif // hifi_PacketHeaders_h From cdd5e68815c6094a31dd9c05614e92d0a27b9848 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 8 Sep 2015 11:28:53 -0700 Subject: [PATCH 14/15] Add colorStart and colorFinish entity particle properties --- examples/example/entities/particlesTest.js | 16 +++-- .../entities/src/EntityItemProperties.cpp | 14 ++++ libraries/entities/src/EntityItemProperties.h | 6 +- libraries/entities/src/EntityPropertyFlags.h | 2 + .../entities/src/ParticleEffectEntityItem.cpp | 64 +++++++++++++++++-- .../entities/src/ParticleEffectEntityItem.h | 14 ++++ 6 files changed, 103 insertions(+), 13 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index 5c0a13c371..0d1ea60005 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 = 10, + NUM_PARTICLE_EXAMPLES = 11, PARTICLE_RADIUS = 0.04; function onClickDownOnEntity(entityID) { @@ -95,13 +95,19 @@ }); break; case 9: - print("Stop emitting"); + print("Color start and finish"); Entities.editEntity(particles, { - alpha: 1.0, - alphaStart: 1.0, - alphaFinish: 1.0, color: { red: 255, green: 255, blue: 255 }, colorSpread: { red: 0, green: 0, blue: 0 }, + colorStart: { red: 255, green: 0, blue: 0 }, + colorFinish: { red: 0, green: 255, blue: 0 } + }); + break; + case 10: + print("Stop emitting"); + Entities.editEntity(particles, { + colorStart: { red: 255, green: 255, blue: 255 }, + colorFinish: { red: 255, green: 255, blue: 255 }, animationIsPlaying: false }); break; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 99008c5da0..66153342e7 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -55,6 +55,8 @@ CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT), CONSTRUCT_PROPERTY(scriptTimestamp, ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP), CONSTRUCT_PROPERTY(collisionSoundURL, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL), CONSTRUCT_PROPERTY(color, ), +CONSTRUCT_PROPERTY(colorStart, ParticleEffectEntityItem::DEFAULT_COLOR), +CONSTRUCT_PROPERTY(colorFinish, ParticleEffectEntityItem::DEFAULT_COLOR), CONSTRUCT_PROPERTY(colorSpread, ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD), CONSTRUCT_PROPERTY(alpha, ENTITY_ITEM_DEFAULT_ALPHA), CONSTRUCT_PROPERTY(alphaStart, ParticleEffectEntityItem::DEFAULT_ALPHA_START), @@ -336,6 +338,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp); CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL); CHECK_PROPERTY_CHANGE(PROP_COLOR, color); + CHECK_PROPERTY_CHANGE(PROP_COLOR_START, colorStart); + CHECK_PROPERTY_CHANGE(PROP_COLOR_FINISH, colorFinish); CHECK_PROPERTY_CHANGE(PROP_COLOR_SPREAD, colorSpread); CHECK_PROPERTY_CHANGE(PROP_ALPHA, alpha); CHECK_PROPERTY_CHANGE(PROP_ALPHA_START, alphaStart); @@ -455,6 +459,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(angularDamping); COPY_PROPERTY_TO_QSCRIPTVALUE(visible); COPY_PROPERTY_TO_QSCRIPTVALUE(color); + COPY_PROPERTY_TO_QSCRIPTVALUE(colorStart); + COPY_PROPERTY_TO_QSCRIPTVALUE(colorFinish); COPY_PROPERTY_TO_QSCRIPTVALUE(colorSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(alpha); COPY_PROPERTY_TO_QSCRIPTVALUE(alphaStart); @@ -593,6 +599,8 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping); COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible); COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, xColor, setColorStart); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorFinish, xColor, setColorFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(alpha, float, setAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart); @@ -885,6 +893,8 @@ 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_COLOR_START, properties.getColorStart()); + APPEND_ENTITY_PROPERTY(PROP_COLOR_FINISH, properties.getColorFinish()); APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, properties.getColorSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, properties.getAlphaStart()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish()); @@ -1167,6 +1177,8 @@ 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_COLOR_START, xColor, setColorStart); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_FINISH, xColor, setColorFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_SPREAD, xColor, setColorSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish); @@ -1314,6 +1326,8 @@ void EntityItemProperties::markAllChanged() { _radiusStartChanged = true; _radiusFinishChanged = true; _radiusSpreadChanged = true; + _colorStartChanged = true; + _colorFinishChanged = true; _colorSpreadChanged = true; _alphaStartChanged = true; _alphaFinishChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 43573c0744..1c5913fc88 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -103,7 +103,9 @@ public: DEFINE_PROPERTY(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64); DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString); DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor); - DEFINE_PROPERTY(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor); + DEFINE_PROPERTY_REF(PROP_COLOR_START, ColorStart, colorStart, xColor); + DEFINE_PROPERTY_REF(PROP_COLOR_FINISH, ColorFinish, colorFinish, xColor); + DEFINE_PROPERTY_REF(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor); DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float); DEFINE_PROPERTY(PROP_ALPHA_START, AlphaStart, alphaStart, float); DEFINE_PROPERTY(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float); @@ -299,6 +301,8 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ScriptTimestamp, scriptTimestamp, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CollisionSoundURL, collisionSoundURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Color, color, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorStart, colorStart, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorFinish, colorFinish, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorSpread, colorSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Alpha, alpha, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaStart, alphaStart, ""); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 4bd6a1cd96..d4f880ed8f 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -155,6 +155,8 @@ enum EntityPropertyList { //Used by particles PROP_COLOR_SPREAD, + PROP_COLOR_START, + PROP_COLOR_FINISH, PROP_ALPHA_SPREAD, PROP_ALPHA_START, PROP_ALPHA_FINISH, diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 9ae80f098b..0686c3a996 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -91,6 +91,10 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _textures(DEFAULT_TEXTURES), _texturesChangedFlag(false), _shapeType(SHAPE_TYPE_NONE), + _isColorStartInitialized(false), + _isColorFinishInitialized(false), + _colorStart(DEFAULT_COLOR), + _colorFinish(DEFAULT_COLOR), _colorSpread(DEFAULT_COLOR_SPREAD), _alpha(DEFAULT_ALPHA), _alphaStart(DEFAULT_ALPHA_START), @@ -104,6 +108,9 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _colorStarts(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), + _colorMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), + _colorFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), _particleColors(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), _alphaStarts(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), @@ -189,6 +196,8 @@ 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(colorStart, getColorStart); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorFinish, getColorFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorSpread, getColorSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaStart, getAlphaStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish); @@ -220,6 +229,8 @@ 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(colorStart, setColorStart); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorFinish, setColorFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorSpread, setColorSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaStart, setAlphaStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish); @@ -300,6 +311,8 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES) { READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread); + READ_ENTITY_PROPERTY(PROP_COLOR_START, xColor, setColorStart); + READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, xColor, setColorFinish); READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart); @@ -333,6 +346,8 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea requestedProperties += PROP_RADIUS_START; requestedProperties += PROP_RADIUS_FINISH; requestedProperties += PROP_COLOR_SPREAD; + requestedProperties += PROP_COLOR_START; + requestedProperties += PROP_COLOR_FINISH; requestedProperties += PROP_ALPHA; requestedProperties += PROP_ALPHA_SPREAD; requestedProperties += PROP_ALPHA_START; @@ -369,6 +384,8 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData, APPEND_ENTITY_PROPERTY(PROP_RADIUS_START, getRadiusStart()); APPEND_ENTITY_PROPERTY(PROP_RADIUS_FINISH, getRadiusFinish()); APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, getColorSpread()); + APPEND_ENTITY_PROPERTY(PROP_COLOR_START, getColorStart()); + APPEND_ENTITY_PROPERTY(PROP_COLOR_FINISH, getColorFinish()); APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, getAlphaSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, getAlphaStart()); @@ -546,6 +563,18 @@ void ParticleEffectEntityItem::updateRadius(quint32 index, float age) { _particleRadiuses[index] = interpolate(_radiusStarts[index], _radiusMiddles[index], _radiusFinishes[index], age); } +void ParticleEffectEntityItem::updateColor(quint32 index, float age) { + _particleColors[index].red = + (int)glm::clamp(interpolate(_colorStarts[index].red, _colorMiddles[index].red, _colorFinishes[index].red, age), + 0.0f, 255.0f); + _particleColors[index].green = + (int)glm::clamp(interpolate(_colorStarts[index].green, _colorMiddles[index].green, _colorFinishes[index].green, age), + 0.0f, 255.0f); + _particleColors[index].blue = + (int)glm::clamp(interpolate(_colorStarts[index].blue, _colorMiddles[index].blue, _colorFinishes[index].blue, age), + 0.0f, 255.0f); +} + void ParticleEffectEntityItem::updateAlpha(quint32 index, float age) { _particleAlphas[index] = glm::clamp(interpolate(_alphaStarts[index], _alphaMiddles[index], _alphaFinishes[index], age), 0.0f, 1.0f); @@ -585,6 +614,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { else { float age = (1.0f - _particleLifetimes[i] / _lifespan); // 0.0 .. 1.0 updateRadius(i, age); + updateColor(i, age); updateAlpha(i, age); integrateParticle(i, deltaTime); extendBounds(_particlePositions[i]); @@ -637,16 +667,33 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { extendBounds(_particlePositions[i]); // Color - if (_colorSpread == xColor(xColor{ 0, 0, 0 })) { - _particleColors[i] = getXColor(); + if (_colorSpread == xColor{ 0, 0, 0 }) { + _colorStarts[i] = getColorStart(); + _colorMiddles[i] = getXColor(); + _colorFinishes[i] = getColorFinish(); } else { + xColor startColor = getColorStart(); + xColor middleColor = getXColor(); + xColor finishColor = getColorFinish(); + float spread = 2.0f * randFloat() - 1.0f; - xColor color = getXColor(); - color.red = (int)glm::clamp((float)color.red + spread * (float)_colorSpread.red, 0.0f, 255.0f); - color.green = (int)glm::clamp((float)color.green + spread * (float)_colorSpread.green, 0.0f, 255.0f); - color.blue = (int)glm::clamp((float)color.blue + spread * (float)_colorSpread.blue, 0.0f, 255.0f); - _particleColors[i] = color; + float spreadMultiplierRed = 1.0f + spread * (float)_colorSpread.red / (float)middleColor.red; + float spreadMultiplierGreen = 1.0f + spread * (float)_colorSpread.green / (float)middleColor.green; + float spreadMultiplierBlue = 1.0f + spread * (float)_colorSpread.blue / (float)middleColor.blue; + + _colorStarts[i].red = (int)glm::clamp(spreadMultiplierRed * (float)startColor.red, 0.0f, 255.0f); + _colorStarts[i].green = (int)glm::clamp(spreadMultiplierGreen * (float)startColor.green, 0.0f, 255.0f); + _colorStarts[i].blue = (int)glm::clamp(spreadMultiplierBlue * (float)startColor.blue, 0.0f, 255.0f); + + _colorMiddles[i].red = (int)glm::clamp(spreadMultiplierRed * (float)middleColor.red, 0.0f, 255.0f); + _colorMiddles[i].green = (int)glm::clamp(spreadMultiplierGreen * (float)middleColor.green, 0.0f, 255.0f); + _colorMiddles[i].blue = (int)glm::clamp(spreadMultiplierBlue * (float)middleColor.blue, 0.0f, 255.0f); + + _colorFinishes[i].red = (int)glm::clamp(spreadMultiplierRed * (float)finishColor.red, 0.0f, 255.0f); + _colorFinishes[i].green = (int)glm::clamp(spreadMultiplierGreen * (float)finishColor.green, 0.0f, 255.0f); + _colorFinishes[i].blue = (int)glm::clamp(spreadMultiplierBlue * (float)finishColor.blue, 0.0f, 255.0f); } + updateColor(i, 0.0f); // Alpha if (_alphaSpread == 0.0f) { @@ -690,6 +737,9 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { _radiusMiddles.resize(_maxParticles); _radiusFinishes.resize(_maxParticles); _particleColors.resize(_maxParticles); + _colorStarts.resize(_maxParticles); + _colorMiddles.resize(_maxParticles); + _colorFinishes.resize(_maxParticles); _particleAlphas.resize(_maxParticles); _alphaStarts.resize(_maxParticles); _alphaMiddles.resize(_maxParticles); diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 7f117ca5cd..9511dde152 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -56,6 +56,14 @@ public: _color[BLUE_INDEX] = value.blue; } + bool _isColorStartInitialized; + void setColorStart(xColor colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; } + xColor getColorStart() const { return _isColorStartInitialized ? _colorStart : getXColor(); } + + bool _isColorFinishInitialized; + void setColorFinish(xColor colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; } + xColor getColorFinish() const { return _isColorFinishInitialized ? _colorFinish : getXColor(); } + static const xColor DEFAULT_COLOR_SPREAD; void setColorSpread(const xColor colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } @@ -176,6 +184,7 @@ protected: bool isAnimatingSomething() const; void stepSimulation(float deltaTime); void updateRadius(quint32 index, float age); + void updateColor(quint32 index, float age); void updateAlpha(quint32 index, float age); void extendBounds(const glm::vec3& point); void integrateParticle(quint32 index, float deltaTime); @@ -183,6 +192,8 @@ protected: // the properties of this entity rgbColor _color; + xColor _colorStart; + xColor _colorFinish; xColor _colorSpread; float _alpha; float _alphaStart; @@ -216,6 +227,9 @@ protected: QVector _radiusMiddles; QVector _radiusFinishes; QVector _particleColors; + QVector _colorStarts; + QVector _colorMiddles; + QVector _colorFinishes; QVector _particleAlphas; QVector _alphaStarts; QVector _alphaMiddles; From 99c1e06201df8c20d7b094de0498a98d394876e5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 8 Sep 2015 13:25:15 -0700 Subject: [PATCH 15/15] Code tidying --- .../entities/src/EntityItemProperties.cpp | 42 +++++----- libraries/entities/src/EntityItemProperties.h | 12 +-- .../entities/src/ParticleEffectEntityItem.cpp | 76 ++++++++++--------- .../entities/src/ParticleEffectEntityItem.h | 30 ++++---- 4 files changed, 82 insertions(+), 78 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 66153342e7..eec872153d 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -55,13 +55,13 @@ CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT), CONSTRUCT_PROPERTY(scriptTimestamp, ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP), CONSTRUCT_PROPERTY(collisionSoundURL, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL), CONSTRUCT_PROPERTY(color, ), +CONSTRUCT_PROPERTY(colorSpread, ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD), CONSTRUCT_PROPERTY(colorStart, ParticleEffectEntityItem::DEFAULT_COLOR), CONSTRUCT_PROPERTY(colorFinish, ParticleEffectEntityItem::DEFAULT_COLOR), -CONSTRUCT_PROPERTY(colorSpread, ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD), CONSTRUCT_PROPERTY(alpha, ENTITY_ITEM_DEFAULT_ALPHA), +CONSTRUCT_PROPERTY(alphaSpread, ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD), CONSTRUCT_PROPERTY(alphaStart, ParticleEffectEntityItem::DEFAULT_ALPHA_START), CONSTRUCT_PROPERTY(alphaFinish, ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH), -CONSTRUCT_PROPERTY(alphaSpread, ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD), CONSTRUCT_PROPERTY(modelURL, ""), CONSTRUCT_PROPERTY(compoundShapeURL, ""), CONSTRUCT_PROPERTY(animationURL, ""), @@ -96,9 +96,9 @@ CONSTRUCT_PROPERTY(velocitySpread, ParticleEffectEntityItem::DEFAULT_VELOCITY_SP CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION), CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), +CONSTRUCT_PROPERTY(radiusSpread, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD), CONSTRUCT_PROPERTY(radiusStart, ParticleEffectEntityItem::DEFAULT_RADIUS_START), CONSTRUCT_PROPERTY(radiusFinish, ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH), -CONSTRUCT_PROPERTY(radiusSpread, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD), CONSTRUCT_PROPERTY(marketplaceID, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), CONSTRUCT_PROPERTY(keyLightColor, ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR), CONSTRUCT_PROPERTY(keyLightIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY), @@ -338,13 +338,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_SCRIPT_TIMESTAMP, scriptTimestamp); CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL); CHECK_PROPERTY_CHANGE(PROP_COLOR, color); + CHECK_PROPERTY_CHANGE(PROP_COLOR_SPREAD, colorSpread); CHECK_PROPERTY_CHANGE(PROP_COLOR_START, colorStart); CHECK_PROPERTY_CHANGE(PROP_COLOR_FINISH, colorFinish); - CHECK_PROPERTY_CHANGE(PROP_COLOR_SPREAD, colorSpread); CHECK_PROPERTY_CHANGE(PROP_ALPHA, alpha); + CHECK_PROPERTY_CHANGE(PROP_ALPHA_SPREAD, alphaSpread); CHECK_PROPERTY_CHANGE(PROP_ALPHA_START, alphaStart); CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish); - 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); @@ -379,9 +379,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration); CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); + CHECK_PROPERTY_CHANGE(PROP_RADIUS_SPREAD, radiusSpread); CHECK_PROPERTY_CHANGE(PROP_RADIUS_START, radiusStart); CHECK_PROPERTY_CHANGE(PROP_RADIUS_FINISH, radiusFinish); - CHECK_PROPERTY_CHANGE(PROP_RADIUS_SPREAD, radiusSpread); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); CHECK_PROPERTY_CHANGE(PROP_NAME, name); CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor); @@ -459,13 +459,13 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(angularDamping); COPY_PROPERTY_TO_QSCRIPTVALUE(visible); COPY_PROPERTY_TO_QSCRIPTVALUE(color); + COPY_PROPERTY_TO_QSCRIPTVALUE(colorSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(colorStart); COPY_PROPERTY_TO_QSCRIPTVALUE(colorFinish); - COPY_PROPERTY_TO_QSCRIPTVALUE(colorSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(alpha); + COPY_PROPERTY_TO_QSCRIPTVALUE(alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(alphaStart); COPY_PROPERTY_TO_QSCRIPTVALUE(alphaFinish); - COPY_PROPERTY_TO_QSCRIPTVALUE(alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL); COPY_PROPERTY_TO_QSCRIPTVALUE(compoundShapeURL); COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL); @@ -498,9 +498,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration); COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); + COPY_PROPERTY_TO_QSCRIPTVALUE(radiusSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(radiusStart); COPY_PROPERTY_TO_QSCRIPTVALUE(radiusFinish); - COPY_PROPERTY_TO_QSCRIPTVALUE(radiusSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID); COPY_PROPERTY_TO_QSCRIPTVALUE(name); COPY_PROPERTY_TO_QSCRIPTVALUE(collisionSoundURL); @@ -599,13 +599,13 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(angularDamping, float, setAngularDamping); COPY_PROPERTY_FROM_QSCRIPTVALUE(visible, bool, setVisible); COPY_PROPERTY_FROM_QSCRIPTVALUE(color, xColor, setColor); + COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(colorStart, xColor, setColorStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(colorFinish, xColor, setColorFinish); - COPY_PROPERTY_FROM_QSCRIPTVALUE(colorSpread, xColor, setColorSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(alpha, float, setAlpha); + COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish); - 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); @@ -637,9 +637,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration); COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius); + COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish); - COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID); COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL); @@ -890,15 +890,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); + APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread()); 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_COLOR_SPREAD, properties.getColorSpread()); APPEND_ENTITY_PROPERTY(PROP_COLOR_START, properties.getColorStart()); APPEND_ENTITY_PROPERTY(PROP_COLOR_FINISH, properties.getColorFinish()); - APPEND_ENTITY_PROPERTY(PROP_COLOR_SPREAD, properties.getColorSpread()); + APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, properties.getAlphaStart()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish()); - APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread()); } if (properties.getType() == EntityTypes::Zone) { @@ -1174,15 +1174,15 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_SPREAD, float, setRadiusSpread); 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_COLOR_SPREAD, xColor, setColorSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_START, xColor, setColorStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_FINISH, xColor, setColorFinish); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR_SPREAD, xColor, setColorSpread); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); } if (properties.getType() == EntityTypes::Zone) { @@ -1323,15 +1323,15 @@ void EntityItemProperties::markAllChanged() { _emitAccelerationChanged = true; _accelerationSpreadChanged = true; _particleRadiusChanged = true; + _radiusSpreadChanged = true; _radiusStartChanged = true; _radiusFinishChanged = true; - _radiusSpreadChanged = true; + _colorSpreadChanged = true; _colorStartChanged = true; _colorFinishChanged = true; - _colorSpreadChanged = true; + _alphaSpreadChanged = true; _alphaStartChanged = true; _alphaFinishChanged = true; - _alphaSpreadChanged = true; _marketplaceIDChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 1c5913fc88..2731ab19d5 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -103,13 +103,13 @@ public: DEFINE_PROPERTY(PROP_SCRIPT_TIMESTAMP, ScriptTimestamp, scriptTimestamp, quint64); DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString); DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor); + DEFINE_PROPERTY_REF(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor); DEFINE_PROPERTY_REF(PROP_COLOR_START, ColorStart, colorStart, xColor); DEFINE_PROPERTY_REF(PROP_COLOR_FINISH, ColorFinish, colorFinish, xColor); - DEFINE_PROPERTY_REF(PROP_COLOR_SPREAD, ColorSpread, colorSpread, xColor); DEFINE_PROPERTY(PROP_ALPHA, Alpha, alpha, float); + DEFINE_PROPERTY(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float); DEFINE_PROPERTY(PROP_ALPHA_START, AlphaStart, alphaStart, float); DEFINE_PROPERTY(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, 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); @@ -143,9 +143,9 @@ public: DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); + DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float); DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float); - DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor); DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float); @@ -301,13 +301,13 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ScriptTimestamp, scriptTimestamp, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, CollisionSoundURL, collisionSoundURL, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Color, color, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorSpread, colorSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorStart, colorStart, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorFinish, colorFinish, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, ColorSpread, colorSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Alpha, alpha, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaSpread, alphaSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaStart, alphaStart, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AlphaFinish, alphaFinish, ""); - 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, ""); @@ -339,9 +339,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusSpread, radiusSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusStart, radiusStart, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusFinish, radiusFinish, ""); - DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusSpread, radiusSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, ""); diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 0686c3a996..dce4445336 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -45,10 +45,9 @@ const xColor ParticleEffectEntityItem::DEFAULT_COLOR = { 255, 255, 255 }; const xColor ParticleEffectEntityItem::DEFAULT_COLOR_SPREAD = { 0, 0, 0 }; const float ParticleEffectEntityItem::DEFAULT_ALPHA = 1.0f; -const float ParticleEffectEntityItem::ALPHA_UNINITIALIZED = -1.0f; -const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = ALPHA_UNINITIALIZED; -const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = ALPHA_UNINITIALIZED; const float ParticleEffectEntityItem::DEFAULT_ALPHA_SPREAD = 0.0f; +const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = DEFAULT_ALPHA; +const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = DEFAULT_ALPHA; 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; @@ -60,10 +59,9 @@ const glm::vec3 ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD(3.0f, 0.0f, 3. const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; -const float ParticleEffectEntityItem::RADIUS_UNINITIALIZED = -1.0f; -const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = RADIUS_UNINITIALIZED; -const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = RADIUS_UNINITIALIZED; const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f; +const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = DEFAULT_PARTICLE_RADIUS; +const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = DEFAULT_PARTICLE_RADIUS; const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; @@ -82,24 +80,26 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _emitAcceleration(DEFAULT_EMIT_ACCELERATION), _accelerationSpread(DEFAULT_ACCELERATION_SPREAD), _particleRadius(DEFAULT_PARTICLE_RADIUS), + _radiusSpread(DEFAULT_RADIUS_SPREAD), _radiusStart(DEFAULT_RADIUS_START), _radiusFinish(DEFAULT_RADIUS_FINISH), - _radiusSpread(DEFAULT_RADIUS_SPREAD), _lastAnimated(usecTimestampNow()), _animationLoop(), _animationSettings(), _textures(DEFAULT_TEXTURES), _texturesChangedFlag(false), _shapeType(SHAPE_TYPE_NONE), - _isColorStartInitialized(false), - _isColorFinishInitialized(false), + _colorSpread(DEFAULT_COLOR_SPREAD), _colorStart(DEFAULT_COLOR), _colorFinish(DEFAULT_COLOR), - _colorSpread(DEFAULT_COLOR_SPREAD), + _isColorStartInitialized(false), + _isColorFinishInitialized(false), _alpha(DEFAULT_ALPHA), + _alphaSpread(DEFAULT_ALPHA_SPREAD), _alphaStart(DEFAULT_ALPHA_START), _alphaFinish(DEFAULT_ALPHA_FINISH), - _alphaSpread(DEFAULT_ALPHA_SPREAD), + _isAlphaStartInitialized(false), + _isAlphaFinishInitialized(false), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), @@ -108,14 +108,14 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte _radiusStarts(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), _radiusFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS), + _particleColors(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), _colorStarts(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), _colorMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), _colorFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), - _particleColors(DEFAULT_MAX_PARTICLES, DEFAULT_COLOR), + _particleAlphas(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaStarts(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), - _particleAlphas(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _timeUntilNextEmit(0.0f), _particleHeadIndex(0), _particleTailIndex(0), @@ -193,15 +193,15 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); COPY_ENTITY_PROPERTY_TO_PROPERTIES(accelerationSpread, getAccelerationSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusSpread, getRadiusSpread); 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(colorSpread, getColorSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorStart, getColorStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorFinish, getColorFinish); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(colorSpread, getColorSpread); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaSpread, getAlphaSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaStart, getAlphaStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish); - COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaSpread, getAlphaSpread); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); return properties; @@ -226,15 +226,15 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusSpread, setRadiusSpread); 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(colorSpread, setColorSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorStart, setColorStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorFinish, setColorFinish); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(colorSpread, setColorSpread); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaSpread, setAlphaSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaStart, setAlphaStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish); - SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaSpread, setAlphaSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); if (somethingChanged) { @@ -773,25 +773,29 @@ float ParticleEffectEntityItem::cubicInterpolate(float y0, float y1, float y2, f } float ParticleEffectEntityItem::interpolate(float start, float middle, float finish, float age) { - if (start == middle && middle == finish) { - return middle; - } else { - float y0, y1, y2, y3, u; + float y0, y1, y2, y3, u; - if (age <= 0.5f) { - y1 = start; - y2 = middle; - y3 = finish; - y0 = 2.0f * y1 - y2; - u = 2.0f * age; - } else { - y0 = start; - y1 = middle; - y2 = finish; - y3 = 2.0f * y2 - y1; - u = 2.0f * age - 1.0f; + if (age <= 0.5f) { + if (start == middle) { + return middle; } - return cubicInterpolate(y0, y1, y2, y3, u); + y1 = start; + y2 = middle; + y3 = finish; + y0 = 2.0f * y1 - y2; + u = 2.0f * age; + } else { + if (middle == finish) { + return middle; + } + + y0 = start; + y1 = middle; + y2 = finish; + y3 = 2.0f * y2 - y1; + u = 2.0f * age - 1.0f; } + + return cubicInterpolate(y0, y1, y2, y3, u); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 9511dde152..4e3c4b57b9 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -57,30 +57,30 @@ public: } bool _isColorStartInitialized; - void setColorStart(xColor colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; } + void setColorStart(const xColor& colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; } xColor getColorStart() const { return _isColorStartInitialized ? _colorStart : getXColor(); } bool _isColorFinishInitialized; - void setColorFinish(xColor colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; } + void setColorFinish(const xColor& colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; } xColor getColorFinish() const { return _isColorFinishInitialized ? _colorFinish : getXColor(); } static const xColor DEFAULT_COLOR_SPREAD; - void setColorSpread(const xColor colorSpread) { _colorSpread = colorSpread; } + void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } static const float DEFAULT_ALPHA; void setAlpha(float alpha) { _alpha = alpha; } float getAlpha() const { return _alpha; } - static const float ALPHA_UNINITIALIZED; - static const float DEFAULT_ALPHA_START; - void setAlphaStart(float alphaStart) { _alphaStart = alphaStart; } - float getAlphaStart() const { return _alphaStart == ALPHA_UNINITIALIZED ? _alpha : _alphaStart; } + bool _isAlphaStartInitialized; + void setAlphaStart(float alphaStart) { _alphaStart = alphaStart; _isAlphaStartInitialized = true; } + float getAlphaStart() const { return _isAlphaStartInitialized ? _alphaStart : _alpha; } static const float DEFAULT_ALPHA_FINISH; - void setAlphaFinish(float alphaFinish) { _alphaFinish = alphaFinish; } - float getAlphaFinish() const { return _alphaFinish == ALPHA_UNINITIALIZED ? _alpha : _alphaFinish; } + bool _isAlphaFinishInitialized; + void setAlphaFinish(float alphaFinish) { _alphaFinish = alphaFinish; _isAlphaFinishInitialized = true; } + float getAlphaFinish() const { return _isAlphaFinishInitialized ? _alphaFinish : _alpha; } static const float DEFAULT_ALPHA_SPREAD; void setAlphaSpread(float alphaSpread) { _alphaSpread = alphaSpread; } @@ -148,15 +148,15 @@ public: void setParticleRadius(float particleRadius) { _particleRadius = particleRadius; } float getParticleRadius() const { return _particleRadius; } - static const float RADIUS_UNINITIALIZED; - static const float DEFAULT_RADIUS_START; - void setRadiusStart(float radiusStart) { _radiusStart = radiusStart; } - float getRadiusStart() const { return _radiusStart == RADIUS_UNINITIALIZED ? _particleRadius : _radiusStart; } + bool _isRadiusStartInitialized; + void setRadiusStart(float radiusStart) { _radiusStart = radiusStart; _isRadiusStartInitialized = true; } + float getRadiusStart() const { return _isRadiusStartInitialized ? _radiusStart : _particleRadius; } static const float DEFAULT_RADIUS_FINISH; - void setRadiusFinish(float radiusFinish) { _radiusFinish = radiusFinish; } - float getRadiusFinish() const { return _radiusFinish == RADIUS_UNINITIALIZED ? _particleRadius : _radiusFinish; } + bool _isRadiusFinishInitialized; + void setRadiusFinish(float radiusFinish) { _radiusFinish = radiusFinish; _isRadiusFinishInitialized = true; } + float getRadiusFinish() const { return _isRadiusFinishInitialized ? _radiusFinish : _particleRadius; } static const float DEFAULT_RADIUS_SPREAD; void setRadiusSpread(float radiusSpread) { _radiusSpread = radiusSpread; }