From 09df9d3dc733946ebd3c3a42ff80f83aea0f7400 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Wed, 3 Apr 2013 15:17:15 -0600 Subject: [PATCH 01/31] Second take on avatar mixer --- CMakeLists.txt | 1 + avatar/CMakeLists.txt | 17 ++++++ avatar/src/avatar.cpp | 120 +++++++++++++++++++++++++++++++++++++++ avatar/src/avatar.h | 0 shared/src/PacketCodes.h | 15 +++++ 5 files changed, 153 insertions(+) create mode 100644 avatar/CMakeLists.txt create mode 100644 avatar/src/avatar.cpp create mode 100644 avatar/src/avatar.h create mode 100644 shared/src/PacketCodes.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fd99276c2..742c59ecea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8) project(hifi) add_subdirectory(space) +add_subdirectory(avatar) add_subdirectory(domain) add_subdirectory(mixer) add_subdirectory(voxel) diff --git a/avatar/CMakeLists.txt b/avatar/CMakeLists.txt new file mode 100644 index 0000000000..c75693302e --- /dev/null +++ b/avatar/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 2.8) + +project(avatar) + +# grab the implemenation and header files +file(GLOB AVATAR_SRCS src/*.cpp src/*.h) + +# add the executable +add_executable(avatar ${AVATAR_SRCS}) + +# link the shared hifi library +include(../LinkHifiShared.cmake) +link_hifi_shared_library(avatar) + +# link the threads library +find_package(Threads REQUIRED) +target_link_libraries(avatar ${CMAKE_THREAD_LIBS_INIT}) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp new file mode 100644 index 0000000000..e321133eae --- /dev/null +++ b/avatar/src/avatar.cpp @@ -0,0 +1,120 @@ +// +// avatar.cpp +// Avatar Mixer +// +// Created by Leonardo Murillo on 03/25/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved +// +// The avatar mixer receives head, hand and positional data from all connected +// agents, and broadcasts that data back to them, every BROADCAST_INTERVAL ms. +// +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "avatar.h" + +AgentList agentList(PKT_AVATAR_MIXER, AVATAR_LISTEN_PORT); +const char *packetFormat = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; + +unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { + Head *agentHead = (Head *)agentToAdd->getLinkedData(); + Hand *agentHand = (Hand *)agentToAdd->getLinkedData(); + unsigned char *packetData; + glm::vec3 headPosition = agentHead->getPos(); + glm::vec3 handPosition = agentHand->getPos(); + + *currentPosition += packAgentId(currentPosition, agentToAdd->getAgentId()); + currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); + + sprintf(packetData, packetFormat, agentHead->getPitch(), + agentHead->getYaw(), + agentHead->getRoll(), + headPosition.x, + headPosition.y, + headPosition.z, + agentHead->getLoudness(), + agentHead->getAverageLoudness(), + handPosition.x, + handPosition.y, + handPosition.z) + + memcpy(currentPosition, packetData, strlen(packetData)); + currentPosition += strlen(packetData); + + // return the new unsigned char * for broadcast packet + return currentPosition; +} + +void *sendAvatarData(void *args) +{ + timeval startTime; + while (true) { + gettimeofday(&startTime, NULL); + + unsigned char *currentBufferPosition; + unsigned char *startPointer; + unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; + + *broadcastPacket = PKT_AGENT_DATA; + currentBufferPosition = broadcastPacket + 1; + startPointer = currentBufferPosition; + + // Construct packet with data for all agents + for (std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) { + if (agent->getLinkedData() != NULL) { + addAgentToBroadcastPacket(currentBufferPosition, agent); + } + } + + // Stream the constructed packet to all agents + for (std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) { + agentList.getAgentSocket().send(agent->getActiveSocket(), broadcastPacket, strlen(broadcastPacket)); + } + + double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); + usleep(usecToSleep); + } +} + +int main(int argc, char* argv[]) +{ + setvbuf(stdout, NULL, _IOLBF, 0); + + agentList.startSilentAgentRemovalThread(); + agentList.startDomainServerCheckInThread(); + + pthread_t sendAvatarDataThread; + pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); + + sockaddr *agentAddress = new sockaddr; + unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; + ssize_t receivedBytes = 0; + + while (true) { + if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + if (packetData[0] == 'H') { + if (agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList.getLastAgentId())) { + agentList.increaseAgentId(); + } + agentList.updateAgentWithData(agentAddress, packetData, receivedBytes); + } + } + } +} diff --git a/avatar/src/avatar.h b/avatar/src/avatar.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/shared/src/PacketCodes.h b/shared/src/PacketCodes.h new file mode 100644 index 0000000000..525dff3481 --- /dev/null +++ b/shared/src/PacketCodes.h @@ -0,0 +1,15 @@ +// +// PacketCodes.h +// Packet codes used throughout all applications +// +// Created by Leonardo Murillo on 03/26/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved +// + +const char PKT_AVATAR_MIXER[] = "X"; +const char PKT_AUDIO_MIXER[] = "M"; +const char PKT_INTERACTIVE_AGENT[] = "I"; +const char PKT_AGENT_DATA[] = "H"; +const char PKT_DOMAIN_SERVER[] = "D"; +const char PKT_PING[] = "P"; +const char PKT_REPLY[] = "R"; From cb5d1b92143fe075aa4404a62c3beeb069ec77d2 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 09:22:34 -0600 Subject: [PATCH 02/31] Second take on Avatar Mixer --- avatar/src/avatar.cpp | 171 +++++++++++++++++++++++++++---------- avatar/src/avatar.h | 62 ++++++++++++++ shared/src/PacketHeaders.h | 1 + 3 files changed, 187 insertions(+), 47 deletions(-) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp index e321133eae..fbc5fa9ee3 100644 --- a/avatar/src/avatar.cpp +++ b/avatar/src/avatar.cpp @@ -22,43 +22,140 @@ #include #include #include -#include +#include #include #include #include #include #include +#include #include "avatar.h" -AgentList agentList(PKT_AVATAR_MIXER, AVATAR_LISTEN_PORT); -const char *packetFormat = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; +const int LISTEN_PORT = 55444; + +std::vector *avatarAgentList = new std::vector; + +AvatarAgent *findAvatarAgentBySocket(sockaddr *activeSocket) { + + sockaddr *agentSocketHolder = new sockaddr(); + + for (std::vector::iterator avatarAgent = avatarAgentList->begin(); + avatarAgent != avatarAgentList->end(); + avatarAgent++) { + agentSocketHolder = avatarAgent->getActiveSocket(); + if (agentSocketHolder->sa_family != activeSocket->sa_family) { + return NULL; + } + sockaddr_in *firstSocket = (sockaddr_in *) activeSocket; + sockaddr_in *secondSocket = (sockaddr_in *) agentSocketHolder; + + if (firstSocket->sin_addr.s_addr == secondSocket->sin_addr.s_addr && + firstSocket->sin_port == secondSocket->sin_port) { + return &*avatarAgent; + } else { + return NULL; + } + } +} + +// Constructor and Destructor +AvatarAgent::AvatarAgent() { + +} + +AvatarAgent::~AvatarAgent() { + +} + +// Property getters +sockaddr *AvatarAgent::getActiveSocket() { + return &_activeSocket; +} + +float AvatarAgent::getPitch() { + return _pitch; +} + +float AvatarAgent::getYaw() { + return _yaw; +} + +float AvatarAgent::getRoll() { + return _roll; +} + +std::map AvatarAgent::getHeadPosition() { + return _headPosition; +} + +float AvatarAgent::getLoudness() { + return _loudness; +} + +float AvatarAgent::getAverageLoudness() { + return _averageLoudness; +} + +std::map AvatarAgent::getHandPosition() { + return _handPosition; +} + +// Property setters +void AvatarAgent::setPitch(float pitch) { + _pitch = pitch; +} + +void AvatarAgent::setYaw(float yaw) { + _yaw = yaw; +} + +void AvatarAgent::setRoll(float roll) { + _roll = roll; +} + +void AvatarAgent::setHeadPosition(float x, float y, float z) { + _headPosition['x'] = x; + _headPosition['y'] = y; + _headPosition['z'] = z; +} + +void AvatarAgent::setLoudness(float loudness) { + _loudness = loudness; +} + +void AvatarAgent::setAverageLoudness(float averageLoudness) { + _averageLoudness = averageLoudness; +} + +void AvatarAgent::setHandPosition(float x, float y, float z) { + _handPosition['x'] = x; + _handPosition['y'] = y; + _handPosition['z'] = z; +} + unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { - Head *agentHead = (Head *)agentToAdd->getLinkedData(); - Hand *agentHand = (Hand *)agentToAdd->getLinkedData(); - unsigned char *packetData; - glm::vec3 headPosition = agentHead->getPos(); - glm::vec3 handPosition = agentHand->getPos(); + unsigned char *packetData = new unsigned char(); + AvatarAgent *thisAgent = new AvatarAgent(); *currentPosition += packAgentId(currentPosition, agentToAdd->getAgentId()); currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); - - sprintf(packetData, packetFormat, agentHead->getPitch(), - agentHead->getYaw(), - agentHead->getRoll(), - headPosition.x, - headPosition.y, - headPosition.z, - agentHead->getLoudness(), - agentHead->getAverageLoudness(), - handPosition.x, - handPosition.y, - handPosition.z) - - memcpy(currentPosition, packetData, strlen(packetData)); - currentPosition += strlen(packetData); - - // return the new unsigned char * for broadcast packet + + sprintf((char *)packetData, packetFormat, thisAgent->getPitch(), + thisAgent->getYaw(), + thisAgent->getRoll(), + thisAgent->getHeadPosition()[0], + thisAgent->getHeadPosition()[1], + thisAgent->getHeadPosition()[2], + thisAgent->getLoudness(), + thisAgent->getAverageLoudness(), + thisAgent->getHandPosition()[0], + thisAgent->getHandPosition()[1], + thisAgent->getHandPosition()[2]); + + memcpy(currentPosition, packetData, strlen((const char*)packetData)); + currentPosition += strlen((const char*)packetData); + return currentPosition; } @@ -72,21 +169,11 @@ void *sendAvatarData(void *args) unsigned char *startPointer; unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - *broadcastPacket = PKT_AGENT_DATA; + *broadcastPacket = *(unsigned char *)PACKET_HEADER_HEAD_DATA; currentBufferPosition = broadcastPacket + 1; startPointer = currentBufferPosition; - // Construct packet with data for all agents - for (std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) { - if (agent->getLinkedData() != NULL) { - addAgentToBroadcastPacket(currentBufferPosition, agent); - } - } - // Stream the constructed packet to all agents - for (std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) { - agentList.getAgentSocket().send(agent->getActiveSocket(), broadcastPacket, strlen(broadcastPacket)); - } double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); usleep(usecToSleep); @@ -97,9 +184,6 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); - agentList.startSilentAgentRemovalThread(); - agentList.startDomainServerCheckInThread(); - pthread_t sendAvatarDataThread; pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); @@ -108,13 +192,6 @@ int main(int argc, char* argv[]) ssize_t receivedBytes = 0; while (true) { - if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { - if (packetData[0] == 'H') { - if (agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList.getLastAgentId())) { - agentList.increaseAgentId(); - } - agentList.updateAgentWithData(agentAddress, packetData, receivedBytes); - } - } + } } diff --git a/avatar/src/avatar.h b/avatar/src/avatar.h index e69de29bb2..d462bbc1e4 100644 --- a/avatar/src/avatar.h +++ b/avatar/src/avatar.h @@ -0,0 +1,62 @@ +// +// avatar.h +// Avatar Mixer - Main header file +// +// Created by Leonardo Murillo on 03/25/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const unsigned short AVATAR_LISTEN_PORT = 55444; +const unsigned short BROADCAST_INTERVAL = 20; +const char *packetFormat = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; + +class AvatarAgent { +private: + sockaddr _activeSocket; + float _pitch; + float _yaw; + float _roll; + std::map _headPosition; + float _loudness; + float _averageLoudness; + std::map _handPosition; +public: + AvatarAgent(); + ~AvatarAgent(); + sockaddr *getActiveSocket(); + void setActiveSocket(sockaddr activeSocket); + float getPitch(); + void setPitch(float pitch); + float getYaw(); + void setYaw(float yaw); + float getRoll(); + void setRoll(float roll); + std::map getHeadPosition(); + void setHeadPosition(float x, float y, float z); + float getLoudness(); + void setLoudness(float loudness); + float getAverageLoudness(); + void setAverageLoudness(float averageLoudness); + std::map getHandPosition(); + void setHandPosition(float x, float y, float z); +}; \ No newline at end of file diff --git a/shared/src/PacketHeaders.h b/shared/src/PacketHeaders.h index 280aa69d70..6439ecb0c4 100644 --- a/shared/src/PacketHeaders.h +++ b/shared/src/PacketHeaders.h @@ -21,6 +21,7 @@ const char PACKET_HEADER_INJECT_AUDIO = 'I'; const char PACKET_HEADER_SET_VOXEL = 'S'; const char PACKET_HEADER_ERASE_VOXEL = 'E'; const char PACKET_HEADER_VOXEL_DATA = 'V'; +const char PACKET_HEADER_AVATAR_SERVER = 'X'; const char PACKET_HEADER_TRANSMITTER_DATA = 't'; #endif From f3a8e363dcd74cd203937e9a055c8fc128f91305 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 13:23:11 -0600 Subject: [PATCH 03/31] pushing new agents into list and changes to private properties --- avatar/src/avatar.cpp | 151 +++++++++++++++++++++++++++++++++--------- avatar/src/avatar.h | 33 +++++++-- 2 files changed, 144 insertions(+), 40 deletions(-) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp index fbc5fa9ee3..aade51712e 100644 --- a/avatar/src/avatar.cpp +++ b/avatar/src/avatar.cpp @@ -31,8 +31,6 @@ #include #include "avatar.h" -const int LISTEN_PORT = 55444; - std::vector *avatarAgentList = new std::vector; AvatarAgent *findAvatarAgentBySocket(sockaddr *activeSocket) { @@ -52,14 +50,34 @@ AvatarAgent *findAvatarAgentBySocket(sockaddr *activeSocket) { if (firstSocket->sin_addr.s_addr == secondSocket->sin_addr.s_addr && firstSocket->sin_port == secondSocket->sin_port) { return &*avatarAgent; - } else { - return NULL; } } + + return NULL; } // Constructor and Destructor -AvatarAgent::AvatarAgent() { +AvatarAgent::AvatarAgent(sockaddr activeSocket, + float pitch, + float yaw, + float roll, + float headPositionX, + float headPositionY, + float headPositionZ, + float loudness, + float averageLoudness, + float handPositionX, + float handPositionY, + float handPositionZ) { + + this->setActiveSocket(activeSocket); + this->setPitch(pitch); + this->setYaw(yaw); + this->setRoll(roll); + this->setHeadPosition(headPositionX, headPositionY, headPositionZ); + this->setLoudness(loudness); + this->setAverageLoudness(averageLoudness); + this->setHandPosition(handPositionX, handPositionY, handPositionZ); } @@ -84,8 +102,16 @@ float AvatarAgent::getRoll() { return _roll; } -std::map AvatarAgent::getHeadPosition() { - return _headPosition; +float AvatarAgent::getHeadPositionX() { + return _headPositionX; +} + +float AvatarAgent::getHeadPositionY() { + return _headPositionY; +} + +float AvatarAgent::getHeadPositionZ() { + return _headPositionZ; } float AvatarAgent::getLoudness() { @@ -96,8 +122,16 @@ float AvatarAgent::getAverageLoudness() { return _averageLoudness; } -std::map AvatarAgent::getHandPosition() { - return _handPosition; +float AvatarAgent::getHandPositionX() { + return _handPositionX; +} + +float AvatarAgent::getHandPositionY() { + return _handPositionY; +} + +float AvatarAgent::getHandPositionZ() { + return _handPositionZ; } // Property setters @@ -114,9 +148,9 @@ void AvatarAgent::setRoll(float roll) { } void AvatarAgent::setHeadPosition(float x, float y, float z) { - _headPosition['x'] = x; - _headPosition['y'] = y; - _headPosition['z'] = z; + _headPositionX = x; + _headPositionY = y; + _headPositionZ = z; } void AvatarAgent::setLoudness(float loudness) { @@ -128,30 +162,28 @@ void AvatarAgent::setAverageLoudness(float averageLoudness) { } void AvatarAgent::setHandPosition(float x, float y, float z) { - _handPosition['x'] = x; - _handPosition['y'] = y; - _handPosition['z'] = z; + _handPositionX = x; + _handPositionY = y; + _handPositionZ = z; } -unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { +unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, AvatarAgent *agentToAdd) { unsigned char *packetData = new unsigned char(); - AvatarAgent *thisAgent = new AvatarAgent(); - *currentPosition += packAgentId(currentPosition, agentToAdd->getAgentId()); currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); - sprintf((char *)packetData, packetFormat, thisAgent->getPitch(), - thisAgent->getYaw(), - thisAgent->getRoll(), - thisAgent->getHeadPosition()[0], - thisAgent->getHeadPosition()[1], - thisAgent->getHeadPosition()[2], - thisAgent->getLoudness(), - thisAgent->getAverageLoudness(), - thisAgent->getHandPosition()[0], - thisAgent->getHandPosition()[1], - thisAgent->getHandPosition()[2]); + sprintf((char *)packetData, packetFormat, agentToAdd->getPitch(), + agentToAdd->getYaw(), + agentToAdd->getRoll(), + agentToAdd->getHeadPosition()['x'], + agentToAdd->getHeadPosition()['y'], + agentToAdd->getHeadPosition()['z'], + agentToAdd->getLoudness(), + agentToAdd->getAverageLoudness(), + agentToAdd->getHandPosition()['x'], + agentToAdd->getHandPosition()['y'], + agentToAdd->getHandPosition()['z']); memcpy(currentPosition, packetData, strlen((const char*)packetData)); currentPosition += strlen((const char*)packetData); @@ -159,8 +191,7 @@ unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent * return currentPosition; } -void *sendAvatarData(void *args) -{ +void *sendAvatarData(void *args) { timeval startTime; while (true) { gettimeofday(&startTime, NULL); @@ -188,10 +219,64 @@ int main(int argc, char* argv[]) pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); sockaddr *agentAddress = new sockaddr; - unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; + char *packetData = new char[MAX_PACKET_SIZE]; ssize_t receivedBytes = 0; + UDPSocket *avatarMixerSocket = new UDPSocket(AVATAR_LISTEN_PORT); + AvatarAgent *matchingAgent = NULL; + + float *pitch; + float *yaw; + float *roll; + float *headPositionX; + float *headPositionY; + float *headPositionZ; + float *loudness; + float *averageLoudness; + float *handPositionX; + float *handPositionY; + float *handPositionZ; + while (true) { - + if (avatarMixerSocket->receive(agentAddress, packetData, &receivedBytes)) { + if (packetData[0] == PACKET_HEADER_HEAD_DATA) { + // Extract data from packet + sscanf(packetData + 1, + PACKET_FORMAT, + &pitch, + &yaw, + &roll, + &headPositionX, + &headPositionY, + &headPositionZ, + &loudness, + &averageLoudness, + &handPositionX, + &handPositionY, + &handPositionZ); + + matchingAgent = findAvatarAgentBySocket(agentAddress); + + if (matchingAgent) { + // We already have this agent on our list, just modify positional data + + } else { + // This is a new agent, we need to add to the list + AvatarAgent thisAgentHolder = *new AvatarAgent(*agentAddress, + *pitch, + *yaw, + *roll, + *headPositionX, + *headPositionY, + *headPositionZ, + *loudness, + *averageLoudness, + *handPositionX, + *handPositionY, + *handPositionZ); + avatarAgentList->push_back(thisAgentHolder); + } + } + } } } diff --git a/avatar/src/avatar.h b/avatar/src/avatar.h index d462bbc1e4..a476e60f29 100644 --- a/avatar/src/avatar.h +++ b/avatar/src/avatar.h @@ -26,9 +26,9 @@ #include #include -const unsigned short AVATAR_LISTEN_PORT = 55444; +const int AVATAR_LISTEN_PORT = 55444; const unsigned short BROADCAST_INTERVAL = 20; -const char *packetFormat = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; +const char *PACKET_FORMAT = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; class AvatarAgent { private: @@ -36,12 +36,27 @@ private: float _pitch; float _yaw; float _roll; - std::map _headPosition; + float _headPositionX; + float _headPositionY; + float _headPositionZ; float _loudness; float _averageLoudness; - std::map _handPosition; + float _handPositionX; + float _handPositionY; + float _handPositionZ; public: - AvatarAgent(); + AvatarAgent(sockaddr activeSocket, + float pitch, + float yaw, + float roll, + float headPositionX, + float headPositionY, + float headPositionZ, + float loudness, + float averageLoudness, + float handPositionX, + float handPositionY, + float handPositionZ); ~AvatarAgent(); sockaddr *getActiveSocket(); void setActiveSocket(sockaddr activeSocket); @@ -51,12 +66,16 @@ public: void setYaw(float yaw); float getRoll(); void setRoll(float roll); - std::map getHeadPosition(); + float getHeadPositionX(); + float getHeadPositionY(); + float getHeadPositionZ(); void setHeadPosition(float x, float y, float z); float getLoudness(); void setLoudness(float loudness); float getAverageLoudness(); void setAverageLoudness(float averageLoudness); - std::map getHandPosition(); + float getHandPositionX(); + float getHandPositionY(); + float getHandPositionZ(); void setHandPosition(float x, float y, float z); }; \ No newline at end of file From 64e563ef7c941e50ec7712fdbe8419e10912c305 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 14:01:57 -0600 Subject: [PATCH 04/31] Sending packets to agents --- avatar/src/avatar.cpp | 47 ++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp index aade51712e..ca2537546b 100644 --- a/avatar/src/avatar.cpp +++ b/avatar/src/avatar.cpp @@ -32,6 +32,7 @@ #include "avatar.h" std::vector *avatarAgentList = new std::vector; +UDPSocket *avatarMixerSocket = new UDPSocket(AVATAR_LISTEN_PORT); AvatarAgent *findAvatarAgentBySocket(sockaddr *activeSocket) { @@ -173,17 +174,17 @@ unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, AvatarA currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); - sprintf((char *)packetData, packetFormat, agentToAdd->getPitch(), - agentToAdd->getYaw(), - agentToAdd->getRoll(), - agentToAdd->getHeadPosition()['x'], - agentToAdd->getHeadPosition()['y'], - agentToAdd->getHeadPosition()['z'], - agentToAdd->getLoudness(), - agentToAdd->getAverageLoudness(), - agentToAdd->getHandPosition()['x'], - agentToAdd->getHandPosition()['y'], - agentToAdd->getHandPosition()['z']); + sprintf((char *)packetData, PACKET_FORMAT, agentToAdd->getPitch(), + agentToAdd->getYaw(), + agentToAdd->getRoll(), + agentToAdd->getHeadPositionX(), + agentToAdd->getHeadPositionY(), + agentToAdd->getHeadPositionZ(), + agentToAdd->getLoudness(), + agentToAdd->getAverageLoudness(), + agentToAdd->getHandPositionX(), + agentToAdd->getHandPositionY(), + agentToAdd->getHandPositionZ()); memcpy(currentPosition, packetData, strlen((const char*)packetData)); currentPosition += strlen((const char*)packetData); @@ -205,6 +206,21 @@ void *sendAvatarData(void *args) { startPointer = currentBufferPosition; + for (std::vector::iterator avatarAgent = avatarAgentList->begin(); + avatarAgent != avatarAgentList->end(); + avatarAgent++) { + + addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + + } + + for (std::vector::iterator avatarAgent = avatarAgentList->begin(); + avatarAgent != avatarAgentList->end(); + avatarAgent++) { + + avatarMixerSocket->send(avatarAgent->getActiveSocket(), broadcastPacket, strlen((const char *)broadcastPacket)); + + } double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); usleep(usecToSleep); @@ -222,7 +238,6 @@ int main(int argc, char* argv[]) char *packetData = new char[MAX_PACKET_SIZE]; ssize_t receivedBytes = 0; - UDPSocket *avatarMixerSocket = new UDPSocket(AVATAR_LISTEN_PORT); AvatarAgent *matchingAgent = NULL; float *pitch; @@ -258,7 +273,15 @@ int main(int argc, char* argv[]) matchingAgent = findAvatarAgentBySocket(agentAddress); if (matchingAgent) { + // We already have this agent on our list, just modify positional data + matchingAgent->setPitch(*pitch); + matchingAgent->setYaw(*yaw); + matchingAgent->setRoll(*roll); + matchingAgent->setHeadPosition(*headPositionX, *headPositionY, *headPositionZ); + matchingAgent->setLoudness(*loudness); + matchingAgent->setAverageLoudness(*averageLoudness); + matchingAgent->setHandPosition(*handPositionX, *handPositionY, *handPositionZ); } else { // This is a new agent, we need to add to the list From 35a8207769a671ac12b984f8b6d7997d1342a399 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 14:56:11 -0600 Subject: [PATCH 05/31] Deleting silent agents --- avatar/src/avatar.cpp | 42 +++++++++++++++++++++++++++++++++++------- avatar/src/avatar.h | 6 +++++- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp index ca2537546b..e4ca846718 100644 --- a/avatar/src/avatar.cpp +++ b/avatar/src/avatar.cpp @@ -69,7 +69,8 @@ AvatarAgent::AvatarAgent(sockaddr activeSocket, float averageLoudness, float handPositionX, float handPositionY, - float handPositionZ) { + float handPositionZ, + double lastHeartbeat) { this->setActiveSocket(activeSocket); this->setPitch(pitch); @@ -79,6 +80,7 @@ AvatarAgent::AvatarAgent(sockaddr activeSocket, this->setLoudness(loudness); this->setAverageLoudness(averageLoudness); this->setHandPosition(handPositionX, handPositionY, handPositionZ); + this->setLastHeartbeat(lastHeartbeat); } @@ -135,6 +137,10 @@ float AvatarAgent::getHandPositionZ() { return _handPositionZ; } +double AvatarAgent::getLastHeartbeat() { + return _lastHeartbeat; +} + // Property setters void AvatarAgent::setPitch(float pitch) { _pitch = pitch; @@ -168,6 +174,9 @@ void AvatarAgent::setHandPosition(float x, float y, float z) { _handPositionZ = z; } +void AvatarAgent::setLastHeartbeat(double lastHeartbeat) { + _lastHeartbeat = lastHeartbeat; +} unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, AvatarAgent *agentToAdd) { unsigned char *packetData = new unsigned char(); @@ -209,24 +218,39 @@ void *sendAvatarData(void *args) { for (std::vector::iterator avatarAgent = avatarAgentList->begin(); avatarAgent != avatarAgentList->end(); avatarAgent++) { - addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); - } for (std::vector::iterator avatarAgent = avatarAgentList->begin(); avatarAgent != avatarAgentList->end(); avatarAgent++) { - avatarMixerSocket->send(avatarAgent->getActiveSocket(), broadcastPacket, strlen((const char *)broadcastPacket)); - } double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); + delete[] broadcastPacket; usleep(usecToSleep); } } +void *popInactiveAvatarAgents(void *args) { + + double checkTime, sleepTime; + + while (true) { + checkTime = usecTimestampNow(); + + for (std::vector::iterator avatarAgent = avatarAgentList->begin(); + avatarAgent != avatarAgentList->end(); + avatarAgent++) { + if ((checkTime - avatarAgent->getLastHeartbeat()) > AGENT_SILENCE_THRESHOLD_USECS) { + avatarAgent = avatarAgentList->erase(avatarAgent); + } + } + + } +} + int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); @@ -234,6 +258,9 @@ int main(int argc, char* argv[]) pthread_t sendAvatarDataThread; pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); + pthread_t popInactiveAvatarAgentsThread; + pthread_create(&popInactiveAvatarAgentsThread, NULL, popInactiveAvatarAgents, NULL); + sockaddr *agentAddress = new sockaddr; char *packetData = new char[MAX_PACKET_SIZE]; ssize_t receivedBytes = 0; @@ -273,7 +300,6 @@ int main(int argc, char* argv[]) matchingAgent = findAvatarAgentBySocket(agentAddress); if (matchingAgent) { - // We already have this agent on our list, just modify positional data matchingAgent->setPitch(*pitch); matchingAgent->setYaw(*yaw); @@ -282,6 +308,7 @@ int main(int argc, char* argv[]) matchingAgent->setLoudness(*loudness); matchingAgent->setAverageLoudness(*averageLoudness); matchingAgent->setHandPosition(*handPositionX, *handPositionY, *handPositionZ); + matchingAgent->setLastHeartbeat(usecTimestampNow()); } else { // This is a new agent, we need to add to the list @@ -296,7 +323,8 @@ int main(int argc, char* argv[]) *averageLoudness, *handPositionX, *handPositionY, - *handPositionZ); + *handPositionZ, + usecTimestampNow()); avatarAgentList->push_back(thisAgentHolder); } } diff --git a/avatar/src/avatar.h b/avatar/src/avatar.h index a476e60f29..326f27d71a 100644 --- a/avatar/src/avatar.h +++ b/avatar/src/avatar.h @@ -44,6 +44,7 @@ private: float _handPositionX; float _handPositionY; float _handPositionZ; + double _lastHeartbeat; public: AvatarAgent(sockaddr activeSocket, float pitch, @@ -56,7 +57,8 @@ public: float averageLoudness, float handPositionX, float handPositionY, - float handPositionZ); + float handPositionZ, + double lastHeartbeat); ~AvatarAgent(); sockaddr *getActiveSocket(); void setActiveSocket(sockaddr activeSocket); @@ -78,4 +80,6 @@ public: float getHandPositionY(); float getHandPositionZ(); void setHandPosition(float x, float y, float z); + double getLastHeartbeat(); + void setLastHeartbeat(double lastHeartbeat); }; \ No newline at end of file From 6bff444f15abdd101aff21ee1c9c06e3e3c32731 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 14:58:27 -0600 Subject: [PATCH 06/31] Removing unnecessary header file --- shared/src/PacketCodes.h | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 shared/src/PacketCodes.h diff --git a/shared/src/PacketCodes.h b/shared/src/PacketCodes.h deleted file mode 100644 index 525dff3481..0000000000 --- a/shared/src/PacketCodes.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// PacketCodes.h -// Packet codes used throughout all applications -// -// Created by Leonardo Murillo on 03/26/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved -// - -const char PKT_AVATAR_MIXER[] = "X"; -const char PKT_AUDIO_MIXER[] = "M"; -const char PKT_INTERACTIVE_AGENT[] = "I"; -const char PKT_AGENT_DATA[] = "H"; -const char PKT_DOMAIN_SERVER[] = "D"; -const char PKT_PING[] = "P"; -const char PKT_REPLY[] = "R"; From 1cf75b37f3c77d0202949e8391c5d95c6fd5abe9 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 15:30:30 -0600 Subject: [PATCH 07/31] Changes to interface side of code --- interface/src/main.cpp | 5 +++-- shared/src/AgentList.cpp | 24 +++++++++++++++++++++++- shared/src/AgentList.h | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b8e2c190e7..1e95b42cc7 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -532,11 +532,12 @@ void simulateHead(float frametime) myHead.setAverageLoudness(averageLoudness); #endif - // Send my streaming head data to agents that are nearby and need to see it! + // Send my stream of head/hand data to the avatar mixer const int MAX_BROADCAST_STRING = 200; + const int AVATAR_SERVER_PORT = 55444; char broadcast_string[MAX_BROADCAST_STRING]; int broadcast_bytes = myHead.getBroadcastData(broadcast_string); - agentList.broadcastToAgents(broadcast_string, broadcast_bytes,AgentList::AGENTS_OF_TYPE_VOXEL_AND_INTERFACE); + agentList.getAgentSocket().send(AVATAR_SERVER_IP, AVATAR_SERVER_PORT, broadcast_string, broadcast_bytes); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) { diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index aa04d99c9a..03f5ff87c4 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -24,7 +24,9 @@ const char * SOLO_AGENT_TYPES_STRING = "MV"; char DOMAIN_HOSTNAME[] = "highfidelity.below92.com"; char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup +char AVATAR_SERVER_IP[100] = ""; const int DOMAINSERVER_PORT = 40102; +const int AVATAR_SERVER_PORT = 55444; bool silentAgentThreadStopFlag = false; bool domainServerCheckinStopFlag = false; @@ -77,7 +79,7 @@ void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size } case PACKET_HEADER_HEAD_DATA: { // head data from another agent - updateAgentWithData(senderAddress, packetData, dataBytes); + updateDataForAllAgents(senderAddress, (unsigned char *)packetData, dataBytes); break; } case PACKET_HEADER_PING: { @@ -95,6 +97,25 @@ void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size } } +void AgentList::updateDataForAllAgents(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { + unsigned char *currentPosition = packetData + 1; + unsigned char *startPosition = packetData; + unsigned char *packetHolder = new unsigned char[(sizeof(float) * 11) + 1]; + packetHolder[0] = *(unsigned char *)PACKET_HEADER_HEAD_DATA; + packetHolder++; + uint16_t agentId; + sockaddr_in *agentActiveSocket = new sockaddr_in; + agentActiveSocket->sin_family = AF_INET; + + while ((currentPosition - startPosition) < dataBytes) { + currentPosition += unpackAgentId(currentPosition, &agentId); + currentPosition += unpackSocket(currentPosition, (sockaddr *)&agentActiveSocket); + memcpy(packetHolder, currentPosition, sizeof(float) * 11); + currentPosition += sizeof(float) * 11; + updateAgentWithData((sockaddr *)agentActiveSocket, packetHolder, (sizeof(float) * 11) + 1); + } +} + void AgentList::updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes) { // find the agent by the sockaddr int agentIndex = indexOfMatchingAgent(senderAddress); @@ -327,6 +348,7 @@ void *checkInWithDomainServer(void *args) { sockaddr_in tempAddress; memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr)); + strcpy(AVATAR_SERVER_IP, inet_ntoa(tempAddress.sin_addr)); printf("Domain server %s: \n", DOMAIN_HOSTNAME); } else { diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index ca6d844b48..4a3cd2f234 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -56,6 +56,7 @@ public: void increaseAgentId(); bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId); void processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes); + void updateDataForAllAgents(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes); void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes); void pingAgents(); From f07714ce5c9cfb10a0ceb989f219c53e8dd3c0dc Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 15:51:08 -0600 Subject: [PATCH 08/31] Debugging --- avatar/src/avatar.cpp | 4 ++++ avatar/src/avatar.h | 1 - interface/src/main.cpp | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp index e4ca846718..ffc68b062b 100644 --- a/avatar/src/avatar.cpp +++ b/avatar/src/avatar.cpp @@ -142,6 +142,10 @@ double AvatarAgent::getLastHeartbeat() { } // Property setters +void AvatarAgent::setActiveSocket(sockaddr activeSocket) { + _activeSocket = activeSocket; +} + void AvatarAgent::setPitch(float pitch) { _pitch = pitch; } diff --git a/avatar/src/avatar.h b/avatar/src/avatar.h index 326f27d71a..b8490d8752 100644 --- a/avatar/src/avatar.h +++ b/avatar/src/avatar.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 1e95b42cc7..cac960d35c 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -534,7 +534,6 @@ void simulateHead(float frametime) // Send my stream of head/hand data to the avatar mixer const int MAX_BROADCAST_STRING = 200; - const int AVATAR_SERVER_PORT = 55444; char broadcast_string[MAX_BROADCAST_STRING]; int broadcast_bytes = myHead.getBroadcastData(broadcast_string); agentList.getAgentSocket().send(AVATAR_SERVER_IP, AVATAR_SERVER_PORT, broadcast_string, broadcast_bytes); From 3f64c29bc9dab48bbc72a2e56908cd04134bf0ce Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Tue, 9 Apr 2013 15:54:16 -0600 Subject: [PATCH 09/31] Debugging --- avatar/src/avatar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp index ffc68b062b..f3f060a36b 100644 --- a/avatar/src/avatar.cpp +++ b/avatar/src/avatar.cpp @@ -214,7 +214,7 @@ void *sendAvatarData(void *args) { unsigned char *startPointer; unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - *broadcastPacket = *(unsigned char *)PACKET_HEADER_HEAD_DATA; + broadcastPacket = (unsigned char *)PACKET_HEADER_HEAD_DATA; currentBufferPosition = broadcastPacket + 1; startPointer = currentBufferPosition; @@ -232,7 +232,6 @@ void *sendAvatarData(void *args) { } double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); - delete[] broadcastPacket; usleep(usecToSleep); } } From a0f3f161b10671b1d49b33cbc17c0e22c36e2234 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 16:39:57 -0700 Subject: [PATCH 10/31] move AvatarData class to AvatarAgentData subclass of AgentData --- avatar/src/AvatarAgentData.cpp | 116 ++++++++++++ avatar/src/AvatarAgentData.h | 58 ++++++ avatar/src/avatar.cpp | 336 --------------------------------- avatar/src/avatar.h | 84 --------- avatar/src/main.cpp | 135 +++++++++++++ mixer/src/main.cpp | 2 +- shared/src/Agent.cpp | 6 +- shared/src/AgentList.cpp | 4 +- shared/src/AgentTypes.h | 3 +- 9 files changed, 317 insertions(+), 427 deletions(-) create mode 100644 avatar/src/AvatarAgentData.cpp create mode 100644 avatar/src/AvatarAgentData.h delete mode 100644 avatar/src/avatar.cpp delete mode 100644 avatar/src/avatar.h create mode 100644 avatar/src/main.cpp diff --git a/avatar/src/AvatarAgentData.cpp b/avatar/src/AvatarAgentData.cpp new file mode 100644 index 0000000000..9a79954cdf --- /dev/null +++ b/avatar/src/AvatarAgentData.cpp @@ -0,0 +1,116 @@ +// +// AvatarAgentData.cpp +// hifi +// +// Created by Stephen Birarda on 4/9/13. +// +// + +#include "AvatarAgentData.h" + +AvatarAgentData::AvatarAgentData() { + +} + +AvatarAgentData::~AvatarAgentData() { + +} + +AvatarAgentData* AvatarAgentData::clone() const { + return new AvatarAgentData(*this); +} + +void AvatarAgentData::parseData(void *data, int size) { + char* packetData = (char *)data + 1; + + // Extract data from packet + sscanf(packetData, + PACKET_FORMAT, + &_pitch, + &_yaw, + &_roll, + &_headPositionX, + &_headPositionY, + &_headPositionZ, + &_loudness, + &_averageLoudness, + &_handPositionX, + &_handPositionY, + &_handPositionZ); +} + +float AvatarAgentData::getPitch() { + return _pitch; +} + +float AvatarAgentData::getYaw() { + return _yaw; +} + +float AvatarAgentData::getRoll() { + return _roll; +} + +float AvatarAgentData::getHeadPositionX() { + return _headPositionX; +} + +float AvatarAgentData::getHeadPositionY() { + return _headPositionY; +} + +float AvatarAgentData::getHeadPositionZ() { + return _headPositionZ; +} + +float AvatarAgentData::getLoudness() { + return _loudness; +} + +float AvatarAgentData::getAverageLoudness() { + return _averageLoudness; +} + +float AvatarAgentData::getHandPositionX() { + return _handPositionX; +} + +float AvatarAgentData::getHandPositionY() { + return _handPositionY; +} + +float AvatarAgentData::getHandPositionZ() { + return _handPositionZ; +} + +void AvatarAgentData::setPitch(float pitch) { + _pitch = pitch; +} + +void AvatarAgentData::setYaw(float yaw) { + _yaw = yaw; +} + +void AvatarAgentData::setRoll(float roll) { + _roll = roll; +} + +void AvatarAgentData::setHeadPosition(float x, float y, float z) { + _headPositionX = x; + _headPositionY = y; + _headPositionZ = z; +} + +void AvatarAgentData::setLoudness(float loudness) { + _loudness = loudness; +} + +void AvatarAgentData::setAverageLoudness(float averageLoudness) { + _averageLoudness = averageLoudness; +} + +void AvatarAgentData::setHandPosition(float x, float y, float z) { + _handPositionX = x; + _handPositionY = y; + _handPositionZ = z; +} diff --git a/avatar/src/AvatarAgentData.h b/avatar/src/AvatarAgentData.h new file mode 100644 index 0000000000..2b06928886 --- /dev/null +++ b/avatar/src/AvatarAgentData.h @@ -0,0 +1,58 @@ +// +// AvatarAgentData.h +// hifi +// +// Created by Stephen Birarda on 4/9/13. +// +// + +#ifndef __hifi__AvatarAgentData__ +#define __hifi__AvatarAgentData__ + +#include +#include + +const char PACKET_FORMAT[] = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; + +class AvatarAgentData : public AgentData { +public: + AvatarAgentData(); + ~AvatarAgentData(); + + void parseData(void *data, int size); + AvatarAgentData* clone() const; + + float getPitch(); + void setPitch(float pitch); + float getYaw(); + void setYaw(float yaw); + float getRoll(); + void setRoll(float roll); + float getHeadPositionX(); + float getHeadPositionY(); + float getHeadPositionZ(); + void setHeadPosition(float x, float y, float z); + float getLoudness(); + void setLoudness(float loudness); + float getAverageLoudness(); + void setAverageLoudness(float averageLoudness); + float getHandPositionX(); + float getHandPositionY(); + float getHandPositionZ(); + void setHandPosition(float x, float y, float z); + +private: + float _pitch; + float _yaw; + float _roll; + float _headPositionX; + float _headPositionY; + float _headPositionZ; + float _loudness; + float _averageLoudness; + float _handPositionX; + float _handPositionY; + float _handPositionZ; +}; + +#endif /* defined(__hifi__AvatarAgentData__) */ diff --git a/avatar/src/avatar.cpp b/avatar/src/avatar.cpp deleted file mode 100644 index f3f060a36b..0000000000 --- a/avatar/src/avatar.cpp +++ /dev/null @@ -1,336 +0,0 @@ -// -// avatar.cpp -// Avatar Mixer -// -// Created by Leonardo Murillo on 03/25/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved -// -// The avatar mixer receives head, hand and positional data from all connected -// agents, and broadcasts that data back to them, every BROADCAST_INTERVAL ms. -// -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "avatar.h" - -std::vector *avatarAgentList = new std::vector; -UDPSocket *avatarMixerSocket = new UDPSocket(AVATAR_LISTEN_PORT); - -AvatarAgent *findAvatarAgentBySocket(sockaddr *activeSocket) { - - sockaddr *agentSocketHolder = new sockaddr(); - - for (std::vector::iterator avatarAgent = avatarAgentList->begin(); - avatarAgent != avatarAgentList->end(); - avatarAgent++) { - agentSocketHolder = avatarAgent->getActiveSocket(); - if (agentSocketHolder->sa_family != activeSocket->sa_family) { - return NULL; - } - sockaddr_in *firstSocket = (sockaddr_in *) activeSocket; - sockaddr_in *secondSocket = (sockaddr_in *) agentSocketHolder; - - if (firstSocket->sin_addr.s_addr == secondSocket->sin_addr.s_addr && - firstSocket->sin_port == secondSocket->sin_port) { - return &*avatarAgent; - } - } - - return NULL; -} - -// Constructor and Destructor -AvatarAgent::AvatarAgent(sockaddr activeSocket, - float pitch, - float yaw, - float roll, - float headPositionX, - float headPositionY, - float headPositionZ, - float loudness, - float averageLoudness, - float handPositionX, - float handPositionY, - float handPositionZ, - double lastHeartbeat) { - - this->setActiveSocket(activeSocket); - this->setPitch(pitch); - this->setYaw(yaw); - this->setRoll(roll); - this->setHeadPosition(headPositionX, headPositionY, headPositionZ); - this->setLoudness(loudness); - this->setAverageLoudness(averageLoudness); - this->setHandPosition(handPositionX, handPositionY, handPositionZ); - this->setLastHeartbeat(lastHeartbeat); - -} - -AvatarAgent::~AvatarAgent() { - -} - -// Property getters -sockaddr *AvatarAgent::getActiveSocket() { - return &_activeSocket; -} - -float AvatarAgent::getPitch() { - return _pitch; -} - -float AvatarAgent::getYaw() { - return _yaw; -} - -float AvatarAgent::getRoll() { - return _roll; -} - -float AvatarAgent::getHeadPositionX() { - return _headPositionX; -} - -float AvatarAgent::getHeadPositionY() { - return _headPositionY; -} - -float AvatarAgent::getHeadPositionZ() { - return _headPositionZ; -} - -float AvatarAgent::getLoudness() { - return _loudness; -} - -float AvatarAgent::getAverageLoudness() { - return _averageLoudness; -} - -float AvatarAgent::getHandPositionX() { - return _handPositionX; -} - -float AvatarAgent::getHandPositionY() { - return _handPositionY; -} - -float AvatarAgent::getHandPositionZ() { - return _handPositionZ; -} - -double AvatarAgent::getLastHeartbeat() { - return _lastHeartbeat; -} - -// Property setters -void AvatarAgent::setActiveSocket(sockaddr activeSocket) { - _activeSocket = activeSocket; -} - -void AvatarAgent::setPitch(float pitch) { - _pitch = pitch; -} - -void AvatarAgent::setYaw(float yaw) { - _yaw = yaw; -} - -void AvatarAgent::setRoll(float roll) { - _roll = roll; -} - -void AvatarAgent::setHeadPosition(float x, float y, float z) { - _headPositionX = x; - _headPositionY = y; - _headPositionZ = z; -} - -void AvatarAgent::setLoudness(float loudness) { - _loudness = loudness; -} - -void AvatarAgent::setAverageLoudness(float averageLoudness) { - _averageLoudness = averageLoudness; -} - -void AvatarAgent::setHandPosition(float x, float y, float z) { - _handPositionX = x; - _handPositionY = y; - _handPositionZ = z; -} - -void AvatarAgent::setLastHeartbeat(double lastHeartbeat) { - _lastHeartbeat = lastHeartbeat; -} - -unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, AvatarAgent *agentToAdd) { - unsigned char *packetData = new unsigned char(); - - currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); - - sprintf((char *)packetData, PACKET_FORMAT, agentToAdd->getPitch(), - agentToAdd->getYaw(), - agentToAdd->getRoll(), - agentToAdd->getHeadPositionX(), - agentToAdd->getHeadPositionY(), - agentToAdd->getHeadPositionZ(), - agentToAdd->getLoudness(), - agentToAdd->getAverageLoudness(), - agentToAdd->getHandPositionX(), - agentToAdd->getHandPositionY(), - agentToAdd->getHandPositionZ()); - - memcpy(currentPosition, packetData, strlen((const char*)packetData)); - currentPosition += strlen((const char*)packetData); - - return currentPosition; -} - -void *sendAvatarData(void *args) { - timeval startTime; - while (true) { - gettimeofday(&startTime, NULL); - - unsigned char *currentBufferPosition; - unsigned char *startPointer; - unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - - broadcastPacket = (unsigned char *)PACKET_HEADER_HEAD_DATA; - currentBufferPosition = broadcastPacket + 1; - startPointer = currentBufferPosition; - - - for (std::vector::iterator avatarAgent = avatarAgentList->begin(); - avatarAgent != avatarAgentList->end(); - avatarAgent++) { - addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); - } - - for (std::vector::iterator avatarAgent = avatarAgentList->begin(); - avatarAgent != avatarAgentList->end(); - avatarAgent++) { - avatarMixerSocket->send(avatarAgent->getActiveSocket(), broadcastPacket, strlen((const char *)broadcastPacket)); - } - - double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); - usleep(usecToSleep); - } -} - -void *popInactiveAvatarAgents(void *args) { - - double checkTime, sleepTime; - - while (true) { - checkTime = usecTimestampNow(); - - for (std::vector::iterator avatarAgent = avatarAgentList->begin(); - avatarAgent != avatarAgentList->end(); - avatarAgent++) { - if ((checkTime - avatarAgent->getLastHeartbeat()) > AGENT_SILENCE_THRESHOLD_USECS) { - avatarAgent = avatarAgentList->erase(avatarAgent); - } - } - - } -} - -int main(int argc, char* argv[]) -{ - setvbuf(stdout, NULL, _IOLBF, 0); - - pthread_t sendAvatarDataThread; - pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); - - pthread_t popInactiveAvatarAgentsThread; - pthread_create(&popInactiveAvatarAgentsThread, NULL, popInactiveAvatarAgents, NULL); - - sockaddr *agentAddress = new sockaddr; - char *packetData = new char[MAX_PACKET_SIZE]; - ssize_t receivedBytes = 0; - - AvatarAgent *matchingAgent = NULL; - - float *pitch; - float *yaw; - float *roll; - float *headPositionX; - float *headPositionY; - float *headPositionZ; - float *loudness; - float *averageLoudness; - float *handPositionX; - float *handPositionY; - float *handPositionZ; - - while (true) { - if (avatarMixerSocket->receive(agentAddress, packetData, &receivedBytes)) { - if (packetData[0] == PACKET_HEADER_HEAD_DATA) { - // Extract data from packet - sscanf(packetData + 1, - PACKET_FORMAT, - &pitch, - &yaw, - &roll, - &headPositionX, - &headPositionY, - &headPositionZ, - &loudness, - &averageLoudness, - &handPositionX, - &handPositionY, - &handPositionZ); - - matchingAgent = findAvatarAgentBySocket(agentAddress); - - if (matchingAgent) { - // We already have this agent on our list, just modify positional data - matchingAgent->setPitch(*pitch); - matchingAgent->setYaw(*yaw); - matchingAgent->setRoll(*roll); - matchingAgent->setHeadPosition(*headPositionX, *headPositionY, *headPositionZ); - matchingAgent->setLoudness(*loudness); - matchingAgent->setAverageLoudness(*averageLoudness); - matchingAgent->setHandPosition(*handPositionX, *handPositionY, *handPositionZ); - matchingAgent->setLastHeartbeat(usecTimestampNow()); - - } else { - // This is a new agent, we need to add to the list - AvatarAgent thisAgentHolder = *new AvatarAgent(*agentAddress, - *pitch, - *yaw, - *roll, - *headPositionX, - *headPositionY, - *headPositionZ, - *loudness, - *averageLoudness, - *handPositionX, - *handPositionY, - *handPositionZ, - usecTimestampNow()); - avatarAgentList->push_back(thisAgentHolder); - } - } - } - } -} diff --git a/avatar/src/avatar.h b/avatar/src/avatar.h deleted file mode 100644 index b8490d8752..0000000000 --- a/avatar/src/avatar.h +++ /dev/null @@ -1,84 +0,0 @@ -// -// avatar.h -// Avatar Mixer - Main header file -// -// Created by Leonardo Murillo on 03/25/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -const int AVATAR_LISTEN_PORT = 55444; -const unsigned short BROADCAST_INTERVAL = 20; -const char *PACKET_FORMAT = "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f"; - -class AvatarAgent { -private: - sockaddr _activeSocket; - float _pitch; - float _yaw; - float _roll; - float _headPositionX; - float _headPositionY; - float _headPositionZ; - float _loudness; - float _averageLoudness; - float _handPositionX; - float _handPositionY; - float _handPositionZ; - double _lastHeartbeat; -public: - AvatarAgent(sockaddr activeSocket, - float pitch, - float yaw, - float roll, - float headPositionX, - float headPositionY, - float headPositionZ, - float loudness, - float averageLoudness, - float handPositionX, - float handPositionY, - float handPositionZ, - double lastHeartbeat); - ~AvatarAgent(); - sockaddr *getActiveSocket(); - void setActiveSocket(sockaddr activeSocket); - float getPitch(); - void setPitch(float pitch); - float getYaw(); - void setYaw(float yaw); - float getRoll(); - void setRoll(float roll); - float getHeadPositionX(); - float getHeadPositionY(); - float getHeadPositionZ(); - void setHeadPosition(float x, float y, float z); - float getLoudness(); - void setLoudness(float loudness); - float getAverageLoudness(); - void setAverageLoudness(float averageLoudness); - float getHandPositionX(); - float getHandPositionY(); - float getHandPositionZ(); - void setHandPosition(float x, float y, float z); - double getLastHeartbeat(); - void setLastHeartbeat(double lastHeartbeat); -}; \ No newline at end of file diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp new file mode 100644 index 0000000000..b94066d029 --- /dev/null +++ b/avatar/src/main.cpp @@ -0,0 +1,135 @@ +// +// main.cpp +// Avatar Mixer +// +// Created by Leonardo Murillo on 03/25/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved +// +// The avatar mixer receives head, hand and positional data from all connected +// agents, and broadcasts that data back to them, every BROADCAST_INTERVAL ms. +// +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "AvatarAgentData.h" + +const int AVATAR_LISTEN_PORT = 55444; +const unsigned short BROADCAST_INTERVAL = 20; + +AgentList agentList(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); + +unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { + unsigned char *packetData = new unsigned char(); + + currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); + + AvatarAgentData *agentData = (AvatarAgentData *)agentToAdd->getLinkedData(); + + sprintf((char *)packetData, PACKET_FORMAT, agentData->getPitch(), + agentData->getYaw(), + agentData->getRoll(), + agentData->getHeadPositionX(), + agentData->getHeadPositionY(), + agentData->getHeadPositionZ(), + agentData->getLoudness(), + agentData->getAverageLoudness(), + agentData->getHandPositionX(), + agentData->getHandPositionY(), + agentData->getHandPositionZ()); + + memcpy(currentPosition, packetData, strlen((const char*)packetData)); + currentPosition += strlen((const char*)packetData); + + return currentPosition; +} + +void *sendAvatarData(void *args) { + timeval startTime; + while (true) { + gettimeofday(&startTime, NULL); + + unsigned char *currentBufferPosition; + unsigned char *startPointer; + unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; + + broadcastPacket = (unsigned char *)PACKET_HEADER_HEAD_DATA; + currentBufferPosition = broadcastPacket + 1; + startPointer = currentBufferPosition; + + + for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); + avatarAgent != agentList.getAgents().end(); + avatarAgent++) { + addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + } + + for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); + avatarAgent != agentList.getAgents().end(); + avatarAgent++) { + agentList.getAgentSocket().send(avatarAgent->getActiveSocket(), broadcastPacket, strlen((const char *)broadcastPacket)); + } + + double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); + usleep(usecToSleep); + } +} + +void attachAvatarDataToAgent(Agent *newAgent) { + if (newAgent->getLinkedData() == NULL) { + newAgent->setLinkedData(new AvatarAgentData()); + } +} + +int main(int argc, char* argv[]) +{ + setvbuf(stdout, NULL, _IOLBF, 0); + + pthread_t sendAvatarDataThread; + pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); + + agentList.linkedDataCreateCallback = attachAvatarDataToAgent; + + agentList.startDomainServerCheckInThread(); + agentList.startSilentAgentRemovalThread(); + + sockaddr *agentAddress = new sockaddr; + char *packetData = new char[MAX_PACKET_SIZE]; + ssize_t receivedBytes = 0; + + while (true) { + if (agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + if (packetData[0] == PACKET_HEADER_HEAD_DATA) { + + if (agentList.addOrUpdateAgent(agentAddress, agentAddress, AGENT_TYPE_INTERFACE, agentList.getLastAgentId())) { + agentList.increaseAgentId(); + } + + agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); + } + } + } + + agentList.stopDomainServerCheckInThread(); + agentList.stopSilentAgentRemovalThread(); +} diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index 10040a05a9..ed455166d8 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -61,7 +61,7 @@ const int AGENT_LOOPBACK_MODIFIER = 307; const int LOOPBACK_SANITY_CHECK = 0; -AgentList agentList(AGENT_TYPE_MIXER, MIXER_LISTEN_PORT); +AgentList agentList(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); StDev stdev; void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) { diff --git a/shared/src/Agent.cpp b/shared/src/Agent.cpp index e9e62f3c66..03068bcd88 100644 --- a/shared/src/Agent.cpp +++ b/shared/src/Agent.cpp @@ -100,7 +100,7 @@ const char* AGENT_TYPE_NAME_DOMAIN = "Domain"; const char* AGENT_TYPE_NAME_VOXEL = "Voxel Server"; const char* AGENT_TYPE_NAME_INTERFACE = "Client Interface"; const char* AGENT_TYPE_NAME_HEAD = "Avatar Head"; // Is this needed??? -const char* AGENT_TYPE_NAME_MIXER = "Audio Mixer"; +const char* AGENT_TYPE_NAME_AUDIO_MIXER = "Audio Mixer"; const char* AGENT_TYPE_NAME_UNKNOWN = "Unknown"; const char* Agent::getTypeName() const { @@ -118,8 +118,8 @@ const char* Agent::getTypeName() const { case AGENT_TYPE_HEAD: name = AGENT_TYPE_NAME_HEAD; break; - case AGENT_TYPE_MIXER: - name = AGENT_TYPE_NAME_MIXER; + case AGENT_TYPE_AUDIO_MIXER: + name = AGENT_TYPE_NAME_AUDIO_MIXER; break; } return name; diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 03f5ff87c4..a5bafd4801 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -202,7 +202,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, newAgent.activatePublicSocket(); } - if (newAgent.getType() == AGENT_TYPE_MIXER && audioMixerSocketUpdate != NULL) { + if (newAgent.getType() == AGENT_TYPE_AUDIO_MIXER && audioMixerSocketUpdate != NULL) { // this is an audio mixer // for now that means we need to tell the audio class // to use the local socket information the domain server gave us @@ -221,7 +221,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, return true; } else { - if (agent->getType() == AGENT_TYPE_MIXER || agent->getType() == AGENT_TYPE_VOXEL) { + if (agent->getType() == AGENT_TYPE_AUDIO_MIXER || agent->getType() == AGENT_TYPE_VOXEL) { // until the Audio class also uses our agentList, we need to update // the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously agent->setLastRecvTimeUsecs(usecTimestampNow()); diff --git a/shared/src/AgentTypes.h b/shared/src/AgentTypes.h index fdfce9af8b..46a7363ce7 100644 --- a/shared/src/AgentTypes.h +++ b/shared/src/AgentTypes.h @@ -22,6 +22,7 @@ const char AGENT_TYPE_DOMAIN = 'D'; const char AGENT_TYPE_VOXEL = 'V'; const char AGENT_TYPE_INTERFACE = 'I'; // could also be injector??? const char AGENT_TYPE_HEAD = 'H'; // Is this needed??? -const char AGENT_TYPE_MIXER = 'M'; +const char AGENT_TYPE_AUDIO_MIXER = 'M'; +const char AGENT_TYPE_AVATAR_MIXER = 'W'; #endif From ae7f3e71d8256ab0200af4d45153763fe75cbb5c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 16:56:19 -0700 Subject: [PATCH 11/31] broadcast to VS and avatar mixer on position change --- interface/src/main.cpp | 20 ++++++++++++-------- shared/src/AgentList.cpp | 8 -------- shared/src/AgentList.h | 6 +----- voxel/src/main.cpp | 6 +++--- 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index cac960d35c..14c0de39e0 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -532,11 +532,15 @@ void simulateHead(float frametime) myHead.setAverageLoudness(averageLoudness); #endif - // Send my stream of head/hand data to the avatar mixer - const int MAX_BROADCAST_STRING = 200; - char broadcast_string[MAX_BROADCAST_STRING]; - int broadcast_bytes = myHead.getBroadcastData(broadcast_string); - agentList.getAgentSocket().send(AVATAR_SERVER_IP, AVATAR_SERVER_PORT, broadcast_string, broadcast_bytes); + // Send my stream of head/hand data to the avatar mixer and voxel server + char broadcastString[200]; + int broadcastBytes = myHead.getBroadcastData(broadcast_string); + + char broadcastReceivers[2]; + *broadcastReceivers = AGENT_TYPE_VOXEL; + *(broadcastReceivers + 1) = AGENT_TYPE_AVATAR_MIXER; + + agentList.broadcastToAgents(broadcast_string, broadcast_bytes, broadcastReceivers); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) { @@ -556,7 +560,7 @@ void simulateHead(float frametime) ::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) { if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL,0,1,&::paintingVoxel,bufferOut,sizeOut)){ - agentList.broadcastToAgents((char*)bufferOut, sizeOut,AgentList::AGENTS_OF_TYPE_VOXEL); + agentList.broadcastToAgents((char*)bufferOut, sizeOut, AGENT_TYPE_VOXEL); delete bufferOut; } } @@ -809,14 +813,14 @@ void sendVoxelServerEraseAll() { char message[100]; sprintf(message,"%c%s",'Z',"erase all"); int messageSize = strlen(message)+1; - ::agentList.broadcastToAgents(message, messageSize,AgentList::AGENTS_OF_TYPE_VOXEL); + ::agentList.broadcastToAgents(message, messageSize, AGENT_TYPE_VOXEL); } void sendVoxelServerAddScene() { char message[100]; sprintf(message,"%c%s",'Z',"add scene"); int messageSize = strlen(message)+1; - ::agentList.broadcastToAgents(message, messageSize,AgentList::AGENTS_OF_TYPE_VOXEL); + ::agentList.broadcastToAgents(message, messageSize, AGENT_TYPE_VOXEL); } void shiftPaintingColor() diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index a5bafd4801..64b387c8b7 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -24,9 +24,7 @@ const char * SOLO_AGENT_TYPES_STRING = "MV"; char DOMAIN_HOSTNAME[] = "highfidelity.below92.com"; char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup -char AVATAR_SERVER_IP[100] = ""; const int DOMAINSERVER_PORT = 40102; -const int AVATAR_SERVER_PORT = 55444; bool silentAgentThreadStopFlag = false; bool domainServerCheckinStopFlag = false; @@ -232,11 +230,6 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, } } -// XXXBHG - do we want to move these? -const char* AgentList::AGENTS_OF_TYPE_HEAD = "H"; -const char* AgentList::AGENTS_OF_TYPE_VOXEL_AND_INTERFACE = "VI"; -const char* AgentList::AGENTS_OF_TYPE_VOXEL = "V"; - void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes,const char* agentTypes) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { // only send to the AgentTypes we are asked to send to. @@ -348,7 +341,6 @@ void *checkInWithDomainServer(void *args) { sockaddr_in tempAddress; memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr)); - strcpy(AVATAR_SERVER_IP, inet_ntoa(tempAddress.sin_addr)); printf("Domain server %s: \n", DOMAIN_HOSTNAME); } else { diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index 4a3cd2f234..cdbbeda4f4 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -67,11 +67,7 @@ public: void stopSilentAgentRemovalThread(); void startDomainServerCheckInThread(); void stopDomainServerCheckInThread(); - - static const char* AGENTS_OF_TYPE_HEAD; - static const char* AGENTS_OF_TYPE_VOXEL_AND_INTERFACE; - static const char* AGENTS_OF_TYPE_VOXEL; - + }; int unpackAgentId(unsigned char *packedData, uint16_t *agentId); diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index 3990a82eac..4879a48f08 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -345,7 +345,7 @@ int main(int argc, const char * argv[]) // Now send this to the connected agents so they know to delete printf("rebroadcasting delete voxel message to connected agents... agentList.broadcastToAgents()\n"); - agentList.broadcastToAgents(packetData,receivedBytes,AgentList::AGENTS_OF_TYPE_HEAD); + agentList.broadcastToAgents(packetData,receivedBytes, AGENT_TYPE_INTERFACE); } if (packetData[0] == PACKET_HEADER_Z_COMMAND) { @@ -373,12 +373,12 @@ int main(int argc, const char * argv[]) // Now send this to the connected agents so they can also process these messages printf("rebroadcasting Z message to connected agents... agentList.broadcastToAgents()\n"); - agentList.broadcastToAgents(packetData,receivedBytes,AgentList::AGENTS_OF_TYPE_HEAD); + agentList.broadcastToAgents(packetData,receivedBytes, AGENT_TYPE_INTERFACE); } if (packetData[0] == PACKET_HEADER_HEAD_DATA) { if (agentList.addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, - packetData[0], + AGENT_TYPE_INTERFACE, agentList.getLastAgentId())) { agentList.increaseAgentId(); } From 7742d3114e100ff39aa805ed0f918f6bf76c94cb Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 17:03:10 -0700 Subject: [PATCH 12/31] add avatar mixer to agent type names, remove head --- shared/src/Agent.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shared/src/Agent.cpp b/shared/src/Agent.cpp index 03068bcd88..605c4465b1 100644 --- a/shared/src/Agent.cpp +++ b/shared/src/Agent.cpp @@ -99,8 +99,8 @@ char Agent::getType() const { const char* AGENT_TYPE_NAME_DOMAIN = "Domain"; const char* AGENT_TYPE_NAME_VOXEL = "Voxel Server"; const char* AGENT_TYPE_NAME_INTERFACE = "Client Interface"; -const char* AGENT_TYPE_NAME_HEAD = "Avatar Head"; // Is this needed??? const char* AGENT_TYPE_NAME_AUDIO_MIXER = "Audio Mixer"; +const char* AGENT_TYPE_NAME_AVATAR_MIXER = "Avatar Mixer"; const char* AGENT_TYPE_NAME_UNKNOWN = "Unknown"; const char* Agent::getTypeName() const { @@ -115,12 +115,12 @@ const char* Agent::getTypeName() const { case AGENT_TYPE_INTERFACE: name = AGENT_TYPE_NAME_INTERFACE; break; - case AGENT_TYPE_HEAD: - name = AGENT_TYPE_NAME_HEAD; - break; case AGENT_TYPE_AUDIO_MIXER: name = AGENT_TYPE_NAME_AUDIO_MIXER; break; + case AGENT_TYPE_AVATAR_MIXER: + name = AGENT_TYPE_NAME_AVATAR_MIXER; + break; } return name; } From 48077b62c8d322368d8878b48d63ad3722b48929 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 17:10:04 -0700 Subject: [PATCH 13/31] remove unnecessary cast and other lines --- shared/src/AgentList.cpp | 2 +- shared/src/AgentList.h | 1 - shared/src/AgentTypes.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 64b387c8b7..6c7bc94e1f 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -99,7 +99,7 @@ void AgentList::updateDataForAllAgents(sockaddr *senderAddress, unsigned char *p unsigned char *currentPosition = packetData + 1; unsigned char *startPosition = packetData; unsigned char *packetHolder = new unsigned char[(sizeof(float) * 11) + 1]; - packetHolder[0] = *(unsigned char *)PACKET_HEADER_HEAD_DATA; + packetHolder[0] = PACKET_HEADER_HEAD_DATA; packetHolder++; uint16_t agentId; sockaddr_in *agentActiveSocket = new sockaddr_in; diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index cdbbeda4f4..36f2174355 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -28,7 +28,6 @@ extern char DOMAIN_HOSTNAME[]; extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup extern const int DOMAINSERVER_PORT; - class AgentList { UDPSocket agentSocket; diff --git a/shared/src/AgentTypes.h b/shared/src/AgentTypes.h index 46a7363ce7..a5d79efac8 100644 --- a/shared/src/AgentTypes.h +++ b/shared/src/AgentTypes.h @@ -21,7 +21,6 @@ const char AGENT_TYPE_DOMAIN = 'D'; const char AGENT_TYPE_VOXEL = 'V'; const char AGENT_TYPE_INTERFACE = 'I'; // could also be injector??? -const char AGENT_TYPE_HEAD = 'H'; // Is this needed??? const char AGENT_TYPE_AUDIO_MIXER = 'M'; const char AGENT_TYPE_AVATAR_MIXER = 'W'; From f2377ea541025784b68d078f626c3ede708f42fd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 17:14:27 -0700 Subject: [PATCH 14/31] some refactoring in updateDataForAllAgents --- shared/src/AgentList.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 6c7bc94e1f..c25670e269 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -96,21 +96,26 @@ void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size } void AgentList::updateDataForAllAgents(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { + int bytesForEachAgent = sizeof(float) * 11; + unsigned char *currentPosition = packetData + 1; unsigned char *startPosition = packetData; - unsigned char *packetHolder = new unsigned char[(sizeof(float) * 11) + 1]; + unsigned char *packetHolder = new unsigned char[bytesForEachAgent + 1]; + packetHolder[0] = PACKET_HEADER_HEAD_DATA; - packetHolder++; + uint16_t agentId; + sockaddr_in *agentActiveSocket = new sockaddr_in; agentActiveSocket->sin_family = AF_INET; while ((currentPosition - startPosition) < dataBytes) { currentPosition += unpackAgentId(currentPosition, &agentId); currentPosition += unpackSocket(currentPosition, (sockaddr *)&agentActiveSocket); - memcpy(packetHolder, currentPosition, sizeof(float) * 11); - currentPosition += sizeof(float) * 11; - updateAgentWithData((sockaddr *)agentActiveSocket, packetHolder, (sizeof(float) * 11) + 1); + memcpy(packetHolder + 1, currentPosition, bytesForEachAgent); + + updateAgentWithData((sockaddr *)agentActiveSocket, packetHolder, bytesForEachAgent + 1); + currentPosition += bytesForEachAgent; } } From 11a317da9672b6f5cd5f0176be0aef3ea2acaf78 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 17:15:40 -0700 Subject: [PATCH 15/31] remove comments in processAgentData --- shared/src/AgentList.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index c25670e269..35170928ec 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -71,24 +71,18 @@ unsigned int AgentList::getSocketListenPort() { void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes) { switch (((char *)packetData)[0]) { case PACKET_HEADER_DOMAIN: { - // list of agents from domain server updateList((unsigned char *)packetData, dataBytes); break; } case PACKET_HEADER_HEAD_DATA: { - // head data from another agent updateDataForAllAgents(senderAddress, (unsigned char *)packetData, dataBytes); break; } case PACKET_HEADER_PING: { - // ping from another agent - //std::cout << "Got ping from " << inet_ntoa(((sockaddr_in *)senderAddress)->sin_addr) << "\n"; agentSocket.send(senderAddress, &PACKET_HEADER_PING_REPLY, 1); break; } case PACKET_HEADER_PING_REPLY: { - // ping reply from another agent - //std::cout << "Got ping reply from " << inet_ntoa(((sockaddr_in *)senderAddress)->sin_addr) << "\n"; handlePingReply(senderAddress); break; } From 4f576ba86f0c923f94a38bc53dfddfdf5b07fa4d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 17:33:53 -0700 Subject: [PATCH 16/31] some spacing issues, conversions from const char to char * --- interface/src/main.cpp | 16 ++++++++-------- shared/src/AgentList.cpp | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 011cab1ce6..7e55c1698e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -534,13 +534,13 @@ void simulateHead(float frametime) // Send my stream of head/hand data to the avatar mixer and voxel server char broadcastString[200]; - int broadcastBytes = myHead.getBroadcastData(broadcast_string); + int broadcastBytes = myHead.getBroadcastData(broadcastString); char broadcastReceivers[2]; *broadcastReceivers = AGENT_TYPE_VOXEL; *(broadcastReceivers + 1) = AGENT_TYPE_AVATAR_MIXER; - agentList.broadcastToAgents(broadcast_string, broadcast_bytes, broadcastReceivers); + agentList.broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) { @@ -559,8 +559,8 @@ void simulateHead(float frametime) ::paintingVoxel.y >= 0.0 && ::paintingVoxel.y <= 1.0 && ::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) { - if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL,0,1,&::paintingVoxel,bufferOut,sizeOut)){ - agentList.broadcastToAgents((char*)bufferOut, sizeOut, AGENT_TYPE_VOXEL); + if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &::paintingVoxel, bufferOut, sizeOut)){ + agentList.broadcastToAgents((char*)bufferOut, sizeOut, &AGENT_TYPE_VOXEL); delete bufferOut; } } @@ -812,15 +812,15 @@ void testPointToVoxel() void sendVoxelServerEraseAll() { char message[100]; sprintf(message,"%c%s",'Z',"erase all"); - int messageSize = strlen(message)+1; - ::agentList.broadcastToAgents(message, messageSize, AGENT_TYPE_VOXEL); + int messageSize = strlen(message) + 1; + ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL); } void sendVoxelServerAddScene() { char message[100]; sprintf(message,"%c%s",'Z',"add scene"); - int messageSize = strlen(message)+1; - ::agentList.broadcastToAgents(message, messageSize, AGENT_TYPE_VOXEL); + int messageSize = strlen(message) + 1; + ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL); } void shiftPaintingColor() diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 35170928ec..460533d50e 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -229,7 +229,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, } } -void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes,const char* agentTypes) { +void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { // only send to the AgentTypes we are asked to send to. if (agent->getActiveSocket() != NULL && strchr(agentTypes,agent->getType())) { From 8fe87d08e99ef6d6889311fcc3b3e232794a894e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 9 Apr 2013 17:59:54 -0700 Subject: [PATCH 17/31] refactoring broadcast avatar data, auto-activate AM public socket --- avatar/src/main.cpp | 60 +++++++++++++++++++++------------------- shared/src/AgentList.cpp | 7 +++++ 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index b94066d029..5e87312eca 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -35,62 +35,61 @@ #include "AvatarAgentData.h" const int AVATAR_LISTEN_PORT = 55444; -const unsigned short BROADCAST_INTERVAL = 20; +const unsigned short BROADCAST_INTERVAL_USECS = 20 * 1000 * 1000; AgentList agentList(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { - unsigned char *packetData = new unsigned char(); - - currentPosition += packSocket(currentPosition, agentToAdd->getActiveSocket()); + currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket()); AvatarAgentData *agentData = (AvatarAgentData *)agentToAdd->getLinkedData(); - sprintf((char *)packetData, PACKET_FORMAT, agentData->getPitch(), - agentData->getYaw(), - agentData->getRoll(), - agentData->getHeadPositionX(), - agentData->getHeadPositionY(), - agentData->getHeadPositionZ(), - agentData->getLoudness(), - agentData->getAverageLoudness(), - agentData->getHandPositionX(), - agentData->getHandPositionY(), - agentData->getHandPositionZ()); - - memcpy(currentPosition, packetData, strlen((const char*)packetData)); - currentPosition += strlen((const char*)packetData); + int bytesWritten = sprintf((char *)currentPosition, + PACKET_FORMAT, + agentData->getPitch(), + agentData->getYaw(), + agentData->getRoll(), + agentData->getHeadPositionX(), + agentData->getHeadPositionY(), + agentData->getHeadPositionZ(), + agentData->getLoudness(), + agentData->getAverageLoudness(), + agentData->getHandPositionX(), + agentData->getHandPositionY(), + agentData->getHandPositionZ()); + currentPosition += bytesWritten; return currentPosition; } void *sendAvatarData(void *args) { timeval startTime; + + unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; + *broadcastPacket = PACKET_HEADER_HEAD_DATA; + + unsigned char* currentBufferPosition = NULL; + while (true) { gettimeofday(&startTime, NULL); - unsigned char *currentBufferPosition; - unsigned char *startPointer; - unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - - broadcastPacket = (unsigned char *)PACKET_HEADER_HEAD_DATA; - currentBufferPosition = broadcastPacket + 1; - startPointer = currentBufferPosition; - + currentBufferPosition = broadcastPacket + 1; for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); avatarAgent != agentList.getAgents().end(); avatarAgent++) { - addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); } for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); avatarAgent != agentList.getAgents().end(); avatarAgent++) { - agentList.getAgentSocket().send(avatarAgent->getActiveSocket(), broadcastPacket, strlen((const char *)broadcastPacket)); + agentList.getAgentSocket().send(avatarAgent->getPublicSocket(), + broadcastPacket, + currentBufferPosition - broadcastPacket); } - double usecToSleep = usecTimestamp(&startTime) + (BROADCAST_INTERVAL * 10000000) - usecTimestampNow(); + double usecToSleep = BROADCAST_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&startTime)); usleep(usecToSleep); } } @@ -132,4 +131,7 @@ int main(int argc, char* argv[]) agentList.stopDomainServerCheckInThread(); agentList.stopSilentAgentRemovalThread(); + + pthread_join(sendAvatarDataThread, NULL); + return 0; } diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 460533d50e..da6132c93e 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -90,6 +90,11 @@ void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size } void AgentList::updateDataForAllAgents(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { + // find the avatar mixer in our agent list and update the lastRecvTime from it + int avatarMixerIndex = indexOfMatchingAgent(senderAddress); + Agent *avatarMixerAgent = &agents[avatarMixerIndex]; + avatarMixerAgent->setLastRecvTimeUsecs(usecTimestampNow()); + int bytesForEachAgent = sizeof(float) * 11; unsigned char *currentPosition = packetData + 1; @@ -207,6 +212,8 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, audioMixerSocketUpdate(publicSocketIn->sin_addr.s_addr, publicSocketIn->sin_port); } else if (newAgent.getType() == AGENT_TYPE_VOXEL) { newAgent.activatePublicSocket(); + } else if (newAgent.getType() == AGENT_TYPE_AVATAR_MIXER) { + newAgent.activatePublicSocket(); } std::cout << "Added agent - " << &newAgent << "\n"; From cf1f087b3849dd28e07e0b1ff41f2bd2b097175c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 11:57:24 -0700 Subject: [PATCH 18/31] add method to parse bulk agent data from a mixer --- interface/src/main.cpp | 27 ++++++++------ shared/src/AgentList.cpp | 78 ++++++++++++++++++++++------------------ shared/src/AgentList.h | 18 +++++++--- 3 files changed, 73 insertions(+), 50 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 6b8d6074db..c58d96c19c 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1050,9 +1050,7 @@ void key(unsigned char k, int x, int y) if (k == '.') addRandomSphere(wantColorRandomizer); } -// // Receive packets from other agents/servers and decide what to do with them! -// void *networkReceive(void *args) { sockaddr senderAddress; @@ -1064,19 +1062,26 @@ void *networkReceive(void *args) packetCount++; bytesCount += bytesReceived; - if (incomingPacket[0] == PACKET_HEADER_TRANSMITTER_DATA) { - // Pass everything but transmitter data to the agent list - myHead.hand->processTransmitterData(incomingPacket, bytesReceived); - } else if (incomingPacket[0] == PACKET_HEADER_VOXEL_DATA || - incomingPacket[0] == PACKET_HEADER_Z_COMMAND || - incomingPacket[0] == PACKET_HEADER_ERASE_VOXEL) { - voxels.parseData(incomingPacket, bytesReceived); - } else { - agentList.processAgentData(&senderAddress, incomingPacket, bytesReceived); + switch (incomingPacket[0]) { + case PACKET_HEADER_TRANSMITTER_DATA: + myHead.hand->processTransmitterData(incomingPacket, bytesReceived); + break; + case PACKET_HEADER_VOXEL_DATA: + case PACKET_HEADER_Z_COMMAND: + case PACKET_HEADER_ERASE_VOXEL: + voxels.parseData(incomingPacket, bytesReceived); + break; + case PACKET_HEADER_HEAD_DATA: + agentList.processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, sizeof(float) * 11); + break; + default: + agentList.processAgentData(&senderAddress, incomingPacket, bytesReceived); + break; } } } + delete[] incomingPacket; pthread_exit(0); return NULL; } diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index da6132c93e..abd688401b 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -74,10 +74,6 @@ void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size updateList((unsigned char *)packetData, dataBytes); break; } - case PACKET_HEADER_HEAD_DATA: { - updateDataForAllAgents(senderAddress, (unsigned char *)packetData, dataBytes); - break; - } case PACKET_HEADER_PING: { agentSocket.send(senderAddress, &PACKET_HEADER_PING_REPLY, 1); break; @@ -89,33 +85,36 @@ void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size } } -void AgentList::updateDataForAllAgents(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { +void AgentList::processBulkAgentData(sockaddr *senderAddress, void *packetData, int numTotalBytes, int numBytesPerAgent) { // find the avatar mixer in our agent list and update the lastRecvTime from it - int avatarMixerIndex = indexOfMatchingAgent(senderAddress); - Agent *avatarMixerAgent = &agents[avatarMixerIndex]; - avatarMixerAgent->setLastRecvTimeUsecs(usecTimestampNow()); + int bulkSendAgentIndex = indexOfMatchingAgent(senderAddress); - int bytesForEachAgent = sizeof(float) * 11; - - unsigned char *currentPosition = packetData + 1; - unsigned char *startPosition = packetData; - unsigned char *packetHolder = new unsigned char[bytesForEachAgent + 1]; + if (bulkSendAgentIndex >= 0) { + Agent *bulkSendAgent = &agents[bulkSendAgentIndex]; + bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow()); + } + + unsigned char *startPosition = (unsigned char *)packetData; + unsigned char *currentPosition = startPosition + 1; + unsigned char *packetHolder = new unsigned char[numBytesPerAgent + 1]; packetHolder[0] = PACKET_HEADER_HEAD_DATA; - uint16_t agentId; + uint16_t agentID = -1; - sockaddr_in *agentActiveSocket = new sockaddr_in; - agentActiveSocket->sin_family = AF_INET; - - while ((currentPosition - startPosition) < dataBytes) { - currentPosition += unpackAgentId(currentPosition, &agentId); - currentPosition += unpackSocket(currentPosition, (sockaddr *)&agentActiveSocket); - memcpy(packetHolder + 1, currentPosition, bytesForEachAgent); + while ((currentPosition - startPosition) < numTotalBytes) { + currentPosition += unpackAgentId(currentPosition, &agentID); + memcpy(packetHolder + 1, currentPosition, numBytesPerAgent); - updateAgentWithData((sockaddr *)agentActiveSocket, packetHolder, bytesForEachAgent + 1); - currentPosition += bytesForEachAgent; + int matchingAgentIndex = indexOfMatchingAgent(agentID); + if (matchingAgentIndex >= 0) { + updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1); + } + + currentPosition += numBytesPerAgent; } + + delete[] packetHolder; } void AgentList::updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes) { @@ -123,19 +122,20 @@ void AgentList::updateAgentWithData(sockaddr *senderAddress, void *packetData, s int agentIndex = indexOfMatchingAgent(senderAddress); if (agentIndex != -1) { - Agent *matchingAgent = &agents[agentIndex]; - - matchingAgent->setLastRecvTimeUsecs(usecTimestampNow()); - - if (matchingAgent->getLinkedData() == NULL) { - if (linkedDataCreateCallback != NULL) { - linkedDataCreateCallback(matchingAgent); - } - } - - matchingAgent->getLinkedData()->parseData(packetData, dataBytes); + updateAgentWithData(&agents[agentIndex], packetData, dataBytes); } +} +void AgentList::updateAgentWithData(Agent *agent, void *packetData, int dataBytes) { + agent->setLastRecvTimeUsecs(usecTimestampNow()); + + if (agent->getLinkedData() == NULL) { + if (linkedDataCreateCallback != NULL) { + linkedDataCreateCallback(agent); + } + } + + agent->getLinkedData()->parseData(packetData, dataBytes); } int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) { @@ -148,6 +148,16 @@ int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) { return -1; } +int AgentList::indexOfMatchingAgent(uint16_t agentID) { + for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { + if (agent->getActiveSocket() != NULL && agent->getAgentId() == agentID) { + return agent - agents.begin(); + } + } + + return -1; +} + uint16_t AgentList::getLastAgentId() { return lastAgentId; } diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index 36f2174355..7132521407 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -49,14 +49,22 @@ public: std::vector& getAgents(); UDPSocket& getAgentSocket(); - int updateList(unsigned char *packetData, size_t dataBytes); - int indexOfMatchingAgent(sockaddr *senderAddress); uint16_t getLastAgentId(); void increaseAgentId(); + + int updateList(unsigned char *packetData, size_t dataBytes); + + int indexOfMatchingAgent(sockaddr *senderAddress); + int indexOfMatchingAgent(uint16_t agentID); + bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId); + void processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes); - void updateDataForAllAgents(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); + void processBulkAgentData(sockaddr *senderAddress, void *packetData, int numTotalBytes, int numBytesPerAgent); + void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes); + void updateAgentWithData(Agent *agent, void *packetData, int dataBytes); + void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes); void pingAgents(); char getOwnerType(); @@ -69,7 +77,7 @@ public: }; -int unpackAgentId(unsigned char *packedData, uint16_t *agentId); -int packAgentId(unsigned char *packStore, uint16_t agentId); +int unpackAgentId(char *packedData, uint16_t *agentId); +int packAgentId(char *packStore, uint16_t agentId); #endif /* defined(__hifi__AgentList__) */ From 66ccc9921b41144f503373df55abf3c3e30de80d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 11:57:47 -0700 Subject: [PATCH 19/31] handle ping and reply and domain server packets in avatar mixer --- avatar/src/main.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index 5e87312eca..c7e607d5d0 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -118,13 +118,15 @@ int main(int argc, char* argv[]) while (true) { if (agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { - if (packetData[0] == PACKET_HEADER_HEAD_DATA) { - - if (agentList.addOrUpdateAgent(agentAddress, agentAddress, AGENT_TYPE_INTERFACE, agentList.getLastAgentId())) { - agentList.increaseAgentId(); - } - - agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); + switch (packetData[0]) { + case PACKET_HEADER_HEAD_DATA: + // this is positional data from an agent + agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); + break; + default: + // hand this off to the AgentList + agentList.processAgentData(agentAddress, (void *)packetData, receivedBytes); + break; } } } From de358d4bf62d980105c784e6a3b249ed59bb5b69 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 12:10:03 -0700 Subject: [PATCH 20/31] fix warnings produced by starfield additions --- interface/src/starfield/Controller.h | 2 +- interface/src/starfield/Loader.h | 4 ++-- interface/src/starfield/data/InputVertex.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/starfield/Controller.h b/interface/src/starfield/Controller.h index b004e73037..edf9fd7ec7 100644 --- a/interface/src/starfield/Controller.h +++ b/interface/src/starfield/Controller.h @@ -99,8 +99,8 @@ namespace starfield { _valLodOveralloc(1.2), _valLodNalloc(0), _valLodNrender(0), - _valLodBrightness(0), _valLodAllocBrightness(0), + _valLodBrightness(0), _ptrRenderer(0l) { } diff --git a/interface/src/starfield/Loader.h b/interface/src/starfield/Loader.h index 83d63adc2c..bff41409a2 100644 --- a/interface/src/starfield/Loader.h +++ b/interface/src/starfield/Loader.h @@ -50,8 +50,8 @@ namespace starfield { return false; } - fprintf(stderr, "Stars.cpp: read %d stars, rendering %d\n", - _valRecordsRead, _ptrVertices->size()); + fprintf(stderr, "Stars.cpp: read %d stars, rendering %ld\n", + _valRecordsRead, _ptrVertices->size()); return true; } diff --git a/interface/src/starfield/data/InputVertex.h b/interface/src/starfield/data/InputVertex.h index dac242ec51..9f30755325 100644 --- a/interface/src/starfield/data/InputVertex.h +++ b/interface/src/starfield/data/InputVertex.h @@ -26,8 +26,8 @@ namespace starfield { InputVertex(float azimuth, float altitude, unsigned color) { - _valColor = color >> 16 & 0xffu | color & 0xff00u | - color << 16 & 0xff0000u | 0xff000000u; + _valColor = (color >> 16 & 0xffu) | (color & 0xff00u) | + (color << 16 & 0xff0000u) | 0xff000000u; azimuth = angleConvert(azimuth); altitude = angleConvert(altitude); From fcee05e9f0d1b8b63fb927db44923ea22ac99dda Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 12:37:14 -0700 Subject: [PATCH 21/31] handle pinging of unknown agents in AgentList thread --- avatar/src/main.cpp | 16 +++++++--- interface/src/main.cpp | 6 ++-- shared/src/AgentList.cpp | 69 +++++++++++++++++++++++++++------------- shared/src/AgentList.h | 9 +++--- 4 files changed, 65 insertions(+), 35 deletions(-) diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index c7e607d5d0..73d3a3b6ba 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -66,7 +66,7 @@ void *sendAvatarData(void *args) { timeval startTime; unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - *broadcastPacket = PACKET_HEADER_HEAD_DATA; + *broadcastPacket = PACKET_HEADER_AVATAR_SERVER; unsigned char* currentBufferPosition = NULL; @@ -78,15 +78,19 @@ void *sendAvatarData(void *args) { for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); avatarAgent != agentList.getAgents().end(); avatarAgent++) { - currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + if (avatarAgent->getLinkedData() != NULL) { + currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + } } for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); avatarAgent != agentList.getAgents().end(); avatarAgent++) { - agentList.getAgentSocket().send(avatarAgent->getPublicSocket(), - broadcastPacket, - currentBufferPosition - broadcastPacket); + if (avatarAgent->getActiveSocket()) { + agentList.getAgentSocket().send(avatarAgent->getPublicSocket(), + broadcastPacket, + currentBufferPosition - broadcastPacket); + } } double usecToSleep = BROADCAST_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&startTime)); @@ -111,6 +115,7 @@ int main(int argc, char* argv[]) agentList.startDomainServerCheckInThread(); agentList.startSilentAgentRemovalThread(); + agentList.startPingUnknownAgentsThread(); sockaddr *agentAddress = new sockaddr; char *packetData = new char[MAX_PACKET_SIZE]; @@ -133,6 +138,7 @@ int main(int argc, char* argv[]) agentList.stopDomainServerCheckInThread(); agentList.stopSilentAgentRemovalThread(); + agentList.stopPingUnknownAgentsThread(); pthread_join(sendAvatarDataThread, NULL); return 0; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index a6abc0cefc..588663276f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -222,9 +222,6 @@ void Timer(int extra) glutTimerFunc(1000,Timer,0); gettimeofday(&timerStart, NULL); - // Ping the agents we can see - agentList.pingAgents(); - // if we haven't detected gyros, check for them now if (!serialPort.active) { serialPort.pair(); @@ -1250,9 +1247,10 @@ int main(int argc, const char * argv[]) int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData ); #endif - // start the thread which checks for silent agents + // start the agentList threads agentList.startSilentAgentRemovalThread(); agentList.startDomainServerCheckInThread(); + agentList.startPingUnknownAgentsThread(); glutInit(&argc, (char**)argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index ae30ce6f45..8826477ea3 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -28,6 +28,7 @@ const int DOMAINSERVER_PORT = 40102; bool silentAgentThreadStopFlag = false; bool domainServerCheckinStopFlag = false; +bool pingUnknownAgentThreadStopFlag = false; pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER; int unpackAgentId(unsigned char *packedData, uint16_t *agentId) { @@ -50,6 +51,7 @@ AgentList::~AgentList() { // stop the spawned threads, if they were started stopSilentAgentRemovalThread(); stopDomainServerCheckInThread(); + stopPingUnknownAgentsThread(); } std::vector& AgentList::getAgents() { @@ -209,7 +211,7 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId); if (socketMatch(publicSocket, localSocket)) { - // likely debugging scenario with DS + agent on local network + // likely debugging scenario with two agents on local network // set the agent active right away newAgent.activatePublicSocket(); } @@ -222,8 +224,6 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, audioMixerSocketUpdate(publicSocketIn->sin_addr.s_addr, publicSocketIn->sin_port); } else if (newAgent.getType() == AGENT_TYPE_VOXEL) { newAgent.activatePublicSocket(); - } else if (newAgent.getType() == AGENT_TYPE_AVATAR_MIXER) { - newAgent.activatePublicSocket(); } std::cout << "Added agent - " << &newAgent << "\n"; @@ -256,39 +256,64 @@ void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes, const c } } -void AgentList::pingAgents() { - char payload[1]; - *payload = PACKET_HEADER_PING; - - for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { - if (agent->getType() == AGENT_TYPE_INTERFACE) { - if (agent->getActiveSocket() != NULL) { - // we know which socket is good for this agent, send there - agentSocket.send(agent->getActiveSocket(), payload, 1); - } else { - // ping both of the sockets for the agent so we can figure out - // which socket we can use - agentSocket.send(agent->getPublicSocket(), payload, 1); - agentSocket.send(agent->getLocalSocket(), payload, 1); - } - } - } -} - void AgentList::handlePingReply(sockaddr *agentAddress) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { // check both the public and local addresses for each agent to see if we find a match // prioritize the private address so that we prune erroneous local matches if (socketMatch(agent->getPublicSocket(), agentAddress)) { agent->activatePublicSocket(); + std::cout << "Activated public socket for agent " << &*agent << "\n"; break; } else if (socketMatch(agent->getLocalSocket(), agentAddress)) { agent->activateLocalSocket(); + std::cout << "Activated local socket for agent " << &*agent << "\n"; break; } } } +void *pingUnknownAgents(void *args) { + + AgentList *agentList = (AgentList *)args; + const int PING_INTERVAL_USECS = 1 * 1000000; + + timeval lastSend; + + while (!pingUnknownAgentThreadStopFlag) { + gettimeofday(&lastSend, NULL); + + for(std::vector::iterator agent = agentList->getAgents().begin(); + agent != agentList->getAgents().end(); + agent++) { + if (agent->getType() == AGENT_TYPE_INTERFACE) { + if (agent->getActiveSocket() == NULL) { + // ping both of the sockets for the agent so we can figure out + // which socket we can use + agentList->getAgentSocket().send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1); + agentList->getAgentSocket().send(agent->getLocalSocket(), &PACKET_HEADER_PING, 1); + } + } + } + + double usecToSleep = PING_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&lastSend)); + + if (usecToSleep > 0) { + usleep(usecToSleep); + } + } + + return NULL; +} + +void AgentList::startPingUnknownAgentsThread() { + pthread_create(&pingUnknownAgentsThread, NULL, pingUnknownAgents, (void *)this); +} + +void AgentList::stopPingUnknownAgentsThread() { + pingUnknownAgentThreadStopFlag = true; + pthread_join(pingUnknownAgentsThread, NULL); +} + void *removeSilentAgents(void *args) { std::vector *agents = (std::vector *)args; double checkTimeUSecs, sleepTime; diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index 7132521407..eaecc1bf50 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -37,6 +37,7 @@ class AgentList { uint16_t lastAgentId; pthread_t removeSilentAgentsThread; pthread_t checkInWithDomainServerThread; + pthread_t pingUnknownAgentsThread; void handlePingReply(sockaddr *agentAddress); public: @@ -66,7 +67,6 @@ public: void updateAgentWithData(Agent *agent, void *packetData, int dataBytes); void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes); - void pingAgents(); char getOwnerType(); unsigned int getSocketListenPort(); @@ -74,10 +74,11 @@ public: void stopSilentAgentRemovalThread(); void startDomainServerCheckInThread(); void stopDomainServerCheckInThread(); - + void startPingUnknownAgentsThread(); + void stopPingUnknownAgentsThread(); }; -int unpackAgentId(char *packedData, uint16_t *agentId); -int packAgentId(char *packStore, uint16_t agentId); +int unpackAgentId(unsigned char *packedData, uint16_t *agentId); +int packAgentId(unsigned char *packStore, uint16_t agentId); #endif /* defined(__hifi__AgentList__) */ From d56952cdc7f18e09421f7a3a5d943600d81d8118 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 13:39:31 -0700 Subject: [PATCH 22/31] don't copy agent delete mutex --- shared/src/Agent.cpp | 3 +-- shared/src/AgentList.cpp | 17 ++++++++--------- voxel/src/main.cpp | 8 ++++---- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/shared/src/Agent.cpp b/shared/src/Agent.cpp index db3f7f4726..8c14d9a617 100644 --- a/shared/src/Agent.cpp +++ b/shared/src/Agent.cpp @@ -67,7 +67,7 @@ Agent::Agent(const Agent &otherAgent) { linkedData = NULL; } - deleteMutex = otherAgent.deleteMutex; + pthread_mutex_init(&deleteMutex, NULL); } Agent& Agent::operator=(Agent otherAgent) { @@ -83,7 +83,6 @@ void Agent::swap(Agent &first, Agent &second) { swap(first.type, second.type); swap(first.linkedData, second.linkedData); swap(first.agentId, second.agentId); - swap(first.deleteMutex, second.deleteMutex); } Agent::~Agent() { diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 8826477ea3..0cfac49429 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -285,13 +285,11 @@ void *pingUnknownAgents(void *args) { for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { - if (agent->getType() == AGENT_TYPE_INTERFACE) { - if (agent->getActiveSocket() == NULL) { - // ping both of the sockets for the agent so we can figure out - // which socket we can use - agentList->getAgentSocket().send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1); - agentList->getAgentSocket().send(agent->getLocalSocket(), &PACKET_HEADER_PING, 1); - } + if (agent->getActiveSocket() == NULL) { + // ping both of the sockets for the agent so we can figure out + // which socket we can use + agentList->getAgentSocket().send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1); + agentList->getAgentSocket().send(agent->getLocalSocket(), &PACKET_HEADER_PING, 1); } } @@ -344,7 +342,6 @@ void *removeSilentAgents(void *args) { } } - sleepTime = AGENT_SILENCE_THRESHOLD_USECS - (usecTimestampNow() - checkTimeUSecs); #ifdef _WIN32 Sleep( static_cast(1000.0f*sleepTime) ); @@ -380,6 +377,8 @@ void AgentList::stopSilentAgentRemovalThread() { void *checkInWithDomainServer(void *args) { + const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; + AgentList *parentAgentList = (AgentList *)args; timeval lastSend; @@ -410,7 +409,7 @@ void *checkInWithDomainServer(void *args) { parentAgentList->getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7); - double usecToSleep = 1000000 - (usecTimestampNow() - usecTimestamp(&lastSend)); + double usecToSleep = DOMAIN_SERVER_CHECK_IN_USECS - (usecTimestampNow() - usecTimestamp(&lastSend)); if (usecToSleep > 0) { usleep(usecToSleep); diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index bbc5a92452..e88777913f 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -131,7 +131,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it - pthread_mutex_lock(&thisAgent->deleteMutex); + pthread_mutex_lock(thisAgent->deleteMutex); // clean up the agent visit data delete agentData->rootMarkerNode; @@ -139,7 +139,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { // unlock the delete mutex so the other thread can // kill the agent if it has dissapeared - pthread_mutex_unlock(&thisAgent->deleteMutex); + pthread_mutex_unlock(thisAgent->deleteMutex); } } @@ -168,7 +168,7 @@ void *distributeVoxelsToListeners(void *args) { // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it - pthread_mutex_lock(&thisAgent->deleteMutex); + pthread_mutex_lock(thisAgent->deleteMutex); stopOctal = NULL; packetCount = 0; @@ -208,7 +208,7 @@ void *distributeVoxelsToListeners(void *args) { // unlock the delete mutex so the other thread can // kill the agent if it has dissapeared - pthread_mutex_unlock(&thisAgent->deleteMutex); + pthread_mutex_unlock(thisAgent->deleteMutex); } // dynamically sleep until we need to fire off the next set of voxels From acc97282c94029f529483b910d18e4c77bdd49f2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 14:35:45 -0700 Subject: [PATCH 23/31] bracket styling changes, removed commented code --- interface/src/Hand.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/interface/src/Hand.cpp b/interface/src/Hand.cpp index e21c6388f8..4cca3017dc 100644 --- a/interface/src/Hand.cpp +++ b/interface/src/Hand.cpp @@ -21,8 +21,7 @@ const float DEFAULT_Y = -1.5; const float DEFAULT_Z = 2.0; const float DEFAULT_TRANSMITTER_HZ = 60.0; -Hand::Hand(glm::vec3 initcolor) -{ +Hand::Hand(glm::vec3 initcolor) { color = initcolor; reset(); noise = 0.0; //0.2; @@ -51,8 +50,7 @@ Hand::Hand(const Hand &otherHand) { renderPointer = otherHand.renderPointer; } -void Hand::reset() -{ +void Hand::reset() { position.x = DEFAULT_X; position.y = DEFAULT_Y; position.z = DEFAULT_Z; @@ -64,8 +62,7 @@ void Hand::reset() transmitterHz = DEFAULT_TRANSMITTER_HZ; } -void Hand::render(int isMine) -{ +void Hand::render(int isMine) { const float POINTER_LENGTH = 20.0; glPushMatrix(); glTranslatef(position.x, position.y, position.z); @@ -89,22 +86,7 @@ void Hand::render(int isMine) glutSolidCube(1.0); glPopMatrix(); } - glPopMatrix(); - - if (1) { - // Render debug info from the transmitter - /* - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - //gluOrtho2D(0, WIDTH, HEIGHT, 0); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glPopMatrix(); - */ - - } - + glPopMatrix(); } void Hand::addAngularVelocity (float pRate, float yRate, float rRate) { @@ -159,8 +141,7 @@ void Hand::processTransmitterData(char *packetData, int numBytes) { } -void Hand::simulate(float deltaTime) -{ +void Hand::simulate(float deltaTime) { const float ANGULAR_SPRING_CONSTANT = 0.25; const float ANGULAR_DAMPING_COEFFICIENT = 5*2.0f*powf(ANGULAR_SPRING_CONSTANT,0.5f); const float LINEAR_SPRING_CONSTANT = 100; From 7bc822669ae6f901275f6bc1a8f43b530f063432 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 14:40:53 -0700 Subject: [PATCH 24/31] some column width fixes in domain server --- domain/src/main.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/domain/src/main.cpp b/domain/src/main.cpp index 9235091660..786bbda482 100644 --- a/domain/src/main.cpp +++ b/domain/src/main.cpp @@ -127,9 +127,12 @@ int main(int argc, const char * argv[]) currentBufferPos = broadcastPacket + 1; startPointer = currentBufferPos; - for(std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) { + for(std::vector::iterator agent = agentList.getAgents().begin(); + agent != agentList.getAgents().end(); + agent++) { - if (DEBUG_TO_SELF || !agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) { + if (DEBUG_TO_SELF || + !agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) { if (strchr(SOLO_AGENT_TYPES_STRING, (int) agent->getType()) == NULL) { // this is an agent of which there can be multiple, just add them to the packet currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); @@ -155,7 +158,9 @@ int main(int argc, const char * argv[]) } if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) { - agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, broadcastPacket, packetBytesWithoutLeadingChar + 1); + agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, + broadcastPacket, + packetBytesWithoutLeadingChar + 1); } } } From 9a4f73e3bdc331990e089c35dcacfdd49ad31bdf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 15:14:42 -0700 Subject: [PATCH 25/31] fix undeclared identifier myHead --- interface/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 97f928ed43..7b8195f59d 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -470,7 +470,7 @@ void simulateHead(float frametime) // Send my stream of head/hand data to the avatar mixer and voxel server char broadcastString[200]; - int broadcastBytes = myHead.getBroadcastData(broadcastString); + int broadcastBytes = myAvatar.getBroadcastData(broadcastString); char broadcastReceivers[2]; *broadcastReceivers = AGENT_TYPE_VOXEL; @@ -1059,7 +1059,7 @@ void *networkReceive(void *args) switch (incomingPacket[0]) { case PACKET_HEADER_TRANSMITTER_DATA: - myHead.hand->processTransmitterData(incomingPacket, bytesReceived); + myAvatar.hand->processTransmitterData(incomingPacket, bytesReceived); break; case PACKET_HEADER_VOXEL_DATA: case PACKET_HEADER_Z_COMMAND: From c378241afbeba5bc0a606ea35b7283a6aef96972 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 15:20:35 -0700 Subject: [PATCH 26/31] NULL terminate the broadcastReceivers char* --- interface/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 7b8195f59d..0ce344bdfd 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -472,9 +472,10 @@ void simulateHead(float frametime) char broadcastString[200]; int broadcastBytes = myAvatar.getBroadcastData(broadcastString); - char broadcastReceivers[2]; + char broadcastReceivers[3]; *broadcastReceivers = AGENT_TYPE_VOXEL; *(broadcastReceivers + 1) = AGENT_TYPE_AVATAR_MIXER; + *(broadcastReceivers + 2) = '\0'; agentList.broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers); From 010c7e028da2cba8c8239dc16f3d89119b28aa15 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 15:30:21 -0700 Subject: [PATCH 27/31] switch from strchr to memchr for broadcastToAgents --- interface/src/main.cpp | 14 +++++--------- shared/src/AgentList.cpp | 4 ++-- shared/src/AgentList.h | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 0ce344bdfd..b15b90487f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -471,13 +471,9 @@ void simulateHead(float frametime) // Send my stream of head/hand data to the avatar mixer and voxel server char broadcastString[200]; int broadcastBytes = myAvatar.getBroadcastData(broadcastString); + const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER}; - char broadcastReceivers[3]; - *broadcastReceivers = AGENT_TYPE_VOXEL; - *(broadcastReceivers + 1) = AGENT_TYPE_AVATAR_MIXER; - *(broadcastReceivers + 2) = '\0'; - - agentList.broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers); + agentList.broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) { @@ -497,7 +493,7 @@ void simulateHead(float frametime) ::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) { if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &::paintingVoxel, bufferOut, sizeOut)){ - agentList.broadcastToAgents((char*)bufferOut, sizeOut, &AGENT_TYPE_VOXEL); + agentList.broadcastToAgents((char*)bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); delete bufferOut; } } @@ -864,14 +860,14 @@ void sendVoxelServerEraseAll() { char message[100]; sprintf(message,"%c%s",'Z',"erase all"); int messageSize = strlen(message) + 1; - ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL); + ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1); } void sendVoxelServerAddScene() { char message[100]; sprintf(message,"%c%s",'Z',"add scene"); int messageSize = strlen(message) + 1; - ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL); + ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1); } void shiftPaintingColor() diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index 0cfac49429..8901a4aa6b 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -246,10 +246,10 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, } } -void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes) { +void AgentList::broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes, int numAgentTypes) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { // only send to the AgentTypes we are asked to send to. - if (agent->getActiveSocket() != NULL && strchr(agentTypes,agent->getType())) { + if (agent->getActiveSocket() != NULL && memchr(agentTypes, agent->getType(), numAgentTypes)) { // we know which socket is good for this agent, send there agentSocket.send(agent->getActiveSocket(), broadcastData, dataBytes); } diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index eaecc1bf50..ee61a35c8d 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -66,7 +66,7 @@ public: void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes); void updateAgentWithData(Agent *agent, void *packetData, int dataBytes); - void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes); + void broadcastToAgents(char *broadcastData, size_t dataBytes, const char* agentTypes, int numAgentTypes); char getOwnerType(); unsigned int getSocketListenPort(); From 7731ae886a7a043719e82620cfa5871e3a0c4422 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 15:30:33 -0700 Subject: [PATCH 28/31] remove some more MARKER_CAPTURE code --- interface/src/main.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b15b90487f..dbcd2b623a 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -192,21 +192,6 @@ timeval timerStart, timerEnd; timeval lastTimeIdle; double elapsedTime; -#ifdef MARKER_CAPTURE - - /*** Marker Capture ***/ - #define MARKER_CAPTURE_INTERVAL 1 - MarkerCapture marker_capturer(CV_CAP_ANY); // Create a new marker capturer, attached to any valid camera. - MarkerAcquisitionView marker_acq_view(&marker_capturer); - bool marker_capture_enabled = true; - bool marker_capture_display = true; - IplImage* marker_capture_frame; - IplImage* marker_capture_blob_frame; - pthread_mutex_t frame_lock; - -#endif - - // Every second, check the frame rates and other stuff void Timer(int extra) { From 3823809497c90de13d8edc5bd1388fa37df7ce9b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 10 Apr 2013 15:37:27 -0700 Subject: [PATCH 29/31] repairs in voxel server --- voxel/src/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index e88777913f..da86c189c3 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -131,7 +131,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it - pthread_mutex_lock(thisAgent->deleteMutex); + pthread_mutex_lock(&thisAgent->deleteMutex); // clean up the agent visit data delete agentData->rootMarkerNode; @@ -139,7 +139,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { // unlock the delete mutex so the other thread can // kill the agent if it has dissapeared - pthread_mutex_unlock(thisAgent->deleteMutex); + pthread_mutex_unlock(&thisAgent->deleteMutex); } } @@ -168,7 +168,7 @@ void *distributeVoxelsToListeners(void *args) { // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it - pthread_mutex_lock(thisAgent->deleteMutex); + pthread_mutex_lock(&thisAgent->deleteMutex); stopOctal = NULL; packetCount = 0; @@ -208,7 +208,7 @@ void *distributeVoxelsToListeners(void *args) { // unlock the delete mutex so the other thread can // kill the agent if it has dissapeared - pthread_mutex_unlock(thisAgent->deleteMutex); + pthread_mutex_unlock(&thisAgent->deleteMutex); } // dynamically sleep until we need to fire off the next set of voxels @@ -345,7 +345,7 @@ int main(int argc, const char * argv[]) // Now send this to the connected agents so they know to delete printf("rebroadcasting delete voxel message to connected agents... agentList.broadcastToAgents()\n"); - agentList.broadcastToAgents(packetData,receivedBytes, AGENT_TYPE_INTERFACE); + agentList.broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_INTERFACE, 1); } if (packetData[0] == PACKET_HEADER_Z_COMMAND) { @@ -373,7 +373,7 @@ int main(int argc, const char * argv[]) // Now send this to the connected agents so they can also process these messages printf("rebroadcasting Z message to connected agents... agentList.broadcastToAgents()\n"); - agentList.broadcastToAgents(packetData,receivedBytes, AGENT_TYPE_INTERFACE); + agentList.broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_INTERFACE, 1); } // If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_INTERFACE, and we // need to make sure we have it in our agentList. From bdde66fec8432b5a221e52a703a109f5e69b97e0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Apr 2013 09:53:24 -0700 Subject: [PATCH 30/31] have avatar mixer reply with bulk packet immediately on receive --- avatar/src/main.cpp | 68 +++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index 73d3a3b6ba..fcaef1045c 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -62,42 +62,6 @@ unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent * return currentPosition; } -void *sendAvatarData(void *args) { - timeval startTime; - - unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; - *broadcastPacket = PACKET_HEADER_AVATAR_SERVER; - - unsigned char* currentBufferPosition = NULL; - - while (true) { - gettimeofday(&startTime, NULL); - - currentBufferPosition = broadcastPacket + 1; - - for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); - avatarAgent != agentList.getAgents().end(); - avatarAgent++) { - if (avatarAgent->getLinkedData() != NULL) { - currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); - } - } - - for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); - avatarAgent != agentList.getAgents().end(); - avatarAgent++) { - if (avatarAgent->getActiveSocket()) { - agentList.getAgentSocket().send(avatarAgent->getPublicSocket(), - broadcastPacket, - currentBufferPosition - broadcastPacket); - } - } - - double usecToSleep = BROADCAST_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&startTime)); - usleep(usecToSleep); - } -} - void attachAvatarDataToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { newAgent->setLinkedData(new AvatarAgentData()); @@ -108,9 +72,6 @@ int main(int argc, char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); - pthread_t sendAvatarDataThread; - pthread_create(&sendAvatarDataThread, NULL, sendAvatarData, NULL); - agentList.linkedDataCreateCallback = attachAvatarDataToAgent; agentList.startDomainServerCheckInThread(); @@ -120,6 +81,12 @@ int main(int argc, char* argv[]) sockaddr *agentAddress = new sockaddr; char *packetData = new char[MAX_PACKET_SIZE]; ssize_t receivedBytes = 0; + + unsigned char *broadcastPacket = new unsigned char[MAX_PACKET_SIZE]; + *broadcastPacket = PACKET_HEADER_AVATAR_SERVER; + + unsigned char* currentBufferPosition = NULL; + int agentIndex = 0; while (true) { if (agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { @@ -127,6 +94,28 @@ int main(int argc, char* argv[]) case PACKET_HEADER_HEAD_DATA: // this is positional data from an agent agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); + + currentBufferPosition = broadcastPacket + 1; + agentIndex = 0; + + // send back a packet with other active agent data to this agent + for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); + avatarAgent != agentList.getAgents().end(); + avatarAgent++) { + if (avatarAgent->getLinkedData() != NULL + && agentIndex != agentList.indexOfMatchingAgent(agentAddress)) { + currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); + } + + agentIndex++; + } + + if (currentBufferPosition - broadcastPacket > 1) { + agentList.getAgentSocket().send(agentAddress, + broadcastPacket, + currentBufferPosition - broadcastPacket); + } + break; default: // hand this off to the AgentList @@ -140,6 +129,5 @@ int main(int argc, char* argv[]) agentList.stopSilentAgentRemovalThread(); agentList.stopPingUnknownAgentsThread(); - pthread_join(sendAvatarDataThread, NULL); return 0; } From 2827a1a44701119dea7f5c522ca201d69157ec7a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 11 Apr 2013 10:17:11 -0700 Subject: [PATCH 31/31] send empty packet from avatar mixer for keepalive --- avatar/src/main.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index fcaef1045c..2fa8523849 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -110,11 +110,9 @@ int main(int argc, char* argv[]) agentIndex++; } - if (currentBufferPosition - broadcastPacket > 1) { - agentList.getAgentSocket().send(agentAddress, - broadcastPacket, - currentBufferPosition - broadcastPacket); - } + agentList.getAgentSocket().send(agentAddress, + broadcastPacket, + currentBufferPosition - broadcastPacket); break; default: