mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-27 07:58:47 +02:00
Merge branch 'feat/create/interactive-window' into feat/create/native-windows
# Conflicts: # scripts/system/libraries/entityList.js # scripts/system/particle_explorer/particleExplorerTool.js
This commit is contained in:
commit
c583c07d9c
75 changed files with 612 additions and 360 deletions
|
@ -64,6 +64,7 @@ Agent::Agent(ReceivedMessage& message) :
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||||
|
|
||||||
DependencyManager::set<ResourceManager>();
|
DependencyManager::set<ResourceManager>();
|
||||||
|
DependencyManager::set<PluginManager>();
|
||||||
|
|
||||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||||
|
|
||||||
|
@ -833,6 +834,8 @@ void Agent::aboutToFinish() {
|
||||||
|
|
||||||
DependencyManager::get<ResourceManager>()->cleanup();
|
DependencyManager::get<ResourceManager>()->cleanup();
|
||||||
|
|
||||||
|
DependencyManager::destroy<PluginManager>();
|
||||||
|
|
||||||
// cleanup the AudioInjectorManager (and any still running injectors)
|
// cleanup the AudioInjectorManager (and any still running injectors)
|
||||||
DependencyManager::destroy<AudioInjectorManager>();
|
DependencyManager::destroy<AudioInjectorManager>();
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,8 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
|
||||||
|
|
||||||
// hash the available codecs (on the mixer)
|
// hash the available codecs (on the mixer)
|
||||||
_availableCodecs.clear(); // Make sure struct is clean
|
_availableCodecs.clear(); // Make sure struct is clean
|
||||||
auto codecPlugins = PluginManager::getInstance()->getCodecPlugins();
|
auto pluginManager = DependencyManager::set<PluginManager>();
|
||||||
|
auto codecPlugins = pluginManager->getCodecPlugins();
|
||||||
std::for_each(codecPlugins.cbegin(), codecPlugins.cend(),
|
std::for_each(codecPlugins.cbegin(), codecPlugins.cend(),
|
||||||
[&](const CodecPluginPointer& codec) {
|
[&](const CodecPluginPointer& codec) {
|
||||||
_availableCodecs[codec->getName()] = codec;
|
_availableCodecs[codec->getName()] = codec;
|
||||||
|
@ -106,6 +107,10 @@ AudioMixer::AudioMixer(ReceivedMessage& message) :
|
||||||
connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);
|
connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioMixer::aboutToFinish() {
|
||||||
|
DependencyManager::destroy<PluginManager>();
|
||||||
|
}
|
||||||
|
|
||||||
void AudioMixer::queueAudioPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) {
|
void AudioMixer::queueAudioPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node) {
|
||||||
if (message->getType() == PacketType::SilentAudioFrame) {
|
if (message->getType() == PacketType::SilentAudioFrame) {
|
||||||
_numSilentPackets++;
|
_numSilentPackets++;
|
||||||
|
|
|
@ -58,6 +58,9 @@ public:
|
||||||
to.getPublicSocket() != from.getPublicSocket() &&
|
to.getPublicSocket() != from.getPublicSocket() &&
|
||||||
to.getLocalSocket() != from.getLocalSocket();
|
to.getLocalSocket() != from.getLocalSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void aboutToFinish() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void run() override;
|
void run() override;
|
||||||
void sendStatsPacket() override;
|
void sendStatsPacket() override;
|
||||||
|
|
|
@ -58,6 +58,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
||||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||||
|
|
||||||
DependencyManager::set<ResourceManager>();
|
DependencyManager::set<ResourceManager>();
|
||||||
|
DependencyManager::set<PluginManager>();
|
||||||
|
|
||||||
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
DependencyManager::registerInheritance<SpatialParentFinder, AssignmentParentFinder>();
|
||||||
|
|
||||||
|
@ -572,6 +573,8 @@ void EntityScriptServer::aboutToFinish() {
|
||||||
|
|
||||||
DependencyManager::get<ResourceManager>()->cleanup();
|
DependencyManager::get<ResourceManager>()->cleanup();
|
||||||
|
|
||||||
|
DependencyManager::destroy<PluginManager>();
|
||||||
|
|
||||||
// cleanup the AudioInjectorManager (and any still running injectors)
|
// cleanup the AudioInjectorManager (and any still running injectors)
|
||||||
DependencyManager::destroy<AudioInjectorManager>();
|
DependencyManager::destroy<AudioInjectorManager>();
|
||||||
DependencyManager::destroy<ScriptEngines>();
|
DependencyManager::destroy<ScriptEngines>();
|
||||||
|
|
|
@ -22,7 +22,7 @@ macro(optional_win_executable_signing)
|
||||||
# setup a post build command to sign the executable
|
# setup a post build command to sign the executable
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${TARGET_NAME} POST_BUILD
|
TARGET ${TARGET_NAME} POST_BUILD
|
||||||
COMMAND ${SIGNTOOL_EXECUTABLE} sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 ${EXECUTABLE_PATH}
|
COMMAND ${SIGNTOOL_EXECUTABLE} sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 ${EXECUTABLE_PATH}
|
||||||
)
|
)
|
||||||
else ()
|
else ()
|
||||||
message(FATAL_ERROR "HF_PFX_PASSPHRASE must be set for executables to be signed.")
|
message(FATAL_ERROR "HF_PFX_PASSPHRASE must be set for executables to be signed.")
|
||||||
|
|
|
@ -130,7 +130,7 @@
|
||||||
; The Inner invocation has written an uninstaller binary for us.
|
; The Inner invocation has written an uninstaller binary for us.
|
||||||
; We need to sign it if it's a production or PR build.
|
; We need to sign it if it's a production or PR build.
|
||||||
!if @PRODUCTION_BUILD@ == 1
|
!if @PRODUCTION_BUILD@ == 1
|
||||||
!system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://tsa.starfieldtech.com /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0
|
!system '"@SIGNTOOL_EXECUTABLE@" sign /fd sha256 /f %HF_PFX_FILE% /p %HF_PFX_PASSPHRASE% /tr http://sha256timestamp.ws.symantec.com/sha256/timestamp /td SHA256 $%TEMP%\@UNINSTALLER_NAME@' = 0
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
; Good. Now we can carry on writing the real installer.
|
; Good. Now we can carry on writing the real installer.
|
||||||
|
|
|
@ -28,6 +28,8 @@ Windows.Window {
|
||||||
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
|
||||||
destroyOnCloseButton: false;
|
destroyOnCloseButton: false;
|
||||||
|
|
||||||
|
signal selfDestruct();
|
||||||
|
|
||||||
property var flags: 0;
|
property var flags: 0;
|
||||||
|
|
||||||
property var source;
|
property var source;
|
||||||
|
@ -67,10 +69,16 @@ Windows.Window {
|
||||||
x = interactiveWindowPosition.x;
|
x = interactiveWindowPosition.x;
|
||||||
y = interactiveWindowPosition.y;
|
y = interactiveWindowPosition.y;
|
||||||
} else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
|
} else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) {
|
||||||
|
if (interactiveWindowPosition.x === 0 && interactiveWindowPosition.y === 0) {
|
||||||
|
// default position for native window in center of main application window
|
||||||
|
nativeWindow.x = Math.floor(Window.x + (Window.innerWidth / 2) - (interactiveWindowSize.width / 2));
|
||||||
|
nativeWindow.y = Math.floor(Window.y + (Window.innerHeight / 2) - (interactiveWindowSize.height / 2));
|
||||||
|
} else {
|
||||||
nativeWindow.x = interactiveWindowPosition.x;
|
nativeWindow.x = interactiveWindowPosition.x;
|
||||||
nativeWindow.y = interactiveWindowPosition.y;
|
nativeWindow.y = interactiveWindowPosition.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateInteractiveWindowSizeForMode() {
|
function updateInteractiveWindowSizeForMode() {
|
||||||
if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
|
if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
|
||||||
|
@ -83,7 +91,6 @@ Windows.Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupPresentationMode() {
|
function setupPresentationMode() {
|
||||||
console.warn(presentationMode);
|
|
||||||
if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
|
if (presentationMode === Desktop.PresentationMode.VIRTUAL) {
|
||||||
if (nativeWindow) {
|
if (nativeWindow) {
|
||||||
nativeWindow.setVisible(false);
|
nativeWindow.setVisible(false);
|
||||||
|
@ -104,7 +111,6 @@ Windows.Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
||||||
x = interactiveWindowPosition.x;
|
x = interactiveWindowPosition.x;
|
||||||
y = interactiveWindowPosition.y;
|
y = interactiveWindowPosition.y;
|
||||||
width = interactiveWindowSize.width;
|
width = interactiveWindowSize.width;
|
||||||
|
@ -161,6 +167,11 @@ Windows.Window {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
nativeWindow.closing.connect(function(closeEvent) {
|
||||||
|
closeEvent.accepted = false;
|
||||||
|
windowClosed();
|
||||||
|
});
|
||||||
|
|
||||||
// finally set the initial window mode:
|
// finally set the initial window mode:
|
||||||
setupPresentationMode();
|
setupPresentationMode();
|
||||||
|
|
||||||
|
@ -243,10 +254,10 @@ Windows.Window {
|
||||||
onWindowClosed: {
|
onWindowClosed: {
|
||||||
// set invisible on close, to make it not re-appear unintended after switching PresentationMode
|
// set invisible on close, to make it not re-appear unintended after switching PresentationMode
|
||||||
interactiveWindowVisible = false;
|
interactiveWindowVisible = false;
|
||||||
}
|
|
||||||
|
|
||||||
onWindowDestroyed: {
|
if ((flags & Desktop.CLOSE_BUTTON_HIDES) !== Desktop.CLOSE_BUTTON_HIDES) {
|
||||||
console.warn("destroyed");
|
selfDestruct();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
|
@ -135,6 +135,8 @@ Item {
|
||||||
|
|
||||||
placeholderText: qsTr("Password")
|
placeholderText: qsTr("Password")
|
||||||
echoMode: TextInput.Password
|
echoMode: TextInput.Password
|
||||||
|
|
||||||
|
Keys.onReturnPressed: linkAccountBody.login()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,8 @@ Item {
|
||||||
root.text = "";
|
root.text = "";
|
||||||
root.isPassword = true;
|
root.isPassword = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: linkAccountBody.login()
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
|
|
@ -164,6 +164,8 @@ Item {
|
||||||
root.text = "";
|
root.text = "";
|
||||||
root.isPassword = focus
|
root.isPassword = focus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: signupBody.signup()
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
|
|
@ -56,8 +56,8 @@ Preference {
|
||||||
id: slider
|
id: slider
|
||||||
value: preference.value
|
value: preference.value
|
||||||
width: 100
|
width: 100
|
||||||
minimumValue: MyAvatar.getDomainMinScale()
|
minimumValue: preference.min
|
||||||
maximumValue: MyAvatar.getDomainMaxScale()
|
maximumValue: preference.max
|
||||||
stepSize: preference.step
|
stepSize: preference.step
|
||||||
onValueChanged: {
|
onValueChanged: {
|
||||||
spinner.realValue = value
|
spinner.realValue = value
|
||||||
|
@ -74,8 +74,8 @@ Preference {
|
||||||
id: spinner
|
id: spinner
|
||||||
decimals: preference.decimals
|
decimals: preference.decimals
|
||||||
realValue: preference.value
|
realValue: preference.value
|
||||||
minimumValue: MyAvatar.getDomainMinScale()
|
minimumValue: preference.min
|
||||||
maximumValue: MyAvatar.getDomainMaxScale()
|
maximumValue: preference.max
|
||||||
width: 100
|
width: 100
|
||||||
onValueChanged: {
|
onValueChanged: {
|
||||||
slider.value = realValue;
|
slider.value = realValue;
|
||||||
|
|
|
@ -129,12 +129,10 @@ Rectangle {
|
||||||
id: stereoMic
|
id: stereoMic
|
||||||
spacing: muteMic.spacing;
|
spacing: muteMic.spacing;
|
||||||
text: qsTr("Enable stereo input");
|
text: qsTr("Enable stereo input");
|
||||||
checked: AudioScriptingInterface.isStereoInput();
|
checked: AudioScriptingInterface.isStereoInput;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var success = AudioScriptingInterface.setStereoInput(checked);
|
AudioScriptingInterface.isStereoInput = checked;
|
||||||
if (!success) {
|
checked = Qt.binding(function() { return AudioScriptingInterface.isStereoInput; }); // restore binding
|
||||||
checked = !checked;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,9 +92,9 @@ Rectangle {
|
||||||
|
|
||||||
onBuyResult: {
|
onBuyResult: {
|
||||||
if (result.status !== 'success') {
|
if (result.status !== 'success') {
|
||||||
failureErrorText.text = result.message;
|
failureErrorText.text = result.data.message;
|
||||||
root.activeView = "checkoutFailure";
|
root.activeView = "checkoutFailure";
|
||||||
UserActivityLogger.commercePurchaseFailure(root.itemId, root.itemAuthor, root.itemPrice, !root.alreadyOwned, result.message);
|
UserActivityLogger.commercePurchaseFailure(root.itemId, root.itemAuthor, root.itemPrice, !root.alreadyOwned, result.data.message);
|
||||||
} else {
|
} else {
|
||||||
root.certificateId = result.data.certificate_id;
|
root.certificateId = result.data.certificate_id;
|
||||||
root.itemHref = result.data.download_url;
|
root.itemHref = result.data.download_url;
|
||||||
|
|
|
@ -17,7 +17,7 @@ PreferencesDialog {
|
||||||
id: root
|
id: root
|
||||||
objectName: "GeneralPreferencesDialog"
|
objectName: "GeneralPreferencesDialog"
|
||||||
title: "General Settings"
|
title: "General Settings"
|
||||||
showCategories: ["User Interface", "HMD", "Snapshots", "Privacy"]
|
showCategories: ["User Interface", "Mouse Sensitivity", "HMD", "Snapshots", "Privacy"]
|
||||||
property var settings: Settings {
|
property var settings: Settings {
|
||||||
category: root.objectName
|
category: root.objectName
|
||||||
property alias x: root.x
|
property alias x: root.x
|
||||||
|
|
|
@ -32,6 +32,6 @@ StackView {
|
||||||
TabletPreferencesDialog {
|
TabletPreferencesDialog {
|
||||||
id: root
|
id: root
|
||||||
objectName: "TabletGeneralPreferences"
|
objectName: "TabletGeneralPreferences"
|
||||||
showCategories: ["User Interface", "HMD", "Snapshots", "Privacy"]
|
showCategories: ["User Interface", "Mouse Sensitivity", "HMD", "Snapshots", "Privacy"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,9 +270,6 @@ public:
|
||||||
}
|
}
|
||||||
_renderContext->doneCurrent();
|
_renderContext->doneCurrent();
|
||||||
|
|
||||||
// Deleting the object with automatically shutdown the thread
|
|
||||||
connect(qApp, &QCoreApplication::aboutToQuit, this, &QObject::deleteLater);
|
|
||||||
|
|
||||||
// Transfer to a new thread
|
// Transfer to a new thread
|
||||||
moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) {
|
moveToNewNamedThread(this, "RenderThread", [this](QThread* renderThread) {
|
||||||
hifi::qt::addBlockingForbiddenThread("Render", renderThread);
|
hifi::qt::addBlockingForbiddenThread("Render", renderThread);
|
||||||
|
@ -815,6 +812,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the plugin manager about our statically linked plugins
|
// Tell the plugin manager about our statically linked plugins
|
||||||
|
DependencyManager::set<PluginManager>();
|
||||||
auto pluginManager = PluginManager::getInstance();
|
auto pluginManager = PluginManager::getInstance();
|
||||||
pluginManager->setInputPluginProvider([] { return getInputPlugins(); });
|
pluginManager->setInputPluginProvider([] { return getInputPlugins(); });
|
||||||
pluginManager->setDisplayPluginProvider([] { return getDisplayPlugins(); });
|
pluginManager->setDisplayPluginProvider([] { return getDisplayPlugins(); });
|
||||||
|
@ -1379,6 +1377,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
initializeRenderEngine();
|
initializeRenderEngine();
|
||||||
qCDebug(interfaceapp, "Initialized Render Engine.");
|
qCDebug(interfaceapp, "Initialized Render Engine.");
|
||||||
|
|
||||||
|
// Overlays need to exist before we set the ContextOverlayInterface dependency
|
||||||
|
_overlays.init(); // do this before scripts load
|
||||||
|
DependencyManager::set<ContextOverlayInterface>();
|
||||||
|
|
||||||
// Initialize the user interface and menu system
|
// Initialize the user interface and menu system
|
||||||
// Needs to happen AFTER the render engine initialization to access its configuration
|
// Needs to happen AFTER the render engine initialization to access its configuration
|
||||||
initializeUi();
|
initializeUi();
|
||||||
|
@ -1515,10 +1517,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
// allow you to move an entity around in your hand
|
// allow you to move an entity around in your hand
|
||||||
_entityEditSender.setPacketsPerSecond(3000); // super high!!
|
_entityEditSender.setPacketsPerSecond(3000); // super high!!
|
||||||
|
|
||||||
// Overlays need to exist before we set the ContextOverlayInterface dependency
|
|
||||||
_overlays.init(); // do this before scripts load
|
|
||||||
DependencyManager::set<ContextOverlayInterface>();
|
|
||||||
|
|
||||||
// Make sure we don't time out during slow operations at startup
|
// Make sure we don't time out during slow operations at startup
|
||||||
updateHeartbeat();
|
updateHeartbeat();
|
||||||
|
|
||||||
|
@ -2556,25 +2554,28 @@ Application::~Application() {
|
||||||
_octreeProcessor.terminate();
|
_octreeProcessor.terminate();
|
||||||
_entityEditSender.terminate();
|
_entityEditSender.terminate();
|
||||||
|
|
||||||
|
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
||||||
|
steamClient->shutdown();
|
||||||
|
}
|
||||||
|
DependencyManager::destroy<PluginManager>();
|
||||||
|
|
||||||
|
DependencyManager::destroy<CompositorHelper>(); // must be destroyed before the FramebufferCache
|
||||||
|
|
||||||
DependencyManager::destroy<AvatarManager>();
|
DependencyManager::destroy<AvatarManager>();
|
||||||
DependencyManager::destroy<AnimationCache>();
|
DependencyManager::destroy<AnimationCache>();
|
||||||
DependencyManager::destroy<FramebufferCache>();
|
DependencyManager::destroy<FramebufferCache>();
|
||||||
DependencyManager::destroy<TextureCache>();
|
DependencyManager::destroy<TextureCache>();
|
||||||
DependencyManager::destroy<ModelCache>();
|
DependencyManager::destroy<ModelCache>();
|
||||||
DependencyManager::destroy<GeometryCache>();
|
|
||||||
DependencyManager::destroy<ScriptCache>();
|
DependencyManager::destroy<ScriptCache>();
|
||||||
DependencyManager::destroy<SoundCache>();
|
DependencyManager::destroy<SoundCache>();
|
||||||
DependencyManager::destroy<OctreeStatsProvider>();
|
DependencyManager::destroy<OctreeStatsProvider>();
|
||||||
|
DependencyManager::destroy<GeometryCache>();
|
||||||
|
|
||||||
DependencyManager::get<ResourceManager>()->cleanup();
|
DependencyManager::get<ResourceManager>()->cleanup();
|
||||||
|
|
||||||
// remove the NodeList from the DependencyManager
|
// remove the NodeList from the DependencyManager
|
||||||
DependencyManager::destroy<NodeList>();
|
DependencyManager::destroy<NodeList>();
|
||||||
|
|
||||||
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
|
||||||
steamClient->shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
ConnexionClient::getInstance().destroy();
|
ConnexionClient::getInstance().destroy();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2594,6 +2595,8 @@ Application::~Application() {
|
||||||
|
|
||||||
// Can't log to file passed this point, FileLogger about to be deleted
|
// Can't log to file passed this point, FileLogger about to be deleted
|
||||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||||
|
|
||||||
|
_renderEventHandler->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::initializeGL() {
|
void Application::initializeGL() {
|
||||||
|
@ -2720,7 +2723,7 @@ void Application::initializeDisplayPlugins() {
|
||||||
setDisplayPlugin(defaultDisplayPlugin);
|
setDisplayPlugin(defaultDisplayPlugin);
|
||||||
|
|
||||||
// Now set the desired plugin if it's not the same as the default plugin
|
// Now set the desired plugin if it's not the same as the default plugin
|
||||||
if (targetDisplayPlugin != defaultDisplayPlugin) {
|
if (!targetDisplayPlugin && (targetDisplayPlugin != defaultDisplayPlugin)) {
|
||||||
setDisplayPlugin(targetDisplayPlugin);
|
setDisplayPlugin(targetDisplayPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2894,6 +2897,7 @@ void Application::initializeUi() {
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
|
connect(compositorHelper.data(), &CompositorHelper::allowMouseCaptureChanged, this, [=] {
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
|
auto compositorHelper = DependencyManager::get<CompositorHelper>(); // don't capture outer smartpointer
|
||||||
showCursor(compositorHelper->getAllowMouseCapture() ?
|
showCursor(compositorHelper->getAllowMouseCapture() ?
|
||||||
Cursor::Manager::lookupIcon(_preferredCursor.get()) :
|
Cursor::Manager::lookupIcon(_preferredCursor.get()) :
|
||||||
Cursor::Icon::SYSTEM);
|
Cursor::Icon::SYSTEM);
|
||||||
|
|
|
@ -139,7 +139,10 @@ void Application::paintGL() {
|
||||||
frame->frameIndex = _renderFrameCount;
|
frame->frameIndex = _renderFrameCount;
|
||||||
frame->framebuffer = finalFramebuffer;
|
frame->framebuffer = finalFramebuffer;
|
||||||
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) {
|
||||||
DependencyManager::get<FramebufferCache>()->releaseFramebuffer(framebuffer);
|
auto frameBufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
|
if (frameBufferCache) {
|
||||||
|
frameBufferCache->releaseFramebuffer(framebuffer);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// deliver final scene rendering commands to the display plugin
|
// deliver final scene rendering commands to the display plugin
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,13 +36,13 @@
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include <UsersScriptingInterface.h>
|
#include <UsersScriptingInterface.h>
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
#include <avatars-renderer/OtherAvatar.h>
|
|
||||||
#include <shared/ConicalViewFrustum.h>
|
#include <shared/ConicalViewFrustum.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "MyAvatar.h"
|
#include "MyAvatar.h"
|
||||||
|
#include "OtherAvatar.h"
|
||||||
#include "SceneScriptingInterface.h"
|
#include "SceneScriptingInterface.h"
|
||||||
|
|
||||||
// 50 times per second - target is 45hz, but this helps account for any small deviations
|
// 50 times per second - target is 45hz, but this helps account for any small deviations
|
||||||
|
@ -192,6 +192,15 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
while (!sortedAvatars.empty()) {
|
while (!sortedAvatars.empty()) {
|
||||||
const SortableAvatar& sortData = sortedAvatars.top();
|
const SortableAvatar& sortData = sortedAvatars.top();
|
||||||
const auto avatar = std::static_pointer_cast<Avatar>(sortData.getAvatar());
|
const auto avatar = std::static_pointer_cast<Avatar>(sortData.getAvatar());
|
||||||
|
const auto otherAvatar = std::static_pointer_cast<OtherAvatar>(sortData.getAvatar());
|
||||||
|
|
||||||
|
// if the geometry is loaded then turn off the orb
|
||||||
|
if (avatar->getSkeletonModel()->isLoaded()) {
|
||||||
|
// remove the orb if it is there
|
||||||
|
otherAvatar->removeOrb();
|
||||||
|
} else {
|
||||||
|
otherAvatar->updateOrbPosition();
|
||||||
|
}
|
||||||
|
|
||||||
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
|
bool ignoring = DependencyManager::get<NodeList>()->isPersonalMutingNode(avatar->getID());
|
||||||
if (ignoring) {
|
if (ignoring) {
|
||||||
|
|
|
@ -1098,7 +1098,6 @@ void MyAvatar::saveData() {
|
||||||
settings.setValue("displayName", _displayName);
|
settings.setValue("displayName", _displayName);
|
||||||
settings.setValue("collisionSoundURL", _collisionSoundURL);
|
settings.setValue("collisionSoundURL", _collisionSoundURL);
|
||||||
settings.setValue("useSnapTurn", _useSnapTurn);
|
settings.setValue("useSnapTurn", _useSnapTurn);
|
||||||
settings.setValue("clearOverlayWhenMoving", _clearOverlayWhenMoving);
|
|
||||||
settings.setValue("userHeight", getUserHeight());
|
settings.setValue("userHeight", getUserHeight());
|
||||||
settings.setValue("enabledFlying", getFlyingEnabled());
|
settings.setValue("enabledFlying", getFlyingEnabled());
|
||||||
|
|
||||||
|
@ -1254,7 +1253,6 @@ void MyAvatar::loadData() {
|
||||||
setDisplayName(settings.value("displayName").toString());
|
setDisplayName(settings.value("displayName").toString());
|
||||||
setCollisionSoundURL(settings.value("collisionSoundURL", DEFAULT_AVATAR_COLLISION_SOUND_URL).toString());
|
setCollisionSoundURL(settings.value("collisionSoundURL", DEFAULT_AVATAR_COLLISION_SOUND_URL).toString());
|
||||||
setSnapTurn(settings.value("useSnapTurn", _useSnapTurn).toBool());
|
setSnapTurn(settings.value("useSnapTurn", _useSnapTurn).toBool());
|
||||||
setClearOverlayWhenMoving(settings.value("clearOverlayWhenMoving", _clearOverlayWhenMoving).toBool());
|
|
||||||
setDominantHand(settings.value("dominantHand", _dominantHand).toString().toLower());
|
setDominantHand(settings.value("dominantHand", _dominantHand).toString().toLower());
|
||||||
setUserHeight(settings.value("userHeight", DEFAULT_AVATAR_HEIGHT).toDouble());
|
setUserHeight(settings.value("userHeight", DEFAULT_AVATAR_HEIGHT).toDouble());
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
|
|
@ -250,7 +250,7 @@ public:
|
||||||
Q_ENUM(DriveKeys)
|
Q_ENUM(DriveKeys)
|
||||||
|
|
||||||
explicit MyAvatar(QThread* thread);
|
explicit MyAvatar(QThread* thread);
|
||||||
~MyAvatar();
|
virtual ~MyAvatar();
|
||||||
|
|
||||||
void instantiableAvatar() override {};
|
void instantiableAvatar() override {};
|
||||||
void registerMetaTypes(ScriptEnginePointer engine);
|
void registerMetaTypes(ScriptEnginePointer engine);
|
||||||
|
@ -469,16 +469,6 @@ public:
|
||||||
* @param {boolean} on
|
* @param {boolean} on
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; }
|
Q_INVOKABLE void setSnapTurn(bool on) { _useSnapTurn = on; }
|
||||||
/**jsdoc
|
|
||||||
* @function MyAvatar.getClearOverlayWhenMoving
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
Q_INVOKABLE bool getClearOverlayWhenMoving() const { return _clearOverlayWhenMoving; }
|
|
||||||
/**jsdoc
|
|
||||||
* @function MyAvatar.setClearOverlayWhenMoving
|
|
||||||
* @param {boolean} on
|
|
||||||
*/
|
|
||||||
Q_INVOKABLE void setClearOverlayWhenMoving(bool on) { _clearOverlayWhenMoving = on; }
|
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -1496,7 +1486,6 @@ private:
|
||||||
ThreadSafeValueCache<QUrl> _prefOverrideAnimGraphUrl;
|
ThreadSafeValueCache<QUrl> _prefOverrideAnimGraphUrl;
|
||||||
QUrl _fstAnimGraphOverrideUrl;
|
QUrl _fstAnimGraphOverrideUrl;
|
||||||
bool _useSnapTurn { true };
|
bool _useSnapTurn { true };
|
||||||
bool _clearOverlayWhenMoving { true };
|
|
||||||
QString _dominantHand { DOMINANT_RIGHT_HAND };
|
QString _dominantHand { DOMINANT_RIGHT_HAND };
|
||||||
|
|
||||||
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // degrees
|
const float ROLL_CONTROL_DEAD_ZONE_DEFAULT = 8.0f; // degrees
|
||||||
|
|
60
interface/src/avatar/OtherAvatar.cpp
Normal file
60
interface/src/avatar/OtherAvatar.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2017/04/27
|
||||||
|
// Copyright 2013-2017 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 "OtherAvatar.h"
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
|
OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) {
|
||||||
|
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||||
|
_headData = new Head(this);
|
||||||
|
_skeletonModel = std::make_shared<SkeletonModel>(this, nullptr);
|
||||||
|
_skeletonModel->setLoadingPriority(OTHERAVATAR_LOADING_PRIORITY);
|
||||||
|
connect(_skeletonModel.get(), &Model::setURLFinished, this, &Avatar::setModelURLFinished);
|
||||||
|
connect(_skeletonModel.get(), &Model::rigReady, this, &Avatar::rigReady);
|
||||||
|
connect(_skeletonModel.get(), &Model::rigReset, this, &Avatar::rigReset);
|
||||||
|
|
||||||
|
// add the purple orb
|
||||||
|
createOrb();
|
||||||
|
}
|
||||||
|
|
||||||
|
OtherAvatar::~OtherAvatar() {
|
||||||
|
removeOrb();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OtherAvatar::removeOrb() {
|
||||||
|
if (qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) {
|
||||||
|
qApp->getOverlays().deleteOverlay(_otherAvatarOrbMeshPlaceholderID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OtherAvatar::updateOrbPosition() {
|
||||||
|
if (_otherAvatarOrbMeshPlaceholder != nullptr) {
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setWorldPosition(getHead()->getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OtherAvatar::createOrb() {
|
||||||
|
if (_otherAvatarOrbMeshPlaceholderID == UNKNOWN_OVERLAY_ID ||
|
||||||
|
!qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) {
|
||||||
|
_otherAvatarOrbMeshPlaceholder = std::make_shared<Sphere3DOverlay>();
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setAlpha(1.0f);
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setColor({ 0xFF, 0x00, 0xFF });
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setIsSolid(false);
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setPulseMin(0.5);
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setPulseMax(1.0);
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setColorPulse(1.0);
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setIgnoreRayIntersection(true);
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setDrawInFront(false);
|
||||||
|
_otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder);
|
||||||
|
// Position focus
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setWorldOrientation(glm::quat(0.0f, 0.0f, 0.0f, 1.0));
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setWorldPosition(getHead()->getPosition());
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setDimensions(glm::vec3(0.5f, 0.5f, 0.5f));
|
||||||
|
_otherAvatarOrbMeshPlaceholder->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
32
interface/src/avatar/OtherAvatar.h
Normal file
32
interface/src/avatar/OtherAvatar.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2017/04/27
|
||||||
|
// Copyright 2013-2017 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_OtherAvatar_h
|
||||||
|
#define hifi_OtherAvatar_h
|
||||||
|
|
||||||
|
#include <avatars-renderer/Avatar.h>
|
||||||
|
#include "ui/overlays/Overlays.h"
|
||||||
|
#include "ui/overlays/Sphere3DOverlay.h"
|
||||||
|
#include "InterfaceLogging.h"
|
||||||
|
|
||||||
|
class OtherAvatar : public Avatar {
|
||||||
|
public:
|
||||||
|
explicit OtherAvatar(QThread* thread);
|
||||||
|
virtual ~OtherAvatar();
|
||||||
|
|
||||||
|
virtual void instantiableAvatar() override { };
|
||||||
|
virtual void createOrb() override;
|
||||||
|
void updateOrbPosition();
|
||||||
|
void removeOrb();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::shared_ptr<Sphere3DOverlay> _otherAvatarOrbMeshPlaceholder { nullptr };
|
||||||
|
OverlayID _otherAvatarOrbMeshPlaceholderID { UNKNOWN_OVERLAY_ID };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_OtherAvatar_h
|
|
@ -35,5 +35,8 @@ QVariant SettingsScriptingInterface::getValue(const QString& setting, const QVar
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsScriptingInterface::setValue(const QString& setting, const QVariant& value) {
|
void SettingsScriptingInterface::setValue(const QString& setting, const QVariant& value) {
|
||||||
Setting::Handle<QVariant>(setting).set(value);
|
// Make a deep-copy of the string.
|
||||||
|
// Dangling pointers can occur with QStrings that are implicitly shared from a QScriptEngine.
|
||||||
|
QString deepCopy = QString::fromUtf16(setting.utf16());
|
||||||
|
Setting::Handle<QVariant>(deepCopy).set(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,38 +88,24 @@ void OverlayConductor::update(float dt) {
|
||||||
_hmdMode = false;
|
_hmdMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isAtRest = updateAvatarIsAtRest();
|
|
||||||
bool isMoving = !isAtRest;
|
|
||||||
|
|
||||||
bool shouldRecenter = false;
|
bool shouldRecenter = false;
|
||||||
|
|
||||||
if (_flags & SuppressedByMove) {
|
if (_suppressedByHead) {
|
||||||
if (!isMoving) {
|
if (updateAvatarIsAtRest()) {
|
||||||
_flags &= ~SuppressedByMove;
|
_suppressedByHead = false;
|
||||||
shouldRecenter = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (myAvatar->getClearOverlayWhenMoving() && isMoving) {
|
|
||||||
_flags |= SuppressedByMove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_flags & SuppressedByHead) {
|
|
||||||
if (isAtRest) {
|
|
||||||
_flags &= ~SuppressedByHead;
|
|
||||||
shouldRecenter = true;
|
shouldRecenter = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_hmdMode && headOutsideOverlay()) {
|
if (_hmdMode && headOutsideOverlay()) {
|
||||||
_flags |= SuppressedByHead;
|
_suppressedByHead = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && (0 == (_flags & SuppressMask));
|
bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && !_suppressedByHead;
|
||||||
if (targetVisible != currentVisible) {
|
if (targetVisible != currentVisible) {
|
||||||
offscreenUi->setPinned(!targetVisible);
|
offscreenUi->setPinned(!targetVisible);
|
||||||
}
|
}
|
||||||
if (shouldRecenter && !_flags) {
|
if (shouldRecenter && !_suppressedByHead) {
|
||||||
centerUI();
|
centerUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,7 @@ private:
|
||||||
bool headOutsideOverlay() const;
|
bool headOutsideOverlay() const;
|
||||||
bool updateAvatarIsAtRest();
|
bool updateAvatarIsAtRest();
|
||||||
|
|
||||||
enum SupressionFlags {
|
bool _suppressedByHead { false };
|
||||||
SuppressedByMove = 0x01,
|
|
||||||
SuppressedByHead = 0x02,
|
|
||||||
SuppressMask = 0x03,
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t _flags { SuppressedByMove };
|
|
||||||
bool _hmdMode { false };
|
bool _hmdMode { false };
|
||||||
|
|
||||||
// used by updateAvatarIsAtRest
|
// used by updateAvatarIsAtRest
|
||||||
|
|
|
@ -161,12 +161,6 @@ void setupPreferences() {
|
||||||
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use reticle cursor instead of arrow", getter, setter));
|
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Use reticle cursor instead of arrow", getter, setter));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
auto getter = [=]()->bool { return myAvatar->getClearOverlayWhenMoving(); };
|
|
||||||
auto setter = [=](bool value) { myAvatar->setClearOverlayWhenMoving(value); };
|
|
||||||
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Clear overlays when moving", getter, setter));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const QString VIEW_CATEGORY{ "View" };
|
static const QString VIEW_CATEGORY{ "View" };
|
||||||
{
|
{
|
||||||
auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); };
|
auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); };
|
||||||
|
@ -233,6 +227,8 @@ void setupPreferences() {
|
||||||
auto getter = [=]()->float { return myAvatar->getTargetScale(); };
|
auto getter = [=]()->float { return myAvatar->getTargetScale(); };
|
||||||
auto setter = [=](float value) { myAvatar->setTargetScale(value); };
|
auto setter = [=](float value) { myAvatar->setTargetScale(value); };
|
||||||
auto preference = new SpinnerSliderPreference(AVATAR_TUNING, "Avatar Scale", getter, setter);
|
auto preference = new SpinnerSliderPreference(AVATAR_TUNING, "Avatar Scale", getter, setter);
|
||||||
|
preference->setMin(0.25);
|
||||||
|
preference->setMax(4);
|
||||||
preference->setStep(0.05f);
|
preference->setStep(0.05f);
|
||||||
preference->setDecimals(2);
|
preference->setDecimals(2);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
|
@ -309,17 +305,21 @@ void setupPreferences() {
|
||||||
{
|
{
|
||||||
auto getter = [=]()->float { return myAvatar->getPitchSpeed(); };
|
auto getter = [=]()->float { return myAvatar->getPitchSpeed(); };
|
||||||
auto setter = [=](float value) { myAvatar->setPitchSpeed(value); };
|
auto setter = [=](float value) { myAvatar->setPitchSpeed(value); };
|
||||||
auto preference = new SpinnerPreference(AVATAR_CAMERA, "Pitch speed (degrees/second)", getter, setter);
|
auto preference = new SpinnerSliderPreference(AVATAR_CAMERA, "Y input:", getter, setter);
|
||||||
preference->setMin(1.0f);
|
preference->setMin(1.0f);
|
||||||
preference->setMax(360.0f);
|
preference->setMax(360.0f);
|
||||||
|
preference->setStep(1);
|
||||||
|
preference->setDecimals(1);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto getter = [=]()->float { return myAvatar->getYawSpeed(); };
|
auto getter = [=]()->float { return myAvatar->getYawSpeed(); };
|
||||||
auto setter = [=](float value) { myAvatar->setYawSpeed(value); };
|
auto setter = [=](float value) { myAvatar->setYawSpeed(value); };
|
||||||
auto preference = new SpinnerPreference(AVATAR_CAMERA, "Yaw speed (degrees/second)", getter, setter);
|
auto preference = new SpinnerSliderPreference(AVATAR_CAMERA, "X input:", getter, setter);
|
||||||
preference->setMin(1.0f);
|
preference->setMin(1.0f);
|
||||||
preference->setMax(360.0f);
|
preference->setMax(360.0f);
|
||||||
|
preference->setStep(1);
|
||||||
|
preference->setDecimals(1);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1426,6 +1426,8 @@ bool AudioClient::setIsStereoInput(bool isStereoInput) {
|
||||||
|
|
||||||
// restart the input device
|
// restart the input device
|
||||||
switchInputToAudioDevice(_inputDeviceInfo);
|
switchInputToAudioDevice(_inputDeviceInfo);
|
||||||
|
|
||||||
|
emit isStereoInputChanged(_isStereoInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stereoInputChanged;
|
return stereoInputChanged;
|
||||||
|
@ -1463,6 +1465,8 @@ void AudioClient::outputFormatChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) {
|
bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest) {
|
||||||
|
Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread");
|
||||||
|
|
||||||
qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.deviceName() << "]";
|
qCDebug(audioclient) << __FUNCTION__ << "inputDeviceInfo: [" << inputDeviceInfo.deviceName() << "]";
|
||||||
bool supportedFormat = false;
|
bool supportedFormat = false;
|
||||||
|
|
||||||
|
@ -1663,6 +1667,8 @@ void AudioClient::outputNotify() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) {
|
bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) {
|
||||||
|
Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread");
|
||||||
|
|
||||||
qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]";
|
qCDebug(audioclient) << "AudioClient::switchOutputToAudioDevice() outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]";
|
||||||
bool supportedFormat = false;
|
bool supportedFormat = false;
|
||||||
|
|
||||||
|
@ -2021,7 +2027,7 @@ void AudioClient::setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 sca
|
||||||
|
|
||||||
|
|
||||||
void AudioClient::startThread() {
|
void AudioClient::startThread() {
|
||||||
moveToNewNamedThread(this, "Audio Thread", [this] { start(); });
|
moveToNewNamedThread(this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::setInputVolume(float volume, bool emitSignal) {
|
void AudioClient::setInputVolume(float volume, bool emitSignal) {
|
||||||
|
|
|
@ -44,6 +44,9 @@ public slots:
|
||||||
virtual bool setIsStereoInput(bool stereo) = 0;
|
virtual bool setIsStereoInput(bool stereo) = 0;
|
||||||
|
|
||||||
virtual bool isStereoInput() = 0;
|
virtual bool isStereoInput() = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void isStereoInputChanged(bool isStereo);
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
||||||
|
|
|
@ -1338,6 +1338,9 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||||
|
if (!isMyAvatar()) {
|
||||||
|
createOrb();
|
||||||
|
}
|
||||||
AvatarData::setSkeletonModelURL(skeletonModelURL);
|
AvatarData::setSkeletonModelURL(skeletonModelURL);
|
||||||
if (QThread::currentThread() == thread()) {
|
if (QThread::currentThread() == thread()) {
|
||||||
_skeletonModel->setURL(_skeletonModelURL);
|
_skeletonModel->setURL(_skeletonModelURL);
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include <graphics-scripting/Forward.h>
|
#include <graphics-scripting/Forward.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
|
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
#include "SkeletonModel.h"
|
#include "SkeletonModel.h"
|
||||||
#include "Rig.h"
|
#include "Rig.h"
|
||||||
|
@ -41,7 +40,6 @@ static const float SCALING_RATIO = .05f;
|
||||||
extern const float CHAT_MESSAGE_SCALE;
|
extern const float CHAT_MESSAGE_SCALE;
|
||||||
extern const float CHAT_MESSAGE_HEIGHT;
|
extern const float CHAT_MESSAGE_HEIGHT;
|
||||||
|
|
||||||
|
|
||||||
enum ScreenTintLayer {
|
enum ScreenTintLayer {
|
||||||
SCREEN_TINT_BEFORE_LANDSCAPE = 0,
|
SCREEN_TINT_BEFORE_LANDSCAPE = 0,
|
||||||
SCREEN_TINT_BEFORE_AVATARS,
|
SCREEN_TINT_BEFORE_AVATARS,
|
||||||
|
@ -69,7 +67,7 @@ public:
|
||||||
static void setShowNamesAboveHeads(bool show);
|
static void setShowNamesAboveHeads(bool show);
|
||||||
|
|
||||||
explicit Avatar(QThread* thread);
|
explicit Avatar(QThread* thread);
|
||||||
~Avatar();
|
virtual ~Avatar();
|
||||||
|
|
||||||
virtual void instantiableAvatar() = 0;
|
virtual void instantiableAvatar() = 0;
|
||||||
|
|
||||||
|
@ -109,6 +107,7 @@ public:
|
||||||
float getLODDistance() const;
|
float getLODDistance() const;
|
||||||
|
|
||||||
virtual bool isMyAvatar() const override { return false; }
|
virtual bool isMyAvatar() const override { return false; }
|
||||||
|
virtual void createOrb() { }
|
||||||
|
|
||||||
virtual QVector<glm::quat> getJointRotations() const override;
|
virtual QVector<glm::quat> getJointRotations() const override;
|
||||||
using AvatarData::getJointRotation;
|
using AvatarData::getJointRotation;
|
||||||
|
@ -167,7 +166,7 @@ public:
|
||||||
|
|
||||||
virtual int parseDataFromBuffer(const QByteArray& buffer) override;
|
virtual int parseDataFromBuffer(const QByteArray& buffer) override;
|
||||||
|
|
||||||
static void renderJointConnectingCone( gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2,
|
static void renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2,
|
||||||
float radius1, float radius2, const glm::vec4& color);
|
float radius1, float radius2, const glm::vec4& color);
|
||||||
|
|
||||||
virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { }
|
virtual void applyCollision(const glm::vec3& contactPoint, const glm::vec3& penetration) { }
|
||||||
|
@ -235,7 +234,7 @@ public:
|
||||||
|
|
||||||
/// Scales a world space position vector relative to the avatar position and scale
|
/// Scales a world space position vector relative to the avatar position and scale
|
||||||
/// \param vector position to be scaled. Will store the result
|
/// \param vector position to be scaled. Will store the result
|
||||||
void scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const;
|
void scaleVectorRelativeToPosition(glm::vec3& positionToScale) const;
|
||||||
|
|
||||||
void slamPosition(const glm::vec3& position);
|
void slamPosition(const glm::vec3& position);
|
||||||
virtual void updateAttitude(const glm::quat& orientation) override;
|
virtual void updateAttitude(const glm::quat& orientation) override;
|
||||||
|
@ -254,7 +253,6 @@ public:
|
||||||
void setPositionViaScript(const glm::vec3& position) override;
|
void setPositionViaScript(const glm::vec3& position) override;
|
||||||
void setOrientationViaScript(const glm::quat& orientation) override;
|
void setOrientationViaScript(const glm::quat& orientation) override;
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.getParentID
|
* @function MyAvatar.getParentID
|
||||||
* @returns {Uuid}
|
* @returns {Uuid}
|
||||||
|
@ -283,7 +281,6 @@ public:
|
||||||
// This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript.
|
// This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript.
|
||||||
Q_INVOKABLE virtual void setParentJointIndex(quint16 parentJointIndex) override;
|
Q_INVOKABLE virtual void setParentJointIndex(quint16 parentJointIndex) override;
|
||||||
|
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Returns an array of joints, where each joint is an object containing name, index, and parentIndex fields.
|
* Returns an array of joints, where each joint is an object containing name, index, and parentIndex fields.
|
||||||
* @function MyAvatar.getSkeleton
|
* @function MyAvatar.getSkeleton
|
||||||
|
@ -349,7 +346,6 @@ public:
|
||||||
// not all subclasses of AvatarData have access to this data.
|
// not all subclasses of AvatarData have access to this data.
|
||||||
virtual bool canMeasureEyeHeight() const override { return true; }
|
virtual bool canMeasureEyeHeight() const override { return true; }
|
||||||
|
|
||||||
|
|
||||||
virtual float getModelScale() const { return _modelScale; }
|
virtual float getModelScale() const { return _modelScale; }
|
||||||
virtual void setModelScale(float scale) { _modelScale = scale; }
|
virtual void setModelScale(float scale) { _modelScale = scale; }
|
||||||
virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); }
|
virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); }
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2017/04/27
|
|
||||||
// Copyright 2013-2017 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 "OtherAvatar.h"
|
|
||||||
|
|
||||||
OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) {
|
|
||||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
|
||||||
_headData = new Head(this);
|
|
||||||
_skeletonModel = std::make_shared<SkeletonModel>(this, nullptr);
|
|
||||||
_skeletonModel->setLoadingPriority(OTHERAVATAR_LOADING_PRIORITY);
|
|
||||||
connect(_skeletonModel.get(), &Model::setURLFinished, this, &Avatar::setModelURLFinished);
|
|
||||||
connect(_skeletonModel.get(), &Model::rigReady, this, &Avatar::rigReady);
|
|
||||||
connect(_skeletonModel.get(), &Model::rigReset, this, &Avatar::rigReset);
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis on 2017/04/27
|
|
||||||
// Copyright 2013-2017 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_OtherAvatar_h
|
|
||||||
#define hifi_OtherAvatar_h
|
|
||||||
|
|
||||||
#include "Avatar.h"
|
|
||||||
|
|
||||||
class OtherAvatar : public Avatar {
|
|
||||||
public:
|
|
||||||
explicit OtherAvatar(QThread* thread);
|
|
||||||
virtual void instantiableAvatar() override {};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_OtherAvatar_h
|
|
|
@ -1269,6 +1269,8 @@ bool EntityScriptingInterface::appendPoint(QUuid entityID, const glm::vec3& poin
|
||||||
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
EntityItemPointer entity = static_cast<EntityItemPointer>(_entityTree->findEntityByEntityItemID(entityID));
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
qCDebug(entities) << "EntityScriptingInterface::setPoints no entity with ID" << entityID;
|
||||||
|
// There is no entity
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTypes::EntityType entityType = entity->getType();
|
EntityTypes::EntityType entityType = entity->getType();
|
||||||
|
|
|
@ -2521,6 +2521,13 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zero out the spread values that were fixed in version ParticleEntityFix so they behave the same as before
|
||||||
|
if (contentVersion < (int)EntityVersion::ParticleEntityFix) {
|
||||||
|
properties.setRadiusSpread(0.0f);
|
||||||
|
properties.setAlphaSpread(0.0f);
|
||||||
|
properties.setColorSpread({0, 0, 0});
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer entity = addEntity(entityItemID, properties);
|
EntityItemPointer entity = addEntity(entityItemID, properties);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
||||||
|
|
|
@ -203,10 +203,11 @@ void GLBackend::releaseResourceTexture(uint32_t slot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::resetResourceStage() {
|
void GLBackend::resetResourceStage() {
|
||||||
for (uint32_t i = 0; i < _resource._buffers.size(); i++) {
|
uint32_t i;
|
||||||
|
for (i = 0; i < _resource._buffers.size(); i++) {
|
||||||
releaseResourceBuffer(i);
|
releaseResourceBuffer(i);
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < _resource._textures.size(); i++) {
|
for (i = 0; i < _resource._textures.size(); i++) {
|
||||||
releaseResourceTexture(i);
|
releaseResourceTexture(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,11 @@ const size_t GLVariableAllocationSupport::MAX_BUFFER_SIZE = MAX_TRANSFER_SIZE;
|
||||||
GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
||||||
switch (texture.getType()) {
|
switch (texture.getType()) {
|
||||||
case Texture::TEX_2D:
|
case Texture::TEX_2D:
|
||||||
|
if (!texture.isArray()) {
|
||||||
return GL_TEXTURE_2D;
|
return GL_TEXTURE_2D;
|
||||||
|
} else {
|
||||||
|
return GL_TEXTURE_2D_ARRAY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Texture::TEX_CUBE:
|
case Texture::TEX_CUBE:
|
||||||
|
@ -77,6 +81,7 @@ GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
||||||
uint8_t GLTexture::getFaceCount(GLenum target) {
|
uint8_t GLTexture::getFaceCount(GLenum target) {
|
||||||
switch (target) {
|
switch (target) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
|
case GL_TEXTURE_2D_ARRAY:
|
||||||
return TEXTURE_2D_NUM_FACES;
|
return TEXTURE_2D_NUM_FACES;
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
return TEXTURE_CUBE_NUM_FACES;
|
return TEXTURE_CUBE_NUM_FACES;
|
||||||
|
@ -86,17 +91,22 @@ uint8_t GLTexture::getFaceCount(GLenum target) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const std::vector<GLenum>& GLTexture::getFaceTargets(GLenum target) {
|
const std::vector<GLenum>& GLTexture::getFaceTargets(GLenum target) {
|
||||||
static std::vector<GLenum> cubeFaceTargets {
|
static const std::vector<GLenum> cubeFaceTargets {
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
|
||||||
};
|
};
|
||||||
static std::vector<GLenum> faceTargets {
|
static const std::vector<GLenum> faceTargets {
|
||||||
GL_TEXTURE_2D
|
GL_TEXTURE_2D
|
||||||
};
|
};
|
||||||
|
static const std::vector<GLenum> arrayFaceTargets{
|
||||||
|
GL_TEXTURE_2D_ARRAY
|
||||||
|
};
|
||||||
switch (target) {
|
switch (target) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
return faceTargets;
|
return faceTargets;
|
||||||
|
case GL_TEXTURE_2D_ARRAY:
|
||||||
|
return arrayFaceTargets;
|
||||||
case GL_TEXTURE_CUBE_MAP:
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
return cubeFaceTargets;
|
return cubeFaceTargets;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -64,7 +64,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gltexture) {
|
if (gltexture) {
|
||||||
|
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||||
|
} else {
|
||||||
|
glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0,
|
||||||
|
b._subresource);
|
||||||
|
}
|
||||||
_colorBuffers.push_back(colorAttachments[unit]);
|
_colorBuffers.push_back(colorAttachments[unit]);
|
||||||
} else {
|
} else {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, 0, 0);
|
||||||
|
@ -91,7 +96,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gltexture) {
|
if (gltexture) {
|
||||||
|
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||||
|
} else {
|
||||||
|
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0,
|
||||||
|
_gpuObject.getDepthStencilBufferSubresource());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ void GL41Texture::syncSampler() const {
|
||||||
glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
||||||
|
|
||||||
if (sampler.doComparison()) {
|
if (sampler.doComparison()) {
|
||||||
glTexParameteri(_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE_ARB);
|
glTexParameteri(_target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
glTexParameteri(_target, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
glTexParameteri(_target, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
||||||
} else {
|
} else {
|
||||||
glTexParameteri(_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glTexParameteri(_target, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
@ -197,7 +197,7 @@ void GL41Texture::syncSampler() const {
|
||||||
glTexParameterf(_target, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip());
|
glTexParameterf(_target, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip());
|
||||||
glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
|
glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip()));
|
||||||
|
|
||||||
glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY, sampler.getMaxAnisotropy());
|
||||||
}
|
}
|
||||||
|
|
||||||
using GL41FixedAllocationTexture = GL41Backend::GL41FixedAllocationTexture;
|
using GL41FixedAllocationTexture = GL41Backend::GL41FixedAllocationTexture;
|
||||||
|
@ -215,12 +215,19 @@ GL41FixedAllocationTexture::~GL41FixedAllocationTexture() {
|
||||||
void GL41FixedAllocationTexture::allocateStorage() const {
|
void GL41FixedAllocationTexture::allocateStorage() const {
|
||||||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||||
const auto numMips = _gpuObject.getNumMips();
|
const auto numMips = _gpuObject.getNumMips();
|
||||||
|
const auto numSlices = _gpuObject.getNumSlices();
|
||||||
|
|
||||||
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||||
for (GLint level = 0; level < numMips; level++) {
|
for (GLint level = 0; level < numMips; level++) {
|
||||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||||
for (GLenum target : getFaceTargets(_target)) {
|
for (GLenum target : getFaceTargets(_target)) {
|
||||||
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, nullptr);
|
if (!_gpuObject.isArray()) {
|
||||||
|
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format,
|
||||||
|
texelFormat.type, nullptr);
|
||||||
|
} else {
|
||||||
|
glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0,
|
||||||
|
texelFormat.format, texelFormat.type, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gltexture) {
|
if (gltexture) {
|
||||||
|
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||||
glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0);
|
glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0);
|
||||||
|
} else {
|
||||||
|
glNamedFramebufferTextureLayer(_id, colorAttachments[unit], gltexture->_texture, 0, b._subresource);
|
||||||
|
}
|
||||||
_colorBuffers.push_back(colorAttachments[unit]);
|
_colorBuffers.push_back(colorAttachments[unit]);
|
||||||
} else {
|
} else {
|
||||||
glNamedFramebufferTexture(_id, colorAttachments[unit], 0, 0);
|
glNamedFramebufferTexture(_id, colorAttachments[unit], 0, 0);
|
||||||
|
@ -87,14 +91,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gltexture) {
|
if (gltexture) {
|
||||||
|
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||||
glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0);
|
glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0);
|
||||||
|
} else {
|
||||||
|
glNamedFramebufferTextureLayer(_id, attachement, gltexture->_texture, 0,
|
||||||
|
_gpuObject.getDepthStencilBufferSubresource());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
glNamedFramebufferTexture(_id, attachement, 0, 0);
|
glNamedFramebufferTexture(_id, attachement, 0, 0);
|
||||||
}
|
}
|
||||||
_depthStamp = _gpuObject.getDepthStamp();
|
_depthStamp = _gpuObject.getDepthStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Last but not least, define where we draw
|
// Last but not least, define where we draw
|
||||||
if (!_colorBuffers.empty()) {
|
if (!_colorBuffers.empty()) {
|
||||||
glNamedFramebufferDrawBuffers(_id, (GLsizei)_colorBuffers.size(), _colorBuffers.data());
|
glNamedFramebufferDrawBuffers(_id, (GLsizei)_colorBuffers.size(), _colorBuffers.data());
|
||||||
|
|
|
@ -152,7 +152,7 @@ public:
|
||||||
glSamplerParameteri(result, GL_TEXTURE_MIN_FILTER, fm.minFilter);
|
glSamplerParameteri(result, GL_TEXTURE_MIN_FILTER, fm.minFilter);
|
||||||
glSamplerParameteri(result, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
glSamplerParameteri(result, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
||||||
if (sampler.doComparison()) {
|
if (sampler.doComparison()) {
|
||||||
glSamplerParameteri(result, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE_ARB);
|
glSamplerParameteri(result, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
glSamplerParameteri(result, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
glSamplerParameteri(result, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
||||||
} else {
|
} else {
|
||||||
glSamplerParameteri(result, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glSamplerParameteri(result, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
@ -341,7 +341,7 @@ void GL45Texture::syncSampler() const {
|
||||||
glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter);
|
||||||
|
|
||||||
if (sampler.doComparison()) {
|
if (sampler.doComparison()) {
|
||||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE_ARB);
|
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]);
|
||||||
} else {
|
} else {
|
||||||
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
@ -374,8 +374,13 @@ void GL45FixedAllocationTexture::allocateStorage() const {
|
||||||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||||
const auto dimensions = _gpuObject.getDimensions();
|
const auto dimensions = _gpuObject.getDimensions();
|
||||||
const auto mips = _gpuObject.getNumMips();
|
const auto mips = _gpuObject.getNumMips();
|
||||||
|
const auto numSlices = _gpuObject.getNumSlices();
|
||||||
|
|
||||||
|
if (!_gpuObject.isArray()) {
|
||||||
glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||||
|
} else {
|
||||||
|
glTextureStorage3D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices);
|
||||||
|
}
|
||||||
|
|
||||||
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
|
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, mips - 1);
|
glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, mips - 1);
|
||||||
|
|
|
@ -64,7 +64,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gltexture) {
|
if (gltexture) {
|
||||||
|
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||||
|
} else {
|
||||||
|
glFramebufferTextureLayer(GL_FRAMEBUFFER, colorAttachments[unit], gltexture->_texture, 0,
|
||||||
|
b._subresource);
|
||||||
|
}
|
||||||
_colorBuffers.push_back(colorAttachments[unit]);
|
_colorBuffers.push_back(colorAttachments[unit]);
|
||||||
} else {
|
} else {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, 0, 0);
|
||||||
|
@ -91,7 +96,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gltexture) {
|
if (gltexture) {
|
||||||
|
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||||
|
} else {
|
||||||
|
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0,
|
||||||
|
_gpuObject.getDepthStencilBufferSubresource());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,16 +268,27 @@ GLsizei getCompressedImageSize(int width, int height, GLenum internalFormat) {
|
||||||
void GLESFixedAllocationTexture::allocateStorage() const {
|
void GLESFixedAllocationTexture::allocateStorage() const {
|
||||||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||||
const auto numMips = _gpuObject.getNumMips();
|
const auto numMips = _gpuObject.getNumMips();
|
||||||
|
const auto numSlices = _gpuObject.getNumSlices();
|
||||||
|
|
||||||
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||||
for (GLint level = 0; level < numMips; level++) {
|
for (GLint level = 0; level < numMips; level++) {
|
||||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||||
for (GLenum target : getFaceTargets(_target)) {
|
for (GLenum target : getFaceTargets(_target)) {
|
||||||
if (texelFormat.isCompressed()) {
|
if (texelFormat.isCompressed()) {
|
||||||
glCompressedTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0,
|
auto size = getCompressedImageSize(dimensions.x, dimensions.y, texelFormat.internalFormat);
|
||||||
getCompressedImageSize(dimensions.x, dimensions.y, texelFormat.internalFormat), nullptr);
|
if (!_gpuObject.isArray()) {
|
||||||
|
glCompressedTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, size, nullptr);
|
||||||
} else {
|
} else {
|
||||||
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, nullptr);
|
glCompressedTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0, size * numSlices, nullptr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!_gpuObject.isArray()) {
|
||||||
|
glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format,
|
||||||
|
texelFormat.type, nullptr);
|
||||||
|
} else {
|
||||||
|
glTexImage3D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, numSlices, 0,
|
||||||
|
texelFormat.format, texelFormat.type, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,7 @@ Frame::~Frame() {
|
||||||
framebuffer.reset();
|
framebuffer.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bufferUpdates.empty());
|
bufferUpdates.clear();
|
||||||
if (!bufferUpdates.empty()) {
|
|
||||||
qFatal("Buffer sync error... frame destroyed without buffer updates being applied");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::finish() {
|
void Frame::finish() {
|
||||||
|
|
|
@ -184,6 +184,10 @@ TexturePointer Texture::createRenderBuffer(const Element& texelFormat, uint16 wi
|
||||||
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexturePointer Texture::createRenderBufferArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips, const Sampler& sampler) {
|
||||||
|
return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, numSlices, numMips, sampler);
|
||||||
|
}
|
||||||
|
|
||||||
TexturePointer Texture::create1D(const Element& texelFormat, uint16 width, uint16 numMips, const Sampler& sampler) {
|
TexturePointer Texture::create1D(const Element& texelFormat, uint16 width, uint16 numMips, const Sampler& sampler) {
|
||||||
return create(TextureUsageType::RESOURCE, TEX_1D, texelFormat, width, 1, 1, 1, 0, numMips, sampler);
|
return create(TextureUsageType::RESOURCE, TEX_1D, texelFormat, width, 1, 1, 1, 0, numMips, sampler);
|
||||||
}
|
}
|
||||||
|
@ -192,6 +196,10 @@ TexturePointer Texture::create2D(const Element& texelFormat, uint16 width, uint1
|
||||||
return create(TextureUsageType::RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
return create(TextureUsageType::RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexturePointer Texture::create2DArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips, const Sampler& sampler) {
|
||||||
|
return create(TextureUsageType::STRICT_RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, numSlices, numMips, sampler);
|
||||||
|
}
|
||||||
|
|
||||||
TexturePointer Texture::createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips, const Sampler& sampler) {
|
TexturePointer Texture::createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips, const Sampler& sampler) {
|
||||||
return create(TextureUsageType::STRICT_RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
return create(TextureUsageType::STRICT_RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler);
|
||||||
}
|
}
|
||||||
|
|
|
@ -374,9 +374,11 @@ public:
|
||||||
static const uint16 SINGLE_MIP = 1;
|
static const uint16 SINGLE_MIP = 1;
|
||||||
static TexturePointer create1D(const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
static TexturePointer create1D(const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
static TexturePointer create2D(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
static TexturePointer create2D(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
|
static TexturePointer create2DArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
static TexturePointer create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
static TexturePointer create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
static TexturePointer createCube(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler());
|
static TexturePointer createCube(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler());
|
||||||
static TexturePointer createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
static TexturePointer createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
|
static TexturePointer createRenderBufferArray(const Element& texelFormat, uint16 width, uint16 height, uint16 numSlices, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
static TexturePointer createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
static TexturePointer createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler());
|
||||||
static TexturePointer createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler());
|
static TexturePointer createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler());
|
||||||
|
|
||||||
|
|
|
@ -515,7 +515,7 @@ TexturePointer Texture::build(const ktx::KTXDescriptor& descriptor) {
|
||||||
header.getPixelHeight(),
|
header.getPixelHeight(),
|
||||||
header.getPixelDepth(),
|
header.getPixelDepth(),
|
||||||
1, // num Samples
|
1, // num Samples
|
||||||
header.getNumberOfSlices(),
|
header.isArray() ? header.getNumberOfSlices() : 0,
|
||||||
header.getNumberOfLevels(),
|
header.getNumberOfLevels(),
|
||||||
samplerDesc);
|
samplerDesc);
|
||||||
texture->setUsage(gpuktxKeyValue._usage);
|
texture->setUsage(gpuktxKeyValue._usage);
|
||||||
|
|
|
@ -163,6 +163,7 @@ namespace ktx {
|
||||||
uint32_t getPixelDepth() const { return (pixelDepth ? pixelDepth : 1); }
|
uint32_t getPixelDepth() const { return (pixelDepth ? pixelDepth : 1); }
|
||||||
uint32_t getNumberOfSlices() const { return (numberOfArrayElements ? numberOfArrayElements : 1); }
|
uint32_t getNumberOfSlices() const { return (numberOfArrayElements ? numberOfArrayElements : 1); }
|
||||||
uint32_t getNumberOfLevels() const { return (numberOfMipmapLevels ? numberOfMipmapLevels : 1); }
|
uint32_t getNumberOfLevels() const { return (numberOfMipmapLevels ? numberOfMipmapLevels : 1); }
|
||||||
|
bool isArray() const { return numberOfArrayElements > 0; }
|
||||||
bool isCompressed() const { return glFormat == COMPRESSED_FORMAT; }
|
bool isCompressed() const { return glFormat == COMPRESSED_FORMAT; }
|
||||||
|
|
||||||
uint32_t evalMaxDimension() const;
|
uint32_t evalMaxDimension() const;
|
||||||
|
|
|
@ -39,8 +39,13 @@ ResourceManager::ResourceManager(bool atpSupportEnabled) : _atpSupportEnabled(at
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager::~ResourceManager() {
|
ResourceManager::~ResourceManager() {
|
||||||
|
if (_thread.isRunning()) {
|
||||||
|
_thread.quit();
|
||||||
|
static const auto MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME = MSECS_PER_SECOND / 2;
|
||||||
|
if (!_thread.wait(MAX_RESOURCE_MANAGER_THREAD_QUITTING_TIME)) {
|
||||||
_thread.terminate();
|
_thread.terminate();
|
||||||
_thread.wait();
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) {
|
void ResourceManager::setUrlPrefixOverride(const QString& prefix, const QString& replacement) {
|
||||||
|
|
|
@ -239,7 +239,7 @@ void Connection::sync() {
|
||||||
sendACK();
|
sendACK();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_lossList.getLength() > 0) {
|
if (_congestionControl->shouldNAK() && _lossList.getLength() > 0) {
|
||||||
// check if we need to re-transmit a loss list
|
// check if we need to re-transmit a loss list
|
||||||
// we do this if it has been longer than the current nakInterval since we last sent
|
// we do this if it has been longer than the current nakInterval since we last sent
|
||||||
auto now = p_high_resolution_clock::now();
|
auto now = p_high_resolution_clock::now();
|
||||||
|
@ -272,9 +272,12 @@ void Connection::sendACK(bool wasCausedBySyncTimeout) {
|
||||||
SequenceNumber nextACKNumber = nextACK();
|
SequenceNumber nextACKNumber = nextACK();
|
||||||
Q_ASSERT_X(nextACKNumber >= _lastSentACK, "Connection::sendACK", "Sending lower ACK, something is wrong");
|
Q_ASSERT_X(nextACKNumber >= _lastSentACK, "Connection::sendACK", "Sending lower ACK, something is wrong");
|
||||||
|
|
||||||
if (nextACKNumber == _lastSentACK) {
|
// if our congestion control doesn't want to send an ACK for every packet received
|
||||||
// We already sent this ACK, but check if we should re-send it.
|
// check if we already sent this ACK
|
||||||
if (nextACKNumber < _lastReceivedAcknowledgedACK) {
|
if (_congestionControl->_ackInterval > 1 && nextACKNumber == _lastSentACK) {
|
||||||
|
|
||||||
|
// if we use ACK2s, check if the receiving side already confirmed receipt of this ACK
|
||||||
|
if (_congestionControl->shouldACK2() && nextACKNumber < _lastReceivedAcknowledgedACK) {
|
||||||
// we already got an ACK2 for this ACK we would be sending, don't bother
|
// we already got an ACK2 for this ACK we would be sending, don't bother
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -287,11 +290,11 @@ void Connection::sendACK(bool wasCausedBySyncTimeout) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we have received new packets since the last sent ACK
|
// we have received new packets since the last sent ACK
|
||||||
|
// or our congestion control dictates that we always send ACKs
|
||||||
|
|
||||||
// update the last sent ACK
|
// update the last sent ACK
|
||||||
_lastSentACK = nextACKNumber;
|
_lastSentACK = nextACKNumber;
|
||||||
|
|
||||||
|
|
||||||
_ackPacket->reset(); // We need to reset it every time.
|
_ackPacket->reset(); // We need to reset it every time.
|
||||||
|
|
||||||
// pack in the ACK sub-sequence number
|
// pack in the ACK sub-sequence number
|
||||||
|
@ -449,6 +452,7 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
|
||||||
// mark our last receive time as now (to push the potential expiry farther)
|
// mark our last receive time as now (to push the potential expiry farther)
|
||||||
_lastReceiveTime = p_high_resolution_clock::now();
|
_lastReceiveTime = p_high_resolution_clock::now();
|
||||||
|
|
||||||
|
if (_congestionControl->shouldProbe()) {
|
||||||
// check if this is a packet pair we should estimate bandwidth from, or just a regular packet
|
// check if this is a packet pair we should estimate bandwidth from, or just a regular packet
|
||||||
if (((uint32_t) sequenceNumber & 0xF) == 0) {
|
if (((uint32_t) sequenceNumber & 0xF) == 0) {
|
||||||
_receiveWindow.onProbePair1Arrival();
|
_receiveWindow.onProbePair1Arrival();
|
||||||
|
@ -460,8 +464,9 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
|
||||||
// reset our control probe tail marker so the next probe that comes with data can be used
|
// reset our control probe tail marker so the next probe that comes with data can be used
|
||||||
_receivedControlProbeTail = false;
|
_receivedControlProbeTail = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_receiveWindow.onPacketArrival();
|
_receiveWindow.onPacketArrival();
|
||||||
|
|
||||||
// If this is not the next sequence number, report loss
|
// If this is not the next sequence number, report loss
|
||||||
|
|
|
@ -40,9 +40,8 @@ void PluginManager::setInputPluginSettingsPersister(const InputPluginSettingsPer
|
||||||
_inputSettingsPersister = persister;
|
_inputSettingsPersister = persister;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginManager* PluginManager::getInstance() {
|
PluginManagerPointer PluginManager::getInstance() {
|
||||||
static PluginManager _manager;
|
return DependencyManager::get<PluginManager>();
|
||||||
return &_manager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString getPluginNameFromMetaData(QJsonObject object) {
|
QString getPluginNameFromMetaData(QJsonObject object) {
|
||||||
|
@ -136,9 +135,6 @@ const LoaderList& getLoadedPlugins() {
|
||||||
return loadedPlugins;
|
return loadedPlugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginManager::PluginManager() {
|
|
||||||
}
|
|
||||||
|
|
||||||
const CodecPluginList& PluginManager::getCodecPlugins() {
|
const CodecPluginList& PluginManager::getCodecPlugins() {
|
||||||
static CodecPluginList codecPlugins;
|
static CodecPluginList codecPlugins;
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
|
|
|
@ -9,12 +9,19 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
#include "Forward.h"
|
#include "Forward.h"
|
||||||
|
|
||||||
class PluginManager : public QObject {
|
|
||||||
|
class PluginManager;
|
||||||
|
using PluginManagerPointer = QSharedPointer<PluginManager>;
|
||||||
|
|
||||||
|
class PluginManager : public QObject, public Dependency {
|
||||||
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static PluginManager* getInstance();
|
static PluginManagerPointer getInstance();
|
||||||
PluginManager();
|
|
||||||
|
|
||||||
const DisplayPluginList& getDisplayPlugins();
|
const DisplayPluginList& getDisplayPlugins();
|
||||||
const InputPluginList& getInputPlugins();
|
const InputPluginList& getInputPlugins();
|
||||||
|
@ -39,6 +46,8 @@ public:
|
||||||
void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister);
|
void setInputPluginSettingsPersister(const InputPluginSettingsPersister& persister);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PluginManager() = default;
|
||||||
|
|
||||||
DisplayPluginProvider _displayPluginProvider { []()->DisplayPluginList { return {}; } };
|
DisplayPluginProvider _displayPluginProvider { []()->DisplayPluginList { return {}; } };
|
||||||
InputPluginProvider _inputPluginProvider { []()->InputPluginList { return {}; } };
|
InputPluginProvider _inputPluginProvider { []()->InputPluginList { return {}; } };
|
||||||
CodecPluginProvider _codecPluginProvider { []()->CodecPluginList { return {}; } };
|
CodecPluginProvider _codecPluginProvider { []()->CodecPluginList { return {}; } };
|
||||||
|
|
|
@ -66,7 +66,7 @@ OffscreenSurface::OffscreenSurface()
|
||||||
}
|
}
|
||||||
|
|
||||||
OffscreenSurface::~OffscreenSurface() {
|
OffscreenSurface::~OffscreenSurface() {
|
||||||
delete _sharedObject;
|
_sharedObject->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffscreenSurface::fetchTexture(TextureAndFence& textureAndFence) {
|
bool OffscreenSurface::fetchTexture(TextureAndFence& textureAndFence) {
|
||||||
|
|
|
@ -60,7 +60,8 @@ enum TextureSlot {
|
||||||
enum ParamSlot {
|
enum ParamSlot {
|
||||||
CameraCorrection = 0,
|
CameraCorrection = 0,
|
||||||
DeferredFrameTransform,
|
DeferredFrameTransform,
|
||||||
ShadowTransform
|
ShadowTransform,
|
||||||
|
DebugParametersBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::string DEFAULT_ALBEDO_SHADER {
|
static const std::string DEFAULT_ALBEDO_SHADER {
|
||||||
|
@ -139,12 +140,11 @@ static const std::string DEFAULT_LIGHTING_SHADER {
|
||||||
" }"
|
" }"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::string DEFAULT_SHADOW_SHADER{
|
static const std::string DEFAULT_SHADOW_DEPTH_SHADER{
|
||||||
"uniform sampler2DShadow shadowMap;"
|
|
||||||
"vec4 getFragmentColor() {"
|
"vec4 getFragmentColor() {"
|
||||||
" for (int i = 255; i >= 0; --i) {"
|
" for (int i = 255; i >= 0; --i) {"
|
||||||
" float depth = i / 255.0;"
|
" float depth = i / 255.0;"
|
||||||
" if (texture(shadowMap, vec3(uv, depth)) > 0.5) {"
|
" if (texture(shadowMaps, vec4(uv, parameters._shadowCascadeIndex, depth)) > 0.5) {"
|
||||||
" return vec4(vec3(depth), 1.0);"
|
" return vec4(vec3(depth), 1.0);"
|
||||||
" }"
|
" }"
|
||||||
" }"
|
" }"
|
||||||
|
@ -323,7 +323,7 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
|
||||||
case ShadowCascade1Mode:
|
case ShadowCascade1Mode:
|
||||||
case ShadowCascade2Mode:
|
case ShadowCascade2Mode:
|
||||||
case ShadowCascade3Mode:
|
case ShadowCascade3Mode:
|
||||||
return DEFAULT_SHADOW_SHADER;
|
return DEFAULT_SHADOW_DEPTH_SHADER;
|
||||||
case ShadowCascadeIndicesMode:
|
case ShadowCascadeIndicesMode:
|
||||||
return DEFAULT_SHADOW_CASCADE_SHADER;
|
return DEFAULT_SHADOW_CASCADE_SHADER;
|
||||||
case LinearDepthMode:
|
case LinearDepthMode:
|
||||||
|
@ -396,6 +396,7 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
|
||||||
slotBindings.insert(gpu::Shader::Binding("cameraCorrectionBuffer", CameraCorrection));
|
slotBindings.insert(gpu::Shader::Binding("cameraCorrectionBuffer", CameraCorrection));
|
||||||
slotBindings.insert(gpu::Shader::Binding("deferredFrameTransformBuffer", DeferredFrameTransform));
|
slotBindings.insert(gpu::Shader::Binding("deferredFrameTransformBuffer", DeferredFrameTransform));
|
||||||
slotBindings.insert(gpu::Shader::Binding("shadowTransformBuffer", ShadowTransform));
|
slotBindings.insert(gpu::Shader::Binding("shadowTransformBuffer", ShadowTransform));
|
||||||
|
slotBindings.insert(gpu::Shader::Binding("parametersBuffer", DebugParametersBuffer));
|
||||||
|
|
||||||
slotBindings.insert(gpu::Shader::Binding("albedoMap", Albedo));
|
slotBindings.insert(gpu::Shader::Binding("albedoMap", Albedo));
|
||||||
slotBindings.insert(gpu::Shader::Binding("normalMap", Normal));
|
slotBindings.insert(gpu::Shader::Binding("normalMap", Normal));
|
||||||
|
@ -403,7 +404,7 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
|
||||||
slotBindings.insert(gpu::Shader::Binding("depthMap", Depth));
|
slotBindings.insert(gpu::Shader::Binding("depthMap", Depth));
|
||||||
slotBindings.insert(gpu::Shader::Binding("obscuranceMap", AmbientOcclusion));
|
slotBindings.insert(gpu::Shader::Binding("obscuranceMap", AmbientOcclusion));
|
||||||
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
|
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
|
||||||
slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow));
|
slotBindings.insert(gpu::Shader::Binding("shadowMaps", Shadow));
|
||||||
slotBindings.insert(gpu::Shader::Binding("linearDepthMap", LinearDepth));
|
slotBindings.insert(gpu::Shader::Binding("linearDepthMap", LinearDepth));
|
||||||
slotBindings.insert(gpu::Shader::Binding("halfLinearDepthMap", HalfLinearDepth));
|
slotBindings.insert(gpu::Shader::Binding("halfLinearDepthMap", HalfLinearDepth));
|
||||||
slotBindings.insert(gpu::Shader::Binding("halfNormalMap", HalfNormal));
|
slotBindings.insert(gpu::Shader::Binding("halfNormalMap", HalfNormal));
|
||||||
|
@ -432,8 +433,11 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::str
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugDeferredBuffer::configure(const Config& config) {
|
void DebugDeferredBuffer::configure(const Config& config) {
|
||||||
|
auto& parameters = _parameters.edit();
|
||||||
|
|
||||||
_mode = (Mode)config.mode;
|
_mode = (Mode)config.mode;
|
||||||
_size = config.size;
|
_size = config.size;
|
||||||
|
parameters._shadowCascadeIndex = glm::clamp(_mode - Mode::ShadowCascade0Mode, 0, (int)SHADOW_CASCADE_MAX_COUNT - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
|
void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||||
|
@ -483,14 +487,15 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
|
||||||
batch.setResourceTexture(Velocity, velocityFramebuffer->getVelocityTexture());
|
batch.setResourceTexture(Velocity, velocityFramebuffer->getVelocityTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch.setUniformBuffer(DebugParametersBuffer, _parameters);
|
||||||
|
|
||||||
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
auto lightStage = renderContext->_scene->getStage<LightStage>();
|
||||||
assert(lightStage);
|
assert(lightStage);
|
||||||
assert(lightStage->getNumLights() > 0);
|
assert(lightStage->getNumLights() > 0);
|
||||||
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow();
|
auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow();
|
||||||
const auto& globalShadow = lightAndShadow.second;
|
const auto& globalShadow = lightAndShadow.second;
|
||||||
if (globalShadow) {
|
if (globalShadow) {
|
||||||
const auto cascadeIndex = glm::clamp(_mode - Mode::ShadowCascade0Mode, 0, (int)globalShadow->getCascadeCount() - 1);
|
batch.setResourceTexture(Shadow, globalShadow->map);
|
||||||
batch.setResourceTexture(Shadow, globalShadow->getCascade(cascadeIndex).map);
|
|
||||||
batch.setUniformBuffer(ShadowTransform, globalShadow->getBuffer());
|
batch.setUniformBuffer(ShadowTransform, globalShadow->getBuffer());
|
||||||
batch.setUniformBuffer(DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
|
batch.setUniformBuffer(DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,12 @@ signals:
|
||||||
|
|
||||||
class DebugDeferredBuffer {
|
class DebugDeferredBuffer {
|
||||||
public:
|
public:
|
||||||
using Inputs = render::VaryingSet6<DeferredFramebufferPointer, LinearDepthFramebufferPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, VelocityFramebufferPointer, DeferredFrameTransformPointer>;
|
using Inputs = render::VaryingSet6<DeferredFramebufferPointer,
|
||||||
|
LinearDepthFramebufferPointer,
|
||||||
|
SurfaceGeometryFramebufferPointer,
|
||||||
|
AmbientOcclusionFramebufferPointer,
|
||||||
|
VelocityFramebufferPointer,
|
||||||
|
DeferredFrameTransformPointer>;
|
||||||
using Config = DebugDeferredBufferConfig;
|
using Config = DebugDeferredBufferConfig;
|
||||||
using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>;
|
using JobModel = render::Job::ModelI<DebugDeferredBuffer, Inputs, Config>;
|
||||||
|
|
||||||
|
@ -52,7 +57,8 @@ public:
|
||||||
protected:
|
protected:
|
||||||
friend class DebugDeferredBufferConfig;
|
friend class DebugDeferredBufferConfig;
|
||||||
|
|
||||||
enum Mode : uint8_t {
|
enum Mode : uint8_t
|
||||||
|
{
|
||||||
// Use Mode suffix to avoid collisions
|
// Use Mode suffix to avoid collisions
|
||||||
Off = 0,
|
Off = 0,
|
||||||
DepthMode,
|
DepthMode,
|
||||||
|
@ -92,6 +98,10 @@ private:
|
||||||
Mode _mode{ Off };
|
Mode _mode{ Off };
|
||||||
glm::vec4 _size;
|
glm::vec4 _size;
|
||||||
|
|
||||||
|
#include "debug_deferred_buffer_shared.slh"
|
||||||
|
|
||||||
|
using ParametersBuffer = gpu::StructBuffer<DebugParameters>;
|
||||||
|
|
||||||
struct CustomPipeline {
|
struct CustomPipeline {
|
||||||
gpu::PipelinePointer pipeline;
|
gpu::PipelinePointer pipeline;
|
||||||
mutable QFileInfo info;
|
mutable QFileInfo info;
|
||||||
|
@ -103,9 +113,10 @@ private:
|
||||||
const gpu::PipelinePointer& getPipeline(Mode mode, std::string customFile = std::string());
|
const gpu::PipelinePointer& getPipeline(Mode mode, std::string customFile = std::string());
|
||||||
std::string getShaderSourceCode(Mode mode, std::string customFile = std::string());
|
std::string getShaderSourceCode(Mode mode, std::string customFile = std::string());
|
||||||
|
|
||||||
|
ParametersBuffer _parameters;
|
||||||
StandardPipelines _pipelines;
|
StandardPipelines _pipelines;
|
||||||
CustomPipelines _customPipelines;
|
CustomPipelines _customPipelines;
|
||||||
int _geometryId { 0 };
|
int _geometryId{ 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DebugDeferredBuffer_h
|
#endif // hifi_DebugDeferredBuffer_h
|
|
@ -68,7 +68,7 @@ enum DeferredShader_MapSlot {
|
||||||
SCATTERING_SPECULAR_UNIT = 9,
|
SCATTERING_SPECULAR_UNIT = 9,
|
||||||
SKYBOX_MAP_UNIT = render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP, // unit = 10
|
SKYBOX_MAP_UNIT = render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP, // unit = 10
|
||||||
SHADOW_MAP_UNIT = 11,
|
SHADOW_MAP_UNIT = 11,
|
||||||
nextAvailableUnit = SHADOW_MAP_UNIT + SHADOW_CASCADE_MAX_COUNT
|
nextAvailableUnit = SHADOW_MAP_UNIT
|
||||||
};
|
};
|
||||||
enum DeferredShader_BufferSlot {
|
enum DeferredShader_BufferSlot {
|
||||||
DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0,
|
DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0,
|
||||||
|
@ -534,9 +534,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
||||||
|
|
||||||
// Bind the shadow buffers
|
// Bind the shadow buffers
|
||||||
if (globalShadow) {
|
if (globalShadow) {
|
||||||
for (unsigned int i = 0; i < globalShadow->getCascadeCount(); i++) {
|
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->map);
|
||||||
batch.setResourceTexture(SHADOW_MAP_UNIT+i, globalShadow->getCascade(i).map);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto program = deferredLightingEffect->_directionalSkyboxLight;
|
auto program = deferredLightingEffect->_directionalSkyboxLight;
|
||||||
|
|
|
@ -74,8 +74,6 @@ LightStage::Shadow::Cascade::Cascade() :
|
||||||
_frustum{ std::make_shared<ViewFrustum>() },
|
_frustum{ std::make_shared<ViewFrustum>() },
|
||||||
_minDistance{ 0.0f },
|
_minDistance{ 0.0f },
|
||||||
_maxDistance{ 20.0f } {
|
_maxDistance{ 20.0f } {
|
||||||
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
|
|
||||||
map = framebuffer->getDepthStencilBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const glm::mat4& LightStage::Shadow::Cascade::getView() const {
|
const glm::mat4& LightStage::Shadow::Cascade::getView() const {
|
||||||
|
@ -127,8 +125,29 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsi
|
||||||
Schema schema;
|
Schema schema;
|
||||||
schema.cascadeCount = cascadeCount;
|
schema.cascadeCount = cascadeCount;
|
||||||
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
|
_schemaBuffer = std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema);
|
||||||
|
|
||||||
|
// Create shadow cascade texture array
|
||||||
|
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); // Depth32 texel format
|
||||||
|
map = gpu::TexturePointer(gpu::Texture::createRenderBufferArray(depthFormat, MAP_SIZE, MAP_SIZE, cascadeCount));
|
||||||
|
gpu::Sampler::Desc samplerDesc;
|
||||||
|
samplerDesc._borderColor = glm::vec4(1.0f);
|
||||||
|
samplerDesc._wrapModeU = gpu::Sampler::WRAP_BORDER;
|
||||||
|
samplerDesc._wrapModeV = gpu::Sampler::WRAP_BORDER;
|
||||||
|
samplerDesc._filter = gpu::Sampler::FILTER_MIN_MAG_LINEAR;
|
||||||
|
samplerDesc._comparisonFunc = gpu::LESS;
|
||||||
|
|
||||||
|
map->setSampler(gpu::Sampler(samplerDesc));
|
||||||
|
|
||||||
_cascades.resize(cascadeCount);
|
_cascades.resize(cascadeCount);
|
||||||
|
|
||||||
|
for (uint cascadeIndex=0; cascadeIndex < cascadeCount; cascadeIndex++) {
|
||||||
|
auto& cascade = _cascades[cascadeIndex];
|
||||||
|
std::string name = "Shadowmap Cascade ";
|
||||||
|
name += '0' + cascadeIndex;
|
||||||
|
cascade.framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(name));
|
||||||
|
cascade.framebuffer->setDepthBuffer(map, depthFormat, cascadeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
setMaxDistance(maxDistance);
|
setMaxDistance(maxDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,6 @@ public:
|
||||||
Cascade();
|
Cascade();
|
||||||
|
|
||||||
gpu::FramebufferPointer framebuffer;
|
gpu::FramebufferPointer framebuffer;
|
||||||
gpu::TexturePointer map;
|
|
||||||
|
|
||||||
const std::shared_ptr<ViewFrustum>& getFrustum() const { return _frustum; }
|
const std::shared_ptr<ViewFrustum>& getFrustum() const { return _frustum; }
|
||||||
|
|
||||||
|
@ -93,6 +92,8 @@ public:
|
||||||
|
|
||||||
const graphics::LightPointer& getLight() const { return _light; }
|
const graphics::LightPointer& getLight() const { return _light; }
|
||||||
|
|
||||||
|
gpu::TexturePointer map;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
#include "Shadows_shared.slh"
|
#include "Shadows_shared.slh"
|
||||||
|
|
|
@ -60,7 +60,7 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs&
|
||||||
if (_opaquePass) {
|
if (_opaquePass) {
|
||||||
gpu::doInBatch("DrawOverlay3D::run::clear", args->_context, [&](gpu::Batch& batch){
|
gpu::doInBatch("DrawOverlay3D::run::clear", args->_context, [&](gpu::Batch& batch){
|
||||||
batch.enableStereo(false);
|
batch.enableStereo(false);
|
||||||
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTHSTENCIL, glm::vec4(), 1.f, 0, false);
|
batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,7 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup");
|
const auto setupOutput = task.addJob<RenderShadowSetup>("ShadowSetup");
|
||||||
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(2);
|
const auto queryResolution = setupOutput.getN<RenderShadowSetup::Outputs>(1);
|
||||||
// Fetch and cull the items from the scene
|
// Fetch and cull the items from the scene
|
||||||
|
|
||||||
static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask);
|
static const auto shadowCasterReceiverFilter = ItemFilter::Builder::visibleWorldItems().withTypeShape().withOpaque().withoutLayered().withTagBits(tagBits, tagMask);
|
||||||
|
@ -248,10 +248,12 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende
|
||||||
const auto sortedShapes = task.addJob<DepthSortShapes>("DepthSortShadow", sortedPipelines, true);
|
const auto sortedShapes = task.addJob<DepthSortShapes>("DepthSortShadow", sortedPipelines, true);
|
||||||
|
|
||||||
render::Varying cascadeFrustums[SHADOW_CASCADE_MAX_COUNT] = {
|
render::Varying cascadeFrustums[SHADOW_CASCADE_MAX_COUNT] = {
|
||||||
ViewFrustumPointer(),
|
ViewFrustumPointer()
|
||||||
ViewFrustumPointer(),
|
#if SHADOW_CASCADE_MAX_COUNT>1
|
||||||
|
,ViewFrustumPointer(),
|
||||||
ViewFrustumPointer(),
|
ViewFrustumPointer(),
|
||||||
ViewFrustumPointer()
|
ViewFrustumPointer()
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
|
||||||
|
@ -293,13 +295,15 @@ RenderShadowSetup::RenderShadowSetup() :
|
||||||
|
|
||||||
void RenderShadowSetup::configure(const Config& configuration) {
|
void RenderShadowSetup::configure(const Config& configuration) {
|
||||||
setConstantBias(0, configuration.constantBias0);
|
setConstantBias(0, configuration.constantBias0);
|
||||||
setConstantBias(1, configuration.constantBias1);
|
|
||||||
setConstantBias(2, configuration.constantBias2);
|
|
||||||
setConstantBias(3, configuration.constantBias3);
|
|
||||||
setSlopeBias(0, configuration.slopeBias0);
|
setSlopeBias(0, configuration.slopeBias0);
|
||||||
|
#if SHADOW_CASCADE_MAX_COUNT>1
|
||||||
|
setConstantBias(1, configuration.constantBias1);
|
||||||
setSlopeBias(1, configuration.slopeBias1);
|
setSlopeBias(1, configuration.slopeBias1);
|
||||||
|
setConstantBias(2, configuration.constantBias2);
|
||||||
setSlopeBias(2, configuration.slopeBias2);
|
setSlopeBias(2, configuration.slopeBias2);
|
||||||
|
setConstantBias(3, configuration.constantBias3);
|
||||||
setSlopeBias(3, configuration.slopeBias3);
|
setSlopeBias(3, configuration.slopeBias3);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) {
|
void RenderShadowSetup::setConstantBias(int cascadeIndex, float value) {
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
#define SHADOW_SCREEN_SPACE_DITHER 1
|
#define SHADOW_SCREEN_SPACE_DITHER 1
|
||||||
|
|
||||||
// the shadow texture
|
// the shadow texture
|
||||||
uniform sampler2DShadow shadowMaps[SHADOW_CASCADE_MAX_COUNT];
|
uniform sampler2DArrayShadow shadowMaps;
|
||||||
|
|
||||||
// Sample the shadowMap with PCF (built-in)
|
// Sample the shadowMap with PCF (built-in)
|
||||||
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {
|
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {
|
||||||
return texture(shadowMaps[cascadeIndex], shadowTexcoord);
|
return texture(shadowMaps, vec4(shadowTexcoord.xy, cascadeIndex, shadowTexcoord.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 PCFkernel[4] = vec2[4](
|
vec2 PCFkernel[4] = vec2[4](
|
||||||
|
|
|
@ -23,11 +23,18 @@ uniform sampler2D occlusionMap;
|
||||||
uniform sampler2D occlusionBlurredMap;
|
uniform sampler2D occlusionBlurredMap;
|
||||||
uniform sampler2D scatteringMap;
|
uniform sampler2D scatteringMap;
|
||||||
uniform sampler2D velocityMap;
|
uniform sampler2D velocityMap;
|
||||||
|
uniform sampler2DArrayShadow shadowMaps;
|
||||||
|
|
||||||
<@include ShadowCore.slh@>
|
<@include ShadowCore.slh@>
|
||||||
|
|
||||||
<$declareDeferredCurvature()$>
|
<$declareDeferredCurvature()$>
|
||||||
|
|
||||||
|
<@include debug_deferred_buffer_shared.slh@>
|
||||||
|
|
||||||
|
layout(std140) uniform parametersBuffer {
|
||||||
|
DebugParameters parameters;
|
||||||
|
};
|
||||||
|
|
||||||
float curvatureAO(float k) {
|
float curvatureAO(float k) {
|
||||||
return 1.0f - (0.0022f * k * k) + (0.0776f * k) + 0.7369f;
|
return 1.0f - (0.0022f * k * k) + (0.0776f * k) + 0.7369f;
|
||||||
}
|
}
|
||||||
|
|
17
libraries/render-utils/src/debug_deferred_buffer_shared.slh
Normal file
17
libraries/render-utils/src/debug_deferred_buffer_shared.slh
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// glsl / C++ compatible source as interface for FadeEffect
|
||||||
|
#ifdef __cplusplus
|
||||||
|
# define INT32 glm::int32
|
||||||
|
#else
|
||||||
|
# define INT32 int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct DebugParameters
|
||||||
|
{
|
||||||
|
INT32 _shadowCascadeIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
// <@if 1@>
|
||||||
|
// Trigger Scribe include
|
||||||
|
// <@endif@> <!def that !>
|
||||||
|
//
|
||||||
|
|
|
@ -370,10 +370,13 @@ void CullShapeBounds::run(const RenderContextPointer& renderContext, const Input
|
||||||
const auto& inShapes = inputs.get0();
|
const auto& inShapes = inputs.get0();
|
||||||
const auto& cullFilter = inputs.get1();
|
const auto& cullFilter = inputs.get1();
|
||||||
const auto& boundsFilter = inputs.get2();
|
const auto& boundsFilter = inputs.get2();
|
||||||
const auto& antiFrustum = inputs.get3();
|
ViewFrustumPointer antiFrustum;
|
||||||
auto& outShapes = outputs.edit0();
|
auto& outShapes = outputs.edit0();
|
||||||
auto& outBounds = outputs.edit1();
|
auto& outBounds = outputs.edit1();
|
||||||
|
|
||||||
|
if (!inputs[3].isNull()) {
|
||||||
|
antiFrustum = inputs.get3();
|
||||||
|
}
|
||||||
outShapes.clear();
|
outShapes.clear();
|
||||||
outBounds = AABox();
|
outBounds = AABox();
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,21 @@ void registerAudioMetaTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterMetaType(engine, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue);
|
qScriptRegisterMetaType(engine, soundSharedPointerToScriptValue, soundSharedPointerFromScriptValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AudioScriptingInterface::setLocalAudioInterface(AbstractAudioInterface* audioInterface) {
|
||||||
|
if (_localAudioInterface) {
|
||||||
|
disconnect(_localAudioInterface, &AbstractAudioInterface::isStereoInputChanged,
|
||||||
|
this, &AudioScriptingInterface::isStereoInputChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
_localAudioInterface = audioInterface;
|
||||||
|
|
||||||
|
if (_localAudioInterface) {
|
||||||
|
connect(_localAudioInterface, &AbstractAudioInterface::isStereoInputChanged,
|
||||||
|
this, &AudioScriptingInterface::isStereoInputChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ScriptAudioInjector* AudioScriptingInterface::playSystemSound(SharedSoundPointer sound, const QVector3D& position) {
|
ScriptAudioInjector* AudioScriptingInterface::playSystemSound(SharedSoundPointer sound, const QVector3D& position) {
|
||||||
AudioInjectorOptions options;
|
AudioInjectorOptions options;
|
||||||
options.position = glm::vec3(position.x(), position.y(), position.z());
|
options.position = glm::vec3(position.x(), position.y(), position.z());
|
||||||
|
@ -61,11 +76,10 @@ ScriptAudioInjector* AudioScriptingInterface::playSound(SharedSoundPointer sound
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioScriptingInterface::setStereoInput(bool stereo) {
|
bool AudioScriptingInterface::setStereoInput(bool stereo) {
|
||||||
bool stereoInputChanged = false;
|
|
||||||
if (_localAudioInterface) {
|
if (_localAudioInterface) {
|
||||||
stereoInputChanged = _localAudioInterface->setIsStereoInput(stereo);
|
QMetaObject::invokeMethod(_localAudioInterface, "setIsStereoInput", Q_ARG(bool, stereo));
|
||||||
}
|
}
|
||||||
return stereoInputChanged;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioScriptingInterface::isStereoInput() {
|
bool AudioScriptingInterface::isStereoInput() {
|
||||||
|
|
|
@ -23,9 +23,11 @@ class AudioScriptingInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
SINGLETON_DEPENDENCY
|
SINGLETON_DEPENDENCY
|
||||||
|
|
||||||
|
Q_PROPERTY(bool isStereoInput READ isStereoInput WRITE setStereoInput NOTIFY isStereoInputChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~AudioScriptingInterface() {}
|
virtual ~AudioScriptingInterface() {}
|
||||||
void setLocalAudioInterface(AbstractAudioInterface* audioInterface) { _localAudioInterface = audioInterface; }
|
void setLocalAudioInterface(AbstractAudioInterface* audioInterface);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AudioScriptingInterface() {}
|
AudioScriptingInterface() {}
|
||||||
|
@ -114,6 +116,13 @@ signals:
|
||||||
*/
|
*/
|
||||||
void inputReceived(const QByteArray& inputSamples);
|
void inputReceived(const QByteArray& inputSamples);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* @function Audio.isStereoInputChanged
|
||||||
|
* @param {boolean} isStereo
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void isStereoInputChanged(bool isStereo);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AbstractAudioInterface* _localAudioInterface { nullptr };
|
AbstractAudioInterface* _localAudioInterface { nullptr };
|
||||||
};
|
};
|
||||||
|
|
|
@ -1639,22 +1639,24 @@ QVariantMap ScriptEngine::fetchModuleSource(const QString& modulePath, const boo
|
||||||
loader->start(MAX_RETRIES);
|
loader->start(MAX_RETRIES);
|
||||||
|
|
||||||
if (!loader->isFinished()) {
|
if (!loader->isFinished()) {
|
||||||
QTimer monitor;
|
// This lambda can get called AFTER this local scope has completed.
|
||||||
QEventLoop loop;
|
// This is why we pass smart ptrs to the lambda instead of references to local variables.
|
||||||
QObject::connect(loader, &BatchLoader::finished, this, [&monitor, &loop]{
|
auto monitor = std::make_shared<QTimer>();
|
||||||
monitor.stop();
|
auto loop = std::make_shared<QEventLoop>();
|
||||||
loop.quit();
|
QObject::connect(loader, &BatchLoader::finished, this, [monitor, loop] {
|
||||||
|
monitor->stop();
|
||||||
|
loop->quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
// this helps detect the case where stop() is invoked during the download
|
// this helps detect the case where stop() is invoked during the download
|
||||||
// but not seen in time to abort processing in onload()...
|
// but not seen in time to abort processing in onload()...
|
||||||
connect(&monitor, &QTimer::timeout, this, [this, &loop]{
|
connect(monitor.get(), &QTimer::timeout, this, [this, loop] {
|
||||||
if (isStopping()) {
|
if (isStopping()) {
|
||||||
loop.exit(-1);
|
loop->exit(-1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
monitor.start(500);
|
monitor->start(500);
|
||||||
loop.exec();
|
loop->exec();
|
||||||
}
|
}
|
||||||
loader->deleteLater();
|
loader->deleteLater();
|
||||||
return req;
|
return req;
|
||||||
|
|
|
@ -84,7 +84,8 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection);
|
connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SIGNAL(visibleChanged()), Qt::QueuedConnection);
|
||||||
connect(object, SIGNAL(presentationModeChanged()), this, SIGNAL(presentationModeChanged()), Qt::QueuedConnection);
|
connect(object, SIGNAL(presentationModeChanged()), this, SIGNAL(presentationModeChanged()), Qt::QueuedConnection);
|
||||||
connect(object, SIGNAL(titleChanged()), this, SIGNAL(titleChanged()), Qt::QueuedConnection);
|
connect(object, SIGNAL(titleChanged()), this, SIGNAL(titleChanged()), Qt::QueuedConnection);
|
||||||
|
connect(object, SIGNAL(windowClosed()), this, SIGNAL(closed()), Qt::QueuedConnection);
|
||||||
|
connect(object, SIGNAL(selfDestruct()), this, SLOT(close()), Qt::QueuedConnection);
|
||||||
|
|
||||||
QUrl sourceURL{ sourceUrl };
|
QUrl sourceURL{ sourceUrl };
|
||||||
// If the passed URL doesn't correspond to a known scheme, assume it's a local file path
|
// If the passed URL doesn't correspond to a known scheme, assume it's a local file path
|
||||||
|
@ -182,7 +183,6 @@ bool InteractiveWindow::isVisible() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The tool window itself has special logic based on whether any tabs are enabled
|
|
||||||
if (_qmlWindow.isNull()) {
|
if (_qmlWindow.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,46 +47,19 @@ using namespace InteractiveWindowEnums;
|
||||||
* @hifi-interface
|
* @hifi-interface
|
||||||
* @hifi-client-en
|
* @hifi-client-en
|
||||||
*
|
*
|
||||||
* @property {string} mode
|
* @property {string} title
|
||||||
|
* @property {Vec2} position
|
||||||
|
* @property {Vec2} size
|
||||||
|
* @property {boolean} visible
|
||||||
|
* @property {Desktop.PresentationMode} presentationMode
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class InteractiveWindow : public QObject {
|
class InteractiveWindow : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* title of the window
|
|
||||||
*
|
|
||||||
* @name InteractiveWindow#title
|
|
||||||
* @type string
|
|
||||||
* @default "InteractiveWindow"
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
|
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* window position on current desktop
|
|
||||||
*
|
|
||||||
* @name InteractiveWindow#position
|
|
||||||
* @type Vec2
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
|
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* window size
|
|
||||||
*
|
|
||||||
* @name InteractiveWindow#size
|
|
||||||
* @type Vec2
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
|
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
|
||||||
|
|
||||||
/**jsdoc
|
|
||||||
* visibility of the window
|
|
||||||
*
|
|
||||||
* @name InteractiveWindow#visible
|
|
||||||
* @type boolean
|
|
||||||
* @default true
|
|
||||||
* @example
|
|
||||||
* // Toggle window visiblity;
|
|
||||||
* interactiveWindow.visible = !interactiveWindow.visible;
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
|
Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
|
||||||
Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
|
Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,11 @@ void Space::processResets(const Transaction::Resets& transactions) {
|
||||||
for (auto& reset : transactions) {
|
for (auto& reset : transactions) {
|
||||||
// Access the true item
|
// Access the true item
|
||||||
auto proxyID = std::get<0>(reset);
|
auto proxyID = std::get<0>(reset);
|
||||||
|
|
||||||
|
// Guard against proxyID being past the end of the list.
|
||||||
|
if (proxyID < 0 || proxyID >= (int32_t)_proxies.size() || proxyID >= (int32_t)_owners.size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto& item = _proxies[proxyID];
|
auto& item = _proxies[proxyID];
|
||||||
|
|
||||||
// Reset the item with a new payload
|
// Reset the item with a new payload
|
||||||
|
|
|
@ -2421,7 +2421,6 @@ function selectParticleEntity(entityID) {
|
||||||
particleExplorerTool.createWebView();
|
particleExplorerTool.createWebView();
|
||||||
|
|
||||||
particleExplorerTool.setActiveParticleEntity(entityID);
|
particleExplorerTool.setActiveParticleEntity(entityID);
|
||||||
particleExplorerTool.setActiveParticleProperties(properties);
|
|
||||||
|
|
||||||
// Switch to particle explorer
|
// Switch to particle explorer
|
||||||
var selectTabMethod = { method: 'selectTab', params: { id: 'particle' } };
|
var selectTabMethod = { method: 'selectTab', params: { id: 'particle' } };
|
||||||
|
|
|
@ -101,6 +101,7 @@ function onWebEventReceived(event) {
|
||||||
|
|
||||||
// If user provides input during a sit, the avatar animation state should be restored
|
// If user provides input during a sit, the avatar animation state should be restored
|
||||||
Controller.keyPressEvent.connect(restoreAnimation);
|
Controller.keyPressEvent.connect(restoreAnimation);
|
||||||
|
Controller.enableMapping(eventMappingName);
|
||||||
MyAvatar.overrideAnimation(ANIMATIONS[emoteName].url, FPS, false, 0, frameCount);
|
MyAvatar.overrideAnimation(ANIMATIONS[emoteName].url, FPS, false, 0, frameCount);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -132,6 +133,7 @@ function restoreAnimation() {
|
||||||
|
|
||||||
// Make sure the input is disconnected after animations are restored so it doesn't affect any emotes other than sit
|
// Make sure the input is disconnected after animations are restored so it doesn't affect any emotes other than sit
|
||||||
Controller.keyPressEvent.disconnect(restoreAnimation);
|
Controller.keyPressEvent.disconnect(restoreAnimation);
|
||||||
|
Controller.disableMapping(eventMappingName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note peek() so as to not interfere with other mappings.
|
// Note peek() so as to not interfere with other mappings.
|
||||||
|
@ -151,7 +153,7 @@ eventMapping.from(Controller.Standard.RS).peek().to(restoreAnimation);
|
||||||
eventMapping.from(Controller.Standard.RightGrip).peek().to(restoreAnimation);
|
eventMapping.from(Controller.Standard.RightGrip).peek().to(restoreAnimation);
|
||||||
eventMapping.from(Controller.Standard.Back).peek().to(restoreAnimation);
|
eventMapping.from(Controller.Standard.Back).peek().to(restoreAnimation);
|
||||||
eventMapping.from(Controller.Standard.Start).peek().to(restoreAnimation);
|
eventMapping.from(Controller.Standard.Start).peek().to(restoreAnimation);
|
||||||
Controller.enableMapping(eventMappingName);
|
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onClicked);
|
||||||
tablet.screenChanged.connect(onScreenChanged);
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
|
|
|
@ -134,12 +134,17 @@ EntityListTool = function() {
|
||||||
url: url,
|
url: url,
|
||||||
locked: properties.locked,
|
locked: properties.locked,
|
||||||
visible: properties.visible,
|
visible: properties.visible,
|
||||||
verticesCount: valueIfDefined(properties.renderInfo.verticesCount),
|
verticesCount: (properties.renderInfo !== undefined ?
|
||||||
texturesCount: valueIfDefined(properties.renderInfo.texturesCount),
|
valueIfDefined(properties.renderInfo.verticesCount) : ""),
|
||||||
texturesSize: valueIfDefined(properties.renderInfo.texturesSize),
|
texturesCount: (properties.renderInfo !== undefined ?
|
||||||
hasTransparent: valueIfDefined(properties.renderInfo.hasTransparent),
|
valueIfDefined(properties.renderInfo.texturesCount) : ""),
|
||||||
|
texturesSize: (properties.renderInfo !== undefined ?
|
||||||
|
valueIfDefined(properties.renderInfo.texturesSize) : ""),
|
||||||
|
hasTransparent: (properties.renderInfo !== undefined ?
|
||||||
|
valueIfDefined(properties.renderInfo.hasTransparent) : ""),
|
||||||
isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false,
|
isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false,
|
||||||
drawCalls: valueIfDefined(properties.renderInfo.drawCalls),
|
drawCalls: (properties.renderInfo !== undefined ?
|
||||||
|
valueIfDefined(properties.renderInfo.drawCalls) : ""),
|
||||||
hasScript: properties.script !== ""
|
hasScript: properties.script !== ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,12 +61,18 @@ function HifiEntityUI(parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
this.sendPackage = {};
|
||||||
this.settingsUpdateLock = false;
|
this.settingsUpdateLock = false;
|
||||||
this.webBridgeSync = _.debounce(function (id, val) {
|
this.webBridgeSync = function(id, val) {
|
||||||
if (self.EventBridge && !self.settingsUpdateLock) {
|
if (!this.settingsUpdateLock) {
|
||||||
var sendPackage = {};
|
this.sendPackage[id] = val;
|
||||||
sendPackage[id] = val;
|
this.webBridgeSyncDebounce();
|
||||||
self.submitChanges(sendPackage);
|
}
|
||||||
|
};
|
||||||
|
this.webBridgeSyncDebounce = _.debounce(function () {
|
||||||
|
if (self.EventBridge) {
|
||||||
|
self.submitChanges(self.sendPackage);
|
||||||
|
self.sendPackage = {};
|
||||||
}
|
}
|
||||||
}, DEBOUNCE_TIMEOUT);
|
}, DEBOUNCE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
@ -159,7 +165,6 @@ HifiEntityUI.prototype = {
|
||||||
var self = this;
|
var self = this;
|
||||||
var fields = document.getElementsByTagName("input");
|
var fields = document.getElementsByTagName("input");
|
||||||
|
|
||||||
self.settingsUpdateLock = true;
|
|
||||||
if (!currentProperties.locked) {
|
if (!currentProperties.locked) {
|
||||||
for (var i = 0; i < fields.length; i++) {
|
for (var i = 0; i < fields.length; i++) {
|
||||||
fields[i].removeAttribute("disabled");
|
fields[i].removeAttribute("disabled");
|
||||||
|
@ -235,10 +240,6 @@ HifiEntityUI.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now unlocking settings Update lock for sending messages on callbacks.
|
|
||||||
setTimeout(function () {
|
|
||||||
self.settingsUpdateLock = false;
|
|
||||||
}, DEBOUNCE_TIMEOUT * 2.5);
|
|
||||||
},
|
},
|
||||||
connect: function (EventBridge) {
|
connect: function (EventBridge) {
|
||||||
this.EventBridge = EventBridge;
|
this.EventBridge = EventBridge;
|
||||||
|
@ -253,28 +254,9 @@ HifiEntityUI.prototype = {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
|
||||||
if (data.messageType === 'particle_settings') {
|
if (data.messageType === 'particle_settings') {
|
||||||
// Update settings
|
self.settingsUpdateLock = true;
|
||||||
var currentProperties = data.currentProperties;
|
self.fillFields(data.currentProperties);
|
||||||
// Update uninitialized variables
|
self.settingsUpdateLock = false;
|
||||||
if (!currentProperties.alphaStart) {
|
|
||||||
currentProperties.alphaStart = currentProperties.alpha;
|
|
||||||
}
|
|
||||||
if (!currentProperties.alphaFinish) {
|
|
||||||
currentProperties.alphaFinish = currentProperties.alpha;
|
|
||||||
}
|
|
||||||
if (!currentProperties.radiusStart) {
|
|
||||||
currentProperties.radiusStart = currentProperties.particleRadius;
|
|
||||||
}
|
|
||||||
if (!currentProperties.radiusFinish) {
|
|
||||||
currentProperties.radiusFinish = currentProperties.particleRadius;
|
|
||||||
}
|
|
||||||
if (!currentProperties.colorStart || !currentProperties.colorStart.red) {
|
|
||||||
currentProperties.colorStart = currentProperties.color;
|
|
||||||
}
|
|
||||||
if (!currentProperties.colorFinish || !currentProperties.colorFinish.red) {
|
|
||||||
currentProperties.colorFinish = currentProperties.color;
|
|
||||||
}
|
|
||||||
self.fillFields(currentProperties);
|
|
||||||
// Do expected property match with structure;
|
// Do expected property match with structure;
|
||||||
} else if (data.messageType === 'particle_close') {
|
} else if (data.messageType === 'particle_close') {
|
||||||
self.disableFields();
|
self.disableFields();
|
||||||
|
|
|
@ -17,7 +17,7 @@ var PARTICLE_EXPLORER_HTML_URL = Script.resolvePath('particleExplorer.html');
|
||||||
ParticleExplorerTool = function (createToolsWindow) {
|
ParticleExplorerTool = function (createToolsWindow) {
|
||||||
var that = {};
|
var that = {};
|
||||||
that.activeParticleEntity = 0;
|
that.activeParticleEntity = 0;
|
||||||
that.activeParticleProperties = {};
|
that.updatedActiveParticleProperties = {};
|
||||||
|
|
||||||
that.createWebView = function() {
|
that.createWebView = function() {
|
||||||
that.webView = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
that.webView = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
@ -37,50 +37,91 @@ ParticleExplorerTool = function (createToolsWindow) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
that.activeParticleEntity = 0;
|
that.activeParticleEntity = 0;
|
||||||
that.activeParticleProperties = {};
|
that.updatedActiveParticleProperties = {};
|
||||||
|
|
||||||
emitScriptEvent({
|
emitScriptEvent({
|
||||||
messageType: "particle_close"
|
messageType: "particle_close"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function sendActiveParticleProperties() {
|
function sendParticleProperties(properties) {
|
||||||
emitScriptEvent({
|
emitScriptEvent({
|
||||||
messageType: "particle_settings",
|
messageType: "particle_settings",
|
||||||
currentProperties: that.activeParticleProperties
|
currentProperties: properties
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendActiveParticleProperties() {
|
||||||
|
var properties = Entities.getEntityProperties(that.activeParticleEntity);
|
||||||
|
if (properties.emitOrientation) {
|
||||||
|
properties.emitOrientation = Quat.safeEulerAngles(properties.emitOrientation);
|
||||||
|
}
|
||||||
|
// Update uninitialized variables
|
||||||
|
if (isNaN(properties.alphaStart)) {
|
||||||
|
properties.alphaStart = properties.alpha;
|
||||||
|
}
|
||||||
|
if (isNaN(properties.alphaFinish)) {
|
||||||
|
properties.alphaFinish = properties.alpha;
|
||||||
|
}
|
||||||
|
if (isNaN(properties.radiusStart)) {
|
||||||
|
properties.radiusStart = properties.particleRadius;
|
||||||
|
}
|
||||||
|
if (isNaN(properties.radiusFinish)) {
|
||||||
|
properties.radiusFinish = properties.particleRadius;
|
||||||
|
}
|
||||||
|
if (isNaN(properties.colorStart.red)) {
|
||||||
|
properties.colorStart = properties.color;
|
||||||
|
}
|
||||||
|
if (isNaN(properties.colorFinish.red)) {
|
||||||
|
properties.colorFinish = properties.color;
|
||||||
|
}
|
||||||
|
sendParticleProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendUpdatedActiveParticleProperties() {
|
||||||
|
sendParticleProperties(that.updatedActiveParticleProperties);
|
||||||
|
that.updatedActiveParticleProperties = {};
|
||||||
|
}
|
||||||
|
|
||||||
that.webEventReceived = function(message) {
|
that.webEventReceived = function(message) {
|
||||||
var data = JSON.parse(message);
|
var data = JSON.parse(message);
|
||||||
if (data.messageType === "settings_update") {
|
if (data.messageType === "settings_update") {
|
||||||
if (data.updatedSettings.emitOrientation) {
|
var updatedSettings = data.updatedSettings;
|
||||||
data.updatedSettings.emitOrientation = Quat.fromVec3Degrees(data.updatedSettings.emitOrientation);
|
|
||||||
}
|
|
||||||
Entities.editEntity(that.activeParticleEntity, data.updatedSettings);
|
|
||||||
|
|
||||||
for (var key in data.updatedSettings) {
|
|
||||||
if (that.activeParticleProperties.hasOwnProperty(key)) {
|
|
||||||
that.activeParticleProperties[key] = data.updatedSettings[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var optionalProps = ["alphaStart", "alphaFinish", "radiusStart", "radiusFinish", "colorStart", "colorFinish"];
|
var optionalProps = ["alphaStart", "alphaFinish", "radiusStart", "radiusFinish", "colorStart", "colorFinish"];
|
||||||
var fallbackProps = ["alpha", "particleRadius", "color"];
|
var fallbackProps = ["alpha", "particleRadius", "color"];
|
||||||
var entityProps = Entities.getEntityProperties(that.activeParticleProperties, optionalProps);
|
for (var i = 0; i < optionalProps.length; i++) {
|
||||||
|
var fallbackProp = fallbackProps[Math.floor(i / 2)];
|
||||||
|
var optionalValue = updatedSettings[optionalProps[i]];
|
||||||
|
var fallbackValue = updatedSettings[fallbackProp];
|
||||||
|
if (optionalValue && fallbackValue) {
|
||||||
|
delete updatedSettings[optionalProps[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedSettings.emitOrientation) {
|
||||||
|
updatedSettings.emitOrientation = Quat.fromVec3Degrees(updatedSettings.emitOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entities.editEntity(that.activeParticleEntity, updatedSettings);
|
||||||
|
|
||||||
|
var entityProps = Entities.getEntityProperties(that.activeParticleEntity, optionalProps);
|
||||||
|
|
||||||
var needsUpdate = false;
|
var needsUpdate = false;
|
||||||
for (var i = 0; i < optionalProps.length; i++) {
|
for (var i = 0; i < optionalProps.length; i++) {
|
||||||
var fallback = fallbackProps[Math.floor(i / 2)];
|
var fallbackProp = fallbackProps[Math.floor(i / 2)];
|
||||||
if (data.updatedSettings[fallback]) {
|
var fallbackValue = updatedSettings[fallbackProp];
|
||||||
var prop = optionalProps[i];
|
if (fallbackValue) {
|
||||||
if (!that.activeParticleProperties[prop] || (fallback === "color" && !that.activeParticleProperties[prop].red)) {
|
var optionalProp = optionalProps[i];
|
||||||
that.activeParticleProperties[prop] = entityProps[fallback];
|
if ((fallbackProp !== "color" && isNaN(entityProps[optionalProp])) || (fallbackProp === "color" && isNaN(entityProps[optionalProp].red))) {
|
||||||
|
that.updatedActiveParticleProperties[optionalProp] = fallbackValue;
|
||||||
needsUpdate = true;
|
needsUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsUpdate) {
|
if (needsUpdate) {
|
||||||
sendActiveParticleProperties();
|
sendUpdatedActiveParticleProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (data.messageType === "page_loaded") {
|
} else if (data.messageType === "page_loaded") {
|
||||||
|
@ -90,10 +131,6 @@ ParticleExplorerTool = function (createToolsWindow) {
|
||||||
|
|
||||||
that.setActiveParticleEntity = function(id) {
|
that.setActiveParticleEntity = function(id) {
|
||||||
that.activeParticleEntity = id;
|
that.activeParticleEntity = id;
|
||||||
};
|
|
||||||
|
|
||||||
that.setActiveParticleProperties = function(properties) {
|
|
||||||
that.activeParticleProperties = properties;
|
|
||||||
sendActiveParticleProperties();
|
sendActiveParticleProperties();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ var SNAPSHOT_DELAY = 500; // 500ms
|
||||||
var FINISH_SOUND_DELAY = 350;
|
var FINISH_SOUND_DELAY = 350;
|
||||||
var resetOverlays;
|
var resetOverlays;
|
||||||
var reticleVisible;
|
var reticleVisible;
|
||||||
var clearOverlayWhenMoving;
|
|
||||||
|
|
||||||
var buttonName = "SNAP";
|
var buttonName = "SNAP";
|
||||||
var buttonConnected = false;
|
var buttonConnected = false;
|
||||||
|
@ -286,6 +285,7 @@ function printToPolaroid(image_url) {
|
||||||
var polaroid_url = image_url;
|
var polaroid_url = image_url;
|
||||||
|
|
||||||
var model_pos = Vec3.sum(MyAvatar.position, Vec3.multiply(1.25, Quat.getForward(MyAvatar.orientation)));
|
var model_pos = Vec3.sum(MyAvatar.position, Vec3.multiply(1.25, Quat.getForward(MyAvatar.orientation)));
|
||||||
|
model_pos.y += 0.2; // Print a bit closer to the head
|
||||||
|
|
||||||
var model_q1 = MyAvatar.orientation;
|
var model_q1 = MyAvatar.orientation;
|
||||||
var model_q2 = Quat.angleAxis(90, Quat.getRight(model_q1));
|
var model_q2 = Quat.angleAxis(90, Quat.getRight(model_q1));
|
||||||
|
@ -295,11 +295,11 @@ function printToPolaroid(image_url) {
|
||||||
"type": 'Model',
|
"type": 'Model',
|
||||||
"shapeType": 'box',
|
"shapeType": 'box',
|
||||||
|
|
||||||
"name": "New Snapshot",
|
"name": "Snapshot by " + MyAvatar.sessionDisplayName,
|
||||||
"description": "Printed from Snaps",
|
"description": "Printed from SNAP app",
|
||||||
"modelURL": POLAROID_MODEL_URL,
|
"modelURL": POLAROID_MODEL_URL,
|
||||||
|
|
||||||
"dimensions": { "x": 0.5667, "y": 0.0212, "z": 0.4176 },
|
"dimensions": { "x": 0.5667, "y": 0.042, "z": 0.4176 },
|
||||||
"position": model_pos,
|
"position": model_pos,
|
||||||
"rotation": model_rot,
|
"rotation": model_rot,
|
||||||
|
|
||||||
|
@ -307,9 +307,9 @@ function printToPolaroid(image_url) {
|
||||||
|
|
||||||
"density": 200,
|
"density": 200,
|
||||||
"restitution": 0.15,
|
"restitution": 0.15,
|
||||||
"gravity": { "x": 0, "y": -4.5, "z": 0 },
|
"gravity": { "x": 0, "y": -2.5, "z": 0 },
|
||||||
|
|
||||||
"velocity": { "x": 0, "y": 3.5, "z": 0 },
|
"velocity": { "x": 0, "y": 1.95, "z": 0 },
|
||||||
"angularVelocity": { "x": -1.0, "y": 0, "z": -1.3 },
|
"angularVelocity": { "x": -1.0, "y": 0, "z": -1.3 },
|
||||||
|
|
||||||
"dynamic": true,
|
"dynamic": true,
|
||||||
|
@ -438,11 +438,6 @@ function takeSnapshot() {
|
||||||
isUploadingPrintableStill = true;
|
isUploadingPrintableStill = true;
|
||||||
updatePrintPermissions();
|
updatePrintPermissions();
|
||||||
|
|
||||||
// Raising the desktop for the share dialog at end will interact badly with clearOverlayWhenMoving.
|
|
||||||
// Turn it off now, before we start futzing with things (and possibly moving).
|
|
||||||
clearOverlayWhenMoving = MyAvatar.getClearOverlayWhenMoving(); // Do not use Settings. MyAvatar keeps a separate copy.
|
|
||||||
MyAvatar.setClearOverlayWhenMoving(false);
|
|
||||||
|
|
||||||
// We will record snapshots based on the starting location. That could change, e.g., when recording a .gif.
|
// We will record snapshots based on the starting location. That could change, e.g., when recording a .gif.
|
||||||
// Even the domainID could change (e.g., if the user falls into a teleporter while recording).
|
// Even the domainID could change (e.g., if the user falls into a teleporter while recording).
|
||||||
href = location.href;
|
href = location.href;
|
||||||
|
@ -544,9 +539,6 @@ function stillSnapshotTaken(pathStillSnapshot, notify) {
|
||||||
// last element in data array tells dialog whether we can share or not
|
// last element in data array tells dialog whether we can share or not
|
||||||
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
||||||
|
|
||||||
if (clearOverlayWhenMoving) {
|
|
||||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
|
||||||
}
|
|
||||||
HMD.openTablet();
|
HMD.openTablet();
|
||||||
|
|
||||||
isDomainOpen(domainID, function (canShare) {
|
isDomainOpen(domainID, function (canShare) {
|
||||||
|
@ -590,9 +582,6 @@ function processingGifStarted(pathStillSnapshot) {
|
||||||
}
|
}
|
||||||
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
||||||
|
|
||||||
if (clearOverlayWhenMoving) {
|
|
||||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
|
||||||
}
|
|
||||||
HMD.openTablet();
|
HMD.openTablet();
|
||||||
|
|
||||||
isDomainOpen(domainID, function (canShare) {
|
isDomainOpen(domainID, function (canShare) {
|
||||||
|
|
Loading…
Reference in a new issue