diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index c47fbb2170..52889cee8e 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" @@ -72,23 +71,42 @@ void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) { mixSample = normalizedSample; } -void *sendBuffer(void *args) { - int sentBytes; +void attachNewBufferToAgent(Agent *newAgent) { + if (!newAgent->getLinkedData()) { + newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL)); + } +} + +int main(int argc, const char* argv[]) { + setvbuf(stdout, NULL, _IOLBF, 0); + + AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); + + ssize_t receivedBytes = 0; + + agentList->linkedDataCreateCallback = attachNewBufferToAgent; + + agentList->startSilentAgentRemovalThread(); + agentList->startDomainServerCheckInThread(); + + unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; + + sockaddr* agentAddress = new sockaddr; + + // make sure our agent socket is non-blocking + agentList->getAgentSocket().setBlocking(false); + int nextFrame = 0; timeval startTime; - AgentList* agentList = AgentList::getInstance(); - gettimeofday(&startTime, NULL); - + while (true) { - sentBytes = 0; - + // 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 != NULL && 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()); @@ -108,10 +126,10 @@ void *sendBuffer(void *args) { 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++) { @@ -119,15 +137,15 @@ void *sendBuffer(void *args) { 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(); + Position agentPosition = agentRingBuffer->getPosition(); + Position otherAgentPosition = otherAgentBuffer->getPosition(); // calculate the distance to the other agent @@ -136,31 +154,32 @@ void *sendBuffer(void *args) { 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, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + 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 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; @@ -184,11 +203,11 @@ void *sendBuffer(void *args) { } float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + - (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); + (OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f)); attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex] - * otherAgentBuffer->getAttenuationRatio() - * offAxisCoefficient; + * otherAgentBuffer->getAttenuationRatio() + * offAxisCoefficient; bearingRelativeAngleToSource *= (M_PI / 180); @@ -197,13 +216,17 @@ void *sendBuffer(void *args) { 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* 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) { @@ -227,9 +250,10 @@ void *sendBuffer(void *args) { 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->shouldBeAddedToMix()) { + if (agentBuffer && agentBuffer->shouldBeAddedToMix()) { agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL); if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) { @@ -240,46 +264,8 @@ void *sendBuffer(void *args) { } } - 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)); - } -} - -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); - - ssize_t receivedBytes = 0; - - agentList->linkedDataCreateCallback = attachNewBufferToAgent; - - agentList->startSilentAgentRemovalThread(); - agentList->startDomainServerCheckInThread(); - - unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; - - pthread_t sendBufferThread; - pthread_create(&sendBufferThread, NULL, sendBuffer, NULL); - - sockaddr *agentAddress = new sockaddr; - - while (true) { - if(agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + // 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())) { @@ -289,9 +275,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; } diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index dd181b63e5..cc7df02659 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 = 2.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; @@ -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}; @@ -397,23 +399,33 @@ void Avatar::simulate(float deltaTime) { if (tiltDecay < 0.0f) {tiltDecay = 0.0f;} _bodyPitch *= tiltDecay; _bodyRoll *= tiltDecay; - + + //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; // decay velocity - _velocity *= (1.0 - LIN_VEL_DECAY * deltaTime); - - // 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)); + float decay = 1.0 - VELOCITY_DECAY * deltaTime; + if ( decay < 0.0 ) { + _velocity = glm::vec3( 0.0f, 0.0f, 0.0f ); + } else { + _velocity *= decay; } - - // update head information + + // 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); // use speed and angular velocity to determine walking vs. standing @@ -452,8 +464,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 @@ -468,8 +479,14 @@ 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); + + _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = + _interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition; + + //_handHoldingPosition + } }//if (_isMine) @@ -498,14 +515,39 @@ 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) { 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 89e9889005..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; @@ -113,7 +112,6 @@ void AvatarTouch::render(glm::vec3 cameraPosition) { } } - void AvatarTouch::simulate (float deltaTime) { glm::vec3 v = _yourBodyPosition - _myBodyPosition; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 2d65337ea7..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 - _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(); + _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) { 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/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 696c2bf0af..6f2bbc24f3 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -679,3 +679,19 @@ void VoxelSystem::removeOutOfView() { ); } } + +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, face)) { + 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 03877206ab..3c95edb6ae 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,9 @@ public: void removeOutOfView(); bool hasViewChanged(); + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + VoxelDetail& detail, float& distance, BoxFace& face); + private: int _callsToTreesToArrays; VoxelNodeBag _removedVoxels; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 654f9143f8..796460caa2 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 @@ -148,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 @@ -211,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 @@ -240,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); @@ -276,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) { @@ -321,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); @@ -462,25 +461,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; + } + } } } @@ -488,7 +487,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 @@ -505,19 +504,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(); @@ -540,7 +539,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); @@ -557,7 +556,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: @@ -584,102 +583,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); @@ -706,7 +705,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 @@ -717,8 +716,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); @@ -726,12 +725,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(); @@ -753,8 +752,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 @@ -976,11 +975,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(); @@ -988,7 +987,7 @@ void displayOverlay() { void display(void) { - PerfStat("display"); + PerfStat("display"); glEnable(GL_LINE_SMOOTH); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -997,22 +996,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 @@ -1020,10 +1003,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; @@ -1053,7 +1036,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)); @@ -1067,7 +1050,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)); @@ -1077,7 +1060,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)); @@ -1094,7 +1077,7 @@ void display(void) myCamera.setTargetPosition(myAvatar.getHeadPosition()); myCamera.setTargetYaw (myAvatar.getBodyYaw()); myCamera.setRoll (0.0); - } + } // important... @@ -1110,19 +1093,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()); @@ -1132,19 +1115,35 @@ 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); - + + // 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); @@ -1302,7 +1301,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; } @@ -1359,25 +1358,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() { @@ -1423,55 +1422,117 @@ 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() { + glm::vec3 origin, direction; + viewFrustum.computePickRay(mouseX / (float)WIDTH, mouseY / (float)HEIGHT, origin, direction); + + VoxelDetail detail; + float distance; + 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; + + 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; + 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)){ + AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); + delete bufferOut; + } + } } const float KEYBOARD_YAW_RATE = 0.8; @@ -1556,42 +1617,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 == 'n' || k == 'N') + 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 if (noiseOn) @@ -1685,23 +1748,21 @@ 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... - if (mousePressed) { - myAvatar.setMousePressed(mousePressed); - } + // tell my avatar if the mouse is being pressed... + myAvatar.setMousePressed(mousePressed); // walking triggers the handControl to stop if (myAvatar.getMode() == AVATAR_MODE_WALKING) { handControl.stop(); - } + } // Read serial port interface devices if (serialPort.active) { @@ -1714,8 +1775,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(); @@ -1812,29 +1873,30 @@ 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; + 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) { @@ -1870,14 +1932,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 @@ -1926,30 +1988,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) { diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index 5079582544..b49b65945c 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -9,120 +9,64 @@ #include #include "AudioRingBuffer.h" -AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) { - ringBufferLengthSamples = ringSamples; - bufferLengthSamples = bufferSamples; - - started = false; - _shouldBeAddedToMix = false; - - endOfLastWrite = NULL; - - buffer = new int16_t[ringBufferLengthSamples]; - nextOutput = buffer; +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; }; AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) { - ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples; - bufferLengthSamples = otherRingBuffer.bufferLengthSamples; - started = otherRingBuffer.started; + _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); + _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) { - if (numBytes > (bufferLengthSamples * sizeof(int16_t))) { + if (numBytes > (_bufferLengthSamples * sizeof(int16_t))) { 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)); + dataPtr += (sizeof(_position)); 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; } @@ -130,34 +74,33 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer = dataPtr; } - if (endOfLastWrite == NULL) { - endOfLastWrite = buffer; - } else if (diffLastWriteNextOutput() > ringBufferLengthSamples - bufferLengthSamples) { - endOfLastWrite = buffer; - nextOutput = buffer; - started = false; + if (!_endOfLastWrite) { + _endOfLastWrite = _buffer; + } 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) { - endOfLastWrite = buffer; + if (_endOfLastWrite >= _buffer + _ringBufferLengthSamples) { + _endOfLastWrite = _buffer; } return numBytes; } -short AudioRingBuffer::diffLastWriteNextOutput() -{ - if (endOfLastWrite == NULL) { +short AudioRingBuffer::diffLastWriteNextOutput() { + if (!_endOfLastWrite) { return 0; } else { - short sampleDifference = endOfLastWrite - nextOutput; + 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..fb739629c9 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; + int _ringBufferLengthSamples; + int _bufferLengthSamples; + Position _position; + float _attenuationRatio; + float _bearing; + int16_t* _nextOutput; + int16_t* _endOfLastWrite; + int16_t* _buffer; + bool _started; bool _shouldBeAddedToMix; bool _shouldLoopbackForAgent; }; 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__) */ 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);