Fix issue #1684 : particles collide against avatars again.

This a quick and dirty fix to resurrect particle-avatar collisions.
We rebuild and pass a list of AvatarData* to the
ParticleCollisionManager every call to update().
This commit is contained in:
Andrew Meadows 2014-01-27 18:01:53 -08:00
parent 2fa3fc523d
commit 2b5675b077
5 changed files with 31 additions and 48 deletions

View file

@ -1796,7 +1796,7 @@ void Application::init() {
_metavoxels.init();
_particleCollisionSystem.init(&_particleEditSender, _particles.getTree(), _voxels.getTree(), &_audio, &_myAvatar);
_particleCollisionSystem.init(&_particleEditSender, _particles.getTree(), _voxels.getTree(), &_audio);
_palette.init(_glWidget->width(), _glWidget->height());
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelAddMode), 0, 0);
@ -2310,7 +2310,12 @@ void Application::update(float deltaTime) {
updateCursor(deltaTime); // Handle cursor updates
_particles.update(); // update the particles...
_particleCollisionSystem.update(); // handle collisions for the particles...
// collide the particles...
QVector<AvatarData*> avatars;
avatars.push_back(&_myAvatar);
_avatarManager.getAvatarBasePointers(avatars);
_particleCollisionSystem.update(avatars);
}
void Application::updateAvatar(float deltaTime) {

View file

@ -230,4 +230,11 @@ void AvatarManager::clearHash() {
while (removeAvatar != _avatarHash.end()) {
removeAvatar = removeAvatarAtHashIterator(removeAvatar);
}
}
}
void AvatarManager::getAvatarBasePointers(QVector<AvatarData*>& avatars) {
AvatarHash::iterator avatarItr = _avatarHash.begin();
while (avatarItr != _avatarHash.end()) {
avatars.push_back( static_cast<AvatarData*>(avatarItr.value().data()) );
}
}

View file

@ -36,6 +36,8 @@ public:
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
void clearHash();
void getAvatarBasePointers(QVector<AvatarData*>& avatars);
public slots:
void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList);

View file

@ -20,17 +20,16 @@
#include "ParticleTree.h"
ParticleCollisionSystem::ParticleCollisionSystem(ParticleEditPacketSender* packetSender,
ParticleTree* particles, VoxelTree* voxels, AbstractAudioInterface* audio, AvatarData* selfAvatar) {
init(packetSender, particles, voxels, audio, selfAvatar);
ParticleTree* particles, VoxelTree* voxels, AbstractAudioInterface* audio) {
init(packetSender, particles, voxels, audio);
}
void ParticleCollisionSystem::init(ParticleEditPacketSender* packetSender,
ParticleTree* particles, VoxelTree* voxels, AbstractAudioInterface* audio, AvatarData* selfAvatar) {
ParticleTree* particles, VoxelTree* voxels, AbstractAudioInterface* audio) {
_packetSender = packetSender;
_particles = particles;
_voxels = voxels;
_audio = audio;
_selfAvatar = selfAvatar;
}
ParticleCollisionSystem::~ParticleCollisionSystem() {
@ -52,8 +51,9 @@ bool ParticleCollisionSystem::updateOperation(OctreeElement* element, void* extr
}
void ParticleCollisionSystem::update() {
void ParticleCollisionSystem::update(QVector<AvatarData*>& avatars) {
// update all particles
_avatars.swap(avatars);
_particles->lockForWrite();
_particles->recurseTreeWithOperation(updateOperation, this);
_particles->unlock();
@ -161,8 +161,8 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
glm::vec3 penetration;
// first check the selfAvatar if set...
if (_selfAvatar) {
AvatarData* avatar = (AvatarData*)_selfAvatar;
for (int i = 0; i < _avatars.size(); ++i) {
AvatarData* avatar = _avatars[i];
CollisionInfo collisionInfo;
collisionInfo._damping = DAMPING;
collisionInfo._elasticity = ELASTICITY;
@ -195,39 +195,6 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) {
}
}
}
// loop through all the other avatars for potential interactions...
// foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
// //qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n";
// if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
// AvatarData* avatar = static_cast<AvatarData*>(node->getLinkedData());
// CollisionInfo collisionInfo;
// if (avatar->findSphereCollision(center, radius, collisionInfo)) {
// collisionInfo._addedVelocity /= (float)(TREE_SCALE);
// glm::vec3 relativeVelocity = collisionInfo._addedVelocity - particle->getVelocity();
// if (glm::dot(relativeVelocity, collisionInfo._penetration) < 0.f) {
// // HACK BEGIN: to allow paddle hands to "hold" particles we attenuate soft collisions against the avatar.
// // NOTE: the physics are wrong (particles cannot roll) but it IS possible to catch a slow moving particle.
// // TODO: make this less hacky when we have more per-collision details
// float elasticity = ELASTICITY;
// float attenuationFactor = glm::length(collisionInfo._addedVelocity) / HALTING_SPEED;
// float damping = DAMPING;
// if (attenuationFactor < 1.f) {
// collisionInfo._addedVelocity *= attenuationFactor;
// elasticity *= attenuationFactor;
// // NOTE: the math below keeps the damping piecewise continuous,
// // while ramping it up to 1.0 when attenuationFactor = 0
// damping = DAMPING + (1.f - attenuationFactor) * (1.f - DAMPING);
// }
// // HACK END
//
// updateCollisionSound(particle, collisionInfo._penetration, COLLISION_FREQUENCY);
// collisionInfo._penetration /= (float)(TREE_SCALE);
// applyHardCollision(particle, ELASTICITY, damping, collisionInfo);
// }
// }
// }
// }
}
void ParticleCollisionSystem::queueParticlePropertiesUpdate(Particle* particle) {

View file

@ -34,15 +34,17 @@ class ParticleCollisionSystem {
public:
ParticleCollisionSystem(ParticleEditPacketSender* packetSender = NULL, ParticleTree* particles = NULL,
VoxelTree* voxels = NULL,
AbstractAudioInterface* audio = NULL,
AvatarData* selfAvatar = NULL);
AbstractAudioInterface* audio = NULL);
void init(ParticleEditPacketSender* packetSender, ParticleTree* particles, VoxelTree* voxels,
AbstractAudioInterface* audio = NULL, AvatarData* selfAvatar = NULL);
AbstractAudioInterface* audio = NULL);
~ParticleCollisionSystem();
void update();
/// Compute collisions for particles against: other particles, voxels, and avatars
/// \param avatars the list of avatars to collide against during this frame
void update(QVector<AvatarData*>& avatars);
void checkParticle(Particle* particle);
void updateCollisionWithVoxels(Particle* particle);
void updateCollisionWithParticles(Particle* particle);
@ -58,7 +60,7 @@ private:
ParticleTree* _particles;
VoxelTree* _voxels;
AbstractAudioInterface* _audio;
AvatarData* _selfAvatar;
QVector<AvatarData*> _avatars; // only used during update()
};
#endif /* defined(__hifi__ParticleCollisionSystem__) */