From 38f8769ff648a09650a280d0cc48cdfbe76a06cf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 11:39:38 -0700 Subject: [PATCH 1/5] stub setup for eve --- CMakeLists.txt | 1 + eve/CMakeLists.txt | 13 +++++++++++++ eve/src/main.cpp | 13 +++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 eve/CMakeLists.txt create mode 100644 eve/src/main.cpp 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..b62368f6d3 --- /dev/null +++ b/eve/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.8) + +set(ROOT_DIR ..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +set(TARGET_NAME eve) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME}) + +# link the shared hifi library +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${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..05159dd9c0 --- /dev/null +++ b/eve/src/main.cpp @@ -0,0 +1,13 @@ +// +// main.cpp +// eve +// +// Created by Stephen Birarda on 4/22/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +int main(int argc, char* argv[]) { + +} + + From c68ec079eba32ed779d1feb436c828a88f959983 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 11:54:24 -0700 Subject: [PATCH 2/5] rename AGENT_TYPE_INTERFACE to AGENT_TYPE_AVATAR, more stubbing for eve --- eve/src/main.cpp | 48 ++++++++++++++++++++++++++++++- interface/src/Head.cpp | 2 +- interface/src/main.cpp | 2 +- libraries/shared/src/Agent.cpp | 2 +- libraries/shared/src/AgentTypes.h | 2 +- voxel-server/src/main.cpp | 8 +++--- 6 files changed, 55 insertions(+), 9 deletions(-) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 05159dd9c0..0533ffe7ea 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -6,8 +6,54 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -int main(int argc, char* argv[]) { +#include +#include +#include +const int EVE_AGENT_LIST_PORT = 55441; + +bool stopReceiveAgentDataThread; + +void *receiveAgentData(void *args) +{ + sockaddr senderAddress; + ssize_t bytesReceived; + unsigned char incomingPacket[MAX_PACKET_SIZE]; + + while (!::stopReceiveAgentDataThread) { + if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { + + // we're going to ignore any data that isn't the agent list from the domain server + // ex: the avatar mixer will be sending us the position of other agents + switch (incomingPacket[0]) { + case PACKET_HEADER_DOMAIN: + AgentList::getInstance()->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(); + + // stop the agent list's threads + agentList->stopDomainServerCheckInThread(); + agentList->stopPingUnknownAgentsThread(); + agentList->stopSilentAgentRemovalThread(); } diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 50ebeed4ae..abba74eb5f 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -331,7 +331,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(); // when this is working, I will grab the position here... diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 488f9f29b1..aad8a9be74 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1630,7 +1630,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/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/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(); } From a558597b6a3f490891ebae986baf7ea0427e299b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 13:10:21 -0700 Subject: [PATCH 3/5] complete an initial version of eve that sits at 0,0,0 --- eve/CMakeLists.txt | 11 ++++- eve/src/main.cpp | 72 +++++++++++++++++++++++++++--- interface/CMakeLists.txt | 1 - libraries/shared/src/AgentList.cpp | 3 +- voxel-server/CMakeLists.txt | 6 +-- 5 files changed, 76 insertions(+), 17 deletions(-) diff --git a/eve/CMakeLists.txt b/eve/CMakeLists.txt index b62368f6d3..cb38529b2d 100644 --- a/eve/CMakeLists.txt +++ b/eve/CMakeLists.txt @@ -3,11 +3,18 @@ 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}) -# link the shared hifi library +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}) \ No newline at end of file +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 index 0533ffe7ea..1078f48fdc 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -6,11 +6,16 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // +#include + +#include #include -#include #include +#include +#include const int EVE_AGENT_LIST_PORT = 55441; +const float DATA_SEND_INTERVAL_MSECS = 10; bool stopReceiveAgentDataThread; @@ -20,14 +25,26 @@ void *receiveAgentData(void *args) ssize_t bytesReceived; unsigned char incomingPacket[MAX_PACKET_SIZE]; + AgentList *agentList = AgentList::getInstance(); + Agent *avatarMixer = NULL; + while (!::stopReceiveAgentDataThread) { - if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { - - // we're going to ignore any data that isn't the agent list from the domain server - // ex: the avatar mixer will be sending us the position of other agents + if (agentList->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { switch (incomingPacket[0]) { - case PACKET_HEADER_DOMAIN: - AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); + 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; } } @@ -50,6 +67,47 @@ int main(int argc, char* argv[]) { // 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(); + + 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(); 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/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/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 From 3016e5665f4c1982fac84379c44362efed277831 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 13:22:48 -0700 Subject: [PATCH 4/5] move eve away from the origin --- eve/src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 1078f48fdc..a6fb867af2 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -73,6 +73,9 @@ int main(int argc, char* argv[]) { // create an AvatarData object, "eve" AvatarData eve = AvatarData(); + // move eve away from the origin + eve.setBodyPosition(glm::vec3(3, 0, -3)); + unsigned char broadcastPacket[MAX_PACKET_SIZE]; broadcastPacket[0] = PACKET_HEADER_HEAD_DATA; From f4d5774e693175711049938c8329477b6f3f973e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 13:55:59 -0700 Subject: [PATCH 5/5] change eve's orientation and hand position --- eve/src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index a6fb867af2..1478f3d1b2 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -76,6 +76,14 @@ int main(int argc, char* argv[]) { // 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;