Merge branch 'master' of https://github.com/worklist/hifi into voxel_lod_fixes

This commit is contained in:
ZappoMan 2013-04-11 18:42:12 -07:00
commit 85bef98f4a
15 changed files with 484 additions and 822 deletions

View file

@ -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<Agent>::iterator avatarAgent = agentList.getAgents().begin();
avatarAgent != agentList.getAgents().end();
for (std::vector<Agent>::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;
}

View file

@ -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<char, Agent *> 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<Agent>::iterator agent = agentList.getAgents().begin();
agent != agentList.getAgents().end();
for(std::vector<Agent>::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);
}

View file

@ -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<float>(x);
target.y = static_cast<float>(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)<NUM_PUCKS) n2 = i + 1;
else n2 = 0;
d1 = glm::distance(beads[i].pos, beads[n1].pos);
if (d1 > 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<float>(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<float>(height);
}
}
}

View file

@ -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 <glm/glm.hpp>
#include "Util.h"
#include "world.h"
#include "InterfaceConfig.h"
#include <iostream>
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__) */

View file

@ -15,6 +15,8 @@
#include <sstream>
#include <SharedUtil.h>
#include "Head.h"
#include <AgentList.h>
#include <AgentTypes.h>
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<NUM_OTHER_AVATARS; o++)
{
DEBUG_otherAvatarListTimer[o] = 0.0f;
DEBUG_otherAvatarListPosition[o] = glm::vec3( 0.0f, 0.0f, 0.0f );
}
//--------------------------------------------------
// test... just slam them into random positions...
//--------------------------------------------------
DEBUG_otherAvatarListPosition[ 0 ] = glm::vec3( 0.0, 0.1, 2.0 );
DEBUG_otherAvatarListPosition[ 1 ] = glm::vec3( 4.0, 0.1, 2.0 );
DEBUG_otherAvatarListPosition[ 2 ] = glm::vec3( 2.0, 0.1, 2.0 );
DEBUG_otherAvatarListPosition[ 3 ] = glm::vec3( 1.0, 0.1, -4.0 );
DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0, 0.1, -2.0 );
}
//---------------------------------------------------
Head::Head(const Head &otherHead)
{
Head::Head(const Head &otherHead) {
initializeAvatar();
position = otherHead.position;
@ -164,38 +181,22 @@ Head::Head(const Head &otherHead)
//---------------------------------------------------
Head::~Head()
{
if (sphere != NULL)
{
Head::~Head() {
if (sphere != NULL) {
gluDeleteQuadric(sphere);
}
}
//---------------------------------------------------
Head* Head::clone() const
{
Head* Head::clone() const {
return new Head(*this);
}
//---------------------------------------------------
void Head::reset()
{
void Head::reset() {
Pitch = Yaw = Roll = 0;
leanForward = leanSideways = 0;
}
//this pertains to moving the head with the glasses
//---------------------------------------------------
void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity)
@ -241,8 +242,6 @@ void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int hea
}
}
//---------------------------------------------------
void Head::addLean(float x, float z) {
// Add Body lean as impulse
leanSideways += x;
@ -250,79 +249,138 @@ void Head::addLean(float x, float z) {
}
//---------------------------------------------------
void Head::setLeanForward(float dist){
leanForward = dist;
}
//---------------------------------------------------
void Head::setLeanSideways(float dist){
leanSideways = dist;
}
void Head::simulate(float deltaTime) {
//-------------------------------------
// DEBUG - other avatars...
//-------------------------------------
closeEnoughToInteract = 0.5f;
closestOtherAvatar = -1;
float closestDistance = 10000.0f;
/*
AgentList * agentList = AgentList::getInstance();
for(std::vector<Agent>::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<NUM_OTHER_AVATARS; o++) {
/*
//-------------------------------------
// move the debug other avatars around...
//-------------------------------------
DEBUG_otherAvatarListTimer[o] += deltaTime;
float x = 6.0f * sin( DEBUG_otherAvatarListTimer[o] * 0.07 + o * 129.0 );
float z = 6.0f * sin( DEBUG_otherAvatarListTimer[o] * 0.10 + o * 12.0 );
float y = 0.0f;
*/
//-------------------------------------
// test other avs for proximity...
//-------------------------------------
glm::vec3 v( avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position );
v -= DEBUG_otherAvatarListPosition[o];
float distance = glm::length( v );
if ( distance < closeEnoughToInteract ) {
if ( distance < closestDistance ) {
closestDistance = distance;
closestOtherAvatar = o;
}
}
}
// Simulate the avatar over time
//---------------------------------------------------
void Head::simulate(float deltaTime)
{
//------------------------
// update avatar skeleton
//------------------------
updateAvatarSkeleton();
//------------------------------------------------------------------------
// update springy behavior:
// reset hand and elbow position according to hand movement
//------------------------------------------------------------------------
updateAvatarSprings( deltaTime );
if ( handBeingMoved ){
if (! previousHandBeingMoved ){
initializeAvatarSprings();
usingSprings = true;
//printf( "just started moving hand\n" );
}
}
else{
if ( previousHandBeingMoved ){
usingSprings = false;
//printf( "just stopped moving hand\n" );
}
}
if ( handBeingMoved ) {
updateHandMovement();
updateAvatarSprings( deltaTime );
}
previousHandBeingMoved = handBeingMoved;
handBeingMoved = false;
const float THRUST_MAG = 10.0;
const float YAW_MAG = 300.0;
avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 );
//notice that the z values from avatar.orientation are flipped to accommodate different coordinate system
if (driveKeys[FWD])
{
if (driveKeys[FWD]) {
glm::vec3 front( avatar.orientation.getFront().x, avatar.orientation.getFront().y, avatar.orientation.getFront().z );
avatar.thrust += front * THRUST_MAG;
}
if (driveKeys[BACK])
{
if (driveKeys[BACK]) {
glm::vec3 front( avatar.orientation.getFront().x, avatar.orientation.getFront().y, avatar.orientation.getFront().z );
avatar.thrust -= front * THRUST_MAG;
}
if (driveKeys[RIGHT])
{
if (driveKeys[RIGHT]) {
glm::vec3 right( avatar.orientation.getRight().x, avatar.orientation.getRight().y, avatar.orientation.getRight().z );
avatar.thrust -= right * THRUST_MAG;
}
if (driveKeys[LEFT])
{
if (driveKeys[LEFT]) {
glm::vec3 right( avatar.orientation.getRight().x, avatar.orientation.getRight().y, avatar.orientation.getRight().z );
avatar.thrust += right * THRUST_MAG;
}
if (driveKeys[UP])
{
if (driveKeys[UP]) {
glm::vec3 up( avatar.orientation.getUp().x, avatar.orientation.getUp().y, avatar.orientation.getUp().z );
avatar.thrust += up * THRUST_MAG;
}
if (driveKeys[DOWN])
{
if (driveKeys[DOWN]) {
glm::vec3 up( avatar.orientation.getUp().x, avatar.orientation.getUp().y, avatar.orientation.getUp().z );
avatar.thrust -= up * THRUST_MAG;
}
if (driveKeys[ROT_RIGHT])
{
if (driveKeys[ROT_RIGHT]) {
avatar.yawDelta -= YAW_MAG * deltaTime;
}
if (driveKeys[ROT_LEFT])
{
if (driveKeys[ROT_LEFT]) {
avatar.yawDelta += YAW_MAG * deltaTime;
}
@ -361,8 +419,7 @@ void Head::simulate(float deltaTime)
*/
if (!noise)
{
if (!noise) {
// Decay back toward center
Pitch *= (1.f - DECAY*2*deltaTime);
Yaw *= (1.f - DECAY*2*deltaTime);
@ -436,13 +493,11 @@ void Head::simulate(float deltaTime)
if (randFloat() < 0.01) EyeballYaw[0] = EyeballYaw[1] = (randFloat()- 0.5)*10;
}
if ((randFloat() < 0.005) && (fabs(PitchTarget - Pitch) < 1.0) && (fabs(YawTarget - Yaw) < 1.0))
{
if ((randFloat() < 0.005) && (fabs(PitchTarget - Pitch) < 1.0) && (fabs(YawTarget - Yaw) < 1.0)) {
SetNewHeadTarget((randFloat()-0.5)*20.0, (randFloat()-0.5)*45.0);
}
if (0)
{
if (0) {
// Pick new target
PitchTarget = (randFloat() - 0.5)*45;
@ -464,26 +519,61 @@ void Head::simulate(float deltaTime)
//---------------------------------------------------
void Head::render(int faceToFace, int isMine)
{
void Head::render(int faceToFace, int isMine) {
//---------------------------------------------------
// show avatar position
//---------------------------------------------------
glPushMatrix();
glTranslatef( position.x, position.y, position.z );
glScalef( 0.03, 0.03, 0.03 );
glutSolidSphere( 1, 10, 10 );
glPopMatrix();
//---------------------------------------------------
// show avatar orientation
//---------------------------------------------------
renderOrientationDirections(avatar.bone[ AVATAR_BONE_HEAD ].position, avatar.bone[ AVATAR_BONE_HEAD ].orientation, 0.2f );
//---------------------------------------------------
// render body
//---------------------------------------------------
renderBody();
//---------------------------------------------------
// render head
//---------------------------------------------------
renderHead( faceToFace, isMine );
//---------------------------------------------------
// render other avatars (DEBUG TEST)
//---------------------------------------------------
for (int o=0; o<NUM_OTHER_AVATARS; o++) {
glPushMatrix();
glTranslatef( DEBUG_otherAvatarListPosition[o].x, DEBUG_otherAvatarListPosition[o].y, DEBUG_otherAvatarListPosition[o].z );
glScalef( 0.03, 0.03, 0.03 );
glutSolidSphere( 1, 10, 10 );
glPopMatrix();
}
if ( usingSprings ) {
if ( closestOtherAvatar != -1 ) {
glm::vec3 v1( avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position );
glm::vec3 v2( DEBUG_otherAvatarListPosition[ closestOtherAvatar ] );
glLineWidth( 5.0 );
glColor4f( 0.9f, 0.5f, 0.2f, 0.6 );
glBegin( GL_LINE_STRIP );
glVertex3f( v1.x, v1.y, v1.z );
glVertex3f( v2.x, v2.y, v2.z );
glEnd();
}
}
}
//---------------------------------------------------
void Head::renderOrientationDirections( glm::vec3 position, Orientation orientation, float size )
{
void Head::renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) {
glm::vec3 pRight = position + orientation.getRight () * size;
glm::vec3 pUp = position + orientation.getUp () * size;
glm::vec3 pFront = position + orientation.getFront () * size;
@ -509,26 +599,33 @@ void Head::renderOrientationDirections( glm::vec3 position, Orientation orientat
//---------------------------------------------------
void Head::renderHead( int faceToFace, int isMine )
{
void Head::renderHead( int faceToFace, int isMine ) {
int side = 0;
// Always render own hand, but don't render head unless showing face2face
glEnable(GL_DEPTH_TEST);
glEnable(GL_RESCALE_NORMAL);
glPushMatrix();
//glScalef(scale, scale, scale);
glTranslatef
(
avatar.bone[ AVATAR_BONE_HEAD ].position.x,
avatar.bone[ AVATAR_BONE_HEAD ].position.y,
avatar.bone[ AVATAR_BONE_HEAD ].position.z
);
if ( usingSprings ) {
glTranslatef
(
avatar.bone[ AVATAR_BONE_HEAD ].springyPosition.x,
avatar.bone[ AVATAR_BONE_HEAD ].springyPosition.y,
avatar.bone[ AVATAR_BONE_HEAD ].springyPosition.z
);
}
else {
glTranslatef
(
avatar.bone[ AVATAR_BONE_HEAD ].position.x,
avatar.bone[ AVATAR_BONE_HEAD ].position.y,
avatar.bone[ AVATAR_BONE_HEAD ].position.z
);
}
glScalef( 0.03, 0.03, 0.03 );
@ -559,8 +656,7 @@ void Head::renderHead( int faceToFace, int isMine )
// Ears
glPushMatrix();
glTranslatef(1.0, 0, 0);
for(side = 0; side < 2; side++)
{
for(side = 0; side < 2; side++) {
glPushMatrix();
glScalef(0.3, 0.65, .65);
glutSolidSphere(0.5, 30, 30);
@ -581,8 +677,7 @@ void Head::renderHead( int faceToFace, int isMine )
glPushMatrix();
glTranslatef(-interBrowDistance/2.0,0.4,0.45);
for(side = 0; side < 2; side++)
{
for(side = 0; side < 2; side++) {
glColor3fv(browColor);
glPushMatrix();
glTranslatef(0, 0.35 + browAudioLift, 0);
@ -680,31 +775,27 @@ void Head::renderHead( int faceToFace, int isMine )
//---------------------------------------------------------
void Head::setHandMovement( glm::vec3 movement )
{
void Head::setHandMovement( glm::vec3 movement ) {
handBeingMoved = true;
movedHandOffset = movement;
}
//-----------------------------------------
void Head::initializeAvatar()
{
void Head::initializeAvatar() {
//avatar.position = glm::vec3( 0.0, 0.0, 0.0 );
avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 );
avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 );
avatar.orientation.setToIdentity();
closestOtherAvatar = 0;
avatar.yaw = -90.0;
avatar.pitch = 0.0;
avatar.roll = 0.0;
avatar.yawDelta = 0.0;
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
for (int b=0; b<NUM_AVATAR_BONES; b++) {
avatar.bone[b].position = glm::vec3( 0.0, 0.0, 0.0 );
avatar.bone[b].springyPosition = glm::vec3( 0.0, 0.0, 0.0 );
avatar.bone[b].springyVelocity = glm::vec3( 0.0, 0.0, 0.0 );
@ -799,12 +890,8 @@ void Head::initializeAvatar()
//-----------------------------------------
void Head::calculateBoneLengths()
{
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
void Head::calculateBoneLengths() {
for (int b=0; b<NUM_AVATAR_BONES; b++) {
avatar.bone[b].length = glm::length( avatar.bone[b].defaultPosePosition );
}
@ -815,76 +902,61 @@ void Head::calculateBoneLengths()
}
//-----------------------------------------
void Head::updateAvatarSkeleton()
{
//------------------------------------------------------------------------
void Head::updateAvatarSkeleton() {
//----------------------------------
// rotate...
//------------------------------------------------------------------------
//----------------------------------
avatar.orientation.setToIdentity();
avatar.orientation.yaw( avatar.yaw );
//------------------------------------------------------------------------
// calculate positions of all bones by traversing the skeleton tree:
//------------------------------------------------------------------------
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
if ( avatar.bone[b].parent == AVATAR_BONE_NULL )
{
for (int b=0; b<NUM_AVATAR_BONES; b++) {
if ( avatar.bone[b].parent == AVATAR_BONE_NULL ) {
avatar.bone[b].orientation.set( avatar.orientation );
avatar.bone[b].position = position;
}
else
{
else {
avatar.bone[b].orientation.set( avatar.bone[ avatar.bone[b].parent ].orientation );
avatar.bone[b].position = avatar.bone[ avatar.bone[b].parent ].position;
}
float xx = glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getRight() );
float yy = glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getUp () );
float zz = -glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getFront() );
float xx = glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getRight () );
float yy = glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getUp () );
float zz = -glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getFront () );
glm::vec3 rotatedBoneVector( xx, yy, zz );
avatar.bone[b].position += rotatedBoneVector;
}
//------------------------------------------------------------------------
// reset hand and elbow position according to hand movement
//------------------------------------------------------------------------
if ( handBeingMoved )
{
updateHandMovement();
handBeingMoved = false;
}
void Head::initializeAvatarSprings() {
for (int b=0; b<NUM_AVATAR_BONES; b++) {
avatar.bone[b].springyPosition = avatar.bone[b].position;
avatar.bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
}
}
//-----------------------------------------------
void Head::updateAvatarSprings( float deltaTime )
{
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
void Head::updateAvatarSprings( float deltaTime ) {
for (int b=0; b<NUM_AVATAR_BONES; b++) {
glm::vec3 springVector( avatar.bone[b].springyPosition );
if ( avatar.bone[b].parent == AVATAR_BONE_NULL )
{
if ( avatar.bone[b].parent == AVATAR_BONE_NULL ) {
springVector -= position;
}
else if ( avatar.bone[b].parent == AVATAR_BONE_PELVIS_SPINE )
{
else if ( avatar.bone[b].parent == AVATAR_BONE_PELVIS_SPINE ) {
springVector -= position;
}
else
{
else {
springVector -= avatar.bone[ avatar.bone[b].parent ].springyPosition;
}
float length = glm::length( springVector );
if ( length > 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; b<NUM_AVATAR_BONES; b++)
{
glColor3fv( skinColor );
//glColor4f( 1.0f, 0.8f, 0.6f, 0.4f );
glPushMatrix();
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
glutSolidSphere( 0.02f, 10.0f, 5.0f );
glPopMatrix();
glColor4fv( lightBlue );
glPushMatrix();
glTranslatef( avatar.bone[b].springyPosition.x, avatar.bone[b].springyPosition.y, avatar.bone[b].springyPosition.z );
glutSolidSphere( 0.01f, 10.0f, 5.0f );
glPopMatrix();
for (int b=0; b<NUM_AVATAR_BONES; b++) {
if ( usingSprings ) {
glColor3fv( lightBlue );
glPushMatrix();
glTranslatef( avatar.bone[b].springyPosition.x, avatar.bone[b].springyPosition.y, avatar.bone[b].springyPosition.z );
glutSolidSphere( 0.02f, 10.0f, 5.0f );
glPopMatrix();
}
else {
glColor3fv( skinColor );
glPushMatrix();
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
glutSolidSphere( 0.02f, 10.0f, 5.0f );
glPopMatrix();
}
}
//-----------------------------------------------------
// Render lines connecting the bone positions
//-----------------------------------------------------
//glColor3f(1,1,1);
glColor3fv( skinColor );
//glColor4f( 1.0f, 0.8f, 0.6f, 0.4f );
glLineWidth(3.0);
if ( usingSprings ) {
glColor3f( 0.2f, 0.3f, 0.4f );
glLineWidth(3.0);
for (int b=1; b<NUM_AVATAR_BONES; b++)
{
glBegin( GL_LINE_STRIP );
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].position.x );
glVertex3fv( &avatar.bone[ b ].position.x);
glEnd();
for (int b=1; b<NUM_AVATAR_BONES; b++) {
glBegin( GL_LINE_STRIP );
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].springyPosition.x );
glVertex3fv( &avatar.bone[ b ].springyPosition.x );
glEnd();
}
}
else {
glColor3fv( skinColor );
glLineWidth(3.0);
//-----------------------------------------------------
// Render lines connecting the springy positions
//-----------------------------------------------------
glColor3f( 0.2f, 0.3f, 0.4f );
glLineWidth(3.0);
for (int b=1; b<NUM_AVATAR_BONES; b++)
{
glBegin( GL_LINE_STRIP );
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].springyPosition.x );
glVertex3fv( &avatar.bone[ b ].springyPosition.x );
glEnd();
for (int b=1; b<NUM_AVATAR_BONES; b++) {
glBegin( GL_LINE_STRIP );
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].position.x );
glVertex3fv( &avatar.bone[ b ].position.x);
glEnd();
}
}
/*
glBegin(GL_LINE_STRIP);
glVertex3fv(&avatar.bone[AVATAR_BONE_CHEST_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_NECK].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_CHEST_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_SHOULDER].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_UPPER_ARM].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_FOREARM].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_HAND].position.x);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3fv(&avatar.bone[AVATAR_BONE_CHEST_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_SHOULDER].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_UPPER_ARM].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_FOREARM].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_HAND].position.x);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3fv(&avatar.bone[AVATAR_BONE_CHEST_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_MID_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_PELVIS_SPINE].position.x);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3fv(&avatar.bone[AVATAR_BONE_PELVIS_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_PELVIS].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_THIGH].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_SHIN].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_LEFT_FOOT].position.x);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex3fv(&avatar.bone[AVATAR_BONE_PELVIS_SPINE].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_PELVIS].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_THIGH].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_SHIN].position.x);
glVertex3fv(&avatar.bone[AVATAR_BONE_RIGHT_FOOT].position.x);
glEnd();
*/
}
// Transmit data to agents requesting it
//called on me just prior to sending data to others (continuasly called)
//---------------------------------------------------
int Head::getBroadcastData(char* data)
{
// Transmit data to agents requesting it
// called on me just prior to sending data to others (continuasly called)
int Head::getBroadcastData(char* data) {
// Copy data for transmission to the buffer, return length of data
sprintf(data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
getRenderPitch() + Pitch, -getRenderYaw() + 180 -Yaw, Roll,
//avatar.yaw, avatar.pitch, avatar.roll,
position.x + leanSideways, position.y, position.z + leanForward,
loudness, averageLoudness,
//hand->getPos().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;
}

View file

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

View file

@ -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<float>(i % width);
tiles[i].y = static_cast<float>(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<float>(screenWidth/width);
float tileheight = static_cast<float>(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;
}
}
}

View file

@ -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 <glm/glm.hpp>
#include "Util.h"
#include "world.h"
#include "InterfaceConfig.h"
#include <iostream>
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__) */

View file

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

View file

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

View file

@ -69,8 +69,6 @@
#include <AgentList.h>
#include <AgentTypes.h>
#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<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++)
{
if (agent->getLinkedData() != NULL)
{
AgentList *agentList = AgentList::getInstance();
for(std::vector<Agent>::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);

View file

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

View file

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

View file

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

View file

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