Showing the changes to libraries/entities/src/EntityCollisionSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -120,95 +120,95 @@ void EntityCollisionSystem::updateCollisionWithEntities(EntityItem* entityA) { · 119 unmodified lines | |||
| 120 | bool shapeCollisions = _entities->findShapeCollisions(&entityA->getCollisionShapeInMeters(), | 120 | bool shapeCollisions = _entities->findShapeCollisions(&entityA->getCollisionShapeInMeters(), |
| 121 | collisions, Octree::NoLock, &shapeCollisionsAccurate); | 121 | collisions, Octree::NoLock, &shapeCollisionsAccurate); |
| 122 | 122 | ||
| 123 | |||
| 123 | if (shapeCollisions) { | 124 | if (shapeCollisions) { |
| 124 | for(int i = 0; i < collisions.size(); i++) { | 125 | for(int i = 0; i < collisions.size(); i++) { |
| 126 | |||
| 125 | CollisionInfo* collision = collisions[i]; | 127 | CollisionInfo* collision = collisions[i]; |
| 126 | penetration = collision->_penetration; | 128 | penetration = collision->_penetration; |
| 127 | entityB = static_cast<EntityItem*>(collision->_extraData); | 129 | entityB = static_cast<EntityItem*>(collision->_extraData); |
| 128 | 130 | ||
| 129 | // TODO: how to handle multiple collisions? | 131 | // NOTE: 'penetration' is the depth that 'entityA' overlaps 'entityB'. It points from A into B. |
| 130 | break; | 132 | glm::vec3 penetrationInTreeUnits = penetration / (float)(TREE_SCALE); |
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | if (shapeCollisions) { | ||
| 135 | // NOTE: 'penetration' is the depth that 'entityA' overlaps 'entityB'. It points from A into B. | ||
| 136 | glm::vec3 penetrationInTreeUnits = penetration / (float)(TREE_SCALE); | ||
| 137 | 133 | ||
| 138 | // Even if the Entities overlap... when the Entities are already moving appart | 134 | // Even if the Entities overlap... when the Entities are already moving appart |
| 139 | // we don't want to count this as a collision. | 135 | // we don't want to count this as a collision. |
| 140 | glm::vec3 relativeVelocity = entityA->getVelocity() - entityB->getVelocity(); | 136 | glm::vec3 relativeVelocity = entityA->getVelocity() - entityB->getVelocity(); |
| 137 | |||
| 138 | bool fullyEnclosedCollision = glm::length(penetrationInTreeUnits) > entityA->getLargestDimension(); | ||
| 141 | 139 | ||
| 142 | bool wantToMoveA = entityA->getCollisionsWillMove(); | 140 | bool wantToMoveA = entityA->getCollisionsWillMove(); |
| 143 | bool wantToMoveB = entityB->getCollisionsWillMove(); | 141 | bool wantToMoveB = entityB->getCollisionsWillMove(); |
| 144 | bool movingTowardEachOther = glm::dot(relativeVelocity, penetrationInTreeUnits) > 0.0f; | 142 | bool movingTowardEachOther = glm::dot(relativeVelocity, penetrationInTreeUnits) > 0.0f; |
| 145 | |||
| 146 | // only do collisions if the entities are moving toward each other and one or the other | ||
| 147 | // of the entities are movable from collisions | ||
| 148 | bool doCollisions = movingTowardEachOther && (wantToMoveA || wantToMoveB); | ||
| 149 | 143 | ||
| 150 | if (doCollisions) { | 144 | // only do collisions if the entities are moving toward each other and one or the other |
| 151 | quint64 now = usecTimestampNow(); | 145 | // of the entities are movable from collisions |
| 146 | bool doCollisions = !fullyEnclosedCollision && movingTowardEachOther && (wantToMoveA || wantToMoveB); | ||
| 147 | |||
| 148 | if (doCollisions) { | ||
| 149 | |||
| 150 | quint64 now = usecTimestampNow(); | ||
| 152 | 151 | ||
| 153 | CollisionInfo collision; | 152 | CollisionInfo collision; |
| 154 | collision._penetration = penetration; | 153 | collision._penetration = penetration; |
| 155 | // for now the contactPoint is the average between the the two paricle centers | 154 | // for now the contactPoint is the average between the the two paricle centers |
| 156 | collision._contactPoint = (0.5f * (float)TREE_SCALE) * (entityA->getPosition() + entityB->getPosition()); | 155 | collision._contactPoint = (0.5f * (float)TREE_SCALE) * (entityA->getPosition() + entityB->getPosition()); |
| 157 | emitGlobalEntityCollisionWithEntity(entityA, entityB, collision); | 156 | emitGlobalEntityCollisionWithEntity(entityA, entityB, collision); |
| 158 | 157 | ||
| 159 | glm::vec3 axis = glm::normalize(penetration); | 158 | glm::vec3 axis = glm::normalize(penetration); |
| 160 | glm::vec3 axialVelocity = glm::dot(relativeVelocity, axis) * axis; | 159 | glm::vec3 axialVelocity = glm::dot(relativeVelocity, axis) * axis; |
| 161 | 160 | ||
| 162 | float massA = entityA->getMass(); | 161 | float massA = entityA->getMass(); |
| 163 | float massB = entityB->getMass(); | 162 | float massB = entityB->getMass(); |
| 164 | float totalMass = massA + massB; | 163 | float totalMass = massA + massB; |
| 165 | float massRatioA = (2.0f * massB / totalMass); | 164 | float massRatioA = (2.0f * massB / totalMass); |
| 166 | float massRatioB = (2.0f * massA / totalMass); | 165 | float massRatioB = (2.0f * massA / totalMass); |
| 167 | 166 | ||
| 168 | // in the event that one of our entities is non-moving, then fix up these ratios | 167 | // in the event that one of our entities is non-moving, then fix up these ratios |
| 169 | if (wantToMoveA && !wantToMoveB) { | 168 | if (wantToMoveA && !wantToMoveB) { |
| 170 | massRatioA = 2.0f; | 169 | massRatioA = 2.0f; |
| 171 | massRatioB = 0.0f; | 170 | massRatioB = 0.0f; |
| 172 | } | 171 | } |
| 173 | 172 | ||
| 174 | if (!wantToMoveA && wantToMoveB) { | 173 | if (!wantToMoveA && wantToMoveB) { |
| 175 | massRatioA = 0.0f; | 174 | massRatioA = 0.0f; |
| 176 | massRatioB = 2.0f; | 175 | massRatioB = 2.0f; |
| 177 | } | 176 | } |
| 178 | 177 | ||
| 179 | // unless the entity is configured to not be moved by collision, calculate it's new position | 178 | // unless the entity is configured to not be moved by collision, calculate it's new position |
| 180 | // and velocity and apply it | 179 | // and velocity and apply it |
| 181 | if (wantToMoveA) { | 180 | if (wantToMoveA) { |
| 182 | // handle Entity A | 181 | // handle Entity A |
| 183 | glm::vec3 newVelocityA = entityA->getVelocity() - axialVelocity * massRatioA; | 182 | glm::vec3 newVelocityA = entityA->getVelocity() - axialVelocity * massRatioA; |
| 184 | glm::vec3 newPositionA = entityA->getPosition() - 0.5f * penetrationInTreeUnits; | 183 | glm::vec3 newPositionA = entityA->getPosition() - 0.5f * penetrationInTreeUnits; |
| 185 | 184 | ||
| 186 | EntityItemProperties propertiesA = entityA->getProperties(); | 185 | EntityItemProperties propertiesA = entityA->getProperties(); |
| 187 | EntityItemID idA(entityA->getID()); | 186 | EntityItemID idA(entityA->getID()); |
| 188 | propertiesA.setVelocity(newVelocityA * (float)TREE_SCALE); | 187 | propertiesA.setVelocity(newVelocityA * (float)TREE_SCALE); |
| 189 | propertiesA.setPosition(newPositionA * (float)TREE_SCALE); | 188 | propertiesA.setPosition(newPositionA * (float)TREE_SCALE); |
| 190 | propertiesA.setLastEdited(now); | 189 | propertiesA.setLastEdited(now); |
| 191 | 190 | ||
| 192 | _entities->updateEntity(idA, propertiesA); | 191 | _entities->updateEntity(idA, propertiesA); |
| 193 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idA, propertiesA); | 192 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idA, propertiesA); |
| 194 | } | 193 | } |
| 195 | 194 | ||
| 196 | // unless the entity is configured to not be moved by collision, calculate it's new position | 195 | // unless the entity is configured to not be moved by collision, calculate it's new position |
| 197 | // and velocity and apply it | 196 | // and velocity and apply it |
| 198 | if (wantToMoveB) { | 197 | if (wantToMoveB) { |
| 199 | glm::vec3 newVelocityB = entityB->getVelocity() + axialVelocity * massRatioB; | 198 | glm::vec3 newVelocityB = entityB->getVelocity() + axialVelocity * massRatioB; |
| 200 | glm::vec3 newPositionB = entityB->getPosition() + 0.5f * penetrationInTreeUnits; | 199 | glm::vec3 newPositionB = entityB->getPosition() + 0.5f * penetrationInTreeUnits; |
| 201 | 200 | ||
| 202 | EntityItemProperties propertiesB = entityB->getProperties(); | 201 | EntityItemProperties propertiesB = entityB->getProperties(); |
| 203 | 202 | ||
| 204 | EntityItemID idB(entityB->getID()); | 203 | EntityItemID idB(entityB->getID()); |
| 205 | propertiesB.setVelocity(newVelocityB * (float)TREE_SCALE); | 204 | propertiesB.setVelocity(newVelocityB * (float)TREE_SCALE); |
| 206 | propertiesB.setPosition(newPositionB * (float)TREE_SCALE); | 205 | propertiesB.setPosition(newPositionB * (float)TREE_SCALE); |
| 207 | propertiesB.setLastEdited(now); | 206 | propertiesB.setLastEdited(now); |
| 208 | 207 | ||
| 209 | _entities->updateEntity(idB, propertiesB); | 208 | _entities->updateEntity(idB, propertiesB); |
| 210 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idB, propertiesB); | 209 | _packetSender->queueEditEntityMessage(PacketTypeEntityAddOrEdit, idB, propertiesB); |
| 211 | } | 210 | } |
| 211 | } | ||
| 212 | } | 212 | } |
| 213 | } | 213 | } |
| 214 | } | 214 | } |