History

collions with voxels and avatars

ZappoMan committed 12 years ago

Commit 4b52fdd1 parent 6b8c9bb6 files · +62 −96Browse files

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

Unified · Split

libraries/entities/src/EntityCollisionSystem.cpp+44−20
@@ -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 info102 // 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 properties109 // 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 details114 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 centers139 // 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
189void EntityCollisionSystem::updateCollisionWithAvatars(EntityItem* entity) {182void 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 avatars184 // 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 other216 // 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
240void EntityCollisionSystem::queueEntityPropertiesUpdate(EntityItem* entity) {226void EntityCollisionSystem::applyHardCollision(EntityItem* entity, const CollisionInfo& collisionInfo) {
241 // queue the result for sending to the Entity server227 // 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}