From 4624649b1b66dc1c3f6df7eb88de4b0acb895736 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 7 Oct 2015 08:57:55 -0700 Subject: [PATCH 1/5] Sanitize particle properties, fix crashes --- examples/example/entities/particlesTest.js | 2 +- .../entities/src/EntityItemProperties.cpp | 4 +- .../entities/src/EntityItemPropertiesMacros.h | 4 + .../entities/src/ParticleEffectEntityItem.cpp | 248 +++++++++++++++--- .../entities/src/ParticleEffectEntityItem.h | 58 ++-- 5 files changed, 261 insertions(+), 55 deletions(-) diff --git a/examples/example/entities/particlesTest.js b/examples/example/entities/particlesTest.js index bfa4a47ffb..5f2cbc0849 100644 --- a/examples/example/entities/particlesTest.js +++ b/examples/example/entities/particlesTest.js @@ -28,7 +28,7 @@ FAST_EMIT_SPEED = 1.0, GRAVITY_EMIT_ACCELERATON = { x: 0.0, y: -0.3, z: 0.0 }, ZERO_EMIT_ACCELERATON = { x: 0.0, y: 0.0, z: 0.0 }, - PI = 3.141593, + PI = 3.141592, DEG_TO_RAD = PI / 180.0, NUM_PARTICLE_EXAMPLES = 18; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 61e369cf96..3326cde9aa 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -694,7 +694,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(textColor, xColor, setTextColor); COPY_PROPERTY_FROM_QSCRIPTVALUE(backgroundColor, xColor, setBackgroundColor); COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(shapeType, ShapeType); - COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, float, setMaxParticles); + COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, quint32, setMaxParticles); COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitSpeed, float, setEmitSpeed); @@ -1401,7 +1401,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_SPEED, float, setEmitSpeed); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 731e49b388..659b3bd14c 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -160,6 +160,10 @@ typedef QVector qVectorVec3; typedef QVector qVectorFloat; inline float float_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toFloat(&isValid); } inline quint64 quint64_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toULongLong(&isValid); } +inline quint32 quint32_convertFromScriptValue(const QScriptValue& v, bool& isValid) { + // Use QString::toUInt() so that isValid is set to false if the number is outside the quint32 range. + return v.toString().toUInt(&isValid); +} inline uint16_t uint16_t_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline int int_convertFromScriptValue(const QScriptValue& v, bool& isValid) { return v.toVariant().toInt(&isValid); } inline bool bool_convertFromScriptValue(const QScriptValue& v, bool& isValid) { isValid = true; return v.toVariant().toBool(); } diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 40d3853c39..869c39db97 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -1,4 +1,3 @@ - // // ParticleEffectEntityItem.cpp // libraries/entities/src @@ -31,8 +30,6 @@ #include #include -#include - #include #include #include @@ -46,30 +43,56 @@ const glm::vec3 X_AXIS = glm::vec3(1.0f, 0.0f, 0.0f); const glm::vec3 Z_AXIS = glm::vec3(0.0f, 0.0f, 1.0f); +const float SCRIPT_MAXIMUM_PI = 3.1416f; // Round up so that reasonable property values work + 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::DEFAULT_ALPHA_SPREAD = 0.0f; const float ParticleEffectEntityItem::DEFAULT_ALPHA_START = DEFAULT_ALPHA; const float ParticleEffectEntityItem::DEFAULT_ALPHA_FINISH = DEFAULT_ALPHA; +const float ParticleEffectEntityItem::MINIMUM_ALPHA = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_ALPHA = 1.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; const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000; +const quint32 ParticleEffectEntityItem::MINIMUM_MAX_PARTICLES = 1; +const quint32 ParticleEffectEntityItem::MAXIMUM_MAX_PARTICLES = 10000; const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; +const float ParticleEffectEntityItem::MINIMUM_LIFESPAN = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_LIFESPAN = 86400.0f; // 1 day const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; +const float ParticleEffectEntityItem::MINIMUM_EMIT_RATE = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_RATE = 1000.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_SPEED = 5.0f; +const float ParticleEffectEntityItem::MINIMUM_EMIT_SPEED = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_SPEED = 1000.0f; // Approx mach 3 const float ParticleEffectEntityItem::DEFAULT_SPEED_SPREAD = 1.0f; const glm::quat ParticleEffectEntityItem::DEFAULT_EMIT_ORIENTATION = glm::angleAxis(-PI_OVER_TWO, X_AXIS); // Vertical const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_DIMENSIONS = glm::vec3(0.0f, 0.0f, 0.0f); // Emit from point +const float ParticleEffectEntityItem::MINIMUM_EMIT_DIMENSION = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_DIMENSION = (float)TREE_SCALE; const float ParticleEffectEntityItem::DEFAULT_EMIT_RADIUS_START = 1.0f; // Emit from surface (when emitDimensions > 0) +const float ParticleEffectEntityItem::MINIMUM_EMIT_RADIUS_START = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_EMIT_RADIUS_START = 1.0f; +const float ParticleEffectEntityItem::MINIMUM_POLAR = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_POLAR = SCRIPT_MAXIMUM_PI; const float ParticleEffectEntityItem::DEFAULT_POLAR_START = 0.0f; // Emit along z-axis const float ParticleEffectEntityItem::DEFAULT_POLAR_FINISH = 0.0f; // "" +const float ParticleEffectEntityItem::MINIMUM_AZIMUTH = -SCRIPT_MAXIMUM_PI; +const float ParticleEffectEntityItem::MAXIMUM_AZIMUTH = SCRIPT_MAXIMUM_PI; const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_START = -PI; // Emit full circumference (when polarFinish > 0) const float ParticleEffectEntityItem::DEFAULT_AZIMUTH_FINISH = PI; // "" const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); +const float ParticleEffectEntityItem::MINIMUM_EMIT_ACCELERATION = -100.0f; // ~ 10g +const float ParticleEffectEntityItem::MAXIMUM_EMIT_ACCELERATION = 100.0f; const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); +const float ParticleEffectEntityItem::MINIMUM_ACCELERATION_SPREAD = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_ACCELERATION_SPREAD = 100.0f; const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; +const float ParticleEffectEntityItem::MINIMUM_PARTICLE_RADIUS = 0.0f; +const float ParticleEffectEntityItem::MAXIMUM_PARTICLE_RADIUS = (float)TREE_SCALE; 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; @@ -114,37 +137,177 @@ ParticleEffectEntityItem::~ParticleEffectEntityItem() { } +void ParticleEffectEntityItem::setAlpha(float alpha) { + if (MINIMUM_ALPHA <= alpha && alpha <= MAXIMUM_ALPHA) { + _alpha = alpha; + } +} + +void ParticleEffectEntityItem::setAlphaStart(float alphaStart) { + if (MINIMUM_ALPHA <= alphaStart && alphaStart <= MAXIMUM_ALPHA) { + _alphaStart = alphaStart; + _isAlphaStartInitialized = true; + } +} + +void ParticleEffectEntityItem::setAlphaFinish(float alphaFinish) { + if (MINIMUM_ALPHA <= alphaFinish && alphaFinish <= MAXIMUM_ALPHA) { + _alphaFinish = alphaFinish; + _isAlphaFinishInitialized = true; + } +} + +void ParticleEffectEntityItem::setAlphaSpread(float alphaSpread) { + if (MINIMUM_ALPHA <= alphaSpread && alphaSpread <= MAXIMUM_ALPHA) { + _alphaSpread = alphaSpread; + } +} + +void ParticleEffectEntityItem::setLifespan(float lifespan) { + if (MINIMUM_LIFESPAN <= lifespan && lifespan <= MAXIMUM_LIFESPAN) { + _lifespan = lifespan; + } +} + +void ParticleEffectEntityItem::setEmitRate(float emitRate) { + if (MINIMUM_EMIT_RATE <= emitRate && emitRate <= MAXIMUM_EMIT_RATE) { + _emitRate = emitRate; + } +} + void ParticleEffectEntityItem::setEmitSpeed(float emitSpeed) { - _emitSpeed = emitSpeed; - computeAndUpdateDimensions(); + if (MINIMUM_EMIT_SPEED <= emitSpeed && emitSpeed <= MAXIMUM_EMIT_SPEED) { + _emitSpeed = emitSpeed; + computeAndUpdateDimensions(); + } } void ParticleEffectEntityItem::setSpeedSpread(float speedSpread) { - _speedSpread = speedSpread; - computeAndUpdateDimensions(); + if (MINIMUM_EMIT_SPEED <= speedSpread && speedSpread <= MAXIMUM_EMIT_SPEED) { + _speedSpread = speedSpread; + computeAndUpdateDimensions(); + } } void ParticleEffectEntityItem::setEmitOrientation(const glm::quat& emitOrientation) { - _emitOrientation = emitOrientation; + _emitOrientation = glm::normalize(emitOrientation); computeAndUpdateDimensions(); } - void ParticleEffectEntityItem::setEmitDimensions(const glm::vec3& emitDimensions) { - _emitDimensions = emitDimensions; - computeAndUpdateDimensions(); + bool updated = false; + if (MINIMUM_EMIT_DIMENSION <= emitDimensions.x && emitDimensions.x <= MAXIMUM_EMIT_DIMENSION) { + _emitDimensions.x = emitDimensions.x; + updated = true; + } + if (MINIMUM_EMIT_DIMENSION <= emitDimensions.y && emitDimensions.y <= MAXIMUM_EMIT_DIMENSION) { + _emitDimensions.y = emitDimensions.y; + updated = true; + } + if (MINIMUM_EMIT_DIMENSION <= emitDimensions.z && emitDimensions.z <= MAXIMUM_EMIT_DIMENSION) { + _emitDimensions.z = emitDimensions.z; + updated = true; + } + if (updated) { + computeAndUpdateDimensions(); + } +} + +void ParticleEffectEntityItem::setEmitRadiusStart(float emitRadiusStart) { + if (MINIMUM_EMIT_RADIUS_START <= emitRadiusStart && emitRadiusStart <= MAXIMUM_EMIT_RADIUS_START) { + _emitRadiusStart = emitRadiusStart; + } +} + +void ParticleEffectEntityItem::setPolarStart(float polarStart) { + if (MINIMUM_POLAR <= polarStart && polarStart <= MAXIMUM_POLAR) { + _polarStart = polarStart; + } +} + +void ParticleEffectEntityItem::setPolarFinish(float polarFinish) { + if (MINIMUM_POLAR <= polarFinish && polarFinish <= MAXIMUM_POLAR) { + _polarFinish = polarFinish; + } +} + +void ParticleEffectEntityItem::setAzimuthStart(float azimuthStart) { + if (MINIMUM_AZIMUTH <= azimuthStart && azimuthStart <= MAXIMUM_AZIMUTH) { + _azimuthStart = azimuthStart; + } +} + +void ParticleEffectEntityItem::setAzimuthFinish(float azimuthFinish) { + if (MINIMUM_AZIMUTH <= azimuthFinish && azimuthFinish <= MAXIMUM_AZIMUTH) { + _azimuthFinish = azimuthFinish; + } } void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) { - _emitAcceleration = emitAcceleration; - computeAndUpdateDimensions(); + bool updated = false; + if (MINIMUM_EMIT_ACCELERATION <= emitAcceleration.x && emitAcceleration.x <= MAXIMUM_EMIT_ACCELERATION) { + _emitAcceleration.x = emitAcceleration.x; + updated = true; + } + if (MINIMUM_EMIT_ACCELERATION <= emitAcceleration.y && emitAcceleration.y <= MAXIMUM_EMIT_ACCELERATION) { + _emitAcceleration.y = emitAcceleration.y; + updated = true; + } + if (MINIMUM_EMIT_ACCELERATION <= emitAcceleration.z && emitAcceleration.z <= MAXIMUM_EMIT_ACCELERATION) { + _emitAcceleration.z = emitAcceleration.z; + updated = true; + } + if (updated) { + computeAndUpdateDimensions(); + } } void ParticleEffectEntityItem::setAccelerationSpread(const glm::vec3& accelerationSpread){ - _accelerationSpread = accelerationSpread; - computeAndUpdateDimensions(); + bool updated = false; + if (MINIMUM_ACCELERATION_SPREAD <= accelerationSpread.x && accelerationSpread.x <= MAXIMUM_ACCELERATION_SPREAD) { + _accelerationSpread.x = accelerationSpread.x; + updated = true; + } + if (MINIMUM_ACCELERATION_SPREAD <= accelerationSpread.y && accelerationSpread.y <= MAXIMUM_ACCELERATION_SPREAD) { + _accelerationSpread.y = accelerationSpread.y; + updated = true; + } + if (MINIMUM_ACCELERATION_SPREAD <= accelerationSpread.z && accelerationSpread.z <= MAXIMUM_ACCELERATION_SPREAD) { + _accelerationSpread.z = accelerationSpread.z; + updated = true; + } + if (updated) { + computeAndUpdateDimensions(); + } } +void ParticleEffectEntityItem::setParticleRadius(float particleRadius) { + if (MINIMUM_PARTICLE_RADIUS <= particleRadius && particleRadius <= MAXIMUM_PARTICLE_RADIUS) { + _particleRadius = particleRadius; + } +} + +void ParticleEffectEntityItem::setRadiusStart(float radiusStart) { + if (MINIMUM_PARTICLE_RADIUS <= radiusStart && radiusStart <= MAXIMUM_PARTICLE_RADIUS) { + _radiusStart = radiusStart; + _isRadiusStartInitialized = true; + } +} + +void ParticleEffectEntityItem::setRadiusFinish(float radiusFinish) { + if (MINIMUM_PARTICLE_RADIUS <= radiusFinish && radiusFinish <= MAXIMUM_PARTICLE_RADIUS) { + _radiusFinish = radiusFinish; + _isRadiusFinishInitialized = true; + } +} + +void ParticleEffectEntityItem::setRadiusSpread(float radiusSpread) { + if (MINIMUM_PARTICLE_RADIUS <= radiusSpread && radiusSpread <= MAXIMUM_PARTICLE_RADIUS) { + _radiusSpread = radiusSpread; + } +} + + void ParticleEffectEntityItem::computeAndUpdateDimensions() { const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error @@ -639,12 +802,12 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _particleLifetimes[i] -= deltaTime; // if particle has died. - if (_particleLifetimes[i] <= 0.0f) { + if (_particleLifetimes[i] <= 0.0f || _lifespan == 0.0f) { // move head forward _particleHeadIndex = (_particleHeadIndex + 1) % _maxParticles; } else { - float age = (1.0f - _particleLifetimes[i] / _lifespan); // 0.0 .. 1.0 + float age = 1.0f - _particleLifetimes[i] / _lifespan; // 0.0 .. 1.0 updateRadius(i, age); updateColor(i, age); updateAlpha(i, age); @@ -654,7 +817,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } // emit new particles, but only if animation is playing - if (getAnimationIsPlaying()) { + if (getAnimationIsPlaying() && _emitRate > 0.0f && _lifespan > 0.0f && _polarStart <= _polarFinish) { float timeLeftInFrame = deltaTime; while (_timeUntilNextEmit < timeLeftInFrame) { @@ -672,10 +835,18 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _radiusMiddles[i] =_particleRadius; _radiusFinishes[i] = getRadiusFinish(); } else { - float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1.0f) * _radiusSpread / _particleRadius; - _radiusStarts[i] = spreadMultiplier * getRadiusStart(); - _radiusMiddles[i] = spreadMultiplier * _particleRadius; - _radiusFinishes[i] = spreadMultiplier * getRadiusFinish(); + float spreadMultiplier; + if (_particleRadius > 0.0f) { + spreadMultiplier = 1.0f + randFloatInRange(-1.0f, 1.0f) * _radiusSpread / _particleRadius; + } else { + spreadMultiplier = 1.0f; + } + _radiusStarts[i] = + glm::clamp(spreadMultiplier * getRadiusStart(), MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS); + _radiusMiddles[i] = + glm::clamp(spreadMultiplier * _particleRadius, MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS); + _radiusFinishes[i] = + glm::clamp(spreadMultiplier * getRadiusFinish(), MINIMUM_PARTICLE_RADIUS, MAXIMUM_PARTICLE_RADIUS); } updateRadius(i, 0.0f); @@ -684,8 +855,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { // Emit along z-axis from position _particlePositions[i] = getPosition(); _particleVelocities[i] = - (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); - _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + (_emitSpeed + randFloatInRange(-1.0f, 1.0f) * _speedSpread) * (_emitOrientation * Z_AXIS); + _particleAccelerations[i] = _emitAcceleration + randFloatInRange(-1.0f, 1.0f) * _accelerationSpread; } else { // Emit around point or from ellipsoid @@ -701,15 +872,14 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { if (_azimuthFinish >= _azimuthStart) { azimuth = _azimuthStart + (_azimuthFinish - _azimuthStart) * randFloat(); } else { - azimuth = _azimuthStart + (2.0f * PI + _azimuthFinish - _azimuthStart) * randFloat(); + azimuth = _azimuthStart + (TWO_PI + _azimuthFinish - _azimuthStart) * randFloat(); } - + glm::vec3 emitDirection; if (_emitDimensions == glm::vec3()) { // Point - emitDirection = glm::angleAxis(PI_OVER_TWO - elevation, X_AXIS) * Z_AXIS; - emitDirection = glm::angleAxis(azimuth, Z_AXIS) * emitDirection; + emitDirection = glm::quat(glm::vec3(PI_OVER_TWO - elevation, 0.0f, azimuth)) * Z_AXIS; _particlePositions[i] = getPosition(); } else { @@ -717,7 +887,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { float radiusScale = 1.0f; if (_emitRadiusStart < 1.0f) { float emitRadiusStart = glm::max(_emitRadiusStart, EPSILON); // Avoid math complications at center - float randRadius = emitRadiusStart + (1.0f - emitRadiusStart) * randFloat(); + float randRadius = + emitRadiusStart + randFloatInRange(0.0f, MAXIMUM_EMIT_RADIUS_START - emitRadiusStart); radiusScale = 1.0f - std::pow(1.0f - randRadius, 3.0f); } @@ -736,8 +907,8 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } _particleVelocities[i] = - (_emitSpeed + (2.0f * randFloat() - 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); - _particleAccelerations[i] = _emitAcceleration + (2.0f * randFloat() - 1.0f) * _accelerationSpread; + (_emitSpeed + randFloatInRange(-1.0f, 1.0f) * _speedSpread) * (_emitOrientation * emitDirection); + _particleAccelerations[i] = _emitAcceleration + randFloatInRange(-1.0f, 1.0f) * _accelerationSpread; } integrateParticle(i, timeLeftInFrame); extendBounds(_particlePositions[i]); @@ -752,10 +923,13 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { xColor middleColor = getXColor(); xColor finishColor = getColorFinish(); - float spread = 2.0f * randFloat() - 1.0f; - 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; + float spread = randFloatInRange(-1.0f, 1.0f); + float spreadMultiplierRed = + middleColor.red > 0 ? 1.0f + spread * (float)_colorSpread.red / (float)middleColor.red : 1.0f; + float spreadMultiplierGreen = + middleColor.green > 0 ? 1.0f + spread * (float)_colorSpread.green / (float)middleColor.green : 1.0f; + float spreadMultiplierBlue = + middleColor.blue > 0 ? 1.0f + spread * (float)_colorSpread.blue / (float)middleColor.blue : 1.0f; _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); @@ -777,7 +951,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { _alphaMiddles[i] = _alpha; _alphaFinishes[i] = getAlphaFinish(); } else { - float spreadMultiplier = 1.0f + (2.0f * randFloat() - 1) * _alphaSpread / _alpha; + float spreadMultiplier = 1.0f + randFloatInRange(-1.0f, 1.0f) * _alphaSpread / _alpha; _alphaStarts[i] = spreadMultiplier * getAlphaStart(); _alphaMiddles[i] = spreadMultiplier * _alpha; _alphaFinishes[i] = spreadMultiplier * getAlphaFinish(); @@ -799,7 +973,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) { } void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) { - if (_maxParticles != maxParticles) { + if (_maxParticles != maxParticles && MINIMUM_MAX_PARTICLES <= maxParticles && maxParticles <= MAXIMUM_MAX_PARTICLES) { _maxParticles = maxParticles; // TODO: try to do something smart here and preserve the state of existing particles. diff --git a/libraries/entities/src/ParticleEffectEntityItem.h b/libraries/entities/src/ParticleEffectEntityItem.h index 6d5b8761b0..d4a9da40c6 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.h +++ b/libraries/entities/src/ParticleEffectEntityItem.h @@ -12,6 +12,7 @@ #define hifi_ParticleEffectEntityItem_h #include + #include "EntityItem.h" class ParticleEffectEntityItem : public EntityItem { @@ -68,22 +69,25 @@ public: void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; } xColor getColorSpread() const { return _colorSpread; } + static const float MAXIMUM_ALPHA; + static const float MINIMUM_ALPHA; + static const float DEFAULT_ALPHA; - void setAlpha(float alpha) { _alpha = alpha; } + void setAlpha(float alpha); float getAlpha() const { return _alpha; } static const float DEFAULT_ALPHA_START; bool _isAlphaStartInitialized = false; - void setAlphaStart(float alphaStart) { _alphaStart = alphaStart; _isAlphaStartInitialized = true; } + void setAlphaStart(float alphaStart); float getAlphaStart() const { return _isAlphaStartInitialized ? _alphaStart : _alpha; } static const float DEFAULT_ALPHA_FINISH; bool _isAlphaFinishInitialized = false; - void setAlphaFinish(float alphaFinish) { _alphaFinish = alphaFinish; _isAlphaFinishInitialized = true; } + void setAlphaFinish(float alphaFinish); float getAlphaFinish() const { return _isAlphaFinishInitialized ? _alphaFinish : _alpha; } static const float DEFAULT_ALPHA_SPREAD; - void setAlphaSpread(float alphaSpread) { _alphaSpread = alphaSpread; } + void setAlphaSpread(float alphaSpread); float getAlphaSpread() const { return _alphaSpread; } void updateShapeType(ShapeType type); @@ -117,18 +121,26 @@ public: float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } static const quint32 DEFAULT_MAX_PARTICLES; + static const quint32 MINIMUM_MAX_PARTICLES; + static const quint32 MAXIMUM_MAX_PARTICLES; void setMaxParticles(quint32 maxParticles); quint32 getMaxParticles() const { return _maxParticles; } static const float DEFAULT_LIFESPAN; - void setLifespan(float lifespan) { _lifespan = lifespan; } + static const float MINIMUM_LIFESPAN; + static const float MAXIMUM_LIFESPAN; + void setLifespan(float lifespan); float getLifespan() const { return _lifespan; } static const float DEFAULT_EMIT_RATE; - void setEmitRate(float emitRate) { _emitRate = emitRate; } + static const float MINIMUM_EMIT_RATE; + static const float MAXIMUM_EMIT_RATE; + void setEmitRate(float emitRate); float getEmitRate() const { return _emitRate; } static const float DEFAULT_EMIT_SPEED; + static const float MINIMUM_EMIT_SPEED; + static const float MAXIMUM_EMIT_SPEED; void setEmitSpeed(float emitSpeed); float getEmitSpeed() const { return _emitSpeed; } @@ -141,53 +153,69 @@ public: const glm::quat& getEmitOrientation() const { return _emitOrientation; } static const glm::vec3 DEFAULT_EMIT_DIMENSIONS; + static const float MINIMUM_EMIT_DIMENSION; + static const float MAXIMUM_EMIT_DIMENSION; void setEmitDimensions(const glm::vec3& emitDimensions); const glm::vec3& getEmitDimensions() const { return _emitDimensions; } static const float DEFAULT_EMIT_RADIUS_START; - void setEmitRadiusStart(float emitRadiusStart) { _emitRadiusStart = emitRadiusStart; } + static const float MINIMUM_EMIT_RADIUS_START; + static const float MAXIMUM_EMIT_RADIUS_START; + void setEmitRadiusStart(float emitRadiusStart); float getEmitRadiusStart() const { return _emitRadiusStart; } + static const float MINIMUM_POLAR; + static const float MAXIMUM_POLAR; + static const float DEFAULT_POLAR_START; - void setPolarStart(float polarStart) { _polarStart = polarStart; } + void setPolarStart(float polarStart); float getPolarStart() const { return _polarStart; } static const float DEFAULT_POLAR_FINISH; - void setPolarFinish(float polarFinish) { _polarFinish = polarFinish; } + void setPolarFinish(float polarFinish); float getPolarFinish() const { return _polarFinish; } + static const float MINIMUM_AZIMUTH; + static const float MAXIMUM_AZIMUTH; + static const float DEFAULT_AZIMUTH_START; - void setAzimuthStart(float azimuthStart) { _azimuthStart = azimuthStart; } + void setAzimuthStart(float azimuthStart); float getAzimuthStart() const { return _azimuthStart; } static const float DEFAULT_AZIMUTH_FINISH; - void setAzimuthFinish(float azimuthFinish) { _azimuthFinish = azimuthFinish; } + void setAzimuthFinish(float azimuthFinish); float getAzimuthFinish() const { return _azimuthFinish; } static const glm::vec3 DEFAULT_EMIT_ACCELERATION; + static const float MINIMUM_EMIT_ACCELERATION; + static const float MAXIMUM_EMIT_ACCELERATION; void setEmitAcceleration(const glm::vec3& emitAcceleration); const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; } static const glm::vec3 DEFAULT_ACCELERATION_SPREAD; + static const float MINIMUM_ACCELERATION_SPREAD; + static const float MAXIMUM_ACCELERATION_SPREAD; void setAccelerationSpread(const glm::vec3& accelerationSpread); const glm::vec3& getAccelerationSpread() const { return _accelerationSpread; } static const float DEFAULT_PARTICLE_RADIUS; - void setParticleRadius(float particleRadius) { _particleRadius = particleRadius; } + static const float MINIMUM_PARTICLE_RADIUS; + static const float MAXIMUM_PARTICLE_RADIUS; + void setParticleRadius(float particleRadius); float getParticleRadius() const { return _particleRadius; } static const float DEFAULT_RADIUS_START; bool _isRadiusStartInitialized = false; - void setRadiusStart(float radiusStart) { _radiusStart = radiusStart; _isRadiusStartInitialized = true; } + void setRadiusStart(float radiusStart); float getRadiusStart() const { return _isRadiusStartInitialized ? _radiusStart : _particleRadius; } static const float DEFAULT_RADIUS_FINISH; bool _isRadiusFinishInitialized = false; - void setRadiusFinish(float radiusFinish) { _radiusFinish = radiusFinish; _isRadiusFinishInitialized = true; } + void setRadiusFinish(float radiusFinish); float getRadiusFinish() const { return _isRadiusFinishInitialized ? _radiusFinish : _particleRadius; } static const float DEFAULT_RADIUS_SPREAD; - void setRadiusSpread(float radiusSpread) { _radiusSpread = radiusSpread; } + void setRadiusSpread(float radiusSpread); float getRadiusSpread() const { return _radiusSpread; } void computeAndUpdateDimensions(); From 05da9d94cd3b0762d8783c644d548f03655d599c Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 7 Oct 2015 11:20:11 -0700 Subject: [PATCH 2/5] fixing the depth stencil texture case --- libraries/gpu/src/gpu/GLBackendOutput.cpp | 2 +- libraries/gpu/src/gpu/GLBackendTexture.cpp | 41 ++++++++-------------- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index 70e4b18b0f..2bcd7e31d8 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -109,7 +109,7 @@ GLBackend::GLFramebuffer* GLBackend::syncGPUObject(const Framebuffer& framebuffe glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); } else { attachement = GL_DEPTH_STENCIL_ATTACHMENT; - glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachement, GL_RENDERBUFFER, gltexture->_texture); + glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0); } (void) CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index ee5e1d3bc6..7916f1c0d8 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -66,7 +66,7 @@ public: texel.internalFormat = GL_RG; break; case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_BYTE; + texel.type = GL_UNSIGNED_INT_24_8; texel.format = GL_DEPTH_STENCIL; texel.internalFormat = GL_DEPTH24_STENCIL8; break; @@ -160,8 +160,8 @@ public: } case gpu::FLOAT: { texel.internalFormat = GL_DEPTH_COMPONENT32F; - break; - } + break; + } case gpu::UINT16: case gpu::INT16: case gpu::NUINT16: @@ -199,7 +199,7 @@ public: texel.internalFormat = GL_RG; break; case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_BYTE; + texel.type = GL_UNSIGNED_INT_24_8; texel.format = GL_DEPTH_STENCIL; texel.internalFormat = GL_DEPTH24_STENCIL8; break; @@ -341,32 +341,19 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { auto semantic = texture.getTexelFormat().getSemantic(); - if (semantic == gpu::DEPTH_STENCIL) { - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &object->_texture); + glTexImage2D(GL_TEXTURE_2D, 0, + texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, + texelFormat.format, texelFormat.type, bytes); - glGenRenderbuffers(1, &object->_texture); - glBindRenderbuffer(GL_RENDERBUFFER, object->_texture); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, texture.getWidth(), texture.getHeight()); - // At this point the mip pixels have been loaded, we can notify - texture.notifyMipFaceGPULoaded(0, 0); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - - } else { - glTexImage2D(GL_TEXTURE_2D, 0, - texelFormat.internalFormat, texture.getWidth(), texture.getHeight(), 0, - texelFormat.format, texelFormat.type, bytes); - - if (bytes && texture.isAutogenerateMips()) { - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - - object->_target = GL_TEXTURE_2D; - - syncSampler(texture.getSampler(), texture.getType(), object); + if (bytes && texture.isAutogenerateMips()) { + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } + object->_target = GL_TEXTURE_2D; + + syncSampler(texture.getSampler(), texture.getType(), object); + // At this point the mip pixels have been loaded, we can notify texture.notifyMipFaceGPULoaded(0, 0); From 0a351a8a0c2a7504beff9c71874f571ed97e9b70 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 7 Oct 2015 14:26:33 -0700 Subject: [PATCH 3/5] FIx the problem with cauterizedClusterMatrices in the case rear view mirror is used. Clean the way to define the depth stencil format for texture --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 20 ++++++++-------- .../render-utils/src/FramebufferCache.cpp | 2 +- .../render-utils/src/MeshPartPayload.cpp | 6 ++++- libraries/render-utils/src/Model.cpp | 24 +++++++++++-------- libraries/render-utils/src/Model.h | 2 ++ 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 7916f1c0d8..b72fadafa0 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -50,6 +50,11 @@ public: case gpu::DEPTH: texel.internalFormat = GL_DEPTH_COMPONENT; break; + case gpu::DEPTH_STENCIL: + texel.type = GL_UNSIGNED_INT_24_8; + texel.format = GL_DEPTH_STENCIL; + texel.internalFormat = GL_DEPTH24_STENCIL8; + break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -65,11 +70,6 @@ public: case gpu::RGBA: texel.internalFormat = GL_RG; break; - case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_INT_24_8; - texel.format = GL_DEPTH_STENCIL; - texel.internalFormat = GL_DEPTH24_STENCIL8; - break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -182,6 +182,11 @@ public: } } break; + case gpu::DEPTH_STENCIL: + texel.type = GL_UNSIGNED_INT_24_8; + texel.format = GL_DEPTH_STENCIL; + texel.internalFormat = GL_DEPTH24_STENCIL8; + break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } @@ -198,11 +203,6 @@ public: case gpu::RGBA: texel.internalFormat = GL_RG; break; - case gpu::DEPTH_STENCIL: - texel.type = GL_UNSIGNED_INT_24_8; - texel.format = GL_DEPTH_STENCIL; - texel.internalFormat = GL_DEPTH24_STENCIL8; - break; default: qCDebug(gpulogging) << "Unknown combination of texel format"; } diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index cd81a21f9a..7b20a3696a 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -71,7 +71,7 @@ void FramebufferCache::createPrimaryFramebuffer() { auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); - auto stencilFormat = gpu::Element(gpu::VEC2, gpu::UINT32, gpu::DEPTH_STENCIL); + auto stencilFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format _primaryStencilTexture = gpu::TexturePointer(gpu::Texture::create2D(stencilFormat, width, height, defaultSampler)); _primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index d1db4e6c7f..54b0bacf6e 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -212,7 +212,11 @@ void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locati Transform transform; if (state.clusterBuffer) { - batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); + if (model->_cauterizeBones) { + batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.cauterizedClusterBuffer); + } else { + batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer); + } } else { if (model->_cauterizeBones) { transform = Transform(state.cauterizedClusterMatrices[0]); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2fe95ef64f..38f5ffdabe 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -167,9 +167,7 @@ bool Model::updateGeometry() { MeshState state; state.clusterMatrices.resize(mesh.clusters.size()); state.cauterizedClusterMatrices.resize(mesh.clusters.size()); - if (mesh.clusters.size() > 1) { - state.clusterBuffer = std::make_shared(mesh.clusters.size() * sizeof(glm::mat4), nullptr); - } + _meshStates.append(state); auto buffer = std::make_shared(); @@ -1006,15 +1004,21 @@ void Model::updateClusterMatrices() { } } - // Once computed the cluster matrices, update the buffer - if (state.clusterBuffer) { - const float* bones; - if (_cauterizeBones) { - bones = (const float*)state.cauterizedClusterMatrices.constData(); + // Once computed the cluster matrices, update the buffer(s) + if (mesh.clusters.size() > 1) { + if (!state.clusterBuffer) { + state.clusterBuffer = std::make_shared(state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); } else { - bones = (const float*)state.clusterMatrices.constData(); + state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.clusterMatrices.constData()); + } + + if (!_cauterizeBoneSet.empty() && (state.cauterizedClusterMatrices.size() > 1)) { + if (!state.cauterizedClusterBuffer) { + state.cauterizedClusterBuffer = std::make_shared(state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); + } else { + state.cauterizedClusterBuffer->setSubData(0, state.cauterizedClusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) state.cauterizedClusterMatrices.constData()); + } } - state.clusterBuffer->setSubData(0, state.clusterMatrices.size() * sizeof(glm::mat4), (const gpu::Byte*) bones); } } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 98341e1a3d..e3a9ce9ac3 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -256,6 +256,8 @@ protected: QVector clusterMatrices; QVector cauterizedClusterMatrices; gpu::BufferPointer clusterBuffer; + gpu::BufferPointer cauterizedClusterBuffer; + }; QVector _meshStates; From 0cebeb7fe9a6d3d917cdd3d491124f9937033cbd Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 7 Oct 2015 15:32:10 -0700 Subject: [PATCH 4/5] Separated AvatarMixer inbound and outbound bandwidth on stats overlay Also, small bug fix to BandwidthRecorder. It would incorrectly calculate outbound pps if the input pps was 0. --- interface/resources/qml/Stats.qml | 11 +++++++++-- interface/src/ui/Stats.cpp | 16 ++++++++-------- interface/src/ui/Stats.h | 12 ++++++++---- libraries/networking/src/BandwidthRecorder.cpp | 4 ++-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index eb39fbc70f..780f9cb89f 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -142,8 +142,15 @@ Item { color: root.fontColor; font.pixelSize: root.fontSize visible: root.expanded; - text: "Avatar Mixer: " + root.avatarMixerKbps + " kbps, " + - root.avatarMixerPps + "pps"; + text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " + + root.avatarMixerInPps + "pps"; + } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + visible: root.expanded; + text: "Avatar Mixer Out: " + root.avatarMixerOutKbps + " kbps, " + + root.avatarMixerOutPps + "pps"; } Text { color: root.fontColor; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 5e73e62832..7e2143c454 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -167,15 +167,15 @@ void Stats::updateStats(bool force) { if (_expanded || force) { SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer); if (avatarMixer) { - STAT_UPDATE(avatarMixerKbps, roundf( - bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer) + - bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer))); - STAT_UPDATE(avatarMixerPps, roundf( - bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer) + - bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerInKbps, roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerInPps, roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerOutKbps, roundf(bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AvatarMixer))); + STAT_UPDATE(avatarMixerOutPps, roundf(bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AvatarMixer))); } else { - STAT_UPDATE(avatarMixerKbps, -1); - STAT_UPDATE(avatarMixerPps, -1); + STAT_UPDATE(avatarMixerInKbps, -1); + STAT_UPDATE(avatarMixerInPps, -1); + STAT_UPDATE(avatarMixerOutKbps, -1); + STAT_UPDATE(avatarMixerOutPps, -1); } SharedNodePointer audioMixerNode = nodeList->soloNodeOfType(NodeType::AudioMixer); if (audioMixerNode || force) { diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index d6aa255dc6..f1426a9e37 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -47,8 +47,10 @@ class Stats : public QQuickItem { STATS_PROPERTY(QVector3D, position, QVector3D(0, 0, 0) ) STATS_PROPERTY(float, velocity, 0) STATS_PROPERTY(float, yaw, 0) - STATS_PROPERTY(int, avatarMixerKbps, 0) - STATS_PROPERTY(int, avatarMixerPps, 0) + STATS_PROPERTY(int, avatarMixerInKbps, 0) + STATS_PROPERTY(int, avatarMixerInPps, 0) + STATS_PROPERTY(int, avatarMixerOutKbps, 0) + STATS_PROPERTY(int, avatarMixerOutPps, 0) STATS_PROPERTY(int, audioMixerKbps, 0) STATS_PROPERTY(int, audioMixerPps, 0) STATS_PROPERTY(int, downloads, 0) @@ -122,8 +124,10 @@ signals: void positionChanged(); void velocityChanged(); void yawChanged(); - void avatarMixerKbpsChanged(); - void avatarMixerPpsChanged(); + void avatarMixerInKbpsChanged(); + void avatarMixerInPpsChanged(); + void avatarMixerOutKbpsChanged(); + void avatarMixerOutPpsChanged(); void audioMixerKbpsChanged(); void audioMixerPpsChanged(); void downloadsChanged(); diff --git a/libraries/networking/src/BandwidthRecorder.cpp b/libraries/networking/src/BandwidthRecorder.cpp index a415a9f477..5db987b236 100644 --- a/libraries/networking/src/BandwidthRecorder.cpp +++ b/libraries/networking/src/BandwidthRecorder.cpp @@ -27,9 +27,9 @@ float BandwidthRecorder::Channel::getAverageInputPacketsPerSecond() { } float BandwidthRecorder::Channel::getAverageOutputPacketsPerSecond() { - float delt = _input.getEventDeltaAverage(); + float delt = _output.getEventDeltaAverage(); if (delt > 0.0f) { - return (1.0f / _output.getEventDeltaAverage()); + return (1.0f / delt); } return 0.0f; } From 00f3b7b1b5ff7b5af0a6f450a16f9b0a9d29a77e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 7 Oct 2015 15:46:42 -0700 Subject: [PATCH 5/5] Renamed delt to averageTimeBetweenPackets --- libraries/networking/src/BandwidthRecorder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/networking/src/BandwidthRecorder.cpp b/libraries/networking/src/BandwidthRecorder.cpp index 5db987b236..d43d4cf21f 100644 --- a/libraries/networking/src/BandwidthRecorder.cpp +++ b/libraries/networking/src/BandwidthRecorder.cpp @@ -19,17 +19,17 @@ BandwidthRecorder::Channel::Channel() { } float BandwidthRecorder::Channel::getAverageInputPacketsPerSecond() { - float delt = _input.getEventDeltaAverage(); - if (delt > 0.0f) { - return (1.0f / delt); + float averageTimeBetweenPackets = _input.getEventDeltaAverage(); + if (averageTimeBetweenPackets > 0.0f) { + return (1.0f / averageTimeBetweenPackets); } return 0.0f; } float BandwidthRecorder::Channel::getAverageOutputPacketsPerSecond() { - float delt = _output.getEventDeltaAverage(); - if (delt > 0.0f) { - return (1.0f / delt); + float averageTimeBetweenPackets = _output.getEventDeltaAverage(); + if (averageTimeBetweenPackets > 0.0f) { + return (1.0f / averageTimeBetweenPackets); } return 0.0f; }