Second take on avatar mixer

This commit is contained in:
Leonardo Murillo 2013-04-03 15:17:15 -06:00
parent 9220ba3ee5
commit 09df9d3dc7
5 changed files with 153 additions and 0 deletions

View file

@ -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)

17
avatar/CMakeLists.txt Normal file
View file

@ -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})

120
avatar/src/avatar.cpp Normal file
View file

@ -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 <iostream>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <fstream>
#include <limits>
#include <AgentList.h>
#include <SharedUtil.h>
#include <PacketCodes.h>
#include <StdDev.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#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<Agent>::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<Agent>::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);
}
}
}
}

0
avatar/src/avatar.h Normal file
View file

15
shared/src/PacketCodes.h Normal file
View file

@ -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";