mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 19:10:56 +02:00
Merge branch 'master' of https://github.com/worklist/hifi into voxel_lod_fixes
This commit is contained in:
commit
85bef98f4a
15 changed files with 484 additions and 822 deletions
|
@ -37,8 +37,6 @@
|
||||||
const int AVATAR_LISTEN_PORT = 55444;
|
const int AVATAR_LISTEN_PORT = 55444;
|
||||||
const unsigned short BROADCAST_INTERVAL_USECS = 20 * 1000 * 1000;
|
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) {
|
unsigned char *addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
||||||
currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket());
|
currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket());
|
||||||
|
|
||||||
|
@ -70,13 +68,14 @@ void attachAvatarDataToAgent(Agent *newAgent) {
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT);
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
agentList.linkedDataCreateCallback = attachAvatarDataToAgent;
|
agentList->linkedDataCreateCallback = attachAvatarDataToAgent;
|
||||||
|
|
||||||
agentList.startDomainServerCheckInThread();
|
agentList->startDomainServerCheckInThread();
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList->startSilentAgentRemovalThread();
|
||||||
agentList.startPingUnknownAgentsThread();
|
agentList->startPingUnknownAgentsThread();
|
||||||
|
|
||||||
sockaddr *agentAddress = new sockaddr;
|
sockaddr *agentAddress = new sockaddr;
|
||||||
char *packetData = new char[MAX_PACKET_SIZE];
|
char *packetData = new char[MAX_PACKET_SIZE];
|
||||||
|
@ -89,43 +88,43 @@ int main(int argc, char* argv[])
|
||||||
int agentIndex = 0;
|
int agentIndex = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
if (agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
||||||
switch (packetData[0]) {
|
switch (packetData[0]) {
|
||||||
case PACKET_HEADER_HEAD_DATA:
|
case PACKET_HEADER_HEAD_DATA:
|
||||||
// this is positional data from an agent
|
// this is positional data from an agent
|
||||||
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
agentList->updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
||||||
|
|
||||||
currentBufferPosition = broadcastPacket + 1;
|
currentBufferPosition = broadcastPacket + 1;
|
||||||
agentIndex = 0;
|
agentIndex = 0;
|
||||||
|
|
||||||
// send back a packet with other active agent data to this agent
|
// send back a packet with other active agent data to this agent
|
||||||
for (std::vector<Agent>::iterator avatarAgent = agentList.getAgents().begin();
|
for (std::vector<Agent>::iterator avatarAgent = agentList->getAgents().begin();
|
||||||
avatarAgent != agentList.getAgents().end();
|
avatarAgent != agentList->getAgents().end();
|
||||||
avatarAgent++) {
|
avatarAgent++) {
|
||||||
if (avatarAgent->getLinkedData() != NULL
|
if (avatarAgent->getLinkedData() != NULL
|
||||||
&& agentIndex != agentList.indexOfMatchingAgent(agentAddress)) {
|
&& agentIndex != agentList->indexOfMatchingAgent(agentAddress)) {
|
||||||
currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent);
|
currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
agentIndex++;
|
agentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
agentList.getAgentSocket().send(agentAddress,
|
agentList->getAgentSocket().send(agentAddress,
|
||||||
broadcastPacket,
|
broadcastPacket,
|
||||||
currentBufferPosition - broadcastPacket);
|
currentBufferPosition - broadcastPacket);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// hand this off to the AgentList
|
// hand this off to the AgentList
|
||||||
agentList.processAgentData(agentAddress, (void *)packetData, receivedBytes);
|
agentList->processAgentData(agentAddress, (void *)packetData, receivedBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
agentList.stopDomainServerCheckInThread();
|
agentList->stopDomainServerCheckInThread();
|
||||||
agentList.stopSilentAgentRemovalThread();
|
agentList->stopSilentAgentRemovalThread();
|
||||||
agentList.stopPingUnknownAgentsThread();
|
agentList->stopPingUnknownAgentsThread();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ const int LOGOFF_CHECK_INTERVAL = 5000;
|
||||||
#define DEBUG_TO_SELF 0
|
#define DEBUG_TO_SELF 0
|
||||||
|
|
||||||
int lastActiveCount = 0;
|
int lastActiveCount = 0;
|
||||||
AgentList agentList(AGENT_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);
|
|
||||||
|
|
||||||
unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
||||||
*currentPosition++ = agentToAdd->getType();
|
*currentPosition++ = agentToAdd->getType();
|
||||||
|
@ -63,6 +62,7 @@ unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
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
|
// 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
|
// 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
|
// 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();
|
in_addr_t serverLocalAddress = getLocalAddress();
|
||||||
|
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList->startSilentAgentRemovalThread();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (agentList.getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
|
if (agentList->getAgentSocket().receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes)) {
|
||||||
std::map<char, Agent *> newestSoloAgents;
|
std::map<char, Agent *> newestSoloAgents;
|
||||||
|
|
||||||
agentType = packetData[0];
|
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,
|
(sockaddr *)&agentLocalAddress,
|
||||||
agentType,
|
agentType,
|
||||||
agentList.getLastAgentId())) {
|
agentList->getLastAgentId())) {
|
||||||
|
|
||||||
agentList.increaseAgentId();
|
agentList->increaseAgentId();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBufferPos = broadcastPacket + 1;
|
currentBufferPos = broadcastPacket + 1;
|
||||||
startPointer = currentBufferPos;
|
startPointer = currentBufferPos;
|
||||||
|
|
||||||
for(std::vector<Agent>::iterator agent = agentList.getAgents().begin();
|
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
|
||||||
agent != agentList.getAgents().end();
|
agent != agentList->getAgents().end();
|
||||||
agent++) {
|
agent++) {
|
||||||
|
|
||||||
if (DEBUG_TO_SELF ||
|
if (DEBUG_TO_SELF ||
|
||||||
|
@ -158,7 +158,7 @@ int main(int argc, const char * argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) {
|
if ((packetBytesWithoutLeadingChar = (currentBufferPos - startPointer))) {
|
||||||
agentList.getAgentSocket().send((sockaddr *)&agentPublicAddress,
|
agentList->getAgentSocket().send((sockaddr *)&agentPublicAddress,
|
||||||
broadcastPacket,
|
broadcastPacket,
|
||||||
packetBytesWithoutLeadingChar + 1);
|
packetBytesWithoutLeadingChar + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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__) */
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
|
#include <AgentList.h>
|
||||||
|
#include <AgentTypes.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -42,9 +44,8 @@ unsigned int iris_texture_height = 256;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------
|
|
||||||
Head::Head()
|
Head::Head() {
|
||||||
{
|
|
||||||
initializeAvatar();
|
initializeAvatar();
|
||||||
|
|
||||||
//position = glm::vec3(0,0,0);
|
//position = glm::vec3(0,0,0);
|
||||||
|
@ -86,9 +87,12 @@ Head::Head()
|
||||||
noise = 0;
|
noise = 0;
|
||||||
|
|
||||||
handBeingMoved = false;
|
handBeingMoved = false;
|
||||||
|
previousHandBeingMoved = false;
|
||||||
movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 );
|
movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 );
|
||||||
|
|
||||||
sphere = NULL;
|
sphere = NULL;
|
||||||
|
|
||||||
|
usingSprings = false;
|
||||||
|
|
||||||
springForce = 6.0f;
|
springForce = 6.0f;
|
||||||
springToBodyTightness = 4.0f;
|
springToBodyTightness = 4.0f;
|
||||||
|
@ -103,14 +107,27 @@ Head::Head()
|
||||||
std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl;
|
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();
|
initializeAvatar();
|
||||||
|
|
||||||
position = otherHead.position;
|
position = otherHead.position;
|
||||||
|
@ -164,38 +181,22 @@ Head::Head(const Head &otherHead)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Head::~Head() {
|
||||||
//---------------------------------------------------
|
if (sphere != NULL) {
|
||||||
Head::~Head()
|
|
||||||
{
|
|
||||||
if (sphere != NULL)
|
|
||||||
{
|
|
||||||
gluDeleteQuadric(sphere);
|
gluDeleteQuadric(sphere);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Head* Head::clone() const {
|
||||||
|
|
||||||
//---------------------------------------------------
|
|
||||||
Head* Head::clone() const
|
|
||||||
{
|
|
||||||
return new Head(*this);
|
return new Head(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Head::reset() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------
|
|
||||||
void Head::reset()
|
|
||||||
{
|
|
||||||
Pitch = Yaw = Roll = 0;
|
Pitch = Yaw = Roll = 0;
|
||||||
leanForward = leanSideways = 0;
|
leanForward = leanSideways = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//this pertains to moving the head with the glasses
|
//this pertains to moving the head with the glasses
|
||||||
//---------------------------------------------------
|
//---------------------------------------------------
|
||||||
void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity)
|
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) {
|
void Head::addLean(float x, float z) {
|
||||||
// Add Body lean as impulse
|
// Add Body lean as impulse
|
||||||
leanSideways += x;
|
leanSideways += x;
|
||||||
|
@ -250,79 +249,138 @@ void Head::addLean(float x, float z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------
|
|
||||||
void Head::setLeanForward(float dist){
|
void Head::setLeanForward(float dist){
|
||||||
leanForward = dist;
|
leanForward = dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------
|
|
||||||
void Head::setLeanSideways(float dist){
|
void Head::setLeanSideways(float dist){
|
||||||
leanSideways = 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
|
//------------------------
|
||||||
//---------------------------------------------------
|
// update avatar skeleton
|
||||||
void Head::simulate(float deltaTime)
|
//------------------------
|
||||||
{
|
|
||||||
updateAvatarSkeleton();
|
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 THRUST_MAG = 10.0;
|
||||||
const float YAW_MAG = 300.0;
|
const float YAW_MAG = 300.0;
|
||||||
|
|
||||||
avatar.thrust = glm::vec3( 0.0, 0.0, 0.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
|
//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 );
|
glm::vec3 front( avatar.orientation.getFront().x, avatar.orientation.getFront().y, avatar.orientation.getFront().z );
|
||||||
avatar.thrust += front * THRUST_MAG;
|
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 );
|
glm::vec3 front( avatar.orientation.getFront().x, avatar.orientation.getFront().y, avatar.orientation.getFront().z );
|
||||||
avatar.thrust -= front * THRUST_MAG;
|
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 );
|
glm::vec3 right( avatar.orientation.getRight().x, avatar.orientation.getRight().y, avatar.orientation.getRight().z );
|
||||||
avatar.thrust -= right * THRUST_MAG;
|
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 );
|
glm::vec3 right( avatar.orientation.getRight().x, avatar.orientation.getRight().y, avatar.orientation.getRight().z );
|
||||||
avatar.thrust += right * THRUST_MAG;
|
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 );
|
glm::vec3 up( avatar.orientation.getUp().x, avatar.orientation.getUp().y, avatar.orientation.getUp().z );
|
||||||
avatar.thrust += up * THRUST_MAG;
|
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 );
|
glm::vec3 up( avatar.orientation.getUp().x, avatar.orientation.getUp().y, avatar.orientation.getUp().z );
|
||||||
avatar.thrust -= up * THRUST_MAG;
|
avatar.thrust -= up * THRUST_MAG;
|
||||||
}
|
}
|
||||||
|
if (driveKeys[ROT_RIGHT]) {
|
||||||
if (driveKeys[ROT_RIGHT])
|
|
||||||
{
|
|
||||||
avatar.yawDelta -= YAW_MAG * deltaTime;
|
avatar.yawDelta -= YAW_MAG * deltaTime;
|
||||||
}
|
}
|
||||||
if (driveKeys[ROT_LEFT])
|
if (driveKeys[ROT_LEFT]) {
|
||||||
{
|
|
||||||
avatar.yawDelta += YAW_MAG * deltaTime;
|
avatar.yawDelta += YAW_MAG * deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,8 +419,7 @@ void Head::simulate(float deltaTime)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
if (!noise)
|
if (!noise) {
|
||||||
{
|
|
||||||
// Decay back toward center
|
// Decay back toward center
|
||||||
Pitch *= (1.f - DECAY*2*deltaTime);
|
Pitch *= (1.f - DECAY*2*deltaTime);
|
||||||
Yaw *= (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.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);
|
SetNewHeadTarget((randFloat()-0.5)*20.0, (randFloat()-0.5)*45.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0)
|
if (0) {
|
||||||
{
|
|
||||||
|
|
||||||
// Pick new target
|
// Pick new target
|
||||||
PitchTarget = (randFloat() - 0.5)*45;
|
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();
|
glPushMatrix();
|
||||||
glTranslatef( position.x, position.y, position.z );
|
glTranslatef( position.x, position.y, position.z );
|
||||||
glScalef( 0.03, 0.03, 0.03 );
|
glScalef( 0.03, 0.03, 0.03 );
|
||||||
glutSolidSphere( 1, 10, 10 );
|
glutSolidSphere( 1, 10, 10 );
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
|
//---------------------------------------------------
|
||||||
|
// show avatar orientation
|
||||||
|
//---------------------------------------------------
|
||||||
renderOrientationDirections(avatar.bone[ AVATAR_BONE_HEAD ].position, avatar.bone[ AVATAR_BONE_HEAD ].orientation, 0.2f );
|
renderOrientationDirections(avatar.bone[ AVATAR_BONE_HEAD ].position, avatar.bone[ AVATAR_BONE_HEAD ].orientation, 0.2f );
|
||||||
|
|
||||||
|
//---------------------------------------------------
|
||||||
|
// render body
|
||||||
|
//---------------------------------------------------
|
||||||
renderBody();
|
renderBody();
|
||||||
|
|
||||||
|
//---------------------------------------------------
|
||||||
|
// render head
|
||||||
|
//---------------------------------------------------
|
||||||
renderHead( faceToFace, isMine );
|
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 pRight = position + orientation.getRight () * size;
|
||||||
glm::vec3 pUp = position + orientation.getUp () * size;
|
glm::vec3 pUp = position + orientation.getUp () * size;
|
||||||
glm::vec3 pFront = position + orientation.getFront () * 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;
|
int side = 0;
|
||||||
|
|
||||||
// Always render own hand, but don't render head unless showing face2face
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_RESCALE_NORMAL);
|
glEnable(GL_RESCALE_NORMAL);
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
//glScalef(scale, scale, scale);
|
|
||||||
|
if ( usingSprings ) {
|
||||||
glTranslatef
|
glTranslatef
|
||||||
(
|
(
|
||||||
avatar.bone[ AVATAR_BONE_HEAD ].position.x,
|
avatar.bone[ AVATAR_BONE_HEAD ].springyPosition.x,
|
||||||
avatar.bone[ AVATAR_BONE_HEAD ].position.y,
|
avatar.bone[ AVATAR_BONE_HEAD ].springyPosition.y,
|
||||||
avatar.bone[ AVATAR_BONE_HEAD ].position.z
|
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 );
|
glScalef( 0.03, 0.03, 0.03 );
|
||||||
|
|
||||||
|
|
||||||
|
@ -559,8 +656,7 @@ void Head::renderHead( int faceToFace, int isMine )
|
||||||
// Ears
|
// Ears
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(1.0, 0, 0);
|
glTranslatef(1.0, 0, 0);
|
||||||
for(side = 0; side < 2; side++)
|
for(side = 0; side < 2; side++) {
|
||||||
{
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glScalef(0.3, 0.65, .65);
|
glScalef(0.3, 0.65, .65);
|
||||||
glutSolidSphere(0.5, 30, 30);
|
glutSolidSphere(0.5, 30, 30);
|
||||||
|
@ -581,8 +677,7 @@ void Head::renderHead( int faceToFace, int isMine )
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(-interBrowDistance/2.0,0.4,0.45);
|
glTranslatef(-interBrowDistance/2.0,0.4,0.45);
|
||||||
for(side = 0; side < 2; side++)
|
for(side = 0; side < 2; side++) {
|
||||||
{
|
|
||||||
glColor3fv(browColor);
|
glColor3fv(browColor);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(0, 0.35 + browAudioLift, 0);
|
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;
|
handBeingMoved = true;
|
||||||
movedHandOffset = movement;
|
movedHandOffset = movement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Head::initializeAvatar() {
|
||||||
//-----------------------------------------
|
|
||||||
void Head::initializeAvatar()
|
|
||||||
{
|
|
||||||
//avatar.position = glm::vec3( 0.0, 0.0, 0.0 );
|
//avatar.position = glm::vec3( 0.0, 0.0, 0.0 );
|
||||||
avatar.velocity = 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.thrust = glm::vec3( 0.0, 0.0, 0.0 );
|
||||||
avatar.orientation.setToIdentity();
|
avatar.orientation.setToIdentity();
|
||||||
|
|
||||||
|
closestOtherAvatar = 0;
|
||||||
|
|
||||||
avatar.yaw = -90.0;
|
avatar.yaw = -90.0;
|
||||||
avatar.pitch = 0.0;
|
avatar.pitch = 0.0;
|
||||||
avatar.roll = 0.0;
|
avatar.roll = 0.0;
|
||||||
|
|
||||||
avatar.yawDelta = 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].position = glm::vec3( 0.0, 0.0, 0.0 );
|
||||||
avatar.bone[b].springyPosition = 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 );
|
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 );
|
avatar.bone[b].length = glm::length( avatar.bone[b].defaultPosePosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,76 +902,61 @@ void Head::calculateBoneLengths()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------
|
void Head::updateAvatarSkeleton() {
|
||||||
void Head::updateAvatarSkeleton()
|
//----------------------------------
|
||||||
{
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// rotate...
|
// rotate...
|
||||||
//------------------------------------------------------------------------
|
//----------------------------------
|
||||||
avatar.orientation.setToIdentity();
|
avatar.orientation.setToIdentity();
|
||||||
avatar.orientation.yaw( avatar.yaw );
|
avatar.orientation.yaw( avatar.yaw );
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// calculate positions of all bones by traversing the skeleton tree:
|
// calculate positions of all bones by traversing the skeleton tree:
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
for (int b=0; b<NUM_AVATAR_BONES; b++)
|
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||||
{
|
if ( avatar.bone[b].parent == AVATAR_BONE_NULL ) {
|
||||||
if ( avatar.bone[b].parent == AVATAR_BONE_NULL )
|
|
||||||
{
|
|
||||||
avatar.bone[b].orientation.set( avatar.orientation );
|
avatar.bone[b].orientation.set( avatar.orientation );
|
||||||
avatar.bone[b].position = position;
|
avatar.bone[b].position = position;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
avatar.bone[b].orientation.set( avatar.bone[ avatar.bone[b].parent ].orientation );
|
avatar.bone[b].orientation.set( avatar.bone[ avatar.bone[b].parent ].orientation );
|
||||||
avatar.bone[b].position = avatar.bone[ avatar.bone[b].parent ].position;
|
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 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 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 zz = -glm::dot( avatar.bone[b].defaultPosePosition, avatar.bone[b].orientation.getFront () );
|
||||||
|
|
||||||
glm::vec3 rotatedBoneVector( xx, yy, zz );
|
glm::vec3 rotatedBoneVector( xx, yy, zz );
|
||||||
avatar.bone[b].position += rotatedBoneVector;
|
avatar.bone[b].position += rotatedBoneVector;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// reset hand and elbow position according to hand movement
|
|
||||||
//------------------------------------------------------------------------
|
void Head::initializeAvatarSprings() {
|
||||||
if ( handBeingMoved )
|
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||||
{
|
avatar.bone[b].springyPosition = avatar.bone[b].position;
|
||||||
updateHandMovement();
|
avatar.bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||||
handBeingMoved = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 );
|
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;
|
springVector -= position;
|
||||||
}
|
}
|
||||||
else if ( avatar.bone[b].parent == AVATAR_BONE_PELVIS_SPINE )
|
else if ( avatar.bone[b].parent == AVATAR_BONE_PELVIS_SPINE ) {
|
||||||
{
|
|
||||||
springVector -= position;
|
springVector -= position;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
springVector -= avatar.bone[ avatar.bone[b].parent ].springyPosition;
|
springVector -= avatar.bone[ avatar.bone[b].parent ].springyPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
float length = glm::length( springVector );
|
float length = glm::length( springVector );
|
||||||
|
|
||||||
if ( length > 0.0f )
|
if ( length > 0.0f ) {
|
||||||
{
|
|
||||||
glm::vec3 springDirection = springVector / length;
|
glm::vec3 springDirection = springVector / length;
|
||||||
|
|
||||||
float force = ( length - avatar.bone[b].length ) * springForce * deltaTime;
|
float force = ( length - avatar.bone[b].length ) * springForce * deltaTime;
|
||||||
|
@ -898,32 +970,22 @@ void Head::updateAvatarSprings( float deltaTime )
|
||||||
|
|
||||||
float decay = 1.0 - springVelocityDecay * deltaTime;
|
float decay = 1.0 - springVelocityDecay * deltaTime;
|
||||||
|
|
||||||
if ( decay > 0.0 )
|
if ( decay > 0.0 ) {
|
||||||
{
|
|
||||||
avatar.bone[b].springyVelocity *= decay;
|
avatar.bone[b].springyVelocity *= decay;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
avatar.bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
avatar.bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
avatar.bone[b].springyPosition += avatar.bone[b].springyVelocity;
|
avatar.bone[b].springyPosition += avatar.bone[b].springyVelocity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float Head::getBodyYaw() {
|
||||||
|
|
||||||
//----------------------
|
|
||||||
float Head::getBodyYaw()
|
|
||||||
{
|
|
||||||
return avatar.yaw;
|
return avatar.yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Head::getHeadLookatDirection() {
|
||||||
//--------------------------------------
|
|
||||||
glm::vec3 Head::getHeadLookatDirection()
|
|
||||||
{
|
|
||||||
return glm::vec3
|
return glm::vec3
|
||||||
(
|
(
|
||||||
avatar.orientation.getFront().x,
|
avatar.orientation.getFront().x,
|
||||||
|
@ -932,9 +994,7 @@ glm::vec3 Head::getHeadLookatDirection()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------
|
glm::vec3 Head::getHeadLookatDirectionUp() {
|
||||||
glm::vec3 Head::getHeadLookatDirectionUp()
|
|
||||||
{
|
|
||||||
return glm::vec3
|
return glm::vec3
|
||||||
(
|
(
|
||||||
avatar.orientation.getUp().x,
|
avatar.orientation.getUp().x,
|
||||||
|
@ -943,9 +1003,7 @@ glm::vec3 Head::getHeadLookatDirectionUp()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------
|
glm::vec3 Head::getHeadLookatDirectionRight() {
|
||||||
glm::vec3 Head::getHeadLookatDirectionRight()
|
|
||||||
{
|
|
||||||
return glm::vec3
|
return glm::vec3
|
||||||
(
|
(
|
||||||
avatar.orientation.getRight().x,
|
avatar.orientation.getRight().x,
|
||||||
|
@ -954,10 +1012,7 @@ glm::vec3 Head::getHeadLookatDirectionRight()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Head::getHeadPosition() {
|
||||||
//-------------------------------
|
|
||||||
glm::vec3 Head::getHeadPosition()
|
|
||||||
{
|
|
||||||
return glm::vec3
|
return glm::vec3
|
||||||
(
|
(
|
||||||
avatar.bone[ AVATAR_BONE_HEAD ].position.x,
|
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
|
return glm::vec3
|
||||||
(
|
(
|
||||||
avatar.bone[ AVATAR_BONE_PELVIS_SPINE ].position.x,
|
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;
|
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 )
|
//transformedHandMovement = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||||
+ glm::dot( movedHandOffset.y, -(float)avatar.orientation.getRight().y )
|
|
||||||
+ glm::dot( movedHandOffset.z, -(float)avatar.orientation.getRight().z );
|
|
||||||
|
//if holding hands, add a pull to the hand...
|
||||||
transformedHandMovement.y
|
if ( usingSprings ) {
|
||||||
= glm::dot( movedHandOffset.x, -(float)avatar.orientation.getUp().x )
|
if ( closestOtherAvatar != -1 ) {
|
||||||
+ glm::dot( movedHandOffset.y, -(float)avatar.orientation.getUp().y )
|
glm::vec3 handShakePull( DEBUG_otherAvatarListPosition[ closestOtherAvatar ]);
|
||||||
+ glm::dot( movedHandOffset.z, -(float)avatar.orientation.getUp().z );
|
handShakePull -= avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||||
|
|
||||||
transformedHandMovement.z
|
handShakePull *= 0.3;
|
||||||
= glm::dot( movedHandOffset.x, -(float)avatar.orientation.getFront().x )
|
|
||||||
+ glm::dot( movedHandOffset.y, -(float)avatar.orientation.getFront().y )
|
transformedHandMovement += handShakePull;
|
||||||
+ glm::dot( movedHandOffset.z, -(float)avatar.orientation.getFront().z );
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement;
|
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement;
|
||||||
glm::vec3 armVector = avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
glm::vec3 armVector = avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||||
armVector -= avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].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 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
|
// reset right hand to be constrained to maximum arm length
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
|
@ -1048,110 +1103,64 @@ void Head::updateHandMovement()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------
|
|
||||||
void Head::renderBody()
|
void Head::renderBody()
|
||||||
{
|
{
|
||||||
//-----------------------------------------
|
//-----------------------------------------
|
||||||
// Render bone positions as spheres
|
// Render bone positions as spheres
|
||||||
//-----------------------------------------
|
//-----------------------------------------
|
||||||
for (int b=0; b<NUM_AVATAR_BONES; b++)
|
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||||
{
|
if ( usingSprings ) {
|
||||||
glColor3fv( skinColor );
|
glColor3fv( lightBlue );
|
||||||
//glColor4f( 1.0f, 0.8f, 0.6f, 0.4f );
|
glPushMatrix();
|
||||||
glPushMatrix();
|
glTranslatef( avatar.bone[b].springyPosition.x, avatar.bone[b].springyPosition.y, avatar.bone[b].springyPosition.z );
|
||||||
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
|
glutSolidSphere( 0.02f, 10.0f, 5.0f );
|
||||||
glutSolidSphere( 0.02f, 10.0f, 5.0f );
|
glPopMatrix();
|
||||||
glPopMatrix();
|
}
|
||||||
|
else {
|
||||||
glColor4fv( lightBlue );
|
glColor3fv( skinColor );
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef( avatar.bone[b].springyPosition.x, avatar.bone[b].springyPosition.y, avatar.bone[b].springyPosition.z );
|
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
|
||||||
glutSolidSphere( 0.01f, 10.0f, 5.0f );
|
glutSolidSphere( 0.02f, 10.0f, 5.0f );
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
// Render lines connecting the bone positions
|
// Render lines connecting the bone positions
|
||||||
//-----------------------------------------------------
|
//-----------------------------------------------------
|
||||||
//glColor3f(1,1,1);
|
if ( usingSprings ) {
|
||||||
glColor3fv( skinColor );
|
glColor3f( 0.2f, 0.3f, 0.4f );
|
||||||
//glColor4f( 1.0f, 0.8f, 0.6f, 0.4f );
|
glLineWidth(3.0);
|
||||||
glLineWidth(3.0);
|
|
||||||
|
|
||||||
for (int b=1; b<NUM_AVATAR_BONES; b++)
|
for (int b=1; b<NUM_AVATAR_BONES; b++) {
|
||||||
{
|
glBegin( GL_LINE_STRIP );
|
||||||
glBegin( GL_LINE_STRIP );
|
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].springyPosition.x );
|
||||||
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].position.x );
|
glVertex3fv( &avatar.bone[ b ].springyPosition.x );
|
||||||
glVertex3fv( &avatar.bone[ b ].position.x);
|
glEnd();
|
||||||
glEnd();
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
glColor3fv( skinColor );
|
||||||
|
glLineWidth(3.0);
|
||||||
|
|
||||||
//-----------------------------------------------------
|
for (int b=1; b<NUM_AVATAR_BONES; b++) {
|
||||||
// Render lines connecting the springy positions
|
glBegin( GL_LINE_STRIP );
|
||||||
//-----------------------------------------------------
|
glVertex3fv( &avatar.bone[ avatar.bone[ b ].parent ].position.x );
|
||||||
glColor3f( 0.2f, 0.3f, 0.4f );
|
glVertex3fv( &avatar.bone[ b ].position.x);
|
||||||
glLineWidth(3.0);
|
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
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
|
// Transmit data to agents requesting it
|
||||||
|
// called on me just prior to sending data to others (continuasly called)
|
||||||
//called on me just prior to sending data to others (continuasly called)
|
int Head::getBroadcastData(char* data) {
|
||||||
|
|
||||||
//---------------------------------------------------
|
|
||||||
int Head::getBroadcastData(char* data)
|
|
||||||
{
|
|
||||||
// Copy data for transmission to the buffer, return length of 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",
|
sprintf(data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
|
||||||
getRenderPitch() + Pitch, -getRenderYaw() + 180 -Yaw, Roll,
|
getRenderPitch() + Pitch, -getRenderYaw() + 180 -Yaw, Roll,
|
||||||
|
//avatar.yaw, avatar.pitch, avatar.roll,
|
||||||
position.x + leanSideways, position.y, position.z + leanForward,
|
position.x + leanSideways, position.y, position.z + leanForward,
|
||||||
loudness, averageLoudness,
|
loudness, averageLoudness,
|
||||||
//hand->getPos().x, hand->getPos().y, hand->getPos().z); //previous to Ventrella change
|
//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);
|
return strlen(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
//called on the other agents - assigns it to my views of the others
|
|
||||||
|
|
||||||
//---------------------------------------------------
|
//called on the other agents - assigns it to my views of the others
|
||||||
void Head::parseData(void *data, int size)
|
void Head::parseData(void *data, int size) {
|
||||||
{
|
|
||||||
sscanf
|
sscanf
|
||||||
(
|
(
|
||||||
(char *)data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
|
(char *)data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
|
||||||
&Pitch, &Yaw, &Roll,
|
&Pitch, &Yaw, &Roll,
|
||||||
|
//&avatar.yaw, &avatar.pitch, &avatar.roll,
|
||||||
&position.x, &position.y, &position.z,
|
&position.x, &position.y, &position.z,
|
||||||
&loudness, &averageLoudness,
|
&loudness, &averageLoudness,
|
||||||
&avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.x,
|
&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;
|
PitchTarget = pitch;
|
||||||
YawTarget = yaw;
|
YawTarget = yaw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
||||||
#define ROT_RIGHT 7
|
#define ROT_RIGHT 7
|
||||||
#define MAX_DRIVE_KEYS 8
|
#define MAX_DRIVE_KEYS 8
|
||||||
|
|
||||||
|
#define NUM_OTHER_AVATARS 5
|
||||||
|
|
||||||
/*
|
/*
|
||||||
enum AvatarJoints
|
enum AvatarJoints
|
||||||
{
|
{
|
||||||
|
@ -237,7 +239,15 @@ class Head : public AgentData {
|
||||||
//glm::vec3 velocity;
|
//glm::vec3 velocity;
|
||||||
//glm::vec3 thrust;
|
//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 handBeingMoved;
|
||||||
|
bool previousHandBeingMoved;
|
||||||
glm::vec3 movedHandOffset;
|
glm::vec3 movedHandOffset;
|
||||||
//glm::vec3 movedHandPosition;
|
//glm::vec3 movedHandPosition;
|
||||||
|
|
||||||
|
@ -255,6 +265,7 @@ class Head : public AgentData {
|
||||||
|
|
||||||
void initializeAvatar();
|
void initializeAvatar();
|
||||||
void updateAvatarSkeleton();
|
void updateAvatarSkeleton();
|
||||||
|
void initializeAvatarSprings();
|
||||||
void updateAvatarSprings( float deltaTime );
|
void updateAvatarSprings( float deltaTime );
|
||||||
void calculateBoneLengths();
|
void calculateBoneLengths();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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__) */
|
|
|
@ -1,33 +1,28 @@
|
||||||
#include "Orientation.h"
|
#include "Orientation.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
//------------------------
|
Orientation::Orientation() {
|
||||||
Orientation::Orientation()
|
|
||||||
{
|
|
||||||
right = glm::vec3( 1.0, 0.0, 0.0 );
|
right = glm::vec3( 1.0, 0.0, 0.0 );
|
||||||
up = glm::vec3( 0.0, 1.0, 0.0 );
|
up = glm::vec3( 0.0, 1.0, 0.0 );
|
||||||
front = glm::vec3( 0.0, 0.0, 1.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 );
|
right = glm::vec3( 1.0, 0.0, 0.0 );
|
||||||
up = glm::vec3( 0.0, 1.0, 0.0 );
|
up = glm::vec3( 0.0, 1.0, 0.0 );
|
||||||
front = glm::vec3( 0.0, 0.0, 1.0 );
|
front = glm::vec3( 0.0, 0.0, 1.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------
|
|
||||||
void Orientation::set( Orientation o )
|
void Orientation::set( Orientation o ) {
|
||||||
{
|
|
||||||
right = o.getRight();
|
right = o.getRight();
|
||||||
up = o.getUp();
|
up = o.getUp();
|
||||||
front = o.getFront();
|
front = o.getFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------
|
|
||||||
void Orientation::yaw( float angle )
|
void Orientation::yaw( float angle ) {
|
||||||
{
|
|
||||||
float r = angle * PI_OVER_180;
|
float r = angle * PI_OVER_180;
|
||||||
float s = sin( r );
|
float s = sin( r );
|
||||||
float c = cos( r );
|
float c = cos( r );
|
||||||
|
@ -41,9 +36,8 @@ void Orientation::yaw( float angle )
|
||||||
right = cosineRight - sineFront;
|
right = cosineRight - sineFront;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------
|
|
||||||
void Orientation::pitch( float angle )
|
void Orientation::pitch( float angle ) {
|
||||||
{
|
|
||||||
float r = angle * PI_OVER_180;
|
float r = angle * PI_OVER_180;
|
||||||
float s = sin( r );
|
float s = sin( r );
|
||||||
float c = cos( r );
|
float c = cos( r );
|
||||||
|
@ -57,9 +51,8 @@ void Orientation::pitch( float angle )
|
||||||
front = cosineFront - sineUp;
|
front = cosineFront - sineUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------
|
|
||||||
void Orientation::roll( float angle )
|
void Orientation::roll( float angle ) {
|
||||||
{
|
|
||||||
double r = angle * PI_OVER_180;
|
double r = angle * PI_OVER_180;
|
||||||
double s = sin( r );
|
double s = sin( r );
|
||||||
double c = cos( r );
|
double c = cos( r );
|
||||||
|
@ -73,9 +66,8 @@ void Orientation::roll( float angle )
|
||||||
right = cosineRight - sineUp;
|
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;
|
right = r;
|
||||||
up = u;
|
up = u;
|
||||||
front = f;
|
front = f;
|
||||||
|
|
|
@ -80,6 +80,23 @@ void render_world_box()
|
||||||
glVertex3f(0,0,0);
|
glVertex3f(0,0,0);
|
||||||
glVertex3f(0, 0, WORLD_SIZE);
|
glVertex3f(0, 0, WORLD_SIZE);
|
||||||
glEnd();
|
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)
|
double diffclock(timeval *clock1,timeval *clock2)
|
||||||
|
|
|
@ -69,8 +69,6 @@
|
||||||
#include <AgentList.h>
|
#include <AgentList.h>
|
||||||
#include <AgentTypes.h>
|
#include <AgentTypes.h>
|
||||||
#include "VoxelSystem.h"
|
#include "VoxelSystem.h"
|
||||||
#include "Lattice.h"
|
|
||||||
#include "Finger.h"
|
|
||||||
#include "Oscilloscope.h"
|
#include "Oscilloscope.h"
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
#include "SerialInterface.h"
|
#include "SerialInterface.h"
|
||||||
|
@ -80,7 +78,6 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
AgentList agentList(AGENT_TYPE_INTERFACE);
|
|
||||||
pthread_t networkReceiveThread;
|
pthread_t networkReceiveThread;
|
||||||
bool stopNetworkReceiveThread = false;
|
bool stopNetworkReceiveThread = false;
|
||||||
|
|
||||||
|
@ -129,9 +126,6 @@ Cloud cloud(0, // Particles
|
||||||
);
|
);
|
||||||
|
|
||||||
VoxelSystem voxels;
|
VoxelSystem voxels;
|
||||||
|
|
||||||
Lattice lattice(160,100);
|
|
||||||
Finger myFinger(WIDTH, HEIGHT);
|
|
||||||
Field field;
|
Field field;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
@ -188,7 +182,6 @@ int menuOn = 1; // Whether to show onscreen menu
|
||||||
//
|
//
|
||||||
|
|
||||||
SerialInterface serialPort;
|
SerialInterface serialPort;
|
||||||
int latency_display = 1;
|
|
||||||
|
|
||||||
glm::vec3 gravity;
|
glm::vec3 gravity;
|
||||||
|
|
||||||
|
@ -199,6 +192,9 @@ float FPS = 120.f;
|
||||||
timeval timerStart, timerEnd;
|
timeval timerStart, timerEnd;
|
||||||
timeval lastTimeIdle;
|
timeval lastTimeIdle;
|
||||||
double elapsedTime;
|
double elapsedTime;
|
||||||
|
timeval applicationStartupTime;
|
||||||
|
bool justStarted = true;
|
||||||
|
|
||||||
|
|
||||||
// Every second, check the frame rates and other stuff
|
// Every second, check the frame rates and other stuff
|
||||||
void Timer(int extra)
|
void Timer(int extra)
|
||||||
|
@ -236,7 +232,7 @@ void displayStats(void)
|
||||||
glm::vec3 avatarPos = myAvatar.getPos();
|
glm::vec3 avatarPos = myAvatar.getPos();
|
||||||
|
|
||||||
char stats[200];
|
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);
|
FPS, packetsPerSecond, bytesPerSecond, avatarPos.x,avatarPos.y,avatarPos.z);
|
||||||
drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats);
|
drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats);
|
||||||
if (serialPort.active) {
|
if (serialPort.active) {
|
||||||
|
@ -321,6 +317,7 @@ void init(void)
|
||||||
}
|
}
|
||||||
myAvatar.setPos(start_location );
|
myAvatar.setPos(start_location );
|
||||||
myCamera.setPosition( start_location );
|
myCamera.setPosition( start_location );
|
||||||
|
|
||||||
|
|
||||||
#ifdef MARKER_CAPTURE
|
#ifdef MARKER_CAPTURE
|
||||||
if(marker_capture_enabled){
|
if(marker_capture_enabled){
|
||||||
|
@ -465,7 +462,7 @@ void simulateHead(float frametime)
|
||||||
int broadcastBytes = myAvatar.getBroadcastData(broadcastString);
|
int broadcastBytes = myAvatar.getBroadcastData(broadcastString);
|
||||||
const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER};
|
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 I'm in paint mode, send a voxel out to VOXEL server agents.
|
||||||
if (::paintOn) {
|
if (::paintOn) {
|
||||||
|
@ -485,7 +482,7 @@ void simulateHead(float frametime)
|
||||||
::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) {
|
::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) {
|
||||||
|
|
||||||
if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &::paintingVoxel, bufferOut, sizeOut)){
|
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;
|
delete bufferOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -804,7 +801,7 @@ void display(void)
|
||||||
float sphereRadius = 0.25f;
|
float sphereRadius = 0.25f;
|
||||||
glColor3f(1,0,0);
|
glColor3f(1,0,0);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef( 0.0f, sphereRadius, 0.0f );
|
//glTranslatef( 0.0f, sphereRadius, 0.0f );
|
||||||
glutSolidSphere( sphereRadius, 15, 15 );
|
glutSolidSphere( sphereRadius, 15, 15 );
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
|
@ -827,10 +824,11 @@ void display(void)
|
||||||
if (displayField) field.render();
|
if (displayField) field.render();
|
||||||
|
|
||||||
// Render avatars of other agents
|
// Render avatars of other agents
|
||||||
for(std::vector<Agent>::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++)
|
AgentList *agentList = AgentList::getInstance();
|
||||||
{
|
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
|
||||||
if (agent->getLinkedData() != NULL)
|
agent != agentList->getAgents().end();
|
||||||
{
|
agent++) {
|
||||||
|
if (agent->getLinkedData() != NULL) {
|
||||||
Head *agentHead = (Head *)agent->getLinkedData();
|
Head *agentHead = (Head *)agent->getLinkedData();
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glm::vec3 pos = agentHead->getPos();
|
glm::vec3 pos = agentHead->getPos();
|
||||||
|
@ -862,16 +860,13 @@ void display(void)
|
||||||
gluOrtho2D(0, WIDTH, HEIGHT, 0);
|
gluOrtho2D(0, WIDTH, HEIGHT, 0);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
//lattice.render(WIDTH, HEIGHT);
|
|
||||||
//myFinger.render();
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
audio.render(WIDTH, HEIGHT);
|
audio.render(WIDTH, HEIGHT);
|
||||||
if (audioScope.getState()) audioScope.render();
|
if (audioScope.getState()) audioScope.render();
|
||||||
#endif
|
#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
|
// 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);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
glDisable(GL_LINE_SMOOTH);
|
glDisable(GL_LINE_SMOOTH);
|
||||||
|
@ -906,7 +901,7 @@ void display(void)
|
||||||
// Draw number of nearby people always
|
// Draw number of nearby people always
|
||||||
glPointSize(1.0f);
|
glPointSize(1.0f);
|
||||||
char agents[100];
|
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);
|
drawtext(WIDTH-100,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0);
|
||||||
|
|
||||||
if (::paintOn) {
|
if (::paintOn) {
|
||||||
|
@ -923,6 +918,13 @@ void display(void)
|
||||||
|
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
frameCount++;
|
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) {
|
int setValue(int state, int *value) {
|
||||||
|
@ -1007,14 +1009,14 @@ void sendVoxelServerEraseAll() {
|
||||||
char message[100];
|
char message[100];
|
||||||
sprintf(message,"%c%s",'Z',"erase all");
|
sprintf(message,"%c%s",'Z',"erase all");
|
||||||
int messageSize = strlen(message) + 1;
|
int messageSize = strlen(message) + 1;
|
||||||
::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1);
|
AgentList::getInstance()->broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendVoxelServerAddScene() {
|
void sendVoxelServerAddScene() {
|
||||||
char message[100];
|
char message[100];
|
||||||
sprintf(message,"%c%s",'Z',"add scene");
|
sprintf(message,"%c%s",'Z',"add scene");
|
||||||
int messageSize = strlen(message) + 1;
|
int messageSize = strlen(message) + 1;
|
||||||
::agentList.broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1);
|
AgentList::getInstance()->broadcastToAgents(message, messageSize, &AGENT_TYPE_VOXEL, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftPaintingColor()
|
void shiftPaintingColor()
|
||||||
|
@ -1026,8 +1028,7 @@ void shiftPaintingColor()
|
||||||
::paintingVoxel.blue = (::dominantColor==2)?randIntInRange(200,255):randIntInRange(40,100);
|
::paintingVoxel.blue = (::dominantColor==2)?randIntInRange(200,255):randIntInRange(40,100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupPaintingVoxel()
|
void setupPaintingVoxel() {
|
||||||
{
|
|
||||||
glm::vec3 avatarPos = myAvatar.getPos();
|
glm::vec3 avatarPos = myAvatar.getPos();
|
||||||
|
|
||||||
::paintingVoxel.x = avatarPos.z/-10.0; // voxel space x is negative z head space
|
::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];
|
char *incomingPacket = new char[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
while (!stopNetworkReceiveThread) {
|
while (!stopNetworkReceiveThread) {
|
||||||
if (agentList.getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) {
|
||||||
packetCount++;
|
packetCount++;
|
||||||
bytesCount += bytesReceived;
|
bytesCount += bytesReceived;
|
||||||
|
|
||||||
|
@ -1212,10 +1213,10 @@ void *networkReceive(void *args)
|
||||||
voxels.parseData(incomingPacket, bytesReceived);
|
voxels.parseData(incomingPacket, bytesReceived);
|
||||||
break;
|
break;
|
||||||
case PACKET_HEADER_BULK_AVATAR_DATA:
|
case PACKET_HEADER_BULK_AVATAR_DATA:
|
||||||
agentList.processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, sizeof(float) * 11);
|
AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, sizeof(float) * 11);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
agentList.processAgentData(&senderAddress, incomingPacket, bytesReceived);
|
AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1272,8 +1273,6 @@ void idle(void)
|
||||||
myAvatar.simulate(1.f/FPS);
|
myAvatar.simulate(1.f/FPS);
|
||||||
balls.simulate(1.f/FPS);
|
balls.simulate(1.f/FPS);
|
||||||
cloud.simulate(1.f/FPS);
|
cloud.simulate(1.f/FPS);
|
||||||
lattice.simulate(1.f/FPS);
|
|
||||||
myFinger.simulate(1.f/FPS);
|
|
||||||
|
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
lastTimeIdle = check;
|
lastTimeIdle = check;
|
||||||
|
@ -1316,7 +1315,6 @@ void mouseFunc( int button, int state, int x, int y )
|
||||||
mouseX = x;
|
mouseX = x;
|
||||||
mouseY = y;
|
mouseY = y;
|
||||||
mousePressed = 1;
|
mousePressed = 1;
|
||||||
lattice.mouseClick((float)x/(float)WIDTH, (float)y/(float)HEIGHT);
|
|
||||||
mouseStartX = x;
|
mouseStartX = x;
|
||||||
mouseStartY = y;
|
mouseStartY = y;
|
||||||
}
|
}
|
||||||
|
@ -1333,8 +1331,6 @@ void motionFunc( int x, int y)
|
||||||
{
|
{
|
||||||
mouseX = x;
|
mouseX = x;
|
||||||
mouseY = y;
|
mouseY = y;
|
||||||
|
|
||||||
lattice.mouseClick((float)x/(float)WIDTH,(float)y/(float)HEIGHT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseoverFunc( int x, int y)
|
void mouseoverFunc( int x, int y)
|
||||||
|
@ -1343,10 +1339,7 @@ void mouseoverFunc( int x, int y)
|
||||||
mouseX = x;
|
mouseX = x;
|
||||||
mouseY = y;
|
mouseY = y;
|
||||||
if (mousePressed == 0)
|
if (mousePressed == 0)
|
||||||
{
|
{}
|
||||||
// lattice.mouseOver((float)x/(float)WIDTH,(float)y/(float)HEIGHT);
|
|
||||||
// myFinger.setTarget(mouseX, mouseY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void attachNewHeadToAgent(Agent *newAgent) {
|
void attachNewHeadToAgent(Agent *newAgent) {
|
||||||
|
@ -1361,10 +1354,11 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
int main(int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
|
AgentList::createInstance(AGENT_TYPE_INTERFACE);
|
||||||
|
|
||||||
|
gettimeofday(&applicationStartupTime, NULL);
|
||||||
const char* domainIP = getCmdOption(argc, argv, "--domain");
|
const char* domainIP = getCmdOption(argc, argv, "--domain");
|
||||||
if (domainIP) {
|
if (domainIP) {
|
||||||
strcpy(DOMAIN_IP,domainIP);
|
strcpy(DOMAIN_IP,domainIP);
|
||||||
|
@ -1376,12 +1370,12 @@ int main(int argc, const char * argv[])
|
||||||
int ip = getLocalAddress();
|
int ip = getLocalAddress();
|
||||||
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
|
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
|
// the callback for our instance of AgentList is attachNewHeadToAgent
|
||||||
agentList.linkedDataCreateCallback = &attachNewHeadToAgent;
|
AgentList::getInstance()->linkedDataCreateCallback = &attachNewHeadToAgent;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
agentList.audioMixerSocketUpdate = &audioMixerUpdate;
|
AgentList::getInstance()->audioMixerSocketUpdate = &audioMixerUpdate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -1390,9 +1384,9 @@ int main(int argc, const char * argv[])
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// start the agentList threads
|
// start the agentList threads
|
||||||
agentList.startSilentAgentRemovalThread();
|
AgentList::getInstance()->startSilentAgentRemovalThread();
|
||||||
agentList.startDomainServerCheckInThread();
|
AgentList::getInstance()->startDomainServerCheckInThread();
|
||||||
agentList.startPingUnknownAgentsThread();
|
AgentList::getInstance()->startPingUnknownAgentsThread();
|
||||||
|
|
||||||
glutInit(&argc, (char**)argv);
|
glutInit(&argc, (char**)argv);
|
||||||
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
|
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
|
||||||
|
|
|
@ -61,7 +61,6 @@ const int AGENT_LOOPBACK_MODIFIER = 307;
|
||||||
|
|
||||||
const int LOOPBACK_SANITY_CHECK = 0;
|
const int LOOPBACK_SANITY_CHECK = 0;
|
||||||
|
|
||||||
AgentList agentList(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
|
|
||||||
StDev stdev;
|
StDev stdev;
|
||||||
|
|
||||||
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
|
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
|
||||||
|
@ -79,13 +78,15 @@ void *sendBuffer(void *args)
|
||||||
int nextFrame = 0;
|
int nextFrame = 0;
|
||||||
timeval startTime;
|
timeval startTime;
|
||||||
|
|
||||||
|
AgentList *agentList = AgentList::getInstance();
|
||||||
|
|
||||||
gettimeofday(&startTime, NULL);
|
gettimeofday(&startTime, NULL);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
sentBytes = 0;
|
sentBytes = 0;
|
||||||
|
|
||||||
for (int i = 0; i < agentList.getAgents().size(); i++) {
|
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||||
AudioRingBuffer *agentBuffer = (AudioRingBuffer *) agentList.getAgents()[i].getLinkedData();
|
AudioRingBuffer *agentBuffer = (AudioRingBuffer *) agentList->getAgents()[i].getLinkedData();
|
||||||
|
|
||||||
if (agentBuffer != NULL && agentBuffer->getEndOfLastWrite() != NULL) {
|
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];
|
float distanceCoeffs[numAgents][numAgents];
|
||||||
memset(distanceCoeffs, 0, sizeof(distanceCoeffs));
|
memset(distanceCoeffs, 0, sizeof(distanceCoeffs));
|
||||||
|
|
||||||
for (int i = 0; i < agentList.getAgents().size(); i++) {
|
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||||
Agent *agent = &agentList.getAgents()[i];
|
Agent *agent = &agentList->getAgents()[i];
|
||||||
|
|
||||||
AudioRingBuffer *agentRingBuffer = (AudioRingBuffer *) agent->getLinkedData();
|
AudioRingBuffer *agentRingBuffer = (AudioRingBuffer *) agent->getLinkedData();
|
||||||
float agentBearing = agentRingBuffer->getBearing();
|
float agentBearing = agentRingBuffer->getBearing();
|
||||||
|
@ -119,15 +120,17 @@ void *sendBuffer(void *args)
|
||||||
agentWantsLoopback = true;
|
agentWantsLoopback = true;
|
||||||
|
|
||||||
// correct the bearing
|
// 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] = {};
|
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)) {
|
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 *agentPosition = agentRingBuffer->getPosition();
|
||||||
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
||||||
|
@ -143,12 +146,15 @@ void *sendBuffer(void *args)
|
||||||
powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
||||||
powf(agentPosition[2] - otherAgentPosition[2], 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
|
// 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;
|
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++) {
|
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||||
AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList.getAgents()[i].getLinkedData();
|
AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList->getAgents()[i].getLinkedData();
|
||||||
if (agentBuffer->wasAddedToMix()) {
|
if (agentBuffer->wasAddedToMix()) {
|
||||||
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||||
|
|
||||||
|
@ -250,14 +256,15 @@ void attachNewBufferToAgent(Agent *newAgent) {
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
int main(int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
|
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
ssize_t receivedBytes = 0;
|
ssize_t receivedBytes = 0;
|
||||||
|
|
||||||
agentList.linkedDataCreateCallback = attachNewBufferToAgent;
|
agentList->linkedDataCreateCallback = attachNewBufferToAgent;
|
||||||
|
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList->startSilentAgentRemovalThread();
|
||||||
agentList.startDomainServerCheckInThread();
|
agentList->startDomainServerCheckInThread();
|
||||||
|
|
||||||
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
|
@ -276,7 +283,7 @@ int main(int argc, const char * argv[])
|
||||||
bool firstSample = true;
|
bool firstSample = true;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
if(agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
|
||||||
if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) {
|
if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) {
|
||||||
|
|
||||||
// Compute and report standard deviation for jitter calculation
|
// 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
|
// add or update the existing interface agent
|
||||||
if (!LOOPBACK_SANITY_CHECK) {
|
if (!LOOPBACK_SANITY_CHECK) {
|
||||||
|
|
||||||
if (agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList.getLastAgentId())) {
|
if (agentList->addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList->getLastAgentId())) {
|
||||||
agentList.increaseAgentId();
|
agentList->increaseAgentId();
|
||||||
}
|
}
|
||||||
|
|
||||||
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
agentList->updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
||||||
} else {
|
} else {
|
||||||
memcpy(loopbackAudioPacket, packetData + 1 + (sizeof(float) * 4), 1024);
|
memcpy(loopbackAudioPacket, packetData + 1 + (sizeof(float) * 4), 1024);
|
||||||
agentList.getAgentSocket().send(agentAddress, loopbackAudioPacket, 1024);
|
agentList->getAgentSocket().send(agentAddress, loopbackAudioPacket, 1024);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,16 +31,27 @@ bool domainServerCheckinStopFlag = false;
|
||||||
bool pingUnknownAgentThreadStopFlag = false;
|
bool pingUnknownAgentThreadStopFlag = false;
|
||||||
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
int unpackAgentId(unsigned char *packedData, uint16_t *agentId) {
|
AgentList* AgentList::_sharedInstance = NULL;
|
||||||
memcpy(packedData, agentId, sizeof(uint16_t));
|
|
||||||
return sizeof(uint16_t);
|
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) {
|
AgentList* AgentList::getInstance() {
|
||||||
memcpy(&agentId, packStore, sizeof(uint16_t));
|
if (_sharedInstance == NULL) {
|
||||||
return sizeof(uint16_t);
|
printf("AgentList getInstance called before call to createInstance. Returning NULL pointer.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return _sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : agentSocket(newSocketListenPort) {
|
AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : agentSocket(newSocketListenPort) {
|
||||||
ownerType = newOwnerType;
|
ownerType = newOwnerType;
|
||||||
socketListenPort = newSocketListenPort;
|
socketListenPort = newSocketListenPort;
|
||||||
|
@ -379,7 +390,7 @@ void *checkInWithDomainServer(void *args) {
|
||||||
sockaddr_in tempAddress;
|
sockaddr_in tempAddress;
|
||||||
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
||||||
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
||||||
printf("Domain server %s: \n", DOMAIN_HOSTNAME);
|
printf("Domain server: %s \n", DOMAIN_HOSTNAME);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
printf("Failed lookup domainserver\n");
|
printf("Failed lookup domainserver\n");
|
||||||
|
@ -414,3 +425,13 @@ void AgentList::stopDomainServerCheckInThread() {
|
||||||
domainServerCheckinStopFlag = true;
|
domainServerCheckinStopFlag = true;
|
||||||
pthread_join(checkInWithDomainServerThread, NULL);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -29,20 +29,9 @@ extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startu
|
||||||
extern const int DOMAINSERVER_PORT;
|
extern const int DOMAINSERVER_PORT;
|
||||||
|
|
||||||
class AgentList {
|
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:
|
public:
|
||||||
AgentList(char ownerType, unsigned int socketListenPort = AGENT_SOCKET_LISTEN_PORT);
|
static AgentList* createInstance(char ownerType, unsigned int socketListenPort = AGENT_SOCKET_LISTEN_PORT);
|
||||||
~AgentList();
|
static AgentList* getInstance();
|
||||||
|
|
||||||
void(*linkedDataCreateCallback)(Agent *);
|
void(*linkedDataCreateCallback)(Agent *);
|
||||||
void(*audioMixerSocketUpdate)(in_addr_t, in_port_t);
|
void(*audioMixerSocketUpdate)(in_addr_t, in_port_t);
|
||||||
|
@ -76,6 +65,24 @@ public:
|
||||||
void stopDomainServerCheckInThread();
|
void stopDomainServerCheckInThread();
|
||||||
void startPingUnknownAgentsThread();
|
void startPingUnknownAgentsThread();
|
||||||
void stopPingUnknownAgentsThread();
|
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);
|
int unpackAgentId(unsigned char *packedData, uint16_t *agentId);
|
||||||
|
|
|
@ -46,7 +46,6 @@ const int PACKETS_PER_CLIENT_PER_INTERVAL = 2;
|
||||||
|
|
||||||
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4;
|
||||||
|
|
||||||
AgentList agentList(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT);
|
|
||||||
VoxelTree randomTree;
|
VoxelTree randomTree;
|
||||||
|
|
||||||
bool wantColorRandomizer = false;
|
bool wantColorRandomizer = false;
|
||||||
|
@ -122,11 +121,11 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
|
||||||
::randomTree.eraseAllVoxels();
|
::randomTree.eraseAllVoxels();
|
||||||
|
|
||||||
// enumerate the agents clean up their marker nodes
|
// 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);
|
//printf("eraseVoxelTreeAndCleanupAgentVisitData() agent[%d]\n",i);
|
||||||
|
|
||||||
Agent *thisAgent = (Agent *)&::agentList.getAgents()[i];
|
Agent *thisAgent = (Agent *)&AgentList::getInstance()->getAgents()[i];
|
||||||
VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData());
|
VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData());
|
||||||
|
|
||||||
// lock this agent's delete mutex so that the delete thread doesn't
|
// lock this agent's delete mutex so that the delete thread doesn't
|
||||||
|
@ -145,6 +144,7 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
|
||||||
|
|
||||||
void *distributeVoxelsToListeners(void *args) {
|
void *distributeVoxelsToListeners(void *args) {
|
||||||
|
|
||||||
|
AgentList *agentList = AgentList::getInstance();
|
||||||
timeval lastSendTime;
|
timeval lastSendTime;
|
||||||
|
|
||||||
unsigned char *stopOctal;
|
unsigned char *stopOctal;
|
||||||
|
@ -161,9 +161,9 @@ void *distributeVoxelsToListeners(void *args) {
|
||||||
gettimeofday(&lastSendTime, NULL);
|
gettimeofday(&lastSendTime, NULL);
|
||||||
|
|
||||||
// enumerate the agents to send 3 packets to each
|
// 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());
|
VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData());
|
||||||
|
|
||||||
// lock this agent's delete mutex so that the delete thread doesn't
|
// lock this agent's delete mutex so that the delete thread doesn't
|
||||||
|
@ -184,7 +184,7 @@ void *distributeVoxelsToListeners(void *args) {
|
||||||
treeRoot,
|
treeRoot,
|
||||||
stopOctal);
|
stopOctal);
|
||||||
|
|
||||||
agentList.getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
||||||
|
|
||||||
packetCount++;
|
packetCount++;
|
||||||
totalBytesSent += voxelPacketEnd - voxelPacket;
|
totalBytesSent += voxelPacketEnd - voxelPacket;
|
||||||
|
@ -233,6 +233,7 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) {
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
int main(int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
|
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT);
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
// Handle Local Domain testing with the --local command line
|
// 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));
|
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
agentList.linkedDataCreateCallback = &attachVoxelAgentDataToAgent;
|
agentList->linkedDataCreateCallback = &attachVoxelAgentDataToAgent;
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList->startSilentAgentRemovalThread();
|
||||||
agentList.startDomainServerCheckInThread();
|
agentList->startDomainServerCheckInThread();
|
||||||
|
|
||||||
srand((unsigned)time(0));
|
srand((unsigned)time(0));
|
||||||
|
|
||||||
|
@ -294,7 +295,7 @@ int main(int argc, const char * argv[])
|
||||||
|
|
||||||
// loop to send to agents requesting data
|
// loop to send to agents requesting data
|
||||||
while (true) {
|
while (true) {
|
||||||
if (agentList.getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) {
|
if (agentList->getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) {
|
||||||
// XXXBHG: Hacked in support for 'S' SET command
|
// XXXBHG: Hacked in support for 'S' SET command
|
||||||
if (packetData[0] == PACKET_HEADER_SET_VOXEL) {
|
if (packetData[0] == PACKET_HEADER_SET_VOXEL) {
|
||||||
unsigned short int itemNumber = (*((unsigned short int*)&packetData[1]));
|
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
|
// Now send this to the connected agents so they know to delete
|
||||||
printf("rebroadcasting delete voxel message to connected agents... agentList.broadcastToAgents()\n");
|
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) {
|
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
|
// Now send this to the connected agents so they can also process these messages
|
||||||
printf("rebroadcasting Z message to connected agents... agentList.broadcastToAgents()\n");
|
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
|
// 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.
|
// need to make sure we have it in our agentList.
|
||||||
if (packetData[0] == PACKET_HEADER_HEAD_DATA) {
|
if (packetData[0] == PACKET_HEADER_HEAD_DATA) {
|
||||||
if (agentList.addOrUpdateAgent(&agentPublicAddress,
|
if (agentList->addOrUpdateAgent(&agentPublicAddress,
|
||||||
&agentPublicAddress,
|
&agentPublicAddress,
|
||||||
AGENT_TYPE_INTERFACE,
|
AGENT_TYPE_INTERFACE,
|
||||||
agentList.getLastAgentId())) {
|
agentList->getLastAgentId())) {
|
||||||
agentList.increaseAgentId();
|
agentList->increaseAgentId();
|
||||||
}
|
}
|
||||||
|
|
||||||
agentList.updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes);
|
agentList->updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue