From 0ac2765b0946dc7c2fae35e953cf2d4922477238 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 8 May 2013 22:45:28 -0700 Subject: [PATCH 01/20] cleaned up a few small code thingies; added a check for where avatar velocity updates avatar position; --- interface/src/Avatar.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 1b0aac8838..0592695df2 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -30,7 +30,7 @@ const float BODY_SPIN_FRICTION = 5.0; const float BODY_UPRIGHT_FORCE = 10.0; const float BODY_PITCH_WHILE_WALKING = 30.0; const float BODY_ROLL_WHILE_TURNING = 0.1; -const float LIN_VEL_DECAY = 5.0; +const float VELOCITY_DECAY = 5.0; const float MY_HAND_HOLDING_PULL = 0.2; const float YOUR_HAND_HOLDING_PULL = 1.0; const float BODY_SPRING_DEFAULT_TIGHTNESS = 1500.0f; @@ -408,8 +408,13 @@ void Avatar::simulate(float deltaTime) { _position += _velocity * deltaTime; // decay velocity - _velocity *= (1.0 - LIN_VEL_DECAY * deltaTime); - + float decay = 1.0 - VELOCITY_DECAY * deltaTime; + if ( decay < 0.0 ) { + _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); + } else { + _velocity *= decay; + } + // If someone is near, damp velocity as a function of closeness const float AVATAR_BRAKING_RANGE = 1.2f; const float AVATAR_BRAKING_STRENGTH = 25.f; @@ -419,7 +424,7 @@ void Avatar::simulate(float deltaTime) { (AVATAR_BRAKING_RANGE - _distanceToNearestAvatar)); } - // update head information + // update head state updateHead(deltaTime); // use speed and angular velocity to determine walking vs. standing From 785e55e06f8d4f0df98c101fb17b0a0ce252a6a8 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 9 May 2013 09:56:35 -0700 Subject: [PATCH 02/20] Working on voxel editing. --- interface/src/VoxelSystem.cpp | 15 +++++++++++++ interface/src/VoxelSystem.h | 3 +++ interface/src/main.cpp | 41 ++++++++++++++++++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 3d5880c305..d1605166c2 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -613,3 +613,18 @@ void VoxelSystem::removeOutOfView() { _nodeCount = 0; _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)this); } + +bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance) { + VoxelNode* node; + if (!_tree->findRayIntersection(origin, direction, node, distance)) { + return false; + } + detail.x = node->getCorner().x; + detail.y = node->getCorner().y; + detail.z = node->getCorner().z; + detail.s = node->getScale(); + detail.red = node->getColor()[0]; + detail.green = node->getColor()[1]; + detail.blue = node->getColor()[2]; + return true; +} diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index f3968004b0..4b998dd942 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -11,6 +11,7 @@ #include "InterfaceConfig.h" #include +#include #include #include #include @@ -64,6 +65,8 @@ public: void removeOutOfView(); bool hasViewChanged(); + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance); + private: int _callsToTreesToArrays; VoxelNodeBag _removedVoxels; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index abbb67cdbc..309d79151d 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -70,7 +70,6 @@ #include "Oscilloscope.h" #include "UDPSocket.h" #include "SerialInterface.h" -#include #include #include #include @@ -1457,6 +1456,44 @@ void setupPaintingVoxel() { shiftPaintingColor(); } +void addVoxelUnderCursor() { + glm::vec3 origin, direction; + viewFrustum.computePickRay(mouseX / (float)WIDTH, mouseY / (float)HEIGHT, origin, direction); + + VoxelDetail detail; + float distance; + if (voxels.findRayIntersection(origin, direction, detail, distance)) { + // get the hit location relative to the center of the voxel + float half = detail.s * 0.5f; + glm::vec3 hit = origin + distance*direction - glm::vec3(detail.x + half, detail.y + half, detail.z + half); + + unsigned char* bufferOut; + int sizeOut; + + if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &detail, bufferOut, sizeOut)){ + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + delete bufferOut; + } + } +} + +void deleteVoxelUnderCursor() { + glm::vec3 origin, direction; + viewFrustum.computePickRay(mouseX / (float)WIDTH, mouseY / (float)HEIGHT, origin, direction); + + VoxelDetail detail; + float distance; + if (voxels.findRayIntersection(origin, direction, detail, distance)) { + unsigned char* bufferOut; + int sizeOut; + + if (createVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, 0, 1, &detail, bufferOut, sizeOut)){ + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + delete bufferOut; + } + } +} + const float KEYBOARD_YAW_RATE = 0.8; const float KEYBOARD_PITCH_RATE = 0.6; const float KEYBOARD_STRAFE_RATE = 0.03; @@ -1574,6 +1611,8 @@ void key(unsigned char k, int x, int y) { if (k == '^') ::shiftPaintingColor(); // shifts randomize color between R,G,B dominant if (k == '-') ::sendVoxelServerEraseAll(); // sends erase all command to voxel server if (k == '%') ::sendVoxelServerAddScene(); // sends add scene command to voxel server + if (k == '1') ::addVoxelUnderCursor(); + if (k == '2') ::deleteVoxelUnderCursor(); if (k == 'n' || k == 'N') { noiseOn = !noiseOn; // Toggle noise From 4a0657fead9058a431f2075276501a5d969cd659 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 9 May 2013 10:29:15 -0700 Subject: [PATCH 03/20] Set up the lights after applying the camera transform so that they will be in world, not view, space. --- interface/src/main.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 07360461b9..23a65fc405 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1006,22 +1006,6 @@ void display(void) glPushMatrix(); { glLoadIdentity(); - // Setup 3D lights - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - - GLfloat light_position0[] = { 1.0, 1.0, 0.0, 0.0 }; - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - GLfloat ambient_color[] = { 0.7, 0.7, 0.8 }; - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color); - GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 }; - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color); - GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0}; - glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color); - - 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 @@ -1153,7 +1137,23 @@ void display(void) glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); glTranslatef(-whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z); - + + // Setup 3D lights (after the camera transform, so that they are positioned in world space) + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + + GLfloat light_position0[] = { 1.0, 1.0, 0.0, 0.0 }; + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + GLfloat ambient_color[] = { 0.7, 0.7, 0.8 }; + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color); + GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 }; + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color); + GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0}; + glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color); + + glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color); + glMateriali(GL_FRONT, GL_SHININESS, 96); + if (::oculusOn) { displayOculus(whichCamera); From 7ff8b84f4cca08fd342e03c4eaf8aee58f5f8bfc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 9 May 2013 10:46:52 -0700 Subject: [PATCH 04/20] Return the box face, as well as the distance, from the ray intersection test. Use it to determine which voxel neighbor we create when adding. --- interface/src/VoxelSystem.cpp | 5 +++-- interface/src/VoxelSystem.h | 3 ++- interface/src/main.cpp | 36 +++++++++++++++++++++++++----- libraries/voxels/src/AABox.cpp | 19 +++++++++++----- libraries/voxels/src/AABox.h | 11 ++++++++- libraries/voxels/src/VoxelTree.cpp | 10 ++++++--- libraries/voxels/src/VoxelTree.h | 3 ++- 7 files changed, 68 insertions(+), 19 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index ac97e7fcfe..6f2bbc24f3 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -680,9 +680,10 @@ void VoxelSystem::removeOutOfView() { } } -bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance) { +bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + VoxelDetail& detail, float& distance, BoxFace& face) { VoxelNode* node; - if (!_tree->findRayIntersection(origin, direction, node, distance)) { + if (!_tree->findRayIntersection(origin, direction, node, distance, face)) { return false; } detail.x = node->getCorner().x; diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 4476ca9fe2..3c95edb6ae 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -65,7 +65,8 @@ public: void removeOutOfView(); bool hasViewChanged(); - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelDetail& detail, float& distance); + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + VoxelDetail& detail, float& distance, BoxFace& face); private: int _callsToTreesToArrays; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 23a65fc405..2a1eb91e75 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1489,11 +1489,34 @@ void addVoxelUnderCursor() { VoxelDetail detail; float distance; - if (voxels.findRayIntersection(origin, direction, detail, distance)) { - // get the hit location relative to the center of the voxel - float half = detail.s * 0.5f; - glm::vec3 hit = origin + distance*direction - glm::vec3(detail.x + half, detail.y + half, detail.z + half); - + BoxFace face; + if (voxels.findRayIntersection(origin, direction, detail, distance, face)) { + // use the face to determine the side on which to create a neighbor + switch (face) { + case MIN_X_FACE: + detail.x -= detail.s; + break; + + case MAX_X_FACE: + detail.x += detail.s; + break; + + case MIN_Y_FACE: + detail.y -= detail.s; + break; + + case MAX_Y_FACE: + detail.y += detail.s; + break; + + case MIN_Z_FACE: + detail.z -= detail.s; + break; + + case MAX_Z_FACE: + detail.z += detail.s; + break; + } unsigned char* bufferOut; int sizeOut; @@ -1510,7 +1533,8 @@ void deleteVoxelUnderCursor() { VoxelDetail detail; float distance; - if (voxels.findRayIntersection(origin, direction, detail, distance)) { + BoxFace face; + if (voxels.findRayIntersection(origin, direction, detail, distance, face)) { unsigned char* bufferOut; int sizeOut; diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index d253167bc6..c26e73e12a 100644 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -95,7 +95,7 @@ static bool findIntersection(float origin, float direction, float corner, float return false; } -bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const { +bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const { // handle the trivial case where the box contains the origin if (contains(origin)) { distance = 0; @@ -105,14 +105,23 @@ bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct float axisDistance; if ((findIntersection(origin.x, direction.x, _corner.x, _size.x, axisDistance) && axisDistance >= 0 && isWithin(origin.y + axisDistance*direction.y, _corner.y, _size.y) && - isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z)) || - (findIntersection(origin.y, direction.y, _corner.y, _size.y, axisDistance) && axisDistance >= 0 && + isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z))) { + distance = axisDistance; + face = direction.x > 0 ? MIN_X_FACE : MAX_X_FACE; + return true; + } + if ((findIntersection(origin.y, direction.y, _corner.y, _size.y, axisDistance) && axisDistance >= 0 && isWithin(origin.x + axisDistance*direction.x, _corner.x, _size.x) && - isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z)) || - (findIntersection(origin.z, direction.z, _corner.z, _size.z, axisDistance) && axisDistance >= 0 && + isWithin(origin.z + axisDistance*direction.z, _corner.z, _size.z))) { + distance = axisDistance; + face = direction.y > 0 ? MIN_Y_FACE : MAX_Y_FACE; + return true; + } + if ((findIntersection(origin.z, direction.z, _corner.z, _size.z, axisDistance) && axisDistance >= 0 && isWithin(origin.y + axisDistance*direction.y, _corner.y, _size.y) && isWithin(origin.x + axisDistance*direction.x, _corner.x, _size.x))) { distance = axisDistance; + face = direction.z > 0 ? MIN_Z_FACE : MAX_Z_FACE; return true; } return false; diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index 2b75affdae..63d586de22 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -13,6 +13,15 @@ #include +enum BoxFace { + MIN_X_FACE, + MAX_X_FACE, + MIN_Y_FACE, + MAX_Y_FACE, + MIN_Z_FACE, + MAX_Z_FACE +}; + class AABox { @@ -37,7 +46,7 @@ public: const glm::vec3& getCenter() const { return _center; }; bool contains(const glm::vec3& point) const; - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const; + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) const; private: glm::vec3 _corner; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index daf2e01a72..bb55f01bc2 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -605,6 +605,7 @@ public: glm::vec3 direction; VoxelNode*& node; float& distance; + BoxFace& face; bool found; }; @@ -612,7 +613,8 @@ bool findRayOperation(VoxelNode* node, void* extraData) { RayArgs* args = static_cast(extraData); AABox box = node->getAABox(); float distance; - if (!box.findRayIntersection(args->origin, args->direction, distance)) { + BoxFace face; + if (!box.findRayIntersection(args->origin, args->direction, distance, face)) { return false; } if (!node->isLeaf()) { @@ -621,14 +623,16 @@ bool findRayOperation(VoxelNode* node, void* extraData) { if (!args->found || distance < args->distance) { args->node = node; args->distance = distance; + args->face = face; args->found = true; } return false; } -bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode*& node, float& distance) +bool VoxelTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + VoxelNode*& node, float& distance, BoxFace& face) { - RayArgs args = { origin / (float)TREE_SCALE, direction, node, distance }; + RayArgs args = { origin / (float)TREE_SCALE, direction, node, distance, face }; recurseTreeWithOperation(findRayOperation, &args); return args.found; } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 319b4aed95..5574ca7602 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -63,7 +63,8 @@ public: void clearDirtyBit() { _isDirty = false; }; unsigned long int getNodesChangedFromBitstream() const { return _nodesChangedFromBitstream; }; - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, VoxelNode*& node, float& distance); + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + VoxelNode*& node, float& distance, BoxFace& face); // Note: this assumes the fileFormat is the HIO individual voxels code files void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); From dcd42096a5e8981c029f00fbd7391549d1a178f5 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 9 May 2013 10:56:08 -0700 Subject: [PATCH 05/20] Tabs -> spaces. --- interface/src/main.cpp | 574 ++++++++++++++++++++--------------------- 1 file changed, 287 insertions(+), 287 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 2a1eb91e75..4b70f20402 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -147,15 +147,15 @@ bool renderStarsOn = true; // Whether to display the stars bool renderAtmosphereOn = true; // Whether to display the atmosphere bool renderAvatarsOn = true; // Whether to render avatars bool paintOn = false; // Whether to paint voxels as you fly around -VoxelDetail paintingVoxel; // The voxel we're painting if we're painting -unsigned char dominantColor = 0; // The dominant color of the voxel we're painting -bool perfStatsOn = false; // Do we want to display perfStats? +VoxelDetail paintingVoxel; // The voxel we're painting if we're painting +unsigned char dominantColor = 0; // The dominant color of the voxel we're painting +bool perfStatsOn = false; // Do we want to display perfStats? bool logOn = true; // Whether to show on-screen log bool wantToKillLocalVoxels = false; -int noiseOn = 0; // Whether to add random noise +int noiseOn = 0; // Whether to add random noise float noise = 1.0; // Overall magnitude scaling for random noise levels bool gyroLook = true; // Whether to allow the gyro data from head to move your view @@ -210,11 +210,11 @@ void Timer(int extra) { FPS = (float)frameCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); packetsPerSecond = (float)packetCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); bytesPerSecond = (float)bytesCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); - frameCount = 0; + frameCount = 0; packetCount = 0; bytesCount = 0; - glutTimerFunc(1000,Timer,0); + glutTimerFunc(1000,Timer,0); gettimeofday(&timerStart, NULL); // if we haven't detected gyros, check for them now @@ -239,27 +239,27 @@ void displayStats(void) { voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered() / 1000.f << "K Updated: " << voxels.getVoxelsUpdated()/1000.f << "K"; drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - voxelStats.str(""); - voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() / 1000.f << "K (" << voxels.getVoxelsCreatedPerSecondAverage() / 1000.f + voxelStats.str(""); + voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() / 1000.f << "K (" << voxels.getVoxelsCreatedPerSecondAverage() / 1000.f << "Kps) "; drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - voxelStats.str(""); - voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() / 1000.f << "K (" << voxels.getVoxelsColoredPerSecondAverage() / 1000.f + voxelStats.str(""); + voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() / 1000.f << "K (" << voxels.getVoxelsColoredPerSecondAverage() / 1000.f << "Kps) "; drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - voxelStats.str(""); - voxelStats << "Voxel Bits Read: " << voxels.getVoxelsBytesRead() * 8.f / 1000000.f + voxelStats.str(""); + voxelStats << "Voxel Bits Read: " << voxels.getVoxelsBytesRead() * 8.f / 1000000.f << "M (" << voxels.getVoxelsBytesReadPerSecondAverage() * 8.f / 1000000.f << " Mbps)"; drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - voxelStats.str(""); - float voxelsBytesPerColored = voxels.getVoxelsColored() + voxelStats.str(""); + float voxelsBytesPerColored = voxels.getVoxelsColored() ? ((float) voxels.getVoxelsBytesRead() / voxels.getVoxelsColored()) : 0; - voxelStats << "Voxels Bits per Colored: " << voxelsBytesPerColored * 8; + voxelStats << "Voxels Bits per Colored: " << voxelsBytesPerColored * 8; drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); Agent *avatarMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); @@ -275,19 +275,19 @@ void displayStats(void) { drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats); - if (::perfStatsOn) { - // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups - char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; - int lines = PerfStat::DumpStats(perfStatLinesArray); - int atZ = 150; // arbitrary place on screen that looks good - for (int line=0; line < lines; line++) { - drawtext(10, statsVerticalOffset + atZ, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); - delete perfStatLinesArray[line]; // we're responsible for cleanup - perfStatLinesArray[line]=NULL; - atZ+=20; // height of a line - } - delete []perfStatLinesArray; // we're responsible for cleanup - } + if (::perfStatsOn) { + // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups + char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; + int lines = PerfStat::DumpStats(perfStatLinesArray); + int atZ = 150; // arbitrary place on screen that looks good + for (int line=0; line < lines; line++) { + drawtext(10, statsVerticalOffset + atZ, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); + delete perfStatLinesArray[line]; // we're responsible for cleanup + perfStatLinesArray[line]=NULL; + atZ+=20; // height of a line + } + delete []perfStatLinesArray; // we're responsible for cleanup + } } void initDisplay(void) { @@ -320,9 +320,9 @@ void init(void) { myAvatar.setNoise(noise); } myAvatar.setPosition(start_location); - myCamera.setPosition(start_location); + myCamera.setPosition(start_location); + - #ifdef MARKER_CAPTURE if(marker_capture_enabled){ marker_capturer.position_updated(&position_updated); @@ -471,25 +471,25 @@ void updateAvatar(float deltaTime) { // If I'm in paint mode, send a voxel out to VOXEL server agents. if (::paintOn) { - glm::vec3 avatarPos = myAvatar.getPosition(); + glm::vec3 avatarPos = myAvatar.getPosition(); - // For some reason, we don't want to flip X and Z here. - ::paintingVoxel.x = avatarPos.x / 10.0; - ::paintingVoxel.y = avatarPos.y / 10.0; - ::paintingVoxel.z = avatarPos.z / 10.0; - - unsigned char* bufferOut; - int sizeOut; - - if (::paintingVoxel.x >= 0.0 && ::paintingVoxel.x <= 1.0 && - ::paintingVoxel.y >= 0.0 && ::paintingVoxel.y <= 1.0 && - ::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) { + // For some reason, we don't want to flip X and Z here. + ::paintingVoxel.x = avatarPos.x / 10.0; + ::paintingVoxel.y = avatarPos.y / 10.0; + ::paintingVoxel.z = avatarPos.z / 10.0; + + unsigned char* bufferOut; + int sizeOut; + + if (::paintingVoxel.x >= 0.0 && ::paintingVoxel.x <= 1.0 && + ::paintingVoxel.y >= 0.0 && ::paintingVoxel.y <= 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::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); - delete bufferOut; - } - } + delete bufferOut; + } + } } } @@ -497,7 +497,7 @@ void updateAvatar(float deltaTime) { // loadViewFrustum() // // Description: this will load the view frustum bounds for EITHER the head -// or the "myCamera". +// or the "myCamera". // // These global scoped variables are used by our loadViewFrustum() and renderViewFrustum functions below, but are also @@ -514,19 +514,19 @@ float viewFrustumOffsetDistance = 25.0; float viewFrustumOffsetUp = 0.0; void loadViewFrustum(ViewFrustum& viewFrustum) { - // We will use these below, from either the camera or head vectors calculated above - glm::vec3 position; - glm::vec3 direction; - glm::vec3 up; - glm::vec3 right; - float fov, nearClip, farClip; - - // Camera or Head? - if (::cameraFrustum) { - position = ::myCamera.getPosition(); - } else { - position = ::myAvatar.getHeadPosition(); - } + // We will use these below, from either the camera or head vectors calculated above + glm::vec3 position; + glm::vec3 direction; + glm::vec3 up; + glm::vec3 right; + float fov, nearClip, farClip; + + // Camera or Head? + if (::cameraFrustum) { + position = ::myCamera.getPosition(); + } else { + position = ::myAvatar.getHeadPosition(); + } fov = ::myCamera.getFieldOfView(); nearClip = ::myCamera.getNearClip(); @@ -549,7 +549,7 @@ void loadViewFrustum(ViewFrustum& viewFrustum) { printf("farClip=%f\n", farClip); */ - // Set the viewFrustum up with the correct position and orientation of the camera + // Set the viewFrustum up with the correct position and orientation of the camera viewFrustum.setPosition(position); viewFrustum.setOrientation(direction,up,right); @@ -566,7 +566,7 @@ void loadViewFrustum(ViewFrustum& viewFrustum) { // renderViewFrustum() // // Description: this will render the view frustum bounds for EITHER the head -// or the "myCamera". +// or the "myCamera". // // Frustum rendering mode. For debug purposes, we allow drawing the frustum in a couple of different ways. // We can draw it with each of these parts: @@ -593,102 +593,102 @@ void renderViewFrustum(ViewFrustum& viewFrustum) { // Load it with the latest details! loadViewFrustum(viewFrustum); - + glm::vec3 position = viewFrustum.getPosition(); glm::vec3 direction = viewFrustum.getDirection(); glm::vec3 up = viewFrustum.getUp(); glm::vec3 right = viewFrustum.getRight(); - + // Get ready to draw some lines glDisable(GL_LIGHTING); glColor4f(1.0, 1.0, 1.0, 1.0); glLineWidth(1.0); glBegin(GL_LINES); - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_VECTORS) { - // Calculate the origin direction vectors - glm::vec3 lookingAt = position + (direction * 0.2f); - glm::vec3 lookingAtUp = position + (up * 0.2f); - glm::vec3 lookingAtRight = position + (right * 0.2f); + if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_VECTORS) { + // Calculate the origin direction vectors + glm::vec3 lookingAt = position + (direction * 0.2f); + glm::vec3 lookingAtUp = position + (up * 0.2f); + glm::vec3 lookingAtRight = position + (right * 0.2f); - // Looking At = white - glColor3f(1,1,1); - glVertex3f(position.x, position.y, position.z); - glVertex3f(lookingAt.x, lookingAt.y, lookingAt.z); + // Looking At = white + glColor3f(1,1,1); + glVertex3f(position.x, position.y, position.z); + glVertex3f(lookingAt.x, lookingAt.y, lookingAt.z); - // Looking At Up = purple - glColor3f(1,0,1); - glVertex3f(position.x, position.y, position.z); - glVertex3f(lookingAtUp.x, lookingAtUp.y, lookingAtUp.z); + // Looking At Up = purple + glColor3f(1,0,1); + glVertex3f(position.x, position.y, position.z); + glVertex3f(lookingAtUp.x, lookingAtUp.y, lookingAtUp.z); - // Looking At Right = cyan - glColor3f(0,1,1); - glVertex3f(position.x, position.y, position.z); - glVertex3f(lookingAtRight.x, lookingAtRight.y, lookingAtRight.z); - } + // Looking At Right = cyan + glColor3f(0,1,1); + glVertex3f(position.x, position.y, position.z); + glVertex3f(lookingAtRight.x, lookingAtRight.y, lookingAtRight.z); + } - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES - || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_NEAR_PLANE) { - // Drawing the bounds of the frustum - // viewFrustum.getNear plane - bottom edge - glColor3f(1,0,0); - glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); - glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); + if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES + || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_NEAR_PLANE) { + // Drawing the bounds of the frustum + // viewFrustum.getNear plane - bottom edge + glColor3f(1,0,0); + glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); + glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); - // viewFrustum.getNear plane - top edge - glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); - glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); + // viewFrustum.getNear plane - top edge + glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); + glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); - // viewFrustum.getNear plane - right edge - glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); - glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); + // viewFrustum.getNear plane - right edge + glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); + glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); - // viewFrustum.getNear plane - left edge - glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); - glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); - } + // viewFrustum.getNear plane - left edge + glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); + glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); + } - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES - || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_FAR_PLANE) { - // viewFrustum.getFar plane - bottom edge - glColor3f(0,1,0); // GREEN!!! - glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); - glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); + if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES + || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_FAR_PLANE) { + // viewFrustum.getFar plane - bottom edge + glColor3f(0,1,0); // GREEN!!! + glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); + glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); - // viewFrustum.getFar plane - top edge - glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); - glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); + // viewFrustum.getFar plane - top edge + glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); + glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); - // viewFrustum.getFar plane - right edge - glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); - glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); + // viewFrustum.getFar plane - right edge + glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); + glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); - // viewFrustum.getFar plane - left edge - glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); - glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); - } + // viewFrustum.getFar plane - left edge + glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); + glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); + } - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES) { - // RIGHT PLANE IS CYAN - // right plane - bottom edge - viewFrustum.getNear to distant - glColor3f(0,1,1); - glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); - glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); + if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES) { + // RIGHT PLANE IS CYAN + // right plane - bottom edge - viewFrustum.getNear to distant + glColor3f(0,1,1); + glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); + glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); - // right plane - top edge - viewFrustum.getNear to distant - glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); - glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); + // right plane - top edge - viewFrustum.getNear to distant + glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); + glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); - // LEFT PLANE IS BLUE - // left plane - bottom edge - viewFrustum.getNear to distant - glColor3f(0,0,1); - glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); - glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); + // LEFT PLANE IS BLUE + // left plane - bottom edge - viewFrustum.getNear to distant + glColor3f(0,0,1); + glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); + glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); - // left plane - top edge - viewFrustum.getNear to distant - glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); - glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); - } + // left plane - top edge - viewFrustum.getNear to distant + glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); + glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); + } glEnd(); glEnable(GL_LIGHTING); @@ -715,7 +715,7 @@ void displaySide(Camera& whichCamera) { } // finally render the starfield - stars.render(whichCamera.getFieldOfView(), aspectRatio, whichCamera.getNearClip(), alpha); + stars.render(whichCamera.getFieldOfView(), aspectRatio, whichCamera.getNearClip(), alpha); } // draw the sky dome @@ -726,8 +726,8 @@ void displaySide(Camera& whichCamera) { glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); - // draw a red sphere - float sphereRadius = 0.25f; + // draw a red sphere + float sphereRadius = 0.25f; glColor3f(1,0,0); glPushMatrix(); glutSolidSphere(sphereRadius, 15, 15); @@ -735,12 +735,12 @@ void displaySide(Camera& whichCamera) { //draw a grid ground plane.... drawGroundPlaneGrid(10.f); - + // Draw voxels if (renderVoxels) { voxels.render(); } - + if (::renderAvatarsOn) { // Render avatars of other agents AgentList* agentList = AgentList::getInstance(); @@ -762,8 +762,8 @@ void displaySide(Camera& whichCamera) { // brad's frustum for debugging if (::frustumOn) renderViewFrustum(::viewFrustum); - - glPopMatrix(); + + glPopMatrix(); } // this shader is an adaptation (HLSL -> GLSL, removed conditional) of the one in the Oculus sample @@ -985,11 +985,11 @@ void displayOverlay() { if (::paintOn) { - char paintMessage[100]; - sprintf(paintMessage,"Painting (%.3f,%.3f,%.3f/%.3f/%d,%d,%d)", - ::paintingVoxel.x,::paintingVoxel.y,::paintingVoxel.z,::paintingVoxel.s, - (unsigned int)::paintingVoxel.red,(unsigned int)::paintingVoxel.green,(unsigned int)::paintingVoxel.blue); - drawtext(WIDTH-350,50, 0.10, 0, 1.0, 0, paintMessage, 1, 1, 0); + char paintMessage[100]; + sprintf(paintMessage,"Painting (%.3f,%.3f,%.3f/%.3f/%d,%d,%d)", + ::paintingVoxel.x,::paintingVoxel.y,::paintingVoxel.z,::paintingVoxel.s, + (unsigned int)::paintingVoxel.red,(unsigned int)::paintingVoxel.green,(unsigned int)::paintingVoxel.blue); + drawtext(WIDTH-350,50, 0.10, 0, 1.0, 0, paintMessage, 1, 1, 0); } glPopMatrix(); @@ -997,7 +997,7 @@ void displayOverlay() { void display(void) { - PerfStat("display"); + PerfStat("display"); glEnable(GL_LINE_SMOOTH); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1013,10 +1013,10 @@ void display(void) myCamera.setTargetYaw (myAvatar.getBodyYaw() - 180.0f); // 180 degrees from body yaw myCamera.setPitch (0.0); myCamera.setRoll (0.0); - myCamera.setUpShift (0.0); + myCamera.setUpShift (0.0); myCamera.setDistance (0.2); myCamera.setTightness (100.0f); - } else { + } else { //float firstPersonPitch = 20.0f; //float firstPersonUpShift = 0.0f; @@ -1046,7 +1046,7 @@ void display(void) } } - myCamera.setPitch (thirdPersonPitch + ff * (firstPersonPitch - thirdPersonPitch )); + myCamera.setPitch (thirdPersonPitch + ff * (firstPersonPitch - thirdPersonPitch )); myCamera.setUpShift (thirdPersonUpShift + ff * (firstPersonUpShift - thirdPersonUpShift )); myCamera.setDistance (thirdPersonDistance + ff * (firstPersonDistance - thirdPersonDistance )); myCamera.setTightness (thirdPersonTightness + ff * (firstPersonTightness - thirdPersonTightness)); @@ -1060,7 +1060,7 @@ void display(void) } //printf("myCamera.getModeShift() = %f\n", myCamera.getModeShift()); - myCamera.setPitch (thirdPersonPitch + myCamera.getModeShift() * (firstPersonPitch - thirdPersonPitch )); + 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)); @@ -1070,7 +1070,7 @@ void display(void) } //printf("myCamera.getModeShift() = %f\n", myCamera.getModeShift()); - myCamera.setPitch (firstPersonPitch + myCamera.getModeShift() * (thirdPersonPitch - firstPersonPitch )); + 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)); @@ -1087,7 +1087,7 @@ void display(void) myCamera.setTargetPosition(myAvatar.getHeadPosition()); myCamera.setTargetYaw (myAvatar.getBodyYaw()); myCamera.setRoll (0.0); - } + } // important... @@ -1103,19 +1103,19 @@ void display(void) glPopMatrix(); */ - - // 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 - // to add other cameras. - // - // Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum() - // code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of - // myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera - Camera whichCamera = myCamera; - Camera viewFrustumOffsetCamera = myCamera; + + // 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 + // to add other cameras. + // + // Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum() + // code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of + // myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera + Camera whichCamera = myCamera; + Camera viewFrustumOffsetCamera = myCamera; - if (::viewFrustumFromOffset && ::frustumOn) { + if (::viewFrustumFromOffset && ::frustumOn) { // set the camera to third-person view but offset so we can see the frustum viewFrustumOffsetCamera.setTargetYaw(::viewFrustumOffsetYaw + myAvatar.getBodyYaw()); @@ -1125,16 +1125,16 @@ void display(void) viewFrustumOffsetCamera.setDistance (::viewFrustumOffsetDistance); viewFrustumOffsetCamera.update(1.f/FPS); whichCamera = viewFrustumOffsetCamera; - } + } - // transform view according to whichCamera - // could be myCamera (if in normal mode) - // or could be viewFrustumOffsetCamera if in offset mode - // I changed the ordering here - roll is FIRST (JJV) + // transform view according to whichCamera + // could be myCamera (if in normal mode) + // or could be viewFrustumOffsetCamera if in offset mode + // I changed the ordering here - roll is FIRST (JJV) glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); - glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); + glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); glTranslatef(-whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z); @@ -1311,7 +1311,7 @@ int quitApp(int state) { int setFrustumRenderMode(int state) { if (state == MENU_ROW_PICKED) { - ::frustumDrawingMode = (::frustumDrawingMode+1)%FRUSTUM_DRAW_MODE_COUNT; + ::frustumDrawingMode = (::frustumDrawingMode+1)%FRUSTUM_DRAW_MODE_COUNT; } return ::frustumDrawingMode; } @@ -1368,25 +1368,25 @@ const char* modeNear = " - Near "; const char* modeFar = " - Far "; const char* getFrustumRenderModeName(int state) { - const char * mode; - switch (state) { - case FRUSTUM_DRAW_MODE_ALL: - mode = modeAll; - break; - case FRUSTUM_DRAW_MODE_VECTORS: - mode = modeVectors; - break; - case FRUSTUM_DRAW_MODE_PLANES: - mode = modePlanes; - break; - case FRUSTUM_DRAW_MODE_NEAR_PLANE: - mode = modeNear; - break; - case FRUSTUM_DRAW_MODE_FAR_PLANE: - mode = modeFar; - break; - } - return mode; + const char * mode; + switch (state) { + case FRUSTUM_DRAW_MODE_ALL: + mode = modeAll; + break; + case FRUSTUM_DRAW_MODE_VECTORS: + mode = modeVectors; + break; + case FRUSTUM_DRAW_MODE_PLANES: + mode = modePlanes; + break; + case FRUSTUM_DRAW_MODE_NEAR_PLANE: + mode = modeNear; + break; + case FRUSTUM_DRAW_MODE_FAR_PLANE: + mode = modeFar; + break; + } + return mode; } void initMenu() { @@ -1432,55 +1432,55 @@ void initMenu() { } void testPointToVoxel() { - float y=0; - float z=0; - float s=0.1; - for (float x=0; x<=1; x+= 0.05) { - printLog(" x=%f"); + float y=0; + float z=0; + float s=0.1; + for (float x=0; x<=1; x+= 0.05) { + printLog(" x=%f"); - unsigned char red = 200; //randomColorValue(65); - unsigned char green = 200; //randomColorValue(65); - unsigned char blue = 200; //randomColorValue(65); - - unsigned char* voxelCode = pointToVoxel(x, y, z, s,red,green,blue); - printVoxelCode(voxelCode); - delete voxelCode; - printLog("\n"); - } + unsigned char red = 200; //randomColorValue(65); + unsigned char green = 200; //randomColorValue(65); + unsigned char blue = 200; //randomColorValue(65); + + unsigned char* voxelCode = pointToVoxel(x, y, z, s,red,green,blue); + printVoxelCode(voxelCode); + delete voxelCode; + printLog("\n"); + } } void sendVoxelServerEraseAll() { - char message[100]; + char message[100]; sprintf(message,"%c%s",'Z',"erase all"); - int messageSize = strlen(message) + 1; - AgentList::getInstance()->broadcastToAgents((unsigned char*) message, messageSize, &AGENT_TYPE_VOXEL, 1); + int messageSize = strlen(message) + 1; + AgentList::getInstance()->broadcastToAgents((unsigned char*) message, messageSize, &AGENT_TYPE_VOXEL, 1); } void sendVoxelServerAddScene() { - char message[100]; + char message[100]; sprintf(message,"%c%s",'Z',"add scene"); - int messageSize = strlen(message) + 1; - AgentList::getInstance()->broadcastToAgents((unsigned char*)message, messageSize, &AGENT_TYPE_VOXEL, 1); + int messageSize = strlen(message) + 1; + AgentList::getInstance()->broadcastToAgents((unsigned char*)message, messageSize, &AGENT_TYPE_VOXEL, 1); } void shiftPaintingColor() { // About the color of the paintbrush... first determine the dominant color ::dominantColor = (::dominantColor+1)%3; // 0=red,1=green,2=blue - ::paintingVoxel.red = (::dominantColor==0)?randIntInRange(200,255):randIntInRange(40,100); - ::paintingVoxel.green = (::dominantColor==1)?randIntInRange(200,255):randIntInRange(40,100); - ::paintingVoxel.blue = (::dominantColor==2)?randIntInRange(200,255):randIntInRange(40,100); + ::paintingVoxel.red = (::dominantColor==0)?randIntInRange(200,255):randIntInRange(40,100); + ::paintingVoxel.green = (::dominantColor==1)?randIntInRange(200,255):randIntInRange(40,100); + ::paintingVoxel.blue = (::dominantColor==2)?randIntInRange(200,255):randIntInRange(40,100); } void setupPaintingVoxel() { - glm::vec3 avatarPos = myAvatar.getPosition(); + glm::vec3 avatarPos = myAvatar.getPosition(); - ::paintingVoxel.x = avatarPos.z/-10.0; // voxel space x is negative z head space - ::paintingVoxel.y = avatarPos.y/-10.0; // voxel space y is negative y head space - ::paintingVoxel.z = avatarPos.x/-10.0; // voxel space z is negative x head space - ::paintingVoxel.s = 1.0/256; - - shiftPaintingColor(); + ::paintingVoxel.x = avatarPos.z/-10.0; // voxel space x is negative z head space + ::paintingVoxel.y = avatarPos.y/-10.0; // voxel space y is negative y head space + ::paintingVoxel.z = avatarPos.x/-10.0; // voxel space z is negative x head space + ::paintingVoxel.s = 1.0/256; + + shiftPaintingColor(); } void addVoxelUnderCursor() { @@ -1518,13 +1518,13 @@ void addVoxelUnderCursor() { break; } unsigned char* bufferOut; - int sizeOut; - - if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &detail, bufferOut, sizeOut)){ + int sizeOut; + + if (createVoxelEditMessage(PACKET_HEADER_SET_VOXEL, 0, 1, &detail, bufferOut, sizeOut)){ AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); - delete bufferOut; - } - } + delete bufferOut; + } + } } void deleteVoxelUnderCursor() { @@ -1536,13 +1536,13 @@ void deleteVoxelUnderCursor() { BoxFace face; if (voxels.findRayIntersection(origin, direction, detail, distance, face)) { unsigned char* bufferOut; - int sizeOut; - - if (createVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, 0, 1, &detail, bufferOut, sizeOut)){ + int sizeOut; + + if (createVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, 0, 1, &detail, bufferOut, sizeOut)){ AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); - delete bufferOut; - } - } + delete bufferOut; + } + } } const float KEYBOARD_YAW_RATE = 0.8; @@ -1627,44 +1627,44 @@ void key(unsigned char k, int x, int y) { return; } - // Process keypresses - if (k == 'q' || k == 'Q') ::terminate(); - if (k == '/') ::renderStatsOn = !::renderStatsOn; // toggle stats - if (k == '*') ::renderStarsOn = !::renderStarsOn; // toggle stars - if (k == 'V' || k == 'v') ::renderVoxels = !::renderVoxels; // toggle voxels + // Process keypresses + if (k == 'q' || k == 'Q') ::terminate(); + if (k == '/') ::renderStatsOn = !::renderStatsOn; // toggle stats + if (k == '*') ::renderStarsOn = !::renderStarsOn; // toggle stars + if (k == 'V' || k == 'v') ::renderVoxels = !::renderVoxels; // toggle voxels if (k == 'A') ::renderAtmosphereOn = !::renderAtmosphereOn; - if (k == 'F') ::frustumOn = !::frustumOn; // toggle view frustum debugging - if (k == 'C') ::cameraFrustum = !::cameraFrustum; // toggle which frustum to look at + if (k == 'F') ::frustumOn = !::frustumOn; // toggle view frustum debugging + if (k == 'C') ::cameraFrustum = !::cameraFrustum; // toggle which frustum to look at if (k == 'O' || k == 'G') setFrustumOffset(MENU_ROW_PICKED); // toggle view frustum offset debugging if (k == 'f') setFullscreen(!::fullscreen); if (k == 'o') setOculus(!::oculusOn); - if (k == '[') ::viewFrustumOffsetYaw -= 0.5; - if (k == ']') ::viewFrustumOffsetYaw += 0.5; - if (k == '{') ::viewFrustumOffsetPitch -= 0.5; - if (k == '}') ::viewFrustumOffsetPitch += 0.5; - if (k == '(') ::viewFrustumOffsetRoll -= 0.5; - if (k == ')') ::viewFrustumOffsetRoll += 0.5; - if (k == '<') ::viewFrustumOffsetDistance -= 0.5; - if (k == '>') ::viewFrustumOffsetDistance += 0.5; - if (k == ',') ::viewFrustumOffsetUp -= 0.05; - if (k == '.') ::viewFrustumOffsetUp += 0.05; + if (k == '[') ::viewFrustumOffsetYaw -= 0.5; + if (k == ']') ::viewFrustumOffsetYaw += 0.5; + if (k == '{') ::viewFrustumOffsetPitch -= 0.5; + if (k == '}') ::viewFrustumOffsetPitch += 0.5; + if (k == '(') ::viewFrustumOffsetRoll -= 0.5; + if (k == ')') ::viewFrustumOffsetRoll += 0.5; + if (k == '<') ::viewFrustumOffsetDistance -= 0.5; + if (k == '>') ::viewFrustumOffsetDistance += 0.5; + if (k == ',') ::viewFrustumOffsetUp -= 0.05; + if (k == '.') ::viewFrustumOffsetUp += 0.05; -// if (k == '|') ViewFrustum::fovAngleAdust -= 0.05; -// if (k == '\\') ViewFrustum::fovAngleAdust += 0.05; +// if (k == '|') ViewFrustum::fovAngleAdust -= 0.05; +// if (k == '\\') ViewFrustum::fovAngleAdust += 0.05; - if (k == 'R') setFrustumRenderMode(MENU_ROW_PICKED); + if (k == 'R') setFrustumRenderMode(MENU_ROW_PICKED); if (k == '&') { - ::paintOn = !::paintOn; // toggle paint - ::setupPaintingVoxel(); // also randomizes colors + ::paintOn = !::paintOn; // toggle paint + ::setupPaintingVoxel(); // also randomizes colors } - if (k == '^') ::shiftPaintingColor(); // shifts randomize color between R,G,B dominant - if (k == '-') ::sendVoxelServerEraseAll(); // sends erase all command to voxel server - if (k == '%') ::sendVoxelServerAddScene(); // sends add scene command to voxel server + if (k == '^') ::shiftPaintingColor(); // shifts randomize color between R,G,B dominant + if (k == '-') ::sendVoxelServerEraseAll(); // sends erase all command to voxel server + if (k == '%') ::sendVoxelServerAddScene(); // sends add scene command to voxel server if (k == '1') ::addVoxelUnderCursor(); if (k == '2') ::deleteVoxelUnderCursor(); - if (k == 'n' || k == 'N') + if (k == 'n' || k == 'N') { noiseOn = !noiseOn; // Toggle noise if (noiseOn) @@ -1758,15 +1758,15 @@ void idle(void) { // Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) { - + float deltaTime = 1.f/FPS; // update behaviors for avatar hand movement: handControl takes mouse values as input, // and gives back 3D values modulated for smooth transitioning between interaction modes. handControl.update(mouseX, mouseY); - myAvatar.setHandMovementValues(handControl.getValues()); + myAvatar.setHandMovementValues(handControl.getValues()); - // tell my avatar if the mouse is being pressed... + // tell my avatar if the mouse is being pressed... if (mousePressed) { myAvatar.setMousePressed(mousePressed); } @@ -1774,7 +1774,7 @@ void idle(void) { // walking triggers the handControl to stop if (myAvatar.getMode() == AVATAR_MODE_WALKING) { handControl.stop(); - } + } // Read serial port interface devices if (serialPort.active && USING_INVENSENSE_MPU9150) { @@ -1787,8 +1787,8 @@ void idle(void) { // read incoming packets from network if (!enableNetworkThread) { networkReceive(0); - } - + } + //loop through all the remote avatars and simulate them... AgentList* agentList = AgentList::getInstance(); agentList->lock(); @@ -1899,19 +1899,19 @@ void mouseFunc(int button, int state, int x, int y) { mouseY = y; mousePressed = 0; } - } + } } void motionFunc(int x, int y) { - mouseX = x; - mouseY = y; + mouseX = x; + mouseY = y; } void mouseoverFunc(int x, int y){ menu.mouseOver(x, y); - mouseX = x; - mouseY = y; + mouseX = x; + mouseY = y; } void attachNewHeadToAgent(Agent *newAgent) { @@ -1947,14 +1947,14 @@ int main(int argc, const char * argv[]) { gettimeofday(&applicationStartupTime, NULL); const char* domainIP = getCmdOption(argc, argv, "--domain"); if (domainIP) { - strcpy(DOMAIN_IP,domainIP); - } + strcpy(DOMAIN_IP,domainIP); + } // Handle Local Domain testing with the --local command line if (cmdOptionExists(argc, argv, "--local")) { - printLog("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)); + printLog("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)); } // the callback for our instance of AgentList is attachNewHeadToAgent @@ -2003,30 +2003,30 @@ int main(int argc, const char * argv[]) { glutDisplayFunc(display); glutReshapeFunc(reshape); - glutKeyboardFunc(key); + glutKeyboardFunc(key); glutKeyboardUpFunc(keyUp); glutSpecialFunc(specialkey); glutSpecialUpFunc(specialkeyUp); - glutMotionFunc(motionFunc); + glutMotionFunc(motionFunc); glutPassiveMotionFunc(mouseoverFunc); - glutMouseFunc(mouseFunc); + glutMouseFunc(mouseFunc); glutIdleFunc(idle); - + init(); printLog( "Init() complete.\n" ); - // Check to see if the user passed in a command line option for randomizing colors - if (cmdOptionExists(argc, argv, "--NoColorRandomizer")) { - wantColorRandomizer = false; - } - - // Check to see if the user passed in a command line option for loading a local - // Voxel File. If so, load it now. + // Check to see if the user passed in a command line option for randomizing colors + if (cmdOptionExists(argc, argv, "--NoColorRandomizer")) { + wantColorRandomizer = false; + } + + // Check to see if the user passed in a command line option for loading a local + // Voxel File. If so, load it now. const char* voxelsFilename = getCmdOption(argc, argv, "-i"); if (voxelsFilename) { - voxels.loadVoxelsFile(voxelsFilename,wantColorRandomizer); + voxels.loadVoxelsFile(voxelsFilename,wantColorRandomizer); printLog("Local Voxel File loaded.\n"); - } + } // create thread for receipt of data via UDP if (enableNetworkThread) { From d9a5bba1d102c25c5a692d04fbff60951051c914 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 11:21:16 -0700 Subject: [PATCH 06/20] remove the unhelpful stack trace setup, using gdb on server for now --- audio-mixer/src/main.cpp | 4 +--- libraries/shared/src/Stacktrace.cpp | 28 ---------------------------- libraries/shared/src/Stacktrace.h | 16 ---------------- 3 files changed, 1 insertion(+), 47 deletions(-) delete mode 100644 libraries/shared/src/Stacktrace.cpp delete mode 100644 libraries/shared/src/Stacktrace.h diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index c47fbb2170..dd128763cd 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include "AudioRingBuffer.h" #include "PacketHeaders.h" @@ -258,8 +257,7 @@ void attachNewBufferToAgent(Agent *newAgent) { } } -int main(int argc, const char* argv[]) { - signal(SIGSEGV, printStacktrace); +int main(int argc, const char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); diff --git a/libraries/shared/src/Stacktrace.cpp b/libraries/shared/src/Stacktrace.cpp deleted file mode 100644 index 0e9b42f50d..0000000000 --- a/libraries/shared/src/Stacktrace.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Stacktrace.cpp -// hifi -// -// Created by Stephen Birarda on 5/6/13. -// -// - -#include -#include -#include -#include - -#include "Stacktrace.h" - -const int NUMBER_OF_STACK_ENTRIES = 20; - -void printStacktrace(int signal) { - void* array[NUMBER_OF_STACK_ENTRIES]; - - // get void*'s for all entries on the stack - size_t size = backtrace(array, NUMBER_OF_STACK_ENTRIES); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", signal); - backtrace_symbols_fd(array, size, 2); - exit(1); -} \ No newline at end of file diff --git a/libraries/shared/src/Stacktrace.h b/libraries/shared/src/Stacktrace.h deleted file mode 100644 index c58422ea0c..0000000000 --- a/libraries/shared/src/Stacktrace.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// Stacktrace.h -// hifi -// -// Created by Stephen Birarda on 5/6/13. -// -// - -#ifndef __hifi__Stacktrace__ -#define __hifi__Stacktrace__ - -#include - -void printStacktrace(int signal); - -#endif /* defined(__hifi__Stacktrace__) */ From e923f5446de57d87c1365809a539f7d1144aa057 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 9 May 2013 11:22:24 -0700 Subject: [PATCH 07/20] clean up --- interface/src/Avatar.cpp | 5 ++++- interface/src/Camera.cpp | 34 +++++++++++++++++----------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index aa343e070c..28eee87afc 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -403,7 +403,10 @@ void Avatar::simulate(float deltaTime) { if (tiltDecay < 0.0f) {tiltDecay = 0.0f;} _bodyPitch *= tiltDecay; _bodyRoll *= tiltDecay; - + + //wtf? - why won't this compile? + //angleBetween(&_orientation.getUp(), &_gravity); + // update position by velocity _position += _velocity * deltaTime; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 2d65337ea7..ed10b8e5fa 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -13,22 +13,22 @@ Camera::Camera() { _frustumNeedsReshape = false; - _mode = CAMERA_MODE_THIRD_PERSON; - _tightness = 10.0; // default - _fieldOfView = 60.0; // default - _nearClip = 0.08; // default - _farClip = 50.0 * TREE_SCALE; // default - _modeShift = 0.0; - _yaw = 0.0; - _pitch = 0.0; - _roll = 0.0; - _upShift = 0.0; - _rightShift = 0.0; - _distance = 0.0; - _idealYaw = 0.0; - _targetPosition = glm::vec3(0.0, 0.0, 0.0); - _position = glm::vec3(0.0, 0.0, 0.0); - _idealPosition = glm::vec3(0.0, 0.0, 0.0); + _mode = CAMERA_MODE_THIRD_PERSON; + _tightness = 10.0; // default + _fieldOfView = 60.0; // default + _nearClip = 0.08; // default + _farClip = 50.0 * TREE_SCALE; // default + _modeShift = 0.0; + _yaw = 0.0; + _pitch = 0.0; + _roll = 0.0; + _upShift = 0.0; + _rightShift = 0.0; + _distance = 0.0; + _idealYaw = 0.0; + _targetPosition = glm::vec3(0.0, 0.0, 0.0); + _position = glm::vec3(0.0, 0.0, 0.0); + _idealPosition = glm::vec3(0.0, 0.0, 0.0); _orientation.setToIdentity(); } @@ -38,7 +38,7 @@ void Camera::update(float deltaTime) { if (_mode == CAMERA_MODE_NULL) { _modeShift = 0.0; } else { - // use iterative forces to keep the camera at the desired position and angle + // use iterative forces to push the camera towards the desired position and angle updateFollowMode(deltaTime); if (_modeShift < 1.0f) { From a92571bdeea3dafba76adb65cca10c60526d97f1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 11:45:59 -0700 Subject: [PATCH 08/20] initialize the _shouldLoopbackForAgent variable --- libraries/shared/src/AudioRingBuffer.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index 5079582544..a399852950 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -9,15 +9,13 @@ #include #include "AudioRingBuffer.h" -AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) { - ringBufferLengthSamples = ringSamples; - bufferLengthSamples = bufferSamples; - - started = false; - _shouldBeAddedToMix = false; - - endOfLastWrite = NULL; - +AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : + ringBufferLengthSamples(ringSamples), + bufferLengthSamples(bufferSamples), + endOfLastWrite(NULL), + started(false), + _shouldBeAddedToMix(false), + _shouldLoopbackForAgent(false) { buffer = new int16_t[ringBufferLengthSamples]; nextOutput = buffer; }; @@ -27,6 +25,7 @@ AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) { bufferLengthSamples = otherRingBuffer.bufferLengthSamples; started = otherRingBuffer.started; _shouldBeAddedToMix = otherRingBuffer._shouldBeAddedToMix; + _shouldLoopbackForAgent = otherRingBuffer._shouldLoopbackForAgent; buffer = new int16_t[ringBufferLengthSamples]; memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples); @@ -149,8 +148,7 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { return numBytes; } -short AudioRingBuffer::diffLastWriteNextOutput() -{ +short AudioRingBuffer::diffLastWriteNextOutput() { if (endOfLastWrite == NULL) { return 0; } else { From 42a50e9bab6b12e703808411bd23b23ebae76843 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 12:05:48 -0700 Subject: [PATCH 09/20] make sure that the AudioRingBuffer exists before trying to use it --- audio-mixer/src/main.cpp | 203 ++++++++++++++++++++------------------- 1 file changed, 105 insertions(+), 98 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index c47fbb2170..5c6781b46e 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -87,7 +87,7 @@ void *sendBuffer(void *args) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); - if (agentBuffer != NULL && agentBuffer->getEndOfLastWrite() != NULL) { + if (agentBuffer && agentBuffer->getEndOfLastWrite() != NULL) { if (!agentBuffer->isStarted() && agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) { @@ -112,124 +112,131 @@ void *sendBuffer(void *args) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData(); - int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; - - for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { - if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { - AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); - - if (otherAgentBuffer->shouldBeAddedToMix()) { - - float bearingRelativeAngleToSource = 0.f; - float attenuationCoefficient = 1.f; - int numSamplesDelay = 0; - float weakChannelAmplitudeRatio = 1.f; + if (agentRingBuffer) { + int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; + + for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { + if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { + AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); - if (otherAgent != agent) { - float *agentPosition = agentRingBuffer->getPosition(); - float *otherAgentPosition = otherAgentBuffer->getPosition(); + if (otherAgentBuffer->shouldBeAddedToMix()) { - // calculate the distance to the other agent + float bearingRelativeAngleToSource = 0.f; + float attenuationCoefficient = 1.f; + int numSamplesDelay = 0; + float weakChannelAmplitudeRatio = 1.f; - // use the distance to the other agent to calculate the change in volume for this frame - int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex()); - int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); - - if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { - float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) + - powf(agentPosition[1] - otherAgentPosition[1], 2) + - powf(agentPosition[2] - otherAgentPosition[2], 2)); + if (otherAgent != agent) { + float *agentPosition = agentRingBuffer->getPosition(); + float *otherAgentPosition = otherAgentBuffer->getPosition(); - float minCoefficient = std::min(1.0f, - powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); - distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; - } - - - // get the angle from the right-angle triangle - float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), - fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI); - float absoluteAngleToSource = 0; - bearingRelativeAngleToSource = 0; - - // find the angle we need for calculation based on the orientation of the triangle - if (otherAgentPosition[0] > agentPosition[0]) { - if (otherAgentPosition[2] > agentPosition[2]) { - absoluteAngleToSource = -90 + triangleAngle; - } else { - absoluteAngleToSource = -90 - triangleAngle; + // 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(agent.getAgentIndex(), otherAgent.getAgentIndex()); + int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); + + if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { + float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) + + powf(agentPosition[1] - otherAgentPosition[1], 2) + + powf(agentPosition[2] - otherAgentPosition[2], 2)); + + float minCoefficient = std::min(1.0f, + powf(0.5, + (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; } - } else { - if (otherAgentPosition[2] > agentPosition[2]) { - absoluteAngleToSource = 90 - triangleAngle; + + + // 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 absoluteAngleToSource = 0; + bearingRelativeAngleToSource = 0; + + // find the angle we need for calculation based on the orientation of the triangle + if (otherAgentPosition[0] > agentPosition[0]) { + if (otherAgentPosition[2] > agentPosition[2]) { + absoluteAngleToSource = -90 + triangleAngle; + } else { + absoluteAngleToSource = -90 - triangleAngle; + } } else { - absoluteAngleToSource = 90 + triangleAngle; + if (otherAgentPosition[2] > agentPosition[2]) { + absoluteAngleToSource = 90 - triangleAngle; + } else { + absoluteAngleToSource = 90 + triangleAngle; + } } - } - - bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing(); - - if (bearingRelativeAngleToSource > 180) { - bearingRelativeAngleToSource -= 360; - } else if (bearingRelativeAngleToSource < -180) { - bearingRelativeAngleToSource += 360; - } - - float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing(); - - if (angleOfDelivery > 180) { - angleOfDelivery -= 360; - } else if (angleOfDelivery < -180) { - angleOfDelivery += 360; - } - - float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + + + bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing(); + + if (bearingRelativeAngleToSource > 180) { + bearingRelativeAngleToSource -= 360; + } else if (bearingRelativeAngleToSource < -180) { + bearingRelativeAngleToSource += 360; + } + + float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing(); + + if (angleOfDelivery > 180) { + angleOfDelivery -= 360; + } else if (angleOfDelivery < -180) { + angleOfDelivery += 360; + } + + float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); - - attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] + + attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] * otherAgentBuffer->getAttenuationRatio() * offAxisCoefficient; - - bearingRelativeAngleToSource *= (M_PI / 180); - - float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); - numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; - weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); - } - - int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix; - int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - - int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() - ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay - : otherAgentBuffer->getNextOutput() - numSamplesDelay; - - for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { - - if (s < numSamplesDelay) { - // pull the earlier sample for the delayed channel - int earlierSample = delaySamplePointer[s] * attenuationCoefficient; - plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); + + bearingRelativeAngleToSource *= (M_PI / 180); + + float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); + numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; + weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } - int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); - plateauAdditionOfSamples(goodChannel[s], currentSample); + int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f + ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL + : clientMix; + int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f + ? clientMix + : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], - currentSample * weakChannelAmplitudeRatio); + int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() + ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay + : otherAgentBuffer->getNextOutput() - numSamplesDelay; + + for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { + + if (s < numSamplesDelay) { + // pull the earlier sample for the delayed channel + int earlierSample = delaySamplePointer[s] * attenuationCoefficient; + plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); + } + + int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); + plateauAdditionOfSamples(goodChannel[s], currentSample); + + if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], + currentSample * weakChannelAmplitudeRatio); + } } } } } - } - - agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); + + agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); + } } for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); - if (agentBuffer->shouldBeAddedToMix()) { + if (agentBuffer && agentBuffer->shouldBeAddedToMix()) { agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL); if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) { From 9ef409b2efbaab554fcc928854a96c5884ad53c5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 12:34:14 -0700 Subject: [PATCH 10/20] perform send of audio buffer on main thread --- audio-mixer/src/main.cpp | 370 +++++++++++++++++++-------------------- 1 file changed, 177 insertions(+), 193 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 5c6781b46e..994fbdf474 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -72,193 +72,6 @@ void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) { mixSample = normalizedSample; } -void *sendBuffer(void *args) { - int sentBytes; - int nextFrame = 0; - timeval startTime; - - AgentList* agentList = AgentList::getInstance(); - - gettimeofday(&startTime, NULL); - - while (true) { - sentBytes = 0; - - for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); - - if (agentBuffer && agentBuffer->getEndOfLastWrite() != NULL) { - - if (!agentBuffer->isStarted() - && agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) { - printf("Held back buffer for agent with ID %d.\n", agent->getAgentId()); - agentBuffer->setShouldBeAddedToMix(false); - } else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - printf("Buffer from agent with ID %d starved.\n", agent->getAgentId()); - agentBuffer->setStarted(false); - agentBuffer->setShouldBeAddedToMix(false); - } else { - // good buffer, add this to the mix - agentBuffer->setStarted(true); - agentBuffer->setShouldBeAddedToMix(true); - } - } - } - - int numAgents = agentList->size(); - float distanceCoefficients[numAgents][numAgents]; - memset(distanceCoefficients, 0, sizeof(distanceCoefficients)); - - for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData(); - - if (agentRingBuffer) { - int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; - - for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { - if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { - AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); - - if (otherAgentBuffer->shouldBeAddedToMix()) { - - float bearingRelativeAngleToSource = 0.f; - float attenuationCoefficient = 1.f; - int numSamplesDelay = 0; - float weakChannelAmplitudeRatio = 1.f; - - if (otherAgent != agent) { - float *agentPosition = agentRingBuffer->getPosition(); - float *otherAgentPosition = otherAgentBuffer->getPosition(); - - // 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(agent.getAgentIndex(), otherAgent.getAgentIndex()); - int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); - - if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { - float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) + - powf(agentPosition[1] - otherAgentPosition[1], 2) + - powf(agentPosition[2] - otherAgentPosition[2], 2)); - - float minCoefficient = std::min(1.0f, - powf(0.5, - (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); - distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; - } - - - // get the angle from the right-angle triangle - float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), - fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI); - float absoluteAngleToSource = 0; - bearingRelativeAngleToSource = 0; - - // find the angle we need for calculation based on the orientation of the triangle - if (otherAgentPosition[0] > agentPosition[0]) { - if (otherAgentPosition[2] > agentPosition[2]) { - absoluteAngleToSource = -90 + triangleAngle; - } else { - absoluteAngleToSource = -90 - triangleAngle; - } - } else { - if (otherAgentPosition[2] > agentPosition[2]) { - absoluteAngleToSource = 90 - triangleAngle; - } else { - absoluteAngleToSource = 90 + triangleAngle; - } - } - - bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing(); - - if (bearingRelativeAngleToSource > 180) { - bearingRelativeAngleToSource -= 360; - } else if (bearingRelativeAngleToSource < -180) { - bearingRelativeAngleToSource += 360; - } - - float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing(); - - if (angleOfDelivery > 180) { - angleOfDelivery -= 360; - } else if (angleOfDelivery < -180) { - angleOfDelivery += 360; - } - - float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + - (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); - - attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] - * otherAgentBuffer->getAttenuationRatio() - * offAxisCoefficient; - - bearingRelativeAngleToSource *= (M_PI / 180); - - float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); - numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; - weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); - } - - int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f - ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL - : clientMix; - int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f - ? clientMix - : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - - int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() - ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay - : otherAgentBuffer->getNextOutput() - numSamplesDelay; - - for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { - - if (s < numSamplesDelay) { - // pull the earlier sample for the delayed channel - int earlierSample = delaySamplePointer[s] * attenuationCoefficient; - plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); - } - - int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); - plateauAdditionOfSamples(goodChannel[s], currentSample); - - if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], - currentSample * weakChannelAmplitudeRatio); - } - } - } - } - } - - agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); - } - } - - for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); - if (agentBuffer && agentBuffer->shouldBeAddedToMix()) { - agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL); - - if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) { - agentBuffer->setNextOutput(agentBuffer->getBuffer()); - } - - agentBuffer->setShouldBeAddedToMix(false); - } - } - - double usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); - - if (usecToSleep > 0) { - usleep(usecToSleep); - } else { - std::cout << "Took too much time, not sleeping!\n"; - } - } - - pthread_exit(0); -} - void attachNewBufferToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL)); @@ -280,13 +93,178 @@ int main(int argc, const char* argv[]) { unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; - pthread_t sendBufferThread; - pthread_create(&sendBufferThread, NULL, sendBuffer, NULL); - sockaddr *agentAddress = new sockaddr; + + int nextFrame = 0; + timeval startTime; + + gettimeofday(&startTime, NULL); while (true) { - if(agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + // enumerate the agents, check if we can add audio from the agent to current mix + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { + AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); + + if (agentBuffer->getEndOfLastWrite() != NULL) { + if (!agentBuffer->isStarted() + && agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) { + printf("Held back buffer for agent with ID %d.\n", agent->getAgentId()); + agentBuffer->setShouldBeAddedToMix(false); + } else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + printf("Buffer from agent with ID %d starved.\n", agent->getAgentId()); + agentBuffer->setStarted(false); + agentBuffer->setShouldBeAddedToMix(false); + } else { + // good buffer, add this to the mix + agentBuffer->setStarted(true); + agentBuffer->setShouldBeAddedToMix(true); + } + } + } + + int numAgents = agentList->size(); + float distanceCoefficients[numAgents][numAgents]; + memset(distanceCoefficients, 0, sizeof(distanceCoefficients)); + + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { + AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData(); + + int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; + + for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { + if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { + AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); + + if (otherAgentBuffer->shouldBeAddedToMix()) { + + float bearingRelativeAngleToSource = 0.f; + float attenuationCoefficient = 1.f; + int numSamplesDelay = 0; + float weakChannelAmplitudeRatio = 1.f; + + if (otherAgent != agent) { + float *agentPosition = agentRingBuffer->getPosition(); + float *otherAgentPosition = otherAgentBuffer->getPosition(); + + // 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(agent.getAgentIndex(), otherAgent.getAgentIndex()); + int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); + + if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { + float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) + + powf(agentPosition[1] - otherAgentPosition[1], 2) + + powf(agentPosition[2] - otherAgentPosition[2], 2)); + + float minCoefficient = std::min(1.0f, + powf(0.5, + (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; + } + + + // get the angle from the right-angle triangle + float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), + fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI); + float absoluteAngleToSource = 0; + bearingRelativeAngleToSource = 0; + + // find the angle we need for calculation based on the orientation of the triangle + if (otherAgentPosition[0] > agentPosition[0]) { + if (otherAgentPosition[2] > agentPosition[2]) { + absoluteAngleToSource = -90 + triangleAngle; + } else { + absoluteAngleToSource = -90 - triangleAngle; + } + } else { + if (otherAgentPosition[2] > agentPosition[2]) { + absoluteAngleToSource = 90 - triangleAngle; + } else { + absoluteAngleToSource = 90 + triangleAngle; + } + } + + bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing(); + + if (bearingRelativeAngleToSource > 180) { + bearingRelativeAngleToSource -= 360; + } else if (bearingRelativeAngleToSource < -180) { + bearingRelativeAngleToSource += 360; + } + + float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing(); + + if (angleOfDelivery > 180) { + angleOfDelivery -= 360; + } else if (angleOfDelivery < -180) { + angleOfDelivery += 360; + } + + float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + + (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); + + attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] + * otherAgentBuffer->getAttenuationRatio() + * offAxisCoefficient; + + bearingRelativeAngleToSource *= (M_PI / 180); + + float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); + numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; + weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); + } + + int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f + ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL + : clientMix; + int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f + ? clientMix + : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; + + int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() + ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay + : otherAgentBuffer->getNextOutput() - numSamplesDelay; + + for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { + + if (s < numSamplesDelay) { + // pull the earlier sample for the delayed channel + int earlierSample = delaySamplePointer[s] * attenuationCoefficient; + plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); + } + + int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); + plateauAdditionOfSamples(goodChannel[s], currentSample); + + if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], + currentSample * weakChannelAmplitudeRatio); + } + } + } + } + } + + agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); + } + + // push forward the next output pointers for any audio buffers we used + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { + AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); + if (agentBuffer && agentBuffer->shouldBeAddedToMix()) { + agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + + if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) { + agentBuffer->setNextOutput(agentBuffer->getBuffer()); + } + + agentBuffer->setShouldBeAddedToMix(false); + } + } + + // pull any new audio data from agents off of the network stack + while (agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) { if (agentList->addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList->getLastAgentID())) { @@ -296,9 +274,15 @@ int main(int argc, const char* argv[]) { agentList->updateAgentWithData(agentAddress, packetData, receivedBytes); } } + + double usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); + + if (usecToSleep > 0) { + usleep(usecToSleep); + } else { + std::cout << "Took too much time, not sleeping!\n"; + } } - pthread_join(sendBufferThread, NULL); - return 0; } From 812f87798432f6b4c1ea3a58fb2d7942e802a4c7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 12:37:39 -0700 Subject: [PATCH 11/20] resolve conflicts on merge with upstream master --- audio-mixer/src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 31da0d5b47..aa8d7a4fee 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -78,7 +78,6 @@ void attachNewBufferToAgent(Agent *newAgent) { } int main(int argc, const char* argv[]) { - signal(SIGSEGV, printStacktrace); setvbuf(stdout, NULL, _IOLBF, 0); AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); From 0a6adc7ed3d5796020ab8b3f56f876b646b5c77c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 12:46:59 -0700 Subject: [PATCH 12/20] make the audio mixer socket non-blocking so it doesn't halt waiting for data --- audio-mixer/src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index aa8d7a4fee..3610efa7cc 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -93,6 +93,9 @@ int main(int argc, const char* argv[]) { sockaddr *agentAddress = new sockaddr; + // make sure our agent socket is non-blocking + agentList->getAgentSocket().setBlocking(false); + int nextFrame = 0; timeval startTime; From a8eb9187f17ce922bcb7049142a56ae1c9700650 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 12:48:20 -0700 Subject: [PATCH 13/20] underscore the sample length variables in AudioRingBuffer --- libraries/shared/src/AudioRingBuffer.cpp | 26 ++++++++++++------------ libraries/shared/src/AudioRingBuffer.h | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index a399852950..072b085c5d 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -10,25 +10,25 @@ #include "AudioRingBuffer.h" AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : - ringBufferLengthSamples(ringSamples), - bufferLengthSamples(bufferSamples), + _ringBufferLengthSamples(ringSamples), + _bufferLengthSamples(bufferSamples), endOfLastWrite(NULL), started(false), _shouldBeAddedToMix(false), _shouldLoopbackForAgent(false) { - buffer = new int16_t[ringBufferLengthSamples]; + buffer = new int16_t[_ringBufferLengthSamples]; nextOutput = buffer; }; AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) { - ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples; - bufferLengthSamples = otherRingBuffer.bufferLengthSamples; + _ringBufferLengthSamples = otherRingBuffer._ringBufferLengthSamples; + _bufferLengthSamples = otherRingBuffer._bufferLengthSamples; started = otherRingBuffer.started; _shouldBeAddedToMix = otherRingBuffer._shouldBeAddedToMix; _shouldLoopbackForAgent = otherRingBuffer._shouldLoopbackForAgent; - buffer = new int16_t[ringBufferLengthSamples]; - memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples); + buffer = new int16_t[_ringBufferLengthSamples]; + memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * _ringBufferLengthSamples); nextOutput = buffer + (otherRingBuffer.nextOutput - otherRingBuffer.buffer); endOfLastWrite = buffer + (otherRingBuffer.endOfLastWrite - otherRingBuffer.buffer); @@ -99,7 +99,7 @@ void AudioRingBuffer::setBearing(float newBearing) { const int AGENT_LOOPBACK_MODIFIER = 307; int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { - if (numBytes > (bufferLengthSamples * sizeof(int16_t))) { + if (numBytes > (_bufferLengthSamples * sizeof(int16_t))) { unsigned char *dataPtr = sourceBuffer + 1; @@ -131,17 +131,17 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { if (endOfLastWrite == NULL) { endOfLastWrite = buffer; - } else if (diffLastWriteNextOutput() > ringBufferLengthSamples - bufferLengthSamples) { + } else if (diffLastWriteNextOutput() > _ringBufferLengthSamples - _bufferLengthSamples) { endOfLastWrite = buffer; nextOutput = buffer; started = false; } - memcpy(endOfLastWrite, sourceBuffer, bufferLengthSamples * sizeof(int16_t)); + memcpy(endOfLastWrite, sourceBuffer, _bufferLengthSamples * sizeof(int16_t)); - endOfLastWrite += bufferLengthSamples; + endOfLastWrite += _bufferLengthSamples; - if (endOfLastWrite >= buffer + ringBufferLengthSamples) { + if (endOfLastWrite >= buffer + _ringBufferLengthSamples) { endOfLastWrite = buffer; } @@ -155,7 +155,7 @@ short AudioRingBuffer::diffLastWriteNextOutput() { short sampleDifference = endOfLastWrite - nextOutput; if (sampleDifference < 0) { - sampleDifference += ringBufferLengthSamples; + sampleDifference += _ringBufferLengthSamples; } return sampleDifference; diff --git a/libraries/shared/src/AudioRingBuffer.h b/libraries/shared/src/AudioRingBuffer.h index 32e4e0c8a9..d939c215ff 100644 --- a/libraries/shared/src/AudioRingBuffer.h +++ b/libraries/shared/src/AudioRingBuffer.h @@ -41,8 +41,8 @@ public: short diffLastWriteNextOutput(); private: - int ringBufferLengthSamples; - int bufferLengthSamples; + int _ringBufferLengthSamples; + int _bufferLengthSamples; float position[3]; float attenuationRatio; float bearing; From 17c61c88c7a94035ad6ea422f588230f224dbf2b Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 9 May 2013 13:04:22 -0700 Subject: [PATCH 14/20] cleaned up avatar slow-down upon nearness; fixed mouse pressed bug; --- interface/src/Avatar.cpp | 27 +++++++++++++++------------ interface/src/Util.cpp | 4 ++-- interface/src/Util.h | 2 +- interface/src/main.cpp | 21 ++++++++++----------- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 8cebf50ee9..bd51ce7f2f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -47,6 +47,8 @@ const float HEAD_MAX_PITCH = 45; const float HEAD_MIN_PITCH = -45; const float HEAD_MAX_YAW = 85; const float HEAD_MIN_YAW = -85; +const float AVATAR_BRAKING_RANGE = 1.6f; +const float AVATAR_BRAKING_STRENGTH = 30.0f; float skinColor [] = {1.0, 0.84, 0.66}; float lightBlue [] = {0.7, 0.8, 1.0}; @@ -404,8 +406,8 @@ void Avatar::simulate(float deltaTime) { _bodyPitch *= tiltDecay; _bodyRoll *= tiltDecay; - //wtf? - why won't this compile? - //angleBetween(&_orientation.getUp(), &_gravity); + //the following will be used to make the avatar upright no matter what gravity is + //float f = angleBetween(_orientation.getUp(), _gravity); // update position by velocity _position += _velocity * deltaTime; @@ -418,15 +420,17 @@ void Avatar::simulate(float deltaTime) { _velocity *= decay; } - // If someone is near, damp velocity as a function of closeness - const float AVATAR_BRAKING_RANGE = 1.6f; - const float AVATAR_BRAKING_STRENGTH = 35.f; - if (_isMine && (_distanceToNearestAvatar < AVATAR_BRAKING_RANGE)) { - _velocity *= - (1.f - deltaTime * AVATAR_BRAKING_STRENGTH * - (AVATAR_BRAKING_RANGE - _distanceToNearestAvatar)); + // If another avatar is near, dampen velocity as a function of closeness + if (_isMine && (_distanceToNearestAvatar < AVATAR_BRAKING_RANGE)) { + float closeness = 1.0f - (_distanceToNearestAvatar / AVATAR_BRAKING_RANGE); + float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime; + if ( drag > 0.0f ) { + _velocity *= drag; + } else { + _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); + } } - + // update head state updateHead(deltaTime); @@ -466,8 +470,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { // Test: Show angle between your fwd vector and nearest avatar glm::vec3 vectorBetweenUs = otherAvatar->getJointPosition(AVATAR_JOINT_PELVIS) - getJointPosition(AVATAR_JOINT_PELVIS); - glm::vec3 myForwardVector = _orientation.getFront(); - printLog("Angle between: %f\n", angleBetween(&vectorBetweenUs, &myForwardVector)); + printLog("Angle between: %f\n", angleBetween(vectorBetweenUs, _orientation.getFront())); */ // test whether shoulders are close enough to allow for reaching to touch hands diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index b8d16ad70b..bf3c568012 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -67,8 +67,8 @@ float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float } // Helper function returns the positive angle in degrees between two 3D vectors -float angleBetween(glm::vec3 * v1, glm::vec3 * v2) { - return acos((glm::dot(*v1, *v2)) / (glm::length(*v1) * glm::length(*v2))) * 180.f / PI; +float angleBetween(const glm::vec3& v1, const glm::vec3& v2) { + return acos((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2))) * 180.f / PI; } // Draw a 3D vector floating in space diff --git a/interface/src/Util.h b/interface/src/Util.h index d4a6ba6b03..3264039067 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -44,7 +44,7 @@ void noiseTest(int w, int h); void drawVector(glm::vec3* vector); -float angleBetween(glm::vec3 * v1, glm::vec3 * v2); +float angleBetween(const glm::vec3& v1, const glm::vec3& v2); double diffclock(timeval *clock1,timeval *clock2); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 4b70f20402..b95bf39a9e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1767,9 +1767,7 @@ void idle(void) { myAvatar.setHandMovementValues(handControl.getValues()); // tell my avatar if the mouse is being pressed... - if (mousePressed) { - myAvatar.setMousePressed(mousePressed); - } + myAvatar.setMousePressed(mousePressed); // walking triggers the handControl to stop if (myAvatar.getMode() == AVATAR_MODE_WALKING) { @@ -1889,19 +1887,20 @@ glm::vec3 getGravity(glm::vec3 pos) { } void mouseFunc(int button, int state, int x, int y) { - if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { - if (state == GLUT_DOWN && !menu.mouseClick(x, y)) { + if ( !menu.mouseClick(x, y)) { // if a menu item was not clicked or unclicked... + if ( button == GLUT_LEFT_BUTTON ) { mouseX = x; mouseY = y; - mousePressed = 1; - } else if (state == GLUT_UP) { - mouseX = x; - mouseY = y; - mousePressed = 0; + if (state == GLUT_DOWN ) { + mousePressed = 1; + } else if (state == GLUT_UP ) { + mousePressed = 0; + } } - } + } } + void motionFunc(int x, int y) { mouseX = x; mouseY = y; From cd69297af236ef7b0085a0763330f4ef4bf0528c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 13:04:42 -0700 Subject: [PATCH 15/20] some refactoring for member variables in AudioRingBuffer --- audio-mixer/src/main.cpp | 20 ++-- libraries/shared/src/AudioRingBuffer.cpp | 117 ++++++----------------- libraries/shared/src/AudioRingBuffer.h | 47 +++++---- 3 files changed, 68 insertions(+), 116 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 3610efa7cc..88cb867df4 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -144,8 +144,8 @@ int main(int argc, const char* argv[]) { float weakChannelAmplitudeRatio = 1.f; if (otherAgent != agent) { - float *agentPosition = agentRingBuffer->getPosition(); - float *otherAgentPosition = otherAgentBuffer->getPosition(); + Position agentPosition = agentRingBuffer->getPosition(); + Position otherAgentPosition = otherAgentBuffer->getPosition(); // calculate the distance to the other agent @@ -154,9 +154,9 @@ int main(int argc, const char* argv[]) { int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex()); if (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) { - float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) + - powf(agentPosition[1] - otherAgentPosition[1], 2) + - powf(agentPosition[2] - otherAgentPosition[2], 2)); + float distanceToAgent = sqrtf(powf(agentPosition.x - otherAgentPosition.x, 2) + + powf(agentPosition.y - otherAgentPosition.y, 2) + + powf(agentPosition.z - otherAgentPosition.z, 2)); float minCoefficient = std::min(1.0f, powf(0.5, @@ -166,20 +166,20 @@ int main(int argc, const char* argv[]) { // 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.z - otherAgentPosition.z), + fabsf(agentPosition.x - otherAgentPosition.x)) * (180 / M_PI); float absoluteAngleToSource = 0; bearingRelativeAngleToSource = 0; // find the angle we need for calculation based on the orientation of the triangle - if (otherAgentPosition[0] > agentPosition[0]) { - if (otherAgentPosition[2] > agentPosition[2]) { + if (otherAgentPosition.x > agentPosition.x) { + if (otherAgentPosition.z > agentPosition.z) { absoluteAngleToSource = -90 + triangleAngle; } else { absoluteAngleToSource = -90 - triangleAngle; } } else { - if (otherAgentPosition[2] > agentPosition[2]) { + if (otherAgentPosition.z > agentPosition.z) { absoluteAngleToSource = 90 - triangleAngle; } else { absoluteAngleToSource = 90 + triangleAngle; diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index 072b085c5d..fb8ecdac86 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -12,90 +12,37 @@ AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : _ringBufferLengthSamples(ringSamples), _bufferLengthSamples(bufferSamples), - endOfLastWrite(NULL), - started(false), + _endOfLastWrite(NULL), + _started(false), _shouldBeAddedToMix(false), _shouldLoopbackForAgent(false) { - buffer = new int16_t[_ringBufferLengthSamples]; - nextOutput = buffer; + + _buffer = new int16_t[_ringBufferLengthSamples]; + _nextOutput = _buffer; }; AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) { _ringBufferLengthSamples = otherRingBuffer._ringBufferLengthSamples; _bufferLengthSamples = otherRingBuffer._bufferLengthSamples; - started = otherRingBuffer.started; + _started = otherRingBuffer._started; _shouldBeAddedToMix = otherRingBuffer._shouldBeAddedToMix; _shouldLoopbackForAgent = otherRingBuffer._shouldLoopbackForAgent; - buffer = new int16_t[_ringBufferLengthSamples]; - memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * _ringBufferLengthSamples); + _buffer = new int16_t[_ringBufferLengthSamples]; + memcpy(_buffer, otherRingBuffer._buffer, sizeof(int16_t) * _ringBufferLengthSamples); - nextOutput = buffer + (otherRingBuffer.nextOutput - otherRingBuffer.buffer); - endOfLastWrite = buffer + (otherRingBuffer.endOfLastWrite - otherRingBuffer.buffer); + _nextOutput = _buffer + (otherRingBuffer._nextOutput - otherRingBuffer._buffer); + _endOfLastWrite = _buffer + (otherRingBuffer._endOfLastWrite - otherRingBuffer._buffer); } AudioRingBuffer::~AudioRingBuffer() { - delete[] buffer; + delete[] _buffer; }; AudioRingBuffer* AudioRingBuffer::clone() const { return new AudioRingBuffer(*this); } -int16_t* AudioRingBuffer::getNextOutput() { - return nextOutput; -} - -void AudioRingBuffer::setNextOutput(int16_t *newPointer) { - nextOutput = newPointer; -} - -int16_t* AudioRingBuffer::getEndOfLastWrite() { - return endOfLastWrite; -} - -void AudioRingBuffer::setEndOfLastWrite(int16_t *newPointer) { - endOfLastWrite = newPointer; -} - -int16_t* AudioRingBuffer::getBuffer() { - return buffer; -} - -bool AudioRingBuffer::isStarted() { - return started; -} - -void AudioRingBuffer::setStarted(bool status) { - started = status; -} - -float* AudioRingBuffer::getPosition() { - return position; -} - -void AudioRingBuffer::setPosition(float *newPosition) { - position[0] = newPosition[0]; - position[1] = newPosition[1]; - position[2] = newPosition[2]; -} - -float AudioRingBuffer::getAttenuationRatio() { - return attenuationRatio; -} - -void AudioRingBuffer::setAttenuationRatio(float newAttenuation) { - attenuationRatio = newAttenuation; -} - -float AudioRingBuffer::getBearing() { - return bearing; -} - -void AudioRingBuffer::setBearing(float newBearing) { - bearing = newBearing; -} - const int AGENT_LOOPBACK_MODIFIER = 307; int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { @@ -103,25 +50,23 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char *dataPtr = sourceBuffer + 1; - for (int p = 0; p < 3; p ++) { - memcpy(&position[p], dataPtr, sizeof(float)); - dataPtr += sizeof(float); - } + memcpy(&_position, dataPtr, sizeof(_position.x) * 3); + dataPtr += (sizeof(_position.x) * 3); unsigned int attenuationByte = *(dataPtr++); - attenuationRatio = attenuationByte / 255.0f; + _attenuationRatio = attenuationByte / 255.0f; - memcpy(&bearing, dataPtr, sizeof(float)); - dataPtr += sizeof(bearing); + memcpy(&_bearing, dataPtr, sizeof(float)); + dataPtr += sizeof(_bearing); - if (bearing > 180 || bearing < -180) { + if (_bearing > 180 || _bearing < -180) { // we were passed an invalid bearing because this agent wants loopback (pressed the H key) _shouldLoopbackForAgent = true; // correct the bearing - bearing = bearing > 0 - ? bearing - AGENT_LOOPBACK_MODIFIER - : bearing + AGENT_LOOPBACK_MODIFIER; + _bearing = _bearing > 0 + ? _bearing - AGENT_LOOPBACK_MODIFIER + : _bearing + AGENT_LOOPBACK_MODIFIER; } else { _shouldLoopbackForAgent = false; } @@ -129,30 +74,30 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer = dataPtr; } - if (endOfLastWrite == NULL) { - endOfLastWrite = buffer; + if (_endOfLastWrite == NULL) { + _endOfLastWrite = _buffer; } else if (diffLastWriteNextOutput() > _ringBufferLengthSamples - _bufferLengthSamples) { - endOfLastWrite = buffer; - nextOutput = buffer; - started = false; + _endOfLastWrite = _buffer; + _nextOutput = _buffer; + _started = false; } - memcpy(endOfLastWrite, sourceBuffer, _bufferLengthSamples * sizeof(int16_t)); + memcpy(_endOfLastWrite, sourceBuffer, _bufferLengthSamples * sizeof(int16_t)); - endOfLastWrite += _bufferLengthSamples; + _endOfLastWrite += _bufferLengthSamples; - if (endOfLastWrite >= buffer + _ringBufferLengthSamples) { - endOfLastWrite = buffer; + if (_endOfLastWrite >= _buffer + _ringBufferLengthSamples) { + _endOfLastWrite = _buffer; } return numBytes; } short AudioRingBuffer::diffLastWriteNextOutput() { - if (endOfLastWrite == NULL) { + if (_endOfLastWrite == NULL) { return 0; } else { - short sampleDifference = endOfLastWrite - nextOutput; + short sampleDifference = _endOfLastWrite - _nextOutput; if (sampleDifference < 0) { sampleDifference += _ringBufferLengthSamples; diff --git a/libraries/shared/src/AudioRingBuffer.h b/libraries/shared/src/AudioRingBuffer.h index d939c215ff..0e0e1ca8bc 100644 --- a/libraries/shared/src/AudioRingBuffer.h +++ b/libraries/shared/src/AudioRingBuffer.h @@ -12,6 +12,12 @@ #include #include "AgentData.h" +struct Position { + float x; + float y; + float z; +}; + class AudioRingBuffer : public AgentData { public: AudioRingBuffer(int ringSamples, int bufferSamples); @@ -21,35 +27,36 @@ public: int parseData(unsigned char* sourceBuffer, int numBytes); AudioRingBuffer* clone() const; - int16_t* getNextOutput(); - void setNextOutput(int16_t *newPointer); - int16_t* getEndOfLastWrite(); - void setEndOfLastWrite(int16_t *newPointer); - int16_t* getBuffer(); - bool isStarted(); - void setStarted(bool status); + int16_t* getNextOutput() const { return _nextOutput; } + void setNextOutput(int16_t *nextOutput) { _nextOutput = nextOutput; } + + int16_t* getEndOfLastWrite() const { return _endOfLastWrite; } + void setEndOfLastWrite(int16_t *endOfLastWrite) { _endOfLastWrite = endOfLastWrite; } + + int16_t* getBuffer() const { return _buffer; } + + bool isStarted() const { return _started; } + void setStarted(bool started) { _started = started; } + bool shouldBeAddedToMix() const { return _shouldBeAddedToMix; } void setShouldBeAddedToMix(bool shouldBeAddedToMix) { _shouldBeAddedToMix = shouldBeAddedToMix; } - float* getPosition(); - void setPosition(float newPosition[]); - float getAttenuationRatio(); - void setAttenuationRatio(float newAttenuation); - float getBearing(); - void setBearing(float newBearing); + const Position& getPosition() const { return _position; } + float getAttenuationRatio() const { return _attenuationRatio; } + float getBearing() const { return _bearing; } bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; } short diffLastWriteNextOutput(); private: int _ringBufferLengthSamples; int _bufferLengthSamples; - float position[3]; - float attenuationRatio; - float bearing; - int16_t *nextOutput; - int16_t *endOfLastWrite; - int16_t *buffer; - bool started; + Position _position; + float _attenuationRatio; + float _bearing; + int16_t* _nextOutput; + int16_t* _endOfLastWrite; + int16_t* _buffer; + bool _started; bool _shouldBeAddedToMix; bool _shouldLoopbackForAgent; }; From b61a9687f8f9ae21ea379ff40ed6fec8ae5e5759 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 9 May 2013 13:14:08 -0700 Subject: [PATCH 16/20] thingy --- interface/src/Avatar.cpp | 2 +- interface/src/AvatarTouch.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bd51ce7f2f..6a99cec79f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -485,7 +485,7 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (_interactingOther) { _avatarTouch.setYourBodyPosition(_interactingOther->_position); - _avatarTouch.setYourHandPosition(_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); + _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); } diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 89e9889005..b8f5f6ebd3 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -63,8 +63,8 @@ void AvatarTouch::setReachableRadius(float r) { void AvatarTouch::render(glm::vec3 cameraPosition) { - if (_canReachToOtherAvatar) { - +if (_canReachToOtherAvatar) +{ glColor4f(0.3, 0.4, 0.5, 0.5); glm::vec3 p(_yourBodyPosition); p.y = 0.0005f; From 23f861f5e2e27937aa131e5e646e9bca8302d24b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 9 May 2013 13:30:11 -0700 Subject: [PATCH 17/20] fixes per code review comments --- audio-mixer/src/main.cpp | 20 ++++++++++---------- libraries/shared/src/AudioRingBuffer.cpp | 8 ++++---- libraries/shared/src/AudioRingBuffer.h | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 88cb867df4..52889cee8e 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -72,7 +72,7 @@ void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) { } void attachNewBufferToAgent(Agent *newAgent) { - if (newAgent->getLinkedData() == NULL) { + if (!newAgent->getLinkedData()) { newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL)); } } @@ -89,9 +89,9 @@ int main(int argc, const char* argv[]) { agentList->startSilentAgentRemovalThread(); agentList->startDomainServerCheckInThread(); - unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; + unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; - sockaddr *agentAddress = new sockaddr; + sockaddr* agentAddress = new sockaddr; // make sure our agent socket is non-blocking agentList->getAgentSocket().setBlocking(false); @@ -106,7 +106,7 @@ int main(int argc, const char* argv[]) { for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); - if (agentBuffer->getEndOfLastWrite() != NULL) { + if (agentBuffer->getEndOfLastWrite()) { if (!agentBuffer->isStarted() && agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) { printf("Held back buffer for agent with ID %d.\n", agent->getAgentId()); @@ -217,15 +217,15 @@ int main(int argc, const char* argv[]) { } int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f - ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL - : clientMix; + ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL + : clientMix; int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f - ? clientMix - : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; + ? clientMix + : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() - ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay - : otherAgentBuffer->getNextOutput() - numSamplesDelay; + ? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay + : otherAgentBuffer->getNextOutput() - numSamplesDelay; for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index fb8ecdac86..b49b65945c 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -50,8 +50,8 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char *dataPtr = sourceBuffer + 1; - memcpy(&_position, dataPtr, sizeof(_position.x) * 3); - dataPtr += (sizeof(_position.x) * 3); + memcpy(&_position, dataPtr, sizeof(_position)); + dataPtr += (sizeof(_position)); unsigned int attenuationByte = *(dataPtr++); _attenuationRatio = attenuationByte / 255.0f; @@ -74,7 +74,7 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer = dataPtr; } - if (_endOfLastWrite == NULL) { + if (!_endOfLastWrite) { _endOfLastWrite = _buffer; } else if (diffLastWriteNextOutput() > _ringBufferLengthSamples - _bufferLengthSamples) { _endOfLastWrite = _buffer; @@ -94,7 +94,7 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { } short AudioRingBuffer::diffLastWriteNextOutput() { - if (_endOfLastWrite == NULL) { + if (!_endOfLastWrite) { return 0; } else { short sampleDifference = _endOfLastWrite - _nextOutput; diff --git a/libraries/shared/src/AudioRingBuffer.h b/libraries/shared/src/AudioRingBuffer.h index 0e0e1ca8bc..fb739629c9 100644 --- a/libraries/shared/src/AudioRingBuffer.h +++ b/libraries/shared/src/AudioRingBuffer.h @@ -28,10 +28,10 @@ public: AudioRingBuffer* clone() const; int16_t* getNextOutput() const { return _nextOutput; } - void setNextOutput(int16_t *nextOutput) { _nextOutput = nextOutput; } + void setNextOutput(int16_t* nextOutput) { _nextOutput = nextOutput; } int16_t* getEndOfLastWrite() const { return _endOfLastWrite; } - void setEndOfLastWrite(int16_t *endOfLastWrite) { _endOfLastWrite = endOfLastWrite; } + void setEndOfLastWrite(int16_t* endOfLastWrite) { _endOfLastWrite = endOfLastWrite; } int16_t* getBuffer() const { return _buffer; } From 14b943f1f75e80260b9d8de44e52dd7d45c5a8a9 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 9 May 2013 13:48:05 -0700 Subject: [PATCH 18/20] added lean code for Philip... --- interface/src/Avatar.cpp | 36 ++++++++++++++++++++++++++++++++--- interface/src/AvatarTouch.cpp | 1 - 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 6a99cec79f..a072615fa2 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -487,6 +487,12 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); + + //_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition = + //_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition; + + //_handHoldingPosition + } }//if (_isMine) @@ -515,14 +521,38 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { void Avatar::updateHead(float deltaTime) { + // hold on to this - used for testing.... + static float test = 0.0f; + test += deltaTime; + _head.leanForward = 0.02 * sin( test * 0.2f ); + _head.leanSideways = 0.02 * sin( test * 0.3f ); + //apply the head lean values to the springy position... - if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) { + if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) + { glm::vec3 headLean = _orientation.getRight() * _head.leanSideways + _orientation.getFront() * _head.leanForward; - _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean; + + // this is not a long-term solution, but it works ok for initial purposes... + _joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; + _joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; + _joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f; + _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition += headLean * 1.0f; + + _joint[ AVATAR_JOINT_LEFT_COLLAR ].springyPosition += headLean * 0.6f; + _joint[ AVATAR_JOINT_LEFT_SHOULDER ].springyPosition += headLean * 0.6f; + _joint[ AVATAR_JOINT_LEFT_ELBOW ].springyPosition += headLean * 0.2f; + _joint[ AVATAR_JOINT_LEFT_WRIST ].springyPosition += headLean * 0.1f; + _joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].springyPosition += headLean * 0.0f; + + _joint[ AVATAR_JOINT_RIGHT_COLLAR ].springyPosition += headLean * 0.6f; + _joint[ AVATAR_JOINT_RIGHT_SHOULDER ].springyPosition += headLean * 0.6f; + _joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f; + _joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f; + _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; } - + // Decay head back to center if turned on if (_returnHeadToCenter) { // Decay back toward center diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index b8f5f6ebd3..d5d77fbbdc 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -113,7 +113,6 @@ if (_canReachToOtherAvatar) } } - void AvatarTouch::simulate (float deltaTime) { glm::vec3 v = _yourBodyPosition - _myBodyPosition; From 14d47d87d8df7057de9434b903f25ff5f18d32d2 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 9 May 2013 13:52:03 -0700 Subject: [PATCH 19/20] thingy --- interface/src/Avatar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index a072615fa2..1107368723 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -522,10 +522,12 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { void Avatar::updateHead(float deltaTime) { // hold on to this - used for testing.... + /* static float test = 0.0f; test += deltaTime; _head.leanForward = 0.02 * sin( test * 0.2f ); _head.leanSideways = 0.02 * sin( test * 0.3f ); + */ //apply the head lean values to the springy position... if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) From 8ecfbce15eca4acd693deaddb1ea6ba2d98a4d02 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 9 May 2013 14:00:40 -0700 Subject: [PATCH 20/20] fixed some small formatting things --- interface/src/Avatar.cpp | 7 +++---- interface/src/AvatarTouch.cpp | 3 +-- interface/src/Camera.cpp | 32 ++++++++++++++++---------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 1107368723..2679815573 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -488,8 +488,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); - //_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition = - //_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition; + _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = + _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition; //_handHoldingPosition @@ -530,8 +530,7 @@ void Avatar::updateHead(float deltaTime) { */ //apply the head lean values to the springy position... - if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) - { + if (fabs(_head.leanSideways + _head.leanForward) > 0.0f) { glm::vec3 headLean = _orientation.getRight() * _head.leanSideways + _orientation.getFront() * _head.leanForward; diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index d5d77fbbdc..d77c7a0a91 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -63,8 +63,7 @@ void AvatarTouch::setReachableRadius(float r) { void AvatarTouch::render(glm::vec3 cameraPosition) { -if (_canReachToOtherAvatar) -{ +if (_canReachToOtherAvatar) { glColor4f(0.3, 0.4, 0.5, 0.5); glm::vec3 p(_yourBodyPosition); p.y = 0.0005f; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index ed10b8e5fa..fdb21656fd 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -13,23 +13,23 @@ Camera::Camera() { _frustumNeedsReshape = false; - _mode = CAMERA_MODE_THIRD_PERSON; - _tightness = 10.0; // default - _fieldOfView = 60.0; // default - _nearClip = 0.08; // default - _farClip = 50.0 * TREE_SCALE; // default + _mode = CAMERA_MODE_THIRD_PERSON; + _tightness = 10.0; // default + _fieldOfView = 60.0; // default + _nearClip = 0.08; // default + _farClip = 50.0 * TREE_SCALE; // default _modeShift = 0.0; - _yaw = 0.0; - _pitch = 0.0; - _roll = 0.0; - _upShift = 0.0; - _rightShift = 0.0; - _distance = 0.0; - _idealYaw = 0.0; - _targetPosition = glm::vec3(0.0, 0.0, 0.0); - _position = glm::vec3(0.0, 0.0, 0.0); - _idealPosition = glm::vec3(0.0, 0.0, 0.0); - _orientation.setToIdentity(); + _yaw = 0.0; + _pitch = 0.0; + _roll = 0.0; + _upShift = 0.0; + _rightShift = 0.0; + _distance = 0.0; + _idealYaw = 0.0; + _targetPosition = glm::vec3(0.0, 0.0, 0.0); + _position = glm::vec3(0.0, 0.0, 0.0); + _idealPosition = glm::vec3(0.0, 0.0, 0.0); + _orientation.setToIdentity(); }