mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 01:04:06 +02:00
Merge branch 'master' into 21089
This commit is contained in:
commit
5eff7c9e15
45 changed files with 484 additions and 206 deletions
|
@ -175,9 +175,6 @@ AssignmentClient::~AssignmentClient() {
|
|||
|
||||
void AssignmentClient::aboutToQuit() {
|
||||
stopAssignmentClient();
|
||||
|
||||
// clear the log handler so that Qt doesn't call the destructor on LogHandler
|
||||
qInstallMessageHandler(0);
|
||||
}
|
||||
|
||||
void AssignmentClient::setUpStatusToMonitor() {
|
||||
|
|
|
@ -45,9 +45,6 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
|
|||
setApplicationName("assignment-client");
|
||||
setApplicationVersion(BuildInfo::VERSION);
|
||||
|
||||
// use the verbose message handler in Logging
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
|
||||
// parse command-line
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("High Fidelity Assignment Client");
|
||||
|
|
|
@ -126,9 +126,6 @@ void AssignmentClientMonitor::stopChildProcesses() {
|
|||
|
||||
void AssignmentClientMonitor::aboutToQuit() {
|
||||
stopChildProcesses();
|
||||
|
||||
// clear the log handler so that Qt doesn't call the destructor on LogHandler
|
||||
qInstallMessageHandler(0);
|
||||
}
|
||||
|
||||
void AssignmentClientMonitor::spawnChildClient() {
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <LogHandler.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "AssignmentClientApp.h"
|
||||
|
@ -18,10 +17,14 @@
|
|||
int main(int argc, char* argv[]) {
|
||||
disableQtBearerPoll(); // Fixes wifi ping spikes
|
||||
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
qInfo() << "Starting.";
|
||||
|
||||
AssignmentClientApp app(argc, argv);
|
||||
|
||||
int acReturn = app.exec();
|
||||
qDebug() << "assignment-client process" << app.applicationPid() << "exiting with status code" << acReturn;
|
||||
|
||||
|
||||
qInfo() << "Quitting.";
|
||||
return acReturn;
|
||||
}
|
||||
|
|
|
@ -72,13 +72,10 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
_iceServerPort(ICE_SERVER_DEFAULT_PORT)
|
||||
{
|
||||
parseCommandLine();
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
|
||||
LogUtils::init();
|
||||
Setting::init();
|
||||
|
||||
connect(this, &QCoreApplication::aboutToQuit, this, &DomainServer::aboutToQuit);
|
||||
|
||||
setOrganizationName(BuildInfo::MODIFIED_ORGANIZATION);
|
||||
setOrganizationDomain("highfidelity.io");
|
||||
setApplicationName("domain-server");
|
||||
|
@ -211,6 +208,7 @@ void DomainServer::parseCommandLine() {
|
|||
}
|
||||
|
||||
DomainServer::~DomainServer() {
|
||||
qInfo() << "Domain Server is shutting down.";
|
||||
// destroy the LimitedNodeList before the DomainServer QCoreApplication is down
|
||||
DependencyManager::destroy<LimitedNodeList>();
|
||||
}
|
||||
|
@ -223,12 +221,6 @@ void DomainServer::queuedQuit(QString quitMessage, int exitCode) {
|
|||
QCoreApplication::exit(exitCode);
|
||||
}
|
||||
|
||||
void DomainServer::aboutToQuit() {
|
||||
|
||||
// clear the log handler so that Qt doesn't call the destructor on LogHandler
|
||||
qInstallMessageHandler(0);
|
||||
}
|
||||
|
||||
void DomainServer::restart() {
|
||||
qDebug() << "domain-server is restarting.";
|
||||
|
||||
|
|
|
@ -72,8 +72,6 @@ public slots:
|
|||
void processICEServerHeartbeatACK(QSharedPointer<ReceivedMessage> message);
|
||||
|
||||
private slots:
|
||||
void aboutToQuit();
|
||||
|
||||
void setupPendingAssignmentCredits();
|
||||
void sendPendingTransactionsToServer();
|
||||
|
||||
|
@ -150,13 +148,9 @@ private:
|
|||
|
||||
bool isAuthenticatedRequest(HTTPConnection* connection, const QUrl& url);
|
||||
|
||||
void handleTokenRequestFinished();
|
||||
QNetworkReply* profileRequestGivenTokenReply(QNetworkReply* tokenReply);
|
||||
void handleProfileRequestFinished();
|
||||
Headers setupCookieHeadersFromProfileReply(QNetworkReply* profileReply);
|
||||
|
||||
void loadExistingSessionsFromSettings();
|
||||
|
||||
QJsonObject jsonForSocket(const HifiSockAddr& socket);
|
||||
QJsonObject jsonObjectForNode(const SharedNodePointer& node);
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <LogHandler.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
|
@ -29,6 +27,9 @@ int main(int argc, char* argv[]) {
|
|||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
#endif
|
||||
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
qInfo() << "Starting.";
|
||||
|
||||
int currentExitCode = 0;
|
||||
|
||||
// use a do-while to handle domain-server restart
|
||||
|
@ -37,7 +38,7 @@ int main(int argc, char* argv[]) {
|
|||
currentExitCode = domainServer.exec();
|
||||
} while (currentExitCode == DomainServer::EXIT_CODE_REBOOT);
|
||||
|
||||
|
||||
qInfo() << "Quitting.";
|
||||
return currentExitCode;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,9 @@ int main(int argc, char* argv[]) {
|
|||
#ifndef WIN32
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
#endif
|
||||
|
||||
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
qInfo() << "Starting.";
|
||||
|
||||
IceServer iceServer(argc, argv);
|
||||
return iceServer.exec();
|
||||
|
|
|
@ -189,6 +189,15 @@ Item {
|
|||
Column {
|
||||
id: octreeCol
|
||||
spacing: 4; x: 4; y: 4;
|
||||
StatText {
|
||||
text: " Frame timing:"
|
||||
}
|
||||
StatText {
|
||||
text: " Batch: " + root.batchFrameTime.toFixed(1) + " ms"
|
||||
}
|
||||
StatText {
|
||||
text: " GPU: " + root.gpuFrameTime.toFixed(1) + " ms"
|
||||
}
|
||||
StatText {
|
||||
text: "Triangles: " + root.triangles +
|
||||
" / Material Switches: " + root.materialSwitches
|
||||
|
|
|
@ -118,6 +118,9 @@ ModalWindow {
|
|||
}
|
||||
}
|
||||
|
||||
property alias keyboardOverride: root.keyboardOverride
|
||||
property alias keyboardRaised: root.keyboardRaised
|
||||
property alias punctuationMode: root.punctuationMode
|
||||
Keyboard {
|
||||
id: keyboard
|
||||
raised: keyboardEnabled && keyboardRaised
|
||||
|
|
|
@ -601,7 +601,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
qCDebug(interfaceapp) << "Home sandbox does not appear to be running....";
|
||||
if (wantsSandboxRunning) {
|
||||
QString contentPath = getRunServerPath();
|
||||
SandboxUtils::runLocalSandbox(contentPath, true, RUNNING_MARKER_FILENAME);
|
||||
bool noUpdater = SteamClient::isRunning();
|
||||
SandboxUtils::runLocalSandbox(contentPath, true, RUNNING_MARKER_FILENAME, noUpdater);
|
||||
sandboxIsRunning = true;
|
||||
}
|
||||
determinedSandboxState = true;
|
||||
|
@ -1121,9 +1122,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
setActiveEyeTracker();
|
||||
#endif
|
||||
|
||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||
applicationUpdater->checkForUpdate();
|
||||
// If launched from Steam, let it handle updates
|
||||
if (!SteamClient::isRunning()) {
|
||||
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
|
||||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||
applicationUpdater->checkForUpdate();
|
||||
}
|
||||
|
||||
// Now that menu is initialized we can sync myAvatar with it's state.
|
||||
myAvatar->updateMotionBehaviorFromMenu();
|
||||
|
@ -1240,7 +1244,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
|
||||
auto glInfo = getGLContextData();
|
||||
properties["gl_info"] = glInfo;
|
||||
properties["gpu_used_memory"] = (int)BYTES_TO_MB(gpu::Context::getUsedGPUMemory());
|
||||
properties["gpu_free_memory"] = (int)BYTES_TO_MB(gpu::Context::getFreeGPUMemory());
|
||||
properties["gpu_frame_time"] = (float)(qApp->getGPUContext()->getFrameTimerGPUAverage());
|
||||
properties["batch_frame_time"] = (float)(qApp->getGPUContext()->getFrameTimerBatchAverage());
|
||||
properties["ideal_thread_count"] = QThread::idealThreadCount();
|
||||
|
||||
auto hmdHeadPose = getHMDSensorPose();
|
||||
|
@ -1656,7 +1663,8 @@ Application::~Application() {
|
|||
|
||||
_window->deleteLater();
|
||||
|
||||
qInstallMessageHandler(nullptr); // NOTE: Do this as late as possible so we continue to get our log messages
|
||||
// Can't log to file passed this point, FileLogger about to be deleted
|
||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||
}
|
||||
|
||||
void Application::initializeGL() {
|
||||
|
@ -3380,13 +3388,31 @@ void Application::loadSettings() {
|
|||
// If there is a preferred plugin, we probably messed it up with the menu settings, so fix it.
|
||||
auto pluginManager = PluginManager::getInstance();
|
||||
auto plugins = pluginManager->getPreferredDisplayPlugins();
|
||||
for (auto plugin : plugins) {
|
||||
auto menu = Menu::getInstance();
|
||||
if (auto action = menu->getActionForOption(plugin->getName())) {
|
||||
action->setChecked(true);
|
||||
action->trigger();
|
||||
// Find and activated highest priority plugin, bail for the rest
|
||||
break;
|
||||
auto menu = Menu::getInstance();
|
||||
if (plugins.size() > 0) {
|
||||
for (auto plugin : plugins) {
|
||||
if (auto action = menu->getActionForOption(plugin->getName())) {
|
||||
action->setChecked(true);
|
||||
action->trigger();
|
||||
// Find and activated highest priority plugin, bail for the rest
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If this is our first run, and no preferred devices were set, default to
|
||||
// an HMD device if available.
|
||||
Setting::Handle<bool> firstRun { Settings::firstRun, true };
|
||||
if (firstRun.get()) {
|
||||
auto displayPlugins = pluginManager->getDisplayPlugins();
|
||||
for (auto& plugin : displayPlugins) {
|
||||
if (plugin->isHmd()) {
|
||||
if (auto action = menu->getActionForOption(plugin->getName())) {
|
||||
action->setChecked(true);
|
||||
action->trigger();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -387,21 +387,9 @@ Menu::Menu() {
|
|||
});
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#define MIN_CORES_FOR_INCREMENTAL_TEXTURES 5
|
||||
bool recommendedIncrementalTransfers = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES);
|
||||
bool recommendedSparseTextures = recommendedIncrementalTransfers;
|
||||
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT]"
|
||||
<< "\n\tidealThreadCount:" << QThread::idealThreadCount()
|
||||
<< "\n\tRECOMMENDED enableSparseTextures:" << recommendedSparseTextures
|
||||
<< "\n\tRECOMMENDED enableIncrementalTextures:" << recommendedIncrementalTransfers;
|
||||
|
||||
gpu::Texture::setEnableIncrementalTextureTransfers(recommendedIncrementalTransfers);
|
||||
gpu::Texture::setEnableSparseTextures(recommendedSparseTextures);
|
||||
|
||||
// Developer > Render > Enable Dynamic Texture Management
|
||||
// Developer > Render > Enable Sparse Textures
|
||||
{
|
||||
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableDynamicTextureManagement, 0, recommendedSparseTextures);
|
||||
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::SparseTextureManagement, 0, gpu::Texture::getEnableSparseTextures());
|
||||
connect(action, &QAction::triggered, [&](bool checked) {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] --- Enable Dynamic Texture Management menu option:" << checked;
|
||||
gpu::Texture::setEnableSparseTextures(checked);
|
||||
|
@ -410,7 +398,7 @@ Menu::Menu() {
|
|||
|
||||
// Developer > Render > Enable Incremental Texture Transfer
|
||||
{
|
||||
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableIncrementalTextureTransfer, 0, recommendedIncrementalTransfers);
|
||||
auto action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::IncrementalTextureTransfer, 0, gpu::Texture::getEnableIncrementalTextureTransfers());
|
||||
connect(action, &QAction::triggered, [&](bool checked) {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] --- Enable Incremental Texture Transfer menu option:" << checked;
|
||||
gpu::Texture::setEnableIncrementalTextureTransfers(checked);
|
||||
|
|
|
@ -97,8 +97,6 @@ namespace MenuOption {
|
|||
const QString EchoLocalAudio = "Echo Local Audio";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
const QString EnableCharacterController = "Enable avatar collisions";
|
||||
const QString EnableIncrementalTextureTransfer = "Enable Incremental Texture Transfer";
|
||||
const QString EnableDynamicTextureManagement = "Enable Dynamic Texture Management";
|
||||
const QString EnableInverseKinematics = "Enable Inverse Kinematics";
|
||||
const QString ExpandMyAvatarSimulateTiming = "Expand /myAvatar/simulation";
|
||||
const QString ExpandMyAvatarTiming = "Expand /myAvatar";
|
||||
|
@ -114,6 +112,7 @@ namespace MenuOption {
|
|||
const QString FrameTimer = "Show Timer";
|
||||
const QString FullscreenMirror = "Mirror";
|
||||
const QString Help = "Help...";
|
||||
const QString IncrementalTextureTransfer = "Enable Incremental Texture Transfer";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IndependentMode = "Independent Mode";
|
||||
const QString ActionMotorControl = "Enable Default Motor Control";
|
||||
|
@ -180,6 +179,7 @@ namespace MenuOption {
|
|||
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode";
|
||||
const QString SimulateEyeTracking = "Simulate";
|
||||
const QString SMIEyeTracking = "SMI Eye Tracking";
|
||||
const QString SparseTextureManagement = "Enable Sparse Texture Management";
|
||||
const QString Stats = "Stats";
|
||||
const QString StopAllScripts = "Stop All Scripts";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
|
|
|
@ -235,6 +235,14 @@ void Avatar::updateAvatarEntities() {
|
|||
properties.setParentID(getID());
|
||||
}
|
||||
|
||||
// NOTE: if this avatar entity is not attached to us, strip its entity script completely...
|
||||
auto attachedScript = properties.getScript();
|
||||
if (!isMyAvatar() && !attachedScript.isEmpty()) {
|
||||
qCDebug(interfaceapp) << "removing entity script from avatar attached entity:" << entityID << "old script:" << attachedScript;
|
||||
QString noScript;
|
||||
properties.setScript(noScript);
|
||||
}
|
||||
|
||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(EntityItemID(entityID));
|
||||
|
||||
if (entity) {
|
||||
|
|
|
@ -64,7 +64,12 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) {
|
|||
}
|
||||
|
||||
void SnapshotUploader::uploadFailure(QNetworkReply& reply) {
|
||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(reply.readAll()); // maybe someday include _inWorldLocation, _filename?
|
||||
QString replyString = reply.readAll();
|
||||
qDebug() << "Error " << reply.errorString() << " uploading snapshot " << _pathname << " from " << _inWorldLocation;
|
||||
if (replyString.size() == 0) {
|
||||
replyString = reply.errorString();
|
||||
}
|
||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(replyString); // maybe someday include _inWorldLocation, _filename?
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
@ -74,6 +79,12 @@ void SnapshotUploader::createStorySuccess(QNetworkReply& reply) {
|
|||
}
|
||||
|
||||
void SnapshotUploader::createStoryFailure(QNetworkReply& reply) {
|
||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(reply.readAll());
|
||||
delete this;
|
||||
}
|
||||
QString replyString = reply.readAll();
|
||||
qDebug() << "Error " << reply.errorString() << " uploading snapshot " << _pathname << " from " << _inWorldLocation;
|
||||
if (replyString.size() == 0) {
|
||||
replyString = reply.errorString();
|
||||
}
|
||||
emit DependencyManager::get<WindowScriptingInterface>()->snapshotShared(replyString);
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
|
|
@ -290,6 +290,12 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(sendingMode, sendingModeResult);
|
||||
}
|
||||
|
||||
auto gpuContext = qApp->getGPUContext();
|
||||
|
||||
// Update Frame timing (in ms)
|
||||
STAT_UPDATE(gpuFrameTime, (float)gpuContext->getFrameTimerGPUAverage());
|
||||
STAT_UPDATE(batchFrameTime, (float)gpuContext->getFrameTimerBatchAverage());
|
||||
|
||||
STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount());
|
||||
STAT_UPDATE(gpuBufferMemory, (int)BYTES_TO_MB(gpu::Context::getBufferGPUMemoryUsage()));
|
||||
STAT_UPDATE(gpuTextures, (int)gpu::Context::getTextureGPUCount());
|
||||
|
@ -302,7 +308,7 @@ void Stats::updateStats(bool force) {
|
|||
STAT_UPDATE(gpuTextureVirtualMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUVirtualMemoryUsage()));
|
||||
STAT_UPDATE(gpuTextureFramebufferMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUFramebufferMemoryUsage()));
|
||||
STAT_UPDATE(gpuTextureSparseMemory, (int)BYTES_TO_MB(gpu::Texture::getTextureGPUSparseMemoryUsage()));
|
||||
STAT_UPDATE(gpuSparseTextureEnabled, qApp->getGPUContext()->getBackend()->isTextureManagementSparseEnabled() ? 1 : 0);
|
||||
STAT_UPDATE(gpuSparseTextureEnabled, gpuContext->getBackend()->isTextureManagementSparseEnabled() ? 1 : 0);
|
||||
STAT_UPDATE(gpuFreeMemory, (int)BYTES_TO_MB(gpu::Context::getFreeGPUMemory()));
|
||||
STAT_UPDATE(rectifiedTextureCount, (int)RECTIFIED_TEXTURE_COUNT.load());
|
||||
STAT_UPDATE(decimatedTextureCount, (int)DECIMATED_TEXTURE_COUNT.load());
|
||||
|
|
|
@ -101,6 +101,8 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(int, gpuTextureSparseMemory, 0)
|
||||
STATS_PROPERTY(int, gpuSparseTextureEnabled, 0)
|
||||
STATS_PROPERTY(int, gpuFreeMemory, 0)
|
||||
STATS_PROPERTY(float, gpuFrameTime, 0)
|
||||
STATS_PROPERTY(float, batchFrameTime, 0)
|
||||
|
||||
public:
|
||||
static Stats* getInstance();
|
||||
|
@ -198,6 +200,8 @@ signals:
|
|||
void gpuTextureSparseMemoryChanged();
|
||||
void gpuSparseTextureEnabledChanged();
|
||||
void gpuFreeMemoryChanged();
|
||||
void gpuFrameTimeChanged();
|
||||
void batchFrameTimeChanged();
|
||||
void rectifiedTextureCountChanged();
|
||||
void decimatedTextureCountChanged();
|
||||
|
||||
|
|
|
@ -228,9 +228,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define DUMP_FBX_JOINTS
|
||||
void AnimSkeleton::dump() const {
|
||||
void AnimSkeleton::dump(bool verbose) const {
|
||||
qCDebug(animation) << "[";
|
||||
for (int i = 0; i < getNumJoints(); i++) {
|
||||
qCDebug(animation) << " {";
|
||||
|
@ -240,24 +238,24 @@ void AnimSkeleton::dump() const {
|
|||
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
|
||||
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
|
||||
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
|
||||
#ifdef DUMP_FBX_JOINTS
|
||||
qCDebug(animation) << " fbxJoint =";
|
||||
qCDebug(animation) << " isFree =" << _joints[i].isFree;
|
||||
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
|
||||
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;
|
||||
qCDebug(animation) << " translation =" << _joints[i].translation;
|
||||
qCDebug(animation) << " preTransform =" << _joints[i].preTransform;
|
||||
qCDebug(animation) << " preRotation =" << _joints[i].preRotation;
|
||||
qCDebug(animation) << " rotation =" << _joints[i].rotation;
|
||||
qCDebug(animation) << " postRotation =" << _joints[i].postRotation;
|
||||
qCDebug(animation) << " postTransform =" << _joints[i].postTransform;
|
||||
qCDebug(animation) << " transform =" << _joints[i].transform;
|
||||
qCDebug(animation) << " rotationMin =" << _joints[i].rotationMin << ", rotationMax =" << _joints[i].rotationMax;
|
||||
qCDebug(animation) << " inverseDefaultRotation" << _joints[i].inverseDefaultRotation;
|
||||
qCDebug(animation) << " inverseBindRotation" << _joints[i].inverseBindRotation;
|
||||
qCDebug(animation) << " bindTransform" << _joints[i].bindTransform;
|
||||
qCDebug(animation) << " isSkeletonJoint" << _joints[i].isSkeletonJoint;
|
||||
#endif
|
||||
if (verbose) {
|
||||
qCDebug(animation) << " fbxJoint =";
|
||||
qCDebug(animation) << " isFree =" << _joints[i].isFree;
|
||||
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
|
||||
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;
|
||||
qCDebug(animation) << " translation =" << _joints[i].translation;
|
||||
qCDebug(animation) << " preTransform =" << _joints[i].preTransform;
|
||||
qCDebug(animation) << " preRotation =" << _joints[i].preRotation;
|
||||
qCDebug(animation) << " rotation =" << _joints[i].rotation;
|
||||
qCDebug(animation) << " postRotation =" << _joints[i].postRotation;
|
||||
qCDebug(animation) << " postTransform =" << _joints[i].postTransform;
|
||||
qCDebug(animation) << " transform =" << _joints[i].transform;
|
||||
qCDebug(animation) << " rotationMin =" << _joints[i].rotationMin << ", rotationMax =" << _joints[i].rotationMax;
|
||||
qCDebug(animation) << " inverseDefaultRotation" << _joints[i].inverseDefaultRotation;
|
||||
qCDebug(animation) << " inverseBindRotation" << _joints[i].inverseBindRotation;
|
||||
qCDebug(animation) << " bindTransform" << _joints[i].bindTransform;
|
||||
qCDebug(animation) << " isSkeletonJoint" << _joints[i].isSkeletonJoint;
|
||||
}
|
||||
if (getParentIndex(i) >= 0) {
|
||||
qCDebug(animation) << " parent =" << getJointName(getParentIndex(i));
|
||||
}
|
||||
|
@ -284,4 +282,4 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const {
|
|||
}
|
||||
qCDebug(animation) << "]";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -63,10 +63,8 @@ public:
|
|||
void mirrorRelativePoses(AnimPoseVec& poses) const;
|
||||
void mirrorAbsolutePoses(AnimPoseVec& poses) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump() const;
|
||||
void dump(bool verbose) const;
|
||||
void dump(const AnimPoseVec& poses) const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints);
|
||||
|
|
|
@ -177,7 +177,6 @@ public:
|
|||
virtual void queueLambda(const std::function<void()> lambda) const;
|
||||
|
||||
bool isTextureManagementSparseEnabled() const override { return (_textureManagement._sparseCapable && Texture::getEnableSparseTextures()); }
|
||||
bool isTextureManagementIncrementalTransferEnabled() const override { return (_textureManagement._incrementalTransferCapable && Texture::getEnableIncrementalTextureTransfers()); }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -369,7 +368,6 @@ protected:
|
|||
|
||||
struct TextureManagementStageState {
|
||||
bool _sparseCapable { false };
|
||||
bool _incrementalTransferCapable { false };
|
||||
} _textureManagement;
|
||||
virtual void initTextureManagementStage() {}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ float GLTexture::getMemoryPressure() {
|
|||
}
|
||||
|
||||
// Return the consumed texture memory divided by the available texture memory.
|
||||
auto consumedGpuMemory = Context::getTextureGPUSparseMemoryUsage();
|
||||
auto consumedGpuMemory = Context::getTextureGPUMemoryUsage() - Context::getTextureGPUFramebufferMemoryUsage();
|
||||
float memoryPressure = (float)consumedGpuMemory / (float)availableTextureMemory;
|
||||
static Context::Size lastConsumedGpuMemory = 0;
|
||||
if (memoryPressure > 1.0f && lastConsumedGpuMemory != consumedGpuMemory) {
|
||||
|
|
|
@ -94,6 +94,7 @@ public:
|
|||
TransferState _transferState;
|
||||
uint32_t _allocatedPages { 0 };
|
||||
uint32_t _lastMipAllocatedPages { 0 };
|
||||
uint16_t _mipOffset { 0 };
|
||||
friend class GL45Backend;
|
||||
};
|
||||
|
||||
|
|
|
@ -148,13 +148,9 @@ uint32_t SparseInfo::getPageCount(const uvec3& dimensions) const {
|
|||
return pageCounts.x * pageCounts.y * pageCounts.z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GL45Backend::initTextureManagementStage() {
|
||||
|
||||
// enable the Sparse Texture on gl45
|
||||
_textureManagement._sparseCapable = true;
|
||||
_textureManagement._incrementalTransferCapable = true;
|
||||
|
||||
// But now let s refine the behavior based on vendor
|
||||
std::string vendor { (const char*)glGetString(GL_VENDOR) };
|
||||
|
@ -282,20 +278,22 @@ GL45Texture::~GL45Texture() {
|
|||
if (!_gpuObject.getUsage().isExternal()) {
|
||||
qCDebug(gpugl45logging) << "Destroying texture " << _id << " from source " << _source.c_str();
|
||||
}
|
||||
if (_sparseInfo.sparse) {
|
||||
Backend::decrementTextureGPUSparseCount();
|
||||
// Remove this texture from the candidate list of derezzable textures
|
||||
{
|
||||
auto mipLevels = usedMipLevels();
|
||||
Lock lock(texturesByMipCountsMutex);
|
||||
if (texturesByMipCounts.count(mipLevels)) {
|
||||
auto& textures = texturesByMipCounts[mipLevels];
|
||||
textures.erase(this);
|
||||
if (textures.empty()) {
|
||||
texturesByMipCounts.erase(mipLevels);
|
||||
}
|
||||
|
||||
// Remove this texture from the candidate list of derezzable textures
|
||||
if (_transferrable) {
|
||||
auto mipLevels = usedMipLevels();
|
||||
Lock lock(texturesByMipCountsMutex);
|
||||
if (texturesByMipCounts.count(mipLevels)) {
|
||||
auto& textures = texturesByMipCounts[mipLevels];
|
||||
textures.erase(this);
|
||||
if (textures.empty()) {
|
||||
texturesByMipCounts.erase(mipLevels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_sparseInfo.sparse) {
|
||||
Backend::decrementTextureGPUSparseCount();
|
||||
|
||||
// Experimenation suggests that allocating sparse textures on one context/thread and deallocating
|
||||
// them on another is buggy. So for sparse textures we need to queue a lambda with the deallocation
|
||||
|
@ -355,7 +353,7 @@ void GL45Texture::allocateStorage() const {
|
|||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip);
|
||||
// Get the dimensions, accounting for the downgrade level
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(_minMip);
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(_minMip + _mipOffset);
|
||||
glTextureStorage2D(_id, usedMipLevels(), _internalFormat, dimensions.x, dimensions.y);
|
||||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
|
@ -370,7 +368,7 @@ void GL45Texture::updateSize() const {
|
|||
Backend::updateTextureGPUSparseMemoryUsage(_size, size);
|
||||
setSize(_allocatedPages * _sparseInfo.pageBytes);
|
||||
} else {
|
||||
setSize(_virtualSize);
|
||||
setSize(_gpuObject.evalTotalSize(_mipOffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,15 +379,18 @@ void GL45Texture::startTransfer() {
|
|||
}
|
||||
|
||||
bool GL45Texture::continueTransfer() {
|
||||
auto backend = _backend.lock();
|
||||
if (!backend || !backend->isTextureManagementIncrementalTransferEnabled()) {
|
||||
if (!Texture::getEnableIncrementalTextureTransfers()) {
|
||||
size_t maxFace = GL_TEXTURE_CUBE_MAP == _target ? CUBE_NUM_FACES : 1;
|
||||
for (uint8_t face = 0; face < maxFace; ++face) {
|
||||
for (uint16_t mipLevel = _minMip; mipLevel <= _maxMip; ++mipLevel) {
|
||||
auto size = _gpuObject.evalMipDimensions(mipLevel);
|
||||
if (_sparseInfo.sparse && mipLevel <= _sparseInfo.maxSparseLevel) {
|
||||
glTexturePageCommitmentEXT(_id, mipLevel, 0, 0, face, size.x, size.y, 1, GL_TRUE);
|
||||
_allocatedPages += _sparseInfo.getPageCount(size);
|
||||
}
|
||||
if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) {
|
||||
auto mip = _gpuObject.accessStoredMipFace(mipLevel, face);
|
||||
GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat());
|
||||
auto size = _gpuObject.evalMipDimensions(mipLevel);
|
||||
if (GL_TEXTURE_2D == _target) {
|
||||
glTextureSubImage2D(_id, mipLevel, 0, 0, size.x, size.y, texelFormat.format, texelFormat.type, mip->readData());
|
||||
} else if (GL_TEXTURE_CUBE_MAP == _target) {
|
||||
|
@ -481,35 +482,30 @@ void GL45Texture::syncSampler() const {
|
|||
glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]);
|
||||
glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]);
|
||||
glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor());
|
||||
// FIXME account for mip offsets here
|
||||
auto baseMip = std::max<uint16_t>(sampler.getMipOffset(), _minMip);
|
||||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, baseMip);
|
||||
glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip());
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip() - _mipOffset));
|
||||
glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
||||
}
|
||||
|
||||
void GL45Texture::postTransfer() {
|
||||
Parent::postTransfer();
|
||||
if (_sparseInfo.sparse) {
|
||||
auto mipLevels = usedMipLevels();
|
||||
if (mipLevels > 1 && _minMip < _sparseInfo.maxSparseLevel) {
|
||||
Lock lock(texturesByMipCountsMutex);
|
||||
texturesByMipCounts[mipLevels].insert(this);
|
||||
}
|
||||
auto mipLevels = usedMipLevels();
|
||||
if (_transferrable && mipLevels > 1 && _minMip < _sparseInfo.maxSparseLevel) {
|
||||
Lock lock(texturesByMipCountsMutex);
|
||||
texturesByMipCounts[mipLevels].insert(this);
|
||||
}
|
||||
}
|
||||
|
||||
void GL45Texture::stripToMip(uint16_t newMinMip) {
|
||||
if (!_sparseInfo.sparse) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newMinMip < _minMip) {
|
||||
qCWarning(gpugl45logging) << "Cannot decrease the min mip";
|
||||
return;
|
||||
}
|
||||
|
||||
if (newMinMip > _sparseInfo.maxSparseLevel) {
|
||||
if (_sparseInfo.sparse && newMinMip > _sparseInfo.maxSparseLevel) {
|
||||
qCWarning(gpugl45logging) << "Cannot increase the min mip into the mip tail";
|
||||
return;
|
||||
}
|
||||
|
@ -533,19 +529,53 @@ void GL45Texture::stripToMip(uint16_t newMinMip) {
|
|||
|
||||
|
||||
uint8_t maxFace = (uint8_t)((_target == GL_TEXTURE_CUBE_MAP) ? GLTexture::CUBE_NUM_FACES : 1);
|
||||
for (uint16_t mip = _minMip; mip < newMinMip; ++mip) {
|
||||
auto id = _id;
|
||||
auto mipDimensions = _gpuObject.evalMipDimensions(mip);
|
||||
_textureTransferHelper->queueExecution([id, mip, mipDimensions, maxFace] {
|
||||
glTexturePageCommitmentEXT(id, mip, 0, 0, 0, mipDimensions.x, mipDimensions.y, maxFace, GL_FALSE);
|
||||
});
|
||||
if (_sparseInfo.sparse) {
|
||||
for (uint16_t mip = _minMip; mip < newMinMip; ++mip) {
|
||||
auto id = _id;
|
||||
auto mipDimensions = _gpuObject.evalMipDimensions(mip);
|
||||
_textureTransferHelper->queueExecution([id, mip, mipDimensions, maxFace] {
|
||||
glTexturePageCommitmentEXT(id, mip, 0, 0, 0, mipDimensions.x, mipDimensions.y, maxFace, GL_FALSE);
|
||||
});
|
||||
|
||||
auto deallocatedPages = _sparseInfo.getPageCount(mipDimensions) * maxFace;
|
||||
assert(deallocatedPages < _allocatedPages);
|
||||
_allocatedPages -= deallocatedPages;
|
||||
auto deallocatedPages = _sparseInfo.getPageCount(mipDimensions) * maxFace;
|
||||
assert(deallocatedPages < _allocatedPages);
|
||||
_allocatedPages -= deallocatedPages;
|
||||
}
|
||||
_minMip = newMinMip;
|
||||
} else {
|
||||
GLuint oldId = _id;
|
||||
// Find the distance between the old min mip and the new one
|
||||
uint16 mipDelta = newMinMip - _minMip;
|
||||
_mipOffset += mipDelta;
|
||||
const_cast<uint16&>(_maxMip) -= mipDelta;
|
||||
auto newLevels = usedMipLevels();
|
||||
|
||||
// Create and setup the new texture (allocate)
|
||||
glCreateTextures(_target, 1, &const_cast<GLuint&>(_id));
|
||||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, _maxMip - _minMip);
|
||||
Vec3u newDimensions = _gpuObject.evalMipDimensions(_mipOffset);
|
||||
glTextureStorage2D(_id, newLevels, _internalFormat, newDimensions.x, newDimensions.y);
|
||||
|
||||
// Copy the contents of the old texture to the new
|
||||
GLuint fbo { 0 };
|
||||
glCreateFramebuffers(1, &fbo);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
for (uint16 targetMip = _minMip; targetMip <= _maxMip; ++targetMip) {
|
||||
uint16 sourceMip = targetMip + mipDelta;
|
||||
Vec3u mipDimensions = _gpuObject.evalMipDimensions(targetMip + _mipOffset);
|
||||
for (GLenum target : getFaceTargets(_target)) {
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, oldId, sourceMip);
|
||||
(void)CHECK_GL_ERROR();
|
||||
glCopyTextureSubImage2D(_id, targetMip, 0, 0, 0, 0, mipDimensions.x, mipDimensions.y);
|
||||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
}
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, &fbo);
|
||||
glDeleteTextures(1, &oldId);
|
||||
}
|
||||
|
||||
_minMip = newMinMip;
|
||||
// Re-sync the sampler to force access to the new mip level
|
||||
syncSampler();
|
||||
updateSize();
|
||||
|
@ -553,7 +583,7 @@ void GL45Texture::stripToMip(uint16_t newMinMip) {
|
|||
|
||||
// Re-insert into the texture-by-mips map if appropriate
|
||||
mipLevels = usedMipLevels();
|
||||
if (_sparseInfo.sparse && mipLevels > 1 && _minMip < _sparseInfo.maxSparseLevel) {
|
||||
if (mipLevels > 1 && (!_sparseInfo.sparse || _minMip < _sparseInfo.maxSparseLevel)) {
|
||||
Lock lock(texturesByMipCountsMutex);
|
||||
texturesByMipCounts[mipLevels].insert(this);
|
||||
}
|
||||
|
@ -570,8 +600,9 @@ void GL45Texture::updateMips() {
|
|||
}
|
||||
|
||||
void GL45Texture::derez() {
|
||||
assert(_sparseInfo.sparse);
|
||||
assert(_minMip < _sparseInfo.maxSparseLevel);
|
||||
if (_sparseInfo.sparse) {
|
||||
assert(_minMip < _sparseInfo.maxSparseLevel);
|
||||
}
|
||||
assert(_minMip < _maxMip);
|
||||
assert(_transferrable);
|
||||
stripToMip(_minMip + 1);
|
||||
|
@ -595,7 +626,7 @@ void GL45Backend::derezTextures() const {
|
|||
}
|
||||
|
||||
qCDebug(gpugl45logging) << "Allowed texture memory " << Texture::getAllowedGPUMemoryUsage();
|
||||
qCDebug(gpugl45logging) << "Used texture memory " << Context::getTextureGPUMemoryUsage();
|
||||
qCDebug(gpugl45logging) << "Used texture memory " << (Context::getTextureGPUMemoryUsage() - Context::getTextureGPUFramebufferMemoryUsage());
|
||||
|
||||
GL45Texture* targetTexture = nullptr;
|
||||
{
|
||||
|
@ -605,5 +636,5 @@ void GL45Backend::derezTextures() const {
|
|||
}
|
||||
lock.unlock();
|
||||
targetTexture->derez();
|
||||
qCDebug(gpugl45logging) << "New Used texture memory " << Context::getTextureGPUMemoryUsage();
|
||||
qCDebug(gpugl45logging) << "New Used texture memory " << (Context::getTextureGPUMemoryUsage() - Context::getTextureGPUFramebufferMemoryUsage());
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ void Context::beginFrame(const glm::mat4& renderPose) {
|
|||
_frameActive = true;
|
||||
_currentFrame = std::make_shared<Frame>();
|
||||
_currentFrame->pose = renderPose;
|
||||
|
||||
if (!_frameRangeTimer) {
|
||||
_frameRangeTimer = std::make_shared<RangeTimer>();
|
||||
}
|
||||
}
|
||||
|
||||
void Context::appendFrameBatch(Batch& batch) {
|
||||
|
@ -73,10 +77,18 @@ void Context::executeFrame(const FramePointer& frame) const {
|
|||
consumeFrameUpdates(frame);
|
||||
_backend->setStereoState(frame->stereoState);
|
||||
{
|
||||
Batch beginBatch;
|
||||
_frameRangeTimer->begin(beginBatch);
|
||||
_backend->render(beginBatch);
|
||||
|
||||
// Execute the frame rendering commands
|
||||
for (auto& batch : frame->batches) {
|
||||
_backend->render(batch);
|
||||
}
|
||||
|
||||
Batch endBatch;
|
||||
_frameRangeTimer->end(endBatch);
|
||||
_backend->render(endBatch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +139,20 @@ void Context::getStats(ContextStats& stats) const {
|
|||
_backend->getStats(stats);
|
||||
}
|
||||
|
||||
double Context::getFrameTimerGPUAverage() const {
|
||||
if (_frameRangeTimer) {
|
||||
return _frameRangeTimer->getGPUAverage();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double Context::getFrameTimerBatchAverage() const {
|
||||
if (_frameRangeTimer) {
|
||||
return _frameRangeTimer->getBatchAverage();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const Backend::TransformCamera& Backend::TransformCamera::recomputeDerived(const Transform& xformView) const {
|
||||
_projectionInverse = glm::inverse(_projection);
|
||||
|
||||
|
@ -183,6 +209,10 @@ Size Context::getFreeGPUMemory() {
|
|||
return _freeGPUMemory.load();
|
||||
}
|
||||
|
||||
Size Context::getUsedGPUMemory() {
|
||||
return getTextureGPUMemoryUsage() + getBufferGPUMemoryUsage();
|
||||
};
|
||||
|
||||
void Context::incrementBufferGPUCount() {
|
||||
static std::atomic<uint32_t> max { 0 };
|
||||
auto total = ++_bufferGPUCount;
|
||||
|
@ -349,3 +379,5 @@ void Backend::updateTextureGPUFramebufferMemoryUsage(Resource::Size prevObjectSi
|
|||
void Backend::updateTextureGPUSparseMemoryUsage(Resource::Size prevObjectSize, Resource::Size newObjectSize) { Context::updateTextureGPUSparseMemoryUsage(prevObjectSize, newObjectSize); }
|
||||
void Backend::incrementTextureGPUTransferCount() { Context::incrementTextureGPUTransferCount(); }
|
||||
void Backend::decrementTextureGPUTransferCount() { Context::decrementTextureGPUTransferCount(); }
|
||||
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ public:
|
|||
void getStats(ContextStats& stats) const { stats = _stats; }
|
||||
|
||||
virtual bool isTextureManagementSparseEnabled() const = 0;
|
||||
virtual bool isTextureManagementIncrementalTransferEnabled() const = 0;
|
||||
|
||||
// These should only be accessed by Backend implementation to repport the buffer and texture allocations,
|
||||
// they are NOT public calls
|
||||
|
@ -205,12 +204,16 @@ public:
|
|||
void getStats(ContextStats& stats) const;
|
||||
|
||||
|
||||
double getFrameTimerGPUAverage() const;
|
||||
double getFrameTimerBatchAverage() const;
|
||||
|
||||
static uint32_t getBufferGPUCount();
|
||||
static Size getBufferGPUMemoryUsage();
|
||||
|
||||
static uint32_t getTextureGPUCount();
|
||||
static uint32_t getTextureGPUSparseCount();
|
||||
static Size getFreeGPUMemory();
|
||||
static Size getUsedGPUMemory();
|
||||
static Size getTextureGPUMemoryUsage();
|
||||
static Size getTextureGPUVirtualMemoryUsage();
|
||||
static Size getTextureGPUFramebufferMemoryUsage();
|
||||
|
@ -223,8 +226,12 @@ protected:
|
|||
std::shared_ptr<Backend> _backend;
|
||||
bool _frameActive { false };
|
||||
FramePointer _currentFrame;
|
||||
RangeTimerPointer _frameRangeTimer;
|
||||
StereoState _stereo;
|
||||
|
||||
double getGPUAverage() const;
|
||||
double getBatchAverage() const;
|
||||
|
||||
// This function can only be called by "static Shader::makeProgram()"
|
||||
// makeProgramShader(...) make a program shader ready to be used in a Batch.
|
||||
// It compiles the sub shaders, link them and defines the Slots and their bindings.
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
//
|
||||
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "Texture.h"
|
||||
|
||||
#include <glm/gtc/constants.hpp>
|
||||
#include <glm/gtx/component_wise.hpp>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
|
@ -31,16 +33,27 @@ std::atomic<uint32_t> Texture::_textureCPUCount{ 0 };
|
|||
std::atomic<Texture::Size> Texture::_textureCPUMemoryUsage{ 0 };
|
||||
std::atomic<Texture::Size> Texture::_allowedCPUMemoryUsage { 0 };
|
||||
|
||||
std::atomic<bool> Texture::_enableSparseTextures { false };
|
||||
std::atomic<bool> Texture::_enableIncrementalTextureTransfers { false };
|
||||
|
||||
#define MIN_CORES_FOR_INCREMENTAL_TEXTURES 5
|
||||
bool recommendedIncrementalTransfers = (QThread::idealThreadCount() >= MIN_CORES_FOR_INCREMENTAL_TEXTURES);
|
||||
bool recommendedSparseTextures = recommendedIncrementalTransfers;
|
||||
|
||||
std::atomic<bool> Texture::_enableSparseTextures { recommendedIncrementalTransfers };
|
||||
std::atomic<bool> Texture::_enableIncrementalTextureTransfers { recommendedSparseTextures };
|
||||
|
||||
struct ReportTextureState {
|
||||
ReportTextureState() {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT]"
|
||||
<< "\n\tidealThreadCount:" << QThread::idealThreadCount()
|
||||
<< "\n\tRECOMMENDED enableSparseTextures:" << recommendedSparseTextures
|
||||
<< "\n\tRECOMMENDED enableIncrementalTextures:" << recommendedIncrementalTransfers;
|
||||
}
|
||||
} report;
|
||||
|
||||
void Texture::setEnableSparseTextures(bool enabled) {
|
||||
#ifdef Q_OS_WIN
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] SETTING - Enable Sparse Textures and Dynamic Texture Management:" << enabled;
|
||||
_enableSparseTextures = enabled;
|
||||
if (!_enableIncrementalTextureTransfers && _enableSparseTextures) {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] WARNING - Sparse texture management requires incremental texture transfer enabled.";
|
||||
}
|
||||
#else
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] Sparse Textures and Dynamic Texture Management not supported on this platform.";
|
||||
#endif
|
||||
|
@ -50,9 +63,6 @@ void Texture::setEnableIncrementalTextureTransfers(bool enabled) {
|
|||
#ifdef Q_OS_WIN
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] SETTING - Enable Incremental Texture Transfer:" << enabled;
|
||||
_enableIncrementalTextureTransfers = enabled;
|
||||
if (!_enableIncrementalTextureTransfers && _enableSparseTextures) {
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] WARNING - Sparse texture management requires incremental texture transfer enabled.";
|
||||
}
|
||||
#else
|
||||
qDebug() << "[TEXTURE TRANSFER SUPPORT] Incremental Texture Transfer not supported on this platform.";
|
||||
#endif
|
||||
|
@ -418,12 +428,18 @@ uint16 Texture::evalDimNumMips(uint16 size) {
|
|||
return 1 + (uint16) val;
|
||||
}
|
||||
|
||||
static const double LOG_2 = log(2.0);
|
||||
|
||||
uint16 Texture::evalNumMips(const Vec3u& dimensions) {
|
||||
double largerDim = glm::compMax(dimensions);
|
||||
double val = log(largerDim) / LOG_2;
|
||||
return 1 + (uint16)val;
|
||||
}
|
||||
|
||||
// The number mips that the texture could have if all existed
|
||||
// = log2(max(width, height, depth))
|
||||
uint16 Texture::evalNumMips() const {
|
||||
double largerDim = std::max(std::max(_width, _height), _depth);
|
||||
double val = log(largerDim)/log(2.0);
|
||||
return 1 + (uint16) val;
|
||||
return evalNumMips({ _width, _height, _depth });
|
||||
}
|
||||
|
||||
bool Texture::assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes) {
|
||||
|
|
|
@ -369,9 +369,12 @@ public:
|
|||
// = 1 + log2(max(width, height, depth))
|
||||
uint16 evalNumMips() const;
|
||||
|
||||
static uint16 evalNumMips(const Vec3u& dimensions);
|
||||
|
||||
// Eval the size that the mips level SHOULD have
|
||||
// not the one stored in the Texture
|
||||
static const uint MIN_DIMENSION = 1;
|
||||
|
||||
Vec3u evalMipDimensions(uint16 level) const;
|
||||
uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); }
|
||||
uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); }
|
||||
|
@ -388,9 +391,9 @@ public:
|
|||
uint32 evalStoredMipFaceSize(uint16 level, const Element& format) const { return evalMipFaceNumTexels(level) * format.getSize(); }
|
||||
uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); }
|
||||
|
||||
uint32 evalTotalSize() const {
|
||||
uint32 evalTotalSize(uint16 startingMip = 0) const {
|
||||
uint32 size = 0;
|
||||
uint16 minMipLevel = minMip();
|
||||
uint16 minMipLevel = std::max(minMip(), startingMip);
|
||||
uint16 maxMipLevel = maxMip();
|
||||
for (uint16 l = minMipLevel; l <= maxMipLevel; l++) {
|
||||
size += evalMipSize(l);
|
||||
|
|
|
@ -61,15 +61,16 @@ void SandboxUtils::ifLocalSandboxRunningElse(std::function<void()> localSandboxR
|
|||
}
|
||||
|
||||
|
||||
void SandboxUtils::runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName) {
|
||||
void SandboxUtils::runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName, bool noUpdater) {
|
||||
QString applicationDirPath = QFileInfo(QCoreApplication::applicationFilePath()).path();
|
||||
QString serverPath = applicationDirPath + "/server-console/server-console.exe";
|
||||
qDebug() << "Application dir path is: " << applicationDirPath;
|
||||
qDebug() << "Server path is: " << serverPath;
|
||||
qDebug() << "autoShutdown: " << autoShutdown;
|
||||
qDebug() << "noUpdater: " << noUpdater;
|
||||
|
||||
bool hasContentPath = !contentPath.isEmpty();
|
||||
bool passArgs = autoShutdown || hasContentPath;
|
||||
bool passArgs = autoShutdown || hasContentPath || noUpdater;
|
||||
|
||||
QStringList args;
|
||||
|
||||
|
@ -87,6 +88,10 @@ void SandboxUtils::runLocalSandbox(QString contentPath, bool autoShutdown, QStri
|
|||
args << "--shutdownWatcher" << interfaceRunningStateFile;
|
||||
}
|
||||
|
||||
if (noUpdater) {
|
||||
args << "--noUpdater";
|
||||
}
|
||||
|
||||
qDebug() << applicationDirPath;
|
||||
qDebug() << "Launching sandbox with:" << args;
|
||||
qDebug() << QProcess::startDetached(serverPath, args);
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
void ifLocalSandboxRunningElse(std::function<void()> localSandboxRunningDoThis,
|
||||
std::function<void()> localSandboxNotRunningDoThat);
|
||||
|
||||
static void runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName);
|
||||
static void runLocalSandbox(QString contentPath, bool autoShutdown, QString runningMarkerName, bool noUpdater);
|
||||
};
|
||||
|
||||
#endif // hifi_SandboxUtils_h
|
||||
|
|
|
@ -10,17 +10,18 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
#include <QMutexLocker>
|
||||
#include <QRegExp>
|
||||
|
||||
#include "LogHandler.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
QMutex LogHandler::_mutex;
|
||||
|
||||
LogHandler& LogHandler::getInstance() {
|
||||
|
@ -28,16 +29,15 @@ LogHandler& LogHandler::getInstance() {
|
|||
return staticInstance;
|
||||
}
|
||||
|
||||
LogHandler::LogHandler()
|
||||
{
|
||||
// setup our timer to flush the verbose logs every 5 seconds
|
||||
QTimer* logFlushTimer = new QTimer(this);
|
||||
connect(logFlushTimer, &QTimer::timeout, this, &LogHandler::flushRepeatedMessages);
|
||||
logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000);
|
||||
|
||||
LogHandler::LogHandler() {
|
||||
// when the log handler is first setup we should print our timezone
|
||||
QString timezoneString = "Time zone: " + QDateTime::currentDateTime().toString("t");
|
||||
printf("%s\n", qPrintable(timezoneString));
|
||||
printMessage(LogMsgType::LogInfo, QMessageLogContext(), timezoneString);
|
||||
}
|
||||
|
||||
LogHandler::~LogHandler() {
|
||||
flushRepeatedMessages();
|
||||
printMessage(LogMsgType::LogDebug, QMessageLogContext(), "LogHandler shutdown.");
|
||||
}
|
||||
|
||||
const char* stringForLogType(LogMsgType msgType) {
|
||||
|
@ -165,7 +165,7 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont
|
|||
stringForLogType(type), context.category);
|
||||
|
||||
if (_shouldOutputProcessID) {
|
||||
prefixString.append(QString(" [%1]").arg(QCoreApplication::instance()->applicationPid()));
|
||||
prefixString.append(QString(" [%1]").arg(QCoreApplication::applicationPid()));
|
||||
}
|
||||
|
||||
if (_shouldOutputThreadID) {
|
||||
|
@ -187,6 +187,14 @@ void LogHandler::verboseMessageHandler(QtMsgType type, const QMessageLogContext&
|
|||
}
|
||||
|
||||
const QString& LogHandler::addRepeatedMessageRegex(const QString& regexString) {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
// setup our timer to flush the verbose logs every 5 seconds
|
||||
QTimer* logFlushTimer = new QTimer(this);
|
||||
connect(logFlushTimer, &QTimer::timeout, this, &LogHandler::flushRepeatedMessages);
|
||||
logFlushTimer->start(VERBOSE_LOG_INTERVAL_SECONDS * 1000);
|
||||
});
|
||||
|
||||
QMutexLocker lock(&_mutex);
|
||||
return *_repeatedMessageRegexes.insert(regexString);
|
||||
}
|
||||
|
|
|
@ -52,8 +52,10 @@ public:
|
|||
|
||||
const QString& addRepeatedMessageRegex(const QString& regexString);
|
||||
const QString& addOnlyOnceMessageRegex(const QString& regexString);
|
||||
|
||||
private:
|
||||
LogHandler();
|
||||
~LogHandler();
|
||||
|
||||
void flushRepeatedMessages();
|
||||
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "ShutdownEventListener.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -19,6 +17,9 @@
|
|||
#include <csignal>
|
||||
#endif
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
ShutdownEventListener& ShutdownEventListener::getInstance() {
|
||||
static ShutdownEventListener staticInstance;
|
||||
return staticInstance;
|
||||
|
@ -29,9 +30,7 @@ void signalHandler(int param) {
|
|||
QMetaObject::invokeMethod(qApp, "quit");
|
||||
}
|
||||
|
||||
ShutdownEventListener::ShutdownEventListener(QObject* parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
ShutdownEventListener::ShutdownEventListener(QObject* parent) : QObject(parent) {
|
||||
#ifndef Q_OS_WIN
|
||||
// be a signal handler for SIGTERM so we can stop our children when we get it
|
||||
signal(SIGTERM, signalHandler);
|
||||
|
|
|
@ -109,7 +109,8 @@ bool FilePersistThread::processQueueItems(const Queue& messages) {
|
|||
}
|
||||
|
||||
FileLogger::FileLogger(QObject* parent) :
|
||||
AbstractLoggerInterface(parent), _fileName(getLogFilename())
|
||||
AbstractLoggerInterface(parent),
|
||||
_fileName(getLogFilename())
|
||||
{
|
||||
_persistThreadInstance = new FilePersistThread(*this);
|
||||
_persistThreadInstance->initialize(true, QThread::LowestPriority);
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
FileLogger(QObject* parent = NULL);
|
||||
virtual ~FileLogger();
|
||||
|
||||
QString getFilename() { return _fileName; }
|
||||
QString getFilename() const { return _fileName; }
|
||||
virtual void addMessage(const QString&) override;
|
||||
virtual QString getLogData() override;
|
||||
virtual void locateLog() override;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <QtQml>
|
||||
#include <QMenuBar>
|
||||
#include <QDebug>
|
||||
|
||||
#include "OffscreenUi.h"
|
||||
|
||||
|
@ -58,6 +59,18 @@ public:
|
|||
_qml->setProperty("visible", _action->isVisible());
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_qml->setProperty("checkable", 0);
|
||||
_qml->setProperty("enabled", 0);
|
||||
_qml->setProperty("text", 0);
|
||||
_qml->setProperty("shortcut", 0);
|
||||
_qml->setProperty("checked", 0);
|
||||
_qml->setProperty("visible", 0);
|
||||
|
||||
_action->setUserData(USER_DATA_ID, nullptr);
|
||||
_qml->setUserData(USER_DATA_ID, nullptr);
|
||||
}
|
||||
|
||||
|
||||
const QUuid uuid{ QUuid::createUuid() };
|
||||
|
||||
|
@ -217,6 +230,7 @@ void VrMenu::insertAction(QAction* before, QAction* action) {
|
|||
}
|
||||
|
||||
class QQuickMenuBase;
|
||||
class QQuickMenu1;
|
||||
|
||||
void VrMenu::removeAction(QAction* action) {
|
||||
if (!action) {
|
||||
|
@ -228,10 +242,7 @@ void VrMenu::removeAction(QAction* action) {
|
|||
qWarning("Attempted to remove menu action with no found QML object");
|
||||
return;
|
||||
}
|
||||
|
||||
QObject* item = findMenuObject(userData->uuid.toString());
|
||||
QObject* menu = item->parent();
|
||||
// Proxy QuickItem requests through the QML layer
|
||||
QQuickMenuBase* qmlItem = reinterpret_cast<QQuickMenuBase*>(item);
|
||||
QMetaObject::invokeMethod(menu, "removeItem", Qt::DirectConnection, Q_ARG(QQuickMenuBase*, qmlItem));
|
||||
|
||||
userData->clear();
|
||||
delete userData;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ void Menu::scanMenu(QMenu& menu, settingsAction modifySetting, Settings& setting
|
|||
groups.pop_back();
|
||||
}
|
||||
|
||||
void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName,
|
||||
void Menu::addDisabledActionAndSeparator(MenuWrapper* destinationMenu, const QString& actionName,
|
||||
int menuItemLocation, const QString& grouping) {
|
||||
QAction* actionBefore = NULL;
|
||||
QAction* separator;
|
||||
|
@ -123,7 +123,7 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
|
|||
const QObject* receiver,
|
||||
const char* member,
|
||||
QAction::MenuRole role,
|
||||
int menuItemLocation,
|
||||
int menuItemLocation,
|
||||
const QString& grouping) {
|
||||
QAction* action = NULL;
|
||||
QAction* actionBefore = NULL;
|
||||
|
@ -165,7 +165,7 @@ QAction* Menu::addActionToQMenuAndActionHash(MenuWrapper* destinationMenu,
|
|||
const QString& actionName,
|
||||
const QKeySequence& shortcut,
|
||||
QAction::MenuRole role,
|
||||
int menuItemLocation,
|
||||
int menuItemLocation,
|
||||
const QString& grouping) {
|
||||
QAction* actionBefore = NULL;
|
||||
|
||||
|
@ -207,7 +207,7 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(MenuWrapper* destinationMe
|
|||
const bool checked,
|
||||
const QObject* receiver,
|
||||
const char* member,
|
||||
int menuItemLocation,
|
||||
int menuItemLocation,
|
||||
const QString& grouping) {
|
||||
|
||||
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member,
|
||||
|
@ -408,6 +408,10 @@ void Menu::removeMenu(const QString& menuName) {
|
|||
parent->removeAction(action);
|
||||
} else {
|
||||
QMenuBar::removeAction(action);
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->addMenuInitializer([=](VrMenu* vrMenu) {
|
||||
vrMenu->removeAction(action);
|
||||
});
|
||||
}
|
||||
|
||||
QMenuBar::repaint();
|
||||
|
@ -496,15 +500,15 @@ void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) {
|
|||
|
||||
void Menu::addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected, QObject* receiver, const char* slot) {
|
||||
auto menu = addMenu(groupName);
|
||||
|
||||
|
||||
QActionGroup* actionGroup = new QActionGroup(menu);
|
||||
actionGroup->setExclusive(true);
|
||||
|
||||
|
||||
for (auto action : actionList) {
|
||||
auto item = addCheckableActionToQMenuAndActionHash(menu, action, 0, action == selected, receiver, slot);
|
||||
actionGroup->addAction(item);
|
||||
}
|
||||
|
||||
|
||||
QMenuBar::repaint();
|
||||
}
|
||||
|
||||
|
@ -582,4 +586,3 @@ void MenuWrapper::insertAction(QAction* before, QAction* action) {
|
|||
vrMenu->insertAction(before, action);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -445,13 +445,11 @@ function hideUserDataTextArea() {
|
|||
};
|
||||
|
||||
function showStaticUserData() {
|
||||
$('#static-userdata').show();
|
||||
$('#static-userdata').css('height', $('#userdata-editor').height())
|
||||
if (editor !== null) {
|
||||
$('#static-userdata').show();
|
||||
$('#static-userdata').css('height', $('#userdata-editor').height())
|
||||
$('#static-userdata').text(editor.getText());
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
function removeStaticUserData() {
|
||||
|
|
|
@ -579,6 +579,10 @@ function backupResourceDirectoriesAndRestart() {
|
|||
}
|
||||
|
||||
function checkNewContent() {
|
||||
if (argv.noUpdater) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start downloading content set
|
||||
var req = request.head({
|
||||
url: HOME_CONTENT_URL
|
||||
|
@ -623,6 +627,7 @@ function checkNewContent() {
|
|||
} else {
|
||||
// They don't want to update, mark content set as current
|
||||
userConfig.set('homeContentLastModified', new Date());
|
||||
userConfig.save(configPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -676,6 +681,7 @@ function maybeInstallDefaultContentSet(onComplete) {
|
|||
}
|
||||
log.debug('Copied home content over to: ' + getRootHifiDataDirectory());
|
||||
userConfig.set('homeContentLastModified', new Date());
|
||||
userConfig.save(configPath);
|
||||
onComplete();
|
||||
});
|
||||
return;
|
||||
|
@ -756,6 +762,7 @@ function maybeInstallDefaultContentSet(onComplete) {
|
|||
// response and decompression complete, return
|
||||
log.debug("Finished unarchiving home content set");
|
||||
userConfig.set('homeContentLastModified', new Date());
|
||||
userConfig.save(configPath);
|
||||
sendStateUpdate('complete');
|
||||
});
|
||||
|
||||
|
@ -766,6 +773,7 @@ function maybeInstallDefaultContentSet(onComplete) {
|
|||
});
|
||||
|
||||
userConfig.set('hasRun', true);
|
||||
userConfig.save(configPath);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -817,7 +825,7 @@ function onContentLoaded() {
|
|||
// Disable splash window for now.
|
||||
// maybeShowSplash();
|
||||
|
||||
if (buildInfo.releaseType == 'PRODUCTION') {
|
||||
if (buildInfo.releaseType == 'PRODUCTION' && !argv.noUpdater) {
|
||||
var currentVersion = null;
|
||||
try {
|
||||
currentVersion = parseInt(buildInfo.buildIdentifier);
|
||||
|
|
|
@ -599,7 +599,7 @@ protected:
|
|||
return;
|
||||
|
||||
case Qt::Key_End:
|
||||
gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(256));
|
||||
gpu::Texture::setAllowedGPUMemoryUsage(MB_TO_BYTES(64));
|
||||
return;
|
||||
|
||||
|
||||
|
|
|
@ -13,3 +13,7 @@ set_target_properties(ice-client PROPERTIES FOLDER "Tools")
|
|||
|
||||
add_subdirectory(ac-client)
|
||||
set_target_properties(ac-client PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(skeleton-dump)
|
||||
set_target_properties(skeleton-dump PROPERTIES FOLDER "Tools")
|
||||
|
||||
|
|
4
tools/skeleton-dump/CMakeLists.txt
Normal file
4
tools/skeleton-dump/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
set(TARGET_NAME skeleton-dump)
|
||||
setup_hifi_project(Core Widgets)
|
||||
link_hifi_libraries(shared fbx model gpu gl animation)
|
||||
|
63
tools/skeleton-dump/src/SkeletonDumpApp.cpp
Normal file
63
tools/skeleton-dump/src/SkeletonDumpApp.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// SkeletonDumpApp.cpp
|
||||
// tools/skeleton-dump/src
|
||||
//
|
||||
// Created by Anthony Thibault on 11/4/16.
|
||||
// Copyright 2016 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 "SkeletonDumpApp.h"
|
||||
#include <QCommandLineParser>
|
||||
#include <QFile>
|
||||
#include <FBXReader.h>
|
||||
#include <AnimSkeleton.h>
|
||||
|
||||
SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc, argv) {
|
||||
|
||||
// parse command-line
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription("High Fidelity FBX Skeleton Analyzer");
|
||||
const QCommandLineOption helpOption = parser.addHelpOption();
|
||||
|
||||
const QCommandLineOption verboseOutput("v", "verbose output");
|
||||
parser.addOption(verboseOutput);
|
||||
|
||||
const QCommandLineOption inputFilenameOption("i", "input file", "filename.fbx");
|
||||
parser.addOption(inputFilenameOption);
|
||||
|
||||
if (!parser.parse(QCoreApplication::arguments())) {
|
||||
qCritical() << parser.errorText() << endl;
|
||||
parser.showHelp();
|
||||
_returnCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (parser.isSet(helpOption)) {
|
||||
parser.showHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
bool verbose = parser.isSet(verboseOutput);
|
||||
|
||||
QString inputFilename;
|
||||
if (parser.isSet(inputFilenameOption)) {
|
||||
inputFilename = parser.value(inputFilenameOption);
|
||||
}
|
||||
|
||||
QFile file(inputFilename);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qCritical() << "Failed to open file " << inputFilename;
|
||||
_returnCode = 2;
|
||||
return;
|
||||
}
|
||||
QByteArray blob = file.readAll();
|
||||
std::unique_ptr<FBXGeometry> fbxGeometry(readFBX(blob, QVariantHash()));
|
||||
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*fbxGeometry));
|
||||
skeleton->dump(verbose);
|
||||
}
|
||||
|
||||
SkeletonDumpApp::~SkeletonDumpApp() {
|
||||
}
|
29
tools/skeleton-dump/src/SkeletonDumpApp.h
Normal file
29
tools/skeleton-dump/src/SkeletonDumpApp.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// SkeletonDumpApp.h
|
||||
// tools/skeleton-dump/src
|
||||
//
|
||||
// Created by Anthony Thibault on 11/4/16.
|
||||
// Copyright 2016 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
|
||||
//
|
||||
|
||||
#ifndef hifi_SkeletonDumpApp_h
|
||||
#define hifi_SkeletonDumpApp_h
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
class SkeletonDumpApp : public QCoreApplication {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SkeletonDumpApp(int argc, char* argv[]);
|
||||
~SkeletonDumpApp();
|
||||
|
||||
int getReturnCode() const { return _returnCode; }
|
||||
|
||||
private:
|
||||
int _returnCode { 0 };
|
||||
};
|
||||
|
||||
#endif //hifi_SkeletonDumpApp_h
|
22
tools/skeleton-dump/src/main.cpp
Normal file
22
tools/skeleton-dump/src/main.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// main.cpp
|
||||
// tools/skeleton-dump/src
|
||||
//
|
||||
// Created by Anthony Thibault on 11/4/16.
|
||||
// Copyright 2016 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 <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <QDebug>
|
||||
|
||||
#include "SkeletonDumpApp.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
SkeletonDumpApp app(argc, argv);
|
||||
return app.getReturnCode();
|
||||
}
|
|
@ -233,7 +233,7 @@ function playSuccessSound() {
|
|||
function playFirecrackerSound(position) {
|
||||
Audio.playSound(firecrackerSound, {
|
||||
position: position,
|
||||
volume: 0.7,
|
||||
volume: 0.5,
|
||||
loop: false
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue