From 3bd8c53115467a0c3632c14666453519b8eb2df6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sat, 7 Dec 2013 11:36:51 -0800 Subject: [PATCH 1/5] =?UTF-8?q?Fix=20to=20get=20other=20avatar=E2=80=99s?= =?UTF-8?q?=20model=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interface/src/Application.cpp | 18 ++++++++-- interface/src/avatar/Avatar.cpp | 46 ++++++++++++++------------ interface/src/avatar/SkeletonModel.cpp | 1 + 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f88b20334b..5852656655 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1412,9 +1412,16 @@ void Application::processAvatarURLsMessage(unsigned char* packetData, size_t dat if (!avatar) { return; } - QDataStream in(QByteArray((char*)packetData, dataBytes)); - QUrl voxelURL; - in >> voxelURL; + // PER Note: message is no longer processed but used to trigger + // Dataserver lookup - redesign this to instantly ask the + // dataserver on first receipt of other avatar UUID, and also + // don't ask over and over again. Instead use this message to + // Tell the other avatars that your dataserver data has + // changed. + + //QDataStream in(QByteArray((char*)packetData, dataBytes)); + //QUrl voxelURL; + //in >> voxelURL; // use this timing to as the data-server for an updated mesh for this avatar (if we have UUID) DataServerClient::getValuesForKeysAndUUID(QStringList() << DataServerKey::FaceMeshURL << DataServerKey::SkeletonURL, @@ -2553,6 +2560,11 @@ void Application::updateAvatar(float deltaTime) { controlledBroadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString, nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); + const float AVATAR_URLS_SEND_INTERVAL = 1.0f; + if (shouldDo(AVATAR_URLS_SEND_INTERVAL, deltaTime)) { + QUrl empty; + Avatar::sendAvatarURLsMessage(empty); + } // Update _viewFrustum with latest camera and view frustum data... // NOTE: we get this from the view frustum, to make it simpler, since the // loadViewFrumstum() method will get the correct details from the camera diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index cab6e9f1df..f4a09ad069 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -168,18 +168,18 @@ void Avatar::follow(Avatar* leadingAvatar) { } void Avatar::simulate(float deltaTime, Transmitter* transmitter) { - + if (_leadingAvatar && !_leadingAvatar->getOwningNode()->isAlive()) { follow(NULL); } - + if (_scale != _newScale) { setScale(_newScale); } // copy velocity so we can use it later for acceleration glm::vec3 oldVelocity = getVelocity(); - + // update balls if (_balls) { _balls->moveOrigin(_position); @@ -194,7 +194,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // update torso rotation based on head lean _skeleton.joint[AVATAR_JOINT_TORSO].rotation = glm::quat(glm::radians(glm::vec3( - _head.getLeanForward(), 0.0f, _head.getLeanSideways()))); + _head.getLeanForward(), 0.0f, _head.getLeanSideways()))); // apply joint data (if any) to skeleton bool enableHandMovement = true; @@ -205,25 +205,16 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { enableHandMovement &= (it->jointID != AVATAR_JOINT_RIGHT_WRIST); } + // update avatar skeleton + _skeleton.update(deltaTime, getOrientation(), _position); + + + // if this is not my avatar, then hand position comes from transmitted data + _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition; + //update the movement of the hand and process handshaking with other avatars... updateHandMovementAndTouching(deltaTime, enableHandMovement); - // use speed and angular velocity to determine walking vs. standing - if (_speed + fabs(_bodyYawDelta) > 0.2) { - _mode = AVATAR_MODE_WALKING; - } else { - _mode = AVATAR_MODE_INTERACTING; - } - - // update position by velocity, and subtract the change added earlier for gravity - _position += _velocity * deltaTime; - - // update avatar skeleton - _skeleton.update(deltaTime, getOrientation(), _position); - - // if this is not my avatar, then hand position comes from transmitted data - _skeleton.joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].position = _handPosition; - _hand.simulate(deltaTime, false); _skeletonModel.simulate(deltaTime); _head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); @@ -233,11 +224,20 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setScale(_scale); _head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2])); _head.simulate(deltaTime, false); - + + // use speed and angular velocity to determine walking vs. standing + if (_speed + fabs(_bodyYawDelta) > 0.2) { + _mode = AVATAR_MODE_WALKING; + } else { + _mode = AVATAR_MODE_INTERACTING; + } + + // update position by velocity, and subtract the change added earlier for gravity + _position += _velocity * deltaTime; // Zero thrust out now that we've added it to velocity in this frame _thrust = glm::vec3(0, 0, 0); - + } void Avatar::setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction) { @@ -452,6 +452,8 @@ void Avatar::renderBody(bool forceRenderHead) { _head.getVideoFace().render(1.0f); } else { // Render the body's voxels and head + glm::vec3 pos = getPosition(); + //printf("Render other at %.3f, %.2f, %.2f\n", pos.x, pos.y, pos.z); _skeletonModel.render(1.0f); _head.render(1.0f, false); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2605c8438f..b8c500d3bd 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -61,6 +61,7 @@ void SkeletonModel::simulate(float deltaTime) { } bool SkeletonModel::render(float alpha) { + if (_jointStates.isEmpty()) { return false; } From 85f7995700f659bc2c1afc2e7765ca8f7517bd35 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 9 Dec 2013 11:00:35 -0800 Subject: [PATCH 2/5] Don't apply ambient occlusion to avatars (just voxels). --- interface/src/Application.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5852656655..7d10928d87 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2992,6 +2992,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } } + // render the ambient occlusion effect if enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... AmbientOcclusion..."); + _ambientOcclusionEffect.render(); + } + // restore default, white specular glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE_SPECULAR_COLOR); @@ -3075,13 +3082,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { renderWorldBox(); } - // render the ambient occlusion effect if enabled - if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... AmbientOcclusion..."); - _ambientOcclusionEffect.render(); - } - // brad's frustum for debugging if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayFrustum) && whichCamera.getMode() != CAMERA_MODE_MIRROR) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), From c36e04c435ef9c5c4a6e43dad1badd0533f424bf Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 9 Dec 2013 11:21:32 -0800 Subject: [PATCH 3/5] This should fix the erroneous persistence on startup. --- interface/src/renderer/GlowEffect.cpp | 10 +++++++--- interface/src/renderer/GlowEffect.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index fe46e02688..51128bf1c3 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -19,6 +19,7 @@ GlowEffect::GlowEffect() : _initialized(false), _renderMode(DIFFUSE_ADD_MODE), _isOddFrame(false), + _isFirstFrame(true), _intensity(0.0f) { } @@ -167,7 +168,7 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { newDiffusedFBO->bind(); glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); + glBindTexture(GL_TEXTURE_2D, _isFirstFrame ? 0 : oldDiffusedFBO->texture()); _diffuseProgram->bind(); QSize size = Application::getInstance()->getGLWidget()->size(); @@ -221,7 +222,7 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { maybeRelease(destFBO); } else { // _renderMode == BLUR_PERSIST_ADD_MODE - // render the secondary to the tertiary with horizontal blur and persistence + // render the secondary to the tertiary with vertical blur and persistence QOpenGLFramebufferObject* tertiaryFBO = Application::getInstance()->getTextureCache()->getTertiaryFramebufferObject(); tertiaryFBO->bind(); @@ -229,7 +230,7 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_CONSTANT_ALPHA, GL_CONSTANT_ALPHA); const float PERSISTENCE_SMOOTHING = 0.9f; - glBlendColor(0.0f, 0.0f, 0.0f, PERSISTENCE_SMOOTHING); + glBlendColor(0.0f, 0.0f, 0.0f, _isFirstFrame ? 0.0f : PERSISTENCE_SMOOTHING); glBindTexture(GL_TEXTURE_2D, secondaryFBO->texture()); @@ -270,6 +271,8 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { glDepthMask(GL_TRUE); glBindTexture(GL_TEXTURE_2D, 0); + _isFirstFrame = false; + return destFBO; } @@ -292,6 +295,7 @@ void GlowEffect::cycleRenderMode() { qDebug() << "Glow mode: Diffuse/add\n"; break; } + _isFirstFrame = true; } Glower::Glower(float amount) { diff --git a/interface/src/renderer/GlowEffect.h b/interface/src/renderer/GlowEffect.h index 8168ae4374..65d3d6c8ce 100644 --- a/interface/src/renderer/GlowEffect.h +++ b/interface/src/renderer/GlowEffect.h @@ -66,6 +66,7 @@ private: bool _isEmpty; ///< set when nothing in the scene is currently glowing bool _isOddFrame; ///< controls the alternation between texture targets in diffuse add mode + bool _isFirstFrame; ///< for persistent modes, notes whether this is the first frame rendered float _intensity; QStack _intensityStack; From 2381b2bbaf6a1b672b6c422117e7bd7c1360b784 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 9 Dec 2013 12:30:14 -0800 Subject: [PATCH 4/5] Get rid of initial glow. --- interface/src/renderer/GlowEffect.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/renderer/GlowEffect.cpp b/interface/src/renderer/GlowEffect.cpp index 51128bf1c3..3bd71b2dd4 100644 --- a/interface/src/renderer/GlowEffect.cpp +++ b/interface/src/renderer/GlowEffect.cpp @@ -167,16 +167,21 @@ QOpenGLFramebufferObject* GlowEffect::render(bool toTexture) { } newDiffusedFBO->bind(); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, _isFirstFrame ? 0 : oldDiffusedFBO->texture()); + if (_isFirstFrame) { + glClear(GL_COLOR_BUFFER_BIT); - _diffuseProgram->bind(); - QSize size = Application::getInstance()->getGLWidget()->size(); - _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); + } else { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, oldDiffusedFBO->texture()); + + _diffuseProgram->bind(); + QSize size = Application::getInstance()->getGLWidget()->size(); + _diffuseProgram->setUniformValue(_diffusionScaleLocation, 1.0f / size.width(), 1.0f / size.height()); - renderFullscreenQuad(); + renderFullscreenQuad(); - _diffuseProgram->release(); + _diffuseProgram->release(); + } newDiffusedFBO->release(); From 9616268da7192ac0ffcd53123e458c492b70c28d Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 9 Dec 2013 13:02:18 -0800 Subject: [PATCH 5/5] Improved full screen mirror view to allow leaning --- interface/src/Application.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5852656655..69224b75f6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -79,8 +79,10 @@ const int MIRROR_VIEW_TOP_PADDING = 5; const int MIRROR_VIEW_LEFT_PADDING = 10; const int MIRROR_VIEW_WIDTH = 265; const int MIRROR_VIEW_HEIGHT = 215; -const float MAX_ZOOM_DISTANCE = 0.3f; -const float MIN_ZOOM_DISTANCE = 2.0f; +const float MIRROR_FULLSCREEN_DISTANCE = 0.2f; +const float MIRROR_REARVIEW_DISTANCE = 0.3f; +const float MIRROR_REARVIEW_BODY_DISTANCE = 1.f; + void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message) { fprintf(stdout, "%s", message.toLocal8Bit().constData()); @@ -376,11 +378,12 @@ void Application::paintGL() { } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness(0.0f); - _myCamera.setDistance(MAX_ZOOM_DISTANCE); - _myCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition()); + float headHeight = _myAvatar.getHead().calculateAverageEyePosition().y - _myAvatar.getPosition().y; + _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar.getScale()); + _myCamera.setTargetPosition(_myAvatar.getPosition() + glm::vec3(0, headHeight, 0)); _myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f))); } - + // Update camera position _myCamera.update( 1.f/_fps ); @@ -432,10 +435,10 @@ void Application::paintGL() { bool eyeRelativeCamera = false; if (_rearMirrorTools->getZoomLevel() == BODY) { - _mirrorCamera.setDistance(MIN_ZOOM_DISTANCE); + _mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar.getScale()); _mirrorCamera.setTargetPosition(_myAvatar.getChestJointPosition()); } else { // HEAD zoom level - _mirrorCamera.setDistance(MAX_ZOOM_DISTANCE); + _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar.getScale()); if (_myAvatar.getSkeletonModel().isActive() && _myAvatar.getHead().getFaceModel().isActive()) { // as a hack until we have a better way of dealing with coordinate precision issues, reposition the // face/body so that the average eye position lies at the origin