Showing the changes to libraries/entities/src/EntityCollisionSystem.cpp (1 of 3 files). Show all
Unified · Split
| @@ -93,7 +93,6 @@ void EntityCollisionSystem::updateCollisionWithVoxels(EntityItem* entity) { · 92 unmodified lines | |||
| 93 | float radius = entity->getRadius() * (float)(TREE_SCALE); | 93 | float radius = entity->getRadius() * (float)(TREE_SCALE); |
| 94 | const float ELASTICITY = 0.4f; | 94 | const float ELASTICITY = 0.4f; |
| 95 | const float DAMPING = 0.05f; | 95 | const float DAMPING = 0.05f; |
| 96 | const float COLLISION_FREQUENCY = 0.5f; | ||
| 97 | CollisionInfo collisionInfo; | 96 | CollisionInfo collisionInfo; |
| 98 | collisionInfo._damping = DAMPING; | 97 | collisionInfo._damping = DAMPING; |
| 99 | collisionInfo._elasticity = ELASTICITY; | 98 | collisionInfo._elasticity = ELASTICITY; |
| @@ -106,7 +105,6 @@ void EntityCollisionSystem::updateCollisionWithVoxels(EntityItem* entity) { · 6 unmodified lines | |||
| 106 | // findSpherePenetration() only computes the penetration but we also want some other collision info | 105 | // findSpherePenetration() only computes the penetration but we also want some other collision info |
| 107 | // so we compute it ourselves here. Note that we must multiply scale by TREE_SCALE when feeding | 106 | // so we compute it ourselves here. Note that we must multiply scale by TREE_SCALE when feeding |
| 108 | // the results to systems outside of this octree reference frame. | 107 | // the results to systems outside of this octree reference frame. |
| 109 | updateCollisionSound(entity, collisionInfo._penetration, COLLISION_FREQUENCY); | ||
| 110 | collisionInfo._contactPoint = (float)TREE_SCALE * (entity->getPosition() + entity->getRadius() * glm::normalize(collisionInfo._penetration)); | 108 | collisionInfo._contactPoint = (float)TREE_SCALE * (entity->getPosition() + entity->getRadius() * glm::normalize(collisionInfo._penetration)); |
| 111 | // let the global script run their collision scripts for Entities if they have them | 109 | // let the global script run their collision scripts for Entities if they have them |
| 112 | emitGlobalEntityCollisionWithVoxel(entity, voxelDetails, collisionInfo); | 110 | emitGlobalEntityCollisionWithVoxel(entity, voxelDetails, collisionInfo); |
| @@ -124,9 +122,6 @@ void EntityCollisionSystem::updateCollisionWithVoxels(EntityItem* entity) { · 11 unmodified lines | |||
| 124 | void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { | 122 | void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { |
| 125 | glm::vec3 center = entityA->getPosition() * (float)(TREE_SCALE); | 123 | glm::vec3 center = entityA->getPosition() * (float)(TREE_SCALE); |
| 126 | float radius = entityA->getRadius() * (float)(TREE_SCALE); | 124 | float radius = entityA->getRadius() * (float)(TREE_SCALE); |
| 127 | //const float ELASTICITY = 0.4f; | ||
| 128 | //const float DAMPING = 0.0f; | ||
| 129 | const float COLLISION_FREQUENCY = 0.5f; | ||
| 130 | glm::vec3 penetration; | 125 | glm::vec3 penetration; |
| 131 | EntityItem* entityB; | 126 | EntityItem* entityB; |
| 132 | if (_entities->findSpherePenetration(center, radius, penetration, (void**)&entityB, Octree::NoLock)) { | 127 | if (_entities->findSpherePenetration(center, radius, penetration, (void**)&entityB, Octree::NoLock)) { |
| @@ -141,6 +136,8 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { · 8 unmodified lines | |||
| 141 | bool doCollisions = true; | 136 | bool doCollisions = true; |
| 142 | 137 | ||
| 143 | if (doCollisions) { | 138 | if (doCollisions) { |
| 139 | quint64 now = usecTimestampNow(); | ||
| 140 | |||
| 144 | entityA->collisionWithEntity(entityB, penetration); | 141 | entityA->collisionWithEntity(entityB, penetration); |
| 145 | entityB->collisionWithEntity(entityA, penetration * -1.0f); // the penetration is reversed | 142 | entityB->collisionWithEntity(entityA, penetration * -1.0f); // the penetration is reversed |
| 146 | 143 | ||
| @@ -165,7 +162,8 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { · 18 unmodified lines | |||
| 165 | EntityItemID idA(entityA->getID()); | 162 | EntityItemID idA(entityA->getID()); |
| 166 | propertiesA.setVelocity(newVelocityA * (float)TREE_SCALE); | 163 | propertiesA.setVelocity(newVelocityA * (float)TREE_SCALE); |
| 167 | propertiesA.setPosition(newPositionA * (float)TREE_SCALE); | 164 | propertiesA.setPosition(newPositionA * (float)TREE_SCALE); |
| 168 | 165 | propertiesA.setLastEdited(now); | |
| 166 | |||
| 169 | _entities->updateEntity(idA, propertiesA); | 167 | _entities->updateEntity(idA, propertiesA); |
| 170 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idA, propertiesA); | 168 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idA, propertiesA); |
| 171 | 169 | ||
| @@ -177,15 +175,13 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { · 5 unmodified lines | |||
| 177 | EntityItemID idB(entityB->getID()); | 175 | EntityItemID idB(entityB->getID()); |
| 178 | propertiesB.setVelocity(newVelocityB * (float)TREE_SCALE); | 176 | propertiesB.setVelocity(newVelocityB * (float)TREE_SCALE); |
| 179 | propertiesB.setPosition(newPositionB * (float)TREE_SCALE); | 177 | propertiesB.setPosition(newPositionB * (float)TREE_SCALE); |
| 178 | propertiesB.setLastEdited(now); | ||
| 180 | 179 | ||
| 181 | _entities->updateEntity(idB, propertiesB); | 180 | _entities->updateEntity(idB, propertiesB); |
| 182 | |||
| 183 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idB, propertiesB); | 181 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idB, propertiesB); |
| 184 | 182 | ||
| 185 | // TODO: Do we need this? | 183 | // TODO: Do we need this? |
| 186 | //_packetSender->releaseQueuedMessages(); | 184 | //_packetSender->releaseQueuedMessages(); |
| 187 | |||
| 188 | //updateCollisionSound(entityA, penetration, COLLISION_FREQUENCY); | ||
| 189 | } | 185 | } |
| 190 | } | 186 | } |
| 191 | } | 187 | } |
| @@ -230,7 +226,6 @@ void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { · 38 unmodified lines | |||
| 230 | if (glm::dot(relativeVelocity, collision->_penetration) <= 0.f) { | 226 | if (glm::dot(relativeVelocity, collision->_penetration) <= 0.f) { |
| 231 | // only collide when Entity and collision point are moving toward each other | 227 | // only collide when Entity and collision point are moving toward each other |
| 232 | // (doing this prevents some "collision snagging" when Entity penetrates the object) | 228 | // (doing this prevents some "collision snagging" when Entity penetrates the object) |
| 233 | updateCollisionSound(entity, collision->_penetration, COLLISION_FREQUENCY); | ||
| 234 | collision->_penetration /= (float)(TREE_SCALE); | 229 | collision->_penetration /= (float)(TREE_SCALE); |
| 235 | entity->applyHardCollision(*collision); | 230 | entity->applyHardCollision(*collision); |
| 236 | queueEntityPropertiesUpdate(entity); | 231 | queueEntityPropertiesUpdate(entity); |
| @@ -251,42 +246,3 @@ void EntityCollisionSystem::queueEntityPropertiesUpdate(EntityItem* entity) { · 14 unmodified lines | |||
| 251 | properties.setVelocity(entity->getVelocity() * (float)TREE_SCALE); | 246 | properties.setVelocity(entity->getVelocity() * (float)TREE_SCALE); |
| 252 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, entityItemID, properties); | 247 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, entityItemID, properties); |
| 253 | } | 248 | } |
| 254 | |||
| 255 | |||
| 256 | void EntityCollisionSystem::updateCollisionSound(EntityItem* Entity, const glm::vec3 &penetration, float frequency) { | ||
| 257 | |||
| 258 | // consider whether to have the collision make a sound | ||
| 259 | const float AUDIBLE_COLLISION_THRESHOLD = 0.3f; | ||
| 260 | const float COLLISION_LOUDNESS = 1.f; | ||
| 261 | const float DURATION_SCALING = 0.004f; | ||
| 262 | const float NOISE_SCALING = 0.1f; | ||
| 263 | glm::vec3 velocity = Entity->getVelocity() * (float)(TREE_SCALE); | ||
| 264 | |||
| 265 | /* | ||
| 266 | // how do we want to handle this?? | ||
| 267 | // | ||
| 268 | glm::vec3 gravity = Entity->getGravity() * (float)(TREE_SCALE); | ||
| 269 | |||
| 270 | if (glm::length(gravity) > EPSILON) { | ||
| 271 | // If gravity is on, remove the effect of gravity on velocity for this | ||
| 272 | // frame, so that we are not constantly colliding with the surface | ||
| 273 | velocity -= _scale * glm::length(gravity) * GRAVITY_EARTH * deltaTime * glm::normalize(gravity); | ||
| 274 | } | ||
| 275 | */ | ||
| 276 | float normalSpeed = glm::dot(velocity, glm::normalize(penetration)); | ||
| 277 | // NOTE: it is possible for normalSpeed to be NaN at this point | ||
| 278 | // (sometimes the average penetration of a bunch of voxels is a zero length vector which cannot be normalized) | ||
| 279 | // however the check below will fail (NaN comparisons always fail) and everything will be fine. | ||
| 280 | |||
| 281 | if (normalSpeed > AUDIBLE_COLLISION_THRESHOLD) { | ||
| 282 | // Volume is proportional to collision velocity | ||
| 283 | // Base frequency is modified upward by the angle of the collision | ||
| 284 | // Noise is a function of the angle of collision | ||
| 285 | // Duration of the sound is a function of both base frequency and velocity of impact | ||
| 286 | float tangentialSpeed = glm::length(velocity) - normalSpeed; | ||
| 287 | _audio->startCollisionSound( std::min(COLLISION_LOUDNESS * normalSpeed, 1.f), | ||
| 288 | frequency * (1.f + tangentialSpeed / normalSpeed), | ||
| 289 | std::min(tangentialSpeed / normalSpeed * NOISE_SCALING, 1.f), | ||
| 290 | 1.f - DURATION_SCALING * powf(frequency, 0.5f) / normalSpeed, false); | ||
| 291 | } | ||
| 292 | } | ||