From a04bd09b83349e820dd6762bef3e0fa0aec69b87 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 17 Mar 2015 16:32:59 -0700 Subject: [PATCH 1/3] Set clip near distance per skeleton model if no separate head model --- interface/src/avatar/MyAvatar.cpp | 15 ++++++++++++--- interface/src/avatar/SkeletonModel.cpp | 7 ++++++- interface/src/avatar/SkeletonModel.h | 4 ++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index bdb0877cda..642da60b18 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1028,7 +1028,18 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { return; // wait until both models are loaded } - + + Camera *camera = Application::getInstance()->getCamera(); + const glm::vec3 cameraPos = camera->getPosition(); + + // Set near clip distance according to skeleton model dimensions if first person and there is no separate head model. + if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) { + camera->setNearClip(DEFAULT_NEAR_CLIP); + } else { + float clipDistance = _skeletonModel.getHeadClipDistance(); + camera->setNearClip(clipDistance); + } + // Render the body's voxels and head Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; @@ -1040,8 +1051,6 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo } // Render head so long as the camera isn't inside it - const Camera *camera = Application::getInstance()->getCamera(); - const glm::vec3 cameraPos = camera->getPosition(); if (shouldRenderHead(cameraPos, renderMode)) { getHead()->render(1.0f, renderFrustum, modelRenderMode, postLighting); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 4fdebd5f6f..3a61f69dee 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -37,7 +37,8 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent) : _defaultEyeModelPosition(glm::vec3(0.0f, 0.0f, 0.0f)), _standingFoot(NO_FOOT), _standingOffset(0.0f), - _clampedFootPosition(0.0f) + _clampedFootPosition(0.0f), + _headClipDistance(DEFAULT_NEAR_CLIP) { } @@ -78,6 +79,10 @@ void SkeletonModel::setJointStates(QVector states) { buildShapes(); } + Extents meshExtents = getMeshExtents(); + _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z); + _headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP); + emit skeletonLoaded(); } diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 5427fcaf25..298d74fb7a 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -110,6 +110,8 @@ public: bool hasSkeleton(); + float getHeadClipDistance() const { return _headClipDistance; } + signals: void skeletonLoaded(); @@ -160,6 +162,8 @@ private: int _standingFoot; glm::vec3 _standingOffset; glm::vec3 _clampedFootPosition; + + float _headClipDistance; // Near clip distance to use if no separate head model }; #endif // hifi_SkeletonModel_h From 7b54443bda95a8622a7306225f82c6b47d13610c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 17 Mar 2015 16:33:20 -0700 Subject: [PATCH 2/3] Adjust clip distance as HMD head moves backwards --- interface/src/avatar/MyAvatar.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 642da60b18..8af5982b3e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1037,6 +1037,16 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo camera->setNearClip(DEFAULT_NEAR_CLIP); } else { float clipDistance = _skeletonModel.getHeadClipDistance(); + if (OculusManager::isConnected()) { + // If avatar is horizontally in front of camera, increase clip distance by the amount it is in front. + glm::vec3 cameraToAvatar = _position - cameraPos; + cameraToAvatar.y = 0.0f; + glm::vec3 cameraLookAt = camera->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f); + float headOffset = glm::dot(cameraLookAt, cameraToAvatar); + if (headOffset > 0) { + clipDistance += headOffset; + } + } camera->setNearClip(clipDistance); } From 648a2e3b1d13b4fdb45eb62d08ac714462328f67 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 18 Mar 2015 12:43:49 -0700 Subject: [PATCH 3/3] Set clip distance on rendering frustum rather than camera This fixes wrong clipping distance used for rendering in FPV if also have rear view mirror. --- interface/src/avatar/MyAvatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8af5982b3e..25cb4d4c6a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1034,7 +1034,7 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo // Set near clip distance according to skeleton model dimensions if first person and there is no separate head model. if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) { - camera->setNearClip(DEFAULT_NEAR_CLIP); + renderFrustum->setNearClip(DEFAULT_NEAR_CLIP); } else { float clipDistance = _skeletonModel.getHeadClipDistance(); if (OculusManager::isConnected()) { @@ -1047,7 +1047,7 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo clipDistance += headOffset; } } - camera->setNearClip(clipDistance); + renderFrustum->setNearClip(clipDistance); } // Render the body's voxels and head