diff --git a/examples/grab.js b/examples/grab.js
index 6bdf218ce2..019ec2320f 100644
--- a/examples/grab.js
+++ b/examples/grab.js
@@ -76,7 +76,7 @@ function mousePressEvent(event) {
return;
}
var pickRay = Camera.computePickRay(event.x, event.y);
- var intersection = Entities.findRayIntersection(pickRay);
+ var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking
if (intersection.intersects && intersection.properties.collisionsWillMove) {
grabbedEntity = intersection.entityID;
var props = Entities.getEntityProperties(grabbedEntity)
diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html
index 4ce787d78a..25467f7573 100644
--- a/examples/html/entityProperties.html
+++ b/examples/html/entityProperties.html
@@ -244,6 +244,7 @@
var elDensity = document.getElementById("property-density");
var elIgnoreForCollisions = document.getElementById("property-ignore-for-collisions");
var elCollisionsWillMove = document.getElementById("property-collisions-will-move");
+ var elCollisionSoundURL = document.getElementById("property-collision-sound-url");
var elLifetime = document.getElementById("property-lifetime");
var elScriptURL = document.getElementById("property-script-url");
var elUserData = document.getElementById("property-user-data");
@@ -437,6 +438,7 @@
elDensity.value = properties.density.toFixed(2);
elIgnoreForCollisions.checked = properties.ignoreForCollisions;
elCollisionsWillMove.checked = properties.collisionsWillMove;
+ elCollisionSoundURL.value = properties.collisionSoundURL;
elLifetime.value = properties.lifetime;
elScriptURL.value = properties.script;
elUserData.value = properties.userData;
@@ -622,6 +624,8 @@
elDensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('density'));
elIgnoreForCollisions.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ignoreForCollisions'));
elCollisionsWillMove.addEventListener('change', createEmitCheckedPropertyUpdateFunction('collisionsWillMove'));
+ elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL'));
+
elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime'));
elScriptURL.addEventListener('change', createEmitTextPropertyUpdateFunction('script'));
elUserData.addEventListener('change', createEmitTextPropertyUpdateFunction('userData'));
@@ -999,6 +1003,13 @@
+
+
Collision Sound URL
+
+
+
+
+
Lifetime
diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js
index 5c6c688f0d..f9f8d57a51 100644
--- a/examples/libraries/entityPropertyDialogBox.js
+++ b/examples/libraries/entityPropertyDialogBox.js
@@ -185,6 +185,8 @@ EntityPropertyDialogBox = (function () {
index++;
array.push({ label: "Collisions Will Move:", type: "checkbox", value: properties.collisionsWillMove });
index++;
+ array.push({ label: "Collision Sound URL:", value: properties.collisionSoundURL });
+ index++;
array.push({ label: "Lifetime:", value: properties.lifetime.toFixed(decimals) });
index++;
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
index cd2e339653..deba442c94 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "EntityTreeRenderer.h"
@@ -46,6 +47,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf
_wantScripts(wantScripts),
_entitiesScriptEngine(NULL),
_sandboxScriptEngine(NULL),
+ _localAudioInterface(NULL),
_lastMouseEventValid(false),
_viewState(viewState),
_scriptingServices(scriptingServices),
@@ -1098,13 +1100,78 @@ void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const
}
}
-void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB,
+void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision) {
+ EntityItem* entity = entityTree->findEntityByEntityItemID(id);
+ QUuid simulatorID = entity->getSimulatorID();
+ if (simulatorID.isNull() || (simulatorID != myNodeID)) {
+ return; // Only one injector per simulation, please.
+ }
+ const QString& collisionSoundURL = entity->getCollisionSoundURL();
+ if (collisionSoundURL.isEmpty()) {
+ return;
+ }
+ SharedSoundPointer sound = DependencyManager::get().data()->getSound(QUrl(collisionSoundURL));
+ if (!sound->isReady()) {
+ return;
+ }
+
+ const float mass = entity->computeMass();
+ const float COLLISION_PENTRATION_TO_VELOCITY = 50; // as a subsitute for RELATIVE entity->getVelocity()
+ const float linearVelocity = glm::length(collision.penetration) * COLLISION_PENTRATION_TO_VELOCITY;
+ const float energy = mass * linearVelocity * linearVelocity / 2.0f;
+ const glm::vec3 position = collision.contactPoint;
+ const float COLLISION_ENERGY_AT_FULL_VOLUME = 10.0f;
+ const float COLLISION_MINIMUM_VOLUME = 0.01f;
+ const float energyPercentOfFull = fmin(1.0f, energy / COLLISION_ENERGY_AT_FULL_VOLUME);
+ //qCDebug(entitiesrenderer) << energyPercentOfFull << energy << " " << " " << linearVelocity << " " << mass;
+ if (energyPercentOfFull < COLLISION_MINIMUM_VOLUME) {
+ return;
+ }
+ // This is a hack. Quiet sound aren't really heard at all, so we compress everything to the range 0.5-1.0, if we play it all.
+ const float COLLISION_SOUND_COMPRESSION = 0.5f;
+ const float volume = (energyPercentOfFull * COLLISION_SOUND_COMPRESSION) + (1.0f - COLLISION_SOUND_COMPRESSION);
+ //qCDebug(entitiesrenderer) << collisionSoundURL << " " << volume << " " << position << " " << sound->isStereo();
+
+ // This is quite similar to AudioScriptingInterface::playSound() and should probably be refactored.
+ AudioInjectorOptions options;
+ options.stereo = sound->isStereo();
+ options.position = position;
+ options.volume = volume;
+ AudioInjector* injector = new AudioInjector(sound.data(), options);
+ injector->setLocalAudioInterface(_localAudioInterface);
+ QThread* injectorThread = new QThread();
+ injectorThread->setObjectName("Audio Injector Thread");
+ injector->moveToThread(injectorThread);
+ // start injecting when the injector thread starts
+ connect(injectorThread, &QThread::started, injector, &AudioInjector::injectAudio);
+ // connect the right slots and signals for AudioInjector and thread cleanup
+ connect(injector, &AudioInjector::destroyed, injectorThread, &QThread::quit);
+ connect(injectorThread, &QThread::finished, injectorThread, &QThread::deleteLater);
+ injectorThread->start();
+}
+
+void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB,
const Collision& collision) {
// If we don't have a tree, or we're in the process of shutting down, then don't
// process these events.
if (!_tree || _shuttingDown) {
return;
}
+
+ // See if we should play sounds
+ EntityTree* entityTree = static_cast(_tree);
+ if (!entityTree->tryLockForRead()) {
+ // I don't know why this can happen, but if it does,
+ // the consequences are a deadlock, so bail.
+ qCDebug(entitiesrenderer) << "NOTICE: skipping collision.";
+ return;
+ }
+ const QUuid& myNodeID = DependencyManager::get()->getSessionUUID();
+ playEntityCollisionSound(myNodeID, entityTree, idA, collision);
+ playEntityCollisionSound(myNodeID, entityTree, idB, collision);
+ entityTree->unlock();
+
+ // And now the entity scripts
QScriptValue entityScriptA = loadEntityScript(idA);
if (entityScriptA.property("collisionWithEntity").isValid()) {
QScriptValueList args;
diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h
index 20534c3e2b..eb8b44f5eb 100644
--- a/libraries/entities-renderer/src/EntityTreeRenderer.h
+++ b/libraries/entities-renderer/src/EntityTreeRenderer.h
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
class AbstractScriptingServicesInterface;
class AbstractViewStateInterface;
@@ -155,6 +156,9 @@ private:
QHash _entityScripts;
+ void playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision);
+ AbstractAudioInterface* _localAudioInterface; // So we can render collision sounds
+
bool _lastMouseEventValid;
MouseEvent _lastMouseEvent;
AbstractViewStateInterface* _viewState;
diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp
index 23d7608fe0..470426d55e 100644
--- a/libraries/entities/src/EntityItem.cpp
+++ b/libraries/entities/src/EntityItem.cpp
@@ -19,6 +19,7 @@
#include
#include
#include // usecTimestampNow()
+#include
#include "EntityScriptingInterface.h"
#include "EntityItem.h"
@@ -52,6 +53,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
_damping(ENTITY_ITEM_DEFAULT_DAMPING),
_lifetime(ENTITY_ITEM_DEFAULT_LIFETIME),
_script(ENTITY_ITEM_DEFAULT_SCRIPT),
+ _collisionSoundURL(ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL),
_registrationPoint(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT),
_angularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY),
_angularDamping(ENTITY_ITEM_DEFAULT_ANGULAR_DAMPING),
@@ -100,6 +102,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
requestedProperties += PROP_DAMPING;
requestedProperties += PROP_LIFETIME;
requestedProperties += PROP_SCRIPT;
+ requestedProperties += PROP_COLLISION_SOUND_URL;
requestedProperties += PROP_REGISTRATION_POINT;
requestedProperties += PROP_ANGULAR_VELOCITY;
requestedProperties += PROP_ANGULAR_DAMPING;
@@ -237,6 +240,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
APPEND_ENTITY_PROPERTY(PROP_SIMULATOR_ID, getSimulatorID());
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, getMarketplaceID());
APPEND_ENTITY_PROPERTY(PROP_NAME, getName());
+ APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, getCollisionSoundURL());
appendSubclassData(packetData, params, entityTreeElementExtraEncodeData,
requestedProperties,
@@ -573,7 +577,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
}
READ_ENTITY_PROPERTY(PROP_NAME, QString, setName);
-
+ READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
////////////////////////////////////
@@ -898,6 +902,7 @@ EntityItemProperties EntityItem::getProperties() const {
COPY_ENTITY_PROPERTY_TO_PROPERTIES(damping, getDamping);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifetime, getLifetime);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(script, getScript);
+ COPY_ENTITY_PROPERTY_TO_PROPERTIES(collisionSoundURL, getCollisionSoundURL);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(registrationPoint, getRegistrationPoint);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularVelocity, getAngularVelocity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(angularDamping, getAngularDamping);
@@ -930,6 +935,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(damping, updateDamping);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifetime, updateLifetime);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(script, setScript);
+ SET_ENTITY_PROPERTY_FROM_PROPERTIES(collisionSoundURL, setCollisionSoundURL);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularVelocity, updateAngularVelocity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(angularDamping, updateAngularDamping);
diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h
index d9096bf429..b9dc14251c 100644
--- a/libraries/entities/src/EntityItem.h
+++ b/libraries/entities/src/EntityItem.h
@@ -246,6 +246,8 @@ public:
const QString& getScript() const { return _script; }
void setScript(const QString& value) { _script = value; }
+ const QString& getCollisionSoundURL() const { return _collisionSoundURL; }
+ void setCollisionSoundURL(const QString& value) { _collisionSoundURL = value; }
const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } /// registration point as ratio of entity
@@ -375,6 +377,7 @@ protected:
float _damping;
float _lifetime;
QString _script;
+ QString _collisionSoundURL;
glm::vec3 _registrationPoint;
glm::vec3 _angularVelocity;
float _angularDamping;
diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp
index de6a8e30b6..2d68a20022 100644
--- a/libraries/entities/src/EntityItemProperties.cpp
+++ b/libraries/entities/src/EntityItemProperties.cpp
@@ -46,6 +46,7 @@ EntityItemProperties::EntityItemProperties() :
CONSTRUCT_PROPERTY(damping, ENTITY_ITEM_DEFAULT_DAMPING),
CONSTRUCT_PROPERTY(lifetime, ENTITY_ITEM_DEFAULT_LIFETIME),
CONSTRUCT_PROPERTY(script, ENTITY_ITEM_DEFAULT_SCRIPT),
+ CONSTRUCT_PROPERTY(collisionSoundURL, ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL),
CONSTRUCT_PROPERTY(color, ),
CONSTRUCT_PROPERTY(modelURL, ""),
CONSTRUCT_PROPERTY(compoundShapeURL, ""),
@@ -288,6 +289,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_DAMPING, damping);
CHECK_PROPERTY_CHANGE(PROP_LIFETIME, lifetime);
CHECK_PROPERTY_CHANGE(PROP_SCRIPT, script);
+ CHECK_PROPERTY_CHANGE(PROP_COLLISION_SOUND_URL, collisionSoundURL);
CHECK_PROPERTY_CHANGE(PROP_COLOR, color);
CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL);
CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
@@ -405,6 +407,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius);
COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID);
COPY_PROPERTY_TO_QSCRIPTVALUE(name);
+ COPY_PROPERTY_TO_QSCRIPTVALUE(collisionSoundURL);
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightColor);
COPY_PROPERTY_TO_QSCRIPTVALUE(keyLightIntensity);
@@ -507,6 +510,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) {
COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius);
COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID);
COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName);
+ COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
COPY_PROPERTY_FROM_QSCRIPTVALUE(keyLightColor, xColor, setKeyLightColor);
COPY_PROPERTY_FROM_QSCRIPTVALUE(keyLightIntensity, float, setKeyLightIntensity);
@@ -735,6 +739,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
APPEND_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, properties.getMarketplaceID());
APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName());
+ APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL());
}
if (propertyCount > 0) {
int endOfEntityItemData = packetData->getUncompressedByteOffset();
@@ -988,7 +993,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MARKETPLACE_ID, QString, setMarketplaceID);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NAME, QString, setName);
-
+ READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL);
+
return valid;
}
@@ -1034,6 +1040,7 @@ void EntityItemProperties::markAllChanged() {
_userDataChanged = true;
_simulatorIDChanged = true;
_scriptChanged = true;
+ _collisionSoundURLChanged = true;
_registrationPointChanged = true;
_angularVelocityChanged = true;
_angularDampingChanged = true;
diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h
index a1ca4d5eff..7d8cbfe9b1 100644
--- a/libraries/entities/src/EntityItemProperties.h
+++ b/libraries/entities/src/EntityItemProperties.h
@@ -97,6 +97,7 @@ public:
DEFINE_PROPERTY(PROP_DAMPING, Damping, damping, float);
DEFINE_PROPERTY(PROP_LIFETIME, Lifetime, lifetime, float);
DEFINE_PROPERTY_REF(PROP_SCRIPT, Script, script, QString);
+ DEFINE_PROPERTY_REF(PROP_COLLISION_SOUND_URL, CollisionSoundURL, collisionSoundURL, QString);
DEFINE_PROPERTY_REF(PROP_COLOR, Color, color, xColor);
DEFINE_PROPERTY_REF(PROP_MODEL_URL, ModelURL, modelURL, QString);
DEFINE_PROPERTY_REF(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString);
@@ -244,6 +245,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Damping, damping, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Lifetime, lifetime, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Script, script, "");
+ DEBUG_PROPERTY_IF_CHANGED(debug, properties, CollisionSoundURL, collisionSoundURL, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Color, color, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ModelURL, modelURL, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CompoundShapeURL, compoundShapeURL, "");
diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h
index bdc1fb37e6..ae44322377 100644
--- a/libraries/entities/src/EntityItemPropertiesDefaults.h
+++ b/libraries/entities/src/EntityItemPropertiesDefaults.h
@@ -30,6 +30,7 @@ const float ENTITY_ITEM_DEFAULT_GLOW_LEVEL = 0.0f;
const bool ENTITY_ITEM_DEFAULT_VISIBLE = true;
const QString ENTITY_ITEM_DEFAULT_SCRIPT = QString("");
+const QString ENTITY_ITEM_DEFAULT_COLLISION_SOUND_URL = QString("");
const glm::vec3 ENTITY_ITEM_DEFAULT_REGISTRATION_POINT = glm::vec3(0.5f, 0.5f, 0.5f); // center
const float ENTITY_ITEM_IMMORTAL_LIFETIME = -1.0f; /// special lifetime which means the entity lives for ever
diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h
index 42032ec04d..66ec70ae60 100644
--- a/libraries/entities/src/EntityPropertyFlags.h
+++ b/libraries/entities/src/EntityPropertyFlags.h
@@ -106,6 +106,7 @@ enum EntityPropertyList {
PROP_ACCELERATION, // all entities
PROP_SIMULATOR_ID, // all entities
PROP_NAME, // all entities
+ PROP_COLLISION_SOUND_URL,
////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties ABOVE this line
diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h
index a5f39cb825..fc90b0c903 100644
--- a/libraries/model/src/model/Stage.h
+++ b/libraries/model/src/model/Stage.h
@@ -71,14 +71,14 @@ public:
EarthSunModel() { valid(); }
protected:
- double _scale = 1000.0; //Km
+ float _scale = 1000.0f; //Km
double _earthRadius = 6360.0;
Quat _surfaceOrientation;
- double _longitude = 0.0;
- double _latitude = 0.0;
- double _altitude = 0.01;
+ float _longitude = 0.0f;
+ float _latitude = 0.0f;
+ float _altitude = 0.01f;
mutable Vec3d _surfacePos;
mutable Mat4d _worldToSurfaceMat;
mutable Mat4d _surfaceToWorldMat;
@@ -93,8 +93,8 @@ protected:
mutable Mat4d _worldToEyeMat;
mutable Mat4d _eyeToWorldMat;
- double _sunLongitude = 0.0;
- double _sunLatitude = 0.0;
+ float _sunLongitude = 0.0f;
+ float _sunLatitude = 0.0f;
mutable Vec3d _sunDir;
mutable Vec3d _surfaceSunDir;
void updateSun() const;
diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp
index 887634cf80..0dcd30a55c 100644
--- a/libraries/networking/src/PacketHeaders.cpp
+++ b/libraries/networking/src/PacketHeaders.cpp
@@ -72,7 +72,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
return 1;
case PacketTypeEntityAddOrEdit:
case PacketTypeEntityData:
- return VERSION_ENTITIES_HAVE_LINE_TYPE;
+ return VERSION_ENTITIES_HAVE_COLLISION_SOUND_URL;
case PacketTypeEntityErase:
return 2;
case PacketTypeAudioStreamStats:
diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h
index 1dff5d7c79..01eb488c14 100644
--- a/libraries/networking/src/PacketHeaders.h
+++ b/libraries/networking/src/PacketHeaders.h
@@ -176,5 +176,6 @@ const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX = 21;
const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_STAGE_HAS_AUTOMATIC_HOURDAY = 22;
const PacketVersion VERSION_ENTITIES_PARTICLE_ENTITIES_HAVE_TEXTURES = 23;
const PacketVersion VERSION_ENTITIES_HAVE_LINE_TYPE = 24;
+const PacketVersion VERSION_ENTITIES_HAVE_COLLISION_SOUND_URL = 25;
#endif // hifi_PacketHeaders_h