From 7a4f9cf722a118d914c813b5a8d37bb6269f4076 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 13 Dec 2013 10:23:37 -0800 Subject: [PATCH] particle to particle collisions --- libraries/octree/src/Octree.cpp | 2 +- libraries/octree/src/OctreeElement.cpp | 5 +++++ libraries/octree/src/OctreeElement.h | 2 ++ .../particles/src/ParticleCollisionSystem.cpp | 16 +++++++++++++++ .../particles/src/ParticleCollisionSystem.h | 1 + .../particles/src/ParticleTreeElement.cpp | 20 +++++++++++++++++++ libraries/particles/src/ParticleTreeElement.h | 3 ++- 7 files changed, 47 insertions(+), 2 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index baac0792b0..6e7193f397 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -599,7 +599,7 @@ bool findSpherePenetrationOp(OctreeElement* element, void* extraData) { } if (element->hasContent()) { glm::vec3 elementPenetration; - if (box.findSpherePenetration(args->center, args->radius, elementPenetration)) { + if (element->findSpherePenetration(args->center, args->radius, elementPenetration)) { args->penetration = addPenetrations(args->penetration, elementPenetration * (float)TREE_SCALE); args->found = true; args->penetratedElement = element; diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index b7a791991b..62561772bb 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -1285,6 +1285,11 @@ void OctreeElement::notifyUpdateHooks() { } } +bool OctreeElement::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const { + return _box.findSpherePenetration(center, radius, penetration); +} + + OctreeElement* OctreeElement::getOrCreateChildElementAt(float x, float y, float z, float s) { OctreeElement* child = NULL; // If the requested size is less than or equal to our scale, but greater than half our scale, then diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index cafe40c6cb..1b5b92cf2b 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -93,6 +93,8 @@ public: virtual bool deleteApproved() const { return true; } + virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; + // Base class methods you don't need to implement const unsigned char* getOctalCode() const { return (_octcodePointer) ? _octalCode.pointer : &_octalCode.buffer[0]; } OctreeElement* getChildAtIndex(int childIndex) const; diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 61960db168..764cbe3381 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -58,6 +58,7 @@ void ParticleCollisionSystem::update() { void ParticleCollisionSystem::checkParticle(Particle* particle) { updateCollisionWithVoxels(particle); + updateCollisionWithParticles(particle); } void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) { @@ -75,6 +76,21 @@ void ParticleCollisionSystem::updateCollisionWithVoxels(Particle* particle) { } } +void ParticleCollisionSystem::updateCollisionWithParticles(Particle* particle) { + glm::vec3 center = particle->getPosition() * (float)TREE_SCALE; + float radius = particle->getRadius() * (float)TREE_SCALE; + const float VOXEL_ELASTICITY = 1.4f; + const float VOXEL_DAMPING = 0.0; + const float VOXEL_COLLISION_FREQUENCY = 0.5f; + glm::vec3 penetration; + OctreeElement* penetratedElement; + if (_particles->findSpherePenetration(center, radius, penetration, &penetratedElement)) { + penetration /= (float)TREE_SCALE; + updateCollisionSound(particle, penetration, VOXEL_COLLISION_FREQUENCY); + applyHardCollision(particle, penetration, VOXEL_ELASTICITY, VOXEL_DAMPING); + } +} + void ParticleCollisionSystem::applyHardCollision(Particle* particle, const glm::vec3& penetration, float elasticity, float damping) { // diff --git a/libraries/particles/src/ParticleCollisionSystem.h b/libraries/particles/src/ParticleCollisionSystem.h index 4ec2ce738b..0daece8634 100644 --- a/libraries/particles/src/ParticleCollisionSystem.h +++ b/libraries/particles/src/ParticleCollisionSystem.h @@ -40,6 +40,7 @@ public: void update(); void checkParticle(Particle* particle); void updateCollisionWithVoxels(Particle* particle); + void updateCollisionWithParticles(Particle* particle); void applyHardCollision(Particle* particle, const glm::vec3& penetration, float elasticity, float damping); void updateCollisionSound(Particle* particle, const glm::vec3 &penetration, float frequency); diff --git a/libraries/particles/src/ParticleTreeElement.cpp b/libraries/particles/src/ParticleTreeElement.cpp index d98e0d2e0a..df234269d1 100644 --- a/libraries/particles/src/ParticleTreeElement.cpp +++ b/libraries/particles/src/ParticleTreeElement.cpp @@ -8,6 +8,8 @@ #include +#include + #include "ParticleTree.h" #include "ParticleTreeElement.h" @@ -84,6 +86,24 @@ void ParticleTreeElement::update(ParticleTreeUpdateArgs& args) { } } +bool ParticleTreeElement::findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const { + uint16_t numberOfParticles = _particles.size(); + for (uint16_t i = 0; i < numberOfParticles; i++) { + glm::vec3 particleCenter = _particles[i].getPosition(); + float particleRadius = _particles[i].getRadius(); + + // don't penetrate yourself + if (particleCenter == center && particleRadius == radius) { + return false; + } + + if (findSphereSpherePenetration(center, radius, particleCenter, particleRadius, penetration)) { + return true; + } + } + return false; +} + bool ParticleTreeElement::containsParticle(const Particle& particle) const { uint16_t numberOfParticles = _particles.size(); for (uint16_t i = 0; i < numberOfParticles; i++) { diff --git a/libraries/particles/src/ParticleTreeElement.h b/libraries/particles/src/ParticleTreeElement.h index d654bc80b3..cc58122515 100644 --- a/libraries/particles/src/ParticleTreeElement.h +++ b/libraries/particles/src/ParticleTreeElement.h @@ -70,9 +70,10 @@ public: /// where an element is not actually rendering all should render elements. If the isRendered() state doesn't match the /// shouldRender() state, the tree will remark elements as changed even in cases there the elements have not changed. virtual bool isRendered() const { return getShouldRender(); } - virtual bool deleteApproved() const { return !hasParticles(); } + virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration) const; + const std::vector& getParticles() const { return _particles; } std::vector& getParticles() { return _particles; } bool hasParticles() const { return _particles.size() > 0; }