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