mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 22:35:14 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
Conflicts: avatar-mixer/src/main.cpp
This commit is contained in:
commit
c6af08d883
16 changed files with 786 additions and 699 deletions
|
@ -78,23 +78,23 @@ void *sendBuffer(void *args)
|
|||
int nextFrame = 0;
|
||||
timeval startTime;
|
||||
|
||||
AgentList *agentList = AgentList::getInstance();
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
|
||||
gettimeofday(&startTime, NULL);
|
||||
|
||||
while (true) {
|
||||
sentBytes = 0;
|
||||
|
||||
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||
AudioRingBuffer *agentBuffer = (AudioRingBuffer *) agentList->getAgents()[i].getLinkedData();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData();
|
||||
|
||||
if (agentBuffer != NULL && agentBuffer->getEndOfLastWrite() != NULL) {
|
||||
|
||||
if (!agentBuffer->isStarted()
|
||||
&& agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) {
|
||||
printf("Held back buffer %d.\n", i);
|
||||
printf("Held back buffer for agent with ID %d.\n", agent->getAgentId());
|
||||
} else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||
printf("Buffer %d starved.\n", i);
|
||||
printf("Buffer from agent with ID %d starved.\n", agent->getAgentId());
|
||||
agentBuffer->setStarted(false);
|
||||
} else {
|
||||
// good buffer, add this to the mix
|
||||
|
@ -104,14 +104,12 @@ void *sendBuffer(void *args)
|
|||
}
|
||||
}
|
||||
|
||||
int numAgents = agentList->getAgents().size();
|
||||
int numAgents = agentList->size();
|
||||
float distanceCoeffs[numAgents][numAgents];
|
||||
memset(distanceCoeffs, 0, sizeof(distanceCoeffs));
|
||||
|
||||
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||
Agent *agent = &agentList->getAgents()[i];
|
||||
|
||||
AudioRingBuffer *agentRingBuffer = (AudioRingBuffer *) agent->getLinkedData();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData();
|
||||
float agentBearing = agentRingBuffer->getBearing();
|
||||
bool agentWantsLoopback = false;
|
||||
|
||||
|
@ -128,9 +126,9 @@ void *sendBuffer(void *args)
|
|||
int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {};
|
||||
|
||||
|
||||
for (int j = 0; j < agentList->getAgents().size(); j++) {
|
||||
if (i != j || ( i == j && agentWantsLoopback)) {
|
||||
AudioRingBuffer *otherAgentBuffer = (AudioRingBuffer *)agentList->getAgents()[j].getLinkedData();
|
||||
for (AgentList::iterator otherAgent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (otherAgent != agent || ( otherAgent == agent && agentWantsLoopback)) {
|
||||
AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData();
|
||||
|
||||
float *agentPosition = agentRingBuffer->getPosition();
|
||||
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
||||
|
@ -138,8 +136,8 @@ void *sendBuffer(void *args)
|
|||
// calculate the distance to the other agent
|
||||
|
||||
// use the distance to the other agent to calculate the change in volume for this frame
|
||||
int lowAgentIndex = std::min(i, j);
|
||||
int highAgentIndex = std::max(i, j);
|
||||
int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex());
|
||||
int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex());
|
||||
|
||||
if (distanceCoeffs[lowAgentIndex][highAgentIndex] == 0) {
|
||||
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
|
||||
|
@ -223,8 +221,8 @@ void *sendBuffer(void *args)
|
|||
agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES);
|
||||
}
|
||||
|
||||
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||
AudioRingBuffer *agentBuffer = (AudioRingBuffer *)agentList->getAgents()[i].getLinkedData();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData();
|
||||
if (agentBuffer->wasAddedToMix()) {
|
||||
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
|
||||
|
@ -256,7 +254,7 @@ void attachNewBufferToAgent(Agent *newAgent) {
|
|||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT);
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
ssize_t receivedBytes = 0;
|
||||
|
|
|
@ -53,12 +53,7 @@ void attachAvatarDataToAgent(Agent *newAgent) {
|
|||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT);
|
||||
if (cmdOptionExists(argc, argv, "--local")) {
|
||||
printf("Local Domain MODE!\n");
|
||||
int ip = getLocalAddress();
|
||||
sprintf(DOMAIN_IP,"%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF));
|
||||
}
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AVATAR_MIXER, AVATAR_LISTEN_PORT);
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
agentList->linkedDataCreateCallback = attachAvatarDataToAgent;
|
||||
|
@ -88,11 +83,11 @@ int main(int argc, const char* argv[])
|
|||
agentIndex = 0;
|
||||
|
||||
// send back a packet with other active agent data to this agent
|
||||
for (std::vector<Agent>::iterator avatarAgent = agentList->getAgents().begin();
|
||||
avatarAgent != agentList->getAgents().end();
|
||||
for (AgentList::iterator avatarAgent = agentList->begin();
|
||||
avatarAgent != agentList->end();
|
||||
avatarAgent++) {
|
||||
if (avatarAgent->getLinkedData() != NULL
|
||||
&& agentIndex != agentList->indexOfMatchingAgent(agentAddress)) {
|
||||
&& !socketMatch(agentAddress, avatarAgent->getActiveSocket())) {
|
||||
currentBufferPosition = addAgentToBroadcastPacket(currentBufferPosition, &*avatarAgent);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ const int LOGOFF_CHECK_INTERVAL = 5000;
|
|||
|
||||
int lastActiveCount = 0;
|
||||
|
||||
unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
||||
unsigned char* addAgentToBroadcastPacket(unsigned char* currentPosition, Agent* agentToAdd) {
|
||||
*currentPosition++ = agentToAdd->getType();
|
||||
|
||||
currentPosition += packAgentId(currentPosition, agentToAdd->getAgentId());
|
||||
|
@ -62,7 +62,7 @@ unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent
|
|||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_DOMAIN, DOMAIN_LISTEN_PORT);
|
||||
// If user asks to run in "local" mode then we do NOT replace the IP
|
||||
// with the EC2 IP. Otherwise, we will replace the IP like we used to
|
||||
// this allows developers to run a local domain without recompiling the
|
||||
|
@ -127,10 +127,7 @@ int main(int argc, const char * argv[])
|
|||
currentBufferPos = broadcastPacket + 1;
|
||||
startPointer = currentBufferPos;
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
|
||||
agent != agentList->getAgents().end();
|
||||
agent++) {
|
||||
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (DEBUG_TO_SELF ||
|
||||
!agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) {
|
||||
if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) {
|
||||
|
|
|
@ -113,8 +113,7 @@ int main(int argc, const char* argv[]) {
|
|||
// move eve away from the origin
|
||||
// pick a random point inside a 10x10 grid
|
||||
|
||||
eve.setPosition(glm::vec3(randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION),
|
||||
0,
|
||||
eve.setPosition(glm::vec3(randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION), 0.4,
|
||||
randFloatInRange(-RANDOM_POSITION_MAX_DIMENSION, RANDOM_POSITION_MAX_DIMENSION)));
|
||||
|
||||
// face any instance of eve down the z-axis
|
||||
|
|
|
@ -61,8 +61,8 @@ Avatar::Avatar(bool isMine) {
|
|||
//_transmitterTimer = 0;
|
||||
_transmitterHz = 0.0;
|
||||
_transmitterPackets = 0;
|
||||
|
||||
initializeSkeleton();
|
||||
_speed = 0.0;
|
||||
_pelvisStandingHeight = 0.0f;
|
||||
|
||||
_TEST_bigSphereRadius = 0.3f;
|
||||
_TEST_bigSpherePosition = glm::vec3( 0.0f, _TEST_bigSphereRadius, 2.0f );
|
||||
|
@ -119,6 +119,8 @@ Avatar::Avatar(bool isMine) {
|
|||
_handHolding.velocity = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_handHolding.force = 10.0f;
|
||||
|
||||
initializeSkeleton();
|
||||
|
||||
if (iris_texture.size() == 0) {
|
||||
switchToResourcesParentIfRequired();
|
||||
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
|
||||
|
@ -129,7 +131,6 @@ Avatar::Avatar(bool isMine) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
Avatar::Avatar(const Avatar &otherAvatar) {
|
||||
|
||||
_velocity = otherAvatar._velocity;
|
||||
|
@ -200,6 +201,9 @@ Avatar::Avatar(const Avatar &otherAvatar) {
|
|||
_head.browAudioLift = otherAvatar._head.browAudioLift;
|
||||
_head.noise = otherAvatar._head.noise;
|
||||
|
||||
|
||||
initializeSkeleton();
|
||||
|
||||
if (iris_texture.size() == 0) {
|
||||
switchToResourcesParentIfRequired();
|
||||
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
|
||||
|
@ -306,30 +310,25 @@ void Avatar::simulate(float deltaTime) {
|
|||
{
|
||||
float closestDistance = 10000.0f;
|
||||
|
||||
AgentList * agentList = AgentList::getInstance();
|
||||
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_AVATAR ) )) {
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *otherAvatar = (Avatar *)agent->getLinkedData();
|
||||
|
||||
// check for collisions with other avatars and respond
|
||||
updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
otherAvatar->getBonePosition( AVATAR_BONE_PELVIS_SPINE ),
|
||||
0.2,
|
||||
0.2,
|
||||
updateAvatarCollisionDetectionAndResponse(otherAvatar->getPosition(),
|
||||
0.1,
|
||||
0.1,
|
||||
otherAvatar->getBodyUpDirection(),
|
||||
deltaTime
|
||||
);
|
||||
deltaTime);
|
||||
|
||||
// test other avatar hand position for proximity
|
||||
glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
|
||||
v -= otherAvatar->getBonePosition( AVATAR_BONE_RIGHT_HAND );
|
||||
|
||||
float distance = glm::length( v );
|
||||
if ( distance < _maxArmLength ) {
|
||||
if ( distance < _maxArmLength + _maxArmLength ) {
|
||||
|
||||
//if ( distance < closestDistance ) { // perhaps I don't need this if we want to allow multi-avatar interactions
|
||||
{
|
||||
|
@ -356,8 +355,7 @@ void Avatar::simulate(float deltaTime) {
|
|||
// Set the vector we send for hand position to other people to be our right hand
|
||||
setHandPosition(_bone[ AVATAR_BONE_RIGHT_HAND ].position);
|
||||
|
||||
}//if ( _isMine )
|
||||
|
||||
}
|
||||
|
||||
updateArmIKAndConstraints( deltaTime );
|
||||
|
||||
|
@ -365,30 +363,23 @@ void Avatar::simulate(float deltaTime) {
|
|||
_interactingOther = NULL;
|
||||
}
|
||||
|
||||
if ( usingBigSphereCollisionTest ) {
|
||||
|
||||
if (usingBigSphereCollisionTest) {
|
||||
// test for avatar collision response (using a big sphere :)
|
||||
updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
_TEST_bigSpherePosition,
|
||||
updateAvatarCollisionDetectionAndResponse(_TEST_bigSpherePosition,
|
||||
_TEST_bigSphereRadius,
|
||||
_TEST_bigSphereRadius,
|
||||
glm::vec3( 0.0, 1.0, 0.0 ),
|
||||
deltaTime
|
||||
);
|
||||
deltaTime);
|
||||
}
|
||||
|
||||
if ( AVATAR_GRAVITY ) {
|
||||
if ( _position.y > _bone[ AVATAR_BONE_RIGHT_FOOT ].radius * 2.0 ) {
|
||||
if ( _position.y > _pelvisStandingHeight + 0.01 ) {
|
||||
_velocity += glm::dvec3(getGravity(getPosition())) * ( 6.0 * deltaTime );
|
||||
}
|
||||
else {
|
||||
if ( _position.y < _bone[ AVATAR_BONE_RIGHT_FOOT ].radius ) {
|
||||
_position.y = _bone[ AVATAR_BONE_RIGHT_FOOT ].radius;
|
||||
} else if ( _position.y < _pelvisStandingHeight ) {
|
||||
_position.y = _pelvisStandingHeight;
|
||||
_velocity.y = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update body springs
|
||||
updateBodySprings( deltaTime );
|
||||
|
@ -424,17 +415,6 @@ void Avatar::simulate(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
float translationalSpeed = glm::length( _velocity );
|
||||
float rotationalSpeed = fabs( _bodyYawDelta );
|
||||
if ( translationalSpeed + rotationalSpeed > 0.2 )
|
||||
{
|
||||
_mode = AVATAR_MODE_WALKING;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mode = AVATAR_MODE_INTERACTING;
|
||||
}
|
||||
|
||||
// update body yaw by body yaw delta
|
||||
if (_isMine) {
|
||||
_bodyYaw += _bodyYawDelta * deltaTime;
|
||||
|
@ -548,8 +528,16 @@ void Avatar::simulate(float deltaTime) {
|
|||
const float AUDIO_AVERAGING_SECS = 0.05;
|
||||
_head.averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * _head.averageLoudness +
|
||||
(deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness;
|
||||
}
|
||||
|
||||
_speed = glm::length( _velocity );
|
||||
float rotationalSpeed = fabs( _bodyYawDelta );
|
||||
|
||||
if ( _speed + rotationalSpeed > 0.2 ) {
|
||||
_mode = AVATAR_MODE_WALKING;
|
||||
} else {
|
||||
_mode = AVATAR_MODE_INTERACTING;
|
||||
}
|
||||
}
|
||||
|
||||
float Avatar::getGirth() {
|
||||
return COLLISION_BODY_RADIUS;
|
||||
|
@ -559,32 +547,27 @@ float Avatar::getHeight() {
|
|||
return COLLISION_HEIGHT;
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 Avatar::getBodyUpDirection() {
|
||||
return _orientation.getUp();
|
||||
}
|
||||
|
||||
// This is a workspace for testing avatar body collision detection and response
|
||||
void Avatar::updateAvatarCollisionDetectionAndResponse
|
||||
( glm::vec3 collisionPosition, float collisionGirth, float collisionHeight, glm::vec3 collisionUpVector, float deltaTime ) {
|
||||
void Avatar::updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPosition,
|
||||
float collisionGirth,
|
||||
float collisionHeight,
|
||||
glm::vec3 collisionUpVector,
|
||||
float deltaTime) {
|
||||
|
||||
float myBodyApproximateBoundingRadius = 1.0f;
|
||||
glm::vec3 vectorFromMyBodyToBigSphere(_position - collisionPosition);
|
||||
bool jointCollision = false;
|
||||
|
||||
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
|
||||
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + collisionGirth )
|
||||
{
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++)
|
||||
{
|
||||
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + collisionGirth ) {
|
||||
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
|
||||
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - collisionPosition);
|
||||
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
|
||||
float combinedRadius = _bone[b].radius + collisionGirth;
|
||||
if ( distanceToBigSphereCenter < combinedRadius )
|
||||
{
|
||||
|
||||
if ( distanceToBigSphereCenter < combinedRadius ) {
|
||||
jointCollision = true;
|
||||
if (distanceToBigSphereCenter > 0.0)
|
||||
{
|
||||
if (distanceToBigSphereCenter > 0.0) {
|
||||
glm::vec3 directionVector = vectorFromJointToBigSphereCenter / distanceToBigSphereCenter;
|
||||
|
||||
float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius);
|
||||
|
@ -607,7 +590,7 @@ void Avatar::updateAvatarCollisionDetectionAndResponse
|
|||
}
|
||||
|
||||
void Avatar::render(bool lookingInMirror) {
|
||||
|
||||
/*
|
||||
// show avatar position
|
||||
glColor4f( 0.5f, 0.5f, 0.5f, 0.6 );
|
||||
glPushMatrix();
|
||||
|
@ -615,6 +598,7 @@ void Avatar::render(bool lookingInMirror) {
|
|||
glScalef( 0.03, 0.03, 0.03 );
|
||||
glutSolidSphere( 1, 10, 10 );
|
||||
glPopMatrix();
|
||||
*/
|
||||
|
||||
if ( usingBigSphereCollisionTest ) {
|
||||
|
||||
|
@ -851,7 +835,7 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
void Avatar::startHandMovement() {
|
||||
|
||||
|
@ -862,7 +846,7 @@ void Avatar::startHandMovement() {
|
|||
}
|
||||
|
||||
void Avatar::stopHandMovement() {
|
||||
//_usingBodySprings = false;
|
||||
//_usingBodySprings = false;
|
||||
}
|
||||
|
||||
void Avatar::setHandMovementValues( glm::vec3 handOffset ) {
|
||||
|
@ -919,7 +903,7 @@ void Avatar::initializeSkeleton() {
|
|||
_bone[ AVATAR_BONE_RIGHT_FOOT ].parent = AVATAR_BONE_RIGHT_SHIN;
|
||||
|
||||
// specify the default pose position
|
||||
_bone[ AVATAR_BONE_PELVIS_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.3, 0.0 );
|
||||
_bone[ AVATAR_BONE_PELVIS_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_bone[ AVATAR_BONE_MID_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.1, 0.0 );
|
||||
_bone[ AVATAR_BONE_CHEST_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 );
|
||||
_bone[ AVATAR_BONE_NECK ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 );
|
||||
|
@ -971,12 +955,19 @@ void Avatar::initializeSkeleton() {
|
|||
// calculate bone length
|
||||
calculateBoneLengths();
|
||||
|
||||
_pelvisStandingHeight =
|
||||
_bone[ AVATAR_BONE_PELVIS_SPINE ].length +
|
||||
_bone[ AVATAR_BONE_LEFT_THIGH ].length +
|
||||
_bone[ AVATAR_BONE_LEFT_SHIN ].length +
|
||||
_bone[ AVATAR_BONE_LEFT_FOOT ].length +
|
||||
_bone[ AVATAR_BONE_RIGHT_FOOT ].radius;
|
||||
|
||||
// generate world positions
|
||||
updateSkeleton();
|
||||
}
|
||||
|
||||
void Avatar::calculateBoneLengths() {
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
|
||||
_bone[b].length = glm::length( _bone[b].defaultPosePosition );
|
||||
}
|
||||
|
||||
|
@ -992,7 +983,7 @@ void Avatar::updateSkeleton() {
|
|||
_orientation.yaw( _bodyYaw );
|
||||
|
||||
// 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 ( _bone[b].parent == AVATAR_BONE_NULL ) {
|
||||
_bone[b].orientation.set( _orientation );
|
||||
_bone[b].position = _position;
|
||||
|
@ -1022,7 +1013,7 @@ void Avatar::updateSkeleton() {
|
|||
}
|
||||
|
||||
void Avatar::initializeBodySprings() {
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
|
||||
_bone[b].springyPosition = _bone[b].position;
|
||||
_bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
}
|
||||
|
@ -1030,7 +1021,7 @@ void Avatar::initializeBodySprings() {
|
|||
|
||||
|
||||
void Avatar::updateBodySprings( float deltaTime ) {
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
|
||||
glm::vec3 springVector( _bone[b].springyPosition );
|
||||
|
||||
if ( _bone[b].parent == AVATAR_BONE_NULL ) {
|
||||
|
@ -1069,49 +1060,15 @@ void Avatar::updateBodySprings( float deltaTime ) {
|
|||
}
|
||||
}
|
||||
|
||||
glm::vec3 Avatar::getHeadLookatDirection() {
|
||||
return glm::vec3
|
||||
(
|
||||
_orientation.getFront().x,
|
||||
_orientation.getFront().y,
|
||||
_orientation.getFront().z
|
||||
);
|
||||
}
|
||||
const glm::vec3& Avatar::getHeadPosition() const {
|
||||
|
||||
glm::vec3 Avatar::getHeadLookatDirectionUp() {
|
||||
return glm::vec3
|
||||
(
|
||||
_orientation.getUp().x,
|
||||
_orientation.getUp().y,
|
||||
_orientation.getUp().z
|
||||
);
|
||||
}
|
||||
|
||||
glm::vec3 Avatar::getHeadLookatDirectionRight() {
|
||||
return glm::vec3
|
||||
(
|
||||
_orientation.getRight().x,
|
||||
_orientation.getRight().y,
|
||||
_orientation.getRight().z
|
||||
);
|
||||
}
|
||||
|
||||
glm::vec3 Avatar::getHeadPosition() {
|
||||
|
||||
if ( _usingBodySprings ) {
|
||||
if (_usingBodySprings) {
|
||||
return _bone[ AVATAR_BONE_HEAD ].springyPosition;
|
||||
}
|
||||
|
||||
return _bone[ AVATAR_BONE_HEAD ].position;
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 Avatar::getBonePosition( AvatarBoneID b ) {
|
||||
return _bone[b].position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Avatar::updateHandMovement( float deltaTime ) {
|
||||
glm::vec3 transformedHandMovement;
|
||||
|
||||
|
@ -1170,7 +1127,7 @@ void Avatar::updateArmIKAndConstraints( float deltaTime ) {
|
|||
void Avatar::renderBody() {
|
||||
|
||||
// Render bone positions as spheres
|
||||
for (int b=0; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int b = 0; b < NUM_AVATAR_BONES; b++) {
|
||||
//renderBoneAsBlock( (AvatarBoneID)b);
|
||||
|
||||
//render bone orientation
|
||||
|
@ -1197,7 +1154,7 @@ void Avatar::renderBody() {
|
|||
glColor3f( 0.4f, 0.5f, 0.6f );
|
||||
glLineWidth(3.0);
|
||||
|
||||
for (int b=1; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int b = 1; b < NUM_AVATAR_BONES; b++) {
|
||||
if ( _bone[b].parent != AVATAR_BONE_NULL ) {
|
||||
glBegin( GL_LINE_STRIP );
|
||||
glVertex3fv( &_bone[ _bone[ b ].parent ].springyPosition.x );
|
||||
|
@ -1210,7 +1167,7 @@ void Avatar::renderBody() {
|
|||
glColor3fv( skinColor );
|
||||
glLineWidth(3.0);
|
||||
|
||||
for (int b=1; b<NUM_AVATAR_BONES; b++) {
|
||||
for (int b = 1; b < NUM_AVATAR_BONES; b++) {
|
||||
if ( _bone[b].parent != AVATAR_BONE_NULL ) {
|
||||
glBegin( GL_LINE_STRIP );
|
||||
glVertex3fv( &_bone[ _bone[ b ].parent ].position.x );
|
||||
|
@ -1223,12 +1180,9 @@ void Avatar::renderBody() {
|
|||
// if the hand is grasping, show it...
|
||||
if (( _usingBodySprings ) && ( _handState == 1 )) {
|
||||
glPushMatrix();
|
||||
glTranslatef
|
||||
(
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.x,
|
||||
glTranslatef(_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.x,
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.y,
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.z
|
||||
);
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].springyPosition.z);
|
||||
glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.4, 0.2 ); glutSolidSphere( 0.025f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
|
||||
|
@ -1299,7 +1253,6 @@ void Avatar::processTransmitterData(unsigned char* packetData, int numBytes) {
|
|||
glm::vec3 linVel(linX*linVelScale, linZ*linVelScale, -linY*linVelScale);
|
||||
addVelocity(linVel);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
// Find and return the gravity vector at my location
|
||||
|
@ -1316,4 +1269,3 @@ glm::vec3 Avatar::getGravity(glm::vec3 pos) {
|
|||
return glm::vec3(0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
const bool AVATAR_GRAVITY = true;
|
||||
const float DECAY = 0.1;
|
||||
const float THRUST_MAG = 10.0;
|
||||
const float YAW_MAG = 300.0;
|
||||
const float YAW_MAG = 500.0; //JJV - changed from 300.0;
|
||||
const float TEST_YAW_DECAY = 5.0;
|
||||
const float LIN_VEL_DECAY = 5.0;
|
||||
|
||||
|
@ -157,7 +157,7 @@ struct AvatarHead
|
|||
|
||||
|
||||
class Avatar : public AvatarData {
|
||||
public:
|
||||
public:
|
||||
Avatar(bool isMine);
|
||||
~Avatar();
|
||||
Avatar(const Avatar &otherAvatar);
|
||||
|
@ -178,12 +178,13 @@ class Avatar : public AvatarData {
|
|||
float getBodyYaw() {return _bodyYaw;};
|
||||
void addBodyYaw(float y) {_bodyYaw += y;};
|
||||
|
||||
glm::vec3 getHeadLookatDirection();
|
||||
glm::vec3 getHeadLookatDirectionUp();
|
||||
glm::vec3 getHeadLookatDirectionRight();
|
||||
glm::vec3 getHeadPosition();
|
||||
glm::vec3 getBonePosition( AvatarBoneID b );
|
||||
glm::vec3 getBodyUpDirection();
|
||||
const glm::vec3& getHeadLookatDirection() const { return _orientation.getFront(); };
|
||||
const glm::vec3& getHeadLookatDirectionUp() const { return _orientation.getUp(); };
|
||||
const glm::vec3& getHeadLookatDirectionRight() const { return _orientation.getRight(); };
|
||||
const glm::vec3& getHeadPosition() const ;
|
||||
const glm::vec3& getBonePosition(AvatarBoneID b) const { return _bone[b].position; };
|
||||
const glm::vec3& getBodyUpDirection() const { return _orientation.getUp(); };
|
||||
float getSpeed() const { return _speed; };
|
||||
float getGirth();
|
||||
float getHeight();
|
||||
|
||||
|
@ -221,7 +222,7 @@ class Avatar : public AvatarData {
|
|||
// Find out what the local gravity vector is at this location
|
||||
glm::vec3 getGravity(glm::vec3 pos);
|
||||
|
||||
private:
|
||||
private:
|
||||
AvatarHead _head;
|
||||
bool _isMine;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
|
@ -238,6 +239,7 @@ class Avatar : public AvatarData {
|
|||
AvatarHandHolding _handHolding;
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
float _speed;
|
||||
float _maxArmLength;
|
||||
Orientation _orientation;
|
||||
int _driveKeys[MAX_DRIVE_KEYS];
|
||||
|
@ -249,8 +251,8 @@ class Avatar : public AvatarData {
|
|||
int _transmitterPackets;
|
||||
Avatar* _interactingOther;
|
||||
bool _interactingOtherIsNearby;
|
||||
float _pelvisStandingHeight;
|
||||
|
||||
// private methods...
|
||||
void initializeSkeleton();
|
||||
void updateSkeleton();
|
||||
void initializeBodySprings();
|
||||
|
@ -258,14 +260,11 @@ class Avatar : public AvatarData {
|
|||
void calculateBoneLengths();
|
||||
void readSensors();
|
||||
void renderBoneAsBlock( AvatarBoneID b );
|
||||
void updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
glm::vec3 collisionPosition,
|
||||
void updateAvatarCollisionDetectionAndResponse(glm::vec3 collisionPosition,
|
||||
float collisionGirth,
|
||||
float collisionHeight,
|
||||
glm::vec3 collisionUpVector,
|
||||
float deltaTime
|
||||
);
|
||||
float deltaTime);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -11,15 +11,18 @@
|
|||
#include "Camera.h"
|
||||
|
||||
Camera::Camera() {
|
||||
_frustumNeedsReshape = false;
|
||||
_mode = CAMERA_MODE_THIRD_PERSON;
|
||||
_tightness = DEFAULT_CAMERA_TIGHTNESS;
|
||||
_tightness = 10.0; // default
|
||||
_fieldOfView = 60.0; // default
|
||||
_nearClip = 0.08; // default
|
||||
_farClip = 50.0; // default
|
||||
_modeShift = 0.0;
|
||||
_yaw = 0.0;
|
||||
_pitch = 0.0;
|
||||
_roll = 0.0;
|
||||
_up = 0.0;
|
||||
_upShift = 0.0;
|
||||
_rightShift = 0.0;
|
||||
_distance = 0.0;
|
||||
_idealYaw = 0.0;
|
||||
_targetPosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
|
@ -29,45 +32,68 @@ Camera::Camera() {
|
|||
}
|
||||
|
||||
|
||||
void Camera::update( float deltaTime ) {
|
||||
|
||||
void Camera::update( float deltaTime )
|
||||
{
|
||||
//----------------------------------------
|
||||
// generate the ortho-normals for the orientation based on the Euler angles
|
||||
_orientation.setToIdentity();
|
||||
_orientation.yaw ( _yaw );
|
||||
_orientation.pitch( _pitch );
|
||||
_orientation.roll ( _roll );
|
||||
|
||||
if ( _mode == CAMERA_MODE_NULL ) {
|
||||
_modeShift = 0.0;
|
||||
} else {
|
||||
// use iterative forces to keep the camera at the desired position and angle
|
||||
updateFollowMode( deltaTime );
|
||||
|
||||
if ( _modeShift < 1.0f ) {
|
||||
_modeShift += MODE_SHIFT_RATE * deltaTime;
|
||||
if ( _modeShift > 1.0f ) {
|
||||
_modeShift = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// use iterative forces to keep the camera at the desired position and angle
|
||||
void Camera::updateFollowMode( float deltaTime ) {
|
||||
// derive t from tightness
|
||||
//----------------------------------------
|
||||
float t = _tightness * deltaTime;
|
||||
|
||||
if ( t > 1.0 ){
|
||||
if ( t > 1.0 ) {
|
||||
t = 1.0;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// update _yaw (before position!)
|
||||
//----------------------------------------
|
||||
_yaw += ( _idealYaw - _yaw ) * t;
|
||||
_orientation.yaw ( _yaw );
|
||||
|
||||
float radian = ( _yaw / 180.0 ) * PIE;
|
||||
|
||||
//----------------------------------------
|
||||
// update _position
|
||||
//----------------------------------------
|
||||
//these need to be checked to make sure they correspond to the coordinate system.
|
||||
//these need to be checked to make sure they correspond to the correct coordinate system.
|
||||
double x = _distance * -sin( radian );
|
||||
double z = _distance * cos( radian );
|
||||
double y = _up;
|
||||
double y = _upShift;
|
||||
|
||||
_idealPosition = _targetPosition + glm::vec3( x, y, z );
|
||||
//_idealPosition += _orientation.getRight() * _rightShift;
|
||||
//_idealPosition += _orientation.getUp () * _upShift;
|
||||
|
||||
// pull position towards ideal position
|
||||
_position += ( _idealPosition - _position ) * t;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// generate the ortho-normals for the orientation based on the Euler angles
|
||||
//------------------------------------------------------------------------------
|
||||
_orientation.setToIdentity();
|
||||
|
||||
_orientation.yaw ( _yaw );
|
||||
_orientation.pitch ( _pitch );
|
||||
_orientation.roll ( _roll );
|
||||
|
||||
//printLog( "orientation.front = %f, %f, %f\n", _orientation.front.x, _orientation.front.y, _orientation.front.z );
|
||||
}
|
||||
|
||||
|
||||
// call to find out if the view frustum needs to be reshaped
|
||||
bool Camera::getFrustumNeedsReshape() {
|
||||
return _frustumNeedsReshape;
|
||||
}
|
||||
|
||||
// call this after reshaping the view frustum
|
||||
void Camera::setFrustumWasReshaped() {
|
||||
_frustumNeedsReshape = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
enum CameraMode
|
||||
{
|
||||
CAMERA_MODE_NULL = -1,
|
||||
CAMERA_MODE_FIRST_PERSON,
|
||||
CAMERA_MODE_THIRD_PERSON,
|
||||
CAMERA_MODE_FIRST_PERSON,
|
||||
CAMERA_MODE_MY_OWN_FACE,
|
||||
NUM_CAMERA_MODES
|
||||
};
|
||||
|
||||
static const float DEFAULT_CAMERA_TIGHTNESS = 10.0f;
|
||||
const float MODE_SHIFT_RATE = 2.0f;
|
||||
|
||||
class Camera
|
||||
{
|
||||
|
@ -29,35 +29,42 @@ public:
|
|||
|
||||
void update( float deltaTime );
|
||||
|
||||
void setMode ( CameraMode m ) { _mode = m; }
|
||||
void setYaw ( float y ) { _idealYaw = y; }
|
||||
void setMode ( CameraMode m ) { _mode = m; _modeShift = 0.0f; }
|
||||
void setYaw ( float y ) { _yaw = y; }
|
||||
void setPitch ( float p ) { _pitch = p; }
|
||||
void setRoll ( float r ) { _roll = r; }
|
||||
void setUp ( float u ) { _up = u; }
|
||||
void setUpShift ( float u ) { _upShift = u; }
|
||||
void setRightShift ( float r ) { _rightShift = r; }
|
||||
void setDistance ( float d ) { _distance = d; }
|
||||
void setTargetPosition ( glm::vec3 t ) { _targetPosition = t; };
|
||||
void setPosition ( glm::vec3 p ) { _position = p; };
|
||||
void setTargetPosition( glm::vec3 t ) { _targetPosition = t; }
|
||||
void setTargetYaw ( float y ) { _idealYaw = y; }
|
||||
void setPosition ( glm::vec3 p ) { _position = p; }
|
||||
void setOrientation ( Orientation o ) { _orientation.set(o); }
|
||||
void setTightness ( float t ) { _tightness = t; }
|
||||
void setFieldOfView ( float f ) { _fieldOfView = f; }
|
||||
void setAspectRatio ( float a ) { _aspectRatio = a; }
|
||||
void setNearClip ( float n ) { _nearClip = n; }
|
||||
void setFarClip ( float f ) { _farClip = f; }
|
||||
void setFieldOfView ( float f ) { _fieldOfView = f; _frustumNeedsReshape = true; }
|
||||
void setAspectRatio ( float a ) { _aspectRatio = a; _frustumNeedsReshape = true; }
|
||||
void setNearClip ( float n ) { _nearClip = n; _frustumNeedsReshape = true; }
|
||||
void setFarClip ( float f ) { _farClip = f; _frustumNeedsReshape = true; }
|
||||
|
||||
float getYaw () { return _yaw; }
|
||||
float getPitch () { return _pitch; }
|
||||
float getRoll () { return _roll; }
|
||||
glm::vec3 getPosition () { return _position; }
|
||||
Orientation getOrientation () { return _orientation; }
|
||||
Orientation getOrientation() { return _orientation; }
|
||||
CameraMode getMode () { return _mode; }
|
||||
float getFieldOfView () { return _fieldOfView; }
|
||||
float getAspectRatio () { return _aspectRatio; }
|
||||
float getModeShift () { return _modeShift; }
|
||||
float getFieldOfView() { return _fieldOfView; }
|
||||
float getAspectRatio() { return _aspectRatio; }
|
||||
float getNearClip () { return _nearClip; }
|
||||
float getFarClip () { return _farClip; }
|
||||
bool getFrustumNeedsReshape(); // call to find out if the view frustum needs to be reshaped
|
||||
void setFrustumWasReshaped(); // call this after reshaping the view frustum.
|
||||
|
||||
private:
|
||||
|
||||
CameraMode _mode;
|
||||
float _modeShift; // 0.0 to 1.0
|
||||
bool _frustumNeedsReshape;
|
||||
glm::vec3 _position;
|
||||
glm::vec3 _idealPosition;
|
||||
glm::vec3 _targetPosition;
|
||||
|
@ -68,11 +75,14 @@ private:
|
|||
float _yaw;
|
||||
float _pitch;
|
||||
float _roll;
|
||||
float _up;
|
||||
float _upShift;
|
||||
float _rightShift;
|
||||
float _idealYaw;
|
||||
float _distance;
|
||||
float _tightness;
|
||||
Orientation _orientation;
|
||||
|
||||
void updateFollowMode( float deltaTime );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -278,9 +278,9 @@ void drawGroundPlaneGrid( float size, int resolution )
|
|||
|
||||
|
||||
void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) {
|
||||
glm::vec3 pRight = position + orientation.right * size;
|
||||
glm::vec3 pUp = position + orientation.up * size;
|
||||
glm::vec3 pFront = position + orientation.front * size;
|
||||
glm::vec3 pRight = position + orientation.getRight() * size;
|
||||
glm::vec3 pUp = position + orientation.getUp() * size;
|
||||
glm::vec3 pFront = position + orientation.getFront() * size;
|
||||
|
||||
glColor3f( 1.0f, 0.0f, 0.0f );
|
||||
glBegin( GL_LINE_STRIP );
|
||||
|
|
|
@ -244,8 +244,6 @@ void updateHandController( int x, int y ) {
|
|||
handController.startX = WIDTH / 2;
|
||||
handController.startY = HEIGHT / 2;
|
||||
handController.envelope = 0.0;
|
||||
//prototype
|
||||
//myAvatar.stopHandMovement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -804,35 +802,67 @@ void display(void)
|
|||
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
|
||||
glMateriali(GL_FRONT, GL_SHININESS, 96);
|
||||
|
||||
//--------------------------------------------------------
|
||||
// camera settings
|
||||
//--------------------------------------------------------
|
||||
if ( ::lookingInMirror ) {
|
||||
//-----------------------------------------------
|
||||
// set the camera to looking at my own face
|
||||
//-----------------------------------------------
|
||||
myCamera.setTargetPosition ( myAvatar.getHeadPosition() );
|
||||
myCamera.setYaw ( - myAvatar.getBodyYaw() );
|
||||
myCamera.setTargetYaw ( - myAvatar.getBodyYaw() );
|
||||
myCamera.setPitch ( 0.0 );
|
||||
myCamera.setRoll ( 0.0 );
|
||||
myCamera.setUp ( 0.0 );
|
||||
myCamera.setUpShift ( 0.0 );
|
||||
myCamera.setDistance ( 0.2 );
|
||||
myCamera.setTightness ( 100.0f );
|
||||
myCamera.update ( 1.f/FPS );
|
||||
} else {
|
||||
//----------------------------------------------------
|
||||
// set the camera to third-person view behind my av
|
||||
//----------------------------------------------------
|
||||
myCamera.setTargetPosition ( myAvatar.getPosition() );
|
||||
myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() );
|
||||
myCamera.setPitch ( 0.0 ); // temporarily, this must be 0.0 or else bad juju
|
||||
myCamera.setRoll ( 0.0 );
|
||||
myCamera.setUp ( 0.45 );
|
||||
myCamera.setDistance ( 1.0 );
|
||||
myCamera.setTightness ( 8.0f );
|
||||
myCamera.update ( 1.f/FPS);
|
||||
|
||||
// float firstPersonPitch = 20.0f;
|
||||
// float firstPersonUpShift = 0.1f;
|
||||
// float firstPersonDistance = 0.0f;
|
||||
// float firstPersonT ightness = 100.0f;
|
||||
|
||||
float thirdPersonPitch = 0.0f;
|
||||
float thirdPersonUpShift = -0.1f;
|
||||
float thirdPersonDistance = 1.f;
|
||||
float thirdPersonTightness = 8.0f;
|
||||
|
||||
myCamera.setPitch (thirdPersonPitch );
|
||||
myCamera.setUpShift (thirdPersonUpShift );
|
||||
myCamera.setDistance (thirdPersonDistance );
|
||||
myCamera.setTightness(thirdPersonTightness);
|
||||
|
||||
/*
|
||||
if ( myAvatar.getSpeed() < 0.02 ) {
|
||||
if (myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) {
|
||||
myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
}
|
||||
|
||||
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
|
||||
|
||||
myCamera.setPitch ( thirdPersonPitch + myCamera.getModeShift() * ( firstPersonPitch - thirdPersonPitch ));
|
||||
myCamera.setUpShift ( thirdPersonUpShift + myCamera.getModeShift() * ( firstPersonUpShift - thirdPersonUpShift ));
|
||||
myCamera.setDistance ( thirdPersonDistance + myCamera.getModeShift() * ( firstPersonDistance - thirdPersonDistance ));
|
||||
myCamera.setTightness ( thirdPersonTightness + myCamera.getModeShift() * ( firstPersonTightness - thirdPersonTightness ));
|
||||
} else {
|
||||
if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON ) {
|
||||
myCamera.setMode(CAMERA_MODE_THIRD_PERSON);
|
||||
}
|
||||
|
||||
printf( "myCamera.getModeShift() = %f\n", myCamera.getModeShift());
|
||||
|
||||
myCamera.setPitch ( firstPersonPitch + myCamera.getModeShift() * ( thirdPersonPitch - firstPersonPitch ));
|
||||
myCamera.setUpShift ( firstPersonUpShift + myCamera.getModeShift() * ( thirdPersonUpShift - firstPersonUpShift ));
|
||||
myCamera.setDistance ( firstPersonDistance + myCamera.getModeShift() * ( thirdPersonDistance - firstPersonDistance ));
|
||||
myCamera.setTightness ( firstPersonTightness + myCamera.getModeShift() * ( thirdPersonTightness - firstPersonTightness ));
|
||||
}
|
||||
*/
|
||||
|
||||
myCamera.setTargetPosition( myAvatar.getHeadPosition() );
|
||||
myCamera.setTargetYaw ( 180.0 - myAvatar.getBodyYaw() );
|
||||
myCamera.setRoll ( 0.0 );
|
||||
}
|
||||
|
||||
// important...
|
||||
myCamera.update( 1.f/FPS );
|
||||
|
||||
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
||||
// main camera, vs, an alternate camera. The alternate camera we support right now
|
||||
// is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism
|
||||
|
@ -847,10 +877,10 @@ void display(void)
|
|||
if (::viewFrustumFromOffset && ::frustumOn) {
|
||||
|
||||
// set the camera to third-person view but offset so we can see the frustum
|
||||
viewFrustumOffsetCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() + ::viewFrustumOffsetYaw );
|
||||
viewFrustumOffsetCamera.setTargetYaw( 180.0 - myAvatar.getBodyYaw() + ::viewFrustumOffsetYaw );
|
||||
viewFrustumOffsetCamera.setPitch ( ::viewFrustumOffsetPitch );
|
||||
viewFrustumOffsetCamera.setRoll ( ::viewFrustumOffsetRoll );
|
||||
viewFrustumOffsetCamera.setUp ( ::viewFrustumOffsetUp );
|
||||
viewFrustumOffsetCamera.setUpShift ( ::viewFrustumOffsetUp );
|
||||
viewFrustumOffsetCamera.setDistance ( ::viewFrustumOffsetDistance );
|
||||
viewFrustumOffsetCamera.update(1.f/FPS);
|
||||
whichCamera = viewFrustumOffsetCamera;
|
||||
|
@ -868,10 +898,8 @@ void display(void)
|
|||
if (::starsOn) {
|
||||
// should be the first rendering pass - w/o depth buffer / lighting
|
||||
|
||||
|
||||
// finally render the starfield
|
||||
stars.render(whichCamera.getFieldOfView(), aspectRatio, whichCamera.getNearClip());
|
||||
|
||||
}
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
|
@ -913,10 +941,8 @@ void display(void)
|
|||
if (displayField) field.render();
|
||||
|
||||
// Render avatars of other agents
|
||||
AgentList *agentList = AgentList::getInstance();
|
||||
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
|
||||
agent != agentList->getAgents().end();
|
||||
agent++) {
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->render(0);
|
||||
|
@ -991,12 +1017,13 @@ void display(void)
|
|||
glPointSize(1.0f);
|
||||
char agents[100];
|
||||
|
||||
int totalAgents = AgentList::getInstance()->getAgents().size();
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
int totalAvatars = 0, totalServers = 0;
|
||||
for (int i = 0; i < totalAgents; i++) {
|
||||
(AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_AVATAR)
|
||||
? totalAvatars++ : totalServers++;
|
||||
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
agent->getType() == AGENT_TYPE_AVATAR ? totalAvatars++ : totalServers++;
|
||||
}
|
||||
|
||||
sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars);
|
||||
drawtext(WIDTH-150,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0);
|
||||
|
||||
|
@ -1534,11 +1561,9 @@ void idle(void) {
|
|||
updateAvatar(deltaTime);
|
||||
|
||||
//loop through all the other avatars and simulate them...
|
||||
AgentList * agentList = AgentList::getInstance();
|
||||
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++)
|
||||
{
|
||||
if (agent->getLinkedData() != NULL)
|
||||
{
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
if (agent->getLinkedData() != NULL) {
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->simulate(deltaTime);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ private:
|
|||
float _pitch;
|
||||
float _roll;
|
||||
|
||||
glm::vec3 right;
|
||||
glm::vec3 up;
|
||||
glm::vec3 front;
|
||||
|
||||
void update(); // actually updates the vectors from yaw, pitch, roll
|
||||
|
||||
public:
|
||||
|
@ -41,13 +45,9 @@ public:
|
|||
void set( Orientation );
|
||||
void setToIdentity();
|
||||
|
||||
glm::vec3 right;
|
||||
glm::vec3 up;
|
||||
glm::vec3 front;
|
||||
|
||||
glm::vec3 getRight() { return right; }
|
||||
glm::vec3 getUp() { return up; }
|
||||
glm::vec3 getFront() { return front; }
|
||||
const glm::vec3& getRight() const { return right; }
|
||||
const glm::vec3& getUp() const { return up; }
|
||||
const glm::vec3& getFront() const { return front; }
|
||||
|
||||
void setRightUpFront( const glm::vec3 &, const glm::vec3 &, const glm::vec3 & );
|
||||
|
||||
|
|
|
@ -22,7 +22,19 @@
|
|||
|
||||
using shared_lib::printLog;
|
||||
|
||||
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) {
|
||||
int unpackAgentId(unsigned char *packedData, uint16_t *agentId) {
|
||||
memcpy(agentId, packedData, sizeof(uint16_t));
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
int packAgentId(unsigned char *packStore, uint16_t agentId) {
|
||||
memcpy(packStore, &agentId, sizeof(uint16_t));
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) :
|
||||
_isAlive(true)
|
||||
{
|
||||
if (agentPublicSocket != NULL) {
|
||||
publicSocket = new sockaddr;
|
||||
memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr));
|
||||
|
@ -46,12 +58,11 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent
|
|||
activeSocket = NULL;
|
||||
linkedData = NULL;
|
||||
_bytesReceivedMovingAverage = NULL;
|
||||
|
||||
deleteMutex = new pthread_mutex_t;
|
||||
pthread_mutex_init(deleteMutex, NULL);
|
||||
}
|
||||
|
||||
Agent::Agent(const Agent &otherAgent) {
|
||||
_isAlive = otherAgent._isAlive;
|
||||
|
||||
if (otherAgent.publicSocket != NULL) {
|
||||
publicSocket = new sockaddr;
|
||||
memcpy(publicSocket, otherAgent.publicSocket, sizeof(sockaddr));
|
||||
|
@ -92,9 +103,6 @@ Agent::Agent(const Agent &otherAgent) {
|
|||
} else {
|
||||
_bytesReceivedMovingAverage = NULL;
|
||||
}
|
||||
|
||||
deleteMutex = new pthread_mutex_t;
|
||||
pthread_mutex_init(deleteMutex, NULL);
|
||||
}
|
||||
|
||||
Agent& Agent::operator=(Agent otherAgent) {
|
||||
|
@ -105,6 +113,7 @@ Agent& Agent::operator=(Agent otherAgent) {
|
|||
void Agent::swap(Agent &first, Agent &second) {
|
||||
using std::swap;
|
||||
|
||||
swap(first._isAlive, second._isAlive);
|
||||
swap(first.publicSocket, second.publicSocket);
|
||||
swap(first.localSocket, second.localSocket);
|
||||
swap(first.activeSocket, second.activeSocket);
|
||||
|
@ -114,13 +123,9 @@ void Agent::swap(Agent &first, Agent &second) {
|
|||
swap(first.firstRecvTimeUsecs, second.firstRecvTimeUsecs);
|
||||
swap(first.lastRecvTimeUsecs, second.lastRecvTimeUsecs);
|
||||
swap(first._bytesReceivedMovingAverage, second._bytesReceivedMovingAverage);
|
||||
swap(first.deleteMutex, second.deleteMutex);
|
||||
}
|
||||
|
||||
Agent::~Agent() {
|
||||
// the deleteMutex isn't destroyed here
|
||||
// that's handled by the agent list silent agent removal thread
|
||||
|
||||
delete publicSocket;
|
||||
delete localSocket;
|
||||
delete linkedData;
|
||||
|
|
|
@ -31,8 +31,6 @@ public:
|
|||
|
||||
bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType);
|
||||
|
||||
pthread_mutex_t *deleteMutex;
|
||||
|
||||
char getType() const;
|
||||
const char* getTypeName() const;
|
||||
void setType(char newType);
|
||||
|
@ -58,6 +56,9 @@ public:
|
|||
AgentData* getLinkedData();
|
||||
void setLinkedData(AgentData *newData);
|
||||
|
||||
bool isAlive() const { return _isAlive; };
|
||||
void setAlive(bool isAlive) { _isAlive = isAlive; };
|
||||
|
||||
void recordBytesReceived(int bytesReceived);
|
||||
float getAverageKilobitsPerSecond();
|
||||
float getAveragePacketsPerSecond();
|
||||
|
@ -73,9 +74,11 @@ private:
|
|||
double lastRecvTimeUsecs;
|
||||
SimpleMovingAverage* _bytesReceivedMovingAverage;
|
||||
AgentData* linkedData;
|
||||
|
||||
bool _isAlive;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Agent* agent);
|
||||
|
||||
int unpackAgentId(unsigned char *packedData, uint16_t *agentId);
|
||||
int packAgentId(unsigned char *packStore, uint16_t agentId);
|
||||
|
||||
#endif /* defined(__hifi__Agent__) */
|
||||
|
|
|
@ -37,7 +37,6 @@ const int DOMAINSERVER_PORT = 40102;
|
|||
bool silentAgentThreadStopFlag = false;
|
||||
bool domainServerCheckinStopFlag = false;
|
||||
bool pingUnknownAgentThreadStopFlag = false;
|
||||
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
AgentList* AgentList::_sharedInstance = NULL;
|
||||
|
||||
|
@ -59,11 +58,15 @@ AgentList* AgentList::getInstance() {
|
|||
return _sharedInstance;
|
||||
}
|
||||
|
||||
AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) :
|
||||
_agentBuckets(),
|
||||
_numAgents(0),
|
||||
agentSocket(newSocketListenPort),
|
||||
ownerType(newOwnerType),
|
||||
socketListenPort(newSocketListenPort),
|
||||
lastAgentId(0)
|
||||
{
|
||||
|
||||
AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : agentSocket(newSocketListenPort) {
|
||||
ownerType = newOwnerType;
|
||||
socketListenPort = newSocketListenPort;
|
||||
lastAgentId = 0;
|
||||
}
|
||||
|
||||
AgentList::~AgentList() {
|
||||
|
@ -73,10 +76,6 @@ AgentList::~AgentList() {
|
|||
stopPingUnknownAgentsThread();
|
||||
}
|
||||
|
||||
std::vector<Agent>& AgentList::getAgents() {
|
||||
return agents;
|
||||
}
|
||||
|
||||
UDPSocket& AgentList::getAgentSocket() {
|
||||
return agentSocket;
|
||||
}
|
||||
|
@ -108,10 +107,9 @@ void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetD
|
|||
|
||||
void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes) {
|
||||
// find the avatar mixer in our agent list and update the lastRecvTime from it
|
||||
int bulkSendAgentIndex = indexOfMatchingAgent(senderAddress);
|
||||
Agent* bulkSendAgent = agentWithAddress(senderAddress);
|
||||
|
||||
if (bulkSendAgentIndex >= 0) {
|
||||
Agent *bulkSendAgent = &agents[bulkSendAgentIndex];
|
||||
if (bulkSendAgent) {
|
||||
bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow());
|
||||
bulkSendAgent->recordBytesReceived(numTotalBytes);
|
||||
}
|
||||
|
@ -128,17 +126,18 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
|
|||
currentPosition += unpackAgentId(currentPosition, &agentID);
|
||||
memcpy(packetHolder + 1, currentPosition, numTotalBytes - (currentPosition - startPosition));
|
||||
|
||||
int matchingAgentIndex = indexOfMatchingAgent(agentID);
|
||||
Agent* matchingAgent = agentWithID(agentID);
|
||||
|
||||
if (matchingAgentIndex < 0) {
|
||||
if (!matchingAgent) {
|
||||
// we're missing this agent, we need to add it to the list
|
||||
addOrUpdateAgent(NULL, NULL, AGENT_TYPE_AVATAR, agentID);
|
||||
|
||||
// theoretically if we can lock the vector we could assume this is size - 1
|
||||
matchingAgentIndex = indexOfMatchingAgent(agentID);
|
||||
// TODO: this is a really stupid way to do this
|
||||
// Add a reverse iterator and go from the end of the list
|
||||
matchingAgent = agentWithID(agentID);
|
||||
}
|
||||
|
||||
currentPosition += updateAgentWithData(&agents[matchingAgentIndex],
|
||||
currentPosition += updateAgentWithData(matchingAgent,
|
||||
packetHolder,
|
||||
numTotalBytes - (currentPosition - startPosition));
|
||||
}
|
||||
|
@ -146,10 +145,10 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac
|
|||
|
||||
int AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) {
|
||||
// find the agent by the sockaddr
|
||||
int agentIndex = indexOfMatchingAgent(senderAddress);
|
||||
Agent* matchingAgent = agentWithAddress(senderAddress);
|
||||
|
||||
if (agentIndex != -1) {
|
||||
return updateAgentWithData(&agents[agentIndex], packetData, dataBytes);
|
||||
if (matchingAgent) {
|
||||
return updateAgentWithData(matchingAgent, packetData, dataBytes);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,24 +170,24 @@ int AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int
|
|||
return agent->getLinkedData()->parseData(packetData, dataBytes);
|
||||
}
|
||||
|
||||
int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
Agent* AgentList::agentWithAddress(sockaddr *senderAddress) {
|
||||
for(AgentList::iterator agent = begin(); agent != end(); agent++) {
|
||||
if (agent->getActiveSocket() != NULL && socketMatch(agent->getActiveSocket(), senderAddress)) {
|
||||
return agent - agents.begin();
|
||||
return &(*agent);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int AgentList::indexOfMatchingAgent(uint16_t agentID) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
Agent* AgentList::agentWithID(uint16_t agentID) {
|
||||
for(AgentList::iterator agent = begin(); agent != end(); agent++) {
|
||||
if (agent->getAgentId() == agentID) {
|
||||
return agent - agents.begin();
|
||||
return &(*agent);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint16_t AgentList::getLastAgentId() {
|
||||
|
@ -227,45 +226,38 @@ int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
|||
}
|
||||
|
||||
bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId) {
|
||||
std::vector<Agent>::iterator agent;
|
||||
AgentList::iterator agent = end();
|
||||
|
||||
if (publicSocket != NULL) {
|
||||
for (agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
for (agent = begin(); agent != end(); agent++) {
|
||||
if (agent->matches(publicSocket, localSocket, agentType)) {
|
||||
// we already have this agent, stop checking
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
agent = agents.end();
|
||||
}
|
||||
|
||||
if (agent == agents.end()) {
|
||||
if (agent == end()) {
|
||||
// we didn't have this agent, so add them
|
||||
Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId);
|
||||
Agent* newAgent = new Agent(publicSocket, localSocket, agentType, agentId);
|
||||
|
||||
if (socketMatch(publicSocket, localSocket)) {
|
||||
// likely debugging scenario with two agents on local network
|
||||
// set the agent active right away
|
||||
newAgent.activatePublicSocket();
|
||||
newAgent->activatePublicSocket();
|
||||
}
|
||||
|
||||
if (newAgent.getType() == AGENT_TYPE_AUDIO_MIXER && audioMixerSocketUpdate != NULL) {
|
||||
if (newAgent->getType() == AGENT_TYPE_AUDIO_MIXER && audioMixerSocketUpdate != NULL) {
|
||||
// this is an audio mixer
|
||||
// for now that means we need to tell the audio class
|
||||
// to use the local socket information the domain server gave us
|
||||
sockaddr_in *publicSocketIn = (sockaddr_in *)publicSocket;
|
||||
audioMixerSocketUpdate(publicSocketIn->sin_addr.s_addr, publicSocketIn->sin_port);
|
||||
} else if (newAgent.getType() == AGENT_TYPE_VOXEL) {
|
||||
newAgent.activatePublicSocket();
|
||||
} else if (newAgent->getType() == AGENT_TYPE_VOXEL) {
|
||||
newAgent->activatePublicSocket();
|
||||
}
|
||||
|
||||
printLog("Added agent - ");
|
||||
Agent::printLog(newAgent);
|
||||
|
||||
pthread_mutex_lock(&vectorChangeMutex);
|
||||
agents.push_back(newAgent);
|
||||
pthread_mutex_unlock(&vectorChangeMutex);
|
||||
addAgentToList(newAgent);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
|
@ -281,8 +273,24 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
|
|||
}
|
||||
}
|
||||
|
||||
void AgentList::addAgentToList(Agent* newAgent) {
|
||||
// find the correct array to add this agent to
|
||||
int bucketIndex = _numAgents / AGENTS_PER_BUCKET;
|
||||
|
||||
if (!_agentBuckets[bucketIndex]) {
|
||||
_agentBuckets[bucketIndex] = new Agent*[AGENTS_PER_BUCKET]();
|
||||
}
|
||||
|
||||
_agentBuckets[bucketIndex][_numAgents % AGENTS_PER_BUCKET] = newAgent;
|
||||
|
||||
++_numAgents;
|
||||
|
||||
printLog("Added agent - ");
|
||||
Agent::printLog(*newAgent);
|
||||
}
|
||||
|
||||
void AgentList::broadcastToAgents(unsigned char *broadcastData, size_t dataBytes, const char* agentTypes, int numAgentTypes) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
for(AgentList::iterator agent = begin(); agent != end(); agent++) {
|
||||
// only send to the AgentTypes we are asked to send to.
|
||||
if (agent->getActiveSocket() != NULL && memchr(agentTypes, agent->getType(), numAgentTypes)) {
|
||||
// we know which socket is good for this agent, send there
|
||||
|
@ -292,7 +300,7 @@ void AgentList::broadcastToAgents(unsigned char *broadcastData, size_t dataBytes
|
|||
}
|
||||
|
||||
void AgentList::handlePingReply(sockaddr *agentAddress) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
for(AgentList::iterator agent = begin(); agent != end(); agent++) {
|
||||
// check both the public and local addresses for each agent to see if we find a match
|
||||
// prioritize the private address so that we prune erroneous local matches
|
||||
if (socketMatch(agent->getPublicSocket(), agentAddress)) {
|
||||
|
@ -307,9 +315,9 @@ void AgentList::handlePingReply(sockaddr *agentAddress) {
|
|||
|
||||
Agent* AgentList::soloAgentOfType(char agentType) {
|
||||
if (memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES)) != NULL) {
|
||||
for(std::vector<Agent>::iterator agent = agents.begin(); agent != agents.end(); agent++) {
|
||||
for(AgentList::iterator agent = begin(); agent != end(); agent++) {
|
||||
if (agent->getType() == agentType) {
|
||||
return &*agent;
|
||||
return &(*agent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -319,7 +327,7 @@ Agent* AgentList::soloAgentOfType(char agentType) {
|
|||
|
||||
void *pingUnknownAgents(void *args) {
|
||||
|
||||
AgentList *agentList = (AgentList *)args;
|
||||
AgentList* agentList = (AgentList*) args;
|
||||
const int PING_INTERVAL_USECS = 1 * 1000000;
|
||||
|
||||
timeval lastSend;
|
||||
|
@ -327,8 +335,8 @@ void *pingUnknownAgents(void *args) {
|
|||
while (!pingUnknownAgentThreadStopFlag) {
|
||||
gettimeofday(&lastSend, NULL);
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agentList->getAgents().begin();
|
||||
agent != agentList->getAgents().end();
|
||||
for(AgentList::iterator agent = agentList->begin();
|
||||
agent != agentList->end();
|
||||
agent++) {
|
||||
if (agent->getActiveSocket() == NULL
|
||||
&& (agent->getPublicSocket() != NULL && agent->getLocalSocket() != NULL)) {
|
||||
|
@ -359,33 +367,21 @@ void AgentList::stopPingUnknownAgentsThread() {
|
|||
}
|
||||
|
||||
void *removeSilentAgents(void *args) {
|
||||
std::vector<Agent> *agents = (std::vector<Agent> *)args;
|
||||
AgentList* agentList = (AgentList*) args;
|
||||
double checkTimeUSecs, sleepTime;
|
||||
|
||||
while (!silentAgentThreadStopFlag) {
|
||||
checkTimeUSecs = usecTimestampNow();
|
||||
|
||||
for(std::vector<Agent>::iterator agent = agents->begin(); agent != agents->end();) {
|
||||
|
||||
pthread_mutex_t* agentDeleteMutex = agent->deleteMutex;
|
||||
for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); ++agent) {
|
||||
|
||||
if ((checkTimeUSecs - agent->getLastRecvTimeUsecs()) > AGENT_SILENCE_THRESHOLD_USECS
|
||||
&& agent->getType() != AGENT_TYPE_VOXEL
|
||||
&& pthread_mutex_trylock(agentDeleteMutex) == 0) {
|
||||
&& agent->getType() != AGENT_TYPE_VOXEL) {
|
||||
|
||||
printLog("Killing agent - ");
|
||||
Agent::printLog(*agent);
|
||||
|
||||
// make sure the vector isn't currently adding an agent
|
||||
pthread_mutex_lock(&vectorChangeMutex);
|
||||
agent = agents->erase(agent);
|
||||
pthread_mutex_unlock(&vectorChangeMutex);
|
||||
|
||||
// release the delete mutex and destroy it
|
||||
pthread_mutex_unlock(agentDeleteMutex);
|
||||
pthread_mutex_destroy(agentDeleteMutex);
|
||||
} else {
|
||||
agent++;
|
||||
agent->setAlive(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,7 +398,7 @@ void *removeSilentAgents(void *args) {
|
|||
}
|
||||
|
||||
void AgentList::startSilentAgentRemovalThread() {
|
||||
pthread_create(&removeSilentAgentsThread, NULL, removeSilentAgents, (void *)&agents);
|
||||
pthread_create(&removeSilentAgentsThread, NULL, removeSilentAgents, (void*) this);
|
||||
}
|
||||
|
||||
void AgentList::stopSilentAgentRemovalThread() {
|
||||
|
@ -414,7 +410,7 @@ void *checkInWithDomainServer(void *args) {
|
|||
|
||||
const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000;
|
||||
|
||||
AgentList *parentAgentList = (AgentList *)args;
|
||||
AgentList* parentAgentList = (AgentList*) args;
|
||||
|
||||
timeval lastSend;
|
||||
unsigned char output[7];
|
||||
|
@ -456,7 +452,7 @@ void *checkInWithDomainServer(void *args) {
|
|||
}
|
||||
|
||||
void AgentList::startDomainServerCheckInThread() {
|
||||
pthread_create(&checkInWithDomainServerThread, NULL, checkInWithDomainServer, (void *)this);
|
||||
pthread_create(&checkInWithDomainServerThread, NULL, checkInWithDomainServer, (void*) this);
|
||||
}
|
||||
|
||||
void AgentList::stopDomainServerCheckInThread() {
|
||||
|
@ -464,12 +460,75 @@ void AgentList::stopDomainServerCheckInThread() {
|
|||
pthread_join(checkInWithDomainServerThread, NULL);
|
||||
}
|
||||
|
||||
int unpackAgentId(unsigned char *packedData, uint16_t *agentId) {
|
||||
memcpy(agentId, packedData, sizeof(uint16_t));
|
||||
return sizeof(uint16_t);
|
||||
AgentList::iterator AgentList::begin() const {
|
||||
Agent** agentBucket = NULL;
|
||||
|
||||
for (int i = 0; i < _numAgents; i++) {
|
||||
if (i % AGENTS_PER_BUCKET == 0) {
|
||||
agentBucket = _agentBuckets[i / AGENTS_PER_BUCKET];
|
||||
}
|
||||
|
||||
if (agentBucket[i % AGENTS_PER_BUCKET]->isAlive()) {
|
||||
return AgentListIterator(this, i);
|
||||
}
|
||||
}
|
||||
|
||||
return AgentListIterator(this, 0);
|
||||
}
|
||||
|
||||
int packAgentId(unsigned char *packStore, uint16_t agentId) {
|
||||
memcpy(packStore, &agentId, sizeof(uint16_t));
|
||||
return sizeof(uint16_t);
|
||||
AgentList::iterator AgentList::end() const {
|
||||
return AgentListIterator(this, _numAgents);
|
||||
}
|
||||
|
||||
AgentListIterator::AgentListIterator(const AgentList* agentList, int agentIndex) :
|
||||
_agentIndex(agentIndex) {
|
||||
_agentList = agentList;
|
||||
}
|
||||
|
||||
AgentListIterator& AgentListIterator::operator=(const AgentListIterator& otherValue) {
|
||||
_agentList = otherValue._agentList;
|
||||
_agentIndex = otherValue._agentIndex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool AgentListIterator::operator==(const AgentListIterator &otherValue) {
|
||||
return _agentIndex == otherValue._agentIndex;
|
||||
}
|
||||
|
||||
bool AgentListIterator::operator!=(const AgentListIterator &otherValue) {
|
||||
return !(*this == otherValue);
|
||||
}
|
||||
|
||||
Agent& AgentListIterator::operator*() {
|
||||
Agent** agentBucket = _agentList->_agentBuckets[_agentIndex / AGENTS_PER_BUCKET];
|
||||
return *agentBucket[_agentIndex % AGENTS_PER_BUCKET];
|
||||
}
|
||||
|
||||
Agent* AgentListIterator::operator->() {
|
||||
Agent** agentBucket = _agentList->_agentBuckets[_agentIndex / AGENTS_PER_BUCKET];
|
||||
return agentBucket[_agentIndex % AGENTS_PER_BUCKET];
|
||||
}
|
||||
|
||||
AgentListIterator& AgentListIterator::operator++() {
|
||||
skipDeadAndStopIncrement();
|
||||
return *this;
|
||||
}
|
||||
|
||||
AgentList::iterator AgentListIterator::operator++(int) {
|
||||
AgentListIterator newIterator = AgentListIterator(*this);
|
||||
skipDeadAndStopIncrement();
|
||||
return newIterator;
|
||||
}
|
||||
|
||||
void AgentListIterator::skipDeadAndStopIncrement() {
|
||||
while (_agentIndex != _agentList->_numAgents) {
|
||||
++_agentIndex;
|
||||
|
||||
if (_agentIndex == _agentList->_numAgents) {
|
||||
break;
|
||||
} else if ((*(*this)).isAlive()) {
|
||||
// skip over the dead agents
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#ifndef __hifi__AgentList__
|
||||
#define __hifi__AgentList__
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <iterator>
|
||||
|
||||
#include "Agent.h"
|
||||
#include "UDPSocket.h"
|
||||
|
@ -19,6 +19,9 @@
|
|||
#include "pthread.h"
|
||||
#endif
|
||||
|
||||
const int MAX_NUM_AGENTS = 10000;
|
||||
const int AGENTS_PER_BUCKET = 100;
|
||||
|
||||
const int MAX_PACKET_SIZE = 1500;
|
||||
const unsigned int AGENT_SOCKET_LISTEN_PORT = 40103;
|
||||
const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000;
|
||||
|
@ -28,15 +31,23 @@ extern char DOMAIN_HOSTNAME[];
|
|||
extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup
|
||||
extern const int DOMAINSERVER_PORT;
|
||||
|
||||
class AgentListIterator;
|
||||
|
||||
class AgentList {
|
||||
public:
|
||||
static AgentList* createInstance(char ownerType, unsigned int socketListenPort = AGENT_SOCKET_LISTEN_PORT);
|
||||
static AgentList* getInstance();
|
||||
|
||||
typedef AgentListIterator iterator;
|
||||
|
||||
AgentListIterator begin() const;
|
||||
AgentListIterator end() const;
|
||||
|
||||
void(*linkedDataCreateCallback)(Agent *);
|
||||
void(*audioMixerSocketUpdate)(in_addr_t, in_port_t);
|
||||
|
||||
std::vector<Agent>& getAgents();
|
||||
int size() { return _numAgents; }
|
||||
|
||||
UDPSocket& getAgentSocket();
|
||||
|
||||
uint16_t getLastAgentId();
|
||||
|
@ -44,8 +55,8 @@ public:
|
|||
|
||||
int updateList(unsigned char *packetData, size_t dataBytes);
|
||||
|
||||
int indexOfMatchingAgent(sockaddr *senderAddress);
|
||||
int indexOfMatchingAgent(uint16_t agentID);
|
||||
Agent* agentWithAddress(sockaddr *senderAddress);
|
||||
Agent* agentWithID(uint16_t agentID);
|
||||
|
||||
bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId);
|
||||
|
||||
|
@ -67,6 +78,8 @@ public:
|
|||
void stopDomainServerCheckInThread();
|
||||
void startPingUnknownAgentsThread();
|
||||
void stopPingUnknownAgentsThread();
|
||||
|
||||
friend class AgentListIterator;
|
||||
private:
|
||||
static AgentList* _sharedInstance;
|
||||
|
||||
|
@ -75,10 +88,13 @@ private:
|
|||
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
|
||||
|
||||
void addAgentToList(Agent* newAgent);
|
||||
|
||||
Agent** _agentBuckets[MAX_NUM_AGENTS / AGENTS_PER_BUCKET];
|
||||
int _numAgents;
|
||||
UDPSocket agentSocket;
|
||||
char ownerType;
|
||||
unsigned int socketListenPort;
|
||||
std::vector<Agent> agents;
|
||||
uint16_t lastAgentId;
|
||||
pthread_t removeSilentAgentsThread;
|
||||
pthread_t checkInWithDomainServerThread;
|
||||
|
@ -87,7 +103,28 @@ private:
|
|||
void handlePingReply(sockaddr *agentAddress);
|
||||
};
|
||||
|
||||
int unpackAgentId(unsigned char *packedData, uint16_t *agentId);
|
||||
int packAgentId(unsigned char *packStore, uint16_t agentId);
|
||||
class AgentListIterator : public std::iterator<std::input_iterator_tag, Agent> {
|
||||
public:
|
||||
AgentListIterator(const AgentList* agentList, int agentIndex);
|
||||
~AgentListIterator() {};
|
||||
|
||||
int getAgentIndex() { return _agentIndex; };
|
||||
|
||||
AgentListIterator& operator=(const AgentListIterator& otherValue);
|
||||
|
||||
bool operator==(const AgentListIterator& otherValue);
|
||||
bool operator!= (const AgentListIterator& otherValue);
|
||||
|
||||
Agent& operator*();
|
||||
Agent* operator->();
|
||||
|
||||
AgentListIterator& operator++();
|
||||
AgentListIterator operator++(int);
|
||||
private:
|
||||
void skipDeadAndStopIncrement();
|
||||
|
||||
const AgentList* _agentList;
|
||||
int _agentIndex;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AgentList__) */
|
||||
|
|
|
@ -122,30 +122,22 @@ void eraseVoxelTreeAndCleanupAgentVisitData() {
|
|||
::randomTree.eraseAllVoxels();
|
||||
|
||||
// enumerate the agents clean up their marker nodes
|
||||
for (int i = 0; i < AgentList::getInstance()->getAgents().size(); i++) {
|
||||
|
||||
for (AgentList::iterator agent = AgentList::getInstance()->begin(); agent != AgentList::getInstance()->end(); agent++) {
|
||||
|
||||
//printf("eraseVoxelTreeAndCleanupAgentVisitData() agent[%d]\n",i);
|
||||
|
||||
Agent *thisAgent = (Agent *)&AgentList::getInstance()->getAgents()[i];
|
||||
VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData());
|
||||
|
||||
// lock this agent's delete mutex so that the delete thread doesn't
|
||||
// kill the agent while we are working with it
|
||||
pthread_mutex_lock(thisAgent->deleteMutex);
|
||||
VoxelAgentData *agentData = (VoxelAgentData *)agent->getLinkedData();
|
||||
|
||||
// clean up the agent visit data
|
||||
delete agentData->rootMarkerNode;
|
||||
agentData->rootMarkerNode = new MarkerNode();
|
||||
|
||||
// unlock the delete mutex so the other thread can
|
||||
// kill the agent if it has dissapeared
|
||||
pthread_mutex_unlock(thisAgent->deleteMutex);
|
||||
}
|
||||
}
|
||||
|
||||
void *distributeVoxelsToListeners(void *args) {
|
||||
|
||||
AgentList *agentList = AgentList::getInstance();
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
timeval lastSendTime;
|
||||
|
||||
unsigned char *stopOctal;
|
||||
|
@ -162,10 +154,8 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
gettimeofday(&lastSendTime, NULL);
|
||||
|
||||
// enumerate the agents to send 3 packets to each
|
||||
for (int i = 0; i < agentList->getAgents().size(); i++) {
|
||||
|
||||
Agent *thisAgent = (Agent *)&agentList->getAgents()[i];
|
||||
VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData());
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
VoxelAgentData *agentData = (VoxelAgentData *)agent->getLinkedData();
|
||||
|
||||
ViewFrustum viewFrustum;
|
||||
// get position and orientation details from the camera
|
||||
|
@ -185,10 +175,6 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
viewFrustum.dump();
|
||||
}
|
||||
|
||||
// lock this agent's delete mutex so that the delete thread doesn't
|
||||
// kill the agent while we are working with it
|
||||
pthread_mutex_lock(thisAgent->deleteMutex);
|
||||
|
||||
stopOctal = NULL;
|
||||
packetCount = 0;
|
||||
totalBytesSent = 0;
|
||||
|
@ -205,7 +191,7 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
::viewFrustumCulling,
|
||||
stopOctal);
|
||||
|
||||
agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
||||
agentList->getAgentSocket().send(agent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket);
|
||||
|
||||
packetCount++;
|
||||
totalBytesSent += voxelPacketEnd - voxelPacket;
|
||||
|
@ -226,10 +212,6 @@ void *distributeVoxelsToListeners(void *args) {
|
|||
delete agentData->rootMarkerNode;
|
||||
agentData->rootMarkerNode = new MarkerNode();
|
||||
}
|
||||
|
||||
// unlock the delete mutex so the other thread can
|
||||
// kill the agent if it has dissapeared
|
||||
pthread_mutex_unlock(thisAgent->deleteMutex);
|
||||
}
|
||||
|
||||
// dynamically sleep until we need to fire off the next set of voxels
|
||||
|
@ -254,7 +236,7 @@ void attachVoxelAgentDataToAgent(Agent *newAgent) {
|
|||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
AgentList *agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT);
|
||||
AgentList* agentList = AgentList::createInstance(AGENT_TYPE_VOXEL, VOXEL_LISTEN_PORT);
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
// Handle Local Domain testing with the --local command line
|
||||
|
|
Loading…
Reference in a new issue