History

handled multiple collisions correctly, and don't collide if fully enclosed

ZappoMan committed 12 years ago

Commit bbd476d1 parent 21b0e312 files · +80 −78Browse files

Showing the changes to libraries/entities/src/EntityCollisionSystem.cpp (1 of 2 files). Show all

Unified · Split

libraries/entities/src/EntityCollisionSystem.cpp+77−77
@@ -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 appart134 // 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 centers154 // 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 ratios167 // 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 position178 // unless the entity is configured to not be moved by collision, calculate it's new position
180 // and velocity and apply it179 // and velocity and apply it
181 if (wantToMoveA) {180 if (wantToMoveA) {
182 // handle Entity A181 // 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 position195 // unless the entity is configured to not be moved by collision, calculate it's new position
197 // and velocity and apply it196 // 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}