diff --git a/CMakeLists.txt b/CMakeLists.txt index 526ba77653..3923f543fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ project(hifi) add_subdirectory(avatar-mixer) add_subdirectory(audio-mixer) add_subdirectory(domain-server) +add_subdirectory(eve) add_subdirectory(interface) add_subdirectory(injector) add_subdirectory(space-server) diff --git a/eve/CMakeLists.txt b/eve/CMakeLists.txt new file mode 100644 index 0000000000..cb38529b2d --- /dev/null +++ b/eve/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +set(ROOT_DIR ..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") + +set(TARGET_NAME eve) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME}) + +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + +# link the required hifi libraries +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/eve/src/main.cpp b/eve/src/main.cpp new file mode 100644 index 0000000000..1478f3d1b2 --- /dev/null +++ b/eve/src/main.cpp @@ -0,0 +1,128 @@ +// +// main.cpp +// eve +// +// Created by Stephen Birarda on 4/22/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include + +#include +#include +#include +#include +#include + +const int EVE_AGENT_LIST_PORT = 55441; +const float DATA_SEND_INTERVAL_MSECS = 10; + +bool stopReceiveAgentDataThread; + +void *receiveAgentData(void *args) +{ + sockaddr senderAddress; + ssize_t bytesReceived; + unsigned char incomingPacket[MAX_PACKET_SIZE]; + + AgentList *agentList = AgentList::getInstance(); + Agent *avatarMixer = NULL; + + while (!::stopReceiveAgentDataThread) { + if (agentList->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { + switch (incomingPacket[0]) { + case PACKET_HEADER_BULK_AVATAR_DATA: + // this is the positional data for other agents + // eve doesn't care about this for now, so let's just update the receive time for the + // avatar mixer - this makes sure it won't be killed during silent agent removal + avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); + + if (avatarMixer != NULL) { + avatarMixer->setLastRecvTimeUsecs(usecTimestampNow()); + } + + break; + default: + // have the agentList handle list of agents from DS, replies from other agents, etc. + agentList->processAgentData(&senderAddress, incomingPacket, bytesReceived); + break; + } + } + } + + pthread_exit(0); + return NULL; +} + +int main(int argc, char* argv[]) { + // create an AgentList instance to handle communication with other agents + AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AVATAR, EVE_AGENT_LIST_PORT); + + // start telling the domain server that we are alive + agentList->startDomainServerCheckInThread(); + + // start the agent list thread that will kill off agents when they stop talking + agentList->startSilentAgentRemovalThread(); + + // start the ping thread that hole punches to create an active connection to other agents + agentList->startPingUnknownAgentsThread(); + + pthread_t receiveAgentDataThread; + pthread_create(&receiveAgentDataThread, NULL, receiveAgentData, NULL); + + // create an AvatarData object, "eve" + AvatarData eve = AvatarData(); + + // move eve away from the origin + eve.setBodyPosition(glm::vec3(3, 0, -3)); + + // turn her back towards the origin + eve.setBodyYaw(-45); + + // put her hand out so somebody can shake it + eve.setHandPosition(glm::vec3(eve.getBodyPosition()[0] - 0.2, + 0.25, + eve.getBodyPosition()[2] + 0.1)); + + unsigned char broadcastPacket[MAX_PACKET_SIZE]; + broadcastPacket[0] = PACKET_HEADER_HEAD_DATA; + + int numBytesToSend = 0; + + timeval thisSend; + double numMicrosecondsSleep = 0; + + while (true) { + // update the thisSend timeval to the current time + gettimeofday(&thisSend, NULL); + + // find the current avatar mixer + Agent *avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); + + // make sure we actually have an avatar mixer with an active socket + if (avatarMixer != NULL && avatarMixer->getActiveSocket() != NULL) { + // use the getBroadcastData method in the AvatarData class to populate the broadcastPacket buffer + numBytesToSend = eve.getBroadcastData((broadcastPacket + 1)); + + + // use the UDPSocket instance attached to our agent list to send avatar data to mixer + agentList->getAgentSocket().send(avatarMixer->getActiveSocket(), broadcastPacket, numBytesToSend); + } + + // sleep for the correct amount of time to have data send be consistently timed + if ((numMicrosecondsSleep = (DATA_SEND_INTERVAL_MSECS * 1000) - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) { + usleep(numMicrosecondsSleep); + } + } + + // stop the receive agent data thread + stopReceiveAgentDataThread = true; + pthread_join(receiveAgentDataThread, NULL); + + // stop the agent list's threads + agentList->stopDomainServerCheckInThread(); + agentList->stopPingUnknownAgentsThread(); + agentList->stopSilentAgentRemovalThread(); +} + + diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index de9b31c9df..e4e8dc1614 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -8,7 +8,6 @@ project(${TARGET_NAME}) # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") -set(GLM_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) set(LODEPNG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LodePNG) set(PORTAUDIO_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/portaudio) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index be8a6680bd..bf410eae94 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -328,7 +328,7 @@ void Head::simulate(float deltaTime) { for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { - if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_INTERFACE ) )) { + if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_AVATAR ) )) { Head *otherAvatar = (Head *)agent->getLinkedData(); if ( _numOtherAvatarsInView < MAX_OTHER_AVATARS ) { diff --git a/interface/src/main.cpp b/interface/src/main.cpp index a66d411c5e..749113f490 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -986,11 +986,18 @@ void display(void) menu.render(WIDTH,HEIGHT); } - // Draw number of nearby people always + // Stats at upper right of screen about who domain server is telling us about glPointSize(1.0f); char agents[100]; - sprintf(agents, "Agents: %ld\n", AgentList::getInstance()->getAgents().size()); - drawtext(WIDTH-100,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); + + int totalAgents = AgentList::getInstance()->getAgents().size(); + int totalAvatars = 0, totalServers = 0; + for (int i = 0; i < totalAgents; i++) { + (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_INTERFACE) + ? totalAvatars++ : totalServers++; + } + sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); + drawtext(WIDTH-150,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); if (::paintOn) { @@ -1632,7 +1639,7 @@ int main(int argc, const char * argv[]) return EXIT_SUCCESS; } - AgentList::createInstance(AGENT_TYPE_INTERFACE); + AgentList::createInstance(AGENT_TYPE_AVATAR); gettimeofday(&applicationStartupTime, NULL); const char* domainIP = getCmdOption(argc, argv, "--domain"); diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index d05afe5e26..819e4c185f 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -132,7 +132,7 @@ const char* Agent::getTypeName() const { case AGENT_TYPE_VOXEL: name = AGENT_TYPE_NAME_VOXEL; break; - case AGENT_TYPE_INTERFACE: + case AGENT_TYPE_AVATAR: name = AGENT_TYPE_NAME_INTERFACE; break; case AGENT_TYPE_AUDIO_MIXER: diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 5316eee79c..b89c9aa70c 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -228,7 +228,6 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, if (agent == agents.end()) { // we didn't have this agent, so add them - Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId); if (socketMatch(publicSocket, localSocket)) { @@ -281,7 +280,7 @@ void AgentList::broadcastToAgents(unsigned char *broadcastData, size_t dataBytes 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 + // prioritize the private address so that we prune erroneous local matches if (socketMatch(agent->getPublicSocket(), agentAddress)) { agent->activatePublicSocket(); break; diff --git a/libraries/shared/src/AgentTypes.h b/libraries/shared/src/AgentTypes.h index a5d79efac8..c43af79446 100644 --- a/libraries/shared/src/AgentTypes.h +++ b/libraries/shared/src/AgentTypes.h @@ -20,7 +20,7 @@ // Agent Type Codes 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_AVATAR = 'I'; // could also be injector??? const char AGENT_TYPE_AUDIO_MIXER = 'M'; const char AGENT_TYPE_AVATAR_MIXER = 'W'; diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 99b72be9cb..88aad84af6 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -7,7 +7,6 @@ set(MACRO_DIR ${ROOT_DIR}/cmake/macros) # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") -set(GLM_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) # set up the external glm library include(${MACRO_DIR}/IncludeGLM.cmake) @@ -22,7 +21,4 @@ include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi voxels library -link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) - -# find required libraries -find_package(GLM REQUIRED) +link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 8f6bab7dc7..942fbb63b9 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/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, &AGENT_TYPE_INTERFACE, 1); + agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_AVATAR, 1); } if (packetData[0] == PACKET_HEADER_Z_COMMAND) { @@ -373,14 +373,14 @@ 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, 1); + agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_AVATAR, 1); } - // If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_INTERFACE, and we + // If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_AVATAR, and we // need to make sure we have it in our agentList. if (packetData[0] == PACKET_HEADER_HEAD_DATA) { if (agentList->addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, - AGENT_TYPE_INTERFACE, + AGENT_TYPE_AVATAR, agentList->getLastAgentId())) { agentList->increaseAgentId(); }