From 33b48947a5930195a15927a93f293867917f8eab Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 23 Jun 2015 17:36:19 -0700 Subject: [PATCH 01/23] Delete Interface.ini.lock file at start-up if it exists Otherwise Interface freezes. --- libraries/shared/src/SettingInterface.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/SettingInterface.cpp b/libraries/shared/src/SettingInterface.cpp index c14fd33565..b60ffc0891 100644 --- a/libraries/shared/src/SettingInterface.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include "PathUtils.h" @@ -53,7 +54,15 @@ namespace Setting { privateInstance = new Manager(); Q_CHECK_PTR(privateInstance); - + + // Delete Interface.ini.lock file if it exists, otherwise Interface freezes. + QString settingsLockFilename = privateInstance->fileName() + ".lock"; + QFile settingsLockFile(settingsLockFilename); + if (settingsLockFile.exists()) { + bool deleted = settingsLockFile.remove(); + qCDebug(shared) << (deleted ? "Deleted" : "Failed to delete") << "settings lock file" << settingsLockFilename; + } + QObject::connect(privateInstance, SIGNAL(destroyed()), thread, SLOT(quit())); QObject::connect(thread, SIGNAL(started()), privateInstance, SLOT(startTimer())); QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); From 377979e38019d20a40d55ac7461a1ff14256c8a2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 25 Jun 2015 15:41:10 -0700 Subject: [PATCH 02/23] Make field of view preference change be applied immediately --- interface/src/Application.cpp | 5 +++-- interface/src/Application.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f828f05258..8c8e624dcb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1029,7 +1029,7 @@ void Application::showEditEntitiesHelp() { InfoView::show(INFO_EDIT_ENTITIES_PATH); } -void Application::resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size) { +void Application::resetCameras(Camera& camera, const glm::uvec2& size) { if (OculusManager::isConnected()) { OculusManager::configureCamera(camera); } else if (TV3DManager::isConnected()) { @@ -1052,7 +1052,6 @@ void Application::resizeGL() { if (_renderResolution != toGlm(renderSize)) { _renderResolution = toGlm(renderSize); DependencyManager::get()->setFrameBufferSize(renderSize); - resetCamerasOnResizeGL(_myCamera, _renderResolution); glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu??? @@ -1060,6 +1059,8 @@ void Application::resizeGL() { glLoadIdentity(); } + resetCameras(_myCamera, _renderResolution); + auto offscreenUi = DependencyManager::get(); auto canvasSize = _glWidget->size(); diff --git a/interface/src/Application.h b/interface/src/Application.h index b126757621..61c029e8cf 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -479,7 +479,7 @@ private slots: void setCursorVisible(bool visible); private: - void resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size); + void resetCameras(Camera& camera, const glm::uvec2& size); void updateProjectionMatrix(); void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true); From f47cff1332da5365a95d2f94393e8dcde21a95f2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 25 Jun 2015 15:41:27 -0700 Subject: [PATCH 03/23] Remove duplicate method call --- interface/src/ui/PreferencesDialog.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index eca250a428..93b3ef8d07 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -221,8 +221,6 @@ void PreferencesDialog::savePreferences() { myAvatar->setLeanScale(ui.leanScaleSpin->value()); myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value()); - Application::getInstance()->resizeGL(); - DependencyManager::get()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value()); qApp->setFieldOfView(ui.fieldOfViewSpin->value()); From 215c260c9e1e1264c003ff91ce9547660a576b43 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 30 Jun 2015 17:08:43 -0700 Subject: [PATCH 04/23] Fix TextOverlay font size setting --- interface/src/ui/overlays/TextOverlay.cpp | 7 +++++++ interface/src/ui/overlays/TextOverlay.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index ccad3bd295..174f8e05dc 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -170,3 +170,10 @@ QSizeF TextOverlay::textSize(const QString& text) const { return QSizeF(extents.x, extents.y); } + +void TextOverlay::setFontSize(int fontSize) { + _fontSize = fontSize; + + delete _textRenderer; + _textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); +} diff --git a/interface/src/ui/overlays/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h index de2597cf9a..32786c3220 100644 --- a/interface/src/ui/overlays/TextOverlay.h +++ b/interface/src/ui/overlays/TextOverlay.h @@ -48,7 +48,7 @@ public: void setText(const QString& text) { _text = text; } void setLeftMargin(int margin) { _leftMargin = margin; } void setTopMargin(int margin) { _topMargin = margin; } - void setFontSize(int fontSize) { _fontSize = fontSize; } + void setFontSize(int fontSize); virtual void setProperties(const QScriptValue& properties); virtual TextOverlay* createClone() const; From d4d6f8f5d5c5b4b8b44ccd7bec232b6052306f8e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 10:06:04 -0700 Subject: [PATCH 05/23] Eliminate per-packet locking for processing --- .../src/ReceivedPacketProcessor.cpp | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/libraries/networking/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp index 894a7b8aa9..706266a903 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -38,19 +38,28 @@ bool ReceivedPacketProcessor::process() { _hasPackets.wait(&_waitingOnPacketsMutex, getMaxWait()); _waitingOnPacketsMutex.unlock(); } + preProcess(); - while (_packets.size() > 0) { - lock(); // lock to make sure nothing changes on us - NetworkPacket& packet = _packets.front(); // get the oldest packet - NetworkPacket temporary = packet; // make a copy of the packet in case the vector is resized on us - _packets.erase(_packets.begin()); // remove the oldest packet - if (!temporary.getNode().isNull()) { - _nodePacketCounts[temporary.getNode()->getUUID()]--; - } - unlock(); // let others add to the packets - processPacket(temporary.getNode(), temporary.getByteArray()); // process our temporary copy + QVector currentPackets; + if (!_packets.size()) { + return isStillRunning(); + } + + lock(); + std::swap(currentPackets, _packets); + unlock(); + + foreach(auto& packet, currentPackets) { + processPacket(packet.getNode(), packet.getByteArray()); midProcess(); } + + lock(); + foreach(auto& packet, currentPackets) { + _nodePacketCounts[packet.getNode()->getUUID()]--; + } + unlock(); + postProcess(); return isStillRunning(); // keep running till they terminate us } From e85eb246d26b5d0126b7c802f45945c66e4ed6a4 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 1 Jul 2015 13:19:46 -0700 Subject: [PATCH 06/23] Delete old TextRenderer after new one is in place --- interface/src/ui/overlays/TextOverlay.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 174f8e05dc..3f033d9266 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -174,6 +174,7 @@ QSizeF TextOverlay::textSize(const QString& text) const { void TextOverlay::setFontSize(int fontSize) { _fontSize = fontSize; - delete _textRenderer; + auto oldTextRenderer = _textRenderer; _textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); + delete oldTextRenderer; } From ce613d59fda3da951cb604cf8a2b779097c42508 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 1 Jul 2015 14:46:37 -0700 Subject: [PATCH 07/23] add inbound edit packet queue depth to entity server --- assignment-client/src/octree/OctreeServer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 43bc922c74..8efe1c39a0 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -627,6 +627,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url // display inbound packet stats statsString += QString().sprintf("%s Edit Statistics... [RESET]\r\n", getMyServerName()); + quint64 currentPacketsInQueue = _octreeInboundPacketProcessor->packetsToProcessCount(); quint64 averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket(); quint64 averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket(); quint64 averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket(); @@ -637,6 +638,9 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url float averageElementsPerPacket = totalPacketsProcessed == 0 ? 0 : totalElementsProcessed / totalPacketsProcessed; + statsString += QString(" Current Inbound Packets Queue: %1 packets\r\n") + .arg(locale.toString((uint)currentPacketsInQueue).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Total Inbound Packets: %1 packets\r\n") .arg(locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' ')); statsString += QString(" Total Inbound Elements: %1 elements\r\n") @@ -1411,6 +1415,8 @@ void OctreeServer::sendStatsPacket() { static QJsonObject statsObject3; + statsObject3[baseName + QString(".3.inbound.data.1.packetQueue")] = + (double)_octreeInboundPacketProcessor->packetsToProcessCount(); statsObject3[baseName + QString(".3.inbound.data.1.totalPackets")] = (double)_octreeInboundPacketProcessor->getTotalPacketsProcessed(); statsObject3[baseName + QString(".3.inbound.data.2.totalElements")] = From 4c200d75bce6aaf53f24fd28250c7ddcc35b3700 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 14:53:08 -0700 Subject: [PATCH 08/23] Tweaking packet processing locking --- .../networking/src/ReceivedPacketProcessor.cpp | 13 ++++++------- libraries/networking/src/ReceivedPacketProcessor.h | 3 ++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp index 706266a903..0d8494d712 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -23,7 +23,7 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi NetworkPacket networkPacket(sendingNode, packet); lock(); - _packets.push_back(networkPacket); + _queuedPackets.push_back(networkPacket); _nodePacketCounts[sendingNode->getUUID()]++; unlock(); @@ -33,29 +33,28 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi bool ReceivedPacketProcessor::process() { - if (_packets.size() == 0) { + if (_queuedPackets.size() == 0) { _waitingOnPacketsMutex.lock(); _hasPackets.wait(&_waitingOnPacketsMutex, getMaxWait()); _waitingOnPacketsMutex.unlock(); } preProcess(); - QVector currentPackets; - if (!_packets.size()) { + if (!_queuedPackets.size()) { return isStillRunning(); } lock(); - std::swap(currentPackets, _packets); + _processingPackets.swap(_queuedPackets); unlock(); - foreach(auto& packet, currentPackets) { + foreach(auto& packet, _processingPackets) { processPacket(packet.getNode(), packet.getByteArray()); midProcess(); } lock(); - foreach(auto& packet, currentPackets) { + foreach(auto& packet, _processingPackets) { _nodePacketCounts[packet.getNode()->getUUID()]--; } unlock(); diff --git a/libraries/networking/src/ReceivedPacketProcessor.h b/libraries/networking/src/ReceivedPacketProcessor.h index bcc9f9a1f5..1a621e505a 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.h +++ b/libraries/networking/src/ReceivedPacketProcessor.h @@ -75,7 +75,8 @@ protected: protected: - QVector _packets; + QVector _queuedPackets; + QVector _processingPackets; QHash _nodePacketCounts; QWaitCondition _hasPackets; From 1e1f199fdb2dbefbb9d9f90588656db44abad8bb Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 14:54:26 -0700 Subject: [PATCH 09/23] Undoing unwisdom --- .../networking/src/ReceivedPacketProcessor.cpp | 13 +++++++------ libraries/networking/src/ReceivedPacketProcessor.h | 3 +-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp index 0d8494d712..706266a903 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -23,7 +23,7 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi NetworkPacket networkPacket(sendingNode, packet); lock(); - _queuedPackets.push_back(networkPacket); + _packets.push_back(networkPacket); _nodePacketCounts[sendingNode->getUUID()]++; unlock(); @@ -33,28 +33,29 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi bool ReceivedPacketProcessor::process() { - if (_queuedPackets.size() == 0) { + if (_packets.size() == 0) { _waitingOnPacketsMutex.lock(); _hasPackets.wait(&_waitingOnPacketsMutex, getMaxWait()); _waitingOnPacketsMutex.unlock(); } preProcess(); - if (!_queuedPackets.size()) { + QVector currentPackets; + if (!_packets.size()) { return isStillRunning(); } lock(); - _processingPackets.swap(_queuedPackets); + std::swap(currentPackets, _packets); unlock(); - foreach(auto& packet, _processingPackets) { + foreach(auto& packet, currentPackets) { processPacket(packet.getNode(), packet.getByteArray()); midProcess(); } lock(); - foreach(auto& packet, _processingPackets) { + foreach(auto& packet, currentPackets) { _nodePacketCounts[packet.getNode()->getUUID()]--; } unlock(); diff --git a/libraries/networking/src/ReceivedPacketProcessor.h b/libraries/networking/src/ReceivedPacketProcessor.h index 1a621e505a..bcc9f9a1f5 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.h +++ b/libraries/networking/src/ReceivedPacketProcessor.h @@ -75,8 +75,7 @@ protected: protected: - QVector _queuedPackets; - QVector _processingPackets; + QVector _packets; QHash _nodePacketCounts; QWaitCondition _hasPackets; From 1d16d80c0c8a1b553bf555d8caff3b0d7396c90f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 14:55:24 -0700 Subject: [PATCH 10/23] Comments from CR --- libraries/networking/src/ReceivedPacketProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/ReceivedPacketProcessor.cpp b/libraries/networking/src/ReceivedPacketProcessor.cpp index 706266a903..3c4b32b4ec 100644 --- a/libraries/networking/src/ReceivedPacketProcessor.cpp +++ b/libraries/networking/src/ReceivedPacketProcessor.cpp @@ -40,13 +40,13 @@ bool ReceivedPacketProcessor::process() { } preProcess(); - QVector currentPackets; if (!_packets.size()) { return isStillRunning(); } lock(); - std::swap(currentPackets, _packets); + QVector currentPackets; + currentPackets.swap(_packets); unlock(); foreach(auto& packet, currentPackets) { From 8b0086417598d831a307a19cd80d6071a321b084 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 1 Jul 2015 15:04:19 -0700 Subject: [PATCH 11/23] hydra hand spheres and lasers are rendering again --- examples/lineRotations.js | 134 +++++++++++++++++++++++++ interface/src/Application.cpp | 2 +- interface/src/avatar/Avatar.cpp | 8 +- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/Hand.cpp | 54 +++++----- interface/src/avatar/Hand.h | 2 +- interface/src/avatar/MyAvatar.cpp | 12 ++- interface/src/avatar/MyAvatar.h | 2 +- interface/src/avatar/SkeletonModel.cpp | 2 +- 9 files changed, 173 insertions(+), 45 deletions(-) create mode 100644 examples/lineRotations.js diff --git a/examples/lineRotations.js b/examples/lineRotations.js new file mode 100644 index 0000000000..e60be82770 --- /dev/null +++ b/examples/lineRotations.js @@ -0,0 +1,134 @@ +// +// RenderableQuadEntityItem.cpp +// libraries/entities-renderer/src/ +// +// Created by Eric Levin on 6/22/15 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include +#include + +#include +#include + +#include "RenderableQuadEntityItem.h" + + + + + + + +EntityItemPointer RenderableQuadEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { + return EntityItemPointer(new RenderableQuadEntityItem(entityID, properties)); +} + +RenderableQuadEntityItem::RenderableQuadEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : +QuadEntityItem(entityItemID, properties) { + _numVertices = 0; + +} + +gpu::PipelinePointer RenderableQuadEntityItem::_pipeline; +gpu::Stream::FormatPointer RenderableQuadEntityItem::_format; + +void RenderableQuadEntityItem::createPipeline() { + static const int NORMAL_OFFSET = 12; + static const int COLOR_OFFSET = 24; + _format.reset(new gpu::Stream::Format()); + _format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); + _format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET); + _format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), COLOR_OFFSET); + + auto VS = DependencyManager::get()->getSimpleVertexShader(); + auto PS = DependencyManager::get()->getSimplePixelShader(); + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + //state->setCullMode(gpu::State::CULL_BACK); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); +} +int generateColor() { + float c1 = static_cast (rand()) / static_cast (RAND_MAX); + float c2 = static_cast (rand()) / static_cast (RAND_MAX); + float c3 = static_cast (rand()) / static_cast (RAND_MAX); + return ((int(c1 * 255.0f) & 0xFF)) | + ((int(c2 * 255.0f) & 0xFF) << 8) | + ((int(c3 * 255.0f) & 0xFF) << 16) | + ((int(255.0f) & 0xFF) << 24); +} + +void RenderableQuadEntityItem::updateGeometry() { + QReadLocker lock(&_quadReadWriteLock); + int compactColor = generateColor(); + _numVertices = 0; + _verticesBuffer.reset(new gpu::Buffer()); + int vertexIndex = 0; + for (int i = 0; i < _normals.size(); i++) { + compactColor = generateColor(); + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); + vertexIndex++; + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); + _verticesBuffer->append(sizeof(int), (gpu::Byte*)&compactColor); + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); + vertexIndex++; + _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); + _verticesBuffer->append(sizeof(int), (gpu::Byte*)&compactColor); + + _numVertices +=2; + } + _pointsChanged = false; + + + +} + + + +void RenderableQuadEntityItem::render(RenderArgs* args) { + if (_points.size() < 2 || _vertices.size() != _normals.size() * 2) { + return; + } + + if (!_pipeline) { + createPipeline(); + } + + PerformanceTimer perfTimer("RenderableQuadEntityItem::render"); + Q_ASSERT(getType() == EntityTypes::Quad); + + Q_ASSERT(args->_batch); + if (_pointsChanged) { + updateGeometry(); + } + + + gpu::Batch& batch = *args->_batch; + Transform transform = Transform(); + transform.setTranslation(getPosition()); + transform.setRotation(getRotation()); + batch.setModelTransform(transform); + + + batch.setPipeline(_pipeline); + + batch.setInputFormat(_format); + batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); + + batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); + + RenderableDebugableEntityItem::render(this, args); +}; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2e2722aec2..ce070f4ca9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3547,7 +3547,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } //Render the sixense lasers if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { - _myAvatar->renderLaserPointers(); + _myAvatar->renderLaserPointers(*renderArgs->_batch); } if (!selfAvatarOnly) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index d0778481a6..384b2f0c86 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -575,9 +575,9 @@ void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool return; } - if (postLighting) { +// if (postLighting) { getHand()->render(renderArgs, false); - } +// } } getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting); } @@ -1010,7 +1010,7 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) { int Avatar::_jointConesID = GeometryCache::UNKNOWN_ID; // render a makeshift cone section that serves as a body part connecting joint spheres -void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, +void Avatar::renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, float radius1, float radius2, const glm::vec4& color) { auto geometryCache = DependencyManager::get(); @@ -1057,7 +1057,7 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, // TODO: this is really inefficient constantly recreating these vertices buffers. It would be // better if the avatars cached these buffers for each of the joints they are rendering geometryCache->updateVertices(_jointConesID, points, color); - geometryCache->renderVertices(gpu::TRIANGLES, _jointConesID); + geometryCache->renderVertices(batch, gpu::TRIANGLES, _jointConesID); } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 236b04864b..b23059acb0 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -148,7 +148,7 @@ public: virtual int parseDataAtOffset(const QByteArray& packet, int offset); - static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, + static void renderJointConnectingCone( gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2, float radius1, float radius2, const glm::vec4& color); virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index 74653d9768..7b2968973c 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -103,7 +103,8 @@ void Hand::resolvePenetrations() { } void Hand::render(RenderArgs* renderArgs, bool isMine) { - if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE && + gpu::Batch& batch = *renderArgs->_batch; + if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) { // draw a green sphere at hand joint location, which is actually near the wrist) for (size_t i = 0; i < getNumPalms(); i++) { @@ -112,31 +113,25 @@ void Hand::render(RenderArgs* renderArgs, bool isMine) { continue; } glm::vec3 position = palm.getPosition(); - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - DependencyManager::get()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10, glm::vec3(0.0f, 1.0f, 0.0f)); - glPopMatrix(); + Transform transform = Transform(); + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSphere(batch, PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10, glm::vec3(0.0f, 1.0f, 0.0f)); } } if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHands)) { - renderHandTargets(isMine); + renderHandTargets(renderArgs, isMine); } - glEnable(GL_DEPTH_TEST); - glEnable(GL_RESCALE_NORMAL); -} - -void Hand::renderHandTargets(bool isMine) { - glPushMatrix(); +} +void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { + gpu::Batch& batch = *renderArgs->_batch; const float avatarScale = DependencyManager::get()->getMyAvatar()->getScale(); const float alpha = 1.0f; const glm::vec3 handColor(1.0, 0.0, 0.0); // Color the hand targets red to be different than skin - - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); if (isMine && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHandTargets)) { for (size_t i = 0; i < getNumPalms(); ++i) { @@ -145,12 +140,12 @@ void Hand::renderHandTargets(bool isMine) { continue; } glm::vec3 targetPosition = palm.getTipPosition(); - glPushMatrix(); - glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z); + Transform transform = Transform(); + transform.setTranslation(targetPosition); + batch.setModelTransform(transform); const float collisionRadius = 0.05f; - DependencyManager::get()->renderSphere(collisionRadius, 10, 10, glm::vec4(0.5f,0.5f,0.5f, alpha), false); - glPopMatrix(); + DependencyManager::get()->renderSphere(batch, collisionRadius, 10, 10, glm::vec4(0.5f,0.5f,0.5f, alpha), false); } } @@ -165,22 +160,19 @@ void Hand::renderHandTargets(bool isMine) { if (palm.isActive()) { glm::vec3 tip = palm.getTipPosition(); glm::vec3 root = palm.getPosition(); - - Avatar::renderJointConnectingCone(root, tip, PALM_FINGER_ROD_RADIUS, PALM_FINGER_ROD_RADIUS, glm::vec4(handColor.r, handColor.g, handColor.b, alpha)); + Transform transform = Transform(); + transform.setTranslation(glm::vec3()); + batch.setModelTransform(transform); + Avatar::renderJointConnectingCone(batch, root, tip, PALM_FINGER_ROD_RADIUS, PALM_FINGER_ROD_RADIUS, glm::vec4(handColor.r, handColor.g, handColor.b, alpha)); // Render sphere at palm/finger root glm::vec3 offsetFromPalm = root + palm.getNormal() * PALM_DISK_THICKNESS; - Avatar::renderJointConnectingCone(root, offsetFromPalm, PALM_DISK_RADIUS, 0.0f, glm::vec4(handColor.r, handColor.g, handColor.b, alpha)); - glPushMatrix(); - glTranslatef(root.x, root.y, root.z); - DependencyManager::get()->renderSphere(PALM_BALL_RADIUS, 20.0f, 20.0f, glm::vec4(handColor.r, handColor.g, handColor.b, alpha)); - glPopMatrix(); + Avatar::renderJointConnectingCone(batch, root, offsetFromPalm, PALM_DISK_RADIUS, 0.0f, glm::vec4(handColor.r, handColor.g, handColor.b, alpha)); + transform = Transform(); + transform.setTranslation(root); + batch.setModelTransform(transform); + DependencyManager::get()->renderSphere(batch, PALM_BALL_RADIUS, 20.0f, 20.0f, glm::vec4(handColor.r, handColor.g, handColor.b, alpha)); } } - - glDepthMask(GL_TRUE); - glEnable(GL_DEPTH_TEST); - - glPopMatrix(); } diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h index cb35497960..f6991c5a55 100644 --- a/interface/src/avatar/Hand.h +++ b/interface/src/avatar/Hand.h @@ -56,7 +56,7 @@ private: Avatar* _owningAvatar; - void renderHandTargets(bool isMine); + void renderHandTargets(RenderArgs* renderArgs, bool isMine); }; #endif // hifi_Hand_h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4b140e0569..3c691c49d4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1212,9 +1212,9 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bo if (shouldRenderHead(renderArgs)) { getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting); } - if (postLighting) { +// if (postLighting) { getHand()->render(renderArgs, true); - } +// } } void MyAvatar::setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visible) { @@ -1587,7 +1587,7 @@ void MyAvatar::updateMotionBehavior() { } //Renders sixense laser pointers for UI selection with controllers -void MyAvatar::renderLaserPointers() { +void MyAvatar::renderLaserPointers(gpu::Batch& batch) { const float PALM_TIP_ROD_RADIUS = 0.002f; //If the Oculus is enabled, we will draw a blue cursor ray @@ -1600,8 +1600,10 @@ void MyAvatar::renderLaserPointers() { //Scale the root vector with the avatar scale scaleVectorRelativeToPosition(root); - - Avatar::renderJointConnectingCone(root, tip, PALM_TIP_ROD_RADIUS, PALM_TIP_ROD_RADIUS, glm::vec4(0, 1, 1, 1)); + Transform transform = Transform(); + transform.setTranslation(glm::vec3()); + batch.setModelTransform(transform); + Avatar::renderJointConnectingCone(batch, root, tip, PALM_TIP_ROD_RADIUS, PALM_TIP_ROD_RADIUS, glm::vec4(0, 1, 1, 1)); } } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2fea09ee27..ce5d2148a8 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -157,7 +157,7 @@ public: bool allowDuplicates = false, bool useSaved = true); /// Renders a laser pointer for UI picking - void renderLaserPointers(); + void renderLaserPointers(gpu::Batch& batch); glm::vec3 getLaserPointerTipPosition(const PalmData* palm); const RecorderPointer getRecorder() const { return _recorder; } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2f66e84b50..8095ba9ac4 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -805,7 +805,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) { // draw a green cylinder between the two points glm::vec3 origin(0.0f); - Avatar::renderJointConnectingCone( origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha)); +// Avatar::renderJointConnectingCone( origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha)); glPopMatrix(); } From 8129d0eb1ff958e86b77de51fd048a1e8965b8ae Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 1 Jul 2015 15:12:37 -0700 Subject: [PATCH 12/23] hydra lasers are now rendering again --- interface/src/avatar/Avatar.cpp | 2 +- interface/src/avatar/SkeletonModel.cpp | 14 ++++++-------- interface/src/avatar/SkeletonModel.h | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 384b2f0c86..f011e9f5de 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -449,7 +449,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo getHead()->getFaceModel().renderJointCollisionShapes(0.7f); } if (renderBounding && shouldRenderHead(renderArgs)) { - _skeletonModel.renderBoundingCollisionShapes(0.7f); + _skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f); } // If this is the avatar being looked at, render a little ball above their head diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 8095ba9ac4..20d458195d 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -776,24 +776,24 @@ void SkeletonModel::resetShapePositionsToDefaultPose() { _boundingShape.setRotation(_rotation); } -void SkeletonModel::renderBoundingCollisionShapes(float alpha) { +void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) { const int BALL_SUBDIVISIONS = 10; if (_shapes.isEmpty()) { // the bounding shape has not been propery computed // so no need to render it return; } - glPushMatrix(); - Application::getInstance()->loadTranslatedViewMatrix(_translation); // draw a blue sphere at the capsule endpoint glm::vec3 endPoint; _boundingShape.getEndPoint(endPoint); endPoint = endPoint - _translation; - glTranslatef(endPoint.x, endPoint.y, endPoint.z); + Transform transform = Transform(); + transform.setTranslation(endPoint); + batch.setModelTransform(transform); auto geometryCache = DependencyManager::get(); - geometryCache->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS, glm::vec4(0.6f, 0.6f, 0.8f, alpha)); + geometryCache->renderSphere(batch, _boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS, glm::vec4(0.6f, 0.6f, 0.8f, alpha)); // draw a yellow sphere at the capsule startpoint glm::vec3 startPoint; @@ -805,9 +805,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) { // draw a green cylinder between the two points glm::vec3 origin(0.0f); -// Avatar::renderJointConnectingCone( origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha)); - - glPopMatrix(); + Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha)); } bool SkeletonModel::hasSkeleton() { diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index bffdc58659..755aa3dfee 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -101,7 +101,7 @@ public: const glm::vec3& getStandingOffset() const { return _standingOffset; } void computeBoundingShape(const FBXGeometry& geometry); - void renderBoundingCollisionShapes(float alpha); + void renderBoundingCollisionShapes(gpu::Batch& batch, float alpha); float getBoundingShapeRadius() const { return _boundingShape.getRadius(); } const CapsuleShape& getBoundingShape() const { return _boundingShape; } const glm::vec3 getBoundingShapeOffset() const { return _boundingShapeLocalOffset; } From 50a7332a5a47d0a8956968a509bccf5068759185 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 1 Jul 2015 15:14:53 -0700 Subject: [PATCH 13/23] removed accidental lineRotations.js file commit --- examples/lineRotations.js | 134 -------------------------------------- 1 file changed, 134 deletions(-) delete mode 100644 examples/lineRotations.js diff --git a/examples/lineRotations.js b/examples/lineRotations.js deleted file mode 100644 index e60be82770..0000000000 --- a/examples/lineRotations.js +++ /dev/null @@ -1,134 +0,0 @@ -// -// RenderableQuadEntityItem.cpp -// libraries/entities-renderer/src/ -// -// Created by Eric Levin on 6/22/15 -// Copyright 2015 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include -#include - -#include -#include - -#include "RenderableQuadEntityItem.h" - - - - - - - -EntityItemPointer RenderableQuadEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { - return EntityItemPointer(new RenderableQuadEntityItem(entityID, properties)); -} - -RenderableQuadEntityItem::RenderableQuadEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : -QuadEntityItem(entityItemID, properties) { - _numVertices = 0; - -} - -gpu::PipelinePointer RenderableQuadEntityItem::_pipeline; -gpu::Stream::FormatPointer RenderableQuadEntityItem::_format; - -void RenderableQuadEntityItem::createPipeline() { - static const int NORMAL_OFFSET = 12; - static const int COLOR_OFFSET = 24; - _format.reset(new gpu::Stream::Format()); - _format->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); - _format->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), NORMAL_OFFSET); - _format->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), COLOR_OFFSET); - - auto VS = DependencyManager::get()->getSimpleVertexShader(); - auto PS = DependencyManager::get()->getSimplePixelShader(); - gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); - - gpu::Shader::BindingSet slotBindings; - gpu::Shader::makeProgram(*program, slotBindings); - - gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - //state->setCullMode(gpu::State::CULL_BACK); - state->setDepthTest(true, true, gpu::LESS_EQUAL); - state->setBlendFunction(false, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); - _pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); -} -int generateColor() { - float c1 = static_cast (rand()) / static_cast (RAND_MAX); - float c2 = static_cast (rand()) / static_cast (RAND_MAX); - float c3 = static_cast (rand()) / static_cast (RAND_MAX); - return ((int(c1 * 255.0f) & 0xFF)) | - ((int(c2 * 255.0f) & 0xFF) << 8) | - ((int(c3 * 255.0f) & 0xFF) << 16) | - ((int(255.0f) & 0xFF) << 24); -} - -void RenderableQuadEntityItem::updateGeometry() { - QReadLocker lock(&_quadReadWriteLock); - int compactColor = generateColor(); - _numVertices = 0; - _verticesBuffer.reset(new gpu::Buffer()); - int vertexIndex = 0; - for (int i = 0; i < _normals.size(); i++) { - compactColor = generateColor(); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); - vertexIndex++; - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); - _verticesBuffer->append(sizeof(int), (gpu::Byte*)&compactColor); - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_vertices.at(vertexIndex)); - vertexIndex++; - _verticesBuffer->append(sizeof(glm::vec3), (const gpu::Byte*)&_normals.at(i)); - _verticesBuffer->append(sizeof(int), (gpu::Byte*)&compactColor); - - _numVertices +=2; - } - _pointsChanged = false; - - - -} - - - -void RenderableQuadEntityItem::render(RenderArgs* args) { - if (_points.size() < 2 || _vertices.size() != _normals.size() * 2) { - return; - } - - if (!_pipeline) { - createPipeline(); - } - - PerformanceTimer perfTimer("RenderableQuadEntityItem::render"); - Q_ASSERT(getType() == EntityTypes::Quad); - - Q_ASSERT(args->_batch); - if (_pointsChanged) { - updateGeometry(); - } - - - gpu::Batch& batch = *args->_batch; - Transform transform = Transform(); - transform.setTranslation(getPosition()); - transform.setRotation(getRotation()); - batch.setModelTransform(transform); - - - batch.setPipeline(_pipeline); - - batch.setInputFormat(_format); - batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); - - batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0); - - RenderableDebugableEntityItem::render(this, args); -}; From f49f368ec3ca565ea1709f89a90d030589a24c74 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 1 Jul 2015 15:16:34 -0700 Subject: [PATCH 14/23] removed dead commented out code --- interface/src/avatar/MyAvatar.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3c691c49d4..de524656ec 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1212,9 +1212,7 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bo if (shouldRenderHead(renderArgs)) { getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting); } -// if (postLighting) { - getHand()->render(renderArgs, true); -// } + getHand()->render(renderArgs, true); } void MyAvatar::setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visible) { From a24df5c02ff2b0983d7a736385951d029816d39b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 1 Jul 2015 15:28:48 -0700 Subject: [PATCH 15/23] added postLighting check back for rendering avatar Hands --- interface/src/avatar/Avatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index f011e9f5de..6ff8fb52df 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -575,9 +575,9 @@ void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bool return; } -// if (postLighting) { + if (postLighting) { getHand()->render(renderArgs, false); -// } + } } getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting); } From 24b4614703418600bacee900034e3e059e9b6f90 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 1 Jul 2015 16:11:08 -0700 Subject: [PATCH 16/23] add more detailed edit timing to entity server --- assignment-client/src/octree/OctreeServer.cpp | 19 ++++++++++ libraries/entities/src/EntityTree.cpp | 36 ++++++++++++++++--- libraries/entities/src/EntityTree.h | 28 +++++++++++++++ libraries/octree/src/Octree.h | 12 +++++-- 4 files changed, 89 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 8efe1c39a0..06fb5c4f47 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -327,6 +327,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url showStats = true; } else if (url.path() == "/resetStats") { _octreeInboundPacketProcessor->resetStats(); + _tree->resetEditStats(); resetSendingStats(); showStats = true; } @@ -636,6 +637,13 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url quint64 totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed(); quint64 totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed(); + quint64 averageDecodeTime = _tree->getAverageDecodeTime(); + quint64 averageLookupTime = _tree->getAverageLookupTime(); + quint64 averageUpdateTime = _tree->getAverageUpdateTime(); + quint64 averageCreateTime = _tree->getAverageCreateTime(); + quint64 averageLoggingTime = _tree->getAverageLoggingTime(); + + float averageElementsPerPacket = totalPacketsProcessed == 0 ? 0 : totalElementsProcessed / totalPacketsProcessed; statsString += QString(" Current Inbound Packets Queue: %1 packets\r\n") @@ -658,6 +666,17 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url statsString += QString(" Average Wait Lock Time/Element: %1 usecs\r\n") .arg(locale.toString((uint)averageLockWaitTimePerElement).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Average Decode Time: %1 usecs\r\n") + .arg(locale.toString((uint)averageDecodeTime).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Average Lookup Time: %1 usecs\r\n") + .arg(locale.toString((uint)averageLookupTime).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Average Update Time: %1 usecs\r\n") + .arg(locale.toString((uint)averageUpdateTime).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Average Create Time: %1 usecs\r\n") + .arg(locale.toString((uint)averageCreateTime).rightJustified(COLUMN_WIDTH, ' ')); + statsString += QString(" Average Logging Time: %1 usecs\r\n") + .arg(locale.toString((uint)averageLoggingTime).rightJustified(COLUMN_WIDTH, ' ')); + int senderNumber = 0; NodeToSenderStatsMap& allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats(); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 752082932b..6a652d609b 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -574,41 +574,61 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char case PacketTypeEntityAdd: case PacketTypeEntityEdit: { + quint64 startDecode = 0, endDecode = 0; + quint64 startLookup = 0, endLookup = 0; + quint64 startUpdate = 0, endUpdate = 0; + quint64 startCreate = 0, endCreate = 0; + quint64 startLogging = 0, endLogging = 0; + + _totalEditMessages++; + EntityItemID entityItemID; EntityItemProperties properties; + startDecode = usecTimestampNow(); bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength, processedBytes, entityItemID, properties); + endDecode = usecTimestampNow(); // If we got a valid edit packet, then it could be a new entity or it could be an update to // an existing entity... handle appropriately if (validEditPacket) { // search for the entity by EntityItemID + startLookup = usecTimestampNow(); EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID); + endLookup = usecTimestampNow(); if (existingEntity && packetType == PacketTypeEntityEdit) { // if the EntityItem exists, then update it + startLogging = usecTimestampNow(); if (wantEditLogging()) { qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID; qCDebug(entities) << " properties:" << properties; } + endLogging = usecTimestampNow(); + + startUpdate = usecTimestampNow(); updateEntity(entityItemID, properties, senderNode); existingEntity->markAsChangedOnServer(); + endUpdate = usecTimestampNow(); + _totalUpdates++; } else if (packetType == PacketTypeEntityAdd) { if (senderNode->getCanRez()) { // this is a new entity... assign a new entityID - if (wantEditLogging()) { - qCDebug(entities) << "User [" << senderNode->getUUID() << "] adding entity."; - qCDebug(entities) << " properties:" << properties; - } properties.setCreated(properties.getLastEdited()); + startCreate = usecTimestampNow(); EntityItemPointer newEntity = addEntity(entityItemID, properties); + endCreate = usecTimestampNow(); + _totalCreates++; if (newEntity) { newEntity->markAsChangedOnServer(); notifyNewlyCreatedEntity(*newEntity, senderNode); + + startLogging = usecTimestampNow(); if (wantEditLogging()) { qCDebug(entities) << "User [" << senderNode->getUUID() << "] added entity. ID:" << newEntity->getEntityItemID(); qCDebug(entities) << " properties:" << properties; } + endLogging = usecTimestampNow(); } } else { @@ -619,6 +639,14 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity.get(); } } + + + _totalDecodeTime += endDecode - startDecode; + _totalLookupTime += endLookup - startLookup; + _totalUpdateTime += endUpdate - startUpdate; + _totalCreateTime += endCreate - startCreate; + _totalLoggingTime += endLogging - startLogging; + break; } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 9c4be9a86f..fa72cc7691 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -168,6 +168,23 @@ public: float getContentsLargestDimension(); + virtual void resetEditStats() { + _totalEditMessages = 0; + _totalUpdates = 0; + _totalCreates = 0; + _totalDecodeTime = 0; + _totalLookupTime = 0; + _totalUpdateTime = 0; + _totalCreateTime = 0; + _totalLoggingTime = 0; + } + + virtual quint64 getAverageDecodeTime() const { return _totalEditMessages == 0 ? 0 : _totalDecodeTime / _totalEditMessages; } + virtual quint64 getAverageLookupTime() const { return _totalEditMessages == 0 ? 0 : _totalLookupTime / _totalEditMessages; } + virtual quint64 getAverageUpdateTime() const { return _totalUpdates == 0 ? 0 : _totalUpdateTime / _totalUpdates; } + virtual quint64 getAverageCreateTime() const { return _totalCreates == 0 ? 0 : _totalCreateTime / _totalCreates; } + virtual quint64 getAverageLoggingTime() const { return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; } + signals: void deletingEntity(const EntityItemID& entityID); void addingEntity(const EntityItemID& entityID); @@ -202,6 +219,17 @@ private: bool _wantEditLogging = false; void maybeNotifyNewCollisionSoundURL(const QString& oldCollisionSoundURL, const QString& newCollisionSoundURL); + + + // some performance tracking properties - only used in server trees + int _totalEditMessages = 0; + int _totalUpdates = 0; + int _totalCreates = 0; + quint64 _totalDecodeTime = 0; + quint64 _totalLookupTime = 0; + quint64 _totalUpdateTime = 0; + quint64 _totalCreateTime = 0; + quint64 _totalLoggingTime = 0; }; #endif // hifi_EntityTree_h diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index d7fc58699f..6eeb423ddd 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -367,8 +367,16 @@ public: bool getIsClient() const { return !_isServer; } /// Is this a client based tree. Allows guards for certain operations void setIsClient(bool isClient) { _isServer = !isClient; } - virtual void dumpTree() { }; - virtual void pruneTree() { }; + virtual void dumpTree() { } + virtual void pruneTree() { } + + virtual void resetEditStats() { } + virtual quint64 getAverageDecodeTime() const { return 0; } + virtual quint64 getAverageLookupTime() const { return 0; } + virtual quint64 getAverageUpdateTime() const { return 0; } + virtual quint64 getAverageCreateTime() const { return 0; } + virtual quint64 getAverageLoggingTime() const { return 0; } + signals: void importSize(float x, float y, float z); From 0c88972f090abde0b2b91460aa4da37311445c9f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 14:37:23 -0700 Subject: [PATCH 17/23] Instrument the inter-idle time and tweaking the timeout setting --- interface/src/Application.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a08ac61cf2..1f22b31c64 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1784,9 +1784,23 @@ void Application::checkFPS() { DependencyManager::get()->sendDomainServerCheckIn(); } -void Application::idle() { - PerformanceTimer perfTimer("idle"); +static SimpleMovingAverage interIdleDurations; +static uint64_t lastIdleEnd{ 0 }; +void Application::idle() { + if (lastIdleEnd != 0) { + uint64_t now = usecTimestampNow(); + interIdleDurations.updateAverage(now - lastIdleEnd); + static uint64_t lastReportTime = now; + if ((now - lastReportTime) >= (1000 * 1000)) { + int avgIdleDuration = (int)interIdleDurations.getAverage(); + qDebug() << "Average inter-idle time: " << avgIdleDuration << "s for " << interIdleDurations.getSampleCount() << " samples"; + interIdleDurations.reset(); + lastReportTime = now; + } + } + + PerformanceTimer perfTimer("idle"); if (_aboutToQuit) { return; // bail early, nothing to do here. } @@ -1830,12 +1844,13 @@ void Application::idle() { } // After finishing all of the above work, restart the idle timer, allowing 2ms to process events. - idleTimer->start(2); } - } + idleTimer->start(_glWidget->isThrottleRendering() ? 10 : 0); + } // check for any requested background downloads. emit checkBackgroundDownloads(); + lastIdleEnd = usecTimestampNow(); } void Application::setFullscreen(bool fullscreen) { From 59027959b8d3a8d7cd4e414f5d049e87b7ef1a85 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 16:30:42 -0700 Subject: [PATCH 18/23] CR comments and fixing the average calculation --- interface/src/Application.cpp | 16 ++++++++------ interface/src/InterfaceLogging.cpp | 1 + interface/src/InterfaceLogging.h | 1 + libraries/shared/src/SimpleAverage.h | 33 ++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 libraries/shared/src/SimpleAverage.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1f22b31c64..5241864100 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -91,6 +91,7 @@ #include #include #include +#include #include #include #include @@ -178,6 +179,7 @@ using namespace std; // Starfield information static unsigned STARFIELD_NUM_STARS = 50000; static unsigned STARFIELD_SEED = 1; +static uint8_t THROTTLED_IDLE_TIMER_DELAY = 2; const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB @@ -1784,17 +1786,17 @@ void Application::checkFPS() { DependencyManager::get()->sendDomainServerCheckIn(); } -static SimpleMovingAverage interIdleDurations; -static uint64_t lastIdleEnd{ 0 }; - void Application::idle() { + static SimpleAverage interIdleDurations; + static uint64_t lastIdleEnd{ 0 }; + if (lastIdleEnd != 0) { uint64_t now = usecTimestampNow(); - interIdleDurations.updateAverage(now - lastIdleEnd); + interIdleDurations.update(now - lastIdleEnd); static uint64_t lastReportTime = now; - if ((now - lastReportTime) >= (1000 * 1000)) { + if ((now - lastReportTime) >= (USECS_PER_SECOND)) { int avgIdleDuration = (int)interIdleDurations.getAverage(); - qDebug() << "Average inter-idle time: " << avgIdleDuration << "s for " << interIdleDurations.getSampleCount() << " samples"; + qCDebug(interfaceapp_timing) << "Average inter-idle time: " << avgIdleDuration << "s for " << interIdleDurations.getCount() << " samples"; interIdleDurations.reset(); lastReportTime = now; } @@ -1845,7 +1847,7 @@ void Application::idle() { // After finishing all of the above work, restart the idle timer, allowing 2ms to process events. } - idleTimer->start(_glWidget->isThrottleRendering() ? 10 : 0); + idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 0); } // check for any requested background downloads. diff --git a/interface/src/InterfaceLogging.cpp b/interface/src/InterfaceLogging.cpp index 18bc4e58e8..0afcb30c27 100644 --- a/interface/src/InterfaceLogging.cpp +++ b/interface/src/InterfaceLogging.cpp @@ -12,3 +12,4 @@ #include "InterfaceLogging.h" Q_LOGGING_CATEGORY(interfaceapp, "hifi.interface") +Q_LOGGING_CATEGORY(interfaceapp_timing, "hifi.interface.timing") diff --git a/interface/src/InterfaceLogging.h b/interface/src/InterfaceLogging.h index d1d92aa93d..be2ee73fba 100644 --- a/interface/src/InterfaceLogging.h +++ b/interface/src/InterfaceLogging.h @@ -15,5 +15,6 @@ #include Q_DECLARE_LOGGING_CATEGORY(interfaceapp) +Q_DECLARE_LOGGING_CATEGORY(interfaceapp_timing) #endif // hifi_InterfaceLogging_h diff --git a/libraries/shared/src/SimpleAverage.h b/libraries/shared/src/SimpleAverage.h new file mode 100644 index 0000000000..33ed9d84cc --- /dev/null +++ b/libraries/shared/src/SimpleAverage.h @@ -0,0 +1,33 @@ +// +// Created by Bradley Austin Davis on 2015/07/01. +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#pragma once +#ifndef hifi_SimpleAverage_h +#define hifi_SimpleAverage_h + +template +class SimpleAverage { +public: + void update(T sample) { + _sum += sample; + ++_count; + } + void reset() { + _sum = 0; + _count = 0; + } + + int getCount() const { return _count; }; + T getAverage() const { return _sum / (T)_count; }; + +private: + int _count; + T _sum; +}; + +#endif From 4cffa26c01ca8bd7b5978ea2100d6da0945a32a6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 16:53:12 -0700 Subject: [PATCH 19/23] CR comments and fixing the microsecond display --- interface/src/Application.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5241864100..261055dc60 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -179,7 +179,7 @@ using namespace std; // Starfield information static unsigned STARFIELD_NUM_STARS = 50000; static unsigned STARFIELD_SEED = 1; -static uint8_t THROTTLED_IDLE_TIMER_DELAY = 2; +static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10; const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB @@ -1795,8 +1795,8 @@ void Application::idle() { interIdleDurations.update(now - lastIdleEnd); static uint64_t lastReportTime = now; if ((now - lastReportTime) >= (USECS_PER_SECOND)) { - int avgIdleDuration = (int)interIdleDurations.getAverage(); - qCDebug(interfaceapp_timing) << "Average inter-idle time: " << avgIdleDuration << "s for " << interIdleDurations.getCount() << " samples"; + static QString LOGLINE("Average inter-idle time: %1 us for %2 samples"); + qCDebug(interfaceapp_timing) << LOGLINE.arg((int)interIdleDurations.getAverage()).arg(interIdleDurations.getCount()); interIdleDurations.reset(); lastReportTime = now; } From 88a733181e73573dcd684dd0ed6a8690e1cad31a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 16:54:59 -0700 Subject: [PATCH 20/23] Fixing comment to reflect code --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 261055dc60..9db6188404 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1845,8 +1845,9 @@ void Application::idle() { _idleLoopStdev.reset(); } - // After finishing all of the above work, restart the idle timer, allowing 2ms to process events. } + // After finishing all of the above work, ensure the idle timer is set to the proper interval, + // depending on whether we're throttling or not idleTimer->start(_glWidget->isThrottleRendering() ? THROTTLED_IDLE_TIMER_DELAY : 0); } From 566842389bccd0ac7e75c965d994116dd50bed6f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 1 Jul 2015 17:04:48 -0700 Subject: [PATCH 21/23] Animation performance test script --- examples/animationPerfTest.js | 91 +++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 examples/animationPerfTest.js diff --git a/examples/animationPerfTest.js b/examples/animationPerfTest.js new file mode 100644 index 0000000000..6bf310db23 --- /dev/null +++ b/examples/animationPerfTest.js @@ -0,0 +1,91 @@ +// +// Created by Bradley Austin Davis on 2015/07/01 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var NUM_MOONS = 20; +// 1 = 60Hz, 2 = 30Hz, 3 = 20Hz, etc +var UPDATE_FREQUENCY_DIVISOR = 2; + +var MAX_RANGE = 75.0; +var LIFETIME = 600; +var SCALE = 0.1; + +var center = Vec3.sum(MyAvatar.position, + Vec3.multiply(MAX_RANGE * SCALE, Quat.getFront(Camera.getOrientation()))); + +var DEGREES_TO_RADIANS = Math.PI / 180.0; +var PARTICLE_MIN_SIZE = 2.50; +var PARTICLE_MAX_SIZE = 2.50; + + +var planet = Entities.addEntity({ + type: "Sphere", + position: center, + dimensions: { x: 10 * SCALE, y: 10 * SCALE, z: 10 * SCALE }, + color: { red: 0, green: 0, blue: 255 }, + ignoreCollisions: true, + collisionsWillMove: false, + lifetime: LIFETIME +}); + +var moons = []; + +// Create initial test particles that will move according to gravity from the planets +for (var i = 0; i < NUM_MOONS; i++) { + var radius = PARTICLE_MIN_SIZE + Math.random() * PARTICLE_MAX_SIZE; + radius *= SCALE; + var gray = Math.random() * 155; + var position = { x: 10 , y: i * 3, z: 0 }; + var color = { red: 100 + gray, green: 100 + gray, blue: 100 + gray }; + if (i == 0) { + color = { red: 255, green: 0, blue: 0 }; + radius = 6 * SCALE + } + moons.push(Entities.addEntity({ + type: "Sphere", + position: Vec3.sum(center, position), + dimensions: { x: radius, y: radius, z: radius }, + color: color, + ignoreCollisions: true, + lifetime: LIFETIME, + collisionsWillMove: false + })); +} + +Script.update.connect(update); + +function scriptEnding() { + Entities.deleteEntity(planet); + for (var i = 0; i < moons.length; i++) { + Entities.deleteEntity(moons[i]); + } +} + +var totalTime = 0.0; +var updateCount = 0; +function update(deltaTime) { + // Apply gravitational force from planets + totalTime += deltaTime; + updateCount++; + if (0 != updateCount % UPDATE_FREQUENCY_DIVISOR) { + return; + } + + var planetProperties = Entities.getEntityProperties(planet); + var center = planetProperties.position; + var particlePos = Entities.getEntityProperties(moons[0]).position; + var relativePos = Vec3.subtract(particlePos.position, center); + for (var t = 0; t < moons.length; t++) { + var thetaDelta = (Math.PI * 2.0 / NUM_MOONS) * t; + var y = Math.sin(totalTime + thetaDelta) * 10.0 * SCALE; + var x = Math.cos(totalTime + thetaDelta) * 10.0 * SCALE; + var newBasePos = Vec3.sum({ x: 0, y: y, z: x }, center); + Entities.editEntity(moons[t], { position: newBasePos}); + } +} + +Script.scriptEnding.connect(scriptEnding); From 0df9ebeda399715fa99849af90f7e831feac8f48 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 1 Jul 2015 22:45:13 -0700 Subject: [PATCH 22/23] Fix rendering of look-at avatar sphere postLighting is never true. --- interface/src/avatar/Avatar.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 6ff8fb52df..63b08b693c 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -451,24 +451,24 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo if (renderBounding && shouldRenderHead(renderArgs)) { _skeletonModel.renderBoundingCollisionShapes(*renderArgs->_batch, 0.7f); } + } - // If this is the avatar being looked at, render a little ball above their head - if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::RenderFocusIndicator)) { - const float LOOK_AT_INDICATOR_RADIUS = 0.03f; - const float LOOK_AT_INDICATOR_OFFSET = 0.22f; - const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; - glm::vec3 position; - if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) { - position = glm::vec3(_position.x, getDisplayNamePosition().y, _position.z); - } else { - position = glm::vec3(_position.x, getDisplayNamePosition().y + LOOK_AT_INDICATOR_OFFSET, _position.z); - } - Transform transform; - transform.setTranslation(position); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphere(batch, LOOK_AT_INDICATOR_RADIUS - , 15, 15, LOOK_AT_INDICATOR_COLOR); + // If this is the avatar being looked at, render a little ball above their head + if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::RenderFocusIndicator)) { + const float LOOK_AT_INDICATOR_RADIUS = 0.03f; + const float LOOK_AT_INDICATOR_OFFSET = 0.22f; + const glm::vec4 LOOK_AT_INDICATOR_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; + glm::vec3 position; + if (_displayName.isEmpty() || _displayNameAlpha == 0.0f) { + position = glm::vec3(_position.x, getDisplayNamePosition().y, _position.z); + } else { + position = glm::vec3(_position.x, getDisplayNamePosition().y + LOOK_AT_INDICATOR_OFFSET, _position.z); } + Transform transform; + transform.setTranslation(position); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphere(batch, LOOK_AT_INDICATOR_RADIUS + , 15, 15, LOOK_AT_INDICATOR_COLOR); } // quick check before falling into the code below: From 925fd71262700becbbc8bc3166a6b4848300703d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 1 Jul 2015 22:45:47 -0700 Subject: [PATCH 23/23] Fix rendering of look-at vectors --- interface/src/avatar/Head.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 02d16a1ca4..ed7d84dd24 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -9,9 +9,11 @@ // #include +#include +#include #include -#include +#include #include #include "Application.h" @@ -293,10 +295,8 @@ void Head::relaxLean(float deltaTime) { } void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) { - if (postLighting) { - if (_renderLookatVectors) { + if (_renderLookatVectors) { renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition()); - } } } @@ -380,17 +380,19 @@ void Head::addLeanDeltas(float sideways, float forward) { } void Head::renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { + auto& batch = *renderArgs->_batch; + auto transform = Transform{}; + batch.setModelTransform(transform); + batch._glLineWidth(2.0f); + + auto deferredLighting = DependencyManager::get(); + deferredLighting->bindSimpleProgram(batch); + auto geometryCache = DependencyManager::get(); - DependencyManager::get()->begin(renderArgs); - - glLineWidth(2.0); - glm::vec4 startColor(0.2f, 0.2f, 0.2f, 1.0f); glm::vec4 endColor(1.0f, 1.0f, 1.0f, 0.0f); - geometryCache->renderLine(leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID); - geometryCache->renderLine(rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID); - - DependencyManager::get()->end(renderArgs); + geometryCache->renderLine(batch, leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID); + geometryCache->renderLine(batch, rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID); }