From b7cd8827f93e752bc512243c33b6e8f7562fcaaf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 30 Dec 2016 14:11:24 -0800 Subject: [PATCH] collision events for owned objects only also: fewer entityID lookups for scripted collision sounds and events --- .../src/EntityTreeRenderer.cpp | 63 +++++++++---------- .../src/EntityTreeRenderer.h | 6 +- 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9a3b66ff1f..0e7fbee5c1 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -956,6 +956,7 @@ void EntityTreeRenderer::checkAndCallPreload(const EntityItemID& entityID, const } } +/* bool EntityTreeRenderer::isCollisionOwner(const QUuid& myNodeID, EntityTreePointer entityTree, const EntityItemID& id, const Collision& collision) { // BUG: this method is poorly named. It should be called like: isOwnerOfObjectOrOwnerOfOtherIfObjectIsUnowned() @@ -982,43 +983,35 @@ bool EntityTreeRenderer::isCollisionOwner(const QUuid& myNodeID, EntityTreePoint return true; } -void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTreePointer entityTree, - const EntityItemID& id, const Collision& collision) { +bool EntityTreeRenderer::isCollisionOwner(const QUuid& myNodeID, EntityTreePointer entityTree, const EntityItemID& id) { + EntityItemPointer entity = entityTree->findEntityByEntityItemID(id); + return ((bool)entity && myNodeID == entity->getSimulatorID()); +} +*/ - if (!isCollisionOwner(myNodeID, entityTree, id, collision)) { - return; - } - - SharedSoundPointer collisionSound; - float mass = 1.0; // value doesn't get used, but set it so compiler is quiet - AACube minAACube; - bool success = false; - _tree->withReadLock([&] { - EntityItemPointer entity = entityTree->findEntityByEntityItemID(id); - if (entity) { - collisionSound = entity->getCollisionSound(); - mass = entity->computeMass(); - minAACube = entity->getMinimumAACube(success); - } - }); - if (!success) { - return; - } +void EntityTreeRenderer::playEntityCollisionSound(EntityItemPointer entity, const Collision& collision) { + assert((bool)entity); + SharedSoundPointer collisionSound = entity->getCollisionSound(); if (!collisionSound) { return; } + bool success = false; + AACube minAACube = entity->getMinimumAACube(success); + if (!success) { + return; + } + float mass = entity->computeMass(); - const float COLLISION_PENETRATION_TO_VELOCITY = 50; // as a subsitute for RELATIVE entity->getVelocity() + const float COLLISION_PENETRATION_TO_VELOCITY = 50.0f; // as a subsitute for RELATIVE entity->getVelocity() // The collision.penetration is a pretty good indicator of changed velocity AFTER the initial contact, // but that first contact depends on exactly where we hit in the physics step. // We can get a more consistent initial-contact energy reading by using the changed velocity. // Note that velocityChange is not a good indicator for continuing collisions, because it does not distinguish // between bounce and sliding along a surface. - const float linearVelocity = (collision.type == CONTACT_EVENT_TYPE_START) ? - glm::length(collision.velocityChange) : - glm::length(collision.penetration) * COLLISION_PENETRATION_TO_VELOCITY; - const float energy = mass * linearVelocity * linearVelocity / 2.0f; - const glm::vec3 position = collision.contactPoint; + const float speedSquared = (collision.type == CONTACT_EVENT_TYPE_START) ? + glm::length2(collision.velocityChange) : + glm::length2(collision.penetration) * COLLISION_PENETRATION_TO_VELOCITY; + const float energy = mass * speedSquared / 2.0f; const float COLLISION_ENERGY_AT_FULL_VOLUME = (collision.type == CONTACT_EVENT_TYPE_START) ? 150.0f : 5.0f; const float COLLISION_MINIMUM_VOLUME = 0.005f; const float energyFactorOfFull = fmin(1.0f, energy / COLLISION_ENERGY_AT_FULL_VOLUME); @@ -1032,7 +1025,7 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT // Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2) const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f; const float stretchFactor = log(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); - AudioInjector::playSound(collisionSound, volume, stretchFactor, position); + AudioInjector::playSound(collisionSound, volume, stretchFactor, collision.contactPoint); } void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, @@ -1048,23 +1041,23 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons return; } - // See if we should play sounds EntityTreePointer entityTree = std::static_pointer_cast(_tree); const QUuid& myNodeID = DependencyManager::get()->getSessionUUID(); - playEntityCollisionSound(myNodeID, entityTree, idA, collision); - playEntityCollisionSound(myNodeID, entityTree, idB, collision); - // And now the entity scripts + // trigger scripted collision sounds and events for locally owned objects // BUG! scripts don't get the final COLLISION_EVENT_TYPE_END event in a timely manner because // by the time it gets here the object has been deactivated and local ownership is relenquished. - if (isCollisionOwner(myNodeID, entityTree, idA, collision)) { + EntityItemPointer entityA = entityTree->findEntityByEntityItemID(idA); + if ((bool)entityA && myNodeID == entityA->getSimulatorID()) { + playEntityCollisionSound(entityA, collision); emit collisionWithEntity(idA, idB, collision); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(idA, "collisionWithEntity", idB, collision); } } - - if (isCollisionOwner(myNodeID, entityTree, idB, collision)) { + EntityItemPointer entityB = entityTree->findEntityByEntityItemID(idB); + if ((bool)entityB && myNodeID == entityB->getSimulatorID()) { + playEntityCollisionSound(entityB, collision); emit collisionWithEntity(idB, idA, collision); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(idB, "collisionWithEntity", idA, collision); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 8c021ad184..a0673207f9 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -170,11 +170,9 @@ private: bool _wantScripts; QSharedPointer _entitiesScriptEngine; - bool isCollisionOwner(const QUuid& myNodeID, EntityTreePointer entityTree, - const EntityItemID& id, const Collision& collision); + //static bool isCollisionOwner(const QUuid& myNodeID, EntityTreePointer entityTree, const EntityItemID& id); - void playEntityCollisionSound(const QUuid& myNodeID, EntityTreePointer entityTree, - const EntityItemID& id, const Collision& collision); + static void playEntityCollisionSound(EntityItemPointer entity, const Collision& collision); bool _lastPointerEventValid; PointerEvent _lastPointerEvent;