From 45ff118249e1f60eb7b538d00b38447d5bbc6ec4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 3 Sep 2015 12:43:36 -0700 Subject: [PATCH] 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