diff --git a/avatar/src/main.cpp b/avatar/src/main.cpp index 6bd50cf93a..f59a2f8bcb 100644 --- a/avatar/src/main.cpp +++ b/avatar/src/main.cpp @@ -37,8 +37,6 @@ const int AVATAR_LISTEN_PORT = 55444; const unsigned short BROADCAST_INTERVAL_USECS = 20 * 1000 * 1000; -AgentList agentList(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); - unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket()); @@ -70,13 +68,14 @@ void attachAvatarDataToAgent(Agent *newAgent) { int main(int argc, char* argv[]) { + AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); - agentList.linkedDataCreateCallback = attachAvatarDataToAgent; + agentList->linkedDataCreateCallback = attachAvatarDataToAgent; - agentList.startDomainServerCheckInThread(); - agentList.startSilentAgentRemovalThread(); - agentList.startPingUnknownAgentsThread(); + agentList->startDomainServerCheckInThread(); + agentList->startSilentAgentRemovalThread(); + agentList->startPingUnknownAgentsThread(); sockaddr *agentAddress = new sockaddr; char *packetData = new char[MAX_PACKET_SIZE]; @@ -89,43 +88,43 @@ int main(int argc, char* argv[]) int agentIndex = 0; while (true) { - if (agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + if (agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { switch (packetData[0]) { case PACKET_HEADER_HEAD_DATA: // this is positional data from an agent - agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); + agentList->updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); currentBufferPosition = broadcastPacket + 1; agentIndex = 0; // send back a packet with other active agent data to this agent - for (std::vector::iterator avatarAgent = agentList.getAgents().begin(); - avatarAgent != agentList.getAgents().end(); + for (std::vector::iterator avatarAgent = agentList->getAgents().begin(); + avatarAgent != agentList->getAgents().end(); avatarAgent++) { if (avatarAgent->getLinkedData() != NULL - && agentIndex != agentList.indexOfMatchingAgent(agentAddress)) { + && agentIndex != agentList->indexOfMatchingAgent(agentAddress)) { currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent); } agentIndex++; } - agentList.getAgentSocket().send(agentAddress, + agentList->getAgentSocket().send(agentAddress, broadcastPacket, currentBufferPosition - broadcastPacket); break; default: // hand this off to the AgentList - agentList.processAgentData(agentAddress, (void *)packetData, receivedBytes); + agentList->processAgentData(agentAddress, (void *)packetData, receivedBytes); break; } } } - agentList.stopDomainServerCheckInThread(); - agentList.stopSilentAgentRemovalThread(); - agentList.stopPingUnknownAgentsThread(); + agentList->stopDomainServerCheckInThread(); + agentList->stopSilentAgentRemovalThread(); + agentList->stopPingUnknownAgentsThread(); return 0; } diff --git a/domain/src/main.cpp b/domain/src/main.cpp index 786bbda482..8ab62eaeeb 100644 --- a/domain/src/main.cpp +++ b/domain/src/main.cpp @@ -48,7 +48,6 @@ const int LOGOFF_CHECK_INTERVAL = 5000; #define DEBUG_TO_SELF 0 int lastActiveCount = 0; -AgentList agentList(AGENT_TYPE_DOMAIN, DOMAIN_LISTEN_PORT); unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) { *currentPosition++ = agentToAdd->getType(); @@ -63,6 +62,7 @@ unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent int main(int argc, const char * argv[]) { + AgentList *agentList = AgentList::createInstance(AGENT_TYPE_DOMAIN, DOMAIN_LISTEN_PORT); // If user asks to run in "local" mode then we do NOT replace the IP // with the EC2 IP. Otherwise, we will replace the IP like we used to // this allows developers to run a local domain without recompiling the @@ -95,10 +95,10 @@ int main(int argc, const char * argv[]) in_addr_t serverLocalAddress = getLocalAddress(); - agentList.startSilentAgentRemovalThread(); + agentList->startSilentAgentRemovalThread(); while (true) { - if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) { + if (agentList->getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) { std::map newestSoloAgents; agentType = packetData[0]; @@ -115,20 +115,20 @@ int main(int argc, const char * argv[]) } } - if (agentList.addOrUpdateAgent((sockaddr *)&agentPublicAddress, + if (agentList->addOrUpdateAgent((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType, - agentList.getLastAgentId())) { + agentList->getLastAgentId())) { - agentList.increaseAgentId(); + agentList->increaseAgentId(); } currentBufferPos = broadcastPacket + 1; startPointer = currentBufferPos; - for(std::vector::iterator agent = agentList.getAgents().begin(); - agent != agentList.getAgents().end(); + for(std::vector::iterator agent = agentList->getAgents().begin(); + agent != agentList->getAgents().end(); agent++) { if (DEBUG_TO_SELF || @@ -158,7 +158,7 @@ int main(int argc, const char * argv[]) } if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) { - agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress, + agentList->getAgentSocket().send((sockaddr *)&agentPublicAddress, broadcastPacket, packetBytesWithoutLeadingChar + 1); } diff --git a/interface/src/Finger.cpp b/interface/src/Finger.cpp deleted file mode 100644 index 1ea3b26fe6..0000000000 --- a/interface/src/Finger.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// -// Finger.cpp -// interface -// -// Created by Philip on 1/21/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#include "Finger.h" - -#ifdef _WIN32 - -float fminf( float x, float y ) -{ - return x < y ? x : y; -} - -#endif - -const int NUM_BEADS = 75; -const float RADIUS = 50; // Radius of beads around finger - -const int NUM_PUCKS = 10; - -Finger::Finger(int w, int h) { - width = w; - height = h; - pos.x = pos.y = 0; - vel.x = vel.y = 0; - target.x = target.y = 0; - m = 1; - pressure = 0; - start = true; - // Create surface beads - beads = new bead[NUM_BEADS]; - pucks = new puck[NUM_PUCKS]; - - float alpha = 0; - for (int i = 0; i < NUM_BEADS; i++) { - beads[i].target.x = cosf(alpha)*RADIUS + 2.0f*(randFloat() - 0.5f); - beads[i].target.y = sinf(alpha)*RADIUS + 2.0f*(randFloat() - 0.5f); - beads[i].pos.x = beads[i].pos.y = 0.0; - beads[i].vel.x = beads[i].vel.y = 0.0; - alpha += 2.0f*PIf/NUM_BEADS; - beads[i].color[0] = randFloat()*0.05f; beads[i].color[1] = randFloat()*0.05f; beads[i].color[2] = 0.75f + randFloat()*0.25f; - beads[i].brightness = 0.0; - } - for (int i = 0; i < NUM_PUCKS; i++) { - pucks[i].pos.x = randFloat()*width; - pucks[i].pos.y = randFloat()*height; - pucks[i].radius = 5.0f + randFloat()*30.0f; - pucks[i].vel.x = pucks[i].vel.y = 0.0; - pucks[i].mass = pucks[i].radius*pucks[i].radius/25.0f; - } - -} - -const float SHADOW_COLOR[4] = {0.0, 0.0, 0.0, 0.75}; -const float SHADOW_OFFSET = 2.5; - -void Finger::render() { - glEnable(GL_POINT_SMOOTH); - - glPointSize(30.0f); - glBegin(GL_POINTS); - glColor4fv(SHADOW_COLOR); - glVertex2f(pos.x + SHADOW_OFFSET, pos.y + SHADOW_OFFSET); - glColor4f(0.0, 0.0, 0.7f, 1.0); - glVertex2f(pos.x, pos.y); - glEnd(); - - // Render Pucks - for (int i = 0; i < NUM_PUCKS; i++) { - glColor4fv(SHADOW_COLOR); - glPointSize(pucks[i].radius*2.f); - glBegin(GL_POINTS); - glVertex2f(pucks[i].pos.x + SHADOW_OFFSET, pucks[i].pos.y + SHADOW_OFFSET); - glColor4f(1.0, 0.0, 0.0, 1.0); - glVertex2f(pucks[i].pos.x, pucks[i].pos.y); - glEnd(); - } - - // Render beads - glPointSize(5.0f); - glLineWidth(3.0); - - glBegin(GL_POINTS); - for (int i = 0; i < NUM_BEADS; i++) { - glColor4fv(SHADOW_COLOR); - glVertex2f(beads[i].pos.x + SHADOW_OFFSET, beads[i].pos.y + SHADOW_OFFSET); - glColor3f(beads[i].color[0]+beads[i].brightness, beads[i].color[1]+beads[i].brightness, beads[i].color[2]+beads[i].brightness); - glVertex2f(beads[i].pos.x, beads[i].pos.y); - } - glEnd(); - -} - -void Finger::setTarget(int x, int y) { - target.x = static_cast(x); - target.y = static_cast(y); - if (start) { - // On startup, set finger to first target location - pos.x = target.x; - pos.y = target.y; - vel.x = vel.y = 0.0; - start = false; - } -} - -void Finger::simulate(float deltaTime) { - // Using the new target position x and y as where the mouse intends the finger to be, move the finger - if (!start) { - - // Move the finger - float distance = glm::distance(pos, target); - //float spring_length = 0; - const float SPRING_FORCE = 1000.0; - - if (distance > 0.1) { - vel += glm::normalize(target - pos)*deltaTime*SPRING_FORCE*distance; - } - // Decay Velocity (Drag) - - vel *= 0.8; - //vel *= (1.f - CONSTANT_DAMPING*deltaTime); - - // Update position - pos += vel*deltaTime; - - // Update the beads - const float BEAD_SPRING_FORCE = 500.0; - const float BEAD_NEIGHBOR_FORCE = 200.0; - const float HARD_SPHERE_FORCE = 2500.0; - const float PRESSURE_FACTOR = 0.00; - float separation, contact; - float newPressure = 0; - int n1, n2; - float d1, d2; - - for (int i = 0; i < NUM_BEADS; i++) { - distance = glm::distance(beads[i].pos, pos + beads[i].target * (1.f + pressure*PRESSURE_FACTOR)); - if (distance > 0.1) { - beads[i].vel += glm::normalize((pos + (beads[i].target*(1.f + pressure*PRESSURE_FACTOR))) - beads[i].pos)*deltaTime*BEAD_SPRING_FORCE*distance; - } - // Add forces from 2 neighboring beads - if ((i-1)>=0) n1 = i - 1; - else n1 = NUM_PUCKS - 1; - if ((i+1) 0.01) beads[i].vel += glm::normalize(beads[n1].pos - beads[i].pos)*deltaTime*BEAD_NEIGHBOR_FORCE*distance; - d2 = glm::distance(beads[i].pos, beads[n2].pos); - if (d2 > 0.01) beads[i].vel += glm::normalize(beads[n2].pos - beads[i].pos)*deltaTime*BEAD_NEIGHBOR_FORCE*distance; - - - // Look for hard collision with pucks - for (int j = 0; j < NUM_PUCKS; j++) { - - separation = glm::distance(beads[i].pos, pucks[j].pos); - contact = 2.5f + pucks[j].radius; - - // Hard Sphere Scattering - - if (separation < contact) { - beads[i].vel += glm::normalize(beads[i].pos - pucks[j].pos)* - deltaTime*HARD_SPHERE_FORCE*(contact - separation); - pucks[j].vel -= glm::normalize(beads[i].pos - pucks[j].pos)* - deltaTime*HARD_SPHERE_FORCE*(contact - separation)/pucks[j].mass; - if (beads[i].brightness < 0.5) beads[i].brightness = 0.5; - beads[i].brightness *= 1.1f; - } else { - beads[i].brightness *= 0.95f; - } - beads[i].brightness = fminf(beads[i].brightness, 1.f); - } - - - // Decay velocity, move beads - beads[i].vel *= 0.85; - beads[i].pos += beads[i].vel*deltaTime; - - // Measure pressure for next run - newPressure += glm::distance(beads[i].pos, pos); - } - if (fabs(newPressure - NUM_BEADS*RADIUS) < 100.f) pressure = newPressure - (NUM_BEADS*RADIUS); - - // Update the pucks for any pressure they have received - for (int j = 0; j < NUM_PUCKS; j++) { - pucks[j].vel *= 0.99; - - if (pucks[j].radius < 25.0) pucks[j].pos += pucks[j].vel*deltaTime; - - // wrap at edges - if (pucks[j].pos.x > width) pucks[j].pos.x = 0.0; - if (pucks[j].pos.x < 0) pucks[j].pos.x = static_cast(width); - if (pucks[j].pos.y > height) pucks[j].pos.y = 0.0; - if (pucks[j].pos.y < 0) pucks[j].pos.y = static_cast(height); - } - - } -} diff --git a/interface/src/Finger.h b/interface/src/Finger.h deleted file mode 100644 index 694eec9e33..0000000000 --- a/interface/src/Finger.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// Finger.h -// interface -// -// Created by Philip on 1/21/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __interface__Finger__ -#define __interface__Finger__ - -#include -#include "Util.h" -#include "world.h" -#include "InterfaceConfig.h" - -#include - -class Finger { -public: - Finger(int w, int h); - void simulate(float deltaTime); - void render(); - void setTarget(int x, int y); -private: - int width, height; // Screen size in pixels - bool start; - glm::vec2 pos, vel; // Position and velocity of finger - float m; // Velocity of finger - float pressure; // Internal pressure of skin vessel as function of measured volume - glm::vec2 target; // Where the mouse is - // little beads used to render the dynamic skin surface - struct bead { - glm::vec2 target, pos, vel; - float color[3]; - float brightness; - } *beads; - struct puck { - glm::vec2 pos, vel; - float brightness; - float radius; - float mass; - } *pucks; -}; - -#endif /* defined(__interface__finger__) */ - diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index cdfd19483c..2b457d8099 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -15,6 +15,8 @@ #include #include #include "Head.h" +#include +#include using namespace std; @@ -42,9 +44,8 @@ unsigned int iris_texture_height = 256; -//--------------------------------------------------- -Head::Head() -{ + +Head::Head() { initializeAvatar(); //position = glm::vec3(0,0,0); @@ -86,9 +87,12 @@ Head::Head() noise = 0; handBeingMoved = false; + previousHandBeingMoved = false; movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - - sphere = NULL; + + sphere = NULL; + + usingSprings = false; springForce = 6.0f; springToBodyTightness = 4.0f; @@ -103,14 +107,27 @@ Head::Head() std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; } } + + for (int o=0; o::iterator agent = agentList->getAgents().begin(); + agent != agentList->getAgents().end(); + agent++) { + if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_INTERFACE ) )) { + Head *agentHead = (Head *)agent->getLinkedData(); + + // when this is working, I will grab the position here... + //glm::vec3 pos = agentHead->getPos(); + + } + } + */ + + for (int o=0; o 0.0f ) - { + if ( length > 0.0f ) { glm::vec3 springDirection = springVector / length; float force = ( length - avatar.bone[b].length ) * springForce * deltaTime; @@ -898,32 +970,22 @@ void Head::updateAvatarSprings( float deltaTime ) float decay = 1.0 - springVelocityDecay * deltaTime; - if ( decay > 0.0 ) - { + if ( decay > 0.0 ) { avatar.bone[b].springyVelocity *= decay; } - else - { + else { avatar.bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f ); } - avatar.bone[b].springyPosition += avatar.bone[b].springyVelocity; } } - - -//---------------------- -float Head::getBodyYaw() -{ +float Head::getBodyYaw() { return avatar.yaw; } - -//-------------------------------------- -glm::vec3 Head::getHeadLookatDirection() -{ +glm::vec3 Head::getHeadLookatDirection() { return glm::vec3 ( avatar.orientation.getFront().x, @@ -932,9 +994,7 @@ glm::vec3 Head::getHeadLookatDirection() ); } -//------------------------------------------- -glm::vec3 Head::getHeadLookatDirectionUp() -{ +glm::vec3 Head::getHeadLookatDirectionUp() { return glm::vec3 ( avatar.orientation.getUp().x, @@ -943,9 +1003,7 @@ glm::vec3 Head::getHeadLookatDirectionUp() ); } -//------------------------------------------- -glm::vec3 Head::getHeadLookatDirectionRight() -{ +glm::vec3 Head::getHeadLookatDirectionRight() { return glm::vec3 ( avatar.orientation.getRight().x, @@ -954,10 +1012,7 @@ glm::vec3 Head::getHeadLookatDirectionRight() ); } - -//------------------------------- -glm::vec3 Head::getHeadPosition() -{ +glm::vec3 Head::getHeadPosition() { return glm::vec3 ( avatar.bone[ AVATAR_BONE_HEAD ].position.x, @@ -967,10 +1022,7 @@ glm::vec3 Head::getHeadPosition() } - -//------------------------------- -glm::vec3 Head::getBodyPosition() -{ +glm::vec3 Head::getBodyPosition() { return glm::vec3 ( avatar.bone[ AVATAR_BONE_PELVIS_SPINE ].position.x, @@ -980,27 +1032,31 @@ glm::vec3 Head::getBodyPosition() } - -//----------------------------- -void Head::updateHandMovement() -{ +void Head::updateHandMovement() { glm::vec3 transformedHandMovement; + + + transformedHandMovement.x = -glm::dot( movedHandOffset, avatar.orientation.getRight () ); + transformedHandMovement.y = -glm::dot( movedHandOffset, avatar.orientation.getUp () ); + transformedHandMovement.z = -glm::dot( movedHandOffset, avatar.orientation.getFront () ); - transformedHandMovement.x - = glm::dot( movedHandOffset.x, -(float)avatar.orientation.getRight().x ) - + glm::dot( movedHandOffset.y, -(float)avatar.orientation.getRight().y ) - + glm::dot( movedHandOffset.z, -(float)avatar.orientation.getRight().z ); - - transformedHandMovement.y - = glm::dot( movedHandOffset.x, -(float)avatar.orientation.getUp().x ) - + glm::dot( movedHandOffset.y, -(float)avatar.orientation.getUp().y ) - + glm::dot( movedHandOffset.z, -(float)avatar.orientation.getUp().z ); - - transformedHandMovement.z - = glm::dot( movedHandOffset.x, -(float)avatar.orientation.getFront().x ) - + glm::dot( movedHandOffset.y, -(float)avatar.orientation.getFront().y ) - + glm::dot( movedHandOffset.z, -(float)avatar.orientation.getFront().z ); - + + //transformedHandMovement = glm::vec3( 0.0f, 0.0f, 0.0f ); + + + //if holding hands, add a pull to the hand... + if ( usingSprings ) { + if ( closestOtherAvatar != -1 ) { + glm::vec3 handShakePull( DEBUG_otherAvatarListPosition[ closestOtherAvatar ]); + handShakePull -= avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position; + + handShakePull *= 0.3; + + transformedHandMovement += handShakePull; + } + } + + avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; glm::vec3 armVector = avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position; armVector -= avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; @@ -1013,8 +1069,7 @@ void Head::updateHandMovement() //------------------------------------------------------------------------------- // if right hand is being dragged beyond maximum arm length... //------------------------------------------------------------------------------- - if ( distance > avatar.maxArmLength ) - { + if ( distance > avatar.maxArmLength ) { //------------------------------------------------------------------------------- // reset right hand to be constrained to maximum arm length //------------------------------------------------------------------------------- @@ -1048,110 +1103,64 @@ void Head::updateHandMovement() - -//----------------------------------------- void Head::renderBody() { //----------------------------------------- // Render bone positions as spheres //----------------------------------------- - for (int b=0; bgetPos().x, hand->getPos().y, hand->getPos().z); //previous to Ventrella change @@ -1161,15 +1170,14 @@ int Head::getBroadcastData(char* data) return strlen(data); } -//called on the other agents - assigns it to my views of the others -//--------------------------------------------------- -void Head::parseData(void *data, int size) -{ +//called on the other agents - assigns it to my views of the others +void Head::parseData(void *data, int size) { sscanf ( (char *)data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &Pitch, &Yaw, &Roll, + //&avatar.yaw, &avatar.pitch, &avatar.roll, &position.x, &position.y, &position.z, &loudness, &averageLoudness, &avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.x, @@ -1183,9 +1191,7 @@ void Head::parseData(void *data, int size) -//--------------------------------------------------- -void Head::SetNewHeadTarget(float pitch, float yaw) -{ +void Head::SetNewHeadTarget(float pitch, float yaw) { PitchTarget = pitch; YawTarget = yaw; } diff --git a/interface/src/Head.h b/interface/src/Head.h index 3268383439..7c9f4b91aa 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -30,6 +30,8 @@ enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define ROT_RIGHT 7 #define MAX_DRIVE_KEYS 8 +#define NUM_OTHER_AVATARS 5 + /* enum AvatarJoints { @@ -237,7 +239,15 @@ class Head : public AgentData { //glm::vec3 velocity; //glm::vec3 thrust; + float closeEnoughToInteract; + int closestOtherAvatar; + glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ]; + float DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ]; + + bool usingSprings; + bool handBeingMoved; + bool previousHandBeingMoved; glm::vec3 movedHandOffset; //glm::vec3 movedHandPosition; @@ -255,6 +265,7 @@ class Head : public AgentData { void initializeAvatar(); void updateAvatarSkeleton(); + void initializeAvatarSprings(); void updateAvatarSprings( float deltaTime ); void calculateBoneLengths(); diff --git a/interface/src/Lattice.cpp b/interface/src/Lattice.cpp deleted file mode 100644 index 10a11b8763..0000000000 --- a/interface/src/Lattice.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// -// Lattice.cpp -// interface -// -// Created by Philip on 1/19/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#include "Lattice.h" - -Lattice::Lattice(int w, int h) { - width = w; - height = h; - tilegap = 2; - lastindex = -1; - tiles = new Tile[width*height]; - for (int i = 0; i < (width*height); i++) { - tiles[i].color[0] = tiles[i].color[1] = tiles[i].color[2] = 0.2f + randFloat()*0.3f; - tiles[i].x = static_cast(i % width); - tiles[i].y = static_cast(i/width); - tiles[i].brightness = 1.0; - tiles[i].type = 0; - tiles[i].excited = tiles[i].inhibited = 0.0; - } -} - -void Lattice::render(int screenWidth, int screenHeight) { - float tilewidth = static_cast(screenWidth/width); - float tileheight = static_cast(screenHeight/height); - float tilecolor[3]; - glBegin(GL_QUADS); - for (int i = 0; i < (width*height); i++) { - if (tiles[i].type == 0) { - tilecolor[0] = 0.25; tilecolor[1] = 0.25; tilecolor[2] = 0.25; - } else if (tiles[i].type == 1) { - if (tiles[i].inhibited >= 0.1) { - tilecolor[0] = 0.5f; tilecolor[1] = 0.0; tilecolor[2] = 0.0; - } else { - tilecolor[0] = 0.2f; tilecolor[1] = 0.0; tilecolor[2] = 0.5f; - } - } - glColor3f(tilecolor[0]*(1.f+tiles[i].excited), tilecolor[1]*(1.f+tiles[i].excited), tilecolor[2]*(1.f+tiles[i].excited)); - glVertex2f(tiles[i].x*tilewidth, tiles[i].y*tileheight); - glVertex2f((tiles[i].x + 1)*tilewidth - tilegap, tiles[i].y*tileheight); - glVertex2f((tiles[i].x + 1)*tilewidth - tilegap, (tiles[i].y + 1)*tileheight - tilegap); - glVertex2f(tiles[i].x*tilewidth, (tiles[i].y + 1)*tileheight - tilegap); - } - glEnd(); -} - -void Lattice::mouseClick(float x, float y) { - // Update lattice based on mouse location, where x and y are floats between 0 and 1 corresponding to screen location clicked - // Change the clicked cell to a different type - //printf("X = %3.1f Y = %3.1f\n", x, y); - int index = int(x*(float)width) + int(y*(float)height)*width; - if (index != lastindex) { - tiles[index].type++; - if (tiles[index].type == 2) tiles[index].type = 0; - lastindex = index; - } -} - -void Lattice::mouseOver(float x, float y) { - // Update lattice based on mouse location, where x and y are floats between 0 and 1 corresponding to screen location clicked - // Excite the hovered cell a bit toward firing - //printf("X = %3.1f Y = %3.1f\n", x, y); - if (0) { - int index = int(x*(float)width) + int(y*(float)height)*width; - if (tiles[index].type > 0) tiles[index].excited += 0.05f; - //printf("excited = %3.1f, inhibited = %3.1f\n", tiles[index].excited, tiles[index].inhibited); - } -} - -void Lattice::simulate(float deltaTime) { - int index; - for (int i = 0; i < (width*height); i++) { - if (tiles[i].type > 0) { - if ((tiles[i].excited > 0.5) && (tiles[i].inhibited < 0.1)) { - tiles[i].excited = 1.0; - tiles[i].inhibited = 1.0; - // Add Energy to neighbors - for (int j = 0; j < 8; j++) { - if (j == 0) index = i - width - 1; - else if (j == 1) index = i - width; - else if (j == 2) index = i - width + 1; - else if (j == 3) index = i - 1; - else if (j == 4) index = i + 1; - else if (j == 5) index = i + width - 1; - else if (j == 6) index = i + width; - else index = i + width + 1; - if ((index > 0) && (index < width*height)) { - if (tiles[index].inhibited < 0.1) tiles[index].excited += 0.5; - } - - } - } - tiles[i].excited *= 0.98f; - tiles[i].inhibited *= 0.98f; - } - } -} - - - - - diff --git a/interface/src/Lattice.h b/interface/src/Lattice.h deleted file mode 100644 index 82d56cc7ae..0000000000 --- a/interface/src/Lattice.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Lattice.h -// interface -// -// Created by Philip on 1/19/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __interface__Lattice__ -#define __interface__Lattice__ - -#include -#include "Util.h" -#include "world.h" -#include "InterfaceConfig.h" -#include - -class Lattice { -public: - Lattice(int width, int height); - void simulate(float deltaTime); - void render(int screenWidth, int screenHeight); - void mouseClick(float x, float y); - void mouseOver(float x, float y); -private: - int lastindex; - int width, height; - int tilegap; - struct Tile { - float x,y; - float color[3]; - float brightness; - float excited; - float inhibited; - int type; - } *tiles; -}; - -#endif /* defined(__interface__lattice__) */ diff --git a/interface/src/Orientation.cpp b/interface/src/Orientation.cpp index 7c37951359..439538ce8a 100755 --- a/interface/src/Orientation.cpp +++ b/interface/src/Orientation.cpp @@ -1,33 +1,28 @@ #include "Orientation.h" #include "Util.h" -//------------------------ -Orientation::Orientation() -{ +Orientation::Orientation() { right = glm::vec3( 1.0, 0.0, 0.0 ); up = glm::vec3( 0.0, 1.0, 0.0 ); front = glm::vec3( 0.0, 0.0, 1.0 ); } -//------------------------------- -void Orientation::setToIdentity() -{ + +void Orientation::setToIdentity() { right = glm::vec3( 1.0, 0.0, 0.0 ); up = glm::vec3( 0.0, 1.0, 0.0 ); front = glm::vec3( 0.0, 0.0, 1.0 ); } -//------------------------------------ -void Orientation::set( Orientation o ) -{ + +void Orientation::set( Orientation o ) { right = o.getRight(); up = o.getUp(); front = o.getFront(); } -//--------------------------------------- -void Orientation::yaw( float angle ) -{ + +void Orientation::yaw( float angle ) { float r = angle * PI_OVER_180; float s = sin( r ); float c = cos( r ); @@ -41,9 +36,8 @@ void Orientation::yaw( float angle ) right = cosineRight - sineFront; } -//--------------------------------------- -void Orientation::pitch( float angle ) -{ + +void Orientation::pitch( float angle ) { float r = angle * PI_OVER_180; float s = sin( r ); float c = cos( r ); @@ -57,9 +51,8 @@ void Orientation::pitch( float angle ) front = cosineFront - sineUp; } -//--------------------------------------- -void Orientation::roll( float angle ) -{ + +void Orientation::roll( float angle ) { double r = angle * PI_OVER_180; double s = sin( r ); double c = cos( r ); @@ -73,9 +66,8 @@ void Orientation::roll( float angle ) right = cosineRight - sineUp; } -//--------------------------------------------------------------------------------------------- -void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) -{ + +void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) { right = r; up = u; front = f; diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index fdd207ce48..3d58c6faa5 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -80,6 +80,23 @@ void render_world_box() glVertex3f(0,0,0); glVertex3f(0, 0, WORLD_SIZE); glEnd(); + // Draw little marker dots along the axis + glEnable(GL_LIGHTING); + glPushMatrix(); + glTranslatef(WORLD_SIZE,0,0); + glColor3f(1,0,0); + glutSolidSphere(0.125,10,10); + glPopMatrix(); + glPushMatrix(); + glTranslatef(0,WORLD_SIZE,0); + glColor3f(0,1,0); + glutSolidSphere(0.125,10,10); + glPopMatrix(); + glPushMatrix(); + glTranslatef(0,0,WORLD_SIZE); + glColor3f(0,0,1); + glutSolidSphere(0.125,10,10); + glPopMatrix(); } double diffclock(timeval *clock1,timeval *clock2) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index a5c23a2d78..99beac33ae 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -69,8 +69,6 @@ #include #include #include "VoxelSystem.h" -#include "Lattice.h" -#include "Finger.h" #include "Oscilloscope.h" #include "UDPSocket.h" #include "SerialInterface.h" @@ -80,7 +78,6 @@ using namespace std; -AgentList agentList(AGENT_TYPE_INTERFACE); pthread_t networkReceiveThread; bool stopNetworkReceiveThread = false; @@ -129,9 +126,6 @@ Cloud cloud(0, // Particles ); VoxelSystem voxels; - -Lattice lattice(160,100); -Finger myFinger(WIDTH, HEIGHT); Field field; #ifndef _WIN32 @@ -188,7 +182,6 @@ int menuOn = 1; // Whether to show onscreen menu // SerialInterface serialPort; -int latency_display = 1; glm::vec3 gravity; @@ -199,6 +192,9 @@ float FPS = 120.f; timeval timerStart, timerEnd; timeval lastTimeIdle; double elapsedTime; +timeval applicationStartupTime; +bool justStarted = true; + // Every second, check the frame rates and other stuff void Timer(int extra) @@ -236,7 +232,7 @@ void displayStats(void) glm::vec3 avatarPos = myAvatar.getPos(); char stats[200]; - sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)=( %f , %f , %f )", + sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)= %4.2f, %4.2f, %4.2f ", FPS, packetsPerSecond, bytesPerSecond, avatarPos.x,avatarPos.y,avatarPos.z); drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); if (serialPort.active) { @@ -321,6 +317,7 @@ void init(void) } myAvatar.setPos(start_location ); myCamera.setPosition( start_location ); + #ifdef MARKER_CAPTURE if(marker_capture_enabled){ @@ -465,7 +462,7 @@ void simulateHead(float frametime) int broadcastBytes = myAvatar.getBroadcastData(broadcastString); const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER}; - agentList.broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2); + AgentList::getInstance()->broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2); // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) { @@ -485,7 +482,7 @@ void simulateHead(float frametime) ::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) { if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &::paintingVoxel, bufferOut, sizeOut)){ - agentList.broadcastToAgents((char*)bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents((char*)bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); delete bufferOut; } } @@ -804,7 +801,7 @@ void display(void) float sphereRadius = 0.25f; glColor3f(1,0,0); glPushMatrix(); - glTranslatef( 0.0f, sphereRadius, 0.0f ); + //glTranslatef( 0.0f, sphereRadius, 0.0f ); glutSolidSphere( sphereRadius, 15, 15 ); glPopMatrix(); @@ -827,10 +824,11 @@ void display(void) if (displayField) field.render(); // Render avatars of other agents - for(std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) - { - if (agent->getLinkedData() != NULL) - { + AgentList *agentList = AgentList::getInstance(); + for(std::vector::iterator agent = agentList->getAgents().begin(); + agent != agentList->getAgents().end(); + agent++) { + if (agent->getLinkedData() != NULL) { Head *agentHead = (Head *)agent->getLinkedData(); glPushMatrix(); glm::vec3 pos = agentHead->getPos(); @@ -862,16 +860,13 @@ void display(void) gluOrtho2D(0, WIDTH, HEIGHT, 0); glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); - - //lattice.render(WIDTH, HEIGHT); - //myFinger.render(); + #ifndef _WIN32 audio.render(WIDTH, HEIGHT); if (audioScope.getState()) audioScope.render(); #endif - if (displayHeadMouse && !displayHead && statsOn) - { + if (displayHeadMouse && !displayHead && statsOn) { // Display small target box at center or head mouse target that can also be used to measure LOD glColor3f(1.0, 1.0, 1.0); glDisable(GL_LINE_SMOOTH); @@ -906,7 +901,7 @@ void display(void) // Draw number of nearby people always glPointSize(1.0f); char agents[100]; - sprintf(agents, "Agents: %ld\n", agentList.getAgents().size()); + sprintf(agents, "Agents: %ld\n", AgentList::getInstance()->getAgents().size()); drawtext(WIDTH-100,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); if (::paintOn) { @@ -923,6 +918,13 @@ void display(void) glutSwapBuffers(); frameCount++; + + // If application has just started, report time from startup to now (first frame display) + if (justStarted) { + printf("Startup Time: %4.2f\n", + (usecTimestampNow() - usecTimestamp(&applicationStartupTime))/1000000.0); + justStarted = false; + } } int setValue(int state, int *value) { @@ -1007,14 +1009,14 @@ void sendVoxelServerEraseAll() { char message[100]; sprintf(message,"%c%s",'Z',"erase all"); int messageSize = strlen(message) + 1; - ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1); } void sendVoxelServerAddScene() { char message[100]; sprintf(message,"%c%s",'Z',"add scene"); int messageSize = strlen(message) + 1; - ::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1); + AgentList::getInstance()->broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1); } void shiftPaintingColor() @@ -1026,8 +1028,7 @@ void shiftPaintingColor() ::paintingVoxel.blue = (::dominantColor==2)?randIntInRange(200,255):randIntInRange(40,100); } -void setupPaintingVoxel() -{ +void setupPaintingVoxel() { glm::vec3 avatarPos = myAvatar.getPos(); ::paintingVoxel.x = avatarPos.z/-10.0; // voxel space x is negative z head space @@ -1198,7 +1199,7 @@ void *networkReceive(void *args) char *incomingPacket = new char[MAX_PACKET_SIZE]; while (!stopNetworkReceiveThread) { - if (agentList.getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { + if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { packetCount++; bytesCount += bytesReceived; @@ -1212,10 +1213,10 @@ void *networkReceive(void *args) voxels.parseData(incomingPacket, bytesReceived); break; case PACKET_HEADER_BULK_AVATAR_DATA: - agentList.processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, sizeof(float) * 11); + AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, sizeof(float) * 11); break; default: - agentList.processAgentData(&senderAddress, incomingPacket, bytesReceived); + AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); break; } } @@ -1272,8 +1273,6 @@ void idle(void) myAvatar.simulate(1.f/FPS); balls.simulate(1.f/FPS); cloud.simulate(1.f/FPS); - lattice.simulate(1.f/FPS); - myFinger.simulate(1.f/FPS); glutPostRedisplay(); lastTimeIdle = check; @@ -1316,7 +1315,6 @@ void mouseFunc( int button, int state, int x, int y ) mouseX = x; mouseY = y; mousePressed = 1; - lattice.mouseClick((float)x/(float)WIDTH, (float)y/(float)HEIGHT); mouseStartX = x; mouseStartY = y; } @@ -1333,8 +1331,6 @@ void motionFunc( int x, int y) { mouseX = x; mouseY = y; - - lattice.mouseClick((float)x/(float)WIDTH,(float)y/(float)HEIGHT); } void mouseoverFunc( int x, int y) @@ -1343,10 +1339,7 @@ void mouseoverFunc( int x, int y) mouseX = x; mouseY = y; if (mousePressed == 0) - { -// lattice.mouseOver((float)x/(float)WIDTH,(float)y/(float)HEIGHT); -// myFinger.setTarget(mouseX, mouseY); - } + {} } void attachNewHeadToAgent(Agent *newAgent) { @@ -1361,10 +1354,11 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) { } #endif - - int main(int argc, const char * argv[]) { + AgentList::createInstance(AGENT_TYPE_INTERFACE); + + gettimeofday(&applicationStartupTime, NULL); const char* domainIP = getCmdOption(argc, argv, "--domain"); if (domainIP) { strcpy(DOMAIN_IP,domainIP); @@ -1376,12 +1370,12 @@ int main(int argc, const char * argv[]) int ip = getLocalAddress(); sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); } - + // the callback for our instance of AgentList is attachNewHeadToAgent - agentList.linkedDataCreateCallback = &attachNewHeadToAgent; + AgentList::getInstance()->linkedDataCreateCallback = &attachNewHeadToAgent; #ifndef _WIN32 - agentList.audioMixerSocketUpdate = &audioMixerUpdate; + AgentList::getInstance()->audioMixerSocketUpdate = &audioMixerUpdate; #endif #ifdef _WIN32 @@ -1390,9 +1384,9 @@ int main(int argc, const char * argv[]) #endif // start the agentList threads - agentList.startSilentAgentRemovalThread(); - agentList.startDomainServerCheckInThread(); - agentList.startPingUnknownAgentsThread(); + AgentList::getInstance()->startSilentAgentRemovalThread(); + AgentList::getInstance()->startDomainServerCheckInThread(); + AgentList::getInstance()->startPingUnknownAgentsThread(); glutInit(&argc, (char**)argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); diff --git a/mixer/src/main.cpp b/mixer/src/main.cpp index ed455166d8..9f77bbc9bb 100644 --- a/mixer/src/main.cpp +++ b/mixer/src/main.cpp @@ -61,7 +61,6 @@ const int AGENT_LOOPBACK_MODIFIER = 307; const int LOOPBACK_SANITY_CHECK = 0; -AgentList agentList(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); StDev stdev; void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) { @@ -79,13 +78,15 @@ void *sendBuffer(void *args) int nextFrame = 0; timeval startTime; + AgentList *agentList = AgentList::getInstance(); + gettimeofday(&startTime, NULL); while (true) { sentBytes = 0; - for (int i = 0; i < agentList.getAgents().size(); i++) { - AudioRingBuffer *agentBuffer = (AudioRingBuffer *) agentList.getAgents()[i].getLinkedData(); + for (int i = 0; i < agentList->getAgents().size(); i++) { + AudioRingBuffer *agentBuffer = (AudioRingBuffer *) agentList->getAgents()[i].getLinkedData(); if (agentBuffer != NULL && agentBuffer->getEndOfLastWrite() != NULL) { @@ -103,12 +104,12 @@ void *sendBuffer(void *args) } } - int numAgents = agentList.getAgents().size(); + int numAgents = agentList->getAgents().size(); float distanceCoeffs[numAgents][numAgents]; memset(distanceCoeffs, 0, sizeof(distanceCoeffs)); - for (int i = 0; i < agentList.getAgents().size(); i++) { - Agent *agent = &agentList.getAgents()[i]; + for (int i = 0; i < agentList->getAgents().size(); i++) { + Agent *agent = &agentList->getAgents()[i]; AudioRingBuffer *agentRingBuffer = (AudioRingBuffer *) agent->getLinkedData(); float agentBearing = agentRingBuffer->getBearing(); @@ -119,15 +120,17 @@ void *sendBuffer(void *args) agentWantsLoopback = true; // correct the bearing - agentBearing = agentBearing > 0 ? agentBearing - AGENT_LOOPBACK_MODIFIER : agentBearing + AGENT_LOOPBACK_MODIFIER; + agentBearing = agentBearing > 0 + ? agentBearing - AGENT_LOOPBACK_MODIFIER + : agentBearing + AGENT_LOOPBACK_MODIFIER; } int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; - for (int j = 0; j < agentList.getAgents().size(); j++) { + for (int j = 0; j < agentList->getAgents().size(); j++) { if (i != j || ( i == j && agentWantsLoopback)) { - AudioRingBuffer *otherAgentBuffer = (AudioRingBuffer *)agentList.getAgents()[j].getLinkedData(); + AudioRingBuffer *otherAgentBuffer = (AudioRingBuffer *)agentList->getAgents()[j].getLinkedData(); float *agentPosition = agentRingBuffer->getPosition(); float *otherAgentPosition = otherAgentBuffer->getPosition(); @@ -143,12 +146,15 @@ void *sendBuffer(void *args) powf(agentPosition[1] - otherAgentPosition[1], 2) + powf(agentPosition[2] - otherAgentPosition[2], 2)); - distanceCoeffs[lowAgentIndex][highAgentIndex] = std::min(1.0f, powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + float minCoefficient = std::min(1.0f, + powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + distanceCoeffs[lowAgentIndex][highAgentIndex] = minCoefficient; } // get the angle from the right-angle triangle - float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI); + float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), + fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI); float angleToSource; @@ -214,11 +220,11 @@ void *sendBuffer(void *args) } } - agentList.getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); + agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); } - for (int i = 0; i < agentList.getAgents().size(); i++) { - AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList.getAgents()[i].getLinkedData(); + for (int i = 0; i < agentList->getAgents().size(); i++) { + AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList->getAgents()[i].getLinkedData(); if (agentBuffer->wasAddedToMix()) { agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL); @@ -250,14 +256,15 @@ void attachNewBufferToAgent(Agent *newAgent) { int main(int argc, const char * argv[]) { + AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); ssize_t receivedBytes = 0; - agentList.linkedDataCreateCallback = attachNewBufferToAgent; + agentList->linkedDataCreateCallback = attachNewBufferToAgent; - agentList.startSilentAgentRemovalThread(); - agentList.startDomainServerCheckInThread(); + agentList->startSilentAgentRemovalThread(); + agentList->startDomainServerCheckInThread(); unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; @@ -276,7 +283,7 @@ int main(int argc, const char * argv[]) bool firstSample = true; while (true) { - if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + if(agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) { // Compute and report standard deviation for jitter calculation @@ -298,14 +305,14 @@ int main(int argc, const char * argv[]) // add or update the existing interface agent if (!LOOPBACK_SANITY_CHECK) { - if (agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList.getLastAgentId())) { - agentList.increaseAgentId(); + if (agentList->addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList->getLastAgentId())) { + agentList->increaseAgentId(); } - agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); + agentList->updateAgentWithData(agentAddress, (void *)packetData, receivedBytes); } else { memcpy(loopbackAudioPacket, packetData + 1 + (sizeof(float) * 4), 1024); - agentList.getAgentSocket().send(agentAddress, loopbackAudioPacket, 1024); + agentList->getAgentSocket().send(agentAddress, loopbackAudioPacket, 1024); } } } diff --git a/shared/src/AgentList.cpp b/shared/src/AgentList.cpp index b2cc6a3ae2..f973b3de1d 100644 --- a/shared/src/AgentList.cpp +++ b/shared/src/AgentList.cpp @@ -31,16 +31,27 @@ bool domainServerCheckinStopFlag = false; bool pingUnknownAgentThreadStopFlag = false; pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER; -int unpackAgentId(unsigned char *packedData, uint16_t *agentId) { - memcpy(packedData, agentId, sizeof(uint16_t)); - return sizeof(uint16_t); +AgentList* AgentList::_sharedInstance = NULL; + +AgentList* AgentList::createInstance(char ownerType, unsigned int socketListenPort) { + if (_sharedInstance == NULL) { + _sharedInstance = new AgentList(ownerType, socketListenPort); + } else { + printf("AgentList createInstance called with existing instance.\n"); + } + + return _sharedInstance; } -int packAgentId(unsigned char *packStore, uint16_t agentId) { - memcpy(&agentId, packStore, sizeof(uint16_t)); - return sizeof(uint16_t); +AgentList* AgentList::getInstance() { + if (_sharedInstance == NULL) { + printf("AgentList getInstance called before call to createInstance. Returning NULL pointer.\n"); + } + + return _sharedInstance; } + AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : agentSocket(newSocketListenPort) { ownerType = newOwnerType; socketListenPort = newSocketListenPort; @@ -379,7 +390,7 @@ void *checkInWithDomainServer(void *args) { sockaddr_in tempAddress; memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr)); - printf("Domain server %s: \n", DOMAIN_HOSTNAME); + printf("Domain server: %s \n", DOMAIN_HOSTNAME); } else { printf("Failed lookup domainserver\n"); @@ -414,3 +425,13 @@ void AgentList::stopDomainServerCheckInThread() { domainServerCheckinStopFlag = true; pthread_join(checkInWithDomainServerThread, NULL); } + +int unpackAgentId(unsigned char *packedData, uint16_t *agentId) { + memcpy(packedData, agentId, sizeof(uint16_t)); + return sizeof(uint16_t); +} + +int packAgentId(unsigned char *packStore, uint16_t agentId) { + memcpy(&agentId, packStore, sizeof(uint16_t)); + return sizeof(uint16_t); +} diff --git a/shared/src/AgentList.h b/shared/src/AgentList.h index ee61a35c8d..454d02ea1a 100644 --- a/shared/src/AgentList.h +++ b/shared/src/AgentList.h @@ -29,20 +29,9 @@ extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startu extern const int DOMAINSERVER_PORT; class AgentList { - - UDPSocket agentSocket; - char ownerType; - unsigned int socketListenPort; - std::vector agents; - uint16_t lastAgentId; - pthread_t removeSilentAgentsThread; - pthread_t checkInWithDomainServerThread; - pthread_t pingUnknownAgentsThread; - - void handlePingReply(sockaddr *agentAddress); public: - AgentList(char ownerType, unsigned int socketListenPort = AGENT_SOCKET_LISTEN_PORT); - ~AgentList(); + static AgentList* createInstance(char ownerType, unsigned int socketListenPort = AGENT_SOCKET_LISTEN_PORT); + static AgentList* getInstance(); void(*linkedDataCreateCallback)(Agent *); void(*audioMixerSocketUpdate)(in_addr_t, in_port_t); @@ -76,6 +65,24 @@ public: void stopDomainServerCheckInThread(); void startPingUnknownAgentsThread(); void stopPingUnknownAgentsThread(); +private: + static AgentList* _sharedInstance; + + AgentList(char ownerType, unsigned int socketListenPort); + ~AgentList(); + AgentList(AgentList const&); // Don't implement, needed to avoid copies of singleton + void operator=(AgentList const&); // Don't implement, needed to avoid copies of singleton + + UDPSocket agentSocket; + char ownerType; + unsigned int socketListenPort; + std::vector agents; + uint16_t lastAgentId; + pthread_t removeSilentAgentsThread; + pthread_t checkInWithDomainServerThread; + pthread_t pingUnknownAgentsThread; + + void handlePingReply(sockaddr *agentAddress); }; int unpackAgentId(unsigned char *packedData, uint16_t *agentId); diff --git a/voxel/src/main.cpp b/voxel/src/main.cpp index da86c189c3..c3ab221b01 100644 --- a/voxel/src/main.cpp +++ b/voxel/src/main.cpp @@ -46,7 +46,6 @@ const int PACKETS_PER_CLIENT_PER_INTERVAL = 2; const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; -AgentList agentList(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); VoxelTree randomTree; bool wantColorRandomizer = false; @@ -122,11 +121,11 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { ::randomTree.eraseAllVoxels(); // enumerate the agents clean up their marker nodes - for (int i = 0; i < agentList.getAgents().size(); i++) { + for (int i = 0; i < AgentList::getInstance()->getAgents().size(); i++) { //printf("eraseVoxelTreeAndCleanupAgentVisitData() agent[%d]\n",i); - - Agent *thisAgent = (Agent *)&::agentList.getAgents()[i]; + + Agent *thisAgent = (Agent *)&AgentList::getInstance()->getAgents()[i]; VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData()); // lock this agent's delete mutex so that the delete thread doesn't @@ -145,6 +144,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() { void *distributeVoxelsToListeners(void *args) { + AgentList *agentList = AgentList::getInstance(); timeval lastSendTime; unsigned char *stopOctal; @@ -161,9 +161,9 @@ void *distributeVoxelsToListeners(void *args) { gettimeofday(&lastSendTime, NULL); // enumerate the agents to send 3 packets to each - for (int i = 0; i < agentList.getAgents().size(); i++) { + for (int i = 0; i < agentList->getAgents().size(); i++) { - Agent *thisAgent = (Agent *)&agentList.getAgents()[i]; + Agent *thisAgent = (Agent *)&agentList->getAgents()[i]; VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData()); // lock this agent's delete mutex so that the delete thread doesn't @@ -184,7 +184,7 @@ void *distributeVoxelsToListeners(void *args) { treeRoot, stopOctal); - agentList.getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket); + agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket); packetCount++; totalBytesSent += voxelPacketEnd - voxelPacket; @@ -233,6 +233,7 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) { int main(int argc, const char * argv[]) { + AgentList *agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT); setvbuf(stdout, NULL, _IOLBF, 0); // Handle Local Domain testing with the --local command line @@ -244,9 +245,9 @@ int main(int argc, const char * argv[]) sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); } - agentList.linkedDataCreateCallback = &attachVoxelAgentDataToAgent; - agentList.startSilentAgentRemovalThread(); - agentList.startDomainServerCheckInThread(); + agentList->linkedDataCreateCallback = &attachVoxelAgentDataToAgent; + agentList->startSilentAgentRemovalThread(); + agentList->startDomainServerCheckInThread(); srand((unsigned)time(0)); @@ -294,7 +295,7 @@ int main(int argc, const char * argv[]) // loop to send to agents requesting data while (true) { - if (agentList.getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) { + if (agentList->getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) { // XXXBHG: Hacked in support for 'S' SET command if (packetData[0] == PACKET_HEADER_SET_VOXEL) { unsigned short int itemNumber = (*((unsigned short int*)&packetData[1])); @@ -345,7 +346,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_INTERFACE, 1); } if (packetData[0] == PACKET_HEADER_Z_COMMAND) { @@ -373,19 +374,19 @@ 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_INTERFACE, 1); } // If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_INTERFACE, and we // need to make sure we have it in our agentList. if (packetData[0] == PACKET_HEADER_HEAD_DATA) { - if (agentList.addOrUpdateAgent(&agentPublicAddress, + if (agentList->addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, AGENT_TYPE_INTERFACE, - agentList.getLastAgentId())) { - agentList.increaseAgentId(); + agentList->getLastAgentId())) { + agentList->increaseAgentId(); } - agentList.updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes); + agentList->updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes); } } }