Showing the changes to libraries/entities/src/EntityCollisionSystem.cpp (1 of 6 files). Show all
Unified · Split
| @@ -99,9 +99,6 @@ void EntityCollisionSystem::updateCollisionWithVoxels(EntityItem* entity) { · 98 unmodified lines | |||
| 99 | VoxelDetail* voxelDetails = NULL; | 99 | VoxelDetail* voxelDetails = NULL; |
| 100 | if (_voxels->findSpherePenetration(center, radius, collisionInfo._penetration, (void**)&voxelDetails)) { | 100 | if (_voxels->findSpherePenetration(center, radius, collisionInfo._penetration, (void**)&voxelDetails)) { |
| 101 | 101 | ||
| 102 | // let the Entities run their collision scripts if they have them | ||
| 103 | //entity->collisionWithVoxel(voxelDetails, collisionInfo._penetration); | ||
| 104 | |||
| 105 | // findSpherePenetration() only computes the penetration but we also want some other collision info | 102 | // findSpherePenetration() only computes the penetration but we also want some other collision info |
| 106 | // so we compute it ourselves here. Note that we must multiply scale by TREE_SCALE when feeding | 103 | // so we compute it ourselves here. Note that we must multiply scale by TREE_SCALE when feeding |
| 107 | // the results to systems outside of this octree reference frame. | 104 | // the results to systems outside of this octree reference frame. |
| @@ -112,9 +109,8 @@ void EntityCollisionSystem::updateCollisionWithVoxels(EntityItem* entity) { · 4 unmodified lines | |||
| 112 | // we must scale back down to the octree reference frame before updating the Entity properties | 109 | // we must scale back down to the octree reference frame before updating the Entity properties |
| 113 | collisionInfo._penetration /= (float)(TREE_SCALE); | 110 | collisionInfo._penetration /= (float)(TREE_SCALE); |
| 114 | collisionInfo._contactPoint /= (float)(TREE_SCALE); | 111 | collisionInfo._contactPoint /= (float)(TREE_SCALE); |
| 115 | entity->applyHardCollision(collisionInfo); | ||
| 116 | queueEntityPropertiesUpdate(entity); | ||
| 117 | 112 | ||
| 113 | applyHardCollision(entity, collisionInfo); | ||
| 118 | delete voxelDetails; // cleanup returned details | 114 | delete voxelDetails; // cleanup returned details |
| 119 | } | 115 | } |
| 120 | } | 116 | } |
| @@ -138,9 +134,6 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { · 17 unmodified lines | |||
| 138 | if (doCollisions) { | 134 | if (doCollisions) { |
| 139 | quint64 now = usecTimestampNow(); | 135 | quint64 now = usecTimestampNow(); |
| 140 | 136 | ||
| 141 | entityA->collisionWithEntity(entityB, penetration); | ||
| 142 | entityB->collisionWithEntity(entityA, penetration * -1.0f); // the penetration is reversed | ||
| 143 | |||
| 144 | CollisionInfo collision; | 137 | CollisionInfo collision; |
| 145 | collision._penetration = penetration; | 138 | collision._penetration = penetration; |
| 146 | // for now the contactPoint is the average between the the two paricle centers | 139 | // for now the contactPoint is the average between the the two paricle centers |
| @@ -188,9 +181,6 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { · 41 unmodified lines | |||
| 188 | 181 | ||
| 189 | void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { | 182 | void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { |
| 190 | 183 | ||
| 191 | // TODO: implement support for colliding with avatars | ||
| 192 | |||
| 193 | #if 0 | ||
| 194 | // Entities that are in hand, don't collide with avatars | 184 | // Entities that are in hand, don't collide with avatars |
| 195 | if (!_avatars) { | 185 | if (!_avatars) { |
| 196 | return; | 186 | return; |
| @@ -200,7 +190,6 @@ void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { · 3 unmodified lines | |||
| 200 | float radius = entity->getRadius() * (float)(TREE_SCALE); | 190 | float radius = entity->getRadius() * (float)(TREE_SCALE); |
| 201 | const float ELASTICITY = 0.9f; | 191 | const float ELASTICITY = 0.9f; |
| 202 | const float DAMPING = 0.1f; | 192 | const float DAMPING = 0.1f; |
| 203 | const float COLLISION_FREQUENCY = 0.5f; | ||
| 204 | glm::vec3 penetration; | 193 | glm::vec3 penetration; |
| 205 | 194 | ||
| 206 | _collisions.clear(); | 195 | _collisions.clear(); |
| @@ -227,22 +216,57 @@ void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) { · 20 unmodified lines | |||
| 227 | // only collide when Entity and collision point are moving toward each other | 216 | // only collide when Entity and collision point are moving toward each other |
| 228 | // (doing this prevents some "collision snagging" when Entity penetrates the object) | 217 | // (doing this prevents some "collision snagging" when Entity penetrates the object) |
| 229 | collision->_penetration /= (float)(TREE_SCALE); | 218 | collision->_penetration /= (float)(TREE_SCALE); |
| 230 | entity->applyHardCollision(*collision); | 219 | applyHardCollision(entity, *collision); |
| 231 | queueEntityPropertiesUpdate(entity); | ||
| 232 | } | 220 | } |
| 233 | } | 221 | } |
| 234 | } | 222 | } |
| 235 | } | 223 | } |
| 236 | |||
| 237 | #endif | ||
| 238 | } | 224 | } |
| 239 | 225 | ||
| 240 | void EntityCollisionSystem::queueEntityPropertiesUpdate(EntityItem* entity) { | 226 | void EntityCollisionSystem::applyHardCollision(EntityItem* entity, const CollisionInfo& collisionInfo) { |
| 241 | // queue the result for sending to the Entity server | 227 | // HALTING_* params are determined using expected acceleration of gravity over some timescale. |
| 228 | // This is a HACK for entities that bounce in a 1.0 gravitational field and should eventually be made more universal. | ||
| 229 | const float HALTING_ENTITY_PERIOD = 0.0167f; // ~1/60th of a second | ||
| 230 | const float HALTING_ENTITY_SPEED = 9.8 * HALTING_ENTITY_PERIOD / (float)(TREE_SCALE); | ||
| 231 | |||
| 232 | // | ||
| 233 | // Update the entity in response to a hard collision. Position will be reset exactly | ||
| 234 | // to outside the colliding surface. Velocity will be modified according to elasticity. | ||
| 235 | // | ||
| 236 | // if elasticity = 0.0, collision is inelastic (vel normal to collision is lost) | ||
| 237 | // if elasticity = 1.0, collision is 100% elastic. | ||
| 238 | // | ||
| 239 | glm::vec3 position = entity->getPosition(); | ||
| 240 | glm::vec3 velocity = entity->getVelocity(); | ||
| 241 | |||
| 242 | const float EPSILON = 0.0f; | ||
| 243 | glm::vec3 relativeVelocity = collisionInfo._addedVelocity - velocity; | ||
| 244 | float velocityDotPenetration = glm::dot(relativeVelocity, collisionInfo._penetration); | ||
| 245 | if (velocityDotPenetration < EPSILON) { | ||
| 246 | // entity is moving into collision surface | ||
| 247 | // | ||
| 248 | // TODO: do something smarter here by comparing the mass of the entity vs that of the other thing | ||
| 249 | // (other's mass could be stored in the Collision Info). The smaller mass should surrender more | ||
| 250 | // position offset and should slave more to the other's velocity in the static-friction case. | ||
| 251 | position -= collisionInfo._penetration; | ||
| 252 | |||
| 253 | if (glm::length(relativeVelocity) < HALTING_ENTITY_SPEED) { | ||
| 254 | // static friction kicks in and entities moves with colliding object | ||
| 255 | velocity = collisionInfo._addedVelocity; | ||
| 256 | } else { | ||
| 257 | glm::vec3 direction = glm::normalize(collisionInfo._penetration); | ||
| 258 | velocity += glm::dot(relativeVelocity, direction) * (1.0f + collisionInfo._elasticity) * direction; // dynamic reflection | ||
| 259 | velocity += glm::clamp(collisionInfo._damping, 0.0f, 1.0f) * (relativeVelocity - glm::dot(relativeVelocity, direction) * direction); // dynamic friction | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 242 | EntityItemProperties properties = entity->getProperties(); | 263 | EntityItemProperties properties = entity->getProperties(); |
| 243 | EntityItemID entityItemID(entity->getID()); | 264 | EntityItemID entityItemID(entity->getID()); |
| 244 | 265 | ||
| 245 | properties.setPosition(entity->getPosition() * (float)TREE_SCALE); | 266 | properties.setPosition(position * (float)TREE_SCALE); |
| 246 | properties.setVelocity(entity->getVelocity() * (float)TREE_SCALE); | 267 | properties.setVelocity(velocity * (float)TREE_SCALE); |
| 268 | properties.setLastEdited(usecTimestampNow()); | ||
| 269 | |||
| 270 | _entities->updateEntity(entityItemID, properties); | ||
| 247 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, entityItemID, properties); | 271 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, entityItemID, properties); |
| 248 | } | 272 | } |