mirror of
https://github.com/overte-org/overte.git
synced 2025-04-18 00:26:33 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into fix/tex-invoke-method
This commit is contained in:
commit
2bd53935fc
23 changed files with 670 additions and 610 deletions
|
@ -16,7 +16,7 @@ Contributing
|
|||
git checkout -b new_branch_name
|
||||
```
|
||||
4. Code
|
||||
* Follow the [coding standard](http://docs.highfidelity.io/v1.0/docs/coding-standard)
|
||||
* Follow the [coding standard](https://readme.highfidelity.com/v1.0/docs/coding-standard)
|
||||
5. Commit
|
||||
* Use [well formed commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
|
||||
6. Update your branch
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
Script.load("away.js");
|
||||
Script.load("progress.js");
|
||||
Script.load("edit.js");
|
||||
Script.load("marketplace.js");
|
||||
Script.load("examples.js");
|
||||
Script.load("selectAudioDevice.js");
|
||||
Script.load("notifications.js");
|
||||
Script.load("users.js");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// marketplace.js
|
||||
// examples.js
|
||||
// examples
|
||||
//
|
||||
// Created by Eric Levin on 8 Jan 2016
|
||||
|
@ -16,9 +16,9 @@ Script.include([
|
|||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
|
||||
|
||||
var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace";
|
||||
var marketplaceWindow = new OverlayWebWindow({
|
||||
title: 'Marketplace',
|
||||
var EXAMPLES_URL = "https://metaverse.highfidelity.com/examples";
|
||||
var examplesWindow = new OverlayWebWindow({
|
||||
title: 'Examples',
|
||||
source: "about:blank",
|
||||
width: 900,
|
||||
height: 700,
|
||||
|
@ -29,43 +29,43 @@ var toolHeight = 50;
|
|||
var toolWidth = 50;
|
||||
|
||||
|
||||
function showMarketplace(marketplaceID) {
|
||||
var url = MARKETPLACE_URL;
|
||||
function showExamples(marketplaceID) {
|
||||
var url = EXAMPLES_URL;
|
||||
if (marketplaceID) {
|
||||
url = url + "/items/" + marketplaceID;
|
||||
}
|
||||
print("setting marketplace URL to " + url);
|
||||
marketplaceWindow.setURL(url);
|
||||
marketplaceWindow.setVisible(true);
|
||||
print("setting examples URL to " + url);
|
||||
examplesWindow.setURL(url);
|
||||
examplesWindow.setVisible(true);
|
||||
}
|
||||
|
||||
function hideMarketplace() {
|
||||
marketplaceWindow.setVisible(false);
|
||||
marketplaceWindow.setURL("about:blank");
|
||||
function hideExamples() {
|
||||
examplesWindow.setVisible(false);
|
||||
examplesWindow.setURL("about:blank");
|
||||
}
|
||||
|
||||
function toggleMarketplace() {
|
||||
if (marketplaceWindow.visible) {
|
||||
hideMarketplace();
|
||||
function toggleExamples() {
|
||||
if (examplesWindow.visible) {
|
||||
hideExamples();
|
||||
} else {
|
||||
showMarketplace();
|
||||
showExamples();
|
||||
}
|
||||
}
|
||||
|
||||
var toolBar = (function() {
|
||||
var that = {},
|
||||
toolBar,
|
||||
browseMarketplaceButton;
|
||||
browseExamplesButton;
|
||||
|
||||
function initialize() {
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.marketplace.toolbar", function(windowDimensions, toolbar) {
|
||||
toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.examples.toolbar", function(windowDimensions, toolbar) {
|
||||
return {
|
||||
x: windowDimensions.x - 8 - toolbar.width,
|
||||
y: 135
|
||||
};
|
||||
});
|
||||
browseMarketplaceButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "market-01.svg",
|
||||
browseExamplesButton = toolBar.addTool({
|
||||
imageURL: toolIconUrl + "examples-01.svg",
|
||||
subImage: {
|
||||
x: 0,
|
||||
y: Tool.IMAGE_WIDTH,
|
||||
|
@ -79,10 +79,10 @@ var toolBar = (function() {
|
|||
showButtonDown: true
|
||||
});
|
||||
|
||||
toolBar.showTool(browseMarketplaceButton, true);
|
||||
toolBar.showTool(browseExamplesButton, true);
|
||||
}
|
||||
|
||||
var browseMarketplaceButtonDown = false;
|
||||
var browseExamplesButtonDown = false;
|
||||
that.mousePressEvent = function(event) {
|
||||
var clickedOverlay,
|
||||
url,
|
||||
|
@ -98,10 +98,8 @@ var toolBar = (function() {
|
|||
y: event.y
|
||||
});
|
||||
|
||||
|
||||
|
||||
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleMarketplace();
|
||||
if (browseExamplesButton === toolBar.clicked(clickedOverlay)) {
|
||||
toggleExamples();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -112,7 +110,7 @@ var toolBar = (function() {
|
|||
var handled = false;
|
||||
|
||||
|
||||
if (browseMarketplaceButtonDown) {
|
||||
if (browseExamplesButtonDown) {
|
||||
var clickedOverlay = Overlays.getOverlayAtPoint({
|
||||
x: event.x,
|
||||
y: event.y
|
||||
|
@ -120,7 +118,7 @@ var toolBar = (function() {
|
|||
}
|
||||
|
||||
newModelButtonDown = false;
|
||||
browseMarketplaceButtonDown = false;
|
||||
browseExamplesButtonDown = false;
|
||||
|
||||
return handled;
|
||||
}
|
|
@ -62,8 +62,6 @@ bool IceServer::packetVersionMatch(const udt::Packet& packet) {
|
|||
if (headerVersion == versionForPacketType(headerType)) {
|
||||
return true;
|
||||
} else {
|
||||
qDebug() << "Packet version mismatch for packet" << headerType << " from" << packet.getSenderSockAddr();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ WebEngineView {
|
|||
id: root
|
||||
property var newUrl;
|
||||
|
||||
profile.httpUserAgent: "Mozilla/5.0 Chrome (HighFidelityInterface)"
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("Connecting JS messaging to Hifi Logging")
|
||||
// Ensure the JS from the web-engine makes it to our logging
|
||||
|
|
|
@ -18,23 +18,12 @@
|
|||
#include <glm/gtx/vector_angle.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include <Qt>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QAbstractNativeEventFilter>
|
||||
#include <QtCore/QMimeData>
|
||||
#include <QtCore/QThreadPool>
|
||||
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtGui/QWheelEvent>
|
||||
#include <QtGui/QWindow>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QDesktopServices>
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
|
@ -44,28 +33,18 @@
|
|||
#include <QtQml/QQmlEngine>
|
||||
#include <QtQuick/QQuickWindow>
|
||||
|
||||
#include <QtWidgets/QActionGroup>
|
||||
#include <QtWidgets/QDesktopWidget>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMenuBar>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
#include <QtMultimedia/QMediaPlayer>
|
||||
|
||||
#include <QtNetwork/QNetworkDiskCache>
|
||||
|
||||
#include <gl/Config.h>
|
||||
#include <gl/QOpenGLContextWrapper.h>
|
||||
|
||||
#include <shared/JSONHelpers.h>
|
||||
|
||||
#include <ResourceScriptingInterface.h>
|
||||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <BuildInfo.h>
|
||||
#include <AssetClient.h>
|
||||
#include <AssetUpload.h>
|
||||
#include <AutoUpdater.h>
|
||||
#include <AudioInjectorManager.h>
|
||||
#include <CursorManager.h>
|
||||
|
@ -110,12 +89,9 @@
|
|||
#include <ScriptCache.h>
|
||||
#include <SoundCache.h>
|
||||
#include <ScriptEngines.h>
|
||||
#include <TextureCache.h>
|
||||
#include <Tooltip.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
#include <VrMenu.h>
|
||||
#include <recording/Deck.h>
|
||||
#include <recording/Recorder.h>
|
||||
#include <QmlWebWindowClass.h>
|
||||
|
@ -137,7 +113,6 @@
|
|||
#include "InterfaceActionFactory.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "LODManager.h"
|
||||
#include "Menu.h"
|
||||
#include "ModelPackager.h"
|
||||
#include "PluginContainerProxy.h"
|
||||
#include "scripting/AccountScriptingInterface.h"
|
||||
|
@ -171,7 +146,7 @@
|
|||
|
||||
|
||||
|
||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// ON Windows PC, Nvidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// FIXME seems to be broken.
|
||||
#if defined(Q_OS_WIN)
|
||||
extern "C" {
|
||||
|
@ -254,14 +229,14 @@ public:
|
|||
});
|
||||
}
|
||||
|
||||
void updateHeartbeat() {
|
||||
static void updateHeartbeat() {
|
||||
auto now = usecTimestampNow();
|
||||
auto elapsed = now - _heartbeat;
|
||||
_movingAverage.addSample(elapsed);
|
||||
_heartbeat = now;
|
||||
}
|
||||
|
||||
void deadlockDetectionCrash() {
|
||||
static void deadlockDetectionCrash() {
|
||||
uint32_t* crashTrigger = nullptr;
|
||||
*crashTrigger = 0xDEAD10CC;
|
||||
}
|
||||
|
@ -390,7 +365,7 @@ public:
|
|||
LambdaEvent(std::function<void()> && fun) :
|
||||
QEvent(static_cast<QEvent::Type>(Lambda)), _fun(fun) {
|
||||
}
|
||||
void call() { _fun(); }
|
||||
void call() const { _fun(); }
|
||||
};
|
||||
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||
|
@ -528,7 +503,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
_maxOctreePPS(maxOctreePacketsPerSecond.get()),
|
||||
_lastFaceTrackerUpdate(0)
|
||||
{
|
||||
// FIXME this may be excessivly conservative. On the other hand
|
||||
// FIXME this may be excessively conservative. On the other hand
|
||||
// maybe I'm used to having an 8-core machine
|
||||
// Perhaps find the ideal thread count and subtract 2 or 3
|
||||
// (main thread, present thread, random OS load)
|
||||
|
@ -1014,12 +989,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
|
||||
applicationUpdater->checkForUpdate();
|
||||
|
||||
// Now that menu is initalized we can sync myAvatar with it's state.
|
||||
// Now that menu is initialized we can sync myAvatar with it's state.
|
||||
getMyAvatar()->updateMotionBehaviorFromMenu();
|
||||
|
||||
// FIXME spacemouse code still needs cleanup
|
||||
#if 0
|
||||
// the 3Dconnexion device wants to be initiliazed after a window is displayed.
|
||||
// the 3Dconnexion device wants to be initialized after a window is displayed.
|
||||
SpacemouseManager::getInstance().init();
|
||||
#endif
|
||||
|
||||
|
@ -1124,7 +1099,7 @@ void Application::showCursor(const QCursor& cursor) {
|
|||
_cursorNeedsChanging = true;
|
||||
}
|
||||
|
||||
void Application::updateHeartbeat() {
|
||||
void Application::updateHeartbeat() const {
|
||||
static_cast<DeadlockWatchdogThread*>(_deadlockWatchdogThread)->updateHeartbeat();
|
||||
}
|
||||
|
||||
|
@ -1218,12 +1193,12 @@ void Application::cleanupBeforeQuit() {
|
|||
|
||||
Application::~Application() {
|
||||
EntityTreePointer tree = getEntities()->getTree();
|
||||
tree->setSimulation(NULL);
|
||||
tree->setSimulation(nullptr);
|
||||
|
||||
_octreeProcessor.terminate();
|
||||
_entityEditSender.terminate();
|
||||
|
||||
_physicsEngine->setCharacterController(NULL);
|
||||
_physicsEngine->setCharacterController(nullptr);
|
||||
|
||||
ModelEntityItem::cleanupLoadedAnimations();
|
||||
|
||||
|
@ -1264,7 +1239,7 @@ Application::~Application() {
|
|||
|
||||
_window->deleteLater();
|
||||
|
||||
qInstallMessageHandler(NULL); // NOTE: Do this as late as possible so we continue to get our log messages
|
||||
qInstallMessageHandler(nullptr); // NOTE: Do this as late as possible so we continue to get our log messages
|
||||
}
|
||||
|
||||
void Application::initializeGL() {
|
||||
|
@ -1744,7 +1719,7 @@ void Application::runTests() {
|
|||
runUnitTests();
|
||||
}
|
||||
|
||||
void Application::audioMuteToggled() {
|
||||
void Application::audioMuteToggled() const {
|
||||
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteAudio);
|
||||
Q_CHECK_PTR(muteAction);
|
||||
muteAction->setChecked(DependencyManager::get<AudioClient>()->isMuted());
|
||||
|
@ -1826,7 +1801,7 @@ bool Application::event(QEvent* event) {
|
|||
}
|
||||
|
||||
if ((int)event->type() == (int)Lambda) {
|
||||
((LambdaEvent*)event)->call();
|
||||
static_cast<LambdaEvent*>(event)->call();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1860,25 +1835,25 @@ bool Application::event(QEvent* event) {
|
|||
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseMove:
|
||||
mouseMoveEvent((QMouseEvent*)event);
|
||||
mouseMoveEvent(static_cast<QMouseEvent*>(event));
|
||||
return true;
|
||||
case QEvent::MouseButtonPress:
|
||||
mousePressEvent((QMouseEvent*)event);
|
||||
mousePressEvent(static_cast<QMouseEvent*>(event));
|
||||
return true;
|
||||
case QEvent::MouseButtonDblClick:
|
||||
mouseDoublePressEvent((QMouseEvent*)event);
|
||||
mouseDoublePressEvent(static_cast<QMouseEvent*>(event));
|
||||
return true;
|
||||
case QEvent::MouseButtonRelease:
|
||||
mouseReleaseEvent((QMouseEvent*)event);
|
||||
mouseReleaseEvent(static_cast<QMouseEvent*>(event));
|
||||
return true;
|
||||
case QEvent::KeyPress:
|
||||
keyPressEvent((QKeyEvent*)event);
|
||||
keyPressEvent(static_cast<QKeyEvent*>(event));
|
||||
return true;
|
||||
case QEvent::KeyRelease:
|
||||
keyReleaseEvent((QKeyEvent*)event);
|
||||
keyReleaseEvent(static_cast<QKeyEvent*>(event));
|
||||
return true;
|
||||
case QEvent::FocusOut:
|
||||
focusOutEvent((QFocusEvent*)event);
|
||||
focusOutEvent(static_cast<QFocusEvent*>(event));
|
||||
return true;
|
||||
case QEvent::TouchBegin:
|
||||
touchBeginEvent(static_cast<QTouchEvent*>(event));
|
||||
|
@ -2306,13 +2281,13 @@ void Application::focusOutEvent(QFocusEvent* event) {
|
|||
|
||||
// synthesize events for keys currently pressed, since we may not get their release events
|
||||
foreach (int key, _keysPressed) {
|
||||
QKeyEvent event(QEvent::KeyRelease, key, Qt::NoModifier);
|
||||
keyReleaseEvent(&event);
|
||||
QKeyEvent keyEvent(QEvent::KeyRelease, key, Qt::NoModifier);
|
||||
keyReleaseEvent(&keyEvent);
|
||||
}
|
||||
_keysPressed.clear();
|
||||
}
|
||||
|
||||
void Application::maybeToggleMenuVisible(QMouseEvent* event) {
|
||||
void Application::maybeToggleMenuVisible(QMouseEvent* event) const {
|
||||
#ifndef Q_OS_MAC
|
||||
// If in full screen, and our main windows menu bar is hidden, and we're close to the top of the QMainWindow
|
||||
// then show the menubar.
|
||||
|
@ -2428,7 +2403,7 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::mouseDoublePressEvent(QMouseEvent* event) {
|
||||
void Application::mouseDoublePressEvent(QMouseEvent* event) const {
|
||||
// if one of our scripts have asked to capture this event, then stop processing it
|
||||
if (_controllerScriptingInterface->isMouseCaptured()) {
|
||||
return;
|
||||
|
@ -2528,7 +2503,7 @@ void Application::touchEndEvent(QTouchEvent* event) {
|
|||
// put any application specific touch behavior below here..
|
||||
}
|
||||
|
||||
void Application::wheelEvent(QWheelEvent* event) {
|
||||
void Application::wheelEvent(QWheelEvent* event) const {
|
||||
_altPressed = false;
|
||||
_controllerScriptingInterface->emitWheelEvent(event); // send events to any registered scripts
|
||||
|
||||
|
@ -2707,9 +2682,11 @@ float Application::getAverageSimsPerSecond() {
|
|||
}
|
||||
return _simsPerSecondReport;
|
||||
}
|
||||
|
||||
void Application::setAvatarSimrateSample(float sample) {
|
||||
_avatarSimsPerSecond.updateAverage(sample);
|
||||
}
|
||||
|
||||
float Application::getAvatarSimrate() {
|
||||
uint64_t now = usecTimestampNow();
|
||||
|
||||
|
@ -2724,7 +2701,7 @@ void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
|||
controller::InputDevice::setLowVelocityFilter(lowVelocityFilter);
|
||||
}
|
||||
|
||||
ivec2 Application::getMouse() {
|
||||
ivec2 Application::getMouse() const {
|
||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||
|
||||
// in the HMD, the reticlePosition is the mouse position
|
||||
|
@ -2741,11 +2718,11 @@ FaceTracker* Application::getActiveFaceTracker() {
|
|||
auto dde = DependencyManager::get<DdeFaceTracker>();
|
||||
|
||||
return (dde->isActive() ? static_cast<FaceTracker*>(dde.data()) :
|
||||
(faceshift->isActive() ? static_cast<FaceTracker*>(faceshift.data()) : NULL));
|
||||
(faceshift->isActive() ? static_cast<FaceTracker*>(faceshift.data()) : nullptr));
|
||||
}
|
||||
|
||||
FaceTracker* Application::getSelectedFaceTracker() {
|
||||
FaceTracker* faceTracker = NULL;
|
||||
FaceTracker* faceTracker = nullptr;
|
||||
#ifdef HAVE_FACESHIFT
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Faceshift)) {
|
||||
faceTracker = DependencyManager::get<Faceshift>().data();
|
||||
|
@ -2759,7 +2736,7 @@ FaceTracker* Application::getSelectedFaceTracker() {
|
|||
return faceTracker;
|
||||
}
|
||||
|
||||
void Application::setActiveFaceTracker() {
|
||||
void Application::setActiveFaceTracker() const {
|
||||
#if defined(HAVE_FACESHIFT) || defined(HAVE_DDE)
|
||||
bool isMuted = Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking);
|
||||
#endif
|
||||
|
@ -2816,60 +2793,68 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
|||
auto entityTree = getEntities()->getTree();
|
||||
auto exportTree = std::make_shared<EntityTree>();
|
||||
exportTree->createRootElement();
|
||||
|
||||
glm::vec3 root(TREE_SCALE, TREE_SCALE, TREE_SCALE);
|
||||
for (auto entityID : entityIDs) { // Gather entities and properties.
|
||||
auto entityItem = entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entityItem) {
|
||||
qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene.";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!givenOffset) {
|
||||
EntityItemID parentID = entityItem->getParentID();
|
||||
if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) {
|
||||
auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties.
|
||||
root.x = glm::min(root.x, position.x);
|
||||
root.y = glm::min(root.y, position.y);
|
||||
root.z = glm::min(root.z, position.z);
|
||||
bool success = true;
|
||||
entityTree->withReadLock([&] {
|
||||
for (auto entityID : entityIDs) { // Gather entities and properties.
|
||||
auto entityItem = entityTree->findEntityByEntityItemID(entityID);
|
||||
if (!entityItem) {
|
||||
qCWarning(interfaceapp) << "Skipping export of" << entityID << "that is not in scene.";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!givenOffset) {
|
||||
EntityItemID parentID = entityItem->getParentID();
|
||||
if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) {
|
||||
auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties.
|
||||
root.x = glm::min(root.x, position.x);
|
||||
root.y = glm::min(root.y, position.y);
|
||||
root.z = glm::min(root.z, position.z);
|
||||
}
|
||||
}
|
||||
entities[entityID] = entityItem;
|
||||
}
|
||||
entities[entityID] = entityItem;
|
||||
}
|
||||
|
||||
if (entities.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
if (entities.size() == 0) {
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (givenOffset) {
|
||||
root = *givenOffset;
|
||||
}
|
||||
for (EntityItemPointer& entityDatum : entities) {
|
||||
auto properties = entityDatum->getProperties();
|
||||
EntityItemID parentID = properties.getParentID();
|
||||
if (parentID.isInvalidID()) {
|
||||
properties.setPosition(properties.getPosition() - root);
|
||||
} else if (!entities.contains(parentID)) {
|
||||
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
|
||||
} // else valid parent -- don't offset
|
||||
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
|
||||
}
|
||||
if (givenOffset) {
|
||||
root = *givenOffset;
|
||||
}
|
||||
for (EntityItemPointer& entityDatum : entities) {
|
||||
auto properties = entityDatum->getProperties();
|
||||
EntityItemID parentID = properties.getParentID();
|
||||
if (parentID.isInvalidID()) {
|
||||
properties.setPosition(properties.getPosition() - root);
|
||||
}
|
||||
else if (!entities.contains(parentID)) {
|
||||
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
|
||||
} // else valid parent -- don't offset
|
||||
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
|
||||
}
|
||||
});
|
||||
if (success) {
|
||||
exportTree->writeToJSONFile(filename.toLocal8Bit().constData());
|
||||
|
||||
exportTree->writeToJSONFile(filename.toLocal8Bit().constData());
|
||||
|
||||
// restore the main window's active state
|
||||
_window->activateWindow();
|
||||
return true;
|
||||
// restore the main window's active state
|
||||
_window->activateWindow();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
|
||||
glm::vec3 offset(x, y, z);
|
||||
QVector<EntityItemPointer> entities;
|
||||
QVector<EntityItemID> ids;
|
||||
getEntities()->getTree()->findEntities(AACube(offset, scale), entities);
|
||||
foreach(EntityItemPointer entity, entities) {
|
||||
ids << entity->getEntityItemID();
|
||||
}
|
||||
auto entityTree = getEntities()->getTree();
|
||||
entityTree->withReadLock([&] {
|
||||
entityTree->findEntities(AACube(offset, scale), entities);
|
||||
foreach(EntityItemPointer entity, entities) {
|
||||
ids << entity->getEntityItemID();
|
||||
}
|
||||
});
|
||||
return exportEntities(filename, ids, &offset);
|
||||
}
|
||||
|
||||
|
@ -2888,7 +2873,7 @@ void Application::loadSettings() {
|
|||
_settingsLoaded = true;
|
||||
}
|
||||
|
||||
void Application::saveSettings() {
|
||||
void Application::saveSettings() const {
|
||||
sessionRunTime.set(_sessionRunTimer.elapsed() / MSECS_PER_SEC);
|
||||
DependencyManager::get<AudioClient>()->saveSettings();
|
||||
DependencyManager::get<LODManager>()->saveSettings();
|
||||
|
@ -2899,12 +2884,15 @@ void Application::saveSettings() {
|
|||
}
|
||||
|
||||
bool Application::importEntities(const QString& urlOrFilename) {
|
||||
_entityClipboard->eraseAllOctreeElements();
|
||||
bool success = false;
|
||||
_entityClipboard->withWriteLock([&] {
|
||||
_entityClipboard->eraseAllOctreeElements();
|
||||
|
||||
bool success = _entityClipboard->readFromURL(urlOrFilename);
|
||||
if (success) {
|
||||
_entityClipboard->reaverageOctreeElements();
|
||||
}
|
||||
success = _entityClipboard->readFromURL(urlOrFilename);
|
||||
if (success) {
|
||||
_entityClipboard->reaverageOctreeElements();
|
||||
}
|
||||
});
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -2975,7 +2963,7 @@ void Application::init() {
|
|||
connect(getMyAvatar(), &MyAvatar::newCollisionSoundURL, DependencyManager::get<SoundCache>().data(), &SoundCache::getSound);
|
||||
}
|
||||
|
||||
void Application::updateLOD() {
|
||||
void Application::updateLOD() const {
|
||||
PerformanceTimer perfTimer("LOD");
|
||||
// adjust it unless we were asked to disable this feature, or if we're currently in throttleRendering mode
|
||||
if (!isThrottleRendering()) {
|
||||
|
@ -3177,13 +3165,13 @@ void Application::reloadResourceCaches() {
|
|||
getMyAvatar()->resetFullAvatarURL();
|
||||
}
|
||||
|
||||
void Application::rotationModeChanged() {
|
||||
void Application::rotationModeChanged() const {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
|
||||
getMyAvatar()->setHeadPitch(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::updateDialogs(float deltaTime) {
|
||||
void Application::updateDialogs(float deltaTime) const {
|
||||
PerformanceTimer perfTimer("updateDialogs");
|
||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||
PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
|
||||
|
@ -3219,7 +3207,7 @@ void Application::update(float deltaTime) {
|
|||
if (!_physicsEnabled && _processOctreeStatsCounter > 0) {
|
||||
|
||||
// process octree stats packets are sent in between full sends of a scene.
|
||||
// We keep physics disabled until we've recieved a full scene and everything near the avatar in that
|
||||
// We keep physics disabled until we've received a full scene and everything near the avatar in that
|
||||
// scene is ready to compute its collision shape.
|
||||
|
||||
if (nearbyEntitiesAreReadyForPhysics()) {
|
||||
|
@ -3524,7 +3512,7 @@ int Application::sendNackPackets() {
|
|||
|
||||
QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers;
|
||||
_octreeServerSceneStats.withReadLock([&] {
|
||||
// retreive octree scene stats of this node
|
||||
// retrieve octree scene stats of this node
|
||||
if (_octreeServerSceneStats.find(nodeUUID) == _octreeServerSceneStats.end()) {
|
||||
return;
|
||||
}
|
||||
|
@ -3724,7 +3712,7 @@ bool Application::isHMDMode() const {
|
|||
}
|
||||
float Application::getTargetFrameRate() { return getActiveDisplayPlugin()->getTargetFrameRate(); }
|
||||
|
||||
QRect Application::getDesirableApplicationGeometry() {
|
||||
QRect Application::getDesirableApplicationGeometry() const {
|
||||
QRect applicationGeometry = getWindow()->geometry();
|
||||
|
||||
// If our parent window is on the HMD, then don't use its geometry, instead use
|
||||
|
@ -3737,7 +3725,7 @@ QRect Application::getDesirableApplicationGeometry() {
|
|||
|
||||
// if our app's screen is the hmd screen, we don't want to place the
|
||||
// running scripts widget on it. So we need to pick a better screen.
|
||||
// we will use the screen for the HMDTools since it's a guarenteed
|
||||
// we will use the screen for the HMDTools since it's a guaranteed
|
||||
// better screen.
|
||||
if (appScreen == hmdScreen) {
|
||||
QScreen* betterScreen = hmdTools->windowHandle()->screen();
|
||||
|
@ -3766,7 +3754,7 @@ void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
|||
viewFrustum.calculate();
|
||||
}
|
||||
|
||||
glm::vec3 Application::getSunDirection() {
|
||||
glm::vec3 Application::getSunDirection() const {
|
||||
// Sun direction is in fact just the location of the sun relative to the origin
|
||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
return skyStage->getSunLight()->getDirection();
|
||||
|
@ -3968,7 +3956,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE;
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) {
|
||||
renderDebugFlags = (RenderArgs::DebugFlags) (renderDebugFlags | (int)RenderArgs::RENDER_DEBUG_HULLS);
|
||||
renderDebugFlags = static_cast<RenderArgs::DebugFlags>(renderDebugFlags |
|
||||
static_cast<int>(RenderArgs::RENDER_DEBUG_HULLS));
|
||||
}
|
||||
renderArgs->_debugFlags = renderDebugFlags;
|
||||
//ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, pendingChanges);
|
||||
|
@ -4033,7 +4022,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
|||
myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * myAvatar->getScale());
|
||||
|
||||
} else { // HEAD zoom level
|
||||
// FIXME note that the positioing of the camera relative to the avatar can suffer limited
|
||||
// FIXME note that the positioning of the camera relative to the avatar can suffer limited
|
||||
// precision as the user's position moves further away from the origin. Thus at
|
||||
// /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways
|
||||
// wildly as you rotate your avatar because the floating point values are becoming
|
||||
|
@ -4079,7 +4068,7 @@ void Application::resetSensors(bool andReload) {
|
|||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void Application::updateWindowTitle(){
|
||||
void Application::updateWindowTitle() const {
|
||||
|
||||
QString buildVersion = " (build " + applicationVersion() + ")";
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
@ -4137,14 +4126,14 @@ void Application::resettingDomain() {
|
|||
_notifiedPacketVersionMismatchThisDomain = false;
|
||||
}
|
||||
|
||||
void Application::nodeAdded(SharedNodePointer node) {
|
||||
void Application::nodeAdded(SharedNodePointer node) const {
|
||||
if (node->getType() == NodeType::AvatarMixer) {
|
||||
// new avatar mixer, send off our identity packet right away
|
||||
getMyAvatar()->sendIdentityPacket();
|
||||
}
|
||||
}
|
||||
|
||||
void Application::nodeActivated(SharedNodePointer node) {
|
||||
void Application::nodeActivated(SharedNodePointer node) const {
|
||||
if (node->getType() == NodeType::AssetServer) {
|
||||
// asset server just connected - check if we have the asset browser showing
|
||||
|
||||
|
@ -4278,7 +4267,7 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer
|
|||
statsMessageLength = octreeStats.unpackFromPacket(message);
|
||||
|
||||
// see if this is the first we've heard of this node...
|
||||
NodeToJurisdictionMap* jurisdiction = NULL;
|
||||
NodeToJurisdictionMap* jurisdiction = nullptr;
|
||||
QString serverType;
|
||||
if (sendingNode->getType() == NodeType::EntityServer) {
|
||||
jurisdiction = &_entityServerJurisdictions;
|
||||
|
@ -4434,7 +4423,7 @@ bool Application::acceptURL(const QString& urlString, bool defaultUpload) {
|
|||
return defaultUpload;
|
||||
}
|
||||
|
||||
void Application::setSessionUUID(const QUuid& sessionUUID) {
|
||||
void Application::setSessionUUID(const QUuid& sessionUUID) const {
|
||||
// HACK: until we swap the library dependency order between physics and entities
|
||||
// we cache the sessionID in two distinct places for physics.
|
||||
Physics::setSessionUUID(sessionUUID); // TODO: remove this one
|
||||
|
@ -4575,7 +4564,7 @@ bool Application::displayAvatarAttachmentConfirmationDialog(const QString& name)
|
|||
}
|
||||
}
|
||||
|
||||
void Application::toggleRunningScriptsWidget() {
|
||||
void Application::toggleRunningScriptsWidget() const {
|
||||
static const QUrl url("hifi/dialogs/RunningScripts.qml");
|
||||
DependencyManager::get<OffscreenUi>()->show(url, "RunningScripts");
|
||||
//if (_runningScriptsWidget->isVisible()) {
|
||||
|
@ -4612,7 +4601,7 @@ void Application::packageModel() {
|
|||
ModelPackager::package();
|
||||
}
|
||||
|
||||
void Application::openUrl(const QUrl& url) {
|
||||
void Application::openUrl(const QUrl& url) const {
|
||||
if (!url.isEmpty()) {
|
||||
if (url.scheme() == HIFI_URL_SCHEME) {
|
||||
DependencyManager::get<AddressManager>()->handleLookupString(url.toString());
|
||||
|
@ -4642,7 +4631,7 @@ void Application::setPreviousScriptLocation(const QString& location) {
|
|||
_previousScriptLocation.set(location);
|
||||
}
|
||||
|
||||
void Application::loadScriptURLDialog() {
|
||||
void Application::loadScriptURLDialog() const {
|
||||
auto newScript = OffscreenUi::getText(nullptr, "Open and Run Script", "Script URL");
|
||||
if (!newScript.isEmpty()) {
|
||||
DependencyManager::get<ScriptEngines>()->loadScript(newScript);
|
||||
|
@ -4707,7 +4696,7 @@ void Application::notifyPacketVersionMismatch() {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::checkSkeleton() {
|
||||
void Application::checkSkeleton() const {
|
||||
if (getMyAvatar()->getSkeletonModel()->isActive() && !getMyAvatar()->getSkeletonModel()->hasSkeleton()) {
|
||||
qCDebug(interfaceapp) << "MyAvatar model has no skeleton";
|
||||
|
||||
|
@ -4788,7 +4777,7 @@ void Application::setMaxOctreePacketsPerSecond(int maxOctreePPS) {
|
|||
}
|
||||
}
|
||||
|
||||
int Application::getMaxOctreePacketsPerSecond() {
|
||||
int Application::getMaxOctreePacketsPerSecond() const {
|
||||
return _maxOctreePPS;
|
||||
}
|
||||
|
||||
|
@ -4812,7 +4801,7 @@ DisplayPlugin* Application::getActiveDisplayPlugin() {
|
|||
}
|
||||
|
||||
const DisplayPlugin* Application::getActiveDisplayPlugin() const {
|
||||
return ((Application*)this)->getActiveDisplayPlugin();
|
||||
return const_cast<Application*>(this)->getActiveDisplayPlugin();
|
||||
}
|
||||
|
||||
static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool active = false) {
|
||||
|
@ -4892,7 +4881,7 @@ void Application::updateDisplayMode() {
|
|||
}
|
||||
}
|
||||
|
||||
// concactonate the groupings into a single list in the order: standard, advanced, developer
|
||||
// concatenate the groupings into a single list in the order: standard, advanced, developer
|
||||
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
|
||||
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
|
||||
|
||||
|
@ -4904,7 +4893,7 @@ void Application::updateDisplayMode() {
|
|||
first = false;
|
||||
}
|
||||
|
||||
// after all plugins have been added to the menu, add a seperator to the menu
|
||||
// after all plugins have been added to the menu, add a separator to the menu
|
||||
auto menu = Menu::getInstance();
|
||||
auto parent = menu->getMenu(MenuOption::OutputMenu);
|
||||
parent->addSeparator();
|
||||
|
@ -4975,7 +4964,7 @@ void Application::updateDisplayMode() {
|
|||
|
||||
emit activeDisplayPluginChanged();
|
||||
|
||||
// reset the avatar, to set head and hand palms back to a resonable default pose.
|
||||
// reset the avatar, to set head and hand palms back to a reasonable default pose.
|
||||
getMyAvatar()->reset(false);
|
||||
|
||||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
|
@ -5104,7 +5093,7 @@ void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
|||
updateDisplayMode();
|
||||
}
|
||||
|
||||
void Application::handleLocalServerConnection() {
|
||||
void Application::handleLocalServerConnection() const {
|
||||
auto server = qobject_cast<QLocalServer*>(sender());
|
||||
|
||||
qDebug() << "Got connection on local server from additional instance - waiting for parameters";
|
||||
|
@ -5117,7 +5106,7 @@ void Application::handleLocalServerConnection() {
|
|||
qApp->getWindow()->activateWindow();
|
||||
}
|
||||
|
||||
void Application::readArgumentsFromLocalSocket() {
|
||||
void Application::readArgumentsFromLocalSocket() const {
|
||||
auto socket = qobject_cast<QLocalSocket*>(sender());
|
||||
|
||||
auto message = socket->readAll();
|
||||
|
|
|
@ -135,14 +135,14 @@ public:
|
|||
const ViewFrustum* getDisplayViewFrustum() const;
|
||||
ViewFrustum* getShadowViewFrustum() override { return &_shadowViewFrustum; }
|
||||
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
|
||||
EntityTreeRenderer* getEntities() { return DependencyManager::get<EntityTreeRenderer>().data(); }
|
||||
EntityTreeRenderer* getEntities() const { return DependencyManager::get<EntityTreeRenderer>().data(); }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
MainWindow* getWindow() { return _window; }
|
||||
EntityTreePointer getEntityClipboard() { return _entityClipboard; }
|
||||
MainWindow* getWindow() const { return _window; }
|
||||
EntityTreePointer getEntityClipboard() const { return _entityClipboard; }
|
||||
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
|
||||
EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; }
|
||||
|
||||
ivec2 getMouse();
|
||||
ivec2 getMouse() const;
|
||||
|
||||
FaceTracker* getActiveFaceTracker();
|
||||
FaceTracker* getSelectedFaceTracker();
|
||||
|
@ -155,7 +155,7 @@ public:
|
|||
|
||||
bool isForeground() const { return _isForeground; }
|
||||
|
||||
uint32_t getFrameCount() { return _frameCount; }
|
||||
uint32_t getFrameCount() const { return _frameCount; }
|
||||
float getFps() const { return _fps; }
|
||||
float getTargetFrameRate(); // frames/second
|
||||
float getLastInstanteousFps() const { return _lastInstantaneousFps; }
|
||||
|
@ -179,7 +179,7 @@ public:
|
|||
DisplayPlugin* getActiveDisplayPlugin();
|
||||
const DisplayPlugin* getActiveDisplayPlugin() const;
|
||||
|
||||
FileLogger* getLogger() { return _logger; }
|
||||
FileLogger* getLogger() const { return _logger; }
|
||||
|
||||
glm::vec2 getViewportDimensions() const;
|
||||
|
||||
|
@ -189,7 +189,7 @@ public:
|
|||
|
||||
bool isAboutToQuit() const { return _aboutToQuit; }
|
||||
|
||||
// the isHMDmode is true whenever we use the interface from an HMD and not a standard flat display
|
||||
// the isHMDMode is true whenever we use the interface from an HMD and not a standard flat display
|
||||
// rendering of several elements depend on that
|
||||
// TODO: carry that information on the Camera as a setting
|
||||
bool isHMDMode() const;
|
||||
|
@ -197,14 +197,14 @@ public:
|
|||
glm::mat4 getEyeOffset(int eye) const;
|
||||
glm::mat4 getEyeProjection(int eye) const;
|
||||
|
||||
QRect getDesirableApplicationGeometry();
|
||||
QRect getDesirableApplicationGeometry() const;
|
||||
Bookmarks* getBookmarks() const { return _bookmarks; }
|
||||
|
||||
virtual bool canAcceptURL(const QString& url) const override;
|
||||
virtual bool acceptURL(const QString& url, bool defaultUpload = false) override;
|
||||
|
||||
void setMaxOctreePacketsPerSecond(int maxOctreePPS);
|
||||
int getMaxOctreePacketsPerSecond();
|
||||
int getMaxOctreePacketsPerSecond() const;
|
||||
|
||||
render::ScenePointer getMain3DScene() override { return _main3DScene; }
|
||||
render::ScenePointer getMain3DScene() const { return _main3DScene; }
|
||||
|
@ -239,22 +239,22 @@ public slots:
|
|||
bool exportEntities(const QString& filename, float x, float y, float z, float scale);
|
||||
bool importEntities(const QString& url);
|
||||
|
||||
void setLowVelocityFilter(bool lowVelocityFilter);
|
||||
static void setLowVelocityFilter(bool lowVelocityFilter);
|
||||
Q_INVOKABLE void loadDialog();
|
||||
Q_INVOKABLE void loadScriptURLDialog();
|
||||
Q_INVOKABLE void loadScriptURLDialog() const;
|
||||
void toggleLogDialog();
|
||||
void toggleRunningScriptsWidget();
|
||||
void toggleRunningScriptsWidget() const;
|
||||
void toggleAssetServerWidget(QString filePath = "");
|
||||
|
||||
void handleLocalServerConnection();
|
||||
void readArgumentsFromLocalSocket();
|
||||
void handleLocalServerConnection() const;
|
||||
void readArgumentsFromLocalSocket() const;
|
||||
|
||||
void packageModel();
|
||||
static void packageModel();
|
||||
|
||||
void openUrl(const QUrl& url);
|
||||
void openUrl(const QUrl& url) const;
|
||||
|
||||
void resetSensors(bool andReload = false);
|
||||
void setActiveFaceTracker();
|
||||
void setActiveFaceTracker() const;
|
||||
|
||||
#ifdef HAVE_IVIEWHMD
|
||||
void setActiveEyeTracker();
|
||||
|
@ -264,7 +264,7 @@ public slots:
|
|||
#endif
|
||||
|
||||
void aboutApp();
|
||||
void showHelp();
|
||||
static void showHelp();
|
||||
|
||||
void cycleCamera();
|
||||
void cameraMenuChanged();
|
||||
|
@ -273,14 +273,14 @@ public slots:
|
|||
|
||||
void reloadResourceCaches();
|
||||
|
||||
void updateHeartbeat();
|
||||
void updateHeartbeat() const;
|
||||
|
||||
void crashApplication();
|
||||
void deadlockApplication();
|
||||
static void crashApplication();
|
||||
static void deadlockApplication();
|
||||
|
||||
void rotationModeChanged();
|
||||
void rotationModeChanged() const;
|
||||
|
||||
void runTests();
|
||||
static void runTests();
|
||||
|
||||
private slots:
|
||||
void showDesktop();
|
||||
|
@ -290,7 +290,7 @@ private slots:
|
|||
|
||||
void resettingDomain();
|
||||
|
||||
void audioMuteToggled();
|
||||
void audioMuteToggled() const;
|
||||
void faceTrackerMuteToggled();
|
||||
|
||||
void activeChanged(Qt::ApplicationState state);
|
||||
|
@ -298,7 +298,7 @@ private slots:
|
|||
void notifyPacketVersionMismatch();
|
||||
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
void saveSettings() const;
|
||||
|
||||
bool acceptSnapshot(const QString& urlString);
|
||||
bool askToSetAvatarUrl(const QString& url);
|
||||
|
@ -308,18 +308,18 @@ private slots:
|
|||
void displayAvatarAttachmentWarning(const QString& message) const;
|
||||
bool displayAvatarAttachmentConfirmationDialog(const QString& name) const;
|
||||
|
||||
void setSessionUUID(const QUuid& sessionUUID);
|
||||
void setSessionUUID(const QUuid& sessionUUID) const;
|
||||
void domainChanged(const QString& domainHostname);
|
||||
void updateWindowTitle();
|
||||
void nodeAdded(SharedNodePointer node);
|
||||
void nodeActivated(SharedNodePointer node);
|
||||
void updateWindowTitle() const;
|
||||
void nodeAdded(SharedNodePointer node) const;
|
||||
void nodeActivated(SharedNodePointer node) const;
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
void packetSent(quint64 length);
|
||||
static void packetSent(quint64 length);
|
||||
void updateDisplayMode();
|
||||
void updateInputModes();
|
||||
|
||||
private:
|
||||
void initDisplay();
|
||||
static void initDisplay();
|
||||
void init();
|
||||
|
||||
void cleanupBeforeQuit();
|
||||
|
@ -327,14 +327,14 @@ private:
|
|||
void update(float deltaTime);
|
||||
|
||||
// Various helper functions called during update()
|
||||
void updateLOD();
|
||||
void updateLOD() const;
|
||||
void updateThreads(float deltaTime);
|
||||
void updateDialogs(float deltaTime);
|
||||
void updateDialogs(float deltaTime) const;
|
||||
|
||||
void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
|
||||
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
static void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
|
||||
|
||||
glm::vec3 getSunDirection();
|
||||
glm::vec3 getSunDirection() const;
|
||||
|
||||
void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region);
|
||||
|
||||
|
@ -344,7 +344,7 @@ private:
|
|||
|
||||
MyAvatar* getMyAvatar() const;
|
||||
|
||||
void checkSkeleton();
|
||||
void checkSkeleton() const;
|
||||
|
||||
void initializeAcceptedFiles();
|
||||
|
||||
|
@ -366,18 +366,18 @@ private:
|
|||
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void mousePressEvent(QMouseEvent* event);
|
||||
void mouseDoublePressEvent(QMouseEvent* event);
|
||||
void mouseDoublePressEvent(QMouseEvent* event) const;
|
||||
void mouseReleaseEvent(QMouseEvent* event);
|
||||
|
||||
void touchBeginEvent(QTouchEvent* event);
|
||||
void touchEndEvent(QTouchEvent* event);
|
||||
void touchUpdateEvent(QTouchEvent* event);
|
||||
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
void wheelEvent(QWheelEvent* event) const;
|
||||
void dropEvent(QDropEvent* event);
|
||||
void dragEnterEvent(QDragEnterEvent* event);
|
||||
static void dragEnterEvent(QDragEnterEvent* event);
|
||||
|
||||
void maybeToggleMenuVisible(QMouseEvent* event);
|
||||
void maybeToggleMenuVisible(QMouseEvent* event) const;
|
||||
|
||||
MainWindow* _window;
|
||||
QElapsedTimer& _sessionRunTimer;
|
||||
|
@ -423,7 +423,7 @@ private:
|
|||
int _avatarSimsPerSecondReport {0};
|
||||
quint64 _lastAvatarSimsPerSecondUpdate {0};
|
||||
Camera _myCamera; // My view onto the world
|
||||
Camera _mirrorCamera; // Cammera for mirror view
|
||||
Camera _mirrorCamera; // Camera for mirror view
|
||||
QRect _mirrorViewRect;
|
||||
|
||||
Setting::Handle<QString> _previousScriptLocation;
|
||||
|
|
|
@ -297,7 +297,14 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
auto sceneLocation = sceneStage->getLocation();
|
||||
auto sceneTime = sceneStage->getTime();
|
||||
|
||||
// Skybox and procedural skybox data
|
||||
auto skybox = std::dynamic_pointer_cast<ProceduralSkybox>(skyStage->getSkybox());
|
||||
static QString userData;
|
||||
|
||||
if (!zone) {
|
||||
userData = QString();
|
||||
skybox->clear();
|
||||
|
||||
_pendingSkyboxTexture = false;
|
||||
_skyboxTexture.clear();
|
||||
|
||||
|
@ -373,9 +380,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
|
||||
switch (zone->getBackgroundMode()) {
|
||||
case BACKGROUND_MODE_SKYBOX: {
|
||||
auto skybox = std::dynamic_pointer_cast<ProceduralSkybox>(skyStage->getSkybox());
|
||||
skybox->setColor(zone->getSkyboxProperties().getColorVec3());
|
||||
static QString userData;
|
||||
if (userData != zone->getUserData()) {
|
||||
userData = zone->getUserData();
|
||||
skybox->parse(userData);
|
||||
|
@ -414,9 +419,15 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
|
|||
|
||||
case BACKGROUND_MODE_INHERIT:
|
||||
default:
|
||||
skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME); // let the application background through
|
||||
_pendingSkyboxTexture = false;
|
||||
// Clear the skybox to release its textures
|
||||
userData = QString();
|
||||
skybox->clear();
|
||||
|
||||
_skyboxTexture.clear();
|
||||
_pendingSkyboxTexture = false;
|
||||
|
||||
// Let the application background through
|
||||
skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1323,7 +1323,9 @@ QVector<EntityItemID> EntityTree::sendEntities(EntityEditPacketSender* packetSen
|
|||
// We need to keep a map so that we can map parent identifiers correctly.
|
||||
QHash<EntityItemID, EntityItemID> map;
|
||||
args.map = ↦
|
||||
recurseTreeWithOperation(sendEntitiesOperation, &args);
|
||||
withReadLock([&] {
|
||||
recurseTreeWithOperation(sendEntitiesOperation, &args);
|
||||
});
|
||||
packetSender->releaseQueuedMessages();
|
||||
|
||||
return map.values().toVector();
|
||||
|
|
|
@ -9,17 +9,20 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <QBuffer>
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
#include <QtDebug>
|
||||
#include <QtEndian>
|
||||
#include <QFileInfo>
|
||||
#include "FBXReader.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QIODevice>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QtEndian>
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <shared/NsightHelpers.h>
|
||||
|
||||
template<class T> int streamSize() {
|
||||
return sizeof(T);
|
||||
}
|
||||
|
@ -299,6 +302,7 @@ FBXNode parseTextFBXNode(Tokenizer& tokenizer) {
|
|||
}
|
||||
|
||||
FBXNode FBXReader::parseFBX(QIODevice* device) {
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff0000ff, device);
|
||||
// verify the prolog
|
||||
const QByteArray BINARY_PROLOG = "Kaydara FBX Binary ";
|
||||
if (device->peek(BINARY_PROLOG.size()) != BINARY_PROLOG) {
|
||||
|
|
|
@ -12,17 +12,20 @@
|
|||
// http://www.scratchapixel.com/old/lessons/3d-advanced-lessons/obj-file-format/obj-file-format/
|
||||
// http://paulbourke.net/dataformats/obj/
|
||||
|
||||
#include "OBJReader.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QIODevice>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QEventLoop>
|
||||
#include <ctype.h> // .obj files are not locale-specific. The C/ASCII charset applies.
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QIODevice>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
|
||||
#include <shared/NsightHelpers.h>
|
||||
#include <NetworkAccessManager.h>
|
||||
|
||||
#include "FBXReader.h"
|
||||
#include "OBJReader.h"
|
||||
#include "ModelFormatLogging.h"
|
||||
|
||||
QHash<QString, float> COMMENT_SCALE_HINTS = {{"This file uses centimeters as units", 1.0f / 100.0f},
|
||||
|
@ -404,7 +407,7 @@ done:
|
|||
|
||||
|
||||
FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url) {
|
||||
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffff0000, nullptr);
|
||||
QBuffer buffer { &model };
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
//
|
||||
#include "GPULogging.h"
|
||||
#include "GLBackendShared.h"
|
||||
#include "GLTexelFormat.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
|
@ -36,369 +37,6 @@ void GLBackend::GLTexture::setSize(GLuint size) {
|
|||
_size = size;
|
||||
}
|
||||
|
||||
class GLTexelFormat {
|
||||
public:
|
||||
GLenum internalFormat;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
|
||||
static GLTexelFormat evalGLTexelFormat(const Element& dstFormat, const Element& srcFormat) {
|
||||
if (dstFormat != srcFormat) {
|
||||
GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
|
||||
|
||||
switch(dstFormat.getDimension()) {
|
||||
case gpu::SCALAR: {
|
||||
texel.format = GL_RED;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RED;
|
||||
break;
|
||||
case gpu::DEPTH:
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT;
|
||||
break;
|
||||
case gpu::DEPTH_STENCIL:
|
||||
texel.type = GL_UNSIGNED_INT_24_8;
|
||||
texel.format = GL_DEPTH_STENCIL;
|
||||
texel.internalFormat = GL_DEPTH24_STENCIL8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC2: {
|
||||
texel.format = GL_RG;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RG;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC3: {
|
||||
texel.format = GL_RGB;
|
||||
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC4: {
|
||||
texel.format = GL_RGBA;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(srcFormat.getSemantic()) {
|
||||
case gpu::BGRA:
|
||||
case gpu::SBGRA:
|
||||
texel.format = GL_BGRA;
|
||||
break;
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGBA;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
texel.internalFormat = GL_SRGB;
|
||||
break;
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB_ALPHA;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
return texel;
|
||||
} else {
|
||||
GLTexelFormat texel = {GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE};
|
||||
|
||||
switch(dstFormat.getDimension()) {
|
||||
case gpu::SCALAR: {
|
||||
texel.format = GL_RED;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_RED;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32: {
|
||||
texel.internalFormat = GL_R32UI;
|
||||
break;
|
||||
}
|
||||
case gpu::INT32: {
|
||||
texel.internalFormat = GL_R32I;
|
||||
break;
|
||||
}
|
||||
case gpu::NUINT32: {
|
||||
texel.internalFormat = GL_RED;
|
||||
break;
|
||||
}
|
||||
case gpu::NINT32: {
|
||||
texel.internalFormat = GL_RED_SNORM;
|
||||
break;
|
||||
}
|
||||
case gpu::FLOAT: {
|
||||
texel.internalFormat = GL_R32F;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT16: {
|
||||
texel.internalFormat = GL_R16UI;
|
||||
break;
|
||||
}
|
||||
case gpu::INT16: {
|
||||
texel.internalFormat = GL_R16I;
|
||||
break;
|
||||
}
|
||||
case gpu::NUINT16: {
|
||||
texel.internalFormat = GL_R16;
|
||||
break;
|
||||
}
|
||||
case gpu::NINT16: {
|
||||
texel.internalFormat = GL_R16_SNORM;
|
||||
break;
|
||||
}
|
||||
case gpu::HALF: {
|
||||
texel.internalFormat = GL_R16F;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT8: {
|
||||
texel.internalFormat = GL_R8UI;
|
||||
break;
|
||||
}
|
||||
case gpu::INT8: {
|
||||
texel.internalFormat = GL_R8I;
|
||||
break;
|
||||
}
|
||||
case gpu::NUINT8: {
|
||||
if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) {
|
||||
texel.internalFormat = GL_SLUMINANCE;
|
||||
} else {
|
||||
texel.internalFormat = GL_R8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gpu::NINT8: {
|
||||
texel.internalFormat = GL_R8_SNORM;
|
||||
break;
|
||||
}
|
||||
case gpu::NUM_TYPES: { // quiet compiler
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case gpu::R11G11B10:
|
||||
texel.format = GL_RGB;
|
||||
// the type should be float
|
||||
texel.internalFormat = GL_R11F_G11F_B10F;
|
||||
break;
|
||||
|
||||
case gpu::DEPTH:
|
||||
texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32:
|
||||
case gpu::INT32:
|
||||
case gpu::NUINT32:
|
||||
case gpu::NINT32: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT32;
|
||||
break;
|
||||
}
|
||||
case gpu::FLOAT: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT32F;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT16:
|
||||
case gpu::INT16:
|
||||
case gpu::NUINT16:
|
||||
case gpu::NINT16:
|
||||
case gpu::HALF: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT16;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT8:
|
||||
case gpu::INT8:
|
||||
case gpu::NUINT8:
|
||||
case gpu::NINT8: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT24;
|
||||
break;
|
||||
}
|
||||
case gpu::NUM_TYPES: { // quiet compiler
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case gpu::DEPTH_STENCIL:
|
||||
texel.type = GL_UNSIGNED_INT_24_8;
|
||||
texel.format = GL_DEPTH_STENCIL;
|
||||
texel.internalFormat = GL_DEPTH24_STENCIL8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC2: {
|
||||
texel.format = GL_RG;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RG;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC3: {
|
||||
texel.format = GL_RGB;
|
||||
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB; // standard 2.2 gamma correction color
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC4: {
|
||||
texel.format = GL_RGBA;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch(dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
texel.internalFormat = GL_RGB;
|
||||
break;
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGBA;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA32UI;
|
||||
break;
|
||||
case gpu::INT32:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA32I;
|
||||
break;
|
||||
case gpu::FLOAT:
|
||||
texel.internalFormat = GL_RGBA32F;
|
||||
break;
|
||||
case gpu::UINT16:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA16UI;
|
||||
break;
|
||||
case gpu::INT16:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA16I;
|
||||
break;
|
||||
case gpu::NUINT16:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA16;
|
||||
break;
|
||||
case gpu::NINT16:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA16_SNORM;
|
||||
break;
|
||||
case gpu::HALF:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA16F;
|
||||
break;
|
||||
case gpu::UINT8:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA8UI;
|
||||
break;
|
||||
case gpu::INT8:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA8I;
|
||||
break;
|
||||
case gpu::NUINT8:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA8;
|
||||
break;
|
||||
case gpu::NINT8:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA8_SNORM;
|
||||
break;
|
||||
case gpu::NUINT32:
|
||||
case gpu::NINT32:
|
||||
case gpu::NUM_TYPES: // quiet compiler
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
texel.internalFormat = GL_SRGB;
|
||||
break;
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB_ALPHA; // standard 2.2 gamma correction color
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
return texel;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
||||
GLTexture* object = Backend::getGPUObject<GLBackend::GLTexture>(texture);
|
||||
|
||||
|
|
372
libraries/gpu/src/gpu/GLTexelFormat.h
Normal file
372
libraries/gpu/src/gpu/GLTexelFormat.h
Normal file
|
@ -0,0 +1,372 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2016/04/03
|
||||
// Copyright 2013-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 "GLBackendShared.h"
|
||||
|
||||
class GLTexelFormat {
|
||||
public:
|
||||
GLenum internalFormat;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
|
||||
static GLTexelFormat evalGLTexelFormat(const gpu::Element& dstFormat, const gpu::Element& srcFormat) {
|
||||
using namespace gpu;
|
||||
if (dstFormat != srcFormat) {
|
||||
GLTexelFormat texel = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE };
|
||||
|
||||
switch (dstFormat.getDimension()) {
|
||||
case gpu::SCALAR: {
|
||||
texel.format = GL_RED;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_R8;
|
||||
break;
|
||||
case gpu::DEPTH:
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT32;
|
||||
break;
|
||||
case gpu::DEPTH_STENCIL:
|
||||
texel.type = GL_UNSIGNED_INT_24_8;
|
||||
texel.format = GL_DEPTH_STENCIL;
|
||||
texel.internalFormat = GL_DEPTH24_STENCIL8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC2: {
|
||||
texel.format = GL_RG;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RG8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC3: {
|
||||
texel.format = GL_RGB;
|
||||
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGB8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC4: {
|
||||
texel.format = GL_RGBA;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (srcFormat.getSemantic()) {
|
||||
case gpu::BGRA:
|
||||
case gpu::SBGRA:
|
||||
texel.format = GL_BGRA;
|
||||
break;
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
texel.internalFormat = GL_RGB8;
|
||||
break;
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGBA8;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
texel.internalFormat = GL_SRGB8;
|
||||
break;
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB8_ALPHA8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
return texel;
|
||||
} else {
|
||||
GLTexelFormat texel = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE };
|
||||
|
||||
switch (dstFormat.getDimension()) {
|
||||
case gpu::SCALAR: {
|
||||
texel.format = GL_RED;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_R8;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32: {
|
||||
texel.internalFormat = GL_R32UI;
|
||||
break;
|
||||
}
|
||||
case gpu::INT32: {
|
||||
texel.internalFormat = GL_R32I;
|
||||
break;
|
||||
}
|
||||
case gpu::NUINT32: {
|
||||
texel.internalFormat = GL_R8;
|
||||
break;
|
||||
}
|
||||
case gpu::NINT32: {
|
||||
texel.internalFormat = GL_R8_SNORM;
|
||||
break;
|
||||
}
|
||||
case gpu::FLOAT: {
|
||||
texel.internalFormat = GL_R32F;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT16: {
|
||||
texel.internalFormat = GL_R16UI;
|
||||
break;
|
||||
}
|
||||
case gpu::INT16: {
|
||||
texel.internalFormat = GL_R16I;
|
||||
break;
|
||||
}
|
||||
case gpu::NUINT16: {
|
||||
texel.internalFormat = GL_R16;
|
||||
break;
|
||||
}
|
||||
case gpu::NINT16: {
|
||||
texel.internalFormat = GL_R16_SNORM;
|
||||
break;
|
||||
}
|
||||
case gpu::HALF: {
|
||||
texel.internalFormat = GL_R16F;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT8: {
|
||||
texel.internalFormat = GL_R8UI;
|
||||
break;
|
||||
}
|
||||
case gpu::INT8: {
|
||||
texel.internalFormat = GL_R8I;
|
||||
break;
|
||||
}
|
||||
case gpu::NUINT8: {
|
||||
if ((dstFormat.getSemantic() == gpu::SRGB || dstFormat.getSemantic() == gpu::SRGBA)) {
|
||||
texel.internalFormat = GL_SLUMINANCE8;
|
||||
} else {
|
||||
texel.internalFormat = GL_R8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case gpu::NINT8: {
|
||||
texel.internalFormat = GL_R8_SNORM;
|
||||
break;
|
||||
}
|
||||
case gpu::NUM_TYPES: { // quiet compiler
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case gpu::R11G11B10:
|
||||
texel.format = GL_RGB;
|
||||
// the type should be float
|
||||
texel.internalFormat = GL_R11F_G11F_B10F;
|
||||
break;
|
||||
|
||||
case gpu::DEPTH:
|
||||
texel.format = GL_DEPTH_COMPONENT; // It's depth component to load it
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT32;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32:
|
||||
case gpu::INT32:
|
||||
case gpu::NUINT32:
|
||||
case gpu::NINT32: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT32;
|
||||
break;
|
||||
}
|
||||
case gpu::FLOAT: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT32F;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT16:
|
||||
case gpu::INT16:
|
||||
case gpu::NUINT16:
|
||||
case gpu::NINT16:
|
||||
case gpu::HALF: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT16;
|
||||
break;
|
||||
}
|
||||
case gpu::UINT8:
|
||||
case gpu::INT8:
|
||||
case gpu::NUINT8:
|
||||
case gpu::NINT8: {
|
||||
texel.internalFormat = GL_DEPTH_COMPONENT24;
|
||||
break;
|
||||
}
|
||||
case gpu::NUM_TYPES: { // quiet compiler
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case gpu::DEPTH_STENCIL:
|
||||
texel.type = GL_UNSIGNED_INT_24_8;
|
||||
texel.format = GL_DEPTH_STENCIL;
|
||||
texel.internalFormat = GL_DEPTH24_STENCIL8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC2: {
|
||||
texel.format = GL_RG;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RG8;
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC3: {
|
||||
texel.format = GL_RGB;
|
||||
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGB8;
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB8; // standard 2.2 gamma correction color
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gpu::VEC4: {
|
||||
texel.format = GL_RGBA;
|
||||
texel.type = _elementTypeToGLType[dstFormat.getType()];
|
||||
|
||||
switch (dstFormat.getSemantic()) {
|
||||
case gpu::RGB:
|
||||
texel.internalFormat = GL_RGB8;
|
||||
break;
|
||||
case gpu::RGBA:
|
||||
texel.internalFormat = GL_RGBA8;
|
||||
switch (dstFormat.getType()) {
|
||||
case gpu::UINT32:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA32UI;
|
||||
break;
|
||||
case gpu::INT32:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA32I;
|
||||
break;
|
||||
case gpu::FLOAT:
|
||||
texel.internalFormat = GL_RGBA32F;
|
||||
break;
|
||||
case gpu::UINT16:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA16UI;
|
||||
break;
|
||||
case gpu::INT16:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA16I;
|
||||
break;
|
||||
case gpu::NUINT16:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA16;
|
||||
break;
|
||||
case gpu::NINT16:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA16_SNORM;
|
||||
break;
|
||||
case gpu::HALF:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA16F;
|
||||
break;
|
||||
case gpu::UINT8:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA8UI;
|
||||
break;
|
||||
case gpu::INT8:
|
||||
texel.format = GL_RGBA_INTEGER;
|
||||
texel.internalFormat = GL_RGBA8I;
|
||||
break;
|
||||
case gpu::NUINT8:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA8;
|
||||
break;
|
||||
case gpu::NINT8:
|
||||
texel.format = GL_RGBA;
|
||||
texel.internalFormat = GL_RGBA8_SNORM;
|
||||
break;
|
||||
case gpu::NUINT32:
|
||||
case gpu::NINT32:
|
||||
case gpu::NUM_TYPES: // quiet compiler
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
break;
|
||||
case gpu::SRGB:
|
||||
texel.internalFormat = GL_SRGB8;
|
||||
break;
|
||||
case gpu::SRGBA:
|
||||
texel.internalFormat = GL_SRGB8_ALPHA8; // standard 2.2 gamma correction color
|
||||
break;
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
qCDebug(gpulogging) << "Unknown combination of texel format";
|
||||
}
|
||||
return texel;
|
||||
}
|
||||
}
|
||||
};
|
|
@ -118,10 +118,8 @@ void GeometryReader::run() {
|
|||
}
|
||||
QThread::currentThread()->setPriority(QThread::LowPriority);
|
||||
|
||||
// Ensure the resource is still being requested
|
||||
auto resource = _resource.toStrongRef();
|
||||
if (!resource) {
|
||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||
if (!_resource.data()) {
|
||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; resource was deleted";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -146,14 +144,28 @@ void GeometryReader::run() {
|
|||
throw QString("unsupported format");
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition",
|
||||
Q_ARG(void*, fbxGeometry));
|
||||
// Ensure the resource has not been deleted, and won't be while invokeMethod is in flight.
|
||||
auto resource = _resource.toStrongRef();
|
||||
if (!resource) {
|
||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||
delete fbxGeometry;
|
||||
} else {
|
||||
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition", Qt::BlockingQueuedConnection, Q_ARG(void*, fbxGeometry));
|
||||
}
|
||||
} else {
|
||||
throw QString("url is invalid");
|
||||
}
|
||||
} catch (const QString& error) {
|
||||
|
||||
qCDebug(modelnetworking) << "Error reading " << _url << ": " << error;
|
||||
QMetaObject::invokeMethod(resource.data(), "finishedLoading", Q_ARG(bool, false));
|
||||
|
||||
auto resource = _resource.toStrongRef();
|
||||
// Ensure the resoruce has not been deleted, and won't be while invokeMethod is in flight.
|
||||
if (!resource) {
|
||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||
} else {
|
||||
QMetaObject::invokeMethod(resource.data(), "finishedLoading", Qt::BlockingQueuedConnection, Q_ARG(bool, false));
|
||||
}
|
||||
}
|
||||
|
||||
QThread::currentThread()->setPriority(originalPriority);
|
||||
|
@ -232,7 +244,7 @@ std::shared_ptr<NetworkGeometry> ModelCache::getGeometry(const QUrl& url, const
|
|||
GeometryExtra geometryExtra = { mapping, textureBaseUrl };
|
||||
GeometryResource::Pointer resource = getResource(url, QUrl(), true, &geometryExtra).staticCast<GeometryResource>();
|
||||
if (resource) {
|
||||
if (resource->isLoaded() && !resource->hasTextures()) {
|
||||
if (resource->isLoaded() && resource->shouldSetTextures()) {
|
||||
resource->setTextures();
|
||||
}
|
||||
return std::make_shared<NetworkGeometry>(resource);
|
||||
|
|
|
@ -107,7 +107,8 @@ protected:
|
|||
friend class GeometryMappingResource;
|
||||
|
||||
// Geometries may not hold onto textures while cached - that is for the texture cache
|
||||
bool hasTextures() const { return !_materials.empty(); }
|
||||
// Instead, these methods clear and reset textures from the geometry when caching/loading
|
||||
bool shouldSetTextures() const { return _geometry && _materials.empty(); }
|
||||
void setTextures();
|
||||
void resetTextures();
|
||||
|
||||
|
|
|
@ -11,19 +11,21 @@
|
|||
|
||||
#include "TextureCache.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QPainter>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
#include <QImageReader>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
|
||||
#include <shared/NsightHelpers.h>
|
||||
|
||||
#include <Finally.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
|
@ -280,6 +282,7 @@ void ImageReader::listSupportedImageFormats() {
|
|||
}
|
||||
|
||||
void ImageReader::run() {
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffff0000, nullptr);
|
||||
auto originalPriority = QThread::currentThread()->priority();
|
||||
if (originalPriority == QThread::InheritPriority) {
|
||||
originalPriority = QThread::NormalPriority;
|
||||
|
@ -326,6 +329,8 @@ void ImageReader::run() {
|
|||
}
|
||||
|
||||
auto url = _url.toString().toStdString();
|
||||
|
||||
PROFILE_RANGE_EX(__FUNCTION__"::textureLoader", 0xffffff00, nullptr);
|
||||
texture = resource.dynamicCast<NetworkTexture>()->getTextureLoader()(image, url);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
void setCubemap(const gpu::TexturePointer& cubemap);
|
||||
const gpu::TexturePointer& getCubemap() const { return _cubemap; }
|
||||
|
||||
virtual void clear() { setCubemap(nullptr); }
|
||||
|
||||
void prepare(gpu::Batch& batch, int textureSlot = SKYBOX_SKYMAP_SLOT, int bufferSlot = SKYBOX_CONSTANTS_SLOT) const;
|
||||
virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const;
|
||||
|
||||
|
|
|
@ -96,6 +96,7 @@ bool Procedural::parseVersion(const QJsonValue& version) {
|
|||
bool Procedural::parseUrl(const QUrl& shaderUrl) {
|
||||
if (!shaderUrl.isValid()) {
|
||||
qWarning() << "Invalid shader URL: " << shaderUrl;
|
||||
_networkShader.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -110,6 +111,7 @@ bool Procedural::parseUrl(const QUrl& shaderUrl) {
|
|||
_shaderPath = _shaderUrl.toLocalFile();
|
||||
qDebug() << "Shader path: " << _shaderPath;
|
||||
if (!QFile(_shaderPath).exists()) {
|
||||
_networkShader.reset();
|
||||
return false;;
|
||||
}
|
||||
} else {
|
||||
|
@ -135,9 +137,14 @@ bool Procedural::parseTextures(const QJsonArray& channels) {
|
|||
|
||||
auto textureCache = DependencyManager::get<TextureCache>();
|
||||
size_t channelCount = std::min(MAX_PROCEDURAL_TEXTURE_CHANNELS, (size_t)_parsedChannels.size());
|
||||
for (size_t i = 0; i < channelCount; ++i) {
|
||||
QString url = _parsedChannels.at((int)i).toString();
|
||||
_channels[i] = textureCache->getTexture(QUrl(url));
|
||||
size_t channel = 0;
|
||||
for (; channel < channelCount; ++channel) {
|
||||
QString url = _parsedChannels.at((int)channel).toString();
|
||||
_channels[channel] = textureCache->getTexture(QUrl(url));
|
||||
}
|
||||
for (; channel < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++channel) {
|
||||
// Release those textures no longer in use
|
||||
_channels[channel] = textureCache->getTexture(QUrl());
|
||||
}
|
||||
|
||||
_channelsDirty = true;
|
||||
|
@ -149,20 +156,21 @@ bool Procedural::parseTextures(const QJsonArray& channels) {
|
|||
void Procedural::parse(const QJsonObject& proceduralData) {
|
||||
_enabled = false;
|
||||
|
||||
if (proceduralData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto version = proceduralData[VERSION_KEY];
|
||||
auto shaderUrl = proceduralData[URL_KEY].toString();
|
||||
shaderUrl = ResourceManager::normalizeURL(shaderUrl);
|
||||
auto uniforms = proceduralData[UNIFORMS_KEY].toObject();
|
||||
auto channels = proceduralData[CHANNELS_KEY].toArray();
|
||||
|
||||
if (parseVersion(version) &&
|
||||
parseUrl(shaderUrl) &&
|
||||
parseUniforms(uniforms) &&
|
||||
parseTextures(channels)) {
|
||||
bool isValid = true;
|
||||
|
||||
// Run through parsing regardless of validity to clear old cached resources
|
||||
isValid = parseVersion(version) && isValid;
|
||||
isValid = parseUrl(shaderUrl) && isValid;
|
||||
isValid = parseUniforms(uniforms) && isValid;
|
||||
isValid = parseTextures(channels) && isValid;
|
||||
|
||||
if (!proceduralData.isEmpty() && isValid) {
|
||||
_enabled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,14 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() {
|
|||
_procedural._state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
|
||||
}
|
||||
|
||||
void ProceduralSkybox::clear() {
|
||||
// Parse and prepare a procedural with no shaders to release textures
|
||||
parse(QString());
|
||||
_procedural.ready();
|
||||
|
||||
Skybox::clear();
|
||||
}
|
||||
|
||||
void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const {
|
||||
if (_procedural.ready()) {
|
||||
ProceduralSkybox::render(batch, frustum, (*this));
|
||||
|
|
|
@ -24,6 +24,8 @@ public:
|
|||
|
||||
void parse(const QString& userData) { _procedural.parse(userData); }
|
||||
|
||||
virtual void clear() override;
|
||||
|
||||
virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const;
|
||||
static void render(gpu::Batch& batch, const ViewFrustum& frustum, const ProceduralSkybox& skybox);
|
||||
|
||||
|
|
|
@ -159,11 +159,13 @@ void Model::updateRenderItems() {
|
|||
Transform collisionMeshOffset;
|
||||
collisionMeshOffset.postTranslate(self->_offset);
|
||||
|
||||
uint32_t deleteGeometryCounter = self->_deleteGeometryCounter;
|
||||
|
||||
render::PendingChanges pendingChanges;
|
||||
foreach (auto itemID, self->_modelMeshRenderItems.keys()) {
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, modelMeshOffset](ModelMeshPartPayload& data) {
|
||||
pendingChanges.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, modelMeshOffset, deleteGeometryCounter](ModelMeshPartPayload& data) {
|
||||
// Ensure the model geometry was not reset between frames
|
||||
if (data._model->isLoaded()) {
|
||||
if (data._model && data._model->isLoaded() && deleteGeometryCounter == data._model->_deleteGeometryCounter) {
|
||||
// lazy update of cluster matrices used for rendering. We need to update them here, so we can correctly update the bounding box.
|
||||
data._model->updateClusterMatrices(modelTransform.getTranslation(), modelTransform.getRotation());
|
||||
|
||||
|
@ -1146,6 +1148,7 @@ void Model::setBlendedVertices(int blendNumber, const std::weak_ptr<NetworkGeome
|
|||
}
|
||||
|
||||
void Model::deleteGeometry() {
|
||||
_deleteGeometryCounter++;
|
||||
_blendedVertexBuffers.clear();
|
||||
_meshStates.clear();
|
||||
_rig->destroyAnimGraph();
|
||||
|
|
|
@ -394,6 +394,8 @@ protected:
|
|||
|
||||
friend class ModelMeshPartPayload;
|
||||
RigPointer _rig;
|
||||
|
||||
uint32_t _deleteGeometryCounter { 0 };
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(ModelPointer)
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
};
|
||||
|
||||
#define PROFILE_RANGE(name) ProfileRange profileRangeThis(name);
|
||||
#define PROFILE_RANGE_EX(name, argbColor, payload) ProfileRange profileRangeThis(name, argbColor, payload);
|
||||
#define PROFILE_RANGE_EX(name, argbColor, payload) ProfileRange profileRangeThis(name, argbColor, (uint64_t)payload);
|
||||
#else
|
||||
#define PROFILE_RANGE(name)
|
||||
#define PROFILE_RANGE_EX(name, argbColor, payload)
|
||||
|
|
Loading…
Reference in a new issue