mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into model-scripting-2
This commit is contained in:
commit
d5ea69d81d
35 changed files with 232 additions and 601 deletions
145
BUILD_WIN.md
145
BUILD_WIN.md
|
@ -1,104 +1,81 @@
|
|||
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Windows specific instructions are found in this file.
|
||||
This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit.
|
||||
|
||||
Interface can be built as 32 or 64 bit.
|
||||
###Step 1. Installing Visual Studio 2013
|
||||
|
||||
###Visual Studio 2013
|
||||
If you don't already have the Community or Professional edition of Visual Studio 2013, download and install [Visual Studio Community 2013](https://www.visualstudio.com/en-us/news/releasenotes/vs2013-community-vs). You do not need to install any of the optional components when going through the installer.
|
||||
|
||||
You can use the Community or Professional editions of Visual Studio 2013.
|
||||
Note: Newer versions of Visual Studio are not yet compatible.
|
||||
|
||||
You can start a Visual Studio 2013 command prompt using the shortcut provided in the Visual Studio Tools folder installed as part of Visual Studio 2013.
|
||||
###Step 2. Installing CMake
|
||||
|
||||
Or you can start a regular command prompt and then run:
|
||||
Download and install the CMake 3.8.0-rc2 "win64-x64 Installer" from the [CMake Website](https://cmake.org/download/). Make sure "Add CMake to system PATH for all users" is checked when going through the installer.
|
||||
|
||||
"%VS120COMNTOOLS%\vsvars32.bat"
|
||||
###Step 3. Installing Qt
|
||||
|
||||
####Windows SDK 8.1
|
||||
Download and install the [Qt 5.6.1 Installer](https://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-windows-x86-msvc2013_64-5.6.1-1.exe). Please note that the download file is large (850MB) and may take some time.
|
||||
|
||||
If using Visual Studio 2013 and building as a Visual Studio 2013 project you need the Windows 8 SDK which you should already have as part of installing Visual Studio 2013. You should be able to see it at `C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86`.
|
||||
Make sure to select all components when going through the installer.
|
||||
|
||||
####nmake
|
||||
###Step 4. Setting Qt Environment Variable
|
||||
|
||||
Some of the external projects may require nmake to compile and install. If it is not installed at the location listed below, please ensure that it is in your PATH so CMake can find it when required.
|
||||
Go to "Control Panel > System > Advanced System Settings > Environment Variables > New..." (or search “Environment Variables” in Start Search).
|
||||
* Set "Variable name": QT_CMAKE_PREFIX_PATH
|
||||
* Set "Variable value": `C:\Qt\Qt5.6.1\5.6\msvc2013_64\lib\cmake`
|
||||
|
||||
We expect nmake.exe to be located at the following path.
|
||||
###Step 5. Installing OpenSSL
|
||||
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin
|
||||
Download and install the "Win64 OpenSSL v1.0.2k" Installer from [this website](https://slproweb.com/products/Win32OpenSSL.html).
|
||||
|
||||
###Qt
|
||||
You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version.
|
||||
|
||||
* [Download the online installer](http://www.qt.io/download-open-source/#section-2)
|
||||
* When it asks you to select components, ONLY select one of the following, 32- or 64-bit to match your build preference:
|
||||
* Qt > Qt 5.6.1 > **msvc2013 32-bit**
|
||||
* Qt > Qt 5.6.1 > **msvc2013 64-bit**
|
||||
|
||||
* Download the offline installer, 32- or 64-bit to match your build preference:
|
||||
* [32-bit](https://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-windows-x86-msvc2013-5.6.1-1.exe)
|
||||
* [64-bit](https://download.qt.io/official_releases/qt/5.6/5.6.1-1/qt-opensource-windows-x86-msvc2013_64-5.6.1-1.exe)
|
||||
|
||||
Once Qt is installed, you need to manually configure the following:
|
||||
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.6.1\msvc2013\lib\cmake` or `Qt\5.6.1\msvc2013_64\lib\cmake` directory.
|
||||
* You can set an environment variable from Control Panel > System > Advanced System Settings > Environment Variables > New
|
||||
|
||||
###External Libraries
|
||||
|
||||
All libraries should be 32- or 64-bit to match your build preference.
|
||||
|
||||
CMake will need to know where the headers and libraries for required external dependencies are.
|
||||
|
||||
We use CMake's `fixup_bundle` to find the DLLs all of our executable targets require, and then copy them beside the executable in a post-build step. If `fixup_bundle` is having problems finding a DLL, you can fix it manually on your end by adding the folder containing that DLL to your path. Let us know which DLL CMake had trouble finding, as it is possible a tweak to our CMake files is required.
|
||||
|
||||
The recommended route for CMake to find the external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure:
|
||||
|
||||
root_lib_dir
|
||||
-> openssl
|
||||
-> bin
|
||||
-> include
|
||||
-> lib
|
||||
|
||||
For many of the external libraries where precompiled binaries are readily available you should be able to simply copy the extracted folder that you get from the download links provided at the top of the guide. Otherwise you may need to build from source and install the built product to this directory. The `root_lib_dir` in the above example can be wherever you choose on your system - as long as the environment variable HIFI_LIB_DIR is set to it. From here on, whenever you see %HIFI_LIB_DIR% you should substitute the directory that you chose.
|
||||
|
||||
####OpenSSL
|
||||
|
||||
Qt will use OpenSSL if it's available, but it doesn't install it, so you must install it separately.
|
||||
|
||||
Your system may already have several versions of the OpenSSL DLL's (ssleay32.dll, libeay32.dll) lying around, but they may be the wrong version. If these DLL's are in the PATH then QT will try to use them, and if they're the wrong version then you will see the following errors in the console:
|
||||
|
||||
QSslSocket: cannot resolve TLSv1_1_client_method
|
||||
QSslSocket: cannot resolve TLSv1_2_client_method
|
||||
QSslSocket: cannot resolve TLSv1_1_server_method
|
||||
QSslSocket: cannot resolve TLSv1_2_server_method
|
||||
QSslSocket: cannot resolve SSL_select_next_proto
|
||||
QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
|
||||
QSslSocket: cannot resolve SSL_get0_next_proto_negotiated
|
||||
|
||||
To prevent these problems, install OpenSSL yourself. Download one of the following binary packages [from this website](https://slproweb.com/products/Win32OpenSSL.html):
|
||||
* Win32 OpenSSL v1.0.1q
|
||||
* Win64 OpenSSL v1.0.1q
|
||||
|
||||
Install OpenSSL into the Windows system directory, to make sure that Qt uses the version that you've just installed, and not some other version.
|
||||
|
||||
###Build High Fidelity using Visual Studio
|
||||
Follow the same build steps from the CMake section of [BUILD.md](BUILD.md), but pass a different generator to CMake.
|
||||
|
||||
For 32-bit builds:
|
||||
|
||||
cmake .. -G "Visual Studio 12"
|
||||
|
||||
For 64-bit builds:
|
||||
###Step 6. Running CMake to Generate Build Files
|
||||
|
||||
Run Command Prompt from Start and run the following commands:
|
||||
cd "%HIFI_DIR%"
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G "Visual Studio 12 Win64"
|
||||
|
||||
Where %HIFI_DIR% is the directory for the highfidelity repository.
|
||||
|
||||
Open %HIFI_DIR%\build\hifi.sln and compile.
|
||||
###Step 7. Making a Build
|
||||
|
||||
###Running Interface
|
||||
If you need to debug Interface, you can run interface from within Visual Studio (see the section below). You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Debug\interface.exe
|
||||
Open '%HIFI_DIR%\build\hifi.sln' using Visual Studio.
|
||||
|
||||
###Debugging Interface
|
||||
* In the Solution Explorer, right click interface and click Set as StartUp Project
|
||||
* Set the "Working Directory" for the Interface debugging sessions to the Debug output directory so that your application can load resources. Do this: right click interface and click Properties, choose Debugging from Configuration Properties, set Working Directory to .\Debug
|
||||
* Now you can run and debug interface through Visual Studio
|
||||
Change the Solution Configuration (next to the green play button) from "Debug" to "Release" for best performance.
|
||||
|
||||
For better performance when running debug builds, set the environment variable ```_NO_DEBUG_HEAP``` to ```1```
|
||||
Run Build > Build Solution.
|
||||
|
||||
###Step 8. Testing Interface
|
||||
|
||||
Create another environment variable (see Step #4)
|
||||
* Set "Variable name": _NO_DEBUG_HEAP
|
||||
* Set "Variable value": 1
|
||||
|
||||
In Visual Studio, right+click "interface" under the Apps folder in Solution Explorer and select "Set as Startup Project". Run Debug > Start Debugging.
|
||||
|
||||
Now, you should have a full build of High Fidelity and be able to run the Interface using Visual Studio. Please check our [Docs](https://wiki.highfidelity.com/wiki/Main_Page) for more information regarding the programming workflow.
|
||||
|
||||
Note: You can also run Interface by launching it from command line or File Explorer from %HIFI_DIR%\build\interface\Release\interface.exe
|
||||
|
||||
###Troubleshooting
|
||||
|
||||
For any problems after Step #6, first try this:
|
||||
* Delete your locally cloned copy of the highfidelity repository
|
||||
* Restart your computer
|
||||
* Redownload the [repository](https://github.com/highfidelity/hifi)
|
||||
* Restart directions from Step #6
|
||||
|
||||
####CMake gives you the same error message repeatedly after the build fails
|
||||
|
||||
Remove `CMakeCache.txt` found in the '%HIFI_DIR%\build' directory
|
||||
|
||||
####nmake cannot be found
|
||||
|
||||
Make sure nmake.exe is located at the following path:
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin
|
||||
|
||||
If not, add the directory where nmake is located to the PATH environment variable.
|
||||
|
||||
####Qt is throwing an error
|
||||
|
||||
Make sure you have the correct version (5.6.1-1) installed and 'QT_CMAKE_PREFIX_PATH' environment variable is set correctly.
|
||||
|
||||
http://preshing.com/20110717/the-windows-heap-is-slow-when-launched-from-the-debugger/
|
||||
|
|
|
@ -2,7 +2,27 @@
|
|||
"name": "Standard to Action",
|
||||
"channels": [
|
||||
{ "from": "Standard.LY", "to": "Actions.TranslateZ" },
|
||||
{ "from": "Standard.LX", "to": "Actions.TranslateX" },
|
||||
|
||||
{ "from": "Standard.LX",
|
||||
"when": [
|
||||
"Application.InHMD", "!Application.AdvancedMovement",
|
||||
"Application.SnapTurn", "!Standard.RX"
|
||||
],
|
||||
"to": "Actions.StepYaw",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "deadZone", "min": 0.15 },
|
||||
"constrainToInteger",
|
||||
{ "type": "pulse", "interval": 0.25 },
|
||||
{ "type": "scale", "scale": 22.5 }
|
||||
]
|
||||
},
|
||||
{ "from": "Standard.LX", "to": "Actions.TranslateX",
|
||||
"when": [ "Application.AdvancedMovement" ]
|
||||
},
|
||||
{ "from": "Standard.LX", "to": "Actions.Yaw",
|
||||
"when": [ "!Application.AdvancedMovement", "!Application.SnapTurn" ]
|
||||
},
|
||||
|
||||
{ "from": "Standard.RX",
|
||||
"when": [ "Application.InHMD", "Application.SnapTurn" ],
|
||||
|
@ -15,29 +35,29 @@
|
|||
{ "type": "scale", "scale": 22.5 }
|
||||
]
|
||||
},
|
||||
{ "from": "Standard.RX", "to": "Actions.Yaw",
|
||||
"when": [ "!Application.SnapTurn" ]
|
||||
},
|
||||
|
||||
{ "from": "Standard.RX", "to": "Actions.Yaw" },
|
||||
{ "from": "Standard.RY",
|
||||
"when": "Application.Grounded",
|
||||
"to": "Actions.Up",
|
||||
"filters":
|
||||
{ "from": "Standard.RY",
|
||||
"when": "Application.Grounded",
|
||||
"to": "Actions.Up",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "deadZone", "min": 0.6 },
|
||||
"invert"
|
||||
]
|
||||
},
|
||||
},
|
||||
|
||||
{ "from": "Standard.RY", "to": "Actions.Up", "filters": "invert"},
|
||||
{ "from": "Standard.RY", "to": "Actions.Up", "filters": "invert"},
|
||||
|
||||
{ "from": "Standard.Back", "to": "Actions.CycleCamera" },
|
||||
{ "from": "Standard.Start", "to": "Actions.ContextMenu" },
|
||||
|
||||
{ "from": "Standard.LT", "to": "Actions.LeftHandClick" },
|
||||
{ "from": "Standard.LT", "to": "Actions.LeftHandClick" },
|
||||
{ "from": "Standard.RT", "to": "Actions.RightHandClick" },
|
||||
|
||||
{ "from": "Standard.LeftHand", "to": "Actions.LeftHand" },
|
||||
{ "from": "Standard.LeftHand", "to": "Actions.LeftHand" },
|
||||
{ "from": "Standard.RightHand", "to": "Actions.RightHand" }
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2 KiB |
File diff suppressed because one or more lines are too long
|
@ -15,12 +15,11 @@ import Qt.labs.settings 1.0
|
|||
Hifi.AvatarInputs {
|
||||
id: root
|
||||
objectName: "AvatarInputs"
|
||||
width: mirrorWidth
|
||||
height: controls.height + mirror.height
|
||||
width: rootWidth
|
||||
height: controls.height
|
||||
x: 10; y: 5
|
||||
|
||||
readonly property int mirrorHeight: 215
|
||||
readonly property int mirrorWidth: 265
|
||||
readonly property int rootWidth: 265
|
||||
readonly property int iconSize: 24
|
||||
readonly property int iconPadding: 5
|
||||
|
||||
|
@ -39,61 +38,15 @@ Hifi.AvatarInputs {
|
|||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Item {
|
||||
id: mirror
|
||||
width: root.mirrorWidth
|
||||
height: root.mirrorVisible ? root.mirrorHeight : 0
|
||||
visible: root.mirrorVisible
|
||||
anchors.left: parent.left
|
||||
clip: true
|
||||
|
||||
Image {
|
||||
id: closeMirror
|
||||
visible: hover.containsMouse
|
||||
width: root.iconSize
|
||||
height: root.iconSize
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: root.iconPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.iconPadding
|
||||
source: "../images/close.svg"
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.closeMirror();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: zoomIn
|
||||
visible: hover.containsMouse
|
||||
width: root.iconSize
|
||||
height: root.iconSize
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: root.iconPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.iconPadding
|
||||
source: root.mirrorZoomed ? "../images/minus.svg" : "../images/plus.svg"
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.toggleZoom();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: controls
|
||||
width: root.mirrorWidth
|
||||
width: root.rootWidth
|
||||
height: 44
|
||||
visible: root.showAudioTools
|
||||
anchors.top: mirror.bottom
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: root.mirrorVisible ? (root.audioClipping ? "red" : "#696969") : "#00000000"
|
||||
color: "#00000000"
|
||||
|
||||
Item {
|
||||
id: audioMeter
|
||||
|
|
|
@ -215,18 +215,10 @@ static const QString FBX_EXTENSION = ".fbx";
|
|||
static const QString OBJ_EXTENSION = ".obj";
|
||||
static const QString AVA_JSON_EXTENSION = ".ava.json";
|
||||
|
||||
static const int MIRROR_VIEW_TOP_PADDING = 5;
|
||||
static const int MIRROR_VIEW_LEFT_PADDING = 10;
|
||||
static const int MIRROR_VIEW_WIDTH = 265;
|
||||
static const int MIRROR_VIEW_HEIGHT = 215;
|
||||
static const float MIRROR_FULLSCREEN_DISTANCE = 0.389f;
|
||||
static const float MIRROR_REARVIEW_DISTANCE = 0.722f;
|
||||
static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f;
|
||||
static const float MIRROR_FIELD_OF_VIEW = 30.0f;
|
||||
|
||||
static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND;
|
||||
|
||||
static const QString INFO_WELCOME_PATH = "html/interface-welcome.html";
|
||||
static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-commands.html";
|
||||
static const QString INFO_HELP_PATH = "html/help.html";
|
||||
|
||||
|
@ -425,6 +417,7 @@ static const QString STATE_CAMERA_THIRD_PERSON = "CameraThirdPerson";
|
|||
static const QString STATE_CAMERA_ENTITY = "CameraEntity";
|
||||
static const QString STATE_CAMERA_INDEPENDENT = "CameraIndependent";
|
||||
static const QString STATE_SNAP_TURN = "SnapTurn";
|
||||
static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement";
|
||||
static const QString STATE_GROUNDED = "Grounded";
|
||||
static const QString STATE_NAV_FOCUSED = "NavigationFocused";
|
||||
|
||||
|
@ -515,7 +508,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
DependencyManager::set<MessagesClient>();
|
||||
controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR,
|
||||
STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT,
|
||||
STATE_SNAP_TURN, STATE_GROUNDED, STATE_NAV_FOCUSED } });
|
||||
STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED } });
|
||||
DependencyManager::set<UserInputMapper>();
|
||||
DependencyManager::set<controller::ScriptingInterface, ControllerScriptingInterface>();
|
||||
DependencyManager::set<InterfaceParentFinder>();
|
||||
|
@ -567,7 +560,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_entityClipboardRenderer(false, this, this),
|
||||
_entityClipboard(new EntityTree()),
|
||||
_lastQueriedTime(usecTimestampNow()),
|
||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||
_previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION),
|
||||
_fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
|
||||
_hmdTabletScale("hmdTabletScale", DEFAULT_HMD_TABLET_SCALE_PERCENT),
|
||||
|
@ -1131,6 +1123,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
_applicationStateDevice->setInputVariant(STATE_SNAP_TURN, []() -> float {
|
||||
return qApp->getMyAvatar()->getSnapTurn() ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_ADVANCED_MOVEMENT_CONTROLS, []() -> float {
|
||||
return qApp->getMyAvatar()->useAdvancedMovementControls() ? 1 : 0;
|
||||
});
|
||||
|
||||
_applicationStateDevice->setInputVariant(STATE_GROUNDED, []() -> float {
|
||||
return qApp->getMyAvatar()->getCharacterController()->onGround() ? 1 : 0;
|
||||
});
|
||||
|
@ -2121,21 +2117,6 @@ void Application::paintGL() {
|
|||
batch.resetStages();
|
||||
});
|
||||
|
||||
auto inputs = AvatarInputs::getInstance();
|
||||
if (inputs->mirrorVisible()) {
|
||||
PerformanceTimer perfTimer("Mirror");
|
||||
|
||||
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||
renderArgs._blitFramebuffer = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
|
||||
|
||||
_mirrorViewRect.moveTo(inputs->x(), inputs->y());
|
||||
|
||||
renderRearViewMirror(&renderArgs, _mirrorViewRect, inputs->mirrorZoomed());
|
||||
|
||||
renderArgs._blitFramebuffer.reset();
|
||||
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||
}
|
||||
|
||||
{
|
||||
PerformanceTimer perfTimer("renderOverlay");
|
||||
// NOTE: There is no batch associated with this renderArgs
|
||||
|
@ -2383,10 +2364,6 @@ void Application::setSettingConstrainToolbarPosition(bool setting) {
|
|||
DependencyManager::get<OffscreenUi>()->setConstrainToolbarToCenterX(setting);
|
||||
}
|
||||
|
||||
void Application::aboutApp() {
|
||||
InfoView::show(INFO_WELCOME_PATH);
|
||||
}
|
||||
|
||||
void Application::showHelp() {
|
||||
static const QString HAND_CONTROLLER_NAME_VIVE = "vive";
|
||||
static const QString HAND_CONTROLLER_NAME_OCULUS_TOUCH = "oculus";
|
||||
|
@ -2888,51 +2865,49 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
break;
|
||||
#endif
|
||||
|
||||
case Qt::Key_H:
|
||||
if (isShifted) {
|
||||
Menu::getInstance()->triggerOption(MenuOption::MiniMirror);
|
||||
} else {
|
||||
// whenever switching to/from full screen mirror from the keyboard, remember
|
||||
// the state you were in before full screen mirror, and return to that.
|
||||
auto previousMode = _myCamera.getMode();
|
||||
if (previousMode != CAMERA_MODE_MIRROR) {
|
||||
switch (previousMode) {
|
||||
case CAMERA_MODE_FIRST_PERSON:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::FirstPerson;
|
||||
break;
|
||||
case CAMERA_MODE_THIRD_PERSON:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::ThirdPerson;
|
||||
break;
|
||||
case Qt::Key_H: {
|
||||
// whenever switching to/from full screen mirror from the keyboard, remember
|
||||
// the state you were in before full screen mirror, and return to that.
|
||||
auto previousMode = _myCamera.getMode();
|
||||
if (previousMode != CAMERA_MODE_MIRROR) {
|
||||
switch (previousMode) {
|
||||
case CAMERA_MODE_FIRST_PERSON:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::FirstPerson;
|
||||
break;
|
||||
case CAMERA_MODE_THIRD_PERSON:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::ThirdPerson;
|
||||
break;
|
||||
|
||||
// FIXME - it's not clear that these modes make sense to return to...
|
||||
case CAMERA_MODE_INDEPENDENT:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::IndependentMode;
|
||||
break;
|
||||
case CAMERA_MODE_ENTITY:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::CameraEntityMode;
|
||||
break;
|
||||
// FIXME - it's not clear that these modes make sense to return to...
|
||||
case CAMERA_MODE_INDEPENDENT:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::IndependentMode;
|
||||
break;
|
||||
case CAMERA_MODE_ENTITY:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::CameraEntityMode;
|
||||
break;
|
||||
|
||||
default:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::ThirdPerson;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_returnFromFullScreenMirrorTo = MenuOption::ThirdPerson;
|
||||
break;
|
||||
}
|
||||
|
||||
bool isMirrorChecked = Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror);
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, !isMirrorChecked);
|
||||
if (isMirrorChecked) {
|
||||
|
||||
// if we got here without coming in from a non-Full Screen mirror case, then our
|
||||
// _returnFromFullScreenMirrorTo is unknown. In that case we'll go to the old
|
||||
// behavior of returning to ThirdPerson
|
||||
if (_returnFromFullScreenMirrorTo.isEmpty()) {
|
||||
_returnFromFullScreenMirrorTo = MenuOption::ThirdPerson;
|
||||
}
|
||||
Menu::getInstance()->setIsOptionChecked(_returnFromFullScreenMirrorTo, true);
|
||||
}
|
||||
cameraMenuChanged();
|
||||
}
|
||||
|
||||
bool isMirrorChecked = Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror);
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FullscreenMirror, !isMirrorChecked);
|
||||
if (isMirrorChecked) {
|
||||
|
||||
// if we got here without coming in from a non-Full Screen mirror case, then our
|
||||
// _returnFromFullScreenMirrorTo is unknown. In that case we'll go to the old
|
||||
// behavior of returning to ThirdPerson
|
||||
if (_returnFromFullScreenMirrorTo.isEmpty()) {
|
||||
_returnFromFullScreenMirrorTo = MenuOption::ThirdPerson;
|
||||
}
|
||||
Menu::getInstance()->setIsOptionChecked(_returnFromFullScreenMirrorTo, true);
|
||||
}
|
||||
cameraMenuChanged();
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_P: {
|
||||
if (!(isShifted || isMeta || isOption)) {
|
||||
bool isFirstPersonChecked = Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson);
|
||||
|
@ -3847,8 +3822,6 @@ void Application::init() {
|
|||
DependencyManager::get<AvatarManager>()->init();
|
||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
|
||||
_mirrorCamera.setMode(CAMERA_MODE_MIRROR);
|
||||
|
||||
_timerStart.start();
|
||||
_lastTimeUpdated.start();
|
||||
|
||||
|
@ -4465,9 +4438,12 @@ void Application::update(float deltaTime) {
|
|||
|
||||
getEntities()->getTree()->withWriteLock([&] {
|
||||
PerformanceTimer perfTimer("handleOutgoingChanges");
|
||||
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getOutgoingChanges();
|
||||
_entitySimulation->handleOutgoingChanges(outgoingChanges);
|
||||
avatarManager->handleOutgoingChanges(outgoingChanges);
|
||||
const VectorOfMotionStates& deactivations = _physicsEngine->getDeactivatedMotionStates();
|
||||
_entitySimulation->handleDeactivatedMotionStates(deactivations);
|
||||
|
||||
const VectorOfMotionStates& outgoingChanges = _physicsEngine->getChangedMotionStates();
|
||||
_entitySimulation->handleChangedMotionStates(outgoingChanges);
|
||||
avatarManager->handleChangedMotionStates(outgoingChanges);
|
||||
});
|
||||
|
||||
if (!_aboutToQuit) {
|
||||
|
@ -5124,58 +5100,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
activeRenderingThread = nullptr;
|
||||
}
|
||||
|
||||
void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool isZoomed) {
|
||||
auto originalViewport = renderArgs->_viewport;
|
||||
// Grab current viewport to reset it at the end
|
||||
|
||||
float aspect = (float)region.width() / region.height();
|
||||
float fov = MIRROR_FIELD_OF_VIEW;
|
||||
|
||||
auto myAvatar = getMyAvatar();
|
||||
|
||||
// bool eyeRelativeCamera = false;
|
||||
if (!isZoomed) {
|
||||
_mirrorCamera.setPosition(myAvatar->getChestPosition() +
|
||||
myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * myAvatar->getScale());
|
||||
|
||||
} else { // HEAD zoom level
|
||||
// FIXME note that the positioning of the camera relative to the avatar can suffer limited
|
||||
// precision as the user's position moves further away from the origin. Thus at
|
||||
// /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways
|
||||
// wildly as you rotate your avatar because the floating point values are becoming
|
||||
// larger, squeezing out the available digits of precision you have available at the
|
||||
// human scale for camera positioning.
|
||||
|
||||
// Previously there was a hack to correct this using the mechanism of repositioning
|
||||
// the avatar at the origin of the world for the purposes of rendering the mirror,
|
||||
// but it resulted in failing to render the avatar's head model in the mirror view
|
||||
// when in first person mode. Presumably this was because of some missed culling logic
|
||||
// that was not accounted for in the hack.
|
||||
|
||||
// This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
|
||||
// investigated in order to adapt the technique while fixing the head rendering issue,
|
||||
// but the complexity of the hack suggests that a better approach
|
||||
_mirrorCamera.setPosition(myAvatar->getDefaultEyePosition() +
|
||||
myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * myAvatar->getScale());
|
||||
}
|
||||
_mirrorCamera.setProjection(glm::perspective(glm::radians(fov), aspect, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP));
|
||||
_mirrorCamera.setOrientation(myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI, 0.0f)));
|
||||
|
||||
|
||||
// set the bounds of rear mirror view
|
||||
// the region is in device independent coordinates; must convert to device
|
||||
float ratio = (float)QApplication::desktop()->windowHandle()->devicePixelRatio() * getRenderResolutionScale();
|
||||
int width = region.width() * ratio;
|
||||
int height = region.height() * ratio;
|
||||
gpu::Vec4i viewport = gpu::Vec4i(0, 0, width, height);
|
||||
renderArgs->_viewport = viewport;
|
||||
|
||||
// render rear mirror view
|
||||
displaySide(renderArgs, _mirrorCamera, true);
|
||||
|
||||
renderArgs->_viewport = originalViewport;
|
||||
}
|
||||
|
||||
void Application::resetSensors(bool andReload) {
|
||||
DependencyManager::get<Faceshift>()->reset();
|
||||
DependencyManager::get<DdeFaceTracker>()->reset();
|
||||
|
|
|
@ -278,8 +278,6 @@ public:
|
|||
|
||||
virtual void pushPostUpdateLambda(void* key, std::function<void()> func) override;
|
||||
|
||||
const QRect& getMirrorViewRect() const { return _mirrorViewRect; }
|
||||
|
||||
void updateMyAvatarLookAtPosition();
|
||||
|
||||
float getAvatarSimrate() const { return _avatarSimCounter.rate(); }
|
||||
|
@ -370,7 +368,6 @@ public slots:
|
|||
void calibrateEyeTracker5Points();
|
||||
#endif
|
||||
|
||||
void aboutApp();
|
||||
static void showHelp();
|
||||
|
||||
void cycleCamera();
|
||||
|
@ -559,8 +556,6 @@ private:
|
|||
int _avatarSimsPerSecondReport {0};
|
||||
quint64 _lastAvatarSimsPerSecondUpdate {0};
|
||||
Camera _myCamera; // My view onto the world
|
||||
Camera _mirrorCamera; // Camera for mirror view
|
||||
QRect _mirrorViewRect;
|
||||
|
||||
Setting::Handle<QString> _previousScriptLocation;
|
||||
Setting::Handle<float> _fieldOfView;
|
||||
|
|
|
@ -74,9 +74,6 @@ Menu::Menu() {
|
|||
// File > Help
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::Help, 0, qApp, SLOT(showHelp()));
|
||||
|
||||
// File > About
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::AboutApp, 0, qApp, SLOT(aboutApp()), QAction::AboutRole);
|
||||
|
||||
// File > Quit
|
||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::Quit, Qt::CTRL | Qt::Key_Q, qApp, SLOT(quit()), QAction::QuitRole);
|
||||
|
||||
|
@ -249,9 +246,6 @@ Menu::Menu() {
|
|||
|
||||
viewMenu->addSeparator();
|
||||
|
||||
// View > Mini Mirror
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MiniMirror, 0, false);
|
||||
|
||||
// View > Center Player In View
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::CenterPlayerInView,
|
||||
0, true, qApp, SLOT(rotationModeChanged()),
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
};
|
||||
|
||||
namespace MenuOption {
|
||||
const QString AboutApp = "About Interface";
|
||||
const QString AddRemoveFriends = "Add/Remove Friends...";
|
||||
const QString AddressBar = "Show Address Bar";
|
||||
const QString Animations = "Animations...";
|
||||
|
@ -123,7 +122,6 @@ namespace MenuOption {
|
|||
const QString LogExtraTimings = "Log Extra Timing Details";
|
||||
const QString LowVelocityFilter = "Low Velocity Filter";
|
||||
const QString MeshVisible = "Draw Mesh";
|
||||
const QString MiniMirror = "Mini Mirror";
|
||||
const QString MuteAudio = "Mute Microphone";
|
||||
const QString MuteEnvironment = "Mute Environment";
|
||||
const QString MuteFaceTracking = "Mute Face Tracking";
|
||||
|
|
|
@ -424,7 +424,7 @@ void AvatarManager::getObjectsToChange(VectorOfMotionStates& result) {
|
|||
}
|
||||
}
|
||||
|
||||
void AvatarManager::handleOutgoingChanges(const VectorOfMotionStates& motionStates) {
|
||||
void AvatarManager::handleChangedMotionStates(const VectorOfMotionStates& motionStates) {
|
||||
// TODO: extract the MyAvatar results once we use a MotionState for it.
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
void getObjectsToRemoveFromPhysics(VectorOfMotionStates& motionStates);
|
||||
void getObjectsToAddToPhysics(VectorOfMotionStates& motionStates);
|
||||
void getObjectsToChange(VectorOfMotionStates& motionStates);
|
||||
void handleOutgoingChanges(const VectorOfMotionStates& motionStates);
|
||||
void handleChangedMotionStates(const VectorOfMotionStates& motionStates);
|
||||
void handleCollisionEvents(const CollisionEvents& collisionEvents);
|
||||
|
||||
Q_INVOKABLE float getAvatarDataRate(const QUuid& sessionID, const QString& rateName = QString("")) const;
|
||||
|
|
|
@ -104,6 +104,7 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
|||
_eyeContactTarget(LEFT_EYE),
|
||||
_realWorldFieldOfView("realWorldFieldOfView",
|
||||
DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES),
|
||||
_useAdvancedMovementControls("advancedMovementForHandControllersIsChecked", false),
|
||||
_hmdSensorMatrix(),
|
||||
_hmdSensorOrientation(),
|
||||
_hmdSensorPosition(),
|
||||
|
|
|
@ -74,6 +74,7 @@ class MyAvatar : public Avatar {
|
|||
|
||||
Q_PROPERTY(bool hmdLeanRecenterEnabled READ getHMDLeanRecenterEnabled WRITE setHMDLeanRecenterEnabled)
|
||||
Q_PROPERTY(bool characterControllerEnabled READ getCharacterControllerEnabled WRITE setCharacterControllerEnabled)
|
||||
Q_PROPERTY(bool useAdvancedMovementControls READ useAdvancedMovementControls WRITE setUseAdvancedMovementControls)
|
||||
|
||||
public:
|
||||
enum DriveKeys {
|
||||
|
@ -176,6 +177,10 @@ public:
|
|||
Q_INVOKABLE void setHMDLeanRecenterEnabled(bool value) { _hmdLeanRecenterEnabled = value; }
|
||||
Q_INVOKABLE bool getHMDLeanRecenterEnabled() const { return _hmdLeanRecenterEnabled; }
|
||||
|
||||
bool useAdvancedMovementControls() const { return _useAdvancedMovementControls.get(); }
|
||||
void setUseAdvancedMovementControls(bool useAdvancedMovementControls)
|
||||
{ _useAdvancedMovementControls.set(useAdvancedMovementControls); }
|
||||
|
||||
// get/set avatar data
|
||||
void saveData();
|
||||
void loadData();
|
||||
|
@ -436,6 +441,7 @@ private:
|
|||
glm::vec3 _trackedHeadPosition;
|
||||
|
||||
Setting::Handle<float> _realWorldFieldOfView;
|
||||
Setting::Handle<bool> _useAdvancedMovementControls;
|
||||
|
||||
// private methods
|
||||
void updateOrientation(float deltaTime);
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <FramebufferCache.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <CursorManager.h>
|
||||
|
@ -42,7 +41,6 @@ ApplicationOverlay::ApplicationOverlay()
|
|||
_domainStatusBorder = geometryCache->allocateID();
|
||||
_magnifierBorder = geometryCache->allocateID();
|
||||
_qmlGeometryId = geometryCache->allocateID();
|
||||
_rearViewGeometryId = geometryCache->allocateID();
|
||||
}
|
||||
|
||||
ApplicationOverlay::~ApplicationOverlay() {
|
||||
|
@ -51,7 +49,6 @@ ApplicationOverlay::~ApplicationOverlay() {
|
|||
geometryCache->releaseID(_domainStatusBorder);
|
||||
geometryCache->releaseID(_magnifierBorder);
|
||||
geometryCache->releaseID(_qmlGeometryId);
|
||||
geometryCache->releaseID(_rearViewGeometryId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +83,6 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
|||
// Now render the overlay components together into a single texture
|
||||
renderDomainConnectionStatusBorder(renderArgs); // renders the connected domain line
|
||||
renderAudioScope(renderArgs); // audio scope in the very back - NOTE: this is the debug audio scope, not the VU meter
|
||||
renderRearView(renderArgs); // renders the mirror view selfie
|
||||
renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope
|
||||
renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture, and the text overlays from scripts
|
||||
renderStatsAndLogs(renderArgs); // currently renders nothing
|
||||
|
@ -163,45 +159,6 @@ void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) {
|
|||
qApp->getOverlays().renderHUD(renderArgs);
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderRearViewToFbo(RenderArgs* renderArgs) {
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderRearView(RenderArgs* renderArgs) {
|
||||
if (!qApp->isHMDMode() && Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror) &&
|
||||
!Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||
gpu::Batch& batch = *renderArgs->_batch;
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
|
||||
auto framebuffer = DependencyManager::get<FramebufferCache>();
|
||||
auto selfieTexture = framebuffer->getSelfieFramebuffer()->getRenderBuffer(0);
|
||||
|
||||
int width = renderArgs->_viewport.z;
|
||||
int height = renderArgs->_viewport.w;
|
||||
mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, ORTHO_NEAR_CLIP, ORTHO_FAR_CLIP);
|
||||
batch.setProjectionTransform(legacyProjection);
|
||||
batch.setModelTransform(Transform());
|
||||
batch.resetViewTransform();
|
||||
|
||||
float screenRatio = ((float)qApp->getDevicePixelRatio());
|
||||
float renderRatio = ((float)qApp->getRenderResolutionScale());
|
||||
|
||||
auto viewport = qApp->getMirrorViewRect();
|
||||
glm::vec2 bottomLeft(viewport.left(), viewport.top() + viewport.height());
|
||||
glm::vec2 topRight(viewport.left() + viewport.width(), viewport.top());
|
||||
bottomLeft *= screenRatio;
|
||||
topRight *= screenRatio;
|
||||
glm::vec2 texCoordMinCorner(0.0f, 0.0f);
|
||||
glm::vec2 texCoordMaxCorner(viewport.width() * renderRatio / float(selfieTexture->getWidth()), viewport.height() * renderRatio / float(selfieTexture->getHeight()));
|
||||
|
||||
batch.setResourceTexture(0, selfieTexture);
|
||||
float alpha = DependencyManager::get<OffscreenUi>()->getDesktop()->property("unpinnedAlpha").toFloat();
|
||||
geometryCache->renderQuad(batch, bottomLeft, topRight, texCoordMinCorner, texCoordMaxCorner, glm::vec4(1.0f, 1.0f, 1.0f, alpha), _rearViewGeometryId);
|
||||
|
||||
batch.setResourceTexture(0, renderArgs->_whiteTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderStatsAndLogs(RenderArgs* renderArgs) {
|
||||
|
||||
// Display stats and log text onscreen
|
||||
|
|
|
@ -31,8 +31,6 @@ public:
|
|||
private:
|
||||
void renderStatsAndLogs(RenderArgs* renderArgs);
|
||||
void renderDomainConnectionStatusBorder(RenderArgs* renderArgs);
|
||||
void renderRearViewToFbo(RenderArgs* renderArgs);
|
||||
void renderRearView(RenderArgs* renderArgs);
|
||||
void renderQmlUi(RenderArgs* renderArgs);
|
||||
void renderAudioScope(RenderArgs* renderArgs);
|
||||
void renderOverlays(RenderArgs* renderArgs);
|
||||
|
@ -51,7 +49,6 @@ private:
|
|||
gpu::TexturePointer _overlayColorTexture;
|
||||
gpu::FramebufferPointer _overlayFramebuffer;
|
||||
int _qmlGeometryId { 0 };
|
||||
int _rearViewGeometryId { 0 };
|
||||
};
|
||||
|
||||
#endif // hifi_ApplicationOverlay_h
|
||||
|
|
|
@ -20,10 +20,6 @@ HIFI_QML_DEF(AvatarInputs)
|
|||
|
||||
|
||||
static AvatarInputs* INSTANCE{ nullptr };
|
||||
static const char SETTINGS_GROUP_NAME[] = "Rear View Tools";
|
||||
static const char ZOOM_LEVEL_SETTINGS[] = "ZoomLevel";
|
||||
|
||||
static Setting::Handle<int> rearViewZoomLevel(QStringList() << SETTINGS_GROUP_NAME << ZOOM_LEVEL_SETTINGS, 0);
|
||||
|
||||
AvatarInputs* AvatarInputs::getInstance() {
|
||||
if (!INSTANCE) {
|
||||
|
@ -36,8 +32,6 @@ AvatarInputs* AvatarInputs::getInstance() {
|
|||
|
||||
AvatarInputs::AvatarInputs(QQuickItem* parent) : QQuickItem(parent) {
|
||||
INSTANCE = this;
|
||||
int zoomSetting = rearViewZoomLevel.get();
|
||||
_mirrorZoomed = zoomSetting == 0;
|
||||
}
|
||||
|
||||
#define AI_UPDATE(name, src) \
|
||||
|
@ -62,8 +56,6 @@ void AvatarInputs::update() {
|
|||
if (!Menu::getInstance()) {
|
||||
return;
|
||||
}
|
||||
AI_UPDATE(mirrorVisible, Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror) && !qApp->isHMDMode()
|
||||
&& !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror));
|
||||
AI_UPDATE(cameraEnabled, !Menu::getInstance()->isOptionChecked(MenuOption::NoFaceTracking));
|
||||
AI_UPDATE(cameraMuted, Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking));
|
||||
AI_UPDATE(isHMD, qApp->isHMDMode());
|
||||
|
@ -122,15 +114,3 @@ void AvatarInputs::toggleAudioMute() {
|
|||
void AvatarInputs::resetSensors() {
|
||||
qApp->resetSensors();
|
||||
}
|
||||
|
||||
void AvatarInputs::toggleZoom() {
|
||||
_mirrorZoomed = !_mirrorZoomed;
|
||||
rearViewZoomLevel.set(_mirrorZoomed ? 0 : 1);
|
||||
emit mirrorZoomedChanged();
|
||||
}
|
||||
|
||||
void AvatarInputs::closeMirror() {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror)) {
|
||||
Menu::getInstance()->triggerOption(MenuOption::MiniMirror);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@ class AvatarInputs : public QQuickItem {
|
|||
AI_PROPERTY(bool, audioMuted, false)
|
||||
AI_PROPERTY(bool, audioClipping, false)
|
||||
AI_PROPERTY(float, audioLevel, 0)
|
||||
AI_PROPERTY(bool, mirrorVisible, false)
|
||||
AI_PROPERTY(bool, mirrorZoomed, true)
|
||||
AI_PROPERTY(bool, isHMD, false)
|
||||
AI_PROPERTY(bool, showAudioTools, true)
|
||||
|
||||
|
@ -44,8 +42,6 @@ signals:
|
|||
void audioMutedChanged();
|
||||
void audioClippingChanged();
|
||||
void audioLevelChanged();
|
||||
void mirrorVisibleChanged();
|
||||
void mirrorZoomedChanged();
|
||||
void isHMDChanged();
|
||||
void showAudioToolsChanged();
|
||||
|
||||
|
@ -53,8 +49,6 @@ protected:
|
|||
Q_INVOKABLE void resetSensors();
|
||||
Q_INVOKABLE void toggleCameraMute();
|
||||
Q_INVOKABLE void toggleAudioMute();
|
||||
Q_INVOKABLE void toggleZoom();
|
||||
Q_INVOKABLE void closeMirror();
|
||||
|
||||
private:
|
||||
float _trailingAudioLoudness{ 0 };
|
||||
|
|
|
@ -655,13 +655,11 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
|
|||
|
||||
|
||||
// pack SimulationOwner and terse update properties near each other
|
||||
|
||||
// NOTE: the server is authoritative for changes to simOwnerID so we always unpack ownership data
|
||||
// even when we would otherwise ignore the rest of the packet.
|
||||
|
||||
bool filterRejection = false;
|
||||
if (propertyFlags.getHasProperty(PROP_SIMULATION_OWNER)) {
|
||||
|
||||
QByteArray simOwnerData;
|
||||
int bytes = OctreePacketData::unpackDataFromBytes(dataAt, simOwnerData);
|
||||
SimulationOwner newSimOwner;
|
||||
|
@ -1879,6 +1877,7 @@ void EntityItem::setSimulationOwner(const SimulationOwner& owner) {
|
|||
}
|
||||
|
||||
void EntityItem::updateSimulationOwner(const SimulationOwner& owner) {
|
||||
// NOTE: this method only used by EntityServer. The Interface uses special code in readEntityDataFromBuffer().
|
||||
if (wantTerseEditLogging() && _simulationOwner != owner) {
|
||||
qCDebug(entities) << "sim ownership for" << getDebugName() << "is now" << owner;
|
||||
}
|
||||
|
@ -1894,8 +1893,9 @@ void EntityItem::clearSimulationOwnership() {
|
|||
}
|
||||
|
||||
_simulationOwner.clear();
|
||||
// don't bother setting the DIRTY_SIMULATOR_ID flag because clearSimulationOwnership()
|
||||
// is only ever called on the entity-server and the flags are only used client-side
|
||||
// don't bother setting the DIRTY_SIMULATOR_ID flag because:
|
||||
// (a) when entity-server calls clearSimulationOwnership() the dirty-flags are meaningless (only used by interface)
|
||||
// (b) the interface only calls clearSimulationOwnership() in a context that already knows best about dirty flags
|
||||
//_dirtyFlags |= Simulation::DIRTY_SIMULATOR_ID;
|
||||
|
||||
}
|
||||
|
|
|
@ -97,6 +97,21 @@ void EntityMotionState::updateServerPhysicsVariables() {
|
|||
_serverActionData = _entity->getActionData();
|
||||
}
|
||||
|
||||
void EntityMotionState::handleDeactivation() {
|
||||
// copy _server data to entity
|
||||
bool success;
|
||||
_entity->setPosition(_serverPosition, success, false);
|
||||
_entity->setOrientation(_serverRotation, success, false);
|
||||
_entity->setVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
_entity->setAngularVelocity(ENTITY_ITEM_ZERO_VEC3);
|
||||
// and also to RigidBody
|
||||
btTransform worldTrans;
|
||||
worldTrans.setOrigin(glmToBullet(_serverPosition));
|
||||
worldTrans.setRotation(glmToBullet(_serverRotation));
|
||||
_body->setWorldTransform(worldTrans);
|
||||
// no need to update velocities... should already be zero
|
||||
}
|
||||
|
||||
// virtual
|
||||
void EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
||||
assert(entityTreeIsLocked());
|
||||
|
@ -111,6 +126,8 @@ void EntityMotionState::handleEasyChanges(uint32_t& flags) {
|
|||
flags &= ~Simulation::DIRTY_PHYSICS_ACTIVATION;
|
||||
_body->setActivationState(WANTS_DEACTIVATION);
|
||||
_outgoingPriority = 0;
|
||||
const float ACTIVATION_EXPIRY = 3.0f; // something larger than the 2.0 hard coded in Bullet
|
||||
_body->setDeactivationTime(ACTIVATION_EXPIRY);
|
||||
} else {
|
||||
// disowned object is still moving --> start timer for ownership bid
|
||||
// TODO? put a delay in here proportional to distance from object?
|
||||
|
@ -221,12 +238,9 @@ void EntityMotionState::getWorldTransform(btTransform& worldTrans) const {
|
|||
}
|
||||
|
||||
// This callback is invoked by the physics simulation at the end of each simulation step...
|
||||
// iff the corresponding RigidBody is DYNAMIC and has moved.
|
||||
// iff the corresponding RigidBody is DYNAMIC and ACTIVE.
|
||||
void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||
if (!_entity) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(_entity);
|
||||
assert(entityTreeIsLocked());
|
||||
measureBodyAcceleration();
|
||||
bool positionSuccess;
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
virtual ~EntityMotionState();
|
||||
|
||||
void updateServerPhysicsVariables();
|
||||
void handleDeactivation();
|
||||
virtual void handleEasyChanges(uint32_t& flags) override;
|
||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override;
|
||||
|
||||
|
|
|
@ -259,13 +259,27 @@ void PhysicalEntitySimulation::getObjectsToChange(VectorOfMotionStates& result)
|
|||
_pendingChanges.clear();
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::handleOutgoingChanges(const VectorOfMotionStates& motionStates) {
|
||||
void PhysicalEntitySimulation::handleDeactivatedMotionStates(const VectorOfMotionStates& motionStates) {
|
||||
for (auto stateItr : motionStates) {
|
||||
ObjectMotionState* state = &(*stateItr);
|
||||
assert(state);
|
||||
if (state->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
EntityMotionState* entityState = static_cast<EntityMotionState*>(state);
|
||||
entityState->handleDeactivation();
|
||||
EntityItemPointer entity = entityState->getEntity();
|
||||
_entitiesToSort.insert(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::handleChangedMotionStates(const VectorOfMotionStates& motionStates) {
|
||||
QMutexLocker lock(&_mutex);
|
||||
|
||||
// walk the motionStates looking for those that correspond to entities
|
||||
for (auto stateItr : motionStates) {
|
||||
ObjectMotionState* state = &(*stateItr);
|
||||
if (state && state->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
assert(state);
|
||||
if (state->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
EntityMotionState* entityState = static_cast<EntityMotionState*>(state);
|
||||
EntityItemPointer entity = entityState->getEntity();
|
||||
assert(entity.get());
|
||||
|
|
|
@ -56,7 +56,8 @@ public:
|
|||
void setObjectsToChange(const VectorOfMotionStates& objectsToChange);
|
||||
void getObjectsToChange(VectorOfMotionStates& result);
|
||||
|
||||
void handleOutgoingChanges(const VectorOfMotionStates& motionStates);
|
||||
void handleDeactivatedMotionStates(const VectorOfMotionStates& motionStates);
|
||||
void handleChangedMotionStates(const VectorOfMotionStates& motionStates);
|
||||
void handleCollisionEvents(const CollisionEvents& collisionEvents);
|
||||
|
||||
EntityEditPacketSender* getPacketSender() { return _entityPacketSender; }
|
||||
|
@ -67,7 +68,7 @@ private:
|
|||
SetOfEntities _entitiesToAddToPhysics;
|
||||
|
||||
SetOfEntityMotionStates _pendingChanges; // EntityMotionStates already in PhysicsEngine that need their physics changed
|
||||
SetOfEntityMotionStates _outgoingChanges; // EntityMotionStates for which we need to send updates to entity-server
|
||||
SetOfEntityMotionStates _outgoingChanges; // EntityMotionStates for which we may need to send updates to entity-server
|
||||
|
||||
SetOfMotionStates _physicalObjects; // MotionStates of entities in PhysicsEngine
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
|||
return _collisionEvents;
|
||||
}
|
||||
|
||||
const VectorOfMotionStates& PhysicsEngine::getOutgoingChanges() {
|
||||
const VectorOfMotionStates& PhysicsEngine::getChangedMotionStates() {
|
||||
BT_PROFILE("copyOutgoingChanges");
|
||||
// Bullet will not deactivate static objects (it doesn't expect them to be active)
|
||||
// so we must deactivate them ourselves
|
||||
|
|
|
@ -65,7 +65,8 @@ public:
|
|||
bool hasOutgoingChanges() const { return _hasOutgoingChanges; }
|
||||
|
||||
/// \return reference to list of changed MotionStates. The list is only valid until beginning of next simulation loop.
|
||||
const VectorOfMotionStates& getOutgoingChanges();
|
||||
const VectorOfMotionStates& getChangedMotionStates();
|
||||
const VectorOfMotionStates& getDeactivatedMotionStates() const { return _dynamicsWorld->getDeactivatedMotionStates(); }
|
||||
|
||||
/// \return reference to list of Collision events. The list is only valid until beginning of next simulation loop.
|
||||
const CollisionEvents& getCollisionEvents();
|
||||
|
|
|
@ -120,30 +120,41 @@ void ThreadSafeDynamicsWorld::synchronizeMotionState(btRigidBody* body) {
|
|||
void ThreadSafeDynamicsWorld::synchronizeMotionStates() {
|
||||
BT_PROFILE("synchronizeMotionStates");
|
||||
_changedMotionStates.clear();
|
||||
|
||||
// NOTE: m_synchronizeAllMotionStates is 'false' by default for optimization.
|
||||
// See PhysicsEngine::init() where we call _dynamicsWorld->setForceUpdateAllAabbs(false)
|
||||
if (m_synchronizeAllMotionStates) {
|
||||
//iterate over all collision objects
|
||||
for (int i=0;i<m_collisionObjects.size();i++) {
|
||||
btCollisionObject* colObj = m_collisionObjects[i];
|
||||
btRigidBody* body = btRigidBody::upcast(colObj);
|
||||
if (body) {
|
||||
if (body->getMotionState()) {
|
||||
synchronizeMotionState(body);
|
||||
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
||||
}
|
||||
if (body && body->getMotionState()) {
|
||||
synchronizeMotionState(body);
|
||||
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//iterate over all active rigid bodies
|
||||
// TODO? if this becomes a performance bottleneck we could derive our own SimulationIslandManager
|
||||
// that remembers a list of objects deactivated last step
|
||||
_activeStates.clear();
|
||||
_deactivatedStates.clear();
|
||||
for (int i=0;i<m_nonStaticRigidBodies.size();i++) {
|
||||
btRigidBody* body = m_nonStaticRigidBodies[i];
|
||||
if (body->isActive()) {
|
||||
if (body->getMotionState()) {
|
||||
ObjectMotionState* motionState = static_cast<ObjectMotionState*>(body->getMotionState());
|
||||
if (motionState) {
|
||||
if (body->isActive()) {
|
||||
synchronizeMotionState(body);
|
||||
_changedMotionStates.push_back(static_cast<ObjectMotionState*>(body->getMotionState()));
|
||||
_changedMotionStates.push_back(motionState);
|
||||
_activeStates.insert(motionState);
|
||||
} else if (_lastActiveStates.find(motionState) != _lastActiveStates.end()) {
|
||||
// this object was active last frame but is no longer
|
||||
_deactivatedStates.push_back(motionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_activeStates.swap(_lastActiveStates);
|
||||
}
|
||||
|
||||
void ThreadSafeDynamicsWorld::saveKinematicState(btScalar timeStep) {
|
||||
|
|
|
@ -49,12 +49,16 @@ public:
|
|||
float getLocalTimeAccumulation() const { return m_localTime; }
|
||||
|
||||
const VectorOfMotionStates& getChangedMotionStates() const { return _changedMotionStates; }
|
||||
const VectorOfMotionStates& getDeactivatedMotionStates() const { return _deactivatedStates; }
|
||||
|
||||
private:
|
||||
// call this instead of non-virtual btDiscreteDynamicsWorld::synchronizeSingleMotionState()
|
||||
void synchronizeMotionState(btRigidBody* body);
|
||||
|
||||
VectorOfMotionStates _changedMotionStates;
|
||||
VectorOfMotionStates _deactivatedStates;
|
||||
SetOfMotionStates _activeStates;
|
||||
SetOfMotionStates _lastActiveStates;
|
||||
};
|
||||
|
||||
#endif // hifi_ThreadSafeDynamicsWorld_h
|
||||
|
|
|
@ -21,7 +21,6 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
|
|||
//If the size changed, we need to delete our FBOs
|
||||
if (_frameBufferSize != frameBufferSize) {
|
||||
_frameBufferSize = frameBufferSize;
|
||||
_selfieFramebuffer.reset();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
_cachedFramebuffers.clear();
|
||||
|
@ -30,16 +29,8 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
|
|||
}
|
||||
|
||||
void FramebufferCache::createPrimaryFramebuffer() {
|
||||
auto colorFormat = gpu::Element::COLOR_SRGBA_32;
|
||||
auto width = _frameBufferSize.width();
|
||||
auto height = _frameBufferSize.height();
|
||||
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||
|
||||
_selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("selfie"));
|
||||
auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler));
|
||||
_selfieFramebuffer->setRenderBuffer(0, tex);
|
||||
|
||||
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
|
||||
}
|
||||
|
||||
|
@ -60,10 +51,3 @@ void FramebufferCache::releaseFramebuffer(const gpu::FramebufferPointer& framebu
|
|||
_cachedFramebuffers.push_back(framebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
gpu::FramebufferPointer FramebufferCache::getSelfieFramebuffer() {
|
||||
if (!_selfieFramebuffer) {
|
||||
createPrimaryFramebuffer();
|
||||
}
|
||||
return _selfieFramebuffer;
|
||||
}
|
||||
|
|
|
@ -27,9 +27,6 @@ public:
|
|||
void setFrameBufferSize(QSize frameBufferSize);
|
||||
const QSize& getFrameBufferSize() const { return _frameBufferSize; }
|
||||
|
||||
/// Returns the framebuffer object used to render selfie maps;
|
||||
gpu::FramebufferPointer getSelfieFramebuffer();
|
||||
|
||||
/// Returns a free framebuffer with a single color attachment for temp or intra-frame operations
|
||||
gpu::FramebufferPointer getFramebuffer();
|
||||
|
||||
|
@ -42,8 +39,6 @@ private:
|
|||
|
||||
gpu::FramebufferPointer _shadowFramebuffer;
|
||||
|
||||
gpu::FramebufferPointer _selfieFramebuffer;
|
||||
|
||||
QSize _frameBufferSize{ 100, 100 };
|
||||
|
||||
std::mutex _mutex;
|
||||
|
|
|
@ -470,8 +470,8 @@ void Menu::removeSeparator(const QString& menuName, const QString& separatorName
|
|||
if (menu) {
|
||||
int textAt = findPositionOfMenuItem(menu, separatorName);
|
||||
QList<QAction*> menuActions = menu->actions();
|
||||
QAction* separatorText = menuActions[textAt];
|
||||
if (textAt > 0 && textAt < menuActions.size()) {
|
||||
QAction* separatorText = menuActions[textAt];
|
||||
QAction* separatorLine = menuActions[textAt - 1];
|
||||
if (separatorLine) {
|
||||
if (separatorLine->isSeparator()) {
|
||||
|
|
|
@ -17,15 +17,14 @@ var mappingName, basicMapping, isChecked;
|
|||
|
||||
var TURN_RATE = 1000;
|
||||
var MENU_ITEM_NAME = "Advanced Movement For Hand Controllers";
|
||||
var SETTINGS_KEY = 'advancedMovementForHandControllersIsChecked';
|
||||
var isDisabled = false;
|
||||
var previousSetting = Settings.getValue(SETTINGS_KEY);
|
||||
if (previousSetting === '' || previousSetting === false || previousSetting === 'false') {
|
||||
var previousSetting = MyAvatar.useAdvancedMovementControls;
|
||||
if (previousSetting === false) {
|
||||
previousSetting = false;
|
||||
isChecked = false;
|
||||
}
|
||||
|
||||
if (previousSetting === true || previousSetting === 'true') {
|
||||
if (previousSetting === true) {
|
||||
previousSetting = true;
|
||||
isChecked = true;
|
||||
}
|
||||
|
@ -37,7 +36,6 @@ function addAdvancedMovementItemToSettingsMenu() {
|
|||
isCheckable: true,
|
||||
isChecked: previousSetting
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function rotate180() {
|
||||
|
@ -72,7 +70,6 @@ function registerBasicMapping() {
|
|||
}
|
||||
return;
|
||||
});
|
||||
basicMapping.from(Controller.Standard.LX).to(Controller.Standard.RX);
|
||||
basicMapping.from(Controller.Standard.RY).to(function(value) {
|
||||
if (isDisabled) {
|
||||
return;
|
||||
|
@ -112,10 +109,10 @@ function menuItemEvent(menuItem) {
|
|||
if (menuItem == MENU_ITEM_NAME) {
|
||||
isChecked = Menu.isOptionChecked(MENU_ITEM_NAME);
|
||||
if (isChecked === true) {
|
||||
Settings.setValue(SETTINGS_KEY, true);
|
||||
MyAvatar.useAdvancedMovementControls = true;
|
||||
disableMappings();
|
||||
} else if (isChecked === false) {
|
||||
Settings.setValue(SETTINGS_KEY, false);
|
||||
MyAvatar.useAdvancedMovementControls = false;
|
||||
enableMappings();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue