Merge branch 'master' of github.com:highfidelity/hifi into model-scripting-2

This commit is contained in:
Seth Alves 2017-03-20 14:06:00 -07:00
commit d5ea69d81d
35 changed files with 232 additions and 601 deletions

View file

@ -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/

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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;

View file

@ -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()),

View file

@ -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";

View file

@ -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.
}

View file

@ -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;

View file

@ -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(),

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);
}
}

View file

@ -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 };

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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());

View file

@ -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

View file

@ -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

View file

@ -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();

View file

@ -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) {

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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()) {

View file

@ -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();
}
}