mirror of
https://github.com/lubosz/overte.git
synced 2025-04-10 04:28:59 +02:00
Merged with zvork fix
This commit is contained in:
commit
a6cbc44885
45 changed files with 295 additions and 210 deletions
|
@ -228,7 +228,7 @@ Java_io_highfidelity_hifiinterface_fragment_LoginFragment_nativeLogin(JNIEnv *en
|
|||
env->ReleaseStringUTFChars(username_, c_username);
|
||||
env->ReleaseStringUTFChars(password_, c_password);
|
||||
|
||||
auto accountManager = AndroidHelper::instance().getAccountManager();
|
||||
auto accountManager = DependencyManager::get<AccountManager>();
|
||||
|
||||
__loginCompletedListener = QAndroidJniObject(instance);
|
||||
__usernameChangedListener = QAndroidJniObject(usernameChangedListener);
|
||||
|
@ -270,18 +270,18 @@ Java_io_highfidelity_hifiinterface_SplashActivity_registerLoadCompleteListener(J
|
|||
}
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_nativeIsLoggedIn(JNIEnv *env, jobject instance) {
|
||||
return AndroidHelper::instance().getAccountManager()->isLoggedIn();
|
||||
return DependencyManager::get<AccountManager>()->isLoggedIn();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_nativeLogout(JNIEnv *env, jobject instance) {
|
||||
AndroidHelper::instance().getAccountManager()->logout();
|
||||
DependencyManager::get<AccountManager>()->logout();
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_io_highfidelity_hifiinterface_MainActivity_nativeGetDisplayName(JNIEnv *env,
|
||||
jobject instance) {
|
||||
QString username = AndroidHelper::instance().getAccountManager()->getAccountInfo().getUsername();
|
||||
QString username = DependencyManager::get<AccountManager>()->getAccountInfo().getUsername();
|
||||
return env->NewStringUTF(username.toLatin1().data());
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ macro(optional_win_executable_signing)
|
|||
# setup a post build command to sign the executable
|
||||
add_custom_command(
|
||||
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 ()
|
||||
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.
|
||||
; We need to sign it if it's a production or PR build.
|
||||
!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
|
||||
|
||||
; Good. Now we can carry on writing the real installer.
|
||||
|
|
|
@ -129,12 +129,10 @@ Rectangle {
|
|||
id: stereoMic
|
||||
spacing: muteMic.spacing;
|
||||
text: qsTr("Enable stereo input");
|
||||
checked: AudioScriptingInterface.isStereoInput();
|
||||
checked: AudioScriptingInterface.isStereoInput;
|
||||
onClicked: {
|
||||
var success = AudioScriptingInterface.setStereoInput(checked);
|
||||
if (!success) {
|
||||
checked = !checked;
|
||||
}
|
||||
AudioScriptingInterface.isStereoInput = checked;
|
||||
checked = Qt.binding(function() { return AudioScriptingInterface.isStereoInput; }); // restore binding
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ PreferencesDialog {
|
|||
id: root
|
||||
objectName: "GeneralPreferencesDialog"
|
||||
title: "General Settings"
|
||||
showCategories: ["User Interface", "HMD", "Snapshots", "Privacy"]
|
||||
showCategories: ["User Interface", "Mouse Sensitivity", "HMD", "Snapshots", "Privacy"]
|
||||
property var settings: Settings {
|
||||
category: root.objectName
|
||||
property alias x: root.x
|
||||
|
|
|
@ -32,6 +32,6 @@ StackView {
|
|||
TabletPreferencesDialog {
|
||||
id: root
|
||||
objectName: "TabletGeneralPreferences"
|
||||
showCategories: ["User Interface", "HMD", "Snapshots", "Privacy"]
|
||||
showCategories: ["User Interface", "Mouse Sensitivity", "HMD", "Snapshots", "Privacy"]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,31 +10,11 @@
|
|||
//
|
||||
#include "AndroidHelper.h"
|
||||
#include <QDebug>
|
||||
#include <AccountManager.h>
|
||||
|
||||
AndroidHelper::AndroidHelper() {
|
||||
}
|
||||
|
||||
AndroidHelper::~AndroidHelper() {
|
||||
workerThread.quit();
|
||||
workerThread.wait();
|
||||
}
|
||||
|
||||
void AndroidHelper::init() {
|
||||
workerThread.start();
|
||||
_accountManager = QSharedPointer<AccountManager>(new AccountManager, &QObject::deleteLater);
|
||||
_accountManager->setIsAgent(true);
|
||||
_accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
|
||||
_accountManager->setSessionID(DependencyManager::get<AccountManager>()->getSessionID());
|
||||
connect(_accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) {
|
||||
DependencyManager::get<AccountManager>()->setAccountInfo(AndroidHelper::instance().getAccountManager()->getAccountInfo());
|
||||
DependencyManager::get<AccountManager>()->setAuthURL(authURL);
|
||||
});
|
||||
|
||||
connect(_accountManager.data(), &AccountManager::logoutComplete, [] () {
|
||||
DependencyManager::get<AccountManager>()->logout();
|
||||
});
|
||||
_accountManager->moveToThread(&workerThread);
|
||||
}
|
||||
|
||||
void AndroidHelper::requestActivity(const QString &activityName, const bool backToScene) {
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#define hifi_Android_Helper_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QThread>
|
||||
#include <AccountManager.h>
|
||||
|
||||
class AndroidHelper : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -23,7 +21,6 @@ public:
|
|||
static AndroidHelper instance;
|
||||
return instance;
|
||||
}
|
||||
void init();
|
||||
void requestActivity(const QString &activityName, const bool backToScene);
|
||||
void notifyLoadComplete();
|
||||
void notifyEnterForeground();
|
||||
|
@ -31,7 +28,6 @@ public:
|
|||
|
||||
void performHapticFeedback(int duration);
|
||||
|
||||
QSharedPointer<AccountManager> getAccountManager() { return _accountManager; }
|
||||
AndroidHelper(AndroidHelper const&) = delete;
|
||||
void operator=(AndroidHelper const&) = delete;
|
||||
|
||||
|
@ -49,8 +45,6 @@ signals:
|
|||
private:
|
||||
AndroidHelper();
|
||||
~AndroidHelper();
|
||||
QSharedPointer<AccountManager> _accountManager;
|
||||
QThread workerThread;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2259,7 +2259,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
AndroidHelper::instance().init();
|
||||
connect(&AndroidHelper::instance(), &AndroidHelper::enterBackground, this, &Application::enterBackground);
|
||||
connect(&AndroidHelper::instance(), &AndroidHelper::enterForeground, this, &Application::enterForeground);
|
||||
AndroidHelper::instance().notifyLoadComplete();
|
||||
|
|
|
@ -36,13 +36,13 @@
|
|||
#include <SettingHandle.h>
|
||||
#include <UsersScriptingInterface.h>
|
||||
#include <UUID.h>
|
||||
#include <avatars-renderer/OtherAvatar.h>
|
||||
#include <shared/ConicalViewFrustum.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "Menu.h"
|
||||
#include "MyAvatar.h"
|
||||
#include "OtherAvatar.h"
|
||||
#include "SceneScriptingInterface.h"
|
||||
|
||||
// 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()) {
|
||||
const SortableAvatar& sortData = sortedAvatars.top();
|
||||
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());
|
||||
if (ignoring) {
|
||||
|
|
|
@ -1098,7 +1098,6 @@ void MyAvatar::saveData() {
|
|||
settings.setValue("displayName", _displayName);
|
||||
settings.setValue("collisionSoundURL", _collisionSoundURL);
|
||||
settings.setValue("useSnapTurn", _useSnapTurn);
|
||||
settings.setValue("clearOverlayWhenMoving", _clearOverlayWhenMoving);
|
||||
settings.setValue("userHeight", getUserHeight());
|
||||
settings.setValue("enabledFlying", getFlyingEnabled());
|
||||
|
||||
|
@ -1254,7 +1253,6 @@ void MyAvatar::loadData() {
|
|||
setDisplayName(settings.value("displayName").toString());
|
||||
setCollisionSoundURL(settings.value("collisionSoundURL", DEFAULT_AVATAR_COLLISION_SOUND_URL).toString());
|
||||
setSnapTurn(settings.value("useSnapTurn", _useSnapTurn).toBool());
|
||||
setClearOverlayWhenMoving(settings.value("clearOverlayWhenMoving", _clearOverlayWhenMoving).toBool());
|
||||
setDominantHand(settings.value("dominantHand", _dominantHand).toString().toLower());
|
||||
setUserHeight(settings.value("userHeight", DEFAULT_AVATAR_HEIGHT).toDouble());
|
||||
settings.endGroup();
|
||||
|
|
|
@ -250,7 +250,7 @@ public:
|
|||
Q_ENUM(DriveKeys)
|
||||
|
||||
explicit MyAvatar(QThread* thread);
|
||||
~MyAvatar();
|
||||
virtual ~MyAvatar();
|
||||
|
||||
void instantiableAvatar() override {};
|
||||
void registerMetaTypes(ScriptEnginePointer engine);
|
||||
|
@ -469,16 +469,6 @@ public:
|
|||
* @param {boolean} 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
|
||||
|
@ -1496,7 +1486,6 @@ private:
|
|||
ThreadSafeValueCache<QUrl> _prefOverrideAnimGraphUrl;
|
||||
QUrl _fstAnimGraphOverrideUrl;
|
||||
bool _useSnapTurn { true };
|
||||
bool _clearOverlayWhenMoving { true };
|
||||
QString _dominantHand { DOMINANT_RIGHT_HAND };
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
bool isAtRest = updateAvatarIsAtRest();
|
||||
bool isMoving = !isAtRest;
|
||||
|
||||
bool shouldRecenter = false;
|
||||
|
||||
if (_flags & SuppressedByMove) {
|
||||
if (!isMoving) {
|
||||
_flags &= ~SuppressedByMove;
|
||||
shouldRecenter = true;
|
||||
}
|
||||
} else {
|
||||
if (myAvatar->getClearOverlayWhenMoving() && isMoving) {
|
||||
_flags |= SuppressedByMove;
|
||||
}
|
||||
}
|
||||
|
||||
if (_flags & SuppressedByHead) {
|
||||
if (isAtRest) {
|
||||
_flags &= ~SuppressedByHead;
|
||||
if (_suppressedByHead) {
|
||||
if (updateAvatarIsAtRest()) {
|
||||
_suppressedByHead = false;
|
||||
shouldRecenter = true;
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
offscreenUi->setPinned(!targetVisible);
|
||||
}
|
||||
if (shouldRecenter && !_flags) {
|
||||
if (shouldRecenter && !_suppressedByHead) {
|
||||
centerUI();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,7 @@ private:
|
|||
bool headOutsideOverlay() const;
|
||||
bool updateAvatarIsAtRest();
|
||||
|
||||
enum SupressionFlags {
|
||||
SuppressedByMove = 0x01,
|
||||
SuppressedByHead = 0x02,
|
||||
SuppressMask = 0x03,
|
||||
};
|
||||
|
||||
uint8_t _flags { SuppressedByMove };
|
||||
bool _suppressedByHead { false };
|
||||
bool _hmdMode { false };
|
||||
|
||||
// used by updateAvatarIsAtRest
|
||||
|
|
|
@ -161,12 +161,6 @@ void setupPreferences() {
|
|||
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" };
|
||||
{
|
||||
auto getter = [=]()->float { return myAvatar->getRealWorldFieldOfView(); };
|
||||
|
|
|
@ -1426,6 +1426,8 @@ bool AudioClient::setIsStereoInput(bool isStereoInput) {
|
|||
|
||||
// restart the input device
|
||||
switchInputToAudioDevice(_inputDeviceInfo);
|
||||
|
||||
emit isStereoInputChanged(_isStereoInput);
|
||||
}
|
||||
|
||||
return stereoInputChanged;
|
||||
|
@ -1463,6 +1465,8 @@ void AudioClient::outputFormatChanged() {
|
|||
}
|
||||
|
||||
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() << "]";
|
||||
bool supportedFormat = false;
|
||||
|
||||
|
@ -1663,6 +1667,8 @@ void AudioClient::outputNotify() {
|
|||
}
|
||||
|
||||
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() << "]";
|
||||
bool supportedFormat = false;
|
||||
|
||||
|
@ -2021,7 +2027,7 @@ void AudioClient::setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 sca
|
|||
|
||||
|
||||
void AudioClient::startThread() {
|
||||
moveToNewNamedThread(this, "Audio Thread", [this] { start(); });
|
||||
moveToNewNamedThread(this, "Audio Thread", [this] { start(); }, QThread::TimeCriticalPriority);
|
||||
}
|
||||
|
||||
void AudioClient::setInputVolume(float volume, bool emitSignal) {
|
||||
|
|
|
@ -44,6 +44,9 @@ public slots:
|
|||
virtual bool setIsStereoInput(bool stereo) = 0;
|
||||
|
||||
virtual bool isStereoInput() = 0;
|
||||
|
||||
signals:
|
||||
void isStereoInputChanged(bool isStereo);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AbstractAudioInterface*)
|
||||
|
|
|
@ -1338,6 +1338,9 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const {
|
|||
}
|
||||
|
||||
void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
||||
if (!isMyAvatar()) {
|
||||
createOrb();
|
||||
}
|
||||
AvatarData::setSkeletonModelURL(skeletonModelURL);
|
||||
if (QThread::currentThread() == thread()) {
|
||||
_skeletonModel->setURL(_skeletonModelURL);
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <graphics-scripting/Forward.h>
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
|
||||
#include "Head.h"
|
||||
#include "SkeletonModel.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_HEIGHT;
|
||||
|
||||
|
||||
enum ScreenTintLayer {
|
||||
SCREEN_TINT_BEFORE_LANDSCAPE = 0,
|
||||
SCREEN_TINT_BEFORE_AVATARS,
|
||||
|
@ -69,7 +67,7 @@ public:
|
|||
static void setShowNamesAboveHeads(bool show);
|
||||
|
||||
explicit Avatar(QThread* thread);
|
||||
~Avatar();
|
||||
virtual ~Avatar();
|
||||
|
||||
virtual void instantiableAvatar() = 0;
|
||||
|
||||
|
@ -109,6 +107,7 @@ public:
|
|||
float getLODDistance() const;
|
||||
|
||||
virtual bool isMyAvatar() const override { return false; }
|
||||
virtual void createOrb() { }
|
||||
|
||||
virtual QVector<glm::quat> getJointRotations() const override;
|
||||
using AvatarData::getJointRotation;
|
||||
|
@ -167,8 +166,8 @@ public:
|
|||
|
||||
virtual int parseDataFromBuffer(const QByteArray& buffer) override;
|
||||
|
||||
static void renderJointConnectingCone( gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2,
|
||||
float radius1, float radius2, const glm::vec4& color);
|
||||
static void renderJointConnectingCone(gpu::Batch& batch, glm::vec3 position1, glm::vec3 position2,
|
||||
float radius1, float radius2, const glm::vec4& color);
|
||||
|
||||
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
|
||||
/// \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);
|
||||
virtual void updateAttitude(const glm::quat& orientation) override;
|
||||
|
@ -254,7 +253,6 @@ public:
|
|||
void setPositionViaScript(const glm::vec3& position) override;
|
||||
void setOrientationViaScript(const glm::quat& orientation) override;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* @function MyAvatar.getParentID
|
||||
* @returns {Uuid}
|
||||
|
@ -283,7 +281,6 @@ public:
|
|||
// This calls through to the SpatiallyNestable versions, but is here to expose these to JavaScript.
|
||||
Q_INVOKABLE virtual void setParentJointIndex(quint16 parentJointIndex) override;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Returns an array of joints, where each joint is an object containing name, index, and parentIndex fields.
|
||||
* @function MyAvatar.getSkeleton
|
||||
|
@ -349,7 +346,6 @@ public:
|
|||
// not all subclasses of AvatarData have access to this data.
|
||||
virtual bool canMeasureEyeHeight() const override { return true; }
|
||||
|
||||
|
||||
virtual float getModelScale() const { return _modelScale; }
|
||||
virtual void setModelScale(float scale) { _modelScale = scale; }
|
||||
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
|
|
@ -203,10 +203,11 @@ void GLBackend::releaseResourceTexture(uint32_t slot) {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
for (uint32_t i = 0; i < _resource._textures.size(); i++) {
|
||||
for (i = 0; i < _resource._textures.size(); i++) {
|
||||
releaseResourceTexture(i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,11 @@ const size_t GLVariableAllocationSupport::MAX_BUFFER_SIZE = MAX_TRANSFER_SIZE;
|
|||
GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
||||
switch (texture.getType()) {
|
||||
case Texture::TEX_2D:
|
||||
return GL_TEXTURE_2D;
|
||||
if (!texture.isArray()) {
|
||||
return GL_TEXTURE_2D;
|
||||
} else {
|
||||
return GL_TEXTURE_2D_ARRAY;
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture::TEX_CUBE:
|
||||
|
@ -77,6 +81,7 @@ GLenum GLTexture::getGLTextureType(const Texture& texture) {
|
|||
uint8_t GLTexture::getFaceCount(GLenum target) {
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
return TEXTURE_2D_NUM_FACES;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
return TEXTURE_CUBE_NUM_FACES;
|
||||
|
@ -86,17 +91,22 @@ uint8_t GLTexture::getFaceCount(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_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
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
|
||||
};
|
||||
static const std::vector<GLenum> arrayFaceTargets{
|
||||
GL_TEXTURE_2D_ARRAY
|
||||
};
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
return faceTargets;
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
return arrayFaceTargets;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
return cubeFaceTargets;
|
||||
default:
|
||||
|
|
|
@ -64,7 +64,12 @@ public:
|
|||
}
|
||||
|
||||
if (gltexture) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
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]);
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[unit], GL_TEXTURE_2D, 0, 0);
|
||||
|
@ -91,7 +96,12 @@ public:
|
|||
}
|
||||
|
||||
if (gltexture) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, gltexture->_texture, 0);
|
||||
} else {
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, attachement, gltexture->_texture, 0,
|
||||
_gpuObject.getDepthStencilBufferSubresource());
|
||||
}
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, attachement, GL_TEXTURE_2D, 0, 0);
|
||||
}
|
||||
|
|
|
@ -215,12 +215,19 @@ GL41FixedAllocationTexture::~GL41FixedAllocationTexture() {
|
|||
void GL41FixedAllocationTexture::allocateStorage() const {
|
||||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||
const auto numMips = _gpuObject.getNumMips();
|
||||
const auto numSlices = _gpuObject.getNumSlices();
|
||||
|
||||
// glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||
for (GLint level = 0; level < numMips; level++) {
|
||||
Vec3u dimensions = _gpuObject.evalMipDimensions(level);
|
||||
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) {
|
||||
glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0);
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glNamedFramebufferTexture(_id, colorAttachments[unit], gltexture->_texture, 0);
|
||||
} else {
|
||||
glNamedFramebufferTextureLayer(_id, colorAttachments[unit], gltexture->_texture, 0, b._subresource);
|
||||
}
|
||||
_colorBuffers.push_back(colorAttachments[unit]);
|
||||
} else {
|
||||
glNamedFramebufferTexture(_id, colorAttachments[unit], 0, 0);
|
||||
|
@ -87,14 +91,18 @@ public:
|
|||
}
|
||||
|
||||
if (gltexture) {
|
||||
glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0);
|
||||
if (gltexture->_target == GL_TEXTURE_2D) {
|
||||
glNamedFramebufferTexture(_id, attachement, gltexture->_texture, 0);
|
||||
} else {
|
||||
glNamedFramebufferTextureLayer(_id, attachement, gltexture->_texture, 0,
|
||||
_gpuObject.getDepthStencilBufferSubresource());
|
||||
}
|
||||
} else {
|
||||
glNamedFramebufferTexture(_id, attachement, 0, 0);
|
||||
}
|
||||
_depthStamp = _gpuObject.getDepthStamp();
|
||||
}
|
||||
|
||||
|
||||
// Last but not least, define where we draw
|
||||
if (!_colorBuffers.empty()) {
|
||||
glNamedFramebufferDrawBuffers(_id, (GLsizei)_colorBuffers.size(), _colorBuffers.data());
|
||||
|
|
|
@ -374,8 +374,13 @@ void GL45FixedAllocationTexture::allocateStorage() const {
|
|||
const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat());
|
||||
const auto dimensions = _gpuObject.getDimensions();
|
||||
const auto mips = _gpuObject.getNumMips();
|
||||
const auto numSlices = _gpuObject.getNumSlices();
|
||||
|
||||
glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y);
|
||||
if (!_gpuObject.isArray()) {
|
||||
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_MAX_LEVEL, mips - 1);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
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 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 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 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 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 createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler());
|
||||
|
||||
|
|
|
@ -515,7 +515,7 @@ TexturePointer Texture::build(const ktx::KTXDescriptor& descriptor) {
|
|||
header.getPixelHeight(),
|
||||
header.getPixelDepth(),
|
||||
1, // num Samples
|
||||
header.getNumberOfSlices(),
|
||||
header.isArray() ? header.getNumberOfSlices() : 0,
|
||||
header.getNumberOfLevels(),
|
||||
samplerDesc);
|
||||
texture->setUsage(gpuktxKeyValue._usage);
|
||||
|
|
|
@ -163,6 +163,7 @@ namespace ktx {
|
|||
uint32_t getPixelDepth() const { return (pixelDepth ? pixelDepth : 1); }
|
||||
uint32_t getNumberOfSlices() const { return (numberOfArrayElements ? numberOfArrayElements : 1); }
|
||||
uint32_t getNumberOfLevels() const { return (numberOfMipmapLevels ? numberOfMipmapLevels : 1); }
|
||||
bool isArray() const { return numberOfArrayElements > 0; }
|
||||
bool isCompressed() const { return glFormat == COMPRESSED_FORMAT; }
|
||||
|
||||
uint32_t evalMaxDimension() const;
|
||||
|
|
|
@ -66,7 +66,7 @@ OffscreenSurface::OffscreenSurface()
|
|||
}
|
||||
|
||||
OffscreenSurface::~OffscreenSurface() {
|
||||
delete _sharedObject;
|
||||
_sharedObject->deleteLater();
|
||||
}
|
||||
|
||||
bool OffscreenSurface::fetchTexture(TextureAndFence& textureAndFence) {
|
||||
|
|
|
@ -140,11 +140,12 @@ static const std::string DEFAULT_LIGHTING_SHADER {
|
|||
};
|
||||
|
||||
static const std::string DEFAULT_SHADOW_SHADER{
|
||||
"uniform sampler2DShadow shadowMap;"
|
||||
"uniform sampler2DArrayShadow shadowMaps;"
|
||||
"uniform int shadowCascadeIndex;"
|
||||
"vec4 getFragmentColor() {"
|
||||
" for (int i = 255; i >= 0; --i) {"
|
||||
" float depth = i / 255.0;"
|
||||
" if (texture(shadowMap, vec3(uv, depth)) > 0.5) {"
|
||||
" if (texture(shadowMaps, vec4(uv, shadowCascadeIndex, depth)) > 0.5) {"
|
||||
" return vec4(vec3(depth), 1.0);"
|
||||
" }"
|
||||
" }"
|
||||
|
@ -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("obscuranceMap", AmbientOcclusion));
|
||||
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("halfLinearDepthMap", HalfLinearDepth));
|
||||
slotBindings.insert(gpu::Shader::Binding("halfNormalMap", HalfNormal));
|
||||
|
@ -490,7 +491,11 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
|
|||
const auto& globalShadow = lightAndShadow.second;
|
||||
if (globalShadow) {
|
||||
const auto cascadeIndex = glm::clamp(_mode - Mode::ShadowCascade0Mode, 0, (int)globalShadow->getCascadeCount() - 1);
|
||||
batch.setResourceTexture(Shadow, globalShadow->getCascade(cascadeIndex).map);
|
||||
const auto cascadeIndexLocation = pipeline->getProgram()->getUniforms().findLocation("shadowCascadeIndex");
|
||||
batch.setResourceTexture(Shadow, globalShadow->map);
|
||||
if (cascadeIndexLocation >= 0) {
|
||||
batch._glUniform1i(cascadeIndexLocation, cascadeIndex);
|
||||
}
|
||||
batch.setUniformBuffer(ShadowTransform, globalShadow->getBuffer());
|
||||
batch.setUniformBuffer(DeferredFrameTransform, frameTransform->getFrameTransformBuffer());
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ enum DeferredShader_MapSlot {
|
|||
SCATTERING_SPECULAR_UNIT = 9,
|
||||
SKYBOX_MAP_UNIT = render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP, // unit = 10
|
||||
SHADOW_MAP_UNIT = 11,
|
||||
nextAvailableUnit = SHADOW_MAP_UNIT + SHADOW_CASCADE_MAX_COUNT
|
||||
nextAvailableUnit = SHADOW_MAP_UNIT
|
||||
};
|
||||
enum DeferredShader_BufferSlot {
|
||||
DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0,
|
||||
|
@ -534,9 +534,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
// Bind the shadow buffers
|
||||
if (globalShadow) {
|
||||
for (unsigned int i = 0; i < globalShadow->getCascadeCount(); i++) {
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT+i, globalShadow->getCascade(i).map);
|
||||
}
|
||||
batch.setResourceTexture(SHADOW_MAP_UNIT, globalShadow->map);
|
||||
}
|
||||
|
||||
auto program = deferredLightingEffect->_directionalSkyboxLight;
|
||||
|
|
|
@ -74,8 +74,6 @@ LightStage::Shadow::Cascade::Cascade() :
|
|||
_frustum{ std::make_shared<ViewFrustum>() },
|
||||
_minDistance{ 0.0f },
|
||||
_maxDistance{ 20.0f } {
|
||||
framebuffer = gpu::FramebufferPointer(gpu::Framebuffer::createShadowmap(MAP_SIZE));
|
||||
map = framebuffer->getDepthStencilBuffer();
|
||||
}
|
||||
|
||||
const glm::mat4& LightStage::Shadow::Cascade::getView() const {
|
||||
|
@ -127,8 +125,29 @@ LightStage::Shadow::Shadow(graphics::LightPointer light, float maxDistance, unsi
|
|||
Schema schema;
|
||||
schema.cascadeCount = cascadeCount;
|
||||
_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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ public:
|
|||
Cascade();
|
||||
|
||||
gpu::FramebufferPointer framebuffer;
|
||||
gpu::TexturePointer map;
|
||||
|
||||
const std::shared_ptr<ViewFrustum>& getFrustum() const { return _frustum; }
|
||||
|
||||
|
@ -93,6 +92,8 @@ public:
|
|||
|
||||
const graphics::LightPointer& getLight() const { return _light; }
|
||||
|
||||
gpu::TexturePointer map;
|
||||
|
||||
protected:
|
||||
|
||||
#include "Shadows_shared.slh"
|
||||
|
|
|
@ -17,19 +17,11 @@
|
|||
#define SHADOW_SCREEN_SPACE_DITHER 1
|
||||
|
||||
// the shadow texture
|
||||
#if SHADOW_CASCADE_MAX_COUNT>1
|
||||
uniform sampler2DShadow shadowMaps[SHADOW_CASCADE_MAX_COUNT];
|
||||
#else
|
||||
uniform sampler2DShadow shadowMaps;
|
||||
#endif
|
||||
uniform sampler2DArrayShadow shadowMaps;
|
||||
|
||||
// Sample the shadowMap with PCF (built-in)
|
||||
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {
|
||||
#if SHADOW_CASCADE_MAX_COUNT>1
|
||||
return texture(shadowMaps[cascadeIndex], shadowTexcoord);
|
||||
#else
|
||||
return texture(shadowMaps, shadowTexcoord);
|
||||
#endif
|
||||
return texture(shadowMaps, vec4(shadowTexcoord.xy, cascadeIndex, shadowTexcoord.z));
|
||||
}
|
||||
|
||||
vec2 PCFkernel[4] = vec2[4](
|
||||
|
@ -97,7 +89,6 @@ float evalShadowCascadeAttenuation(int cascadeIndex, ShadowSampleOffsets offsets
|
|||
|
||||
float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDepth, vec3 worldNormal) {
|
||||
ShadowSampleOffsets offsets = evalShadowFilterOffsets(worldPosition);
|
||||
#if 0
|
||||
vec4 cascadeShadowCoords[2];
|
||||
cascadeShadowCoords[0] = vec4(0);
|
||||
cascadeShadowCoords[1] = vec4(0);
|
||||
|
@ -114,11 +105,6 @@ float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDe
|
|||
float attenuation = mix(cascadeAttenuations.x, cascadeAttenuations.y, cascadeMix);
|
||||
// Falloff to max distance
|
||||
return mix(1.0, attenuation, evalShadowFalloff(viewDepth));
|
||||
#else
|
||||
vec4 shadowTexcoord = evalShadowTexcoord(0, worldPosition);
|
||||
float attenuation = fetchShadow(0, shadowTexcoord.xyz);
|
||||
return attenuation;
|
||||
#endif
|
||||
}
|
||||
|
||||
<@endif@>
|
||||
|
|
|
@ -23,6 +23,21 @@ void registerAudioMetaTypes(QScriptEngine* engine) {
|
|||
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) {
|
||||
AudioInjectorOptions options;
|
||||
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 stereoInputChanged = false;
|
||||
if (_localAudioInterface) {
|
||||
stereoInputChanged = _localAudioInterface->setIsStereoInput(stereo);
|
||||
QMetaObject::invokeMethod(_localAudioInterface, "setIsStereoInput", Q_ARG(bool, stereo));
|
||||
}
|
||||
return stereoInputChanged;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioScriptingInterface::isStereoInput() {
|
||||
|
|
|
@ -23,9 +23,11 @@ class AudioScriptingInterface : public QObject, public Dependency {
|
|||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
Q_PROPERTY(bool isStereoInput READ isStereoInput WRITE setStereoInput NOTIFY isStereoInputChanged)
|
||||
|
||||
public:
|
||||
virtual ~AudioScriptingInterface() {}
|
||||
void setLocalAudioInterface(AbstractAudioInterface* audioInterface) { _localAudioInterface = audioInterface; }
|
||||
void setLocalAudioInterface(AbstractAudioInterface* audioInterface);
|
||||
|
||||
protected:
|
||||
AudioScriptingInterface() {}
|
||||
|
@ -52,7 +54,7 @@ protected:
|
|||
/**jsdoc
|
||||
* @function Audio.setStereoInput
|
||||
* @param {boolean} stereo
|
||||
* @returns {boolean}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
Q_INVOKABLE bool setStereoInput(bool stereo);
|
||||
|
||||
|
@ -114,6 +116,13 @@ signals:
|
|||
*/
|
||||
void inputReceived(const QByteArray& inputSamples);
|
||||
|
||||
/**jsdoc
|
||||
* @function Audio.isStereoInputChanged
|
||||
* @param {boolean} isStereo
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void isStereoInputChanged(bool isStereo);
|
||||
|
||||
private:
|
||||
AbstractAudioInterface* _localAudioInterface { nullptr };
|
||||
};
|
||||
|
|
|
@ -1639,22 +1639,24 @@ QVariantMap ScriptEngine::fetchModuleSource(const QString& modulePath, const boo
|
|||
loader->start(MAX_RETRIES);
|
||||
|
||||
if (!loader->isFinished()) {
|
||||
QTimer monitor;
|
||||
QEventLoop loop;
|
||||
QObject::connect(loader, &BatchLoader::finished, this, [&monitor, &loop]{
|
||||
monitor.stop();
|
||||
loop.quit();
|
||||
// This lambda can get called AFTER this local scope has completed.
|
||||
// This is why we pass smart ptrs to the lambda instead of references to local variables.
|
||||
auto monitor = std::make_shared<QTimer>();
|
||||
auto loop = std::make_shared<QEventLoop>();
|
||||
QObject::connect(loader, &BatchLoader::finished, this, [monitor, loop] {
|
||||
monitor->stop();
|
||||
loop->quit();
|
||||
});
|
||||
|
||||
// this helps detect the case where stop() is invoked during the download
|
||||
// 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()) {
|
||||
loop.exit(-1);
|
||||
loop->exit(-1);
|
||||
}
|
||||
});
|
||||
monitor.start(500);
|
||||
loop.exec();
|
||||
monitor->start(500);
|
||||
loop->exec();
|
||||
}
|
||||
loader->deleteLater();
|
||||
return req;
|
||||
|
|
|
@ -44,6 +44,11 @@ void Space::processResets(const Transaction::Resets& transactions) {
|
|||
for (auto& reset : transactions) {
|
||||
// Access the true item
|
||||
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];
|
||||
|
||||
// Reset the item with a new payload
|
||||
|
|
|
@ -17,7 +17,6 @@ var SNAPSHOT_DELAY = 500; // 500ms
|
|||
var FINISH_SOUND_DELAY = 350;
|
||||
var resetOverlays;
|
||||
var reticleVisible;
|
||||
var clearOverlayWhenMoving;
|
||||
|
||||
var buttonName = "SNAP";
|
||||
var buttonConnected = false;
|
||||
|
@ -286,6 +285,7 @@ function printToPolaroid(image_url) {
|
|||
var polaroid_url = image_url;
|
||||
|
||||
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_q2 = Quat.angleAxis(90, Quat.getRight(model_q1));
|
||||
|
@ -295,11 +295,11 @@ function printToPolaroid(image_url) {
|
|||
"type": 'Model',
|
||||
"shapeType": 'box',
|
||||
|
||||
"name": "New Snapshot",
|
||||
"description": "Printed from Snaps",
|
||||
"name": "Snapshot by " + MyAvatar.sessionDisplayName,
|
||||
"description": "Printed from SNAP app",
|
||||
"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,
|
||||
"rotation": model_rot,
|
||||
|
||||
|
@ -307,9 +307,9 @@ function printToPolaroid(image_url) {
|
|||
|
||||
"density": 200,
|
||||
"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 },
|
||||
|
||||
"dynamic": true,
|
||||
|
@ -438,11 +438,6 @@ function takeSnapshot() {
|
|||
isUploadingPrintableStill = true;
|
||||
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.
|
||||
// Even the domainID could change (e.g., if the user falls into a teleporter while recording).
|
||||
href = location.href;
|
||||
|
@ -544,9 +539,6 @@ function stillSnapshotTaken(pathStillSnapshot, notify) {
|
|||
// last element in data array tells dialog whether we can share or not
|
||||
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
||||
|
||||
if (clearOverlayWhenMoving) {
|
||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||
}
|
||||
HMD.openTablet();
|
||||
|
||||
isDomainOpen(domainID, function (canShare) {
|
||||
|
@ -590,9 +582,6 @@ function processingGifStarted(pathStillSnapshot) {
|
|||
}
|
||||
Settings.setValue("previousStillSnapPath", pathStillSnapshot);
|
||||
|
||||
if (clearOverlayWhenMoving) {
|
||||
MyAvatar.setClearOverlayWhenMoving(true); // not until after the share dialog
|
||||
}
|
||||
HMD.openTablet();
|
||||
|
||||
isDomainOpen(domainID, function (canShare) {
|
||||
|
|
Loading…
Reference in a new issue