diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 9cb977dc1c..a7c34b8a36 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -52,11 +52,10 @@ const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SA const long MAX_SAMPLE_VALUE = std::numeric_limits::max(); const long MIN_SAMPLE_VALUE = std::numeric_limits::min(); -const float DISTANCE_RATIO = 3.0/4.2; +const float DISTANCE_RATIO = 3.0f / 0.3f; const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5; const int PHASE_DELAY_AT_90 = 20; - const int AGENT_LOOPBACK_MODIFIER = 307; const int LOOPBACK_SANITY_CHECK = 0; @@ -127,7 +126,7 @@ void *sendBuffer(void *args) for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { - if (otherAgent != agent || ( otherAgent == agent && agentWantsLoopback)) { + if (otherAgent != agent || (otherAgent == agent && agentWantsLoopback)) { AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); float *agentPosition = agentRingBuffer->getPosition(); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index f90027d25a..df1e547d31 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -151,10 +151,8 @@ int audioCallback (const void *inputBuffer, unsigned char *currentPacketPtr = dataPacket + 1; // memcpy the three float positions - for (int p = 0; p < 3; p++) { - memcpy(currentPacketPtr, &data->linkedAvatar->getPosition()[p], sizeof(float)); - currentPacketPtr += sizeof(float); - } + memcpy(currentPacketPtr, &data->linkedAvatar->getHeadPosition(), sizeof(float) * 3); + currentPacketPtr += (sizeof(float) * 3); // tell the mixer not to add additional attenuation to our source *(currentPacketPtr++) = 255; diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 4fa556c66d..100f5e1430 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -662,7 +662,7 @@ void Avatar::render(bool lookingInMirror) { glTranslatef(width * 0.5, 0, 0); glDisable(GL_LIGHTING); - if (_keyState == NoKeyDown) { + if (_keyState == NO_KEY_DOWN) { drawtext(0, 0, chatMessageScale, 180, 1.0, 0, _chatMessage.c_str(), 0, 1, 0); } else { diff --git a/interface/src/ChatEntry.cpp b/interface/src/ChatEntry.cpp index b658cbaefd..aca13a79ac 100644 --- a/interface/src/ChatEntry.cpp +++ b/interface/src/ChatEntry.cpp @@ -15,8 +15,8 @@ using namespace std; const int MAX_CONTENT_LENGTH = 140; void ChatEntry::clear () { - contents.clear(); - cursorPos = 0; + _contents.clear(); + _cursorPos = 0; } bool ChatEntry::key(unsigned char k) { @@ -25,22 +25,22 @@ bool ChatEntry::key(unsigned char k) { return false; case '\b': - if (cursorPos != 0) { - contents.erase(cursorPos - 1, 1); - cursorPos--; + if (_cursorPos != 0) { + _contents.erase(_cursorPos - 1, 1); + _cursorPos--; } return true; case 127: // delete - if (cursorPos < contents.size()) { - contents.erase(cursorPos, 1); + if (_cursorPos < _contents.size()) { + _contents.erase(_cursorPos, 1); } return true; default: - if (contents.size() != MAX_CONTENT_LENGTH) { - contents.insert(cursorPos, 1, k); - cursorPos++; + if (_contents.size() != MAX_CONTENT_LENGTH) { + _contents.insert(_cursorPos, 1, k); + _cursorPos++; } return true; } @@ -49,24 +49,24 @@ bool ChatEntry::key(unsigned char k) { void ChatEntry::specialKey(unsigned char k) { switch (k) { case GLUT_KEY_LEFT: - if (cursorPos != 0) { - cursorPos--; + if (_cursorPos != 0) { + _cursorPos--; } break; case GLUT_KEY_RIGHT: - if (cursorPos != contents.size()) { - cursorPos++; + if (_cursorPos != _contents.size()) { + _cursorPos++; } break; } } void ChatEntry::render(int screenWidth, int screenHeight) { - drawtext(20, screenHeight - 150, 0.10, 0, 1.0, 0, contents.c_str(), 1, 1, 1); + drawtext(20, screenHeight - 150, 0.10, 0, 1.0, 0, _contents.c_str(), 1, 1, 1); float width = 0; - for (string::iterator it = contents.begin(), end = it + cursorPos; it != end; it++) { + for (string::iterator it = _contents.begin(), end = it + _cursorPos; it != end; it++) { width += glutStrokeWidth(GLUT_STROKE_ROMAN, *it)*0.10; } glDisable(GL_LINE_SMOOTH); diff --git a/interface/src/ChatEntry.h b/interface/src/ChatEntry.h index ea9fc8eb77..db92822158 100644 --- a/interface/src/ChatEntry.h +++ b/interface/src/ChatEntry.h @@ -14,7 +14,7 @@ class ChatEntry { public: - const std::string& getContents () const { return contents; } + const std::string& getContents () const { return _contents; } void clear (); @@ -25,9 +25,8 @@ public: private: - std::string contents; - - int cursorPos; + std::string _contents; + int _cursorPos; }; #endif /* defined(__interface__ChatEntry__) */ diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 05402d51bb..291c665132 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -39,7 +39,7 @@ #include #endif -#include +#include #include #include @@ -88,10 +88,11 @@ using namespace std; void reshape(int width, int height); // will be defined below void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below - +bool enableNetworkThread = true; pthread_t networkReceiveThread; bool stopNetworkReceiveThread = false; - + +unsigned char incomingPacket[MAX_PACKET_SIZE]; int packetCount = 0; int packetsPerSecond = 0; int bytesPerSecond = 0; @@ -353,8 +354,11 @@ void terminate () { #ifndef _WIN32 audio.terminate(); #endif - stopNetworkReceiveThread = true; - pthread_join(networkReceiveThread, NULL); + + if (enableNetworkThread) { + stopNetworkReceiveThread = true; + pthread_join(networkReceiveThread, NULL); + } exit(EXIT_SUCCESS); } @@ -1348,7 +1352,7 @@ void specialkey(int k, int x, int y) void keyUp(unsigned char k, int x, int y) { if (::chatEntryOn) { - myAvatar.setKeyState(AvatarData::NoKeyDown); + myAvatar.setKeyState(NO_KEY_DOWN); return; } @@ -1366,7 +1370,7 @@ void key(unsigned char k, int x, int y) if (::chatEntryOn) { if (chatEntry.key(k)) { myAvatar.setKeyState(k == '\b' || k == 127 ? // backspace or delete - AvatarData::DeleteKeyDown : AvatarData::InsertKeyDown); + DELETE_KEY_DOWN : INSERT_KEY_DOWN); myAvatar.setChatMessage(string(chatEntry.getContents().size(), 'X')); } else { @@ -1445,18 +1449,17 @@ void key(unsigned char k, int x, int y) if (k == '\r') { ::chatEntryOn = true; - myAvatar.setKeyState(AvatarData::NoKeyDown); + myAvatar.setKeyState(NO_KEY_DOWN); myAvatar.setChatMessage(string()); } } // Receive packets from other agents/servers and decide what to do with them! -void *networkReceive(void *args) +void* networkReceive(void* args) { sockaddr senderAddress; ssize_t bytesReceived; - unsigned char *incomingPacket = new unsigned char[MAX_PACKET_SIZE]; - + while (!stopNetworkReceiveThread) { if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { packetCount++; @@ -1480,12 +1483,15 @@ void *networkReceive(void *args) AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); break; } + } else if (!enableNetworkThread) { + break; } } - delete[] incomingPacket; - pthread_exit(0); - return NULL; + if (enableNetworkThread) { + pthread_exit(0); + } + return NULL; } void idle(void) { @@ -1520,6 +1526,11 @@ void idle(void) { // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // updateAvatar(deltaTime); + + // read incoming packets from network + if (!enableNetworkThread) { + networkReceive(0); + } //loop through all the other avatars and simulate them... AgentList* agentList = AgentList::getInstance(); @@ -1663,6 +1674,10 @@ int main(int argc, const char * argv[]) listenPort = atoi(portStr); } AgentList::createInstance(AGENT_TYPE_AVATAR, listenPort); + enableNetworkThread = !cmdOptionExists(argc, argv, "--nonblocking"); + if (!enableNetworkThread) { + AgentList::getInstance()->getAgentSocket().setBlocking(false); + } gettimeofday(&applicationStartupTime, NULL); const char* domainIP = getCmdOption(argc, argv, "--domain"); @@ -1746,8 +1761,10 @@ int main(int argc, const char * argv[]) } // create thread for receipt of data via UDP - pthread_create(&networkReceiveThread, NULL, networkReceive, NULL); - printLog("Network receive thread created.\n"); + if (enableNetworkThread) { + pthread_create(&networkReceiveThread, NULL, networkReceive, NULL); + printLog("Network receive thread created.\n"); + } glutTimerFunc(1000, Timer, 0); glutMainLoop(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b80fbc445e..8881c397af 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -51,7 +51,7 @@ AvatarData::AvatarData() : _cameraAspectRatio(0.0f), _cameraNearClip(0.0f), _cameraFarClip(0.0f), - _keyState(NoKeyDown) { + _keyState(NO_KEY_DOWN) { } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 39a53481fa..88d5c1ac1f 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -15,6 +15,13 @@ #include +enum KeyState +{ + NO_KEY_DOWN, + INSERT_KEY_DOWN, + DELETE_KEY_DOWN +}; + class AvatarData : public AgentData { public: AvatarData(); @@ -76,8 +83,6 @@ public: void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; } void setCameraFarClip(float farClip) { _cameraFarClip = farClip; } - enum KeyState { NoKeyDown, InsertKeyDown, DeleteKeyDown }; - // key state void setKeyState(KeyState s) { _keyState = s; } KeyState keyState() const { return _keyState; } @@ -118,7 +123,7 @@ protected: float _cameraNearClip; float _cameraFarClip; - // key state (nothing, down, up, backspace) + // key state KeyState _keyState; // chat message diff --git a/libraries/shared/src/UDPSocket.cpp b/libraries/shared/src/UDPSocket.cpp index 0fa5ce08a4..31040946e0 100644 --- a/libraries/shared/src/UDPSocket.cpp +++ b/libraries/shared/src/UDPSocket.cpp @@ -119,7 +119,7 @@ unsigned short loadBufferWithSocketInfo(char *addressBuffer, sockaddr *socket) { } } -UDPSocket::UDPSocket(int listeningPort) { +UDPSocket::UDPSocket(int listeningPort) : blocking(true) { init(); // create the socket handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -191,6 +191,18 @@ bool UDPSocket::init() { return true; } +void UDPSocket::setBlocking(bool blocking) { + this->blocking = blocking; + +#ifdef _WIN32 + u_long mode = blocking ? 0 : 1; + ioctlsocket(handle, FIONBIO, &mode); +#else + int flags = fcntl(handle, F_GETFL, 0); + fcntl(handle, F_SETFL, blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK)); +#endif +} + // Receive data on this socket with retrieving address of sender bool UDPSocket::receive(void *receivedData, ssize_t *receivedBytes) { diff --git a/libraries/shared/src/UDPSocket.h b/libraries/shared/src/UDPSocket.h index 2bc5638b5e..80c093d6f4 100644 --- a/libraries/shared/src/UDPSocket.h +++ b/libraries/shared/src/UDPSocket.h @@ -23,12 +23,15 @@ class UDPSocket { UDPSocket(int listening_port); ~UDPSocket(); bool init(); + void setBlocking(bool blocking); + bool isBlocking() { return blocking; } int send(sockaddr *destAddress, const void *data, size_t byteLength); int send(char *destAddress, int destPort, const void *data, size_t byteLength); bool receive(void *receivedData, ssize_t *receivedBytes); bool receive(sockaddr *recvAddress, void *receivedData, ssize_t *receivedBytes); private: int handle; + bool blocking; }; bool socketMatch(sockaddr *first, sockaddr *second);