mirror of
https://github.com/overte-org/overte.git
synced 2025-04-26 23:16:19 +02:00
Merge branch 'master' into 20601
Conflicts: interface/src/avatar/Head.cpp
This commit is contained in:
commit
c20cd40275
24 changed files with 358 additions and 108 deletions
|
@ -327,6 +327,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
showStats = true;
|
showStats = true;
|
||||||
} else if (url.path() == "/resetStats") {
|
} else if (url.path() == "/resetStats") {
|
||||||
_octreeInboundPacketProcessor->resetStats();
|
_octreeInboundPacketProcessor->resetStats();
|
||||||
|
_tree->resetEditStats();
|
||||||
resetSendingStats();
|
resetSendingStats();
|
||||||
showStats = true;
|
showStats = true;
|
||||||
}
|
}
|
||||||
|
@ -627,6 +628,7 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
// display inbound packet stats
|
// display inbound packet stats
|
||||||
statsString += QString().sprintf("<b>%s Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n",
|
statsString += QString().sprintf("<b>%s Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n",
|
||||||
getMyServerName());
|
getMyServerName());
|
||||||
|
quint64 currentPacketsInQueue = _octreeInboundPacketProcessor->packetsToProcessCount();
|
||||||
quint64 averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
|
quint64 averageTransitTimePerPacket = _octreeInboundPacketProcessor->getAverageTransitTimePerPacket();
|
||||||
quint64 averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
|
quint64 averageProcessTimePerPacket = _octreeInboundPacketProcessor->getAverageProcessTimePerPacket();
|
||||||
quint64 averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
|
quint64 averageLockWaitTimePerPacket = _octreeInboundPacketProcessor->getAverageLockWaitTimePerPacket();
|
||||||
|
@ -635,8 +637,18 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
quint64 totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
|
quint64 totalElementsProcessed = _octreeInboundPacketProcessor->getTotalElementsProcessed();
|
||||||
quint64 totalPacketsProcessed = _octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
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;
|
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")
|
statsString += QString(" Total Inbound Packets: %1 packets\r\n")
|
||||||
.arg(locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' '));
|
.arg(locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' '));
|
||||||
statsString += QString(" Total Inbound Elements: %1 elements\r\n")
|
statsString += QString(" Total Inbound Elements: %1 elements\r\n")
|
||||||
|
@ -654,6 +666,17 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
|
||||||
statsString += QString(" Average Wait Lock Time/Element: %1 usecs\r\n")
|
statsString += QString(" Average Wait Lock Time/Element: %1 usecs\r\n")
|
||||||
.arg(locale.toString((uint)averageLockWaitTimePerElement).rightJustified(COLUMN_WIDTH, ' '));
|
.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;
|
int senderNumber = 0;
|
||||||
NodeToSenderStatsMap& allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats();
|
NodeToSenderStatsMap& allSenderStats = _octreeInboundPacketProcessor->getSingleSenderStats();
|
||||||
|
@ -1411,6 +1434,8 @@ void OctreeServer::sendStatsPacket() {
|
||||||
|
|
||||||
static QJsonObject statsObject3;
|
static QJsonObject statsObject3;
|
||||||
|
|
||||||
|
statsObject3[baseName + QString(".3.inbound.data.1.packetQueue")] =
|
||||||
|
(double)_octreeInboundPacketProcessor->packetsToProcessCount();
|
||||||
statsObject3[baseName + QString(".3.inbound.data.1.totalPackets")] =
|
statsObject3[baseName + QString(".3.inbound.data.1.totalPackets")] =
|
||||||
(double)_octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
(double)_octreeInboundPacketProcessor->getTotalPacketsProcessed();
|
||||||
statsObject3[baseName + QString(".3.inbound.data.2.totalElements")] =
|
statsObject3[baseName + QString(".3.inbound.data.2.totalElements")] =
|
||||||
|
|
91
examples/animationPerfTest.js
Normal file
91
examples/animationPerfTest.js
Normal file
|
@ -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);
|
|
@ -91,6 +91,7 @@
|
||||||
#include <SceneScriptingInterface.h>
|
#include <SceneScriptingInterface.h>
|
||||||
#include <ScriptCache.h>
|
#include <ScriptCache.h>
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
|
#include <SimpleAverage.h>
|
||||||
#include <SoundCache.h>
|
#include <SoundCache.h>
|
||||||
#include <TextRenderer.h>
|
#include <TextRenderer.h>
|
||||||
#include <Tooltip.h>
|
#include <Tooltip.h>
|
||||||
|
@ -178,6 +179,7 @@ using namespace std;
|
||||||
// Starfield information
|
// Starfield information
|
||||||
static unsigned STARFIELD_NUM_STARS = 50000;
|
static unsigned STARFIELD_NUM_STARS = 50000;
|
||||||
static unsigned STARFIELD_SEED = 1;
|
static unsigned STARFIELD_SEED = 1;
|
||||||
|
static uint8_t THROTTLED_IDLE_TIMER_DELAY = 10;
|
||||||
|
|
||||||
const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
|
const qint64 MAXIMUM_CACHE_SIZE = 10 * BYTES_PER_GIGABYTES; // 10GB
|
||||||
|
|
||||||
|
@ -1037,7 +1039,7 @@ void Application::showEditEntitiesHelp() {
|
||||||
InfoView::show(INFO_EDIT_ENTITIES_PATH);
|
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()) {
|
if (OculusManager::isConnected()) {
|
||||||
OculusManager::configureCamera(camera);
|
OculusManager::configureCamera(camera);
|
||||||
} else if (TV3DManager::isConnected()) {
|
} else if (TV3DManager::isConnected()) {
|
||||||
|
@ -1060,7 +1062,6 @@ void Application::resizeGL() {
|
||||||
if (_renderResolution != toGlm(renderSize)) {
|
if (_renderResolution != toGlm(renderSize)) {
|
||||||
_renderResolution = toGlm(renderSize);
|
_renderResolution = toGlm(renderSize);
|
||||||
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
|
DependencyManager::get<TextureCache>()->setFrameBufferSize(renderSize);
|
||||||
resetCamerasOnResizeGL(_myCamera, _renderResolution);
|
|
||||||
|
|
||||||
glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
|
glViewport(0, 0, _renderResolution.x, _renderResolution.y); // shouldn't this account for the menu???
|
||||||
|
|
||||||
|
@ -1068,6 +1069,8 @@ void Application::resizeGL() {
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetCameras(_myCamera, _renderResolution);
|
||||||
|
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
|
||||||
auto canvasSize = _glWidget->size();
|
auto canvasSize = _glWidget->size();
|
||||||
|
@ -1784,8 +1787,22 @@ void Application::checkFPS() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::idle() {
|
void Application::idle() {
|
||||||
PerformanceTimer perfTimer("idle");
|
static SimpleAverage<float> interIdleDurations;
|
||||||
|
static uint64_t lastIdleEnd{ 0 };
|
||||||
|
|
||||||
|
if (lastIdleEnd != 0) {
|
||||||
|
uint64_t now = usecTimestampNow();
|
||||||
|
interIdleDurations.update(now - lastIdleEnd);
|
||||||
|
static uint64_t lastReportTime = now;
|
||||||
|
if ((now - lastReportTime) >= (USECS_PER_SECOND)) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PerformanceTimer perfTimer("idle");
|
||||||
if (_aboutToQuit) {
|
if (_aboutToQuit) {
|
||||||
return; // bail early, nothing to do here.
|
return; // bail early, nothing to do here.
|
||||||
}
|
}
|
||||||
|
@ -1828,13 +1845,15 @@ void Application::idle() {
|
||||||
_idleLoopStdev.reset();
|
_idleLoopStdev.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
|
|
||||||
idleTimer->start(2);
|
|
||||||
}
|
}
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for any requested background downloads.
|
// check for any requested background downloads.
|
||||||
emit checkBackgroundDownloads();
|
emit checkBackgroundDownloads();
|
||||||
|
lastIdleEnd = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setFullscreen(bool fullscreen) {
|
void Application::setFullscreen(bool fullscreen) {
|
||||||
|
@ -3542,7 +3561,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
}
|
}
|
||||||
//Render the sixense lasers
|
//Render the sixense lasers
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) {
|
||||||
_myAvatar->renderLaserPointers();
|
_myAvatar->renderLaserPointers(*renderArgs->_batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!selfAvatarOnly) {
|
if (!selfAvatarOnly) {
|
||||||
|
|
|
@ -483,7 +483,7 @@ private slots:
|
||||||
void setCursorVisible(bool visible);
|
void setCursorVisible(bool visible);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resetCamerasOnResizeGL(Camera& camera, const glm::uvec2& size);
|
void resetCameras(Camera& camera, const glm::uvec2& size);
|
||||||
void updateProjectionMatrix();
|
void updateProjectionMatrix();
|
||||||
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
void updateProjectionMatrix(Camera& camera, bool updateViewFrustum = true);
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,4 @@
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(interfaceapp, "hifi.interface")
|
Q_LOGGING_CATEGORY(interfaceapp, "hifi.interface")
|
||||||
|
Q_LOGGING_CATEGORY(interfaceapp_timing, "hifi.interface.timing")
|
||||||
|
|
|
@ -15,5 +15,6 @@
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(interfaceapp)
|
Q_DECLARE_LOGGING_CATEGORY(interfaceapp)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(interfaceapp_timing)
|
||||||
|
|
||||||
#endif // hifi_InterfaceLogging_h
|
#endif // hifi_InterfaceLogging_h
|
||||||
|
|
|
@ -449,7 +449,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
||||||
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
|
getHead()->getFaceModel().renderJointCollisionShapes(0.7f);
|
||||||
}
|
}
|
||||||
if (renderBounding && shouldRenderHead(renderArgs)) {
|
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
|
// If this is the avatar being looked at, render a little ball above their head
|
||||||
|
@ -469,7 +470,6 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition, boo
|
||||||
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, LOOK_AT_INDICATOR_RADIUS
|
DependencyManager::get<DeferredLightingEffect>()->renderSolidSphere(batch, LOOK_AT_INDICATOR_RADIUS
|
||||||
, 15, 15, LOOK_AT_INDICATOR_COLOR);
|
, 15, 15, LOOK_AT_INDICATOR_COLOR);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// quick check before falling into the code below:
|
// quick check before falling into the code below:
|
||||||
// (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m)
|
// (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m)
|
||||||
|
@ -1010,7 +1010,7 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||||
int Avatar::_jointConesID = GeometryCache::UNKNOWN_ID;
|
int Avatar::_jointConesID = GeometryCache::UNKNOWN_ID;
|
||||||
|
|
||||||
// render a makeshift cone section that serves as a body part connecting joint spheres
|
// 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) {
|
float radius1, float radius2, const glm::vec4& color) {
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -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
|
// 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
|
// better if the avatars cached these buffers for each of the joints they are rendering
|
||||||
geometryCache->updateVertices(_jointConesID, points, color);
|
geometryCache->updateVertices(_jointConesID, points, color);
|
||||||
geometryCache->renderVertices(gpu::TRIANGLES, _jointConesID);
|
geometryCache->renderVertices(batch, gpu::TRIANGLES, _jointConesID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ public:
|
||||||
|
|
||||||
virtual int parseDataAtOffset(const QByteArray& packet, int offset);
|
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);
|
float radius1, float radius2, const glm::vec4& color);
|
||||||
|
|
||||||
virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { }
|
virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { }
|
||||||
|
|
|
@ -103,6 +103,7 @@ void Hand::resolvePenetrations() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hand::render(RenderArgs* renderArgs, bool isMine) {
|
void Hand::render(RenderArgs* renderArgs, bool isMine) {
|
||||||
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE &&
|
if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE &&
|
||||||
Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) {
|
Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes)) {
|
||||||
// draw a green sphere at hand joint location, which is actually near the wrist)
|
// draw a green sphere at hand joint location, which is actually near the wrist)
|
||||||
|
@ -112,32 +113,26 @@ void Hand::render(RenderArgs* renderArgs, bool isMine) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glm::vec3 position = palm.getPosition();
|
glm::vec3 position = palm.getPosition();
|
||||||
glPushMatrix();
|
Transform transform = Transform();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
transform.setTranslation(position);
|
||||||
DependencyManager::get<GeometryCache>()->renderSphere(PALM_COLLISION_RADIUS * _owningAvatar->getScale(), 10, 10, glm::vec3(0.0f, 1.0f, 0.0f));
|
batch.setModelTransform(transform);
|
||||||
glPopMatrix();
|
DependencyManager::get<GeometryCache>()->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)) {
|
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) {
|
void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
glPushMatrix();
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
|
|
||||||
const float avatarScale = DependencyManager::get<AvatarManager>()->getMyAvatar()->getScale();
|
const float avatarScale = DependencyManager::get<AvatarManager>()->getMyAvatar()->getScale();
|
||||||
|
|
||||||
const float alpha = 1.0f;
|
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
|
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)) {
|
if (isMine && Menu::getInstance()->isOptionChecked(MenuOption::DisplayHandTargets)) {
|
||||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
for (size_t i = 0; i < getNumPalms(); ++i) {
|
||||||
PalmData& palm = getPalms()[i];
|
PalmData& palm = getPalms()[i];
|
||||||
|
@ -145,12 +140,12 @@ void Hand::renderHandTargets(bool isMine) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
glm::vec3 targetPosition = palm.getTipPosition();
|
glm::vec3 targetPosition = palm.getTipPosition();
|
||||||
glPushMatrix();
|
Transform transform = Transform();
|
||||||
glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z);
|
transform.setTranslation(targetPosition);
|
||||||
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
const float collisionRadius = 0.05f;
|
const float collisionRadius = 0.05f;
|
||||||
DependencyManager::get<GeometryCache>()->renderSphere(collisionRadius, 10, 10, glm::vec4(0.5f,0.5f,0.5f, alpha), false);
|
DependencyManager::get<GeometryCache>()->renderSphere(batch, collisionRadius, 10, 10, glm::vec4(0.5f,0.5f,0.5f, alpha), false);
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,22 +160,19 @@ void Hand::renderHandTargets(bool isMine) {
|
||||||
if (palm.isActive()) {
|
if (palm.isActive()) {
|
||||||
glm::vec3 tip = palm.getTipPosition();
|
glm::vec3 tip = palm.getTipPosition();
|
||||||
glm::vec3 root = palm.getPosition();
|
glm::vec3 root = palm.getPosition();
|
||||||
|
Transform transform = Transform();
|
||||||
Avatar::renderJointConnectingCone(root, tip, PALM_FINGER_ROD_RADIUS, PALM_FINGER_ROD_RADIUS, glm::vec4(handColor.r, handColor.g, handColor.b, alpha));
|
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
|
// Render sphere at palm/finger root
|
||||||
glm::vec3 offsetFromPalm = root + palm.getNormal() * PALM_DISK_THICKNESS;
|
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));
|
Avatar::renderJointConnectingCone(batch, root, offsetFromPalm, PALM_DISK_RADIUS, 0.0f, glm::vec4(handColor.r, handColor.g, handColor.b, alpha));
|
||||||
glPushMatrix();
|
transform = Transform();
|
||||||
glTranslatef(root.x, root.y, root.z);
|
transform.setTranslation(root);
|
||||||
DependencyManager::get<GeometryCache>()->renderSphere(PALM_BALL_RADIUS, 20.0f, 20.0f, glm::vec4(handColor.r, handColor.g, handColor.b, alpha));
|
batch.setModelTransform(transform);
|
||||||
glPopMatrix();
|
DependencyManager::get<GeometryCache>()->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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ private:
|
||||||
|
|
||||||
Avatar* _owningAvatar;
|
Avatar* _owningAvatar;
|
||||||
|
|
||||||
void renderHandTargets(bool isMine);
|
void renderHandTargets(RenderArgs* renderArgs, bool isMine);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Hand_h
|
#endif // hifi_Hand_h
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
#include <gpu/GPUConfig.h>
|
||||||
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <GlowEffect.h>
|
#include <DeferredLightingEffect.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
@ -293,12 +295,10 @@ void Head::relaxLean(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) {
|
void Head::render(RenderArgs* renderArgs, float alpha, ViewFrustum* renderFrustum, bool postLighting) {
|
||||||
if (postLighting) {
|
|
||||||
if (_renderLookatVectors) {
|
if (_renderLookatVectors) {
|
||||||
renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getLookAtPosition());
|
renderLookatVectors(renderArgs, _leftEyePosition, _rightEyePosition, getLookAtPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Head::setScale (float scale) {
|
void Head::setScale (float scale) {
|
||||||
if (_scale == scale) {
|
if (_scale == scale) {
|
||||||
|
@ -367,17 +367,19 @@ void Head::addLeanDeltas(float sideways, float forward) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::renderLookatVectors(RenderArgs* renderArgs, glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
|
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<DeferredLightingEffect>();
|
||||||
|
deferredLighting->bindSimpleProgram(batch);
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
DependencyManager::get<GlowEffect>()->begin(renderArgs);
|
|
||||||
|
|
||||||
glLineWidth(2.0);
|
|
||||||
|
|
||||||
glm::vec4 startColor(0.2f, 0.2f, 0.2f, 1.0f);
|
glm::vec4 startColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||||
glm::vec4 endColor(1.0f, 1.0f, 1.0f, 0.0f);
|
glm::vec4 endColor(1.0f, 1.0f, 1.0f, 0.0f);
|
||||||
geometryCache->renderLine(leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID);
|
geometryCache->renderLine(batch, leftEyePosition, lookatPosition, startColor, endColor, _leftEyeLookAtID);
|
||||||
geometryCache->renderLine(rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID);
|
geometryCache->renderLine(batch, rightEyePosition, lookatPosition, startColor, endColor, _rightEyeLookAtID);
|
||||||
|
|
||||||
DependencyManager::get<GlowEffect>()->end(renderArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1208,10 +1208,8 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, bo
|
||||||
if (shouldRenderHead(renderArgs)) {
|
if (shouldRenderHead(renderArgs)) {
|
||||||
getHead()->render(renderArgs, 1.0f, renderFrustum, postLighting);
|
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) {
|
void MyAvatar::setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visible) {
|
||||||
if (model->isActive() && model->isRenderable()) {
|
if (model->isActive() && model->isRenderable()) {
|
||||||
|
@ -1584,7 +1582,7 @@ void MyAvatar::updateMotionBehavior() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Renders sixense laser pointers for UI selection with controllers
|
//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;
|
const float PALM_TIP_ROD_RADIUS = 0.002f;
|
||||||
|
|
||||||
//If the Oculus is enabled, we will draw a blue cursor ray
|
//If the Oculus is enabled, we will draw a blue cursor ray
|
||||||
|
@ -1597,8 +1595,10 @@ void MyAvatar::renderLaserPointers() {
|
||||||
|
|
||||||
//Scale the root vector with the avatar scale
|
//Scale the root vector with the avatar scale
|
||||||
scaleVectorRelativeToPosition(root);
|
scaleVectorRelativeToPosition(root);
|
||||||
|
Transform transform = Transform();
|
||||||
Avatar::renderJointConnectingCone(root, tip, PALM_TIP_ROD_RADIUS, PALM_TIP_ROD_RADIUS, glm::vec4(0, 1, 1, 1));
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ public:
|
||||||
bool allowDuplicates = false, bool useSaved = true);
|
bool allowDuplicates = false, bool useSaved = true);
|
||||||
|
|
||||||
/// Renders a laser pointer for UI picking
|
/// Renders a laser pointer for UI picking
|
||||||
void renderLaserPointers();
|
void renderLaserPointers(gpu::Batch& batch);
|
||||||
glm::vec3 getLaserPointerTipPosition(const PalmData* palm);
|
glm::vec3 getLaserPointerTipPosition(const PalmData* palm);
|
||||||
|
|
||||||
const RecorderPointer getRecorder() const { return _recorder; }
|
const RecorderPointer getRecorder() const { return _recorder; }
|
||||||
|
|
|
@ -776,24 +776,24 @@ void SkeletonModel::resetShapePositionsToDefaultPose() {
|
||||||
_boundingShape.setRotation(_rotation);
|
_boundingShape.setRotation(_rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
|
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
|
||||||
const int BALL_SUBDIVISIONS = 10;
|
const int BALL_SUBDIVISIONS = 10;
|
||||||
if (_shapes.isEmpty()) {
|
if (_shapes.isEmpty()) {
|
||||||
// the bounding shape has not been propery computed
|
// the bounding shape has not been propery computed
|
||||||
// so no need to render it
|
// so no need to render it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
glPushMatrix();
|
|
||||||
|
|
||||||
Application::getInstance()->loadTranslatedViewMatrix(_translation);
|
Application::getInstance()->loadTranslatedViewMatrix(_translation);
|
||||||
|
|
||||||
// draw a blue sphere at the capsule endpoint
|
// draw a blue sphere at the capsule endpoint
|
||||||
glm::vec3 endPoint;
|
glm::vec3 endPoint;
|
||||||
_boundingShape.getEndPoint(endPoint);
|
_boundingShape.getEndPoint(endPoint);
|
||||||
endPoint = endPoint - _translation;
|
endPoint = endPoint - _translation;
|
||||||
glTranslatef(endPoint.x, endPoint.y, endPoint.z);
|
Transform transform = Transform();
|
||||||
|
transform.setTranslation(endPoint);
|
||||||
|
batch.setModelTransform(transform);
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
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
|
// draw a yellow sphere at the capsule startpoint
|
||||||
glm::vec3 startPoint;
|
glm::vec3 startPoint;
|
||||||
|
@ -805,9 +805,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
|
||||||
|
|
||||||
// draw a green cylinder between the two points
|
// draw a green cylinder between the two points
|
||||||
glm::vec3 origin(0.0f);
|
glm::vec3 origin(0.0f);
|
||||||
Avatar::renderJointConnectingCone( origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha));
|
Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha));
|
||||||
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkeletonModel::hasSkeleton() {
|
bool SkeletonModel::hasSkeleton() {
|
||||||
|
|
|
@ -101,7 +101,7 @@ public:
|
||||||
const glm::vec3& getStandingOffset() const { return _standingOffset; }
|
const glm::vec3& getStandingOffset() const { return _standingOffset; }
|
||||||
|
|
||||||
void computeBoundingShape(const FBXGeometry& geometry);
|
void computeBoundingShape(const FBXGeometry& geometry);
|
||||||
void renderBoundingCollisionShapes(float alpha);
|
void renderBoundingCollisionShapes(gpu::Batch& batch, float alpha);
|
||||||
float getBoundingShapeRadius() const { return _boundingShape.getRadius(); }
|
float getBoundingShapeRadius() const { return _boundingShape.getRadius(); }
|
||||||
const CapsuleShape& getBoundingShape() const { return _boundingShape; }
|
const CapsuleShape& getBoundingShape() const { return _boundingShape; }
|
||||||
const glm::vec3 getBoundingShapeOffset() const { return _boundingShapeLocalOffset; }
|
const glm::vec3 getBoundingShapeOffset() const { return _boundingShapeLocalOffset; }
|
||||||
|
|
|
@ -221,8 +221,6 @@ void PreferencesDialog::savePreferences() {
|
||||||
myAvatar->setLeanScale(ui.leanScaleSpin->value());
|
myAvatar->setLeanScale(ui.leanScaleSpin->value());
|
||||||
myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value());
|
myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value());
|
||||||
|
|
||||||
Application::getInstance()->resizeGL();
|
|
||||||
|
|
||||||
DependencyManager::get<AvatarManager>()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
|
DependencyManager::get<AvatarManager>()->getMyAvatar()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
|
||||||
|
|
||||||
qApp->setFieldOfView(ui.fieldOfViewSpin->value());
|
qApp->setFieldOfView(ui.fieldOfViewSpin->value());
|
||||||
|
|
|
@ -170,3 +170,11 @@ QSizeF TextOverlay::textSize(const QString& text) const {
|
||||||
|
|
||||||
return QSizeF(extents.x, extents.y);
|
return QSizeF(extents.x, extents.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextOverlay::setFontSize(int fontSize) {
|
||||||
|
_fontSize = fontSize;
|
||||||
|
|
||||||
|
auto oldTextRenderer = _textRenderer;
|
||||||
|
_textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT);
|
||||||
|
delete oldTextRenderer;
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
void setText(const QString& text) { _text = text; }
|
void setText(const QString& text) { _text = text; }
|
||||||
void setLeftMargin(int margin) { _leftMargin = margin; }
|
void setLeftMargin(int margin) { _leftMargin = margin; }
|
||||||
void setTopMargin(int margin) { _topMargin = margin; }
|
void setTopMargin(int margin) { _topMargin = margin; }
|
||||||
void setFontSize(int fontSize) { _fontSize = fontSize; }
|
void setFontSize(int fontSize);
|
||||||
|
|
||||||
virtual void setProperties(const QScriptValue& properties);
|
virtual void setProperties(const QScriptValue& properties);
|
||||||
virtual TextOverlay* createClone() const;
|
virtual TextOverlay* createClone() const;
|
||||||
|
|
|
@ -574,41 +574,61 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
|
|
||||||
case PacketTypeEntityAdd:
|
case PacketTypeEntityAdd:
|
||||||
case PacketTypeEntityEdit: {
|
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;
|
EntityItemID entityItemID;
|
||||||
EntityItemProperties properties;
|
EntityItemProperties properties;
|
||||||
|
startDecode = usecTimestampNow();
|
||||||
bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength,
|
bool validEditPacket = EntityItemProperties::decodeEntityEditPacket(editData, maxLength,
|
||||||
processedBytes, entityItemID, properties);
|
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
|
// 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
|
// an existing entity... handle appropriately
|
||||||
if (validEditPacket) {
|
if (validEditPacket) {
|
||||||
// search for the entity by EntityItemID
|
// search for the entity by EntityItemID
|
||||||
|
startLookup = usecTimestampNow();
|
||||||
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
|
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
|
||||||
|
endLookup = usecTimestampNow();
|
||||||
if (existingEntity && packetType == PacketTypeEntityEdit) {
|
if (existingEntity && packetType == PacketTypeEntityEdit) {
|
||||||
// if the EntityItem exists, then update it
|
// if the EntityItem exists, then update it
|
||||||
|
startLogging = usecTimestampNow();
|
||||||
if (wantEditLogging()) {
|
if (wantEditLogging()) {
|
||||||
qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID;
|
qCDebug(entities) << "User [" << senderNode->getUUID() << "] editing entity. ID:" << entityItemID;
|
||||||
qCDebug(entities) << " properties:" << properties;
|
qCDebug(entities) << " properties:" << properties;
|
||||||
}
|
}
|
||||||
|
endLogging = usecTimestampNow();
|
||||||
|
|
||||||
|
startUpdate = usecTimestampNow();
|
||||||
updateEntity(entityItemID, properties, senderNode);
|
updateEntity(entityItemID, properties, senderNode);
|
||||||
existingEntity->markAsChangedOnServer();
|
existingEntity->markAsChangedOnServer();
|
||||||
|
endUpdate = usecTimestampNow();
|
||||||
|
_totalUpdates++;
|
||||||
} else if (packetType == PacketTypeEntityAdd) {
|
} else if (packetType == PacketTypeEntityAdd) {
|
||||||
if (senderNode->getCanRez()) {
|
if (senderNode->getCanRez()) {
|
||||||
// this is a new entity... assign a new entityID
|
// 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());
|
properties.setCreated(properties.getLastEdited());
|
||||||
|
startCreate = usecTimestampNow();
|
||||||
EntityItemPointer newEntity = addEntity(entityItemID, properties);
|
EntityItemPointer newEntity = addEntity(entityItemID, properties);
|
||||||
|
endCreate = usecTimestampNow();
|
||||||
|
_totalCreates++;
|
||||||
if (newEntity) {
|
if (newEntity) {
|
||||||
newEntity->markAsChangedOnServer();
|
newEntity->markAsChangedOnServer();
|
||||||
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
||||||
|
|
||||||
|
startLogging = usecTimestampNow();
|
||||||
if (wantEditLogging()) {
|
if (wantEditLogging()) {
|
||||||
qCDebug(entities) << "User [" << senderNode->getUUID() << "] added entity. ID:"
|
qCDebug(entities) << "User [" << senderNode->getUUID() << "] added entity. ID:"
|
||||||
<< newEntity->getEntityItemID();
|
<< newEntity->getEntityItemID();
|
||||||
qCDebug(entities) << " properties:" << properties;
|
qCDebug(entities) << " properties:" << properties;
|
||||||
}
|
}
|
||||||
|
endLogging = usecTimestampNow();
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -619,6 +639,14 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
||||||
qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity.get();
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,23 @@ public:
|
||||||
|
|
||||||
float getContentsLargestDimension();
|
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:
|
signals:
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
@ -202,6 +219,17 @@ private:
|
||||||
|
|
||||||
bool _wantEditLogging = false;
|
bool _wantEditLogging = false;
|
||||||
void maybeNotifyNewCollisionSoundURL(const QString& oldCollisionSoundURL, const QString& newCollisionSoundURL);
|
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
|
#endif // hifi_EntityTree_h
|
||||||
|
|
|
@ -38,19 +38,28 @@ bool ReceivedPacketProcessor::process() {
|
||||||
_hasPackets.wait(&_waitingOnPacketsMutex, getMaxWait());
|
_hasPackets.wait(&_waitingOnPacketsMutex, getMaxWait());
|
||||||
_waitingOnPacketsMutex.unlock();
|
_waitingOnPacketsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
preProcess();
|
preProcess();
|
||||||
while (_packets.size() > 0) {
|
if (!_packets.size()) {
|
||||||
lock(); // lock to make sure nothing changes on us
|
return isStillRunning();
|
||||||
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
|
lock();
|
||||||
|
QVector<NetworkPacket> currentPackets;
|
||||||
|
currentPackets.swap(_packets);
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
foreach(auto& packet, currentPackets) {
|
||||||
|
processPacket(packet.getNode(), packet.getByteArray());
|
||||||
midProcess();
|
midProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock();
|
||||||
|
foreach(auto& packet, currentPackets) {
|
||||||
|
_nodePacketCounts[packet.getNode()->getUUID()]--;
|
||||||
|
}
|
||||||
|
unlock();
|
||||||
|
|
||||||
postProcess();
|
postProcess();
|
||||||
return isStillRunning(); // keep running till they terminate us
|
return isStillRunning(); // keep running till they terminate us
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,8 +367,16 @@ public:
|
||||||
bool getIsClient() const { return !_isServer; } /// Is this a client based tree. Allows guards for certain operations
|
bool getIsClient() const { return !_isServer; } /// Is this a client based tree. Allows guards for certain operations
|
||||||
void setIsClient(bool isClient) { _isServer = !isClient; }
|
void setIsClient(bool isClient) { _isServer = !isClient; }
|
||||||
|
|
||||||
virtual void dumpTree() { };
|
virtual void dumpTree() { }
|
||||||
virtual void pruneTree() { };
|
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:
|
signals:
|
||||||
void importSize(float x, float y, float z);
|
void importSize(float x, float y, float z);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "PathUtils.h"
|
#include "PathUtils.h"
|
||||||
|
@ -54,6 +55,14 @@ namespace Setting {
|
||||||
privateInstance = new Manager();
|
privateInstance = new Manager();
|
||||||
Q_CHECK_PTR(privateInstance);
|
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(privateInstance, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||||
QObject::connect(thread, SIGNAL(started()), privateInstance, SLOT(startTimer()));
|
QObject::connect(thread, SIGNAL(started()), privateInstance, SLOT(startTimer()));
|
||||||
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||||
|
|
33
libraries/shared/src/SimpleAverage.h
Normal file
33
libraries/shared/src/SimpleAverage.h
Normal file
|
@ -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<typename T>
|
||||||
|
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
|
Loading…
Reference in a new issue