mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #9354 from sethalves/update-tablet-ui-again
Update tablet ui again
This commit is contained in:
commit
493985ac2a
18 changed files with 104 additions and 45 deletions
|
@ -194,8 +194,9 @@ static QTimer pingTimer;
|
|||
|
||||
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
|
||||
|
||||
// For processing on QThreadPool, target 2 less than the ideal number of threads, leaving
|
||||
// 2 logical cores available for time sensitive tasks.
|
||||
// For processing on QThreadPool, we target a number of threads after reserving some
|
||||
// based on how many are being consumed by the application and the display plugin. However,
|
||||
// we will never drop below the 'min' value
|
||||
static const int MIN_PROCESSING_THREAD_POOL_SIZE = 2;
|
||||
|
||||
static const QString SNAPSHOT_EXTENSION = ".jpg";
|
||||
|
@ -3309,15 +3310,15 @@ void Application::idle(float nsecsElapsed) {
|
|||
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
||||
}
|
||||
|
||||
PROFILE_COUNTER(app, "fps", { { "fps", _frameCounter.rate() } });
|
||||
PROFILE_COUNTER(app, "downloads", {
|
||||
{ "current", ResourceCache::getLoadingRequests().length() },
|
||||
{ "pending", ResourceCache::getPendingRequestCount() }
|
||||
});
|
||||
PROFILE_COUNTER(app, "processing", {
|
||||
{ "current", DependencyManager::get<StatTracker>()->getStat("Processing") },
|
||||
{ "pending", DependencyManager::get<StatTracker>()->getStat("PendingProcessing") }
|
||||
});
|
||||
auto displayPlugin = getActiveDisplayPlugin();
|
||||
if (displayPlugin) {
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "present", float, displayPlugin->presentRate());
|
||||
}
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "fps", float, _frameCounter.rate());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentDownloads", int, ResourceCache::getLoadingRequests().length());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingDownloads", int, ResourceCache::getPendingRequestCount());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "currentProcessing", int, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
|
||||
PROFILE_COUNTER_IF_CHANGED(app, "pendingProcessing", int, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
|
||||
|
||||
PROFILE_RANGE(app, __FUNCTION__);
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "Application.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(trace_test, "trace.test")
|
||||
|
||||
TestScriptingInterface* TestScriptingInterface::getInstance() {
|
||||
static TestScriptingInterface sharedInstance;
|
||||
return &sharedInstance;
|
||||
|
@ -125,3 +127,10 @@ bool TestScriptingInterface::waitForCondition(qint64 maxWaitMs, std::function<bo
|
|||
return condition();
|
||||
}
|
||||
|
||||
void TestScriptingInterface::startTraceEvent(QString name) {
|
||||
tracing::traceEvent(trace_test(), name, tracing::DurationBegin, "");
|
||||
}
|
||||
|
||||
void TestScriptingInterface::endTraceEvent(QString name) {
|
||||
tracing::traceEvent(trace_test(), name, tracing::DurationEnd);
|
||||
}
|
||||
|
|
|
@ -65,6 +65,11 @@ public slots:
|
|||
*/
|
||||
bool stopTracing(QString filename);
|
||||
|
||||
void startTraceEvent(QString name);
|
||||
|
||||
void endTraceEvent(QString name);
|
||||
|
||||
|
||||
private:
|
||||
bool waitForCondition(qint64 maxWaitMs, std::function<bool()> condition);
|
||||
};
|
||||
|
|
|
@ -902,7 +902,7 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
|
|||
|
||||
void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
||||
|
||||
PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xffff00ff, 0);
|
||||
PROFILE_RANGE_EX(simulation_animation_detail, __FUNCTION__, 0xffff00ff, 0);
|
||||
PerformanceTimer perfTimer("updateAnimations");
|
||||
|
||||
setModelOffset(rootTransform);
|
||||
|
|
|
@ -561,22 +561,22 @@ void OpenGLDisplayPlugin::compositeLayers() {
|
|||
updateCompositeFramebuffer();
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX(render, "compositeScene", 0xff0077ff, (uint64_t)presentCount())
|
||||
PROFILE_RANGE_EX(render_detail, "compositeScene", 0xff0077ff, (uint64_t)presentCount())
|
||||
compositeScene();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX(render, "compositeOverlay", 0xff0077ff, (uint64_t)presentCount())
|
||||
PROFILE_RANGE_EX(render_detail, "compositeOverlay", 0xff0077ff, (uint64_t)presentCount())
|
||||
compositeOverlay();
|
||||
}
|
||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||
if (compositorHelper->getReticleVisible()) {
|
||||
PROFILE_RANGE_EX(render, "compositePointer", 0xff0077ff, (uint64_t)presentCount())
|
||||
PROFILE_RANGE_EX(render_detail, "compositePointer", 0xff0077ff, (uint64_t)presentCount())
|
||||
compositePointer();
|
||||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE_EX(render, "compositeExtra", 0xff0077ff, (uint64_t)presentCount())
|
||||
PROFILE_RANGE_EX(render_detail, "compositeExtra", 0xff0077ff, (uint64_t)presentCount())
|
||||
compositeExtra();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace render {
|
|||
template <> void payloadRender(const RenderableModelEntityItemMeta::Pointer& payload, RenderArgs* args) {
|
||||
if (args) {
|
||||
if (payload && payload->entity) {
|
||||
PROFILE_RANGE(render, "MetaModelRender");
|
||||
PROFILE_RANGE(render_detail, "MetaModelRender");
|
||||
payload->entity->render(args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
|||
|
||||
_inRenderTransferPass = true;
|
||||
{ // Sync all the buffers
|
||||
PROFILE_RANGE(render_gpu_gl, "syncGPUBuffer");
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "syncGPUBuffer");
|
||||
|
||||
for (auto& cached : batch._buffers._items) {
|
||||
if (cached._data) {
|
||||
|
@ -210,7 +210,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
|||
}
|
||||
|
||||
{ // Sync all the buffers
|
||||
PROFILE_RANGE(render_gpu_gl, "syncCPUTransform");
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "syncCPUTransform");
|
||||
_transform._cameras.clear();
|
||||
_transform._cameraOffsets.clear();
|
||||
|
||||
|
@ -242,7 +242,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
|||
}
|
||||
|
||||
{ // Sync the transform buffers
|
||||
PROFILE_RANGE(render_gpu_gl, "syncGPUTransform");
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "syncGPUTransform");
|
||||
transferTransformState(batch);
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,7 @@ void GLBackend::render(const Batch& batch) {
|
|||
}
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl, "Transfer");
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "Transfer");
|
||||
renderPassTransfer(batch);
|
||||
}
|
||||
|
||||
|
@ -314,7 +314,7 @@ void GLBackend::render(const Batch& batch) {
|
|||
}
|
||||
#endif
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl, _stereo._enable ? "Render Stereo" : "Render");
|
||||
PROFILE_RANGE(render_gpu_gl_detail, _stereo._enable ? "Render Stereo" : "Render");
|
||||
renderPassDraw(batch);
|
||||
}
|
||||
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
||||
|
@ -387,18 +387,22 @@ void GLBackend::resetStages() {
|
|||
|
||||
|
||||
void GLBackend::do_pushProfileRange(const Batch& batch, size_t paramOffset) {
|
||||
auto name = batch._profileRanges.get(batch._params[paramOffset]._uint);
|
||||
profileRanges.push_back(name);
|
||||
if (trace_render_gpu_gl_detail().isDebugEnabled()) {
|
||||
auto name = batch._profileRanges.get(batch._params[paramOffset]._uint);
|
||||
profileRanges.push_back(name);
|
||||
#if defined(NSIGHT_FOUND)
|
||||
nvtxRangePush(name.c_str());
|
||||
nvtxRangePush(name.c_str());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::do_popProfileRange(const Batch& batch, size_t paramOffset) {
|
||||
profileRanges.pop_back();
|
||||
if (trace_render_gpu_gl_detail().isDebugEnabled()) {
|
||||
profileRanges.pop_back();
|
||||
#if defined(NSIGHT_FOUND)
|
||||
nvtxRangePop();
|
||||
nvtxRangePop();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: As long as we have gl calls explicitely issued from interface
|
||||
|
|
|
@ -28,7 +28,7 @@ void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) {
|
|||
auto query = batch._queries.get(batch._params[paramOffset]._uint);
|
||||
GLQuery* glquery = syncGPUObject(*query);
|
||||
if (glquery) {
|
||||
PROFILE_RANGE_BEGIN(render_gpu_gl, glquery->_profileRangeId, query->getName().c_str(), 0xFFFF7F00);
|
||||
PROFILE_RANGE_BEGIN(render_gpu_gl_detail, glquery->_profileRangeId, query->getName().c_str(), 0xFFFF7F00);
|
||||
|
||||
++_queryStage._rangeQueryDepth;
|
||||
glGetInteger64v(GL_TIMESTAMP, (GLint64*)&glquery->_batchElapsedTime);
|
||||
|
@ -62,7 +62,7 @@ void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) {
|
|||
glGetInteger64v(GL_TIMESTAMP, &now);
|
||||
glquery->_batchElapsedTime = now - glquery->_batchElapsedTime;
|
||||
|
||||
PROFILE_RANGE_END(render_gpu_gl, glquery->_profileRangeId);
|
||||
PROFILE_RANGE_END(render_gpu_gl_detail, glquery->_profileRangeId);
|
||||
|
||||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(gpugllogging, "hifi.gpu.gl")
|
||||
Q_LOGGING_CATEGORY(trace_render_gpu_gl, "trace.render.gpu.gl")
|
||||
Q_LOGGING_CATEGORY(trace_render_gpu_gl_detail, "trace.render.gpu.gl.detail")
|
||||
|
||||
namespace gpu { namespace gl {
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
Q_DECLARE_LOGGING_CATEGORY(gpugllogging)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_render_gpu_gl)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_render_gpu_gl_detail)
|
||||
|
||||
namespace gpu { namespace gl {
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ FramePointer Context::endFrame() {
|
|||
}
|
||||
|
||||
void Context::executeBatch(Batch& batch) const {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
batch.flush();
|
||||
_backend->render(batch);
|
||||
}
|
||||
|
@ -94,6 +95,8 @@ void Context::consumeFrameUpdates(const FramePointer& frame) const {
|
|||
}
|
||||
|
||||
void Context::executeFrame(const FramePointer& frame) const {
|
||||
PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||
|
||||
// Grab the stats at the around the frame and delta to have a consistent sampling
|
||||
ContextStats beginStats;
|
||||
getStats(beginStats);
|
||||
|
|
|
@ -283,7 +283,7 @@ void Model::reset() {
|
|||
}
|
||||
|
||||
bool Model::updateGeometry() {
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
PROFILE_RANGE(render_detail, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("Model::updateGeometry");
|
||||
bool needFullUpdate = false;
|
||||
|
||||
|
@ -1114,7 +1114,7 @@ void Model::snapToRegistrationPoint() {
|
|||
}
|
||||
|
||||
void Model::simulate(float deltaTime, bool fullUpdate) {
|
||||
PROFILE_RANGE(simulation, __FUNCTION__);
|
||||
PROFILE_RANGE(simulation_detail, __FUNCTION__);
|
||||
PerformanceTimer perfTimer("Model::simulate");
|
||||
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|
||||
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
#include "MIDIEvent.h"
|
||||
|
||||
static const QString SCRIPT_EXCEPTION_FORMAT = "[UncaughtException] %1 in %2:%3";
|
||||
static const QScriptEngine::QObjectWrapOptions DEFAULT_QOBJECT_WRAP_OPTIONS =
|
||||
QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeChildObjects;
|
||||
|
||||
Q_DECLARE_METATYPE(QScriptEngine::FunctionSignature)
|
||||
int functionSignatureMetaID = qRegisterMetaType<QScriptEngine::FunctionSignature>();
|
||||
|
@ -95,7 +97,7 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine){
|
|||
}
|
||||
|
||||
QScriptValue avatarDataToScriptValue(QScriptEngine* engine, AvatarData* const &in) {
|
||||
return engine->newQObject(in);
|
||||
return engine->newQObject(in, QScriptEngine::QtOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
||||
}
|
||||
|
||||
void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
|
||||
|
@ -106,7 +108,7 @@ Q_DECLARE_METATYPE(controller::InputController*)
|
|||
//static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
||||
|
||||
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
|
||||
return engine->newQObject(in);
|
||||
return engine->newQObject(in, QScriptEngine::QtOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
||||
}
|
||||
|
||||
void inputControllerFromScriptValue(const QScriptValue &object, controller::InputController* &out) {
|
||||
|
@ -460,7 +462,8 @@ static QScriptValue scriptableResourceToScriptValue(QScriptEngine* engine, const
|
|||
|
||||
auto object = engine->newQObject(
|
||||
const_cast<ScriptableResourceRawPtr>(resource),
|
||||
QScriptEngine::ScriptOwnership);
|
||||
QScriptEngine::ScriptOwnership,
|
||||
DEFAULT_QOBJECT_WRAP_OPTIONS);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -479,7 +482,8 @@ static QScriptValue createScriptableResourcePrototype(QScriptEngine* engine) {
|
|||
state->setProperty(metaEnum.key(i), metaEnum.value(i));
|
||||
}
|
||||
|
||||
auto prototypeState = engine->newQObject(state, QScriptEngine::QtOwnership, QScriptEngine::ExcludeSlots | QScriptEngine::ExcludeSuperClassMethods);
|
||||
auto prototypeState = engine->newQObject(state, QScriptEngine::QtOwnership,
|
||||
QScriptEngine::ExcludeDeleteLater | QScriptEngine::ExcludeSlots | QScriptEngine::ExcludeSuperClassMethods);
|
||||
prototype.setProperty("State", prototypeState);
|
||||
|
||||
return prototype;
|
||||
|
@ -614,7 +618,7 @@ void ScriptEngine::registerGlobalObject(const QString& name, QObject* object) {
|
|||
|
||||
if (!globalObject().property(name).isValid()) {
|
||||
if (object) {
|
||||
QScriptValue value = newQObject(object);
|
||||
QScriptValue value = newQObject(object, QScriptEngine::QtOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
|
||||
globalObject().setProperty(name, value);
|
||||
} else {
|
||||
globalObject().setProperty(name, QScriptValue());
|
||||
|
|
|
@ -9,16 +9,21 @@
|
|||
#include "Profile.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(trace_app, "trace.app")
|
||||
Q_LOGGING_CATEGORY(trace_app_detail, "trace.app.detail")
|
||||
Q_LOGGING_CATEGORY(trace_network, "trace.network")
|
||||
Q_LOGGING_CATEGORY(trace_parse, "trace.parse")
|
||||
Q_LOGGING_CATEGORY(trace_render, "trace.render")
|
||||
Q_LOGGING_CATEGORY(trace_render_detail, "trace.render.detail")
|
||||
Q_LOGGING_CATEGORY(trace_render_gpu, "trace.render.gpu")
|
||||
Q_LOGGING_CATEGORY(trace_resource, "trace.resource")
|
||||
Q_LOGGING_CATEGORY(trace_resource_network, "trace.resource.network")
|
||||
Q_LOGGING_CATEGORY(trace_resource_parse, "trace.resource.parse")
|
||||
Q_LOGGING_CATEGORY(trace_simulation, "trace.simulation")
|
||||
Q_LOGGING_CATEGORY(trace_simulation_detail, "trace.simulation.detail")
|
||||
Q_LOGGING_CATEGORY(trace_simulation_animation, "trace.simulation.animation")
|
||||
Q_LOGGING_CATEGORY(trace_simulation_animation_detail, "trace.simulation.animation.detail")
|
||||
Q_LOGGING_CATEGORY(trace_simulation_physics, "trace.simulation.physics")
|
||||
Q_LOGGING_CATEGORY(trace_simulation_physics_detail, "trace.simulation.physics.detail")
|
||||
|
||||
#if defined(NSIGHT_FOUND)
|
||||
#include "nvToolsExt.h"
|
||||
|
|
|
@ -13,16 +13,22 @@
|
|||
#include "Trace.h"
|
||||
#include "SharedUtil.h"
|
||||
|
||||
// When profiling something that may happen many times per frame, use a xxx_detail category so that they may easily be filtered out of trace results
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_app)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_app_detail)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_network)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_render)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_render_detail)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_render_gpu)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_resource)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_resource_parse)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_resource_network)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_simulation)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_simulation_detail)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_simulation_animation)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_simulation_animation_detail)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_simulation_physics)
|
||||
Q_DECLARE_LOGGING_CATEGORY(trace_simulation_physics_detail)
|
||||
|
||||
class Duration {
|
||||
public:
|
||||
|
@ -69,6 +75,7 @@ inline void counter(const QLoggingCategory& category, const QString& name, const
|
|||
#define PROFILE_RANGE_END(category, rangeId) Duration::endRange(trace_##category(), rangeId)
|
||||
#define PROFILE_ASYNC_BEGIN(category, name, id, ...) asyncBegin(trace_##category(), name, id, ##__VA_ARGS__);
|
||||
#define PROFILE_ASYNC_END(category, name, id, ...) asyncEnd(trace_##category(), name, id, ##__VA_ARGS__);
|
||||
#define PROFILE_COUNTER_IF_CHANGED(category, name, type, value) { static type lastValue = 0; type newValue = value; if (newValue != lastValue) { counter(trace_##category(), name, { { name, newValue }}); lastValue = newValue; } }
|
||||
#define PROFILE_COUNTER(category, name, ...) counter(trace_##category(), name, ##__VA_ARGS__);
|
||||
#define PROFILE_INSTANT(category, name, ...) instant(trace_##category(), name, ##__VA_ARGS__);
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ glm::vec3 SpatiallyNestable::getVelocity() const {
|
|||
bool success;
|
||||
glm::vec3 result = getVelocity(success);
|
||||
if (!success) {
|
||||
qCDebug(shared) << "Warning -- setVelocity failed" << getID();
|
||||
qCDebug(shared) << "Warning -- getVelocity failed" << getID();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
@ -107,6 +108,12 @@ void Tracer::serialize(const QString& originalPath) {
|
|||
|
||||
QString path = originalPath;
|
||||
|
||||
// Filter for specific tokens potentially present in the path:
|
||||
auto now = QDateTime::currentDateTime();
|
||||
|
||||
path = path.replace("{DATE}", now.date().toString("yyyyMMdd"));
|
||||
path = path.replace("{TIME}", now.time().toString("HHmm"));
|
||||
|
||||
// If the filename is relative, turn it into an absolute path relative to the document directory.
|
||||
QFileInfo originalFileInfo(path);
|
||||
if (originalFileInfo.isRelative()) {
|
||||
|
|
|
@ -58,8 +58,13 @@ ExtendedOverlay.prototype.editOverlay = function (properties) { // change displa
|
|||
Overlays.editOverlay(this.activeOverlay, properties);
|
||||
};
|
||||
|
||||
function color(selected) {
|
||||
return selected ? SELECTED_COLOR : UNSELECTED_COLOR;
|
||||
function color(selected, level) {
|
||||
var base = selected ? SELECTED_COLOR : UNSELECTED_COLOR;
|
||||
function scale(component) {
|
||||
var delta = 0xFF - component;
|
||||
return component + (delta * level);
|
||||
}
|
||||
return {red: scale(base.red), green: scale(base.green), blue: scale(base.blue)};
|
||||
}
|
||||
|
||||
function textures(selected) {
|
||||
|
@ -71,7 +76,7 @@ ExtendedOverlay.prototype.select = function (selected) {
|
|||
return;
|
||||
}
|
||||
|
||||
this.editOverlay({color: color(selected)});
|
||||
this.editOverlay({color: color(selected, this.audioLevel)});
|
||||
if (this.model) {
|
||||
this.model.editOverlay({textures: textures(selected)});
|
||||
}
|
||||
|
@ -204,7 +209,7 @@ function addAvatarNode(id) {
|
|||
drawInFront: true,
|
||||
solid: true,
|
||||
alpha: 0.8,
|
||||
color: color(selected),
|
||||
color: color(selected, 0.0),
|
||||
ignoreRayIntersection: false}, selected, true);
|
||||
}
|
||||
function populateUserList() {
|
||||
|
@ -288,6 +293,7 @@ function updateOverlays() {
|
|||
|
||||
overlay.ping = pingPong;
|
||||
overlay.editOverlay({
|
||||
color: color(ExtendedOverlay.isSelected(id), overlay.audioLevel),
|
||||
position: target,
|
||||
dimensions: 0.032 * distance
|
||||
});
|
||||
|
@ -422,7 +428,7 @@ var LOUDNESS_FLOOR = 11.0;
|
|||
var LOUDNESS_SCALE = 2.8 / 5.0;
|
||||
var LOG2 = Math.log(2.0);
|
||||
var AUDIO_LEVEL_UPDATE_INTERVAL_MS = 100; // 10hz for now (change this and change the AVERAGING_RATIO too)
|
||||
var accumulatedLevels = {};
|
||||
var myData = {}; // we're not includied in ExtendedOverlay.get.
|
||||
|
||||
function getAudioLevel(id) {
|
||||
// the VU meter should work similarly to the one in AvatarInputs: log scale, exponentially averaged
|
||||
|
@ -430,13 +436,18 @@ function getAudioLevel(id) {
|
|||
// of updating (the latter for efficiency too).
|
||||
var avatar = AvatarList.getAvatar(id);
|
||||
var audioLevel = 0.0;
|
||||
var data = id ? ExtendedOverlay.get(id) : myData;
|
||||
if (!data) {
|
||||
print('no data for', id);
|
||||
return audioLevel;
|
||||
}
|
||||
|
||||
// we will do exponential moving average by taking some the last loudness and averaging
|
||||
accumulatedLevels[id] = AVERAGING_RATIO * (accumulatedLevels[id] || 0) + (1 - AVERAGING_RATIO) * (avatar.audioLoudness);
|
||||
data.accumulatedLevel = AVERAGING_RATIO * (data.accumulatedLevel || 0) + (1 - AVERAGING_RATIO) * (avatar.audioLoudness);
|
||||
|
||||
// add 1 to insure we don't go log() and hit -infinity. Math.log is
|
||||
// natural log, so to get log base 2, just divide by ln(2).
|
||||
var logLevel = Math.log(accumulatedLevels[id] + 1) / LOG2;
|
||||
var logLevel = Math.log(data.accumulatedLevel + 1) / LOG2;
|
||||
|
||||
if (logLevel <= LOUDNESS_FLOOR) {
|
||||
audioLevel = logLevel / LOUDNESS_FLOOR * LOUDNESS_SCALE;
|
||||
|
@ -446,6 +457,7 @@ function getAudioLevel(id) {
|
|||
if (audioLevel > 1.0) {
|
||||
audioLevel = 1;
|
||||
}
|
||||
data.audioLevel = audioLevel;
|
||||
return audioLevel;
|
||||
}
|
||||
|
||||
|
@ -455,7 +467,7 @@ function getAudioLevel(id) {
|
|||
Script.setInterval(function () {
|
||||
if (pal.visible) {
|
||||
var param = {};
|
||||
AvatarList.getAvatarIdentifiers().sort().forEach(function (id) {
|
||||
AvatarList.getAvatarIdentifiers().forEach(function (id) {
|
||||
var level = getAudioLevel(id);
|
||||
// qml didn't like an object with null/empty string for a key, so...
|
||||
var userId = id || 0;
|
||||
|
|
Loading…
Reference in a new issue