diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 28b8358742..64e93fd751 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -30,7 +30,8 @@ const unsigned int AVATAR_DATA_SEND_INTERVAL_USECS = (1 / 60.0) * 1000 * 1000; AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) : ThreadedAssignment(dataBuffer, numBytes) { - + // make sure we hear about node kills so we can tell the other nodes + connect(NodeList::getInstance(), &NodeList::nodeKilled, this, &AvatarMixer::nodeKilled); } unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *nodeToAdd) { @@ -46,7 +47,7 @@ unsigned char* addNodeToBroadcastPacket(unsigned char *currentPosition, Node *no void attachAvatarDataToNode(Node* newNode) { if (newNode->getLinkedData() == NULL) { - newNode->setLinkedData(new AvatarData(newNode)); + newNode->setLinkedData(new AvatarData()); } } @@ -116,6 +117,22 @@ void broadcastAvatarData() { } } +void AvatarMixer::nodeKilled(SharedNodePointer killedNode) { + if (killedNode->getType() == NODE_TYPE_AGENT + && killedNode->getLinkedData()) { + // this was an avatar we were sending to other people + // send a kill packet for it to our other nodes + unsigned char packetData[MAX_PACKET_SIZE]; + int numHeaderBytes = populateTypeAndVersion(packetData, PACKET_TYPE_KILL_AVATAR); + + QByteArray rfcUUID = killedNode->getUUID().toRfc4122(); + memcpy(packetData + numHeaderBytes, rfcUUID.constData(), rfcUUID.size()); + + NodeList::getInstance()->broadcastToNodes(packetData, numHeaderBytes + NUM_BYTES_RFC4122_UUID, + QSet() << NODE_TYPE_AGENT); + } +} + void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { NodeList* nodeList = NodeList::getInstance(); @@ -136,7 +153,10 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc } break; } - case PACKET_TYPE_KILL_NODE: + case PACKET_TYPE_KILL_AVATAR: { + nodeList->processKillNode(dataByteArray); + break; + } default: // hand this off to the NodeList nodeList->processNodeData(senderSockAddr, (unsigned char*) dataByteArray.data(), dataByteArray.size()); diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index c2158fad1c..2da0ed98eb 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -19,6 +19,8 @@ public: public slots: /// runs the avatar mixer void run(); + + void nodeKilled(SharedNodePointer killedNode); void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d9f6c74934..0ee7cca467 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -532,7 +532,7 @@ void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignme void DomainServer::nodeKilled(SharedNodePointer node) { // if this node has linked data it was from an assignment if (node->getLinkedData()) { - Assignment* nodeAssignment = (Assignment*) node->getLinkedData(); + Assignment* nodeAssignment = (Assignment*) node->getLinkedData(); addReleasedAssignmentBackToQueue(nodeAssignment); } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2f545113bd..2640753267 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -116,6 +116,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _voxelImporter(_window), _wantToKillLocalVoxels(false), _audioScope(256, 200, true), + _avatarManager(), _profile(QString()), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _mouseX(0), @@ -138,8 +139,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _nudgeStarted(false), _lookingAlongX(false), _lookingAwayFromOrigin(true), - _lookatTargetAvatar(NULL), - _lookatIndicatorScale(1.0f), _chatEntryOn(false), _audio(&_audioScope, STARTUP_JITTER_SAMPLES), _enableProcessVoxelsThread(true), @@ -220,9 +219,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // Voxel File. _voxelsFilename = getCmdOption(argc, constArgv, "-i"); - // the callback for our instance of NodeList is attachNewHeadToNode - nodeList->linkedDataCreateCallback = &attachNewHeadToNode; - #ifdef _WIN32 WSADATA WsaData; int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData); @@ -294,7 +290,7 @@ Application::~Application() { _settings->sync(); // let the avatar mixer know we're out - NodeList::getInstance()->sendKillNode(QSet() << NODE_TYPE_AVATAR_MIXER); + MyAvatar::sendKillAvatar(); // ask the datagram processing thread to quit and wait until it is done _nodeThread->quit(); @@ -1160,8 +1156,8 @@ void Application::mouseMoveEvent(QMouseEvent* event) { if (activeWindow() == _window) { // orbit behavior if (_mousePressed && !Menu::getInstance()->isVoxelModeActionChecked()) { - if (_lookatTargetAvatar) { - _myAvatar.orbit(_lookatTargetAvatar->getPosition(), deltaX, deltaY); + if (_avatarManager.getLookAtTargetAvatar()) { + _myAvatar.orbit(_avatarManager.getLookAtTargetAvatar()->getPosition(), deltaX, deltaY); return; } if (_isHoverVoxel) { @@ -1212,7 +1208,7 @@ void Application::mousePressEvent(QMouseEvent* event) { return; } - if (!_palette.isActive() && (!_isHoverVoxel || _lookatTargetAvatar)) { + if (!_palette.isActive() && (!_isHoverVoxel || _avatarManager.getLookAtTargetAvatar())) { // disable for now // _pieMenu.mousePressEvent(_mouseX, _mouseY); } @@ -1846,40 +1842,6 @@ const float MAX_AVATAR_EDIT_VELOCITY = 1.0f; const float MAX_VOXEL_EDIT_DISTANCE = 50.0f; const float HEAD_SPHERE_RADIUS = 0.07f; -static QUuid DEFAULT_NODE_ID_REF; - -void Application::updateLookatTargetAvatar(glm::vec3& eyePosition) { - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateLookatTargetAvatar()"); - - if (!_mousePressed) { - _lookatTargetAvatar = findLookatTargetAvatar(eyePosition, DEFAULT_NODE_ID_REF); - } -} - -Avatar* Application::findLookatTargetAvatar(glm::vec3& eyePosition, QUuid& nodeUUID = DEFAULT_NODE_ID_REF) { - - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { - Avatar* avatar = (Avatar*)node->getLinkedData(); - float distance; - - if (avatar->findRayIntersection(_mouseRayOrigin, _mouseRayDirection, 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(); - nodeUUID = avatar->getOwningNode()->getUUID(); - return avatar; - } - } - } - - return NULL; -} - bool Application::isLookingAtMyAvatar(Avatar* avatar) { glm::vec3 theirLookat = avatar->getHead().getLookAtPosition(); glm::vec3 myHeadPosition = _myAvatar.getHead().getPosition(); @@ -1890,17 +1852,6 @@ bool Application::isLookingAtMyAvatar(Avatar* avatar) { return false; } -void Application::renderLookatIndicator(glm::vec3 pointOfInterest) { - - const float DISTANCE_FROM_HEAD_SPHERE = 0.1f * _lookatIndicatorScale; - const float INDICATOR_RADIUS = 0.1f * _lookatIndicatorScale; - const float YELLOW[] = { 1.0f, 1.0f, 0.0f }; - const int NUM_SEGMENTS = 30; - glm::vec3 haloOrigin(pointOfInterest.x, pointOfInterest.y + DISTANCE_FROM_HEAD_SPHERE, pointOfInterest.z); - glColor3f(YELLOW[0], YELLOW[1], YELLOW[2]); - renderCircle(haloOrigin, INDICATOR_RADIUS, IDENTITY_UP, NUM_SEGMENTS); -} - void Application::renderHighlightVoxel(VoxelDetail voxel) { glDisable(GL_LIGHTING); glPushMatrix(); @@ -1915,41 +1866,6 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) { glPopMatrix(); } -void Application::updateAvatars(float deltaTime) { - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); - - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - QMutexLocker locker(&node->getMutex()); - if (node->getLinkedData()) { - Avatar *avatar = (Avatar *)node->getLinkedData(); - if (!avatar->isInitialized()) { - avatar->init(); - } - avatar->simulate(deltaTime, NULL); - avatar->setMouseRay(_mouseRayOrigin, _mouseRayDirection); - } - } - - // simulate avatar fades - for (vector::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) { - Avatar* avatar = *fade; - const float SHRINK_RATE = 0.9f; - - avatar->setTargetScale(avatar->getScale() * SHRINK_RATE); - - const float MIN_FADE_SCALE = 0.001f; - - if (avatar->getTargetScale() < MIN_FADE_SCALE) { - delete avatar; - _avatarFades.erase(fade--); - - } else { - avatar->simulate(deltaTime, NULL); - } - } -} - void Application::updateMouseRay() { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); @@ -2002,7 +1918,6 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) { glm::vec3 rayOrigin, rayDirection; _viewFrustum.computePickRay(0.5f, 0.5f, rayOrigin, rayDirection); lookAtSpot = rayOrigin + rayDirection * FAR_AWAY_STARE; - } else { // just look in direction of the mouse ray lookAtSpot = _mouseRayOrigin + _mouseRayDirection * FAR_AWAY_STARE; @@ -2359,7 +2274,7 @@ void Application::update(float deltaTime) { glm::vec3 lookAtSpot; updateFaceshift(); - updateLookatTargetAvatar(lookAtSpot); + _avatarManager.updateLookAtTargetAvatar(lookAtSpot); updateMyAvatarLookAtPosition(lookAtSpot); // Find the voxel we are hovering over, and respond if clicked @@ -2374,7 +2289,7 @@ void Application::update(float deltaTime) { updateSerialDevices(deltaTime); // Read serial port interface devices updateAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... - updateAvatars(deltaTime); //loop through all the other avatars and simulate them... + _avatarManager.updateAvatars(deltaTime); //loop through all the other avatars and simulate them... updateMyAvatarSimulation(deltaTime); // Simulate myself updateParticles(deltaTime); // Simulate particle cloud movements updateMetavoxels(deltaTime); // update metavoxels @@ -2743,7 +2658,7 @@ void Application::updateShadowMap() { glTranslatef(translation.x, translation.y, translation.z); - renderAvatars(true); + _avatarManager.renderAvatars(true); _particles.render(); glPopMatrix(); @@ -2971,7 +2886,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } } - renderAvatars(whichCamera.getMode() == CAMERA_MODE_MIRROR, selfAvatarOnly); + _avatarManager.renderAvatars(whichCamera.getMode() == CAMERA_MODE_MIRROR, selfAvatarOnly); if (!selfAvatarOnly) { // Render the world box @@ -3125,11 +3040,8 @@ void Application::displayOverlay() { glPointSize(1.0f); char nodes[100]; - int totalAvatars = 0, totalServers = 0; - - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++; - } + int totalAvatars = _avatarManager.size(); + int totalServers = NodeList::getInstance()->size(); sprintf(nodes, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); drawtext(_glWidget->width() - 150, 20, 0.10f, 0, 1.0f, 0, nodes, 1, 0, 0); @@ -3545,46 +3457,6 @@ void Application::renderCoverageMapsRecursively(CoverageMap* map) { } } -void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { - if (!Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - return; - } - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::renderAvatars()"); - - if (!selfAvatarOnly) { - // Render avatars of other nodes - NodeList* nodeList = NodeList::getInstance(); - - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { - QMutexLocker locker(&node->getMutex()); - - if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { - Avatar *avatar = (Avatar *)node->getLinkedData(); - if (!avatar->isInitialized()) { - avatar->init(); - } - avatar->render(false); - avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); - } - } - - // render avatar fades - Glower glower; - for (vector::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) { - (*fade)->render(false); - } - } - - // Render my own Avatar - _myAvatar.render(forceRenderHead); - _myAvatar.setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); - - if (Menu::getInstance()->isOptionChecked(MenuOption::LookAtIndicator) && _lookatTargetAvatar) { - renderLookatIndicator(_lookatOtherPosition); - } -} - // renderViewFrustum() // // Description: this will render the view frustum bounds for EITHER the head @@ -3849,17 +3721,6 @@ void Application::setMenuShortcutsEnabled(bool enabled) { setShortcutsEnabled(_window->menuBar(), enabled); } -void Application::attachNewHeadToNode(Node* newNode) { - if (newNode->getLinkedData() == NULL) { - newNode->setLinkedData(new Avatar(newNode)); - - // new UUID requires mesh and skeleton request to data-server - DataServerClient::getValuesForKeysAndUUID(QStringList() << DataServerKey::FaceMeshURL << DataServerKey::SkeletonURL, - newNode->getUUID(), Application::getInstance()->getProfile()); - - } -} - void Application::updateWindowTitle(){ QString title = ""; @@ -3960,16 +3821,9 @@ void Application::nodeKilled(SharedNodePointer node) { } _voxelSceneStatsLock.unlock(); - } else if (node->getType() == NODE_TYPE_AGENT) { - Avatar* avatar = static_cast(node->getLinkedData()); - if (avatar == _lookatTargetAvatar) { - _lookatTargetAvatar = NULL; - } - - // take over the avatar in order to fade it out - node->setLinkedData(NULL); - - _avatarFades.push_back(avatar); + } else if (node->getType() == NODE_TYPE_AVATAR_MIXER) { + // our avatar mixer has gone away - clear the hash of avatars + _avatarManager.clearHash(); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 203d74fa82..defe4dc8aa 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -50,6 +50,7 @@ #include "VoxelSystem.h" #include "VoxelImporter.h" #include "avatar/Avatar.h" +#include "avatar/AvatarManager.h" #include "avatar/MyAvatar.h" #include "avatar/Profile.h" #include "devices/Faceshift.h" @@ -151,6 +152,7 @@ public: VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; } VoxelTree* getClipboard() { return &_clipboard; } Environment* getEnvironment() { return &_environment; } + bool isMousePressed() const { return _mousePressed; } bool isMouseHidden() const { return _mouseHidden; } const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; } const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } @@ -169,8 +171,7 @@ public: TextureCache* getTextureCache() { return &_textureCache; } GlowEffect* getGlowEffect() { return &_glowEffect; } - Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; } - + AvatarManager& getAvatarManager() { return _avatarManager; } Profile* getProfile() { return &_profile; } void resetProfile(const QString& username); @@ -233,14 +234,12 @@ public slots: void initAvatarAndViewFrustum(); private slots: - void timer(); void idle(); void setFullscreen(bool fullscreen); void setEnable3DTVMode(bool enable3DTVMode); - - + void renderThrustAtVoxel(const glm::vec3& thrust); void renderCoverageMap(); @@ -279,7 +278,6 @@ private: void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot); void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face); void updateMouseVoxels(float deltaTime, float& distance, BoxFace& face); - void updateLookatTargetAvatar(glm::vec3& eyePosition); void updateHandAndTouch(float deltaTime); void updateLeap(float deltaTime); void updateSixense(float deltaTime); @@ -301,7 +299,6 @@ private: void renderHighlightVoxel(VoxelDetail voxel); void updateAvatar(float deltaTime); - void updateAvatars(float deltaTime); void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); @@ -310,7 +307,6 @@ private: void updateShadowMap(); void displayOverlay(); void displayStats(); - void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false); void renderViewFrustum(ViewFrustum& viewFrustum); void checkBandwidthMeterClick(); @@ -373,6 +369,7 @@ private: VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server + AvatarManager _avatarManager; MyAvatar _myAvatar; // The rendered avatar of oneself Profile _profile; // The data-server linked profile for this user @@ -442,10 +439,6 @@ private: bool _lookingAwayFromOrigin; glm::vec3 _nudgeGuidePosition; - Avatar* _lookatTargetAvatar; - glm::vec3 _lookatOtherPosition; - float _lookatIndicatorScale; - glm::vec3 _transmitterPickStart; glm::vec3 _transmitterPickEnd; @@ -494,7 +487,6 @@ private: QReadWriteLock _voxelSceneStatsLock; std::vector _voxelFades; - std::vector _avatarFades; ControllerScriptingInterface _controllerScriptingInterface; QPointer _logDialog; diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index ad18a11c98..b78bd0c309 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // +#include + #include #include "Application.h" @@ -90,11 +92,30 @@ void DatagramProcessor::processDatagrams() { senderSockAddr); break; case PACKET_TYPE_BULK_AVATAR_DATA: - NodeList::getInstance()->processBulkNodeData(senderSockAddr, - incomingPacket, - bytesReceived); + case PACKET_TYPE_KILL_AVATAR: { + // update having heard from the avatar-mixer and record the bytes received + SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr); + + if (avatarMixer) { + avatarMixer->setLastHeardMicrostamp(usecTimestampNow()); + avatarMixer->recordBytesReceived(bytesReceived); + + QByteArray datagram(reinterpret_cast(incomingPacket), bytesReceived); + + if (incomingPacket[0] == PACKET_TYPE_BULK_AVATAR_DATA) { + QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram", + Q_ARG(const QByteArray&, datagram), + Q_ARG(const QWeakPointer&, avatarMixer)); + } else { + // this is an avatar kill, pass it to the application AvatarManager + QMetaObject::invokeMethod(&application->getAvatarManager(), "processKillAvatar", + Q_ARG(const QByteArray&, datagram)); + } + } + application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived); break; + } case PACKET_TYPE_DATA_SERVER_GET: case PACKET_TYPE_DATA_SERVER_PUT: case PACKET_TYPE_DATA_SERVER_SEND: diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c717957da7..8fd268938e 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -334,7 +334,6 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollisionProxies); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true); - addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtIndicator, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::FaceshiftTCP, 0, @@ -902,7 +901,7 @@ void Menu::goToDomain() { } // send a node kill request, indicating to other clients that they should play the "disappeared" effect - NodeList::getInstance()->sendKillNode(QSet() << NODE_TYPE_AVATAR_MIXER); + Application::getInstance()->getAvatar()->sendKillAvatar(); // give our nodeList the new domain-server hostname NodeList::getInstance()->setDomainHostname(domainDialog.textValue()); @@ -944,7 +943,7 @@ void Menu::goToLocation() { if (newAvatarPos != avatarPos) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect - NodeList::getInstance()->sendKillNode(QSet() << NODE_TYPE_AVATAR_MIXER); + MyAvatar::sendKillAvatar(); qDebug("Going To Location: %f, %f, %f...", x, y, z); myAvatar->setPosition(newAvatarPos); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 3f597bb4ad..03149ce07c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -221,7 +221,6 @@ namespace MenuOption { const QString LodTools = "LOD Tools"; const QString Log = "Log"; const QString Login = "Login"; - const QString LookAtIndicator = "Look-at Indicator"; const QString LookAtVectors = "Look-at Vectors"; const QString MetavoxelEditor = "Metavoxel Editor..."; const QString Metavoxels = "Metavoxels"; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index b0d2a204bd..c5071570d5 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -57,7 +57,7 @@ GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 }; GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 }; VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) - : NodeData(NULL), + : NodeData(), _treeScale(treeScale), _maxVoxels(maxVoxels), _initialized(false) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 7705a5d03e..5e41619997 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -58,8 +58,8 @@ const int NUM_BODY_CONE_SIDES = 9; const float CHAT_MESSAGE_SCALE = 0.0015f; const float CHAT_MESSAGE_HEIGHT = 0.1f; -Avatar::Avatar(Node* owningNode) : - AvatarData(owningNode), +Avatar::Avatar() : + AvatarData(), _head(this), _hand(this), _skeletonModel(this), @@ -75,6 +75,7 @@ Avatar::Avatar(Node* owningNode) : _mouseRayDirection(0.0f, 0.0f, 0.0f), _isCollisionsOn(true), _moving(false), + _owningAvatarMixer(), _initialized(false) { // we may have been created in the network thread, but we live in the main thread @@ -85,17 +86,11 @@ Avatar::Avatar(Node* owningNode) : _handData = &_hand; } - Avatar::~Avatar() { _headData = NULL; _handData = NULL; } -void Avatar::deleteOrDeleteLater() { - this->deleteLater(); -} - - void Avatar::init() { _head.init(); _hand.init(); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 725aa9d5cf..10a3760f6e 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -69,10 +69,8 @@ class Avatar : public AvatarData { Q_OBJECT public: - - Avatar(Node* owningNode = NULL); + Avatar(); ~Avatar(); - void deleteOrDeleteLater(); void init(); void simulate(float deltaTime, Transmitter* transmitter); @@ -92,6 +90,9 @@ public: Head& getHead() { return _head; } Hand& getHand() { return _hand; } glm::quat getWorldAlignedOrientation() const; + + Node* getOwningAvatarMixer() { return _owningAvatarMixer.data(); } + void setOwningAvatarMixer(const QWeakPointer& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; } bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const; @@ -110,8 +111,10 @@ public: /// \param collision[out] the details of the collision point /// \return whether or not the sphere collided virtual bool findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision); + + virtual bool isMyAvatar() { return false; } - virtual int parseData(unsigned char* sourceBuffer, int numBytes); + int parseData(unsigned char* sourceBuffer, int numBytes); static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2); @@ -141,8 +144,8 @@ protected: glm::vec3 _mouseRayDirection; bool _isCollisionsOn; float _stringLength; - bool _moving; ///< set when position is changing + QWeakPointer _owningAvatarMixer; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp new file mode 100644 index 0000000000..dd1686a0d2 --- /dev/null +++ b/interface/src/avatar/AvatarManager.cpp @@ -0,0 +1,233 @@ +// +// AvatarManager.cpp +// hifi +// +// Created by Stephen Birarda on 1/23/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#include +#include + +#include "Application.h" +#include "Avatar.h" +#include "Menu.h" +#include "MyAvatar.h" + +#include "AvatarManager.h" + +AvatarManager::AvatarManager(QObject* parent) : + _lookAtTargetAvatar(), + _lookAtOtherPosition(), + _lookAtIndicatorScale(1.0f), + _avatarHash(), + _avatarFades() +{ + // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar + qRegisterMetaType >("NodeWeakPointer"); +} + +void AvatarManager::updateLookAtTargetAvatar(glm::vec3 &eyePosition) { + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + PerformanceWarning warn(showWarnings, "Application::updateLookatTargetAvatar()"); + + 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; + } + } + + _lookAtTargetAvatar.clear(); + } +} + +void AvatarManager::updateAvatars(float deltaTime) { + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); + + // simulate avatars + AvatarHash::iterator avatar = _avatarHash.begin(); + if (avatar != _avatarHash.end()) { + if (avatar->data()->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()); + } else { + // the mixer that owned this avatar is gone, give it to the vector of fades and kill it + avatar = removeAvatarAtHashIterator(avatar); + } + } + + // simulate avatar fades + simulateAvatarFades(deltaTime); +} + +void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) { + if (!Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { + return; + } + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::renderAvatars()"); + + if (!selfAvatarOnly) { + + // Render avatars of other nodes + foreach (const AvatarSharedPointer& avatar, _avatarHash) { + if (!avatar->isInitialized()) { + avatar->init(); + } + avatar->render(false); + avatar->setDisplayingLookatVectors(Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors)); + } + + renderAvatarFades(); + } + + // 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(); + + 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); + } else { + fadingAvatar->data()->simulate(deltaTime, NULL); + } + } +} + +void AvatarManager::renderAvatarFades() { + // render avatar fades + Glower glower; + + foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { + fadingAvatar->render(false); + } +} + +void AvatarManager::processDataServerResponse(const QString& userString, const QStringList& keyList, + const QStringList &valueList) { + 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)); + if (matchingAvatar) { + if (keyList[i] == DataServerKey::FaceMeshURL) { + qDebug() << "Changing mesh to" << valueList[i] << "for avatar with UUID" + << uuidStringWithoutCurlyBraces(QUuid(userString)); + + QMetaObject::invokeMethod(&matchingAvatar->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)); + + QMetaObject::invokeMethod(&matchingAvatar->getSkeletonModel(), + "setURL", Q_ARG(QUrl, QUrl(valueList[i]))); + } + } + } + } + } +} + +void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer) { + unsigned char packetData[MAX_PACKET_SIZE]; + memcpy(packetData, datagram.data(), datagram.size()); + + int numBytesPacketHeader = numBytesForPacketHeader(packetData); + + int bytesRead = numBytesPacketHeader; + + unsigned char avatarData[MAX_PACKET_SIZE]; + int numBytesDummyPacketHeader = populateTypeAndVersion(avatarData, PACKET_TYPE_HEAD_DATA); + + // enumerate over all of the avatars in this packet + // 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)); + + AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID); + + if (!matchingAvatar) { + // construct a new Avatar for this node + matchingAvatar = AvatarSharedPointer(new Avatar()); + matchingAvatar->setOwningAvatarMixer(mixerWeakPointer); + + // insert the new avatar into our hash + _avatarHash.insert(nodeUUID, matchingAvatar); + + // new UUID requires mesh and skeleton request to data-server + DataServerClient::getValuesForKeysAndUUID(QStringList() << DataServerKey::FaceMeshURL << DataServerKey::SkeletonURL, + nodeUUID, this); + + qDebug() << "Adding avatar with UUID" << nodeUUID << "to AvatarManager hash."; + } + + // copy the rest of the packet to the avatarData holder so we can read the next Avatar from there + memcpy(avatarData + numBytesDummyPacketHeader, packetData + bytesRead, datagram.size() - bytesRead); + + // have the matching (or new) avatar parse the data from the packet + bytesRead += matchingAvatar->parseData(avatarData, datagram.size() - bytesRead); + } +} + +void AvatarManager::processKillAvatar(const QByteArray& datagram) { + // read the node id + QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(reinterpret_cast + (datagram.data())), + NUM_BYTES_RFC4122_UUID)); + + // remove the avatar with that UUID from our hash, if it exists + AvatarHash::iterator matchedAvatar = _avatarHash.find(nodeUUID); + if (matchedAvatar != _avatarHash.end()) { + removeAvatarAtHashIterator(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); +} + +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); + } +} \ No newline at end of file diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h new file mode 100644 index 0000000000..7d0f11646d --- /dev/null +++ b/interface/src/avatar/AvatarManager.h @@ -0,0 +1,60 @@ +// +// AvatarManager.h +// hifi +// +// Created by Stephen Birarda on 1/23/2014. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__AvatarManager__ +#define __hifi__AvatarManager__ + +#include +#include +#include + +#include + +#include "Avatar.h" + +typedef QSharedPointer AvatarSharedPointer; +typedef QHash AvatarHash; + +class AvatarManager : public QObject, public DataServerCallbackObject { + Q_OBJECT +public: + AvatarManager(QObject* parent = 0); + + const AvatarHash& getAvatarHash() { return _avatarHash; } + int size() const { return _avatarHash.size(); } + + Avatar* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); } + + void updateLookAtTargetAvatar(glm::vec3& eyePosition); + + void updateAvatars(float deltaTime); + void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false); + + void clearHash(); + +public slots: + void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList); + + void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer); + void processKillAvatar(const QByteArray& datagram); + +private: + void simulateAvatarFades(float deltaTime); + void renderAvatarFades(); + + AvatarHash::iterator removeAvatarAtHashIterator(const AvatarHash::iterator& iterator); + + QWeakPointer _lookAtTargetAvatar; + glm::vec3 _lookAtOtherPosition; + float _lookAtIndicatorScale; + + AvatarHash _avatarHash; + QVector _avatarFades; +}; + +#endif /* defined(__hifi__AvatarManager__) */ diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index e5aa33ad40..18d6031f98 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -43,7 +43,7 @@ Hand::Hand(Avatar* owningAvatar) : void Hand::init() { // Different colors for my hand and others' hands - if (_owningAvatar && _owningAvatar->getOwningNode() == NULL) { + if (_owningAvatar && _owningAvatar->isMyAvatar()) { _ballColor = glm::vec3(0.0, 0.4, 0.0); } else { @@ -54,8 +54,6 @@ void Hand::init() { void Hand::reset() { } - - glm::vec3 Hand::getAndResetGrabDelta() { const float HAND_GRAB_SCALE_DISTANCE = 2.f; glm::vec3 delta = _grabDelta * _owningAvatar->getScale() * HAND_GRAB_SCALE_DISTANCE; @@ -185,49 +183,46 @@ void Hand::updateCollisions() { glm::vec3 totalPenetration; // check other avatars - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { - Avatar* otherAvatar = (Avatar*)node->getLinkedData(); - if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { - // Check for palm collisions - glm::vec3 myPalmPosition = palm.getPosition(); - float palmCollisionDistance = 0.1f; - bool wasColliding = palm.getIsCollidingWithPalm(); - palm.setIsCollidingWithPalm(false); - // If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound - for (size_t j = 0; j < otherAvatar->getHand().getNumPalms(); j++) { - PalmData& otherPalm = otherAvatar->getHand().getPalms()[j]; - if (!otherPalm.isActive()) { - continue; - } - glm::vec3 otherPalmPosition = otherPalm.getPosition(); - if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { - palm.setIsCollidingWithPalm(true); - if (!wasColliding) { - const float PALM_COLLIDE_VOLUME = 1.f; - const float PALM_COLLIDE_FREQUENCY = 1000.f; - 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); - // 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) { - // add slapback here - } + foreach (const AvatarSharedPointer& avatar, Application::getInstance()->getAvatarManager().getAvatarHash()) { + if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) { + // Check for palm collisions + glm::vec3 myPalmPosition = palm.getPosition(); + float palmCollisionDistance = 0.1f; + bool wasColliding = palm.getIsCollidingWithPalm(); + palm.setIsCollidingWithPalm(false); + // If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound + for (size_t j = 0; j < avatar->getHand().getNumPalms(); j++) { + PalmData& otherPalm = avatar->getHand().getPalms()[j]; + if (!otherPalm.isActive()) { + continue; + } + glm::vec3 otherPalmPosition = otherPalm.getPosition(); + if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) { + palm.setIsCollidingWithPalm(true); + if (!wasColliding) { + const float PALM_COLLIDE_VOLUME = 1.f; + const float PALM_COLLIDE_FREQUENCY = 1000.f; + 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); + // 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) { + // add slapback here } - - } + + } } - glm::vec3 avatarPenetration; - if (otherAvatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) { - totalPenetration = addPenetrations(totalPenetration, avatarPenetration); - // Check for collisions with the other avatar's leap palms - } + } + glm::vec3 avatarPenetration; + if (avatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) { + totalPenetration = addPenetrations(totalPenetration, avatarPenetration); + // Check for collisions with the other avatar's leap palms } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d10cd1b17d..ca7a3b863b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -37,8 +37,8 @@ const bool USING_HEAD_LEAN = false; const float SKIN_COLOR[] = {1.0f, 0.84f, 0.66f}; const float DARK_SKIN_COLOR[] = {0.9f, 0.78f, 0.63f}; -MyAvatar::MyAvatar(Node* owningNode) : - Avatar(owningNode), +MyAvatar::MyAvatar() : + Avatar(), _mousePressed(false), _bodyPitchDelta(0.0f), _bodyRollDelta(0.0f), @@ -472,6 +472,21 @@ void MyAvatar::loadData(QSettings* settings) { settings->endGroup(); } +void MyAvatar::sendKillAvatar() { + unsigned char packet[MAX_PACKET_SIZE]; + unsigned char* packetPosition = packet; + + packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_AVATAR); + + NodeList* nodeList = NodeList::getInstance(); + + QByteArray rfcUUID = nodeList->getOwnerUUID().toRfc4122(); + memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size()); + packetPosition += rfcUUID.size(); + + nodeList->broadcastToNodes(packet, packetPosition - packet, QSet() << NODE_TYPE_AVATAR_MIXER); +} + void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) { // first orbit horizontally glm::quat orientation = getOrientation(); @@ -776,16 +791,16 @@ void MyAvatar::updateChatCircle(float deltaTime) { // find all circle-enabled members and sort by distance QVector sortedAvatars; - foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { - if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { - SortedAvatar sortedAvatar; - sortedAvatar.avatar = (Avatar*)node->getLinkedData(); - if (!sortedAvatar.avatar->isChatCirclingEnabled()) { - continue; - } - sortedAvatar.distance = glm::distance(_position, sortedAvatar.avatar->getPosition()); - sortedAvatars.append(sortedAvatar); + foreach (const AvatarSharedPointer& avatar, Application::getInstance()->getAvatarManager().getAvatarHash()) { + SortedAvatar sortedAvatar; + sortedAvatar.avatar = avatar.data(); + + if (!sortedAvatar.avatar->isChatCirclingEnabled()) { + continue; } + + sortedAvatar.distance = glm::distance(_position, sortedAvatar.avatar->getPosition()); + sortedAvatars.append(sortedAvatar); } qSort(sortedAvatars.begin(), sortedAvatars.end()); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 894913f824..92afe530eb 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -24,8 +24,8 @@ enum AvatarHandState class MyAvatar : public Avatar { public: - MyAvatar(Node* owningNode = NULL); - + MyAvatar(); + void reset(); void simulate(float deltaTime, Transmitter* transmitter); void updateFromGyros(bool turnWithHead); @@ -62,6 +62,10 @@ public: void setDriveKeys(int key, float val) { _driveKeys[key] = val; }; bool getDriveKeys(int key) { return _driveKeys[key]; }; void jump() { _shouldJump = true; }; + + bool isMyAvatar() { return true; } + + static void sendKillAvatar(); // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; diff --git a/interface/src/avatar/Profile.cpp b/interface/src/avatar/Profile.cpp index dd2b547c47..83105f3f41 100644 --- a/interface/src/avatar/Profile.cpp +++ b/interface/src/avatar/Profile.cpp @@ -158,35 +158,11 @@ void Profile::processDataServerResponse(const QString& userString, const QString if (userString == _username || userString == uuidStringWithoutCurlyBraces(_uuid)) { qDebug("Changing user's face model URL to %s", valueList[i].toLocal8Bit().constData()); Application::getInstance()->getProfile()->setFaceModelURL(QUrl(valueList[i])); - } else { - // mesh URL for a UUID, find avatar in our list - SharedNodePointer matchingNode = NodeList::getInstance()->nodeWithUUID(QUuid(userString)); - if (matchingNode && matchingNode->getType() == NODE_TYPE_AGENT) { - qDebug() << "Changing mesh to" << valueList[i] << "for avatar with UUID" - << uuidStringWithoutCurlyBraces(matchingNode->getUUID()); - - Avatar* avatar = (Avatar *) matchingNode->getLinkedData(); - - QMetaObject::invokeMethod(&avatar->getHead().getFaceModel(), - "setURL", Q_ARG(QUrl, QUrl(valueList[i]))); - } } } else if (keyList[i] == DataServerKey::SkeletonURL) { if (userString == _username || userString == uuidStringWithoutCurlyBraces(_uuid)) { qDebug("Changing user's skeleton URL to %s", valueList[i].toLocal8Bit().constData()); Application::getInstance()->getProfile()->setSkeletonModelURL(QUrl(valueList[i])); - } else { - // skeleton URL for a UUID, find avatar in our list - SharedNodePointer matchingNode = NodeList::getInstance()->nodeWithUUID(QUuid(userString)); - if (matchingNode && matchingNode->getType() == NODE_TYPE_AGENT) { - qDebug() << "Changing skeleton to" << valueList[i] << "for avatar with UUID" - << uuidStringWithoutCurlyBraces(matchingNode->getUUID()); - - Avatar* avatar = (Avatar *) matchingNode->getLinkedData(); - - QMetaObject::invokeMethod(&avatar->getSkeletonModel(), - "setURL", Q_ARG(QUrl, QUrl(valueList[i]))); - } } } else if (keyList[i] == DataServerKey::Domain && keyList[i + 1] == DataServerKey::Position && keyList[i + 2] == DataServerKey::Orientation && valueList[i] != " " && @@ -198,7 +174,7 @@ void Profile::processDataServerResponse(const QString& userString, const QString if (coordinateItems.size() == 3 && orientationItems.size() == 3) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect - NodeList::getInstance()->sendKillNode(QSet() << NODE_TYPE_AVATAR_MIXER); + MyAvatar::sendKillAvatar(); qDebug() << "Changing domain to" << valueList[i].toLocal8Bit().constData() << ", position to" << valueList[i + 1].toLocal8Bit().constData() << @@ -211,8 +187,7 @@ void Profile::processDataServerResponse(const QString& userString, const QString orientationItems[1].toFloat(), orientationItems[2].toFloat()))) * glm::angleAxis(180.0f, 0.0f, 1.0f, 0.0f); - Application::getInstance()->getAvatar() - ->setOrientation(newOrientation); + Application::getInstance()->getAvatar()->setOrientation(newOrientation); // move the user a couple units away const float DISTANCE_TO_USER = 2.0f; diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index c471c896a4..e65d4632f6 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -16,7 +16,7 @@ #include "AudioRingBuffer.h" AudioRingBuffer::AudioRingBuffer(int numFrameSamples) : - NodeData(NULL), + NodeData(), _sampleCapacity(numFrameSamples * RING_BUFFER_LENGTH_FRAMES), _isStarved(true), _hasStarted(false) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1ae44bb57a..8f548869ec 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -22,8 +22,8 @@ using namespace std; static const float fingerVectorRadix = 4; // bits of precision when converting from float<->fixed -AvatarData::AvatarData(Node* owningNode) : - NodeData(owningNode), +AvatarData::AvatarData() : + NodeData(), _handPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index ac0d198fc9..fc9bad7f02 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -70,7 +70,7 @@ class AvatarData : public NodeData { Q_PROPERTY(float bodyRoll READ getBodyRoll WRITE setBodyRoll) Q_PROPERTY(QString chatMessage READ getQStringChatMessage WRITE setChatMessage) public: - AvatarData(Node* owningNode = NULL); + AvatarData(); ~AvatarData(); const glm::vec3& getPosition() const { return _position; } diff --git a/libraries/octree-server/src/OctreeQueryNode.cpp b/libraries/octree-server/src/OctreeQueryNode.cpp index a932266d7d..f220180980 100644 --- a/libraries/octree-server/src/OctreeQueryNode.cpp +++ b/libraries/octree-server/src/OctreeQueryNode.cpp @@ -13,8 +13,7 @@ #include #include "OctreeSendThread.h" -OctreeQueryNode::OctreeQueryNode(Node* owningNode) : - OctreeQuery(owningNode), +OctreeQueryNode::OctreeQueryNode() : _viewSent(false), _octreePacketAvailableBytes(MAX_PACKET_SIZE), _maxSearchLevel(1), @@ -38,9 +37,8 @@ OctreeQueryNode::OctreeQueryNode(Node* owningNode) : _sequenceNumber = 0; } -void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer) { +void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* octreeServer, const QUuid& nodeUUID) { // Create octree sending thread... - QUuid nodeUUID = getOwningNode()->getUUID(); _octreeSendThread = new OctreeSendThread(nodeUUID, octreeServer); _octreeSendThread->initialize(true); } diff --git a/libraries/octree-server/src/OctreeQueryNode.h b/libraries/octree-server/src/OctreeQueryNode.h index 865f1607ab..6fc3c1a07b 100644 --- a/libraries/octree-server/src/OctreeQueryNode.h +++ b/libraries/octree-server/src/OctreeQueryNode.h @@ -24,7 +24,7 @@ class OctreeServer; class OctreeQueryNode : public OctreeQuery { public: - OctreeQueryNode(Node* owningNode); + OctreeQueryNode(); virtual ~OctreeQueryNode(); virtual PACKET_TYPE getMyPacketType() const = 0; @@ -80,7 +80,7 @@ public: OctreeSceneStats stats; - void initializeOctreeSendThread(OctreeServer* octreeServer); + void initializeOctreeSendThread(OctreeServer* octreeServer, const QUuid& nodeUUID); bool isOctreeSendThreadInitalized() { return _octreeSendThread; } void dumpOutOfView(); diff --git a/libraries/octree-server/src/OctreeServer.cpp b/libraries/octree-server/src/OctreeServer.cpp index cc362f58a0..438f71dd16 100644 --- a/libraries/octree-server/src/OctreeServer.cpp +++ b/libraries/octree-server/src/OctreeServer.cpp @@ -22,23 +22,12 @@ OctreeServer* OctreeServer::_instance = NULL; void OctreeServer::attachQueryNodeToNode(Node* newNode) { if (newNode->getLinkedData() == NULL) { - OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode(newNode); + OctreeQueryNode* newQueryNodeData = _instance->createOctreeQueryNode(); newQueryNodeData->resetOctreePacket(true); // don't bump sequence newNode->setLinkedData(newQueryNodeData); } } -void OctreeServer::nodeKilled(SharedNodePointer node) { - // Use this to cleanup our node - if (node->getType() == NODE_TYPE_AGENT) { - OctreeQueryNode* nodeData = (OctreeQueryNode*)node->getLinkedData(); - if (nodeData) { - node->setLinkedData(NULL); - delete nodeData; - } - } -}; - OctreeServer::OctreeServer(const unsigned char* dataBuffer, int numBytes) : ThreadedAssignment(dataBuffer, numBytes), _argc(0), @@ -499,7 +488,7 @@ void OctreeServer::processDatagram(const QByteArray& dataByteArray, const HifiSo } OctreeQueryNode* nodeData = (OctreeQueryNode*) node->getLinkedData(); if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { - nodeData->initializeOctreeSendThread(this); + nodeData->initializeOctreeSendThread(this, nodeUUID); } } } else if (packetType == PACKET_TYPE_JURISDICTION_REQUEST) { @@ -573,8 +562,6 @@ void OctreeServer::run() { setvbuf(stdout, NULL, _IOLBF, 0); - // tell our NodeList about our desire to get notifications - connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), this, SLOT(nodeKilled(SharedNodePointer))); nodeList->linkedDataCreateCallback = &OctreeServer::attachQueryNodeToNode; srand((unsigned)time(0)); diff --git a/libraries/octree-server/src/OctreeServer.h b/libraries/octree-server/src/OctreeServer.h index c68f09b6e0..86ad134df0 100644 --- a/libraries/octree-server/src/OctreeServer.h +++ b/libraries/octree-server/src/OctreeServer.h @@ -48,7 +48,7 @@ public: uint64_t getLoadElapsedTime() const { return (_persistThread) ? _persistThread->getLoadElapsedTime() : 0; } // Subclasses must implement these methods - virtual OctreeQueryNode* createOctreeQueryNode(Node* newNode) = 0; + virtual OctreeQueryNode* createOctreeQueryNode() = 0; virtual Octree* createTree() = 0; virtual unsigned char getMyNodeType() const = 0; virtual PACKET_TYPE getMyQueryMessageType() const = 0; @@ -69,8 +69,6 @@ public slots: void run(); void processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr); - void nodeKilled(SharedNodePointer node); - protected: void parsePayload(); void initHTTPManager(int port); diff --git a/libraries/octree/src/JurisdictionListener.h b/libraries/octree/src/JurisdictionListener.h index 110b2f0d98..fea76f57eb 100644 --- a/libraries/octree/src/JurisdictionListener.h +++ b/libraries/octree/src/JurisdictionListener.h @@ -23,6 +23,7 @@ /// within the domain. As with other ReceivedPacketProcessor classes the user is responsible for reading inbound packets /// and adding them to the processing queue by calling queueReceivedPacket() class JurisdictionListener : public ReceivedPacketProcessor { + Q_OBJECT public: static const int DEFAULT_PACKETS_PER_SECOND = 1; static const int NO_SERVER_CHECK_RATE = 60; // if no servers yet detected, keep checking at 60fps diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index dd65fe5246..ec474beb3d 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -22,8 +22,8 @@ using namespace std; static const float fingerVectorRadix = 4; // bits of precision when converting from float<->fixed -OctreeQuery::OctreeQuery(Node* owningNode) : - NodeData(owningNode), +OctreeQuery::OctreeQuery() : + NodeData(), _uuid(), _cameraPosition(0,0,0), _cameraOrientation(), diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index 8be18ea441..c306c5a851 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -51,7 +51,7 @@ class OctreeQuery : public NodeData { Q_OBJECT public: - OctreeQuery(Node* owningNode = NULL); + OctreeQuery(); virtual ~OctreeQuery(); int getBroadcastData(unsigned char* destinationBuffer); diff --git a/libraries/particle-server/src/ParticleNodeData.h b/libraries/particle-server/src/ParticleNodeData.h index 5d6655f505..1758b2e9a3 100644 --- a/libraries/particle-server/src/ParticleNodeData.h +++ b/libraries/particle-server/src/ParticleNodeData.h @@ -15,8 +15,8 @@ class ParticleNodeData : public OctreeQueryNode { public: - ParticleNodeData(Node* owningNode) : - OctreeQueryNode(owningNode), + ParticleNodeData() : + OctreeQueryNode(), _lastDeletedParticlesSentAt(0) { }; virtual PACKET_TYPE getMyPacketType() const { return PACKET_TYPE_PARTICLE_DATA; } diff --git a/libraries/particle-server/src/ParticleServer.cpp b/libraries/particle-server/src/ParticleServer.cpp index 9d7d70db83..6df12e5ff2 100644 --- a/libraries/particle-server/src/ParticleServer.cpp +++ b/libraries/particle-server/src/ParticleServer.cpp @@ -26,8 +26,8 @@ ParticleServer::~ParticleServer() { tree->removeNewlyCreatedHook(this); } -OctreeQueryNode* ParticleServer::createOctreeQueryNode(Node* newNode) { - return new ParticleNodeData(newNode); +OctreeQueryNode* ParticleServer::createOctreeQueryNode() { + return new ParticleNodeData(); } Octree* ParticleServer::createTree() { diff --git a/libraries/particle-server/src/ParticleServer.h b/libraries/particle-server/src/ParticleServer.h index e925d4e9ce..55e1b77285 100644 --- a/libraries/particle-server/src/ParticleServer.h +++ b/libraries/particle-server/src/ParticleServer.h @@ -24,7 +24,7 @@ public: ~ParticleServer(); // Subclasses must implement these methods - virtual OctreeQueryNode* createOctreeQueryNode(Node* newNode); + virtual OctreeQueryNode* createOctreeQueryNode(); virtual Octree* createTree(); virtual unsigned char getMyNodeType() const { return NODE_TYPE_PARTICLE_SERVER; } virtual PACKET_TYPE getMyQueryMessageType() const { return PACKET_TYPE_PARTICLE_QUERY; } diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 8eb525a388..7e8866e7d4 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -191,37 +191,37 @@ 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(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); - } - } - } - } +// foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { +// //qDebug() << "updateCollisionWithAvatars()... node:" << *node << "\n"; +// if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) { +// AvatarData* avatar = static_cast(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); +// } +// } +// } +// } } // TODO: convert applyHardCollision() to take a CollisionInfo& instead of penetration + addedVelocity diff --git a/libraries/shared/src/Node.cpp b/libraries/shared/src/Node.cpp index fa8bf0ef8f..603e1febba 100644 --- a/libraries/shared/src/Node.cpp +++ b/libraries/shared/src/Node.cpp @@ -39,7 +39,7 @@ Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const Node::~Node() { if (_linkedData) { - _linkedData->deleteOrDeleteLater(); + delete _linkedData; } delete _bytesReceivedMovingAverage; diff --git a/libraries/shared/src/NodeData.cpp b/libraries/shared/src/NodeData.cpp index 6ab7f2242b..a7fa18f409 100644 --- a/libraries/shared/src/NodeData.cpp +++ b/libraries/shared/src/NodeData.cpp @@ -8,16 +8,6 @@ #include "NodeData.h" -NodeData::NodeData(Node* owningNode) : - _owningNode(owningNode) -{ - -} - NodeData::~NodeData() { - -} - -void NodeData::deleteOrDeleteLater() { - delete this; + } \ No newline at end of file diff --git a/libraries/shared/src/NodeData.h b/libraries/shared/src/NodeData.h index 252b03ccc5..af5d13cd04 100644 --- a/libraries/shared/src/NodeData.h +++ b/libraries/shared/src/NodeData.h @@ -16,16 +16,9 @@ class Node; class NodeData : public QObject { Q_OBJECT public: - NodeData(Node* owningNode = NULL); virtual ~NodeData() = 0; virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0; - - virtual void deleteOrDeleteLater(); - - Node* getOwningNode() { return _owningNode; } -protected: - Node* _owningNode; }; #endif diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 0a3132e54b..5c5791d475 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -178,53 +178,6 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char processSTUNResponse(packetData, dataBytes); break; } - case PACKET_TYPE_KILL_NODE: { - processKillNode(packetData, dataBytes); - break; - } - } -} - -void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) { - SharedNodePointer bulkSendNode = nodeWithAddress(senderAddress); - - // find the avatar mixer in our node list and update the lastRecvTime from it - if (bulkSendNode) { - - bulkSendNode->setLastHeardMicrostamp(usecTimestampNow()); - bulkSendNode->recordBytesReceived(numTotalBytes); - - int numBytesPacketHeader = numBytesForPacketHeader(packetData); - - unsigned char* startPosition = packetData; - unsigned char* currentPosition = startPosition + numBytesPacketHeader; - unsigned char* packetHolder = new unsigned char[numTotalBytes]; - - // we've already verified packet version for the bulk packet, so all head data in the packet is also up to date - populateTypeAndVersion(packetHolder, PACKET_TYPE_HEAD_DATA); - - while ((currentPosition - startPosition) < numTotalBytes) { - - memcpy(packetHolder + numBytesPacketHeader, - currentPosition, - numTotalBytes - (currentPosition - startPosition)); - - QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)currentPosition, NUM_BYTES_RFC4122_UUID)); - SharedNodePointer matchingNode = nodeWithUUID(nodeUUID); - - if (!matchingNode) { - // we're missing this node, we need to add it to the list - matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr()); - } - - currentPosition += updateNodeWithData(matchingNode.data(), - HifiSockAddr(), - packetHolder, - numTotalBytes - (currentPosition - startPosition)); - - } - - delete[] packetHolder; } } @@ -460,30 +413,13 @@ NodeHash::iterator NodeList::killNodeAtHashIterator(NodeHash::iterator& nodeItem return _nodeHash.erase(nodeItemToKill); } -void NodeList::sendKillNode(const QSet& destinationNodeTypes) { - unsigned char packet[MAX_PACKET_SIZE]; - unsigned char* packetPosition = packet; - - packetPosition += populateTypeAndVersion(packetPosition, PACKET_TYPE_KILL_NODE); - - QByteArray rfcUUID = _ownerUUID.toRfc4122(); - memcpy(packetPosition, rfcUUID.constData(), rfcUUID.size()); - packetPosition += rfcUUID.size(); - - broadcastToNodes(packet, packetPosition - packet, destinationNodeTypes); -} - -void NodeList::processKillNode(unsigned char* packetData, size_t dataBytes) { - // skip the header - int numBytesPacketHeader = numBytesForPacketHeader(packetData); - packetData += numBytesPacketHeader; - dataBytes -= numBytesPacketHeader; - +void NodeList::processKillNode(const QByteArray& dataByteArray) { // read the node id - QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)packetData, NUM_BYTES_RFC4122_UUID)); + QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader(reinterpret_cast + (dataByteArray.data())), + NUM_BYTES_RFC4122_UUID)); - packetData += NUM_BYTES_RFC4122_UUID; - dataBytes -= NUM_BYTES_RFC4122_UUID; + // kill the node with this UUID, if it exists killNodeWithUUID(nodeUUID); } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 13f9485069..c660517add 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -104,8 +104,6 @@ public: int fillPingPacket(unsigned char* buffer); int fillPingReplyPacket(unsigned char* pingBuffer, unsigned char* replyBuffer); void pingPublicAndLocalSocketsForInactiveNode(Node* node); - - void sendKillNode(const QSet& destinationNodeTypes); SharedNodePointer nodeWithAddress(const HifiSockAddr& senderSockAddr); SharedNodePointer nodeWithUUID(const QUuid& nodeUUID); @@ -113,7 +111,8 @@ public: SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes); - void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes); + + void processKillNode(const QByteArray& datagram); int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes); @@ -144,7 +143,6 @@ private: void sendSTUNRequest(); void processSTUNResponse(unsigned char* packetData, size_t dataBytes); - void processKillNode(unsigned char* packetData, size_t dataBytes); NodeHash::iterator killNodeAtHashIterator(NodeHash::iterator& nodeItemToKill); NodeHash _nodeHash; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index a7176fccf8..1febc9367d 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -20,7 +20,7 @@ const PACKET_TYPE PACKET_TYPE_STUN_RESPONSE = 1; const PACKET_TYPE PACKET_TYPE_DOMAIN = 'D'; const PACKET_TYPE PACKET_TYPE_PING = 'P'; const PACKET_TYPE PACKET_TYPE_PING_REPLY = 'R'; -const PACKET_TYPE PACKET_TYPE_KILL_NODE = 'K'; +const PACKET_TYPE PACKET_TYPE_KILL_AVATAR = 'K'; const PACKET_TYPE PACKET_TYPE_HEAD_DATA = 'H'; const PACKET_TYPE PACKET_TYPE_INJECT_AUDIO = 'I'; const PACKET_TYPE PACKET_TYPE_MIXED_AUDIO = 'A'; diff --git a/libraries/voxel-server/src/VoxelNodeData.h b/libraries/voxel-server/src/VoxelNodeData.h index 92a5230567..9697b9cec3 100644 --- a/libraries/voxel-server/src/VoxelNodeData.h +++ b/libraries/voxel-server/src/VoxelNodeData.h @@ -14,7 +14,7 @@ class VoxelNodeData : public OctreeQueryNode { public: - VoxelNodeData(Node* owningNode) : OctreeQueryNode(owningNode) { }; + VoxelNodeData() : OctreeQueryNode() { }; virtual PACKET_TYPE getMyPacketType() const { return PACKET_TYPE_VOXEL_DATA; } }; diff --git a/libraries/voxel-server/src/VoxelServer.cpp b/libraries/voxel-server/src/VoxelServer.cpp index c8aee246e3..3a8c0d1364 100644 --- a/libraries/voxel-server/src/VoxelServer.cpp +++ b/libraries/voxel-server/src/VoxelServer.cpp @@ -24,8 +24,8 @@ VoxelServer::~VoxelServer() { // nothing special to do here... } -OctreeQueryNode* VoxelServer::createOctreeQueryNode(Node* newNode) { - return new VoxelNodeData(newNode); +OctreeQueryNode* VoxelServer::createOctreeQueryNode() { + return new VoxelNodeData(); } Octree* VoxelServer::createTree() { diff --git a/libraries/voxel-server/src/VoxelServer.h b/libraries/voxel-server/src/VoxelServer.h index 316280e37c..06cea132c0 100644 --- a/libraries/voxel-server/src/VoxelServer.h +++ b/libraries/voxel-server/src/VoxelServer.h @@ -34,7 +34,7 @@ public: int getEnvironmentDataCount() const { return sizeof(_environmentData)/sizeof(EnvironmentData); } // Subclasses must implement these methods - virtual OctreeQueryNode* createOctreeQueryNode(Node* newNode); + virtual OctreeQueryNode* createOctreeQueryNode(); virtual Octree* createTree(); virtual unsigned char getMyNodeType() const { return NODE_TYPE_VOXEL_SERVER; } virtual PACKET_TYPE getMyQueryMessageType() const { return PACKET_TYPE_VOXEL_QUERY; } diff --git a/libraries/voxels/src/VoxelQuery.cpp b/libraries/voxels/src/VoxelQuery.cpp index b595f448cb..239b352ca1 100644 --- a/libraries/voxels/src/VoxelQuery.cpp +++ b/libraries/voxels/src/VoxelQuery.cpp @@ -6,9 +6,4 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#include "VoxelQuery.h" - -VoxelQuery::VoxelQuery(Node* owningNode) : OctreeQuery(owningNode) { -} - - +#include "VoxelQuery.h" \ No newline at end of file diff --git a/libraries/voxels/src/VoxelQuery.h b/libraries/voxels/src/VoxelQuery.h index 0a4cdda6a4..6898430d82 100644 --- a/libraries/voxels/src/VoxelQuery.h +++ b/libraries/voxels/src/VoxelQuery.h @@ -14,10 +14,8 @@ class VoxelQuery : public OctreeQuery { public: - VoxelQuery(Node* owningNode = NULL); - // currently just an alias - + VoxelQuery() : OctreeQuery() {}; private: // privatize the copy constructor and assignment operator so they cannot be called VoxelQuery(const VoxelQuery&);