From 09df9d3dc733946ebd3c3a42ff80f83aea0f7400 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Wed, 3 Apr 2013 15:17:15 -0600 Subject: [PATCH] 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";