diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index b1e2117db3..d84dd64a1b 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -94,8 +94,6 @@ int main(int argc, const char * argv[]) agentList->startSilentAgentRemovalThread(); - uint16_t packetAgentID = 0; - while (true) { if (agentList->getAgentSocket()->receive((sockaddr *)&agentPublicAddress, packetData, &receivedBytes) && (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_HEADER_DOMAIN_LIST_REQUEST)) { @@ -135,25 +133,26 @@ int main(int argc, const char * argv[]) if (numInterestTypes > 0) { // if the agent has sent no types of interest, assume they want nothing but their own ID back for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType) - && memchr(agentTypesOfInterest, agent->getType(), numInterestTypes)) { - // this is not the agent themselves - // and this is an agent of a type in the passed agent types of interest - // or the agent did not pass us any specific types they are interested in + if (!agent->matches((sockaddr*) &agentPublicAddress, (sockaddr*) &agentLocalAddress, agentType)) { + if (memchr(agentTypesOfInterest, agent->getType(), numInterestTypes)) { + // this is not the agent themselves + // and this is an agent of a type in the passed agent types of interest + // or the agent did not pass us any specific types they are interested in - if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) { - // this is an agent of which there can be multiple, just add them to the packet - // don't send avatar agents to other avatars, that will come from avatar mixer - if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) { - currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); - } + if (memchr(SOLO_AGENT_TYPES, agent->getType(), sizeof(SOLO_AGENT_TYPES)) == NULL) { + // this is an agent of which there can be multiple, just add them to the packet + // don't send avatar agents to other avatars, that will come from avatar mixer + if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) { + currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); + } - } else { - // solo agent, we need to only send newest - if (newestSoloAgents[agent->getType()] == NULL || - newestSoloAgents[agent->getType()]->getWakeMicrostamp() < agent->getWakeMicrostamp()) { - // we have to set the newer solo agent to add it to the broadcast later - newestSoloAgents[agent->getType()] = &(*agent); + } else { + // solo agent, we need to only send newest + if (newestSoloAgents[agent->getType()] == NULL || + newestSoloAgents[agent->getType()]->getWakeMicrostamp() < agent->getWakeMicrostamp()) { + // we have to set the newer solo agent to add it to the broadcast later + newestSoloAgents[agent->getType()] = &(*agent); + } } } } else { @@ -162,9 +161,6 @@ int main(int argc, const char * argv[]) // this is the agent, just update last receive to now agent->setLastHeardMicrostamp(timeNow); - // grab the ID for this agent so we can send it back with the packet - packetAgentID = agent->getAgentID(); - if (packetData[0] == PACKET_HEADER_DOMAIN_REPORT_FOR_DUTY && memchr(SOLO_AGENT_TYPES, agentType, sizeof(SOLO_AGENT_TYPES))) { agent->setWakeMicrostamp(timeNow); @@ -181,7 +177,7 @@ int main(int argc, const char * argv[]) } // add the agent ID to the end of the pointer - currentBufferPos += packAgentId(currentBufferPos, packetAgentID); + currentBufferPos += packAgentId(currentBufferPos, newAgent->getAgentID()); // send the constructed list back to this agent agentList->getAgentSocket()->send((sockaddr*) &agentPublicAddress, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0db20f3526..5d6ac99b7a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -146,7 +146,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _viewFrustumOffsetDistance(25.0), _viewFrustumOffsetUp(0.0), _audioScope(256, 200, true), - _manualFirstPerson(false), _mouseX(0), _mouseY(0), _mousePressed(false), @@ -172,7 +171,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _window->setWindowTitle("Interface"); printLog("Interface Startup:\n"); - unsigned int listenPort = AGENT_SOCKET_LISTEN_PORT; + unsigned int listenPort = 0; // bind to an ephemeral port by default const char** constArgv = const_cast(argv); const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); if (portStr) { @@ -829,6 +828,7 @@ void Application::terminate() { static void sendAvatarVoxelURLMessage(const QUrl& url) { uint16_t ownerID = AgentList::getInstance()->getOwnerID(); + if (ownerID == UNKNOWN_AGENT_ID) { return; // we don't yet know who we are } @@ -882,6 +882,10 @@ void Application::editPreferences() { headCameraPitchYawScale->setValue(_headCameraPitchYawScale); form->addRow("Head Camera Pitch/Yaw Scale:", headCameraPitchYawScale); + QDoubleSpinBox* leanScale = new QDoubleSpinBox(); + leanScale->setValue(_myAvatar.getLeanScale()); + form->addRow("Lean Scale:", leanScale); + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); @@ -895,6 +899,7 @@ void Application::editPreferences() { sendAvatarVoxelURLMessage(url); _headCameraPitchYawScale = headCameraPitchYawScale->value(); + _myAvatar.setLeanScale(leanScale->value()); } void Application::pair() { @@ -905,6 +910,8 @@ void Application::setHead(bool head) { if (head) { _myCamera.setMode(CAMERA_MODE_MIRROR); _myCamera.setModeShiftRate(100.0f); + _manualFirstPerson->setChecked(false); + } else { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); _myCamera.setModeShiftRate(1.0f); @@ -922,7 +929,9 @@ void Application::setFullscreen(bool fullscreen) { } void Application::setRenderFirstPerson(bool firstPerson) { - _manualFirstPerson = firstPerson; + if (firstPerson && _lookingInMirror->isChecked()) { + _lookingInMirror->trigger(); + } } void Application::setFrustumOffset(bool frustumOffset) { @@ -1251,8 +1260,8 @@ void Application::initMenu() { _renderFrameTimerOn->setChecked(false); (_renderLookatOn = renderMenu->addAction("Lookat Vectors"))->setCheckable(true); _renderLookatOn->setChecked(false); - - renderMenu->addAction("First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P)->setCheckable(true); + (_manualFirstPerson = renderMenu->addAction( + "First Person", this, SLOT(setRenderFirstPerson(bool)), Qt::Key_P))->setCheckable(true); QMenu* toolsMenu = menuBar->addMenu("Tools"); (_renderStatsOn = toolsMenu->addAction("Stats"))->setCheckable(true); @@ -1572,7 +1581,7 @@ void Application::update(float deltaTime) { } } else { if (_myCamera.getMode() != CAMERA_MODE_MIRROR && !OculusManager::isConnected()) { - if (_manualFirstPerson) { + if (_manualFirstPerson->isChecked()) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON ) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); _myCamera.setModeShiftRate(1.0f); diff --git a/interface/src/Application.h b/interface/src/Application.h index 4d99d73001..fb63cafced 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -192,6 +192,7 @@ private: QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats QAction* _renderFrameTimerOn; // Whether to show onscreen text overlay with stats QAction* _renderLookatOn; // Whether to show lookat vectors from avatar eyes if looking at something + QAction* _manualFirstPerson; // Whether to force first-person mode QAction* _logOn; // Whether to show on-screen log QActionGroup* _voxelModeActions; // The group of voxel edit mode actions QAction* _addVoxelMode; // Whether add voxel mode is enabled @@ -255,7 +256,6 @@ private: Environment _environment; int _headMouseX, _headMouseY; - bool _manualFirstPerson; float _headCameraPitchYawScale; HandControl _handControl; diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index e33624467e..771ce8e7e5 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -74,12 +74,12 @@ Avatar::Avatar(Agent* owningAgent) : _bodyRollDelta(0.0f), _movedHandOffset(0.0f, 0.0f, 0.0f), _mode(AVATAR_MODE_STANDING), - _cameraPosition(0.0f, 0.0f, 0.0f), _handHoldingPosition(0.0f, 0.0f, 0.0f), _velocity(0.0f, 0.0f, 0.0f), _thrust(0.0f, 0.0f, 0.0f), _speed(0.0f), _maxArmLength(0.0f), + _leanScale(0.5f), _pelvisStandingHeight(0.0f), _pelvisFloatingHeight(0.0f), _distanceToNearestAvatar(std::numeric_limits::max()), @@ -287,7 +287,7 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa _head.setRoll(estimatedRotation.z * AMPLIFY_ROLL); // Update torso lean distance based on accelerometer data - glm::vec3 estimatedPosition = serialInterface->getEstimatedPosition(); + glm::vec3 estimatedPosition = serialInterface->getEstimatedPosition() * _leanScale; const float TORSO_LENGTH = 0.5f; const float MAX_LEAN = 45.0f; _head.setLeanSideways(glm::clamp(glm::degrees(atanf(-estimatedPosition.x / TORSO_LENGTH)), -MAX_LEAN, MAX_LEAN)); @@ -584,7 +584,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // set head lookat position if (!_owningAgent) { if (_interactingOther) { - _head.setLookAtPosition(_interactingOther->caclulateAverageEyePosition()); + _head.setLookAtPosition(_interactingOther->calculateAverageEyePosition()); } else { _head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); // 0,0,0 represents NOT looking at anything } @@ -914,9 +914,7 @@ void Avatar::setGravity(glm::vec3 gravity) { } void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) { - - _cameraPosition = Application::getInstance()->getCamera()->getPosition(); - + if (!_owningAgent && usingBigSphereCollisionTest) { // show TEST big sphere glColor4f(0.5f, 0.6f, 0.8f, 0.7); @@ -935,7 +933,7 @@ void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) { // if this is my avatar, then render my interactions with the other avatar if (!_owningAgent) { - _avatarTouch.render(getCameraPosition()); + _avatarTouch.render(Application::getInstance()->getCamera()->getPosition()); } // Render the balls @@ -1134,17 +1132,15 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { } float Avatar::getBallRenderAlpha(int ball, bool lookingInMirror) const { - const float RENDER_OPAQUE_BEYOND = 1.0f; // Meters beyond which body is shown opaque - const float RENDER_TRANSLUCENT_BEYOND = 0.5f; - float distanceToCamera = glm::length(_cameraPosition - _bodyBall[ball].position); + const float RENDER_OPAQUE_OUTSIDE = 1.25f; // render opaque if greater than this distance + const float DO_NOT_RENDER_INSIDE = 0.75f; // do not render if less than this distance + float distanceToCamera = glm::length(Application::getInstance()->getCamera()->getPosition() - _bodyBall[ball].position); return (lookingInMirror || _owningAgent) ? 1.0f : glm::clamp( - (distanceToCamera - RENDER_TRANSLUCENT_BEYOND) / (RENDER_OPAQUE_BEYOND - RENDER_TRANSLUCENT_BEYOND), 0.f, 1.f); + (distanceToCamera - DO_NOT_RENDER_INSIDE) / (RENDER_OPAQUE_OUTSIDE - DO_NOT_RENDER_INSIDE), 0.f, 1.f); } void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) { - - // Render the body as balls and cones if (renderAvatarBalls || !_voxels.getVoxelURL().isValid()) { for (int b = 0; b < NUM_AVATAR_BODY_BALLS; b++) { @@ -1153,7 +1149,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) { // Always render other people, and render myself when beyond threshold distance if (b == BODY_BALL_HEAD_BASE) { // the head is rendered as a special if (alpha > 0.0f) { - _head.render(lookingInMirror, _cameraPosition, alpha); + _head.render(lookingInMirror, alpha); } } else if (alpha > 0.0f) { // Render the body ball sphere @@ -1228,6 +1224,8 @@ void Avatar::loadData(QSettings* settings) { _voxels.setVoxelURL(settings->value("voxelURL").toUrl()); + _leanScale = loadSetting(settings, "leanScale", 0.5f); + settings->endGroup(); } @@ -1249,6 +1247,8 @@ void Avatar::saveData(QSettings* set) { set->setValue("voxelURL", _voxels.getVoxelURL()); + set->setValue("leanScale", _leanScale); + set->endGroup(); } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index de76092328..34483b6d93 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -96,6 +96,7 @@ public: void setMovedHandOffset (glm::vec3 movedHandOffset ) { _movedHandOffset = movedHandOffset;} void setThrust (glm::vec3 newThrust ) { _thrust = newThrust; }; void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors);} + void setLeanScale (float scale ) { _leanScale = scale;} void setGravity (glm::vec3 gravity); void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction); void setOrientation (const glm::quat& orientation); @@ -115,6 +116,7 @@ public: float getSpeed () const { return _speed;} float getHeight () const { return _height;} AvatarMode getMode () const { return _mode;} + float getLeanScale () const { return _leanScale;} float getAbsoluteHeadYaw () const; float getAbsoluteHeadPitch () const; Head& getHead () {return _head; } @@ -177,13 +179,12 @@ private: glm::vec3 _movedHandOffset; AvatarBall _bodyBall[ NUM_AVATAR_BODY_BALLS ]; AvatarMode _mode; - glm::vec3 _cameraPosition; glm::vec3 _handHoldingPosition; glm::vec3 _velocity; glm::vec3 _thrust; float _speed; float _maxArmLength; - glm::quat _righting; + float _leanScale; int _driveKeys[MAX_DRIVE_KEYS]; float _pelvisStandingHeight; float _pelvisFloatingHeight; @@ -202,7 +203,7 @@ private: AvatarVoxelSystem _voxels; // private methods... - glm::vec3 caclulateAverageEyePosition() { return _head.caclulateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) + glm::vec3 calculateAverageEyePosition() { return _head.calculateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat) glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const; float getBallRenderAlpha(int ball, bool lookingInMirror) const; void renderBody(bool lookingInMirror, bool renderAvatarBalls); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index d58c29f84d..c7fac99d8b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -5,6 +5,7 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. #include +#include "Application.h" #include "Avatar.h" #include "Head.h" #include "Util.h" @@ -161,7 +162,7 @@ void Head::determineIfLookingAtSomething() { if ( fabs(_lookAtPosition.x + _lookAtPosition.y + _lookAtPosition.z) == 0.0 ) { // a lookatPosition of 0,0,0 signifies NOT looking _lookingAtSomething = false; } else { - glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - caclulateAverageEyePosition()); + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - calculateAverageEyePosition()); float dot = glm::dot(targetLookatAxis, getFrontDirection()); if (dot < MINIMUM_EYE_ROTATION_DOT) { // too far off from center for the eyes to rotate _lookingAtSomething = false; @@ -202,7 +203,7 @@ void Head::calculateGeometry() { } -void Head::render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha) { +void Head::render(bool lookingInMirror, float alpha) { _renderAlpha = alpha; _lookingInMirror = lookingInMirror; @@ -212,7 +213,7 @@ void Head::render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderMohawk(cameraPosition); + renderMohawk(); renderHeadSphere(); renderEyeBalls(); renderEars(); @@ -256,7 +257,7 @@ void Head::createMohawk() { } } -void Head::renderMohawk(glm::vec3 cameraPosition) { +void Head::renderMohawk() { if (!_mohawkTriangleFan) { createMohawk(); @@ -267,7 +268,7 @@ void Head::renderMohawk(glm::vec3 cameraPosition) { glm::vec3 baseAxis = _hairTuft[t].midPosition - _hairTuft[t].basePosition; glm::vec3 midAxis = _hairTuft[t].endPosition - _hairTuft[t].midPosition; - glm::vec3 viewVector = _hairTuft[t].basePosition - cameraPosition; + glm::vec3 viewVector = _hairTuft[t].basePosition - Application::getInstance()->getCamera()->getPosition(); glm::vec3 basePerpendicular = glm::normalize(glm::cross(baseAxis, viewVector)); glm::vec3 midPerpendicular = glm::normalize(glm::cross(midAxis, viewVector)); diff --git a/interface/src/Head.h b/interface/src/Head.h index 4150cbbc50..d331b98efc 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -33,8 +33,8 @@ public: void reset(); void simulate(float deltaTime, bool isMine); - void render(bool lookingInMirror, glm::vec3 cameraPosition, float alpha); - void renderMohawk(glm::vec3 cameraPosition); + void render(bool lookingInMirror, float alpha); + void renderMohawk(); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } @@ -55,7 +55,7 @@ public: const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) float getAverageLoudness() {return _averageLoudness;}; - glm::vec3 caclulateAverageEyePosition() { return _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; } + glm::vec3 calculateAverageEyePosition() { return _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; } float yawRate; float noise; diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 74fe5abd1c..cc566dd6fb 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -498,9 +498,9 @@ void runTimingTests() { } float loadSetting(QSettings* settings, const char* name, float defaultValue) { - float value = settings->value(name, 0.0f).toFloat(); + float value = settings->value(name, defaultValue).toFloat(); if (isnan(value)) { value = defaultValue; } return value; -} \ No newline at end of file +} diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 9c309bb23f..56641bd2a0 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -62,7 +62,6 @@ AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : _agentSocket(newSocketListenPort), _ownerType(newOwnerType), _agentTypesOfInterest(NULL), - _socketListenPort(newSocketListenPort), _ownerID(UNKNOWN_AGENT_ID), _lastAgentID(0) { pthread_mutex_init(&mutex, 0); @@ -224,7 +223,7 @@ void AgentList::sendDomainServerCheckIn() { packetPosition += packSocket(checkInPacket + sizeof(PACKET_HEADER) + sizeof(AGENT_TYPE), getLocalAddress(), - htons(_socketListenPort)); + htons(_agentSocket.getListeningPort())); // add the number of bytes for agent types of interest *(packetPosition++) = numBytesAgentsOfInterest; diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index 3007dbc8e3..1b51913928 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -58,7 +58,7 @@ public: UDPSocket* getAgentSocket() { return &_agentSocket; } - unsigned int getSocketListenPort() const { return _socketListenPort; }; + unsigned int getSocketListenPort() const { return _agentSocket.getListeningPort(); }; void(*linkedDataCreateCallback)(Agent *); diff --git a/libraries/shared/src/UDPSocket.cpp b/libraries/shared/src/UDPSocket.cpp index b7c2275635..69cf0cfebe 100644 --- a/libraries/shared/src/UDPSocket.cpp +++ b/libraries/shared/src/UDPSocket.cpp @@ -117,7 +117,7 @@ unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket) { } } -UDPSocket::UDPSocket(int listeningPort) : blocking(true) { +UDPSocket::UDPSocket(int listeningPort) : listeningPort(listeningPort), blocking(true) { init(); // create the socket handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -140,6 +140,13 @@ UDPSocket::UDPSocket(int listeningPort) : blocking(true) { return; } + // if we requested an ephemeral port, get the actual port + if (listeningPort == 0) { + socklen_t addressLength = sizeof(sockaddr_in); + getsockname(handle, (sockaddr*) &bind_address, &addressLength); + listeningPort = ntohs(bind_address.sin_port); + } + // set timeout on socket recieve to 0.5 seconds struct timeval tv; tv.tv_sec = 0; diff --git a/libraries/shared/src/UDPSocket.h b/libraries/shared/src/UDPSocket.h index b56a1cc0cf..8539ff93c2 100644 --- a/libraries/shared/src/UDPSocket.h +++ b/libraries/shared/src/UDPSocket.h @@ -23,14 +23,16 @@ public: UDPSocket(int listening_port); ~UDPSocket(); bool init(); + int getListeningPort() const { return listeningPort; } void setBlocking(bool blocking); - bool isBlocking() { return blocking; } + bool isBlocking() const { return blocking; } int send(sockaddr* destAddress, const void* data, size_t byteLength) const; int send(char* destAddress, int destPort, const void* data, size_t byteLength) const; bool receive(void* receivedData, ssize_t* receivedBytes) const; bool receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const; private: int handle; + int listeningPort; bool blocking; };