From 167acb8873a0023db7f2ddb395e05c120a57049a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 28 Jan 2014 14:16:34 -0800 Subject: [PATCH] Adding avatars back into ParticleCollisionSystem. Had to add Application::_myAvatar to the AvatarManager list so that particles would properly collide. --- interface/src/Application.cpp | 10 +- interface/src/avatar/AvatarManager.cpp | 174 +++++++++++------- interface/src/avatar/AvatarManager.h | 27 +-- interface/src/avatar/Hand.cpp | 13 +- interface/src/avatar/MyAvatar.cpp | 13 +- libraries/avatars/src/AvatarHashMap.cpp | 30 +++ libraries/avatars/src/AvatarHashMap.h | 37 ++++ .../particles/src/ParticleCollisionSystem.cpp | 15 +- .../particles/src/ParticleCollisionSystem.h | 9 +- 9 files changed, 216 insertions(+), 112 deletions(-) create mode 100644 libraries/avatars/src/AvatarHashMap.cpp create mode 100644 libraries/avatars/src/AvatarHashMap.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 838c5c1763..8bc845ff24 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1754,6 +1754,7 @@ void Application::init() { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); _myCamera.setModeShiftRate(1.0f); _myAvatar.setDisplayingLookatVectors(false); + _avatarManager.setMyAvatar(&_myAvatar); _mirrorCamera.setMode(CAMERA_MODE_MIRROR); _mirrorCamera.setAspectRatio((float)MIRROR_VIEW_WIDTH / (float)MIRROR_VIEW_HEIGHT); @@ -1800,7 +1801,7 @@ void Application::init() { _metavoxels.init(); - _particleCollisionSystem.init(&_particleEditSender, _particles.getTree(), _voxels.getTree(), &_audio); + _particleCollisionSystem.init(&_particleEditSender, _particles.getTree(), _voxels.getTree(), &_audio, &_avatarManager); _palette.init(_glWidget->width(), _glWidget->height()); _palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelAddMode), 0, 0); @@ -2314,12 +2315,7 @@ void Application::update(float deltaTime) { updateCursor(deltaTime); // Handle cursor updates _particles.update(); // update the particles... - - // collide the particles... - QVector avatars; - avatars.push_back(&_myAvatar); - _avatarManager.getAvatarBasePointers(avatars); - _particleCollisionSystem.update(avatars); + _particleCollisionSystem.update(); // collide the particles... } void Application::updateAvatar(float deltaTime) { diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 5ac521d838..417cdcb2ac 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -16,17 +16,28 @@ #include "AvatarManager.h" + AvatarManager::AvatarManager(QObject* parent) : _lookAtTargetAvatar(), _lookAtOtherPosition(), _lookAtIndicatorScale(1.0f), - _avatarHash(), - _avatarFades() + _avatarFades(), + _myAvatar(NULL) { // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar qRegisterMetaType >("NodeWeakPointer"); } +void AvatarManager::setMyAvatar(MyAvatar* myAvatar) { + if (!_myAvatar) { + // can only ever set this once + _myAvatar = myAvatar; + // add _myAvatar to the list + AvatarSharedPointer myPointer = AvatarSharedPointer(_myAvatar); + _avatarHash.insert(MY_AVATAR_KEY, myPointer); + } +} + void AvatarManager::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateLookatTargetAvatar()"); @@ -34,22 +45,26 @@ void AvatarManager::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { Application* applicationInstance = Application::getInstance(); if (!applicationInstance->isMousePressed()) { - foreach (const AvatarSharedPointer& avatar, _avatarHash) { - float distance; - - if (avatar->findRayIntersection(applicationInstance->getMouseRayOrigin(), - applicationInstance->getMouseRayDirection(), distance)) { - // rescale to compensate for head embiggening - eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * - (avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); - - _lookAtIndicatorScale = avatar->getHead().getScale(); - _lookAtOtherPosition = avatar->getHead().getPosition(); - - _lookAtTargetAvatar = avatar; - - // found the look at target avatar, return - return; + glm::vec3 mouseOrigin = applicationInstance->getMouseRayOrigin(); + glm::vec3 mouseDirection = applicationInstance->getMouseRayDirection(); + + foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { + Avatar* avatar = static_cast(avatarPointer.data()); + if (avatar != static_cast(_myAvatar)) { + float distance; + if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) { + // rescale to compensate for head embiggening + eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * + (avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); + + _lookAtIndicatorScale = avatar->getHead().getScale(); + _lookAtOtherPosition = avatar->getHead().getPosition(); + + _lookAtTargetAvatar = avatarPointer; + + // found the look at target avatar, return + return; + } } } @@ -61,20 +76,28 @@ void AvatarManager::updateAvatars(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); + Application* applicationInstance = Application::getInstance(); + glm::vec3 mouseOrigin = applicationInstance->getMouseRayOrigin(); + glm::vec3 mouseDirection = applicationInstance->getMouseRayDirection(); + // simulate avatars - AvatarHash::iterator avatar = _avatarHash.begin(); - if (avatar != _avatarHash.end()) { - if (avatar->data()->getOwningAvatarMixer()) { + AvatarHash::iterator avatarIterator = _avatarHash.begin(); + while (avatarIterator != _avatarHash.end()) { + if (MY_AVATAR_KEY == avatarIterator.key()) { + // for now skip updates to _myAvatar because it is done explicitly in Application + // TODO: update _myAvatar in this context + ++avatarIterator; + continue; + } + Avatar* avatar = static_cast(avatarIterator.value().data()); + if (avatar->getOwningAvatarMixer()) { // this avatar's mixer is still around, go ahead and simulate it - avatar->data()->simulate(deltaTime, NULL); - - Application* applicationInstance = Application::getInstance(); - - avatar->data()->setMouseRay(applicationInstance->getMouseRayOrigin(), - applicationInstance->getMouseRayDirection()); + avatar->simulate(deltaTime, NULL); + avatar->setMouseRay(mouseOrigin, mouseDirection); + ++avatarIterator; } else { // the mixer that owned this avatar is gone, give it to the vector of fades and kill it - avatar = removeAvatarAtHashIterator(avatar); + avatarIterator = erase(avatarIterator); } } @@ -88,41 +111,44 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { } PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::renderAvatars()"); + bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); if (!selfAvatarOnly) { - // Render avatars of other nodes - foreach (const AvatarSharedPointer& avatar, _avatarHash) { + foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { + Avatar* avatar = static_cast(avatarPointer.data()); if (!avatar->isInitialized()) { avatar->init(); } - avatar->render(false); - avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); + if (avatar == static_cast(_myAvatar)) { + avatar->render(forceRenderHead); + } else { + avatar->render(false); + } + avatar->setDisplayingLookatVectors(renderLookAtVectors); } - renderAvatarFades(); + } else if (_myAvatar) { + // Render my own Avatar + _myAvatar->render(forceRenderHead); + _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } - - // Render my own Avatar - Avatar* myAvatar = Application::getInstance()->getAvatar(); - myAvatar->render(forceRenderHead); - myAvatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); } void AvatarManager::simulateAvatarFades(float deltaTime) { - QVector::iterator fadingAvatar = _avatarFades.begin(); + QVector::iterator fadingIterator = _avatarFades.begin(); - while (fadingAvatar != _avatarFades.end()) { - const float SHRINK_RATE = 0.9f; - - fadingAvatar->data()->setTargetScale(fadingAvatar->data()->getScale() * SHRINK_RATE); - - const float MIN_FADE_SCALE = 0.001f; - - if (fadingAvatar->data()->getTargetScale() < MIN_FADE_SCALE) { - fadingAvatar = _avatarFades.erase(fadingAvatar); + const float SHRINK_RATE = 0.9f; + const float MIN_FADE_SCALE = 0.001f; + + while (fadingIterator != _avatarFades.end()) { + Avatar* avatar = static_cast(fadingIterator->data()); + avatar->setTargetScale(avatar->getScale() * SHRINK_RATE); + if (avatar->getTargetScale() < MIN_FADE_SCALE) { + fadingIterator = _avatarFades.erase(fadingIterator); } else { - fadingAvatar->data()->simulate(deltaTime, NULL); + avatar->simulate(deltaTime, NULL); + ++fadingIterator; } } } @@ -132,29 +158,36 @@ void AvatarManager::renderAvatarFades() { Glower glower; foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { - fadingAvatar->render(false); + Avatar* avatar = static_cast(fadingAvatar.data()); + avatar->render(false); } } void AvatarManager::processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList &valueList) { + QUuid avatarKey = QUuid(userString); + if (avatarKey == MY_AVATAR_KEY) { + // ignore updates to our own mesh + return; + } for (int i = 0; i < keyList.size(); i++) { if (valueList[i] != " ") { if (keyList[i] == DataServerKey::FaceMeshURL || keyList[i] == DataServerKey::SkeletonURL) { // mesh URL for a UUID, find avatar in our list - AvatarSharedPointer matchingAvatar = _avatarHash.value(QUuid(userString)); + AvatarSharedPointer matchingAvatar = _avatarHash.value(avatarKey); if (matchingAvatar) { + Avatar* avatar = static_cast(matchingAvatar.data()); if (keyList[i] == DataServerKey::FaceMeshURL) { qDebug() << "Changing mesh to" << valueList[i] << "for avatar with UUID" - << uuidStringWithoutCurlyBraces(QUuid(userString)); + << uuidStringWithoutCurlyBraces(avatarKey); - QMetaObject::invokeMethod(&matchingAvatar->getHead().getFaceModel(), + QMetaObject::invokeMethod(&(avatar->getHead().getFaceModel()), "setURL", Q_ARG(QUrl, QUrl(valueList[i]))); } else if (keyList[i] == DataServerKey::SkeletonURL) { qDebug() << "Changing skeleton to" << valueList[i] << "for avatar with UUID" - << uuidStringWithoutCurlyBraces(QString(userString)); + << uuidStringWithoutCurlyBraces(avatarKey.toString()); - QMetaObject::invokeMethod(&matchingAvatar->getSkeletonModel(), + QMetaObject::invokeMethod(&(avatar->getSkeletonModel()), "setURL", Q_ARG(QUrl, QUrl(valueList[i]))); } } @@ -178,15 +211,17 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const // only add them if mixerWeakPointer points to something (meaning that mixer is still around) while (bytesRead < datagram.size() && mixerWeakPointer.data()) { QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); + // TODO: skip the data if nodeUUID is same as MY_AVATAR_KEY AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID); if (!matchingAvatar) { // construct a new Avatar for this node - matchingAvatar = AvatarSharedPointer(new Avatar()); - matchingAvatar->setOwningAvatarMixer(mixerWeakPointer); + Avatar* avatar = new Avatar(); + avatar->setOwningAvatarMixer(mixerWeakPointer); // insert the new avatar into our hash + matchingAvatar = AvatarSharedPointer(avatar); _avatarHash.insert(nodeUUID, matchingAvatar); // new UUID requires mesh and skeleton request to data-server @@ -213,28 +248,27 @@ void AvatarManager::processKillAvatar(const QByteArray& datagram) { // remove the avatar with that UUID from our hash, if it exists AvatarHash::iterator matchedAvatar = _avatarHash.find(nodeUUID); if (matchedAvatar != _avatarHash.end()) { - removeAvatarAtHashIterator(matchedAvatar); + erase(matchedAvatar); } } -AvatarHash::iterator AvatarManager::removeAvatarAtHashIterator(const AvatarHash::iterator& iterator) { - qDebug() << "Removing Avatar with UUID" << iterator.key() << "from AvatarManager hash."; - _avatarFades.push_back(iterator.value()); - return _avatarHash.erase(iterator); +AvatarHash::iterator AvatarManager::erase(const AvatarHash::iterator& iterator) { + if (iterator.key() != MY_AVATAR_KEY) { + qDebug() << "Removing Avatar with UUID" << iterator.key() << "from AvatarManager hash."; + _avatarFades.push_back(iterator.value()); + return AvatarHashMap::erase(iterator); + } else { + // never remove _myAvatar from the list + AvatarHash::iterator returnIterator = iterator; + return ++returnIterator; + } } void AvatarManager::clearHash() { // clear the AvatarManager hash - typically happens on the removal of the avatar-mixer AvatarHash::iterator removeAvatar = _avatarHash.begin(); - while (removeAvatar != _avatarHash.end()) { - removeAvatar = removeAvatarAtHashIterator(removeAvatar); + removeAvatar = erase(removeAvatar); } } -void AvatarManager::getAvatarBasePointers(QVector& avatars) { - AvatarHash::iterator avatarItr = _avatarHash.begin(); - while (avatarItr != _avatarHash.end()) { - avatars.push_back( static_cast(avatarItr.value().data()) ); - } -} diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 82fe279254..f092789ded 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -13,32 +13,32 @@ #include #include +#include #include #include "Avatar.h" -typedef QSharedPointer AvatarSharedPointer; -typedef QHash AvatarHash; +class MyAvatar; -class AvatarManager : public QObject, public DataServerCallbackObject { +const QUuid MY_AVATAR_KEY; // NULL key + +class AvatarManager : public QObject, public DataServerCallbackObject, public AvatarHashMap { Q_OBJECT public: AvatarManager(QObject* parent = 0); + + void setMyAvatar(MyAvatar* myAvatar); - const AvatarHash& getAvatarHash() { return _avatarHash; } - int size() const { return _avatarHash.size(); } - - Avatar* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } + AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } void updateLookAtTargetAvatar(glm::vec3& eyePosition); void updateAvatars(float deltaTime); void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false); + // virtual override void clearHash(); - void getAvatarBasePointers(QVector& avatars); - public slots: void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList); @@ -46,17 +46,20 @@ public slots: void processKillAvatar(const QByteArray& datagram); private: + AvatarManager(const AvatarManager& other); + void simulateAvatarFades(float deltaTime); void renderAvatarFades(); - AvatarHash::iterator removeAvatarAtHashIterator(const AvatarHash::iterator& iterator); + // virtual override + AvatarHash::iterator erase(const AvatarHash::iterator& iterator); - QWeakPointer _lookAtTargetAvatar; + QWeakPointer _lookAtTargetAvatar; glm::vec3 _lookAtOtherPosition; float _lookAtIndicatorScale; - AvatarHash _avatarHash; QVector _avatarFades; + MyAvatar* _myAvatar; }; #endif /* defined(__hifi__AvatarManager__) */ diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 18d6031f98..b441000cc1 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -183,7 +183,12 @@ void Hand::updateCollisions() { glm::vec3 totalPenetration; // check other avatars - foreach (const AvatarSharedPointer& avatar, Application::getInstance()->getAvatarManager().getAvatarHash()) { + foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { + Avatar* avatar = static_cast(avatarPointer.data()); + if (avatar == _owningAvatar) { + // don't collid with our own hands + continue; + } if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { // Check for palm collisions glm::vec3 myPalmPosition = palm.getPosition(); @@ -205,9 +210,9 @@ void Hand::updateCollisions() { const float PALM_COLLIDE_DURATION_MAX = 0.75f; const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f; Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME, - PALM_COLLIDE_FREQUENCY, - PALM_COLLIDE_DURATION_MAX, - PALM_COLLIDE_DECAY_PER_SAMPLE); + PALM_COLLIDE_FREQUENCY, + PALM_COLLIDE_DURATION_MAX, + PALM_COLLIDE_DECAY_PER_SAMPLE); // If the other person's palm is in motion, move mine downward to show I was hit const float MIN_VELOCITY_FOR_SLAP = 0.05f; if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ca7a3b863b..6910826524 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -791,14 +791,15 @@ void MyAvatar::updateChatCircle(float deltaTime) { // find all circle-enabled members and sort by distance QVector sortedAvatars; - foreach (const AvatarSharedPointer& avatar, Application::getInstance()->getAvatarManager().getAvatarHash()) { - SortedAvatar sortedAvatar; - sortedAvatar.avatar = avatar.data(); - - if (!sortedAvatar.avatar->isChatCirclingEnabled()) { + foreach (const AvatarSharedPointer& avatarPointer, Application::getInstance()->getAvatarManager().getAvatarHash()) { + Avatar* avatar = static_cast(avatarPointer.data()); + if ( ! avatar->isChatCirclingEnabled() || + avatar == static_cast(this)) { continue; } - + + SortedAvatar sortedAvatar; + sortedAvatar.avatar = avatar; sortedAvatar.distance = glm::distance(_position, sortedAvatar.avatar->getPosition()); sortedAvatars.append(sortedAvatar); } diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp new file mode 100644 index 0000000000..b1bb42edbf --- /dev/null +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -0,0 +1,30 @@ +// +// AvatarHashMap.cpp +// hifi +// +// Created by Stephen AndrewMeadows on 1/28/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#include "AvatarHashMap.h" + +AvatarHashMap::AvatarHashMap() : + _avatarHash() +{ +} + +void AvatarHashMap::insert(const QUuid& id, AvatarSharedPointer avatar) { + _avatarHash.insert(id, avatar); +} + +void AvatarHashMap::clearHash() { + AvatarHash::iterator removeAvatar = _avatarHash.begin(); + while (removeAvatar != _avatarHash.end()) { + removeAvatar = erase(removeAvatar); + } +} + +AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) { + return _avatarHash.erase(iterator); +} + diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h new file mode 100644 index 0000000000..37e9004d6f --- /dev/null +++ b/libraries/avatars/src/AvatarHashMap.h @@ -0,0 +1,37 @@ +// +// AvatarHashMap.h +// hifi +// +// Created by Stephen AndrewMeadows on 1/28/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AvatarHashMap__ +#define __hifi__AvatarHashMap__ + +#include +#include +#include + +#include "AvatarData.h" + +typedef QSharedPointer AvatarSharedPointer; +typedef QHash AvatarHash; + +class AvatarHashMap { +public: + AvatarHashMap(); + + const AvatarHash& getAvatarHash() { return _avatarHash; } + int size() const { return _avatarHash.size(); } + + virtual void insert(const QUuid& id, AvatarSharedPointer avatar); + virtual void clearHash(); + +protected: + virtual AvatarHash::iterator erase(const AvatarHash::iterator& iterator); + + AvatarHash _avatarHash; +}; + +#endif /* defined(__hifi__AvatarHashMap__) */ diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index d53898ac05..4f5bc85d5a 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -25,11 +25,13 @@ ParticleCollisionSystem::ParticleCollisionSystem(ParticleEditPacketSender* packe } void ParticleCollisionSystem::init(ParticleEditPacketSender* packetSender, - ParticleTree* particles, VoxelTree* voxels, AbstractAudioInterface* audio) { + ParticleTree* particles, VoxelTree* voxels, AbstractAudioInterface* audio, + AvatarHashMap* avatars) { _packetSender = packetSender; _particles = particles; _voxels = voxels; _audio = audio; + _avatars = avatars; } ParticleCollisionSystem::~ParticleCollisionSystem() { @@ -51,9 +53,8 @@ bool ParticleCollisionSystem::updateOperation(OctreeElement* element, void* extr } -void ParticleCollisionSystem::update(QVector& avatars) { +void ParticleCollisionSystem::update() { // update all particles - _avatars.swap(avatars); _particles->lockForWrite(); _particles->recurseTreeWithOperation(updateOperation, this); _particles->unlock(); @@ -147,9 +148,8 @@ const float MIN_EXPECTED_FRAME_PERIOD = 0.0167f; // 1/60th of a second const float HALTING_SPEED = 9.8 * MIN_EXPECTED_FRAME_PERIOD / (float)(TREE_SCALE); void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { - // particles that are in hand, don't collide with avatars - if (particle->getInHand()) { + if (!_avatars || particle->getInHand()) { return; } @@ -160,9 +160,8 @@ void ParticleCollisionSystem::updateCollisionWithAvatars(Particle* particle) { const float COLLISION_FREQUENCY = 0.5f; glm::vec3 penetration; - // first check the selfAvatar if set... - for (int i = 0; i < _avatars.size(); ++i) { - AvatarData* avatar = _avatars[i]; + foreach (const AvatarSharedPointer& avatarPointer, _avatars->getAvatarHash()) { + AvatarData* avatar = avatarPointer.data(); CollisionInfo collisionInfo; collisionInfo._damping = DAMPING; collisionInfo._elasticity = ELASTICITY; diff --git a/libraries/particles/src/ParticleCollisionSystem.h b/libraries/particles/src/ParticleCollisionSystem.h index b4293071bb..352864134e 100644 --- a/libraries/particles/src/ParticleCollisionSystem.h +++ b/libraries/particles/src/ParticleCollisionSystem.h @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -37,13 +38,11 @@ public: AbstractAudioInterface* audio = NULL); void init(ParticleEditPacketSender* packetSender, ParticleTree* particles, VoxelTree* voxels, - AbstractAudioInterface* audio = NULL); + AbstractAudioInterface* audio = NULL, AvatarHashMap* _avatars = NULL); ~ParticleCollisionSystem(); - /// 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& avatars); + void update(); void checkParticle(Particle* particle); void updateCollisionWithVoxels(Particle* particle); @@ -60,7 +59,7 @@ private: ParticleTree* _particles; VoxelTree* _voxels; AbstractAudioInterface* _audio; - QVector _avatars; // only used during update() + AvatarHashMap* _avatars; }; #endif /* defined(__hifi__ParticleCollisionSystem__) */