Skip to content

Commit

Permalink
improve bounding box based collision detection #92
Browse files Browse the repository at this point in the history
good result, if only a single set of colliding particles exists between two particle groups
  • Loading branch information
kateyy committed Feb 9, 2014
1 parent 01bf042 commit 278dd1d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
31 changes: 24 additions & 7 deletions src/particles/particlecollision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,16 @@ void ParticleCollision::performCheck()
auto lastLeftHand = --particleGroups.cend();
auto lastRightHand = particleGroups.cend();

glowutils::AxisAlignedBoundingBox intersectVolume;
const glm::vec3 & i_llf = intersectVolume.llf(); // to shorten the lua function call
const glm::vec3 & i_urb = intersectVolume.urb();
glowutils::AxisAlignedBoundingBox intersectVolume; // the intersection volume of the particle group bounding boxes

glowutils::AxisAlignedBoundingBox leftSubbox; // the subvolume of the left hand group that actually contains particles
glowutils::AxisAlignedBoundingBox rightSubbox;
std::vector<glm::vec3> leftParticleSubset;
std::vector<glm::vec3> rightParticleSubset;

IntersectionBox commonSubbox;
glm::vec3 & i_llf = commonSubbox.llf;
glm::vec3 & i_urb = commonSubbox.urb;

debug_intersectionBoxes.clear();

Expand All @@ -45,12 +52,22 @@ void ParticleCollision::performCheck()
auto rightHand = leftHand;
++rightHand;
for (; rightHand != lastRightHand; ++rightHand) {
if (checkBoundingBoxCollision(leftHand->second->boundingBox(), rightHand->second->boundingBox(), &intersectVolume)) {

m_lua->call("particleBboxCollision", leftHand->first, rightHand->first, i_llf.x, i_llf.y, i_llf.z, i_urb.x, i_urb.y, i_urb.z);
if (!checkBoundingBoxCollision(leftHand->second->boundingBox(), rightHand->second->boundingBox(), &intersectVolume))
continue; // not interested if the groups don't intersect

leftHand->second->particlesInVolume(intersectVolume, leftParticleSubset, leftSubbox);
rightHand->second->particlesInVolume(intersectVolume, rightParticleSubset, rightSubbox);

if (leftParticleSubset.empty() || rightParticleSubset.empty())
continue; // particles of one box flow into the other, where the other doesn't have particles

commonSubbox.llf = glm::max(leftSubbox.llf(), rightSubbox.llf());
commonSubbox.urb = glm::min(leftSubbox.urb(), rightSubbox.urb());

debug_intersectionBoxes.push_back(IntersectionBox(i_llf, i_urb));
}
debug_intersectionBoxes.push_back(commonSubbox);

m_lua->call("particleBboxCollision", leftHand->first, rightHand->first, i_llf.x, i_llf.y, i_llf.z, i_urb.x, i_urb.y, i_urb.z);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/particles/particlecollision.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class ParticleCollision
LuaWrapper * m_lua;

struct IntersectionBox {
IntersectionBox() = default;
IntersectionBox(const glm::vec3 & llf, const glm::vec3 & urb);
glm::vec3 llf;
glm::vec3 urb;
Expand Down
28 changes: 27 additions & 1 deletion src/particles/particlegroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ glm::vec3 vec3(const physx::PxVec3 & vec3)
}

void ParticleGroup::updateVisuals()
{
{
PxParticleReadData * readData = m_particleSystem->lockParticleReadData();
assert(readData);

Expand Down Expand Up @@ -309,3 +309,29 @@ void ParticleGroup::setUseGpuParticles(const bool enable)

m_scene->addActor(*m_particleSystem);
}

void ParticleGroup::particlesInVolume(const glowutils::AxisAlignedBoundingBox & boundingBox, std::vector<glm::vec3> & particles, glowutils::AxisAlignedBoundingBox & subbox)
{
PxParticleReadData * readData = m_particleSystem->lockParticleReadData();
assert(readData);


PxStrideIterator<const PxVec3> pxPositionIt = readData->positionBuffer;
PxStrideIterator<const PxParticleFlags> pxFlagIt = readData->flagsBuffer;

subbox = glowutils::AxisAlignedBoundingBox();

for (unsigned i = 0; i < readData->validParticleRange; ++i, ++pxPositionIt, ++pxFlagIt) {
assert(pxPositionIt.ptr());
if (!(*pxFlagIt & PxParticleFlag::eVALID))
continue;
const physx::PxVec3 & pxPosition = *pxPositionIt;
const glm::vec3 pos = glm::vec3(pxPosition.x, pxPosition.y, pxPosition.z);
if (!boundingBox.inside(pos))
continue;
particles.push_back(pos);
subbox.extend(pos);
}

readData->unlock();
}
5 changes: 5 additions & 0 deletions src/particles/particlegroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ class ParticleGroup
void emit(const float ratio, const glm::vec3 & position, const glm::vec3 & direction);
void stopEmit();

/** fill particles with all my particles which have there center in the specified boundingbox.
* @param subbox is the axis aligned bounding box of the particles that are inside the input bounding box.
* This should only be called while the physics scene simulation is not running! */
void particlesInVolume(const glowutils::AxisAlignedBoundingBox & boundingBox, std::vector<glm::vec3> & particles, glowutils::AxisAlignedBoundingBox & subbox);

/** Subscribed to World to receive time delta for timed emit of particles. (Observer pattern) */
void updateEmitting(const double & delta);
/** Subscribed to World to update particle visuals. (Observer pattern) */
Expand Down

0 comments on commit 278dd1d

Please sign in to comment.