This commit is contained in:
Philip Rosedale 2013-12-13 10:38:21 -08:00
commit 09258cb17b
7 changed files with 47 additions and 2 deletions

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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) {
//

View file

@ -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);

View file

@ -8,6 +8,8 @@
#include <QtCore/QDebug>
#include <GeometryUtil.h>
#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++) {

View file

@ -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<Particle>& getParticles() const { return _particles; }
std::vector<Particle>& getParticles() { return _particles; }
bool hasParticles() const { return _particles.size() > 0; }