mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-15 12:56:40 +02:00
Merge pull request #14592 from huffman/fix/myavatar-collisions
Fix MyAvatar::collisionWithEntity not firing
This commit is contained in:
commit
2c247bc3df
1 changed files with 40 additions and 36 deletions
|
@ -28,7 +28,6 @@
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <shared/QtHelpers.h>
|
#include <shared/QtHelpers.h>
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
@ -529,6 +528,7 @@ void AvatarManager::handleChangedMotionStates(const VectorOfMotionStates& motion
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents) {
|
void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents) {
|
||||||
|
bool playedCollisionSound { false };
|
||||||
for (Collision collision : collisionEvents) {
|
for (Collision collision : collisionEvents) {
|
||||||
// TODO: The plan is to handle MOTIONSTATE_TYPE_AVATAR, and then MOTIONSTATE_TYPE_MYAVATAR. As it is, other
|
// TODO: The plan is to handle MOTIONSTATE_TYPE_AVATAR, and then MOTIONSTATE_TYPE_MYAVATAR. As it is, other
|
||||||
// people's avatars will have an id that doesn't match any entities, and one's own avatar will have
|
// people's avatars will have an id that doesn't match any entities, and one's own avatar will have
|
||||||
|
@ -536,43 +536,47 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents
|
||||||
// my avatar. (Other user machines will make a similar analysis and inject sound for their collisions.)
|
// my avatar. (Other user machines will make a similar analysis and inject sound for their collisions.)
|
||||||
if (collision.idA.isNull() || collision.idB.isNull()) {
|
if (collision.idA.isNull() || collision.idB.isNull()) {
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
auto collisionSound = myAvatar->getCollisionSound();
|
myAvatar->collisionWithEntity(collision);
|
||||||
if (collisionSound) {
|
|
||||||
const auto characterController = myAvatar->getCharacterController();
|
|
||||||
const float avatarVelocityChange = (characterController ? glm::length(characterController->getVelocityChange()) : 0.0f);
|
|
||||||
const float velocityChange = glm::length(collision.velocityChange) + avatarVelocityChange;
|
|
||||||
const float MIN_AVATAR_COLLISION_ACCELERATION = 2.4f; // walking speed
|
|
||||||
const bool isSound = (collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
|
|
||||||
|
|
||||||
if (!isSound) {
|
if (!playedCollisionSound) {
|
||||||
return; // No sense iterating for others. We only have one avatar.
|
playedCollisionSound = true;
|
||||||
|
auto collisionSound = myAvatar->getCollisionSound();
|
||||||
|
if (collisionSound) {
|
||||||
|
const auto characterController = myAvatar->getCharacterController();
|
||||||
|
const float avatarVelocityChange =
|
||||||
|
(characterController ? glm::length(characterController->getVelocityChange()) : 0.0f);
|
||||||
|
const float velocityChange = glm::length(collision.velocityChange) + avatarVelocityChange;
|
||||||
|
const float MIN_AVATAR_COLLISION_ACCELERATION = 2.4f; // walking speed
|
||||||
|
const bool isSound =
|
||||||
|
(collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
|
||||||
|
|
||||||
|
if (!isSound) {
|
||||||
|
return; // No sense iterating for others. We only have one avatar.
|
||||||
|
}
|
||||||
|
// Your avatar sound is personal to you, so let's say the "mass" part of the kinetic energy is already accounted for.
|
||||||
|
const float energy = velocityChange * velocityChange;
|
||||||
|
const float COLLISION_ENERGY_AT_FULL_VOLUME = 10.0f;
|
||||||
|
const float energyFactorOfFull = fmin(1.0f, energy / COLLISION_ENERGY_AT_FULL_VOLUME);
|
||||||
|
|
||||||
|
// For general entity collisionSoundURL, playSound supports changing the pitch for the sound based on the size of the object,
|
||||||
|
// but most avatars are roughly the same size, so let's not be so fancy yet.
|
||||||
|
const float AVATAR_STRETCH_FACTOR = 1.0f;
|
||||||
|
|
||||||
|
_collisionInjectors.remove_if(
|
||||||
|
[](const AudioInjectorPointer& injector) { return !injector || injector->isFinished(); });
|
||||||
|
|
||||||
|
static const int MAX_INJECTOR_COUNT = 3;
|
||||||
|
if (_collisionInjectors.size() < MAX_INJECTOR_COUNT) {
|
||||||
|
AudioInjectorOptions options;
|
||||||
|
options.stereo = collisionSound->isStereo();
|
||||||
|
options.position = myAvatar->getWorldPosition();
|
||||||
|
options.volume = energyFactorOfFull;
|
||||||
|
options.pitch = 1.0f / AVATAR_STRETCH_FACTOR;
|
||||||
|
|
||||||
|
auto injector = AudioInjector::playSoundAndDelete(collisionSound, options);
|
||||||
|
_collisionInjectors.emplace_back(injector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Your avatar sound is personal to you, so let's say the "mass" part of the kinetic energy is already accounted for.
|
|
||||||
const float energy = velocityChange * velocityChange;
|
|
||||||
const float COLLISION_ENERGY_AT_FULL_VOLUME = 10.0f;
|
|
||||||
const float energyFactorOfFull = fmin(1.0f, energy / COLLISION_ENERGY_AT_FULL_VOLUME);
|
|
||||||
|
|
||||||
// For general entity collisionSoundURL, playSound supports changing the pitch for the sound based on the size of the object,
|
|
||||||
// but most avatars are roughly the same size, so let's not be so fancy yet.
|
|
||||||
const float AVATAR_STRETCH_FACTOR = 1.0f;
|
|
||||||
|
|
||||||
_collisionInjectors.remove_if([](const AudioInjectorPointer& injector) {
|
|
||||||
return !injector || injector->isFinished();
|
|
||||||
});
|
|
||||||
|
|
||||||
static const int MAX_INJECTOR_COUNT = 3;
|
|
||||||
if (_collisionInjectors.size() < MAX_INJECTOR_COUNT) {
|
|
||||||
AudioInjectorOptions options;
|
|
||||||
options.stereo = collisionSound->isStereo();
|
|
||||||
options.position = myAvatar->getWorldPosition();
|
|
||||||
options.volume = energyFactorOfFull;
|
|
||||||
options.pitch = 1.0f / AVATAR_STRETCH_FACTOR;
|
|
||||||
|
|
||||||
auto injector = AudioInjector::playSoundAndDelete(collisionSound, options);
|
|
||||||
_collisionInjectors.emplace_back(injector);
|
|
||||||
}
|
|
||||||
myAvatar->collisionWithEntity(collision);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue