From 68ba2201df10c63269fc137e1486787826bd0481 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Mar 2014 10:22:02 -0700 Subject: [PATCH] cleanup of Avatar:: and MyAvatar::render() MyAvatar now calls Avatar::render() which does most of the work. Also, made ::renderBody() a proper virtual function --- interface/src/avatar/Avatar.cpp | 69 ++++++++++++++------------ interface/src/avatar/Avatar.h | 4 +- interface/src/avatar/AvatarManager.cpp | 18 +++---- interface/src/avatar/AvatarManager.h | 2 +- interface/src/avatar/MyAvatar.cpp | 62 ++--------------------- interface/src/avatar/MyAvatar.h | 4 +- 6 files changed, 55 insertions(+), 104 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index bcf24a7bfb..cb6e3d67ee 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -189,55 +189,60 @@ static TextRenderer* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::render(bool forShadowMap) { +void Avatar::render(const glm::vec3& cameraPosition, bool forShadowMap) { // simple frustum check float boundingRadius = getBillboardSize(); - if (Application::getInstance()->getViewFrustum()->sphereInFrustum(_position, boundingRadius) == ViewFrustum::OUTSIDE) { + if (Application::getInstance()->getViewFrustum()->sphereInFrustum(cameraPosition, boundingRadius) == ViewFrustum::OUTSIDE) { return; } - glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); - float lengthToTarget = glm::length(toTarget); + glm::vec3 toTarget = cameraPosition - Application::getInstance()->getAvatar()->getPosition(); + float distanceToTarget = glm::length(toTarget); { - // glow when moving in the distance - + // glow when moving far away const float GLOW_DISTANCE = 20.0f; - Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f); + Glower glower(_moving && distanceToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f); // render body + if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { + renderBody(forShadowMap); + } if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { _skeletonModel.renderCollisionProxies(0.7f); } if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) { getHead()->getFaceModel().renderCollisionProxies(0.7f); } - if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(); - } - // render voice intensity sphere for avatars that are farther away - const float MAX_SPHERE_ANGLE = 10.f * RADIANS_PER_DEGREE; - const float MIN_SPHERE_ANGLE = 1.f * RADIANS_PER_DEGREE; - const float MIN_SPHERE_SIZE = 0.01f; - const float SPHERE_LOUDNESS_SCALING = 0.0005f; - const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f }; - float height = getSkeletonHeight(); - glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f; - float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); - float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; - - if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { - glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE); - glPushMatrix(); - glTranslatef(_position.x, _position.y, _position.z); - glScalef(height, height, height); - glutSolidSphere(sphereRadius, 15, 15); - glPopMatrix(); + // quick check before falling into the code below: + // (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m) + const float MIN_VOICE_SPHERE_DISTANCE = 12.f; + if (distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) { + // render voice intensity sphere for avatars that are farther away + const float MAX_SPHERE_ANGLE = 10.f * RADIANS_PER_DEGREE; + const float MIN_SPHERE_ANGLE = 1.f * RADIANS_PER_DEGREE; + const float MIN_SPHERE_SIZE = 0.01f; + const float SPHERE_LOUDNESS_SCALING = 0.0005f; + const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f }; + float height = getSkeletonHeight(); + glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f; + float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); + float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; + + if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { + glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE); + glPushMatrix(); + glTranslatef(_position.x, _position.y, _position.z); + glScalef(height, height, height); + glutSolidSphere(sphereRadius, 15, 15); + glPopMatrix(); + } } } + const float DISPLAYNAME_DISTANCE = 10.0f; - setShowDisplayName(!forShadowMap && lengthToTarget < DISPLAYNAME_DISTANCE); + setShowDisplayName(!forShadowMap && distanceToTarget < DISPLAYNAME_DISTANCE); if (forShadowMap) { return; } @@ -257,7 +262,6 @@ void Avatar::render(bool forShadowMap) { glm::vec3 chatAxis = glm::axis(chatRotation); glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z); - glColor3f(0.f, 0.8f, 0.f); glRotatef(180.f, 0.f, 1.f, 0.f); glRotatef(180.f, 0.f, 0.f, 1.f); @@ -302,9 +306,12 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { return glm::angleAxis(angle * proportion, axis); } -void Avatar::renderBody() { +void Avatar::renderBody(bool forShadowMap) { if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { // render the billboard until both models are loaded + if (forShadowMap) { + return; + } renderBillboard(); return; } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 2bd7fc89e8..542320805e 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -74,7 +74,7 @@ public: void init(); void simulate(float deltaTime); - void render(bool forShadowMap = false); + virtual void render(const glm::vec3& cameraPosition, bool forShadowMap); //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } @@ -181,6 +181,7 @@ protected: float getPelvisToHeadLength() const; void renderDisplayName(); + virtual void renderBody(bool forShadowMap); private: @@ -189,7 +190,6 @@ private: bool _shouldRenderBillboard; bool _modelsDirty; - void renderBody(); void renderBillboard(); float getBillboardSize() const; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 88ce2b4399..cd7d360743 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -77,7 +77,7 @@ void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); - + glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); if (!selfAvatarOnly) { foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { @@ -85,17 +85,13 @@ void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly if (!avatar->isInitialized()) { continue; } - if (avatar == static_cast(_myAvatar.data())) { - _myAvatar->render(forShadowMapOrMirror); - } else { - avatar->render(forShadowMapOrMirror); - } + avatar->render(cameraPosition, forShadowMapOrMirror); avatar->setDisplayingLookatVectors(renderLookAtVectors); } - renderAvatarFades(forShadowMapOrMirror); + renderAvatarFades(cameraPosition, forShadowMapOrMirror); } else { // just render myAvatar - _myAvatar->render(forShadowMapOrMirror); + _myAvatar->render(cameraPosition, forShadowMapOrMirror); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } } @@ -118,13 +114,15 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { } } -void AvatarManager::renderAvatarFades(bool forShadowMap) { +void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, bool forShadowMap) { // render avatar fades Glower glower(forShadowMap ? 0.0f : 1.0f); foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { Avatar* avatar = static_cast(fadingAvatar.data()); - avatar->render(forShadowMap); + if (avatar != static_cast(_myAvatar.data())) { + avatar->render(cameraPosition, forShadowMap); + } } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index c690dfa966..455153b92a 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -45,7 +45,7 @@ private: void processKillAvatar(const QByteArray& datagram); void simulateAvatarFades(float deltaTime); - void renderAvatarFades(bool forShadowMap); + void renderAvatarFades(const glm::vec3& cameraPosition, bool forShadowMap); // virtual override AvatarHash::iterator erase(const AvatarHash::iterator& iterator); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e4aaa07a4b..c56865afc6 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -453,68 +453,14 @@ void MyAvatar::renderDebugBodyPoints() { } -void MyAvatar::render(bool forShadowMapOrMirror) { + +// virtual +void MyAvatar::render(const glm::vec3& cameraPosition, bool forShadowMapOrMirror) { // don't render if we've been asked to disable local rendering if (!_shouldRender) { return; // exit early } - - if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(forShadowMapOrMirror); - } - // render body - if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { - _skeletonModel.renderCollisionProxies(0.8f); - } - if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) { - getHead()->getFaceModel().renderCollisionProxies(0.8f); - } - setShowDisplayName(!forShadowMapOrMirror); - if (forShadowMapOrMirror) { - return; - } - renderDisplayName(); - - if (!_chatMessage.empty()) { - int width = 0; - int lastWidth = 0; - for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) { - width += (lastWidth = textRenderer()->computeWidth(*it)); - } - glPushMatrix(); - - glm::vec3 chatPosition = getHead()->getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale; - glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); - glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); - glm::vec3 chatAxis = glm::axis(chatRotation); - glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z); - - glColor3f(0.f, 0.8f, 0.f); - glRotatef(180.f, 0.f, 1.f, 0.f); - glRotatef(180.f, 0.f, 0.f, 1.f); - glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f); - - glDisable(GL_LIGHTING); - glDepthMask(false); - if (_keyState == NO_KEY_DOWN) { - textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); - - } else { - // rather than using substr and allocating a new string, just replace the last - // character with a null, then restore it - int lastIndex = _chatMessage.size() - 1; - char lastChar = _chatMessage[lastIndex]; - _chatMessage[lastIndex] = '\0'; - textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); - _chatMessage[lastIndex] = lastChar; - glColor3f(0.f, 1.f, 0.f); - textRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); - } - glEnable(GL_LIGHTING); - glDepthMask(true); - - glPopMatrix(); - } + Avatar::render(cameraPosition, forShadowMapOrMirror); } void MyAvatar::renderHeadMouse() const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index dfc114d952..3544fb1a61 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -35,7 +35,8 @@ public: void simulate(float deltaTime); void updateFromGyros(float deltaTime); - void render(bool forShadowMapOrMirror = false); + void render(const glm::vec3& cameraPosition, bool forShadowMapOrMirror = false); + void renderBody(bool forceRenderHead); void renderDebugBodyPoints(); void renderHeadMouse() const; @@ -120,7 +121,6 @@ private: bool _billboardValid; // private methods - void renderBody(bool forceRenderHead); void updateThrust(float deltaTime); void updateHandMovementAndTouching(float deltaTime); void updateCollisionWithAvatars(float deltaTime);