mirror of
https://github.com/overte-org/overte.git
synced 2025-06-05 23:14:20 +02:00
178 lines
6.5 KiB
C++
178 lines
6.5 KiB
C++
//
|
|
// main.cpp
|
|
// eve
|
|
//
|
|
// Created by Stephen Birarda on 4/22/13.
|
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
//
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <SharedUtil.h>
|
|
#include <AgentTypes.h>
|
|
#include <PacketHeaders.h>
|
|
#include <AgentList.h>
|
|
#include <AvatarData.h>
|
|
#include <AudioInjector.h>
|
|
|
|
const int EVE_AGENT_LIST_PORT = 55441;
|
|
const float DATA_SEND_INTERVAL_MSECS = 10;
|
|
const float MIN_AUDIO_SEND_INTERVAL_SECS = 10;
|
|
const int MIN_ITERATIONS_BETWEEN_AUDIO_SENDS = (MIN_AUDIO_SEND_INTERVAL_SECS * 1000) / DATA_SEND_INTERVAL_MSECS;
|
|
const int MAX_AUDIO_SEND_INTERVAL_SECS = 15;
|
|
const float MAX_ITERATIONS_BETWEEN_AUDIO_SENDS = (MAX_AUDIO_SEND_INTERVAL_SECS * 1000) / DATA_SEND_INTERVAL_MSECS;
|
|
|
|
bool stopReceiveAgentDataThread;
|
|
bool injectAudioThreadRunning = false;
|
|
|
|
int TEMP_AUDIO_LISTEN_PORT = 55439;
|
|
UDPSocket audioSocket(TEMP_AUDIO_LISTEN_PORT);
|
|
|
|
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;
|
|
}
|
|
|
|
void *injectAudio(void *args) {
|
|
::injectAudioThreadRunning = true;
|
|
|
|
AudioInjector* eveAudioInjector = (AudioInjector *)args;
|
|
|
|
// look for an audio mixer in our agent list
|
|
Agent* audioMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER);
|
|
|
|
if (audioMixer != NULL) {
|
|
// until the audio mixer is setup for ping-reply, activate the public socket if it's not active
|
|
if (audioMixer->getActiveSocket() == NULL) {
|
|
audioMixer->activatePublicSocket();
|
|
}
|
|
|
|
// we have an active audio mixer we can send data to
|
|
eveAudioInjector->injectAudio(&::audioSocket, audioMixer->getActiveSocket());
|
|
}
|
|
|
|
::injectAudioThreadRunning = false;
|
|
pthread_exit(0);
|
|
return NULL;
|
|
}
|
|
|
|
int main(const int argc, const char* argv[]) {
|
|
// new seed for random audio sleep times
|
|
srand(time(0));
|
|
|
|
// 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));
|
|
|
|
// read eve's audio data
|
|
AudioInjector eveAudioInjector("eve.raw");
|
|
|
|
unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
|
broadcastPacket[0] = PACKET_HEADER_HEAD_DATA;
|
|
|
|
int numBytesToSend = 0;
|
|
|
|
timeval thisSend;
|
|
double numMicrosecondsSleep = 0;
|
|
|
|
int numIterationsLeftBeforeAudioSend = 0;
|
|
pthread_t injectAudioThread;
|
|
|
|
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);
|
|
}
|
|
|
|
if (numIterationsLeftBeforeAudioSend == 0) {
|
|
if (!::injectAudioThreadRunning) {
|
|
pthread_create(&injectAudioThread, NULL, injectAudio, (void*) &eveAudioInjector);
|
|
|
|
numIterationsLeftBeforeAudioSend = randIntInRange(MIN_ITERATIONS_BETWEEN_AUDIO_SENDS,
|
|
MAX_ITERATIONS_BETWEEN_AUDIO_SENDS);
|
|
}
|
|
} else {
|
|
numIterationsLeftBeforeAudioSend--;
|
|
}
|
|
|
|
// 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();
|
|
}
|
|
|
|
|