Merge branch 'master' of https://github.com/worklist/hifi into 20216

Conflicts:
	interface/CMakeLists.txt
This commit is contained in:
Thijs Wenker 2014-12-19 13:53:33 +01:00
commit e913095af5
132 changed files with 1498 additions and 1566 deletions

235
BUILD.md
View file

@ -1,33 +1,29 @@
Dependencies
===
###Dependencies
* [cmake](http://www.cmake.org/cmake/resources/software.html) ~> 2.8.12.2
* [Qt](http://qt-project.org/downloads) ~> 5.2.0
* [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.2
* [Qt](http://qt-project.org/downloads) ~> 5.3.0
* [glm](http://glm.g-truc.net/0.9.5/index.html) ~> 0.9.5.4
* [OpenSSL](https://www.openssl.org/related/binaries.html) ~> 1.0.1g
* IMPORTANT: OpenSSL 1.0.1g is critical to avoid a security vulnerability.
* [Intel Threading Building Blocks](https://www.threadingbuildingblocks.org/) ~> 4.3
#####Linux only
* [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0
* [zLib](http://www.zlib.net/) ~> 1.2.8
### OS Specific Build Guides
* [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X.
* [BUILD_LINUX.md](BUILD_LINUX.md) - additional instructions for Linux.
* [BUILD_WIN.md](BUILD_WIN.md) - additional instructions for Windows.
#####Windows only
* [GLEW](http://glew.sourceforge.net/) ~> 1.10.0
* [freeglut MSVC](http://www.transmissionzero.co.uk/software/freeglut-devel/) ~> 2.8.1
* [zLib](http://www.zlib.net/) ~> 1.2.8
CMake
===
###CMake
Hifi uses CMake to generate build files and project files for your platform.
####Qt
In order for CMake to find the Qt5 find modules, you will need to set an ENV variable pointing to your Qt installation.
For example, a Qt5 5.2.0 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment).
For example, a Qt5 5.3.2 installation to /usr/local/qt5 would require that QT_CMAKE_PREFIX_PATH be set with the following command. This can either be entered directly into your shell session before you build or in your shell profile (e.g.: ~/.bash_profile, ~/.bashrc, ~/.zshrc - this depends on your shell and environment).
The path it needs to be set to will depend on where and how Qt5 was installed. e.g.
export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.0/clang_64/lib/cmake/
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.2.1/lib/cmake
export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.3.2/clang_64/lib/cmake/
export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.3.2/lib/cmake
export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake
####Generating build files
@ -42,7 +38,7 @@ Any variables that need to be set for CMake to find dependencies can be set as E
For example, to pass the QT_CMAKE_PREFIX_PATH variable during build file generation:
cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.2.1/lib/cmake
cmake .. -DQT_CMAKE_PREFIX_PATH=/usr/local/qt/5.3.2/lib/cmake
####Finding Dependencies
You can point our [Cmake find modules](cmake/modules/) to the correct version of dependencies by setting one of the three following variables to the location of the correct version of the dependency.
@ -53,206 +49,7 @@ In the examples below the variable $NAME would be replaced by the name of the de
* $NAME_ROOT_DIR - set this variable in your ENV
* HIFI_LIB_DIR - set this variable in your ENV to your High Fidelity lib folder, should contain a folder '$name'
UNIX
===
In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source.
####Linux
Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required:
libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev
####OS X
#####Package Managers
[Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple.
brew tap highfidelity/homebrew-formulas
brew install cmake glm openssl
brew install highfidelity/formulas/qt5
brew link qt5 --force
We have a [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) that you can use/tap to install some of the dependencies. In the code block above qt5 is installed from a formula in this repository.
*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.2.0 stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.*
#####Xcode
If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles.
cmake .. -GXcode
After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run.
If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories.
Windows
===
####Visual Studio
Currently building on Windows has been tested using the following compilers:
* Visual Studio C++ 2010 Express
* Visual Studio 2013
(If anyone can test using Visual Studio 2013 Express then please update this document)
#####Windows SDK 7.1
If using Visual Studio 2010, or using Visual Studio 2013 but building as a Visual Studio 2010 project, you need [Microsoft Windows SDK for Windows 7 and .NET Framework 4](http://www.microsoft.com/en-us/download/details.aspx?id=8279).
NOTE: If using Visual Studio C++ 2010 Express, you need to follow a specific install order. See below before installing the Windows SDK.
######Windows SDK 8.1
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`.
#####Visual Studio C++ 2010 Express
Visual Studio C++ 2010 Express can be downloaded [here](http://www.visualstudio.com/en-us/downloads#d-2010-express).
The following patches/service packs are also required:
* [VS2010 SP1](http://www.microsoft.com/en-us/download/details.aspx?id=23691)
* [VS2010 SP1 Compiler Update](http://www.microsoft.com/en-us/download/details.aspx?id=4422)
IMPORTANT: Use the following install order:
Visual Studio C++ 2010 Express
Windows SDK 7.1
VS2010 SP1
VS2010 SP1 Compiler Update
If you get an error while installing the VS2010 SP1 Compiler update saying that you don't have the Windows SDK installed, then uninstall all of the above and start again in the correct order.
Some of the build instructions will ask you to start a Visual Studio Command Prompt. You should have a shortcut in your Start menu called "Open Visual Studio Command Prompt (2010)" which will do so.
#####Visual Studio 2013
You can use the Community or Professional editions of Visual Studio 2013.
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.
Or you can start a regular command prompt and then run:
"%VS120COMNTOOLS%\vsvars32.bat"
If you experience issues building interface on Visual Studio 2013, try generating the build files with Visual Studio 2010 instead. To do so, download Visual Studio 2010 and run `cmake .. -G "Visual Studio 10"` (Assuming running from %HIFI_DIR%\build).
####Qt
You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version.
NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules.
* Download the online installer [here](http://qt-project.org/downloads)
* When it asks you to select components, ONLY select the following:
* Qt > Qt 5.2.0 > **msvc2010 32-bit OpenGL**
* Download the offline installer [here](http://download.qt-project.org/official_releases/qt/5.2/5.2.0/qt-windows-opensource-5.2.0-msvc2010_opengl-x86-offline.exe)
Once Qt is installed, you need to manually configure the following:
* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.2.0\msvc2010_opengl\bin\`.
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.2.0\msvc2010_opengl` directory.
If building as a Visual Studio 2013 project, download and configure the msvc2013 version of Qt instead.
####External Libraries
CMake will need to know where the headers and libraries for required external dependencies are.
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
-> freeglut
-> bin
-> include
-> lib
-> glew
-> bin
-> include
-> lib
-> glm
-> glm
-> glm.hpp
-> openssl
-> bin
-> include
-> lib
-> zlib
-> include
-> lib
-> test
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.
As with the Qt libraries, you will need to make sure that directories containing DLL'S are in your path. Where possible, you can use static builds of the external dependencies to avoid this requirement.
#### 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 the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html):
* Visual C++ 2008 Redistributables
* Win32 OpenSSL v1.0.1h
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.
#### Zlib
Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib.
Add the following environment variables (remember to substitute your own directory for %HIFI_LIB_DIR%):
ZLIB_LIBRARY=%HIFI_LIB_DIR%\zlib\lib\zdll.lib
ZLIB_INCLUDE_DIR=%HIFI_LIB_DIR%\zlib\include
Add to the PATH: `%HIFI_LIB_DIR%\zlib`
Important! This should be added at the beginning of the path, not the end. That's because your
system likely has many copies of zlib1.dll, and you want High Fidelity to use the correct version. If High Fidelity picks up the wrong zlib1.dll then it might be unable to use it, and that would cause it to fail to start, showing only the cryptic error "The application was unable to start correctly: 0xc0000022".
#### freeglut
Download the binary package: `freeglut-MSVC-2.8.1-1.mp.zip`. Extract to %HIFI_LIB_DIR%\freeglut.
Add to the PATH: `%HIFI_LIB_DIR%\freeglut\bin`
#### GLEW
Download the binary package: `glew-1.10.0-win32.zip`. Extract to %HIFI_LIB_DIR%\glew (you'll need to rename the default directory name).
Add to the PATH: `%HIFI_LIB_DIR%\glew\bin\Release\Win32`
#### GLM
This package contains only headers, so there's nothing to add to the PATH.
Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder.
#### Build High Fidelity using Visual Studio
Follow the same build steps from the CMake section, but pass a different generator to CMake.
cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 10"
If you're using Visual Studio 2013 then pass "Visual Studio 12" instead of "Visual Studio 10" (yes, 12, not 13).
Open %HIFI_DIR%\build\hifi.sln and compile.
####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
####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
Optional Components
===
###Optional Components
####QXmpp
@ -260,7 +57,7 @@ You can find QXmpp [here](https://github.com/qxmpp-project/qxmpp). The inclusion
OS X users who tap our [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) can install QXmpp via homebrew - `brew install highfidelity/formulas/qxmpp`.
#### Devices
####Devices
You can support external input/output devices such as Leap Motion, Faceplus, Faceshift, PrioVR, MIDI, Razr Hydra and more by adding each individual SDK in the visible building path. Refer to the readme file available in each device folder in [interface/external/](interface/external) for the detailed explanation of the requirements to use the device.

12
BUILD_LINUX.md Normal file
View file

@ -0,0 +1,12 @@
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file.
###Linux Specific Dependencies
* [freeglut](http://freeglut.sourceforge.net/) ~> 2.8.0
* [zLib](http://www.zlib.net/) ~> 1.2.8
In general, as long as external dependencies are placed in OS standard locations, CMake will successfully find them during its run. When possible, you may choose to install depencies from your package manager of choice, or from source.
###Qt5 Dependencies
Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required:
libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack-dev

22
BUILD_OSX.md Normal file
View file

@ -0,0 +1,22 @@
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file.
###Homebrew
[Homebrew](http://brew.sh/) is an excellent package manager for OS X. It makes install of all hifi dependencies very simple.
brew tap highfidelity/homebrew-formulas
brew install cmake glm openssl tbb
brew install highfidelity/formulas/qt5
brew link qt5 --force
We have a [homebrew formulas repository](https://github.com/highfidelity/homebrew-formulas) that you can use/tap to install some of the dependencies. In the code block above qt5 is installed from a formula in this repository.
*Our [qt5 homebrew formula](https://raw.github.com/highfidelity/homebrew-formulas/master/qt5.rb) is for a patched version of Qt 5.3.x stable that removes wireless network scanning that can reduce real-time audio performance. We recommended you use this formula to install Qt.*
###Xcode
If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles.
cmake .. -GXcode
After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run.
If the build completes successfully, you will have built targets for all components located in the `build/${target_name}/Debug` directories.

149
BUILD_WIN.md Normal file
View file

@ -0,0 +1,149 @@
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.
###Windows Dependencies
* [GLEW](http://glew.sourceforge.net/) ~> 1.10.0
* [freeglut MSVC](http://www.transmissionzero.co.uk/software/freeglut-devel/) ~> 2.8.1
* [zLib](http://www.zlib.net/) ~> 1.2.8
###Visual Studio
Currently building on Windows has been tested using the following compilers:
* Visual Studio 2013
(If anyone can test using Visual Studio 2013 Express then please update this document)
####Visual Studio 2013
You can use the Community or Professional editions of Visual Studio 2013.
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.
Or you can start a regular command prompt and then run:
"%VS120COMNTOOLS%\vsvars32.bat"
#####Windows SDK 8.1
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`.
###Qt
You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version.
NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules.
* Download the online installer [here](http://qt-project.org/downloads)
* When it asks you to select components, ONLY select the following:
* Qt > Qt 5.3.2 > **msvc2013 32-bit OpenGL**
* Download the offline installer [here](http://download.qt-project.org/official_releases/qt/5.3/5.3.2/qt-opensource-windows-x86-msvc2013_opengl-5.3.2.exe)
Once Qt is installed, you need to manually configure the following:
* Make sure the Qt runtime DLLs are loadable. You must do this before you attempt to build because some tools for the build depend on Qt. E.g., add to the PATH: `Qt\5.3.2\msvc2013_opengl\bin\`.
* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt\5.3.2\msvc2013_opengl` directory.
###External Libraries
CMake will need to know where the headers and libraries for required external dependencies are.
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
-> freeglut
-> bin
-> include
-> lib
-> glew
-> bin
-> include
-> lib
-> glm
-> glm
-> glm.hpp
-> openssl
-> bin
-> include
-> lib
-> tbb
-> include
-> lib
-> zlib
-> include
-> lib
-> test
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.
As with the Qt libraries, you will need to make sure that directories containing DLL'S are in your path. Where possible, you can use static builds of the external dependencies to avoid this requirement.
###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 the following binary packages [from this website](http://slproweb.com/products/Win32OpenSSL.html):
* Visual C++ 2008 Redistributables
* Win32 OpenSSL v1.0.1h
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.
###Intel Threading Building Blocks (TBB)
Download the zip from the [TBB website](https://www.threadingbuildingblocks.org/).
We recommend you extract it to %HIFI_LIB_DIR%\tbb. This will help our FindTBB cmake module find what it needs. You can place it wherever you like on your machine if you specify TBB_ROOT_DIR as an environment variable or a variable passed when cmake is run.
###Zlib
Download the compiled DLL from the [zlib website](http://www.zlib.net/). Extract to %HIFI_LIB_DIR%\zlib.
Add the following environment variables (remember to substitute your own directory for %HIFI_LIB_DIR%):
ZLIB_LIBRARY=%HIFI_LIB_DIR%\zlib\lib\zdll.lib
ZLIB_INCLUDE_DIR=%HIFI_LIB_DIR%\zlib\include
Add to the PATH: `%HIFI_LIB_DIR%\zlib`
Important! This should be added at the beginning of the path, not the end. That's because your
system likely has many copies of zlib1.dll, and you want High Fidelity to use the correct version. If High Fidelity picks up the wrong zlib1.dll then it might be unable to use it, and that would cause it to fail to start, showing only the cryptic error "The application was unable to start correctly: 0xc0000022".
###freeglut
Download the binary package: `freeglut-MSVC-2.8.1-1.mp.zip`. Extract to %HIFI_LIB_DIR%\freeglut.
Add to the PATH: `%HIFI_LIB_DIR%\freeglut\bin`
###GLEW
Download the binary package: `glew-1.10.0-win32.zip`. Extract to %HIFI_LIB_DIR%\glew (you'll need to rename the default directory name).
Add to the PATH: `%HIFI_LIB_DIR%\glew\bin\Release\Win32`
###GLM
This package contains only headers, so there's nothing to add to the PATH.
Be careful with glm. For the folder other libraries would normally call 'include', the folder containing the headers, glm opts to use 'glm'. You will have a glm folder nested inside the top-level glm folder.
###Build High Fidelity using Visual Studio
Follow the same build steps from the CMake section, but pass a different generator to CMake.
cmake .. -DZLIB_LIBRARY=%ZLIB_LIBRARY% -DZLIB_INCLUDE_DIR=%ZLIB_INCLUDE_DIR% -G "Visual Studio 12"
Open %HIFI_DIR%\build\hifi.sln and compile.
###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
###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

View file

@ -34,6 +34,24 @@ elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-strict-aliasing")
endif(WIN32)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
if (APPLE)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++0x")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --stdlib=libc++")
endif ()
if (NOT QT_CMAKE_PREFIX_PATH)
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
endif ()

View file

@ -12,7 +12,7 @@ link_hifi_libraries(
)
if (UNIX)
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${CMAKE_DL_LIBS})
target_link_libraries(${TARGET_NAME} ${CMAKE_DL_LIBS})
endif (UNIX)
link_shared_dependencies()

View file

@ -439,12 +439,13 @@ int AudioMixer::prepareMixForListeningNode(Node* node) {
// loop through all other nodes that have sufficient audio to mix
int streamsMixed = 0;
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([&](const SharedNodePointer& otherNode){
if (otherNode->getLinkedData()) {
AudioMixerClientData* otherNodeClientData = (AudioMixerClientData*) otherNode->getLinkedData();
// enumerate the ARBs attached to the otherNode and add all that should be added to mix
const QHash<QUuid, PositionalAudioStream*>& otherNodeAudioStreams = otherNodeClientData->getAudioStreams();
QHash<QUuid, PositionalAudioStream*>::ConstIterator i;
for (i = otherNodeAudioStreams.constBegin(); i != otherNodeAudioStreams.constEnd(); i++) {
@ -454,14 +455,15 @@ int AudioMixer::prepareMixForListeningNode(Node* node) {
if (otherNodeStream->getType() == PositionalAudioStream::Microphone) {
streamUUID = otherNode->getUUID();
}
if (*otherNode != *node || otherNodeStream->shouldLoopbackForNode()) {
streamsMixed += addStreamToMixForListeningNodeWithStream(listenerNodeData, streamUUID,
otherNodeStream, nodeAudioStream);
streamsMixed += addStreamToMixForListeningNodeWithStream(listenerNodeData, streamUUID,
otherNodeStream, nodeAudioStream);
}
}
}
}
});
return streamsMixed;
}
@ -539,12 +541,11 @@ void AudioMixer::readPendingDatagram(const QByteArray& receivedPacket, const Hif
QByteArray packet = receivedPacket;
populatePacketHeader(packet, PacketTypeMuteEnvironment);
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node){
if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && node != nodeList->sendingNodeForPacket(receivedPacket)) {
nodeList->writeDatagram(packet, packet.size(), node);
}
}
});
} else {
// let processNodeData handle it.
nodeList->processNodeData(senderSockAddr, receivedPacket);
@ -607,8 +608,9 @@ void AudioMixer::sendStatsPacket() {
NodeList* nodeList = NodeList::getInstance();
int clientNumber = 0;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node) {
// if we're too large, send the packet
if (sizeOfStats > TOO_BIG_FOR_MTU) {
nodeList->sendStatsToDomainServer(statsObject2);
@ -626,7 +628,7 @@ void AudioMixer::sendStatsPacket() {
somethingToSend = true;
sizeOfStats += property.size() + value.size();
}
}
});
if (somethingToSend) {
nodeList->sendStatsToDomainServer(statsObject2);
@ -764,7 +766,8 @@ void AudioMixer::run() {
_lastPerSecondCallbackTime = now;
}
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node) {
if (node->getLinkedData()) {
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
@ -831,7 +834,7 @@ void AudioMixer::run() {
++_sumListeners;
}
}
}
});
++_numStatFrames;
@ -889,7 +892,7 @@ void AudioMixer::perSecondActions() {
_timeSpentPerHashMatchCallStats.getWindowSum() / WINDOW_LENGTH_USECS * 100.0,
_timeSpentPerHashMatchCallStats.getCurrentIntervalSum() / USECS_PER_SECOND * 100.0);
foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([](const SharedNodePointer& node) {
if (node->getLinkedData()) {
AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData();
@ -899,7 +902,7 @@ void AudioMixer::perSecondActions() {
nodeData->printUpstreamDownstreamStats();
}
}
}
});
}
_datagramsReadPerCallStats.currentIntervalComplete();

View file

@ -122,7 +122,7 @@ void AvatarMixer::broadcastAvatarData() {
AvatarMixerClientData* nodeData = NULL;
AvatarMixerClientData* otherNodeData = NULL;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node) {
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()
&& (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) {
++_sumListeners;
@ -135,7 +135,7 @@ void AvatarMixer::broadcastAvatarData() {
// this is an AGENT we have received head data from
// send back a packet with other active node data to this node
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& otherNode) {
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()
&& (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) {
@ -203,13 +203,13 @@ void AvatarMixer::broadcastAvatarData() {
otherNodeData->getMutex().unlock();
}
}
});
nodeList->writeDatagram(mixedAvatarByteArray, node);
nodeData->getMutex().unlock();
}
}
});
_lastFrameTimestamp = QDateTime::currentMSecsSinceEpoch();
}

View file

@ -131,15 +131,17 @@ void EntityServer::pruneDeletedEntities() {
if (tree->hasAnyDeletedEntities()) {
quint64 earliestLastDeletedEntitiesSent = usecTimestampNow() + 1; // in the future
foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) {
if (otherNode->getLinkedData()) {
EntityNodeData* nodeData = static_cast<EntityNodeData*>(otherNode->getLinkedData());
NodeList::getInstance()->eachNode([&earliestLastDeletedEntitiesSent](const SharedNodePointer& node) {
if (node->getLinkedData()) {
EntityNodeData* nodeData = static_cast<EntityNodeData*>(node->getLinkedData());
quint64 nodeLastDeletedEntitiesSentAt = nodeData->getLastDeletedEntitiesSentAt();
if (nodeLastDeletedEntitiesSentAt < earliestLastDeletedEntitiesSent) {
earliestLastDeletedEntitiesSent = nodeLastDeletedEntitiesSentAt;
}
}
}
});
tree->forgetEntitiesDeletedBefore(earliestLastDeletedEntitiesSent);
}
}

View file

@ -261,7 +261,7 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
continue;
}
const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID);
const SharedNodePointer& destinationNode = NodeList::getInstance()->nodeWithUUID(nodeUUID);
// retrieve sequence number stats of node, prune its missing set
SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats();

View file

@ -1222,13 +1222,16 @@ void OctreeServer::aboutToFinish() {
qDebug() << qPrintable(_safeServerName) << "server STARTING about to finish...";
qDebug() << qPrintable(_safeServerName) << "inform Octree Inbound Packet Processor that we are shutting down...";
_octreeInboundPacketProcessor->shuttingDown();
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([this](const SharedNodePointer& node) {
qDebug() << qPrintable(_safeServerName) << "server about to finish while node still connected node:" << *node;
forceNodeShutdown(node);
}
});
if (_persistThread) {
_persistThread->aboutToFinish();
}
qDebug() << qPrintable(_safeServerName) << "server ENDING about to finish...";
}

View file

@ -25,10 +25,9 @@ macro(LINK_HIFI_LIBRARIES)
# link the actual library - it is static so don't bubble it up
target_link_libraries(${TARGET_NAME} ${HIFI_LIBRARY})
# ask the library what its dynamic dependencies are and link them
get_target_property(LINKED_TARGET_DEPENDENCY_LIBRARIES ${HIFI_LIBRARY} DEPENDENCY_LIBRARIES)
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK ${LINKED_TARGET_DEPENDENCY_LIBRARIES})
# ask the library what its include dependencies are and link them
get_target_property(LINKED_TARGET_DEPENDENCY_INCLUDES ${HIFI_LIBRARY} DEPENDENCY_INCLUDES)
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES ${LINKED_TARGET_DEPENDENCY_INCLUDES})
endforeach()
endmacro(LINK_HIFI_LIBRARIES)

View file

@ -9,17 +9,14 @@
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
macro(LINK_SHARED_DEPENDENCIES)
if (${TARGET_NAME}_LIBRARIES_TO_LINK)
list(REMOVE_DUPLICATES ${TARGET_NAME}_LIBRARIES_TO_LINK)
macro(LINK_SHARED_DEPENDENCIES)
if (${TARGET_NAME}_DEPENDENCY_INCLUDES)
list(REMOVE_DUPLICATES ${TARGET_NAME}_DEPENDENCY_INCLUDES)
# link these libraries to our target
target_link_libraries(${TARGET_NAME} ${${TARGET_NAME}_LIBRARIES_TO_LINK})
# include those in our own target
include_directories(SYSTEM ${${TARGET_NAME}_DEPENDENCY_INCLUDES})
endif ()
# we've already linked our Qt modules, but we need to bubble them up to parents
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${${TARGET}_QT_MODULES_TO_LINK}")
# set the property on this target so it can be retreived by targets linking to us
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_LIBRARIES "${${TARGET}_LIBRARIES_TO_LINK}")
set_target_properties(${TARGET_NAME} PROPERTIES DEPENDENCY_INCLUDES "${${TARGET_NAME}_DEPENDENCY_INCLUDES}")
endmacro(LINK_SHARED_DEPENDENCIES)

View file

@ -18,16 +18,14 @@ macro(SETUP_HIFI_LIBRARY)
# create a library and set the property so it can be referenced later
add_library(${TARGET_NAME} ${LIB_SRCS} ${AUTOMTC_SRC})
set(QT_MODULES_TO_LINK ${ARGN})
list(APPEND QT_MODULES_TO_LINK Core)
set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN})
list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core)
find_package(Qt5 COMPONENTS ${QT_MODULES_TO_LINK} REQUIRED)
foreach(QT_MODULE ${QT_MODULES_TO_LINK})
get_target_property(QT_LIBRARY_LOCATION Qt5::${QT_MODULE} LOCATION)
# add the actual path to the Qt module to our LIBRARIES_TO_LINK variable
# find these Qt modules and link them to our own target
find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED)
foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES})
target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE})
list(APPEND ${TARGET_NAME}_QT_MODULES_TO_LINK ${QT_LIBRARY_LOCATION})
endforeach()
endmacro(SETUP_HIFI_LIBRARY)

View file

@ -25,17 +25,13 @@ macro(SETUP_HIFI_PROJECT)
# add the executable, include additional optional sources
add_executable(${TARGET_NAME} ${TARGET_SRCS} "${AUTOMTC_SRC}")
set(QT_MODULES_TO_LINK ${ARGN})
list(APPEND QT_MODULES_TO_LINK Core)
set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN})
list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core)
find_package(Qt5 COMPONENTS ${QT_MODULES_TO_LINK} REQUIRED)
foreach(QT_MODULE ${QT_MODULES_TO_LINK})
# find these Qt modules and link them to our own target
find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED)
foreach(QT_MODULE ${${TARGET_NAME}_DEPENDENCY_QT_MODULES})
target_link_libraries(${TARGET_NAME} Qt5::${QT_MODULE})
# add the actual path to the Qt module to our LIBRARIES_TO_LINK variable
get_target_property(QT_LIBRARY_LOCATION Qt5::${QT_MODULE} LOCATION)
list(APPEND ${TARGET_NAME}_QT_MODULES_TO_LINK ${QT_LIBRARY_LOCATION})
endforeach()
endmacro()

View file

@ -0,0 +1,75 @@
#
# FindTBB.cmake
#
# Try to find the Intel Threading Building Blocks library
#
# You can provide a TBB_ROOT_DIR which contains lib and include directories
#
# Once done this will define
#
# TBB_FOUND - system was able to find TBB
# TBB_INCLUDE_DIRS - the TBB include directory
# TBB_LIBRARIES - link this to use TBB
#
# Created on 12/14/2014 by Stephen Birarda
# Copyright 2014 High Fidelity, Inc.
#
# Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
hifi_library_search_hints("tbb")
find_path(TBB_INCLUDE_DIRS tbb/tbb.h PATH_SUFFIXES include HINTS ${TBB_SEARCH_DIRS})
set(_TBB_LIB_NAME "tbb")
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
if (APPLE)
set(_TBB_LIB_DIR "lib/libc++")
elseif (UNIX)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_TBB_ARCH_DIR "intel64")
else()
set(_TBB_ARCH_DIR "ia32")
endif()
execute_process(
COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION
)
if (GCC_VERSION VERSION_GREATER 4.4 OR GCC_VERSION VERSION_EQUAL 4.4)
set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/gcc4.4")
elseif (GCC_VERSION VERSION_GREATER 4.1 OR GCC_VERSION VERSION_EQUAL 4.1)
set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/gcc4.1")
else ()
message(FATAL_ERROR "Could not find a compatible version of Threading Building Blocks library for your compiler.")
endif ()
elseif (WIN32)
if (CMAKE_CL_64)
set(_TBB_ARCH_DIR "intel64")
else()
set(_TBB_ARCH_DIR "ia32")
endif()
set(_TBB_LIB_DIR "lib/${_TBB_ARCH_DIR}/vc12")
endif ()
find_library(TBB_LIBRARY_DEBUG NAMES ${_TBB_LIB_NAME}_debug PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS})
find_library(TBB_LIBRARY_RELEASE NAMES ${_TBB_LIB_NAME} PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS})
find_library(TBB_MALLOC_LIBRARY_DEBUG NAMES ${_TBB_LIB_MALLOC_NAME}_debug PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS})
find_library(TBB_MALLOC_LIBRARY_RELEASE NAMES ${_TBB_LIB_MALLOC_NAME} PATH_SUFFIXES ${_TBB_LIB_DIR} HINTS ${TBB_SEARCH_DIRS})
include(SelectLibraryConfigurations)
include(FindPackageHandleStandardArgs)
select_library_configurations(TBB)
select_library_configurations(TBB_MALLOC)
find_package_handle_standard_args(TBB DEFAULT_MSG TBB_LIBRARY TBB_MALLOC_LIBRARY TBB_INCLUDE_DIRS)
set(TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY})

View file

@ -32,9 +32,10 @@ if (APPLE)
find_library(VISAGE_VISION_LIBRARY NAME vsvision PATH_SUFFIXES lib HINTS ${VISAGE_SEARCH_DIRS})
find_library(VISAGE_OPENCV_LIBRARY NAME OpenCV PATH_SUFFIXES dependencies/OpenCV_MacOSX/lib HINTS ${VISAGE_SEARCH_DIRS})
find_library(AppKit AppKit)
find_library(QuartzCore QuartzCore)
find_library(CoreVideo CoreVideo)
find_library(QTKit QTKit)
find_library(IOKit IOKit)
elseif (WIN32)
find_path(VISAGE_XML_INCLUDE_DIR libxml/xmlreader.h PATH_SUFFIXES dependencies/libxml2/include HINTS ${VISAGE_SEARCH_DIRS})
find_path(VISAGE_OPENCV_INCLUDE_DIR opencv/cv.h PATH_SUFFIXES dependencies/OpenCV/include HINTS ${VISAGE_SEARCH_DIRS})
@ -49,19 +50,19 @@ include(FindPackageHandleStandardArgs)
list(APPEND VISAGE_ARGS_LIST VISAGE_BASE_INCLUDE_DIR VISAGE_XML_INCLUDE_DIR
VISAGE_OPENCV_INCLUDE_DIR VISAGE_OPENCV2_INCLUDE_DIR
VISAGE_CORE_LIBRARY VISAGE_VISION_LIBRARY VISAGE_OPENCV_LIBRARY)
VISAGE_CORE_LIBRARY VISAGE_VISION_LIBRARY)
if (APPLE)
list(APPEND VISAGE_ARGS_LIST QuartzCore AppKit QTKit)
list(APPEND VISAGE_ARGS_LIST CoreVideo QTKit IOKit)
endif ()
find_package_handle_standard_args(Visage DEFAULT_MSG ${VISAGE_ARGS_LIST})
set(VISAGE_INCLUDE_DIRS "${VISAGE_XML_INCLUDE_DIR}" "${VISAGE_OPENCV_INCLUDE_DIR}" "${VISAGE_OPENCV2_INCLUDE_DIR}" "${VISAGE_BASE_INCLUDE_DIR}")
set(VISAGE_LIBRARIES "${VISAGE_CORE_LIBRARY}" "${VISAGE_VISION_LIBRARY}" "${VISAGE_OPENCV_LIBRARY}")
set(VISAGE_LIBRARIES "${VISAGE_CORE_LIBRARY}" "${VISAGE_VISION_LIBRARY}")
if (APPLE)
list(APPEND VISAGE_LIBRARIES ${QuartzCore} ${AppKit} ${QTKit})
list(APPEND VISAGE_LIBRARIES "${CoreVideo}" "${QTKit}" "${IOKit}")
endif ()
mark_as_advanced(VISAGE_INCLUDE_DIRS VISAGE_LIBRARIES)

View file

@ -50,6 +50,6 @@ endif ()
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
# append OpenSSL to our list of libraries to link
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${OPENSSL_LIBRARIES}")
target_link_libraries(${TARGET_NAME} ${OPENSSL_LIBRARIES})
link_shared_dependencies()

View file

@ -1,131 +1,3 @@
// Add your JavaScript for assignment below this line
// The following is an example of Conway's Game of Life (http://en.wikipedia.org/wiki/Conway's_Game_of_Life)
var NUMBER_OF_CELLS_EACH_DIMENSION = 64;
var NUMBER_OF_CELLS = NUMBER_OF_CELLS_EACH_DIMENSION * NUMBER_OF_CELLS_EACH_DIMENSION;
var currentCells = [];
var nextCells = [];
var METER_LENGTH = 1;
var cellScale = (NUMBER_OF_CELLS_EACH_DIMENSION * METER_LENGTH) / NUMBER_OF_CELLS_EACH_DIMENSION;
// randomly populate the cell start values
for (var i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
// create the array to hold this row
currentCells[i] = [];
// create the array to hold this row in the nextCells array
nextCells[i] = [];
for (var j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
currentCells[i][j] = Math.floor(Math.random() * 2);
// put the same value in the nextCells array for first board draw
nextCells[i][j] = currentCells[i][j];
}
}
function isNeighbourAlive(i, j) {
if (i < 0 || i >= NUMBER_OF_CELLS_EACH_DIMENSION
|| i < 0 || j >= NUMBER_OF_CELLS_EACH_DIMENSION) {
return 0;
} else {
return currentCells[i][j];
}
}
function updateCells() {
var i = 0;
var j = 0;
for (i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
for (j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
// figure out the number of live neighbours for the i-j cell
var liveNeighbours =
isNeighbourAlive(i + 1, j - 1) + isNeighbourAlive(i + 1, j) + isNeighbourAlive(i + 1, j + 1) +
isNeighbourAlive(i, j - 1) + isNeighbourAlive(i, j + 1) +
isNeighbourAlive(i - 1, j - 1) + isNeighbourAlive(i - 1, j) + isNeighbourAlive(i - 1, j + 1);
if (currentCells[i][j]) {
// live cell
if (liveNeighbours < 2) {
// rule #1 - under-population - this cell will die
// mark it zero to mark the change
nextCells[i][j] = 0;
} else if (liveNeighbours < 4) {
// rule #2 - this cell lives
// mark it -1 to mark no change
nextCells[i][j] = -1;
} else {
// rule #3 - overcrowding - this cell dies
// mark it zero to mark the change
nextCells[i][j] = 0;
}
} else {
// dead cell
if (liveNeighbours == 3) {
// rule #4 - reproduction - this cell revives
// mark it one to mark the change
nextCells[i][j] = 1;
} else {
// this cell stays dead
// mark it -1 for no change
nextCells[i][j] = -1;
}
}
if (Math.random() < 0.001) {
// Random mutation to keep things interesting in there.
nextCells[i][j] = 1;
}
}
}
for (i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
for (j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
if (nextCells[i][j] != -1) {
// there has been a change to this cell, change the value in the currentCells array
currentCells[i][j] = nextCells[i][j];
}
}
}
}
function sendNextCells() {
for (var i = 0; i < NUMBER_OF_CELLS_EACH_DIMENSION; i++) {
for (var j = 0; j < NUMBER_OF_CELLS_EACH_DIMENSION; j++) {
if (nextCells[i][j] != -1) {
// there has been a change to the state of this cell, send it
// find the x and y position for this voxel, z = 0
var x = j * cellScale;
var y = i * cellScale;
// queue a packet to add a voxel for the new cell
var color = (nextCells[i][j] == 1) ? 255 : 1;
Voxels.setVoxel(x, y, 0, cellScale, color, color, color);
}
}
}
}
var sentFirstBoard = false;
function step(deltaTime) {
if (sentFirstBoard) {
// we've already sent the first full board, perform a step in time
updateCells();
} else {
// this will be our first board send
sentFirstBoard = true;
}
sendNextCells();
}
Script.update.connect(step);
Voxels.setPacketsPerSecond(200);
// Here you can put a script that will be run by an assignment-client (AC)
// For examples, please go to http://public.highfidelity.io/scripts
// The directory named acScripts contains assignment-client specific scripts you can try.

View file

@ -857,49 +857,48 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
if (nodeData->isAuthenticated()) {
// if this authenticated node has any interest types, send back those nodes as well
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& otherNode){
// reset our nodeByteArray and nodeDataStream
QByteArray nodeByteArray;
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
if (otherNode->getUUID() != node->getUUID() && nodeInterestList.contains(otherNode->getType())) {
// don't send avatar nodes to other avatars, that will come from avatar mixer
nodeDataStream << *otherNode.data();
// pack the secret that these two nodes will use to communicate with each other
QUuid secretUUID = nodeData->getSessionSecretHash().value(otherNode->getUUID());
if (secretUUID.isNull()) {
// generate a new secret UUID these two nodes can use
secretUUID = QUuid::createUuid();
// set that on the current Node's sessionSecretHash
nodeData->getSessionSecretHash().insert(otherNode->getUUID(), secretUUID);
// set it on the other Node's sessionSecretHash
reinterpret_cast<DomainServerNodeData*>(otherNode->getLinkedData())
->getSessionSecretHash().insert(node->getUUID(), secretUUID);
}
nodeDataStream << secretUUID;
if (broadcastPacket.size() + nodeByteArray.size() > dataMTU) {
// we need to break here and start a new packet
// so send the current one
nodeList->writeDatagram(broadcastPacket, node, senderSockAddr);
// reset the broadcastPacket structure
broadcastPacket.resize(numBroadcastPacketLeadBytes);
broadcastDataStream.device()->seek(numBroadcastPacketLeadBytes);
}
// append the nodeByteArray to the current state of broadcastDataStream
broadcastPacket.append(nodeByteArray);
}
}
});
}
// always write the last broadcastPacket
@ -996,14 +995,14 @@ void DomainServer::readAvailableDatagrams() {
void DomainServer::setupPendingAssignmentCredits() {
// enumerate the NodeList to find the assigned nodes
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) {
// check if we have a non-finalized transaction for this node to add this amount to
TransactionHash::iterator i = _pendingAssignmentCredits.find(nodeData->getWalletUUID());
WalletTransaction* existingTransaction = NULL;
while (i != _pendingAssignmentCredits.end() && i.key() == nodeData->getWalletUUID()) {
if (!i.value()->isFinalized()) {
existingTransaction = i.value();
@ -1012,16 +1011,16 @@ void DomainServer::setupPendingAssignmentCredits() {
++i;
}
}
qint64 elapsedMsecsSinceLastPayment = nodeData->getPaymentIntervalTimer().elapsed();
nodeData->getPaymentIntervalTimer().restart();
const float CREDITS_PER_HOUR = 0.10f;
const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000);
const int SATOSHIS_PER_MSEC = CREDITS_PER_MSEC * SATOSHIS_PER_CREDIT;
float pendingCredits = elapsedMsecsSinceLastPayment * SATOSHIS_PER_MSEC;
if (existingTransaction) {
existingTransaction->incrementAmount(pendingCredits);
} else {
@ -1030,7 +1029,7 @@ void DomainServer::setupPendingAssignmentCredits() {
_pendingAssignmentCredits.insert(nodeData->getWalletUUID(), freshTransaction);
}
}
}
});
}
void DomainServer::sendPendingTransactionsToServer() {
@ -1155,11 +1154,12 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
// add the number of currently connected agent users
int numConnectedAuthedUsers = 0;
foreach(const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([&numConnectedAuthedUsers](const SharedNodePointer& node){
if (node->getLinkedData() && !static_cast<DomainServerNodeData*>(node->getLinkedData())->getUsername().isEmpty()) {
++numConnectedAuthedUsers;
}
}
});
const QString DOMAIN_HEARTBEAT_KEY = "heartbeat";
const QString HEARTBEAT_NUM_USERS_KEY = "num_users";
@ -1277,8 +1277,9 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS
parseNodeDataFromByteArray(packetStream, throwawayNodeType, nodePublicAddress, nodeLocalAddress,
senderSockAddr);
SharedNodePointer checkInNode = nodeList->updateSocketsForNode(nodeUUID,
nodePublicAddress, nodeLocalAddress);
SharedNodePointer checkInNode = nodeList->nodeWithUUID(nodeUUID);
checkInNode->setPublicSocket(nodePublicAddress);
checkInNode->setLocalSocket(nodeLocalAddress);
// update last receive to now
quint64 timeNow = usecTimestampNow();
@ -1470,15 +1471,15 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
QJsonObject assignedNodesJSON;
// enumerate the NodeList to find the assigned nodes
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([this, &assignedNodesJSON](const SharedNodePointer& node){
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
if (!nodeData->getAssignmentUUID().isNull()) {
// add the node using the UUID as the key
QString uuidString = uuidStringWithoutCurlyBraces(nodeData->getAssignmentUUID());
assignedNodesJSON[uuidString] = jsonObjectForNode(node);
}
}
});
assignmentJSON["fulfilled"] = assignedNodesJSON;
@ -1532,12 +1533,10 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
QJsonArray nodesJSONArray;
// enumerate the NodeList to find the assigned nodes
LimitedNodeList* nodeList = LimitedNodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
LimitedNodeList::getInstance()->eachNode([this, &nodesJSONArray](const SharedNodePointer& node){
// add the node using the UUID as the key
nodesJSONArray.append(jsonObjectForNode(node));
}
});
rootJSON["nodes"] = nodesJSONArray;
@ -2065,16 +2064,9 @@ void DomainServer::addStaticAssignmentsToQueue() {
QHash<QUuid, SharedAssignmentPointer>::iterator staticAssignment = staticHashCopy.begin();
while (staticAssignment != staticHashCopy.end()) {
// add any of the un-matched static assignments to the queue
bool foundMatchingAssignment = false;
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
if (node->getUUID() == staticAssignment->data()->getUUID()) {
foundMatchingAssignment = true;
}
}
if (!foundMatchingAssignment) {
if (!NodeList::getInstance()->nodeWithUUID(staticAssignment->data()->getUUID())) {
// this assignment has not been fulfilled - reset the UUID and add it to the assignment queue
refreshStaticAssignmentAndAddToQueue(*staticAssignment);
}

View file

@ -1,9 +1,3 @@
var SETTING_GRID_VISIBLE = 'gridVisible';
var SETTING_GRID_SNAP_TO_GRID = 'gridSnapToGrid';
var SETTING_GRID_MINOR_WIDTH= 'gridMinorWidth';
var SETTING_GRID_MAJOR_EVERY = 'gridMajorEvery';
var SETTING_GRID_COLOR = 'gridColor';
Grid = function(opts) {
var that = {};
@ -18,6 +12,9 @@ Grid = function(opts) {
var worldSize = 16384;
var minorGridWidth = 0.5;
var majorGridWidth = 1.5;
var snapToGrid = false;
var gridOverlay = Overlays.addOverlay("grid", {
@ -26,7 +23,7 @@ Grid = function(opts) {
color: { red: 0, green: 0, blue: 128 },
alpha: 1.0,
rotation: Quat.fromPitchYawRollDegrees(90, 0, 0),
minorGridSpacing: 0.1,
minorGridWidth: 0.1,
majorGridEvery: 2,
});
@ -43,37 +40,16 @@ Grid = function(opts) {
that.getSnapToGrid = function() { return snapToGrid; };
that.setEnabled = function(enabled) {
if (that.enabled != enabled) {
that.enabled = enabled;
if (enabled) {
if (selectionManager.hasSelection()) {
that.setPosition(selectionManager.getBottomPosition());
} else {
that.setPosition(MyAvatar.position);
}
}
updateGrid();
}
that.enabled = enabled;
updateGrid();
}
that.setVisible = function(visible, noUpdate) {
if (visible != that.visible) {
that.visible = visible;
updateGrid();
that.visible = visible;
updateGrid();
if (visible) {
if (selectionManager.hasSelection()) {
that.setPosition(selectionManager.getBottomPosition());
} else {
that.setPosition(MyAvatar.position);
}
}
if (!noUpdate) {
that.emitUpdate();
}
if (!noUpdate) {
that.emitUpdate();
}
}
@ -205,43 +181,15 @@ Grid = function(opts) {
}
function cleanup() {
saveSettings();
Overlays.deleteOverlay(gridOverlay);
}
function loadSettings() {
that.setVisible(Settings.getValue(SETTING_GRID_VISIBLE) == "true", true);
snapToGrid = Settings.getValue(SETTING_GRID_SNAP_TO_GRID) == "true";
minorGridSpacing = parseFloat(Settings.getValue(SETTING_GRID_MINOR_WIDTH), 10);
majorGridEvery = parseInt(Settings.getValue(SETTING_GRID_MAJOR_EVERY), 10);
try {
var newColor = JSON.parse(Settings.getValue(SETTING_GRID_COLOR));
if (newColor.red !== undefined && newColor.green !== undefined && newColor.blue !== undefined) {
gridColor.red = newColor.red;
gridColor.green = newColor.green;
gridColor.blue = newColor.blue;
}
} catch (e) {
}
updateGrid();
}
function saveSettings() {
Settings.setValue(SETTING_GRID_VISIBLE, that.visible);
Settings.setValue(SETTING_GRID_SNAP_TO_GRID, snapToGrid);
Settings.setValue(SETTING_GRID_MINOR_WIDTH, minorGridSpacing);
Settings.setValue(SETTING_GRID_MAJOR_EVERY, majorGridEvery);
Settings.setValue(SETTING_GRID_COLOR, JSON.stringify(gridColor));
}
that.addListener = function(callback) {
that.onUpdate = callback;
}
Script.scriptEnding.connect(cleanup);
loadSettings();
updateGrid();
that.onUpdate = null;

View file

@ -2,7 +2,7 @@ set(TARGET_NAME interface)
project(${TARGET_NAME})
# set a default root dir for each of our optional externals if it was not passed
set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "Visage" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb" "RSSDK")
set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb" "RSSDK")
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
@ -107,7 +107,8 @@ endif()
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
# link required hifi libraries
link_hifi_libraries(shared octree voxels gpu fbx metavoxels networking entities avatars audio animation script-engine physics render-utils)
link_hifi_libraries(shared octree voxels gpu fbx metavoxels networking entities avatars audio animation script-engine physics
render-utils entities-renderer)
# find any optional and required libraries
find_package(ZLIB REQUIRED)
@ -156,7 +157,6 @@ if (VISAGE_FOUND AND NOT DISABLE_VISAGE AND APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-comment")
find_library(AVFoundation AVFoundation)
find_library(CoreMedia CoreMedia)
find_library(NEW_STD_LIBRARY libc++.dylib /usr/lib/)
target_link_libraries(${TARGET_NAME} ${AVFoundation} ${CoreMedia} ${NEW_STD_LIBRARY})
endif ()

View file

@ -64,6 +64,7 @@
#include <HFBackEvent.h>
#include <LocalVoxelsList.h>
#include <LogHandler.h>
#include <MainWindow.h>
#include <NetworkAccessManager.h>
#include <OctalCode.h>
#include <OctreeSceneStats.h>
@ -73,6 +74,7 @@
#include <ProgramObject.h>
#include <ResourceCache.h>
#include <SoundCache.h>
#include <TextRenderer.h>
#include <UserActivityLogger.h>
#include <UUID.h>
@ -110,7 +112,6 @@
#include "ui/InfoView.h"
#include "ui/Snapshot.h"
#include "ui/Stats.h"
#include "ui/TextRenderer.h"
@ -143,7 +144,6 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
QApplication(argc, argv),
_window(new MainWindow(desktop())),
_glWidget(new GLCanvas()),
_toolWindow(NULL),
_nodeThread(new QThread(this)),
_datagramProcessor(),
@ -156,9 +156,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_voxelImporter(),
_importSucceded(false),
_sharedVoxelSystem(TREE_SCALE, DEFAULT_MAX_VOXELS_PER_SYSTEM, &_clipboard),
_entities(true),
_entities(true, this, this),
_entityCollisionSystem(),
_entityClipboardRenderer(false),
_entityClipboardRenderer(false, this, this),
_entityClipboard(),
_wantToKillLocalVoxels(false),
_viewFrustum(),
@ -192,8 +192,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
_isVSyncOn(true),
_aboutToQuit(false)
{
Model::setViewStateInterface(this); // The model class will sometimes need to know view state details from us
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
Model::setAbstractViewStateInterface(this); // The model class will sometimes need to know view state details from us
// read the ApplicationInfo.ini file for Name/Version/Domain information
QSettings applicationInfo(PathUtils::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat);
@ -363,16 +364,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
ResourceCache::setRequestLimit(3);
_window->setCentralWidget(_glWidget);
_window->setCentralWidget(glCanvas.data());
restoreSizeAndPosition();
_window->setVisible(true);
_glWidget->setFocusPolicy(Qt::StrongFocus);
_glWidget->setFocus();
glCanvas->setFocusPolicy(Qt::StrongFocus);
glCanvas->setFocus();
// enable mouse tracking; otherwise, we only get drag events
_glWidget->setMouseTracking(true);
glCanvas->setMouseTracking(true);
_toolWindow = new ToolWindow();
_toolWindow->setWindowFlags(_toolWindow->windowFlags() | Qt::WindowStaysOnTopHint);
@ -391,7 +392,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
checkVersion();
_overlays.init(_glWidget); // do this before scripts load
_overlays.init(glCanvas.data()); // do this before scripts load
LocalVoxelsList::getInstance()->addPersistantTree(DOMAIN_TREE_NAME, _voxels.getTree());
LocalVoxelsList::getInstance()->addPersistantTree(CLIPBOARD_TREE_NAME, &_clipboard);
@ -440,6 +441,7 @@ void Application::aboutToQuit() {
}
Application::~Application() {
_entities.getTree()->setSimulation(NULL);
qInstallMessageHandler(NULL);
@ -481,8 +483,6 @@ Application::~Application() {
Menu::getInstance()->deleteLater();
_myAvatar = NULL;
delete _glWidget;
}
void Application::saveSettings() {
@ -622,7 +622,7 @@ void Application::paintGL() {
if (OculusManager::isConnected()) {
DependencyManager::get<TextureCache>()->setFrameBufferSize(OculusManager::getRenderTargetSize());
} else {
QSize fbSize = _glWidget->getDeviceSize() * getRenderResolutionScale();
QSize fbSize = DependencyManager::get<GLCanvas>()->getDeviceSize() * getRenderResolutionScale();
DependencyManager::get<TextureCache>()->setFrameBufferSize(fbSize);
}
@ -1046,7 +1046,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
if (isShifted) {
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() - 0.1f);
if (TV3DManager::isConnected()) {
TV3DManager::configureCamera(_myCamera, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
TV3DManager::configureCamera(_myCamera, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
}
} else {
_myCamera.setEyeOffsetPosition(_myCamera.getEyeOffsetPosition() + glm::vec3(-0.001, 0, 0));
@ -1058,7 +1059,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
if (isShifted) {
_viewFrustum.setFocalLength(_viewFrustum.getFocalLength() + 0.1f);
if (TV3DManager::isConnected()) {
TV3DManager::configureCamera(_myCamera, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
TV3DManager::configureCamera(_myCamera, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
}
} else {
@ -1504,7 +1506,7 @@ void Application::idle() {
{
PerformanceTimer perfTimer("updateGL");
PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()");
_glWidget->updateGL();
DependencyManager::get<GLCanvas>()->updateGL();
}
{
PerformanceTimer perfTimer("rest");
@ -1530,13 +1532,14 @@ void Application::idle() {
void Application::checkBandwidthMeterClick() {
// ... to be called upon button release
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) &&
Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
Menu::getInstance()->isOptionChecked(MenuOption::UserInterface) &&
glm::compMax(glm::abs(glm::ivec2(getMouseX() - getMouseDragStartedX(),
getMouseY() - getMouseDragStartedY())))
<= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH
&& _bandwidthMeter.isWithinArea(getMouseX(), getMouseY(), _glWidget->width(), _glWidget->height())) {
&& _bandwidthMeter.isWithinArea(getMouseX(), getMouseY(), glCanvas->width(), glCanvas->height())) {
// The bandwidth meter is visible, the click didn't get dragged too far and
// we actually hit the bandwidth meter
@ -1565,7 +1568,8 @@ void Application::setFullscreen(bool fullscreen) {
}
void Application::setEnable3DTVMode(bool enable3DTVMode) {
resizeGL(_glWidget->getDeviceWidth(),_glWidget->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
resizeGL(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
}
void Application::setEnableVRMode(bool enableVRMode) {
@ -1590,7 +1594,8 @@ void Application::setEnableVRMode(bool enableVRMode) {
_myCamera.setHmdRotation(glm::quat());
}
resizeGL(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
resizeGL(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
}
void Application::setRenderVoxels(bool voxelRender) {
@ -1652,8 +1657,9 @@ glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVox
bool Application::mouseOnScreen() const {
if (OculusManager::isConnected()) {
return getMouseX() >= 0 && getMouseX() <= _glWidget->getDeviceWidth() &&
getMouseY() >= 0 && getMouseY() <= _glWidget->getDeviceHeight();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
return getMouseX() >= 0 && getMouseX() <= glCanvas->getDeviceWidth() &&
getMouseY() >= 0 && getMouseY() <= glCanvas->getDeviceHeight();
}
return true;
}
@ -1693,13 +1699,13 @@ int Application::getMouseDragStartedY() const {
}
FaceTracker* Application::getActiveFaceTracker() {
Faceshift* faceshift = DependencyManager::get<Faceshift>();
Visage* visage = DependencyManager::get<Visage>();
DdeFaceTracker* dde = DependencyManager::get<DdeFaceTracker>();
Faceshift::SharedPointer faceshift = DependencyManager::get<Faceshift>();
Visage::SharedPointer visage = DependencyManager::get<Visage>();
DdeFaceTracker::SharedPointer dde = DependencyManager::get<DdeFaceTracker>();
return (dde->isActive() ? static_cast<FaceTracker*>(dde) :
(faceshift->isActive() ? static_cast<FaceTracker*>(faceshift) :
(visage->isActive() ? static_cast<FaceTracker*>(visage) : NULL)));
return (dde->isActive() ? static_cast<FaceTracker*>(dde.data()) :
(faceshift->isActive() ? static_cast<FaceTracker*>(faceshift.data()) :
(visage->isActive() ? static_cast<FaceTracker*>(visage.data()) : NULL)));
}
struct SendVoxelsOperationArgs {
@ -1772,7 +1778,8 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString suggestedName = desktopLocation.append("/voxels.svo");
QString fileNameString = QFileDialog::getSaveFileName(_glWidget, tr("Export Voxels"), suggestedName,
QString fileNameString = QFileDialog::getSaveFileName(DependencyManager::get<GLCanvas>().data(),
tr("Export Voxels"), suggestedName,
tr("Sparse Voxel Octree Files (*.svo)"));
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
const char* fileName = fileNameAscii.data();
@ -2027,9 +2034,9 @@ void Application::init() {
_metavoxels.init();
_audio.init(_glWidget);
_rearMirrorTools = new RearMirrorTools(_glWidget, _mirrorViewRect, _settings);
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
_audio.init(glCanvas.data());
_rearMirrorTools = new RearMirrorTools(glCanvas.data(), _mirrorViewRect, _settings);
connect(_rearMirrorTools, SIGNAL(closeView()), SLOT(closeMirrorView()));
connect(_rearMirrorTools, SIGNAL(restoreView()), SLOT(restoreMirrorView()));
@ -2042,11 +2049,12 @@ void Application::init() {
// save settings when avatar changes
connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings);
// make sure our texture cache knows about window size changes
DependencyManager::get<TextureCache>()->associateWithWidget(getGLWidget());
// make sure our texture cache knows about window size changes
DependencyManager::get<TextureCache>()->associateWithWidget(glCanvas.data());
// initialize the GlowEffect with our widget
DependencyManager::get<GlowEffect>()->init(getGLWidget(), Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect));
DependencyManager::get<GlowEffect>()->init(glCanvas.data(),
Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect));
}
void Application::closeMirrorView() {
@ -2114,7 +2122,7 @@ void Application::updateMouseRay() {
void Application::updateFaceshift() {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateFaceshift()");
Faceshift* faceshift = DependencyManager::get<Faceshift>();
Faceshift::SharedPointer faceshift = DependencyManager::get<Faceshift>();
// Update faceshift
faceshift->update();
@ -2458,72 +2466,73 @@ int Application::sendNackPackets() {
char packet[MAX_PACKET_SIZE];
// iterates thru all nodes in NodeList
foreach(const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList* nodeList = NodeList::getInstance();
nodeList->eachNode([&](const SharedNodePointer& node){
if (node->getActiveSocket() &&
( node->getType() == NodeType::VoxelServer
|| node->getType() == NodeType::EntityServer)
) {
if (node->getActiveSocket()
&& (node->getType() == NodeType::VoxelServer || node->getType() == NodeType::EntityServer)) {
QUuid nodeUUID = node->getUUID();
// if there are octree packets from this node that are waiting to be processed,
// don't send a NACK since the missing packets may be among those waiting packets.
if (_octreeProcessor.hasPacketsToProcessFrom(nodeUUID)) {
continue;
return;
}
_octreeSceneStatsLock.lockForRead();
// retreive octree scene stats of this node
if (_octreeServerSceneStats.find(nodeUUID) == _octreeServerSceneStats.end()) {
_octreeSceneStatsLock.unlock();
continue;
return;
}
// get sequence number stats of node, prune its missing set, and make a copy of the missing set
SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats();
sequenceNumberStats.pruneMissingSet();
const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet();
_octreeSceneStatsLock.unlock();
// construct nack packet(s) for this node
int numSequenceNumbersAvailable = missingSequenceNumbers.size();
QSet<OCTREE_PACKET_SEQUENCE>::const_iterator missingSequenceNumbersIterator = missingSequenceNumbers.constBegin();
while (numSequenceNumbersAvailable > 0) {
char* dataAt = packet;
int bytesRemaining = MAX_PACKET_SIZE;
// pack header
int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack);
dataAt += numBytesPacketHeader;
bytesRemaining -= numBytesPacketHeader;
// calculate and pack the number of sequence numbers
int numSequenceNumbersRoomFor = (bytesRemaining - sizeof(uint16_t)) / sizeof(OCTREE_PACKET_SEQUENCE);
uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numSequenceNumbersRoomFor);
uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt;
*numSequenceNumbersAt = numSequenceNumbers;
dataAt += sizeof(uint16_t);
// pack sequence numbers
for (int i = 0; i < numSequenceNumbers; i++) {
OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt;
*sequenceNumberAt = *missingSequenceNumbersIterator;
dataAt += sizeof(OCTREE_PACKET_SEQUENCE);
missingSequenceNumbersIterator++;
}
numSequenceNumbersAvailable -= numSequenceNumbers;
// send it
NodeList::getInstance()->writeUnverifiedDatagram(packet, dataAt - packet, node);
nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node);
packetsSent++;
}
}
}
});
return packetsSent;
}
@ -2556,7 +2565,9 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
int inViewServers = 0;
int unknownJurisdictionServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList* nodeList = NodeList::getInstance();
nodeList->eachNode([&](const SharedNodePointer& node) {
// only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) {
totalServers++;
@ -2587,7 +2598,7 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
}
}
}
}
});
if (wantExtraDebugging) {
qDebug("Servers: total %d, in view %d, unknown jurisdiction %d",
@ -2613,20 +2624,18 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
if (wantExtraDebugging) {
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
}
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node){
// only send to the NodeTypes that are serverType
if (node->getActiveSocket() && node->getType() == serverType) {
// get the server bounds for this server
QUuid nodeUUID = node->getUUID();
bool inView = false;
bool unknownView = false;
// if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction...
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
@ -2636,15 +2645,15 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
}
} else {
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AACube serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.cubeInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inView = true;
@ -2657,15 +2666,15 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
}
}
}
if (inView) {
_octreeQuery.setMaxOctreePacketsPerSecond(perServerPPS);
} else if (unknownView) {
if (wantExtraDebugging) {
qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
<< perUnknownServer << " to send us jurisdiction.";
<< perUnknownServer << " to send us jurisdiction.";
}
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
// If there's only one server, then don't do this, and just let the normal voxel query pass through
// as expected... this way, we will actually get a valid scene if there is one to be seen
@ -2689,22 +2698,22 @@ void Application::queryOctree(NodeType_t serverType, PacketType packetType, Node
}
// set up the packet for sending...
unsigned char* endOfQueryPacket = queryPacket;
// insert packet type/version and node UUID
endOfQueryPacket += populatePacketHeader(reinterpret_cast<char*>(endOfQueryPacket), packetType);
// encode the query data...
endOfQueryPacket += _octreeQuery.getBroadcastData(endOfQueryPacket);
int packetLength = endOfQueryPacket - queryPacket;
// make sure we still have an active socket
nodeList->writeUnverifiedDatagram(reinterpret_cast<const char*>(queryPacket), packetLength, node);
// Feed number of bytes to corresponding channel of the bandwidth meter
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
}
}
});
}
bool Application::isHMDMode() const {
@ -2917,8 +2926,9 @@ void Application::updateShadowMap() {
}
fbo->release();
glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
glViewport(0, 0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
}
const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f };
@ -2945,6 +2955,18 @@ bool Application::shouldRenderMesh(float largestDimension, float distanceToCamer
return Menu::getInstance()->shouldRenderMesh(largestDimension, distanceToCamera);
}
float Application::getSizeScale() const {
return Menu::getInstance()->getVoxelSizeScale();
}
int Application::getBoundaryLevelAdjust() const {
return Menu::getInstance()->getBoundaryLevelAdjust();
}
PickRay Application::computePickRay(float x, float y) {
return getCamera()->computePickRay(x, y);
}
QImage Application::renderAvatarBillboard() {
DependencyManager::get<TextureCache>()->getPrimaryFramebufferObject()->bind();
@ -2952,7 +2974,9 @@ QImage Application::renderAvatarBillboard() {
Glower glower;
const int BILLBOARD_SIZE = 64;
renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
renderRearViewMirror(QRect(0, DependencyManager::get<GLCanvas>()->getDeviceHeight() - BILLBOARD_SIZE,
BILLBOARD_SIZE, BILLBOARD_SIZE),
true);
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits());
@ -3255,8 +3279,9 @@ bool Application::getCascadeShadowsEnabled() {
}
glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
float horizontalScale = _glWidget->getDeviceWidth() / 2.0f;
float verticalScale = _glWidget->getDeviceHeight() / 2.0f;
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
float horizontalScale = glCanvas->getDeviceWidth() / 2.0f;
float verticalScale = glCanvas->getDeviceHeight() / 2.0f;
// -1,-1 is 0,windowHeight
// 1,1 is windowWidth,0
@ -3275,7 +3300,7 @@ glm::vec2 Application::getScaledScreenPoint(glm::vec2 projectedPoint) {
// -1,-1 1,-1
glm::vec2 screenPoint((projectedPoint.x + 1.0) * horizontalScale,
((projectedPoint.y + 1.0) * -verticalScale) + _glWidget->getDeviceHeight());
((projectedPoint.y + 1.0) * -verticalScale) + glCanvas->getDeviceHeight());
return screenPoint;
}
@ -3586,7 +3611,7 @@ void Application::resetSensors() {
QScreen* currentScreen = _window->windowHandle()->screen();
QWindow* mainWindow = _window->windowHandle();
QPoint windowCenter = mainWindow->geometry().center();
_glWidget->cursor().setPos(currentScreen, windowCenter);
DependencyManager::get<GLCanvas>()->cursor().setPos(currentScreen, windowCenter);
_myAvatar->reset();
@ -4022,7 +4047,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->registerGlobalObject("Menu", MenuScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("Settings", SettingsScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("AudioDevice", AudioDeviceScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>());
scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get<AnimationCache>().data());
scriptEngine->registerGlobalObject("SoundCache", &SoundCache::getInstance());
scriptEngine->registerGlobalObject("Account", AccountScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("Metavoxels", &_metavoxels);
@ -4267,7 +4292,8 @@ void Application::setPreviousScriptLocation(const QString& previousScriptLocatio
void Application::loadDialog() {
QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Open Script"),
QString fileNameString = QFileDialog::getOpenFileName(DependencyManager::get<GLCanvas>().data(),
tr("Open Script"),
getPreviousScriptLocation(),
tr("JavaScript Files (*.js)"));
if (!fileNameString.isEmpty()) {
@ -4303,7 +4329,7 @@ void Application::loadScriptURLDialog() {
void Application::toggleLogDialog() {
if (! _logDialog) {
_logDialog = new LogDialog(_glWidget, getLogger());
_logDialog = new LogDialog(DependencyManager::get<GLCanvas>().data(), getLogger());
}
if (_logDialog->isVisible()) {
@ -4363,7 +4389,7 @@ void Application::parseVersionXml() {
}
if (!shouldSkipVersion(latestVersion) && applicationVersion() != latestVersion) {
new UpdateDialog(_glWidget, releaseNotes, latestVersion, downloadUrl);
new UpdateDialog(DependencyManager::get<GLCanvas>().data(), releaseNotes, latestVersion, downloadUrl);
}
sender->deleteLater();
}
@ -4396,7 +4422,7 @@ void Application::takeSnapshot() {
}
if (!_snapshotShareDialog) {
_snapshotShareDialog = new SnapshotShareDialog(fileName, _glWidget);
_snapshotShareDialog = new SnapshotShareDialog(fileName, DependencyManager::get<GLCanvas>().data());
}
_snapshotShareDialog->show();
}

View file

@ -12,28 +12,22 @@
#ifndef hifi_Application_h
#define hifi_Application_h
#include <map>
#include <time.h>
#include <gpu/GPUConfig.h>
#include <QApplication>
#include <QMainWindow>
#include <QAction>
#include <QHash>
#include <QImage>
#include <QList>
#include <QPointer>
#include <QSet>
#include <QSettings>
#include <QStringList>
#include <QHash>
#include <QTouchEvent>
#include <QUndoStack>
#include <QSystemTrayIcon>
#include <AbstractScriptingServicesInterface.h>
#include <AbstractViewStateInterface.h>
#include <EntityCollisionSystem.h>
#include <EntityEditPacketSender.h>
#include <EntityTreeRenderer.h>
#include <GeometryCache.h>
#include <NetworkPacket.h>
#include <NodeList.h>
@ -42,10 +36,8 @@
#include <ScriptEngine.h>
#include <TextureCache.h>
#include <ViewFrustum.h>
#include <ViewStateInterface.h>
#include <VoxelEditPacketSender.h>
#include "MainWindow.h"
#include "Audio.h"
#include "Camera.h"
#include "DatagramProcessor.h"
@ -61,7 +53,6 @@
#include "avatar/MyAvatar.h"
#include "devices/PrioVR.h"
#include "devices/SixenseManager.h"
#include "entities/EntityTreeRenderer.h"
#include "scripting/ControllerScriptingInterface.h"
#include "ui/BandwidthDialog.h"
#include "ui/BandwidthMeter.h"
@ -89,17 +80,19 @@
#include "UndoStackScriptingInterface.h"
class QAction;
class QActionGroup;
class QGLWidget;
class QKeyEvent;
class QMouseEvent;
class QSettings;
class QSystemTrayIcon;
class QTouchEvent;
class QWheelEvent;
class FaceTracker;
class MainWindow;
class Node;
class ProgramObject;
class ScriptEngine;
static const float NODE_ADDED_RED = 0.0f;
static const float NODE_ADDED_GREEN = 1.0f;
@ -127,7 +120,7 @@ static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS
static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html";
static const QString INFO_EDIT_ENTITIES_PATH = "html/edit-entities-commands.html";
class Application : public QApplication, public ViewStateInterface {
class Application : public QApplication, public AbstractViewStateInterface, AbstractScriptingServicesInterface {
Q_OBJECT
friend class OctreePacketProcessor;
@ -182,46 +175,50 @@ public:
void removeVoxel(glm::vec3 position, float scale);
glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel);
bool isThrottleRendering() const { return DependencyManager::get<GLCanvas>()->isThrottleRendering(); }
GLCanvas* getGLWidget() { return _glWidget; }
bool isThrottleRendering() const { return _glWidget->isThrottleRendering(); }
MyAvatar* getAvatar() { return _myAvatar; }
const MyAvatar* getAvatar() const { return _myAvatar; }
Audio* getAudio() { return &_audio; }
Camera* getCamera() { return &_myCamera; }
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
ViewFrustum* getDisplayViewFrustum() { return &_displayViewFrustum; }
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
VoxelImporter* getVoxelImporter() { return &_voxelImporter; }
VoxelSystem* getVoxels() { return &_voxels; }
VoxelTree* getVoxelTree() { return _voxels.getTree(); }
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
EntityTreeRenderer* getEntities() { return &_entities; }
bool getImportSucceded() { return _importSucceded; }
VoxelSystem* getSharedVoxelSystem() { return &_sharedVoxelSystem; }
Environment* getEnvironment() { return &_environment; }
PrioVR* getPrioVR() { return &_prioVR; }
QUndoStack* getUndoStack() { return &_undoStack; }
MainWindow* getWindow() { return _window; }
VoxelImporter* getVoxelImporter() { return &_voxelImporter; }
VoxelTree* getClipboard() { return &_clipboard; }
EntityTree* getEntityClipboard() { return &_entityClipboard; }
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
Environment* getEnvironment() { return &_environment; }
VoxelTree* getVoxelTree() { return _voxels.getTree(); }
bool getImportSucceded() { return _importSucceded; }
bool isMousePressed() const { return _mousePressed; }
bool isMouseHidden() const { return _glWidget->cursor().shape() == Qt::BlankCursor; }
bool isMouseHidden() const { return DependencyManager::get<GLCanvas>()->cursor().shape() == Qt::BlankCursor; }
void setCursorVisible(bool visible);
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
bool mouseOnScreen() const;
int getMouseX() const;
int getMouseY() const;
int getTrueMouseX() const { return _glWidget->mapFromGlobal(QCursor::pos()).x(); }
int getTrueMouseY() const { return _glWidget->mapFromGlobal(QCursor::pos()).y(); }
int getTrueMouseX() const { return DependencyManager::get<GLCanvas>()->mapFromGlobal(QCursor::pos()).x(); }
int getTrueMouseY() const { return DependencyManager::get<GLCanvas>()->mapFromGlobal(QCursor::pos()).y(); }
int getMouseDragStartedX() const;
int getMouseDragStartedY() const;
int getTrueMouseDragStartedX() const { return _mouseDragStartedX; }
int getTrueMouseDragStartedY() const { return _mouseDragStartedY; }
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
FaceTracker* getActiveFaceTracker();
PrioVR* getPrioVR() { return &_prioVR; }
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
QUndoStack* getUndoStack() { return &_undoStack; }
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
Overlays& getOverlays() { return _overlays; }
@ -241,14 +238,15 @@ public:
void saveSettings();
MainWindow* getWindow() { return _window; }
NodeToOctreeSceneStats* getOcteeSceneStats() { return &_octreeServerSceneStats; }
void lockOctreeSceneStats() { _octreeSceneStatsLock.lockForRead(); }
void unlockOctreeSceneStats() { _octreeSceneStatsLock.unlock(); }
ToolWindow* getToolWindow() { return _toolWindow ; }
ControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
virtual AbstractControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine);
AvatarManager& getAvatarManager() { return _avatarManager; }
void resetProfile(const QString& username);
@ -285,12 +283,17 @@ public:
virtual bool getShadowsEnabled();
virtual bool getCascadeShadowsEnabled();
virtual QThread* getMainThread() { return thread(); }
virtual float getSizeScale() const;
virtual int getBoundaryLevelAdjust() const;
virtual PickRay computePickRay(float x, float y);
virtual const glm::vec3& getAvatarPosition() const { return getAvatar()->getPosition(); }
NodeBounds& getNodeBoundsDisplay() { return _nodeBoundsDisplay; }
FileLogger* getLogger() { return _logger; }
glm::vec2 getViewportDimensions() const { return glm::vec2(_glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); }
glm::vec2 getViewportDimensions() const { return glm::vec2(DependencyManager::get<GLCanvas>()->getDeviceWidth(),
DependencyManager::get<GLCanvas>()->getDeviceHeight()); }
NodeToJurisdictionMap& getVoxelServerJurisdictions() { return _voxelServerJurisdictions; }
NodeToJurisdictionMap& getEntityServerJurisdictions() { return _entityServerJurisdictions; }
void pasteVoxelsToOctalCode(const unsigned char* octalCodeDestination);
@ -309,9 +312,6 @@ public:
bool isVSyncEditable() const;
bool isAboutToQuit() const { return _aboutToQuit; }
void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine);
// the isHMDmode is true whenever we use the interface from an HMD and not a standard flat display
// rendering of several elements depend on that
// TODO: carry that information on the Camera as a setting
@ -468,7 +468,6 @@ private:
int sendNackPackets();
MainWindow* _window;
GLCanvas* _glWidget; // our GLCanvas has a couple extra features
ToolWindow* _toolWindow;

View file

@ -95,10 +95,8 @@ void Camera::setFarClip(float f) {
}
PickRay Camera::computePickRay(float x, float y) {
float screenWidth = Application::getInstance()->getGLWidget()->width();
float screenHeight = Application::getInstance()->getGLWidget()->height();
return computeViewPickRay(x / screenWidth, y / screenHeight);
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
return computeViewPickRay(x / glCanvas->width(), y / glCanvas->height());
}
PickRay Camera::computeViewPickRay(float xRatio, float yRatio) {

View file

@ -9,13 +9,13 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QMainWindow>
#include <QMimeData>
#include <QUrl>
#include <QWindow>
#include "Application.h"
#include "GLCanvas.h"
#include "MainWindow.h"
#include "devices/OculusManager.h"
const int MSECS_PER_FRAME_WHEN_THROTTLED = 66;

View file

@ -15,11 +15,14 @@
#include <QGLWidget>
#include <QTimer>
#include <DependencyManager.h>
/// customized canvas that simply forwards requests/events to the singleton application
class GLCanvas : public QGLWidget {
Q_OBJECT
SINGLETON_DEPENDENCY(GLCanvas)
public:
GLCanvas();
bool isThrottleRendering() const;
int getDeviceWidth() const;
@ -56,6 +59,12 @@ private slots:
void activeChanged(Qt::ApplicationState state);
void throttleRender();
bool eventFilter(QObject*, QEvent* event);
private:
GLCanvas();
~GLCanvas() {
qDebug() << "Deleting GLCanvas";
}
};
#endif // hifi_GLCanvas_h

View file

@ -32,6 +32,7 @@
#include <AccountManager.h>
#include <AddressManager.h>
#include <DependencyManager.h>
#include <MainWindow.h>
#include <GlowEffect.h>
#include <PathUtils.h>
#include <UUID.h>
@ -427,7 +428,7 @@ Menu::Menu() :
appInstance,
SLOT(setRenderVoxels(bool)));
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::EnableGlowEffect, 0, true,
DependencyManager::get<GlowEffect>(), SLOT(toggleGlowEffect(bool)));
DependencyManager::get<GlowEffect>().data(), SLOT(toggleGlowEffect(bool)));
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Wireframe, Qt::ALT | Qt::Key_W, false);
addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
@ -438,12 +439,12 @@ Menu::Menu() :
MenuOption::Faceshift,
0,
true,
DependencyManager::get<Faceshift>(),
DependencyManager::get<Faceshift>().data(),
SLOT(setTCPEnabled(bool)));
#endif
#ifdef HAVE_VISAGE
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::Visage, 0, false,
DependencyManager::get<Visage>(), SLOT(updateEnabled()));
DependencyManager::get<Visage>().data(), SLOT(updateEnabled()));
#endif
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSkeletonCollisionShapes);
@ -1057,11 +1058,11 @@ void Menu::bumpSettings() {
void sendFakeEnterEvent() {
QPoint lastCursorPosition = QCursor::pos();
QGLWidget* glWidget = Application::getInstance()->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
QPoint windowPosition = glWidget->mapFromGlobal(lastCursorPosition);
QPoint windowPosition = glCanvas->mapFromGlobal(lastCursorPosition);
QEnterEvent enterEvent = QEnterEvent(windowPosition, windowPosition, lastCursorPosition);
QCoreApplication::sendEvent(glWidget, &enterEvent);
QCoreApplication::sendEvent(glCanvas.data(), &enterEvent);
}
const float DIALOG_RATIO_OF_WINDOW = 0.30f;
@ -1309,7 +1310,7 @@ void Menu::toggleLoginMenuItem() {
void Menu::bandwidthDetails() {
if (! _bandwidthDialog) {
_bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(),
_bandwidthDialog = new BandwidthDialog(DependencyManager::get<GLCanvas>().data(),
Application::getInstance()->getBandwidthMeter());
connect(_bandwidthDialog, SIGNAL(closed()), SLOT(bandwidthDetailsClosed()));
@ -1424,7 +1425,7 @@ void Menu::bandwidthDetailsClosed() {
void Menu::octreeStatsDetails() {
if (!_octreeStatsDialog) {
_octreeStatsDialog = new OctreeStatsDialog(Application::getInstance()->getGLWidget(),
_octreeStatsDialog = new OctreeStatsDialog(DependencyManager::get<GLCanvas>().data(),
Application::getInstance()->getOcteeSceneStats());
connect(_octreeStatsDialog, SIGNAL(closed()), SLOT(octreeStatsDetailsClosed()));
_octreeStatsDialog->show();
@ -1608,7 +1609,7 @@ bool Menu::shouldRenderMesh(float largestDimension, float distanceToCamera) {
void Menu::lodTools() {
if (!_lodToolsDialog) {
_lodToolsDialog = new LodToolsDialog(Application::getInstance()->getGLWidget());
_lodToolsDialog = new LodToolsDialog(DependencyManager::get<GLCanvas>().data());
connect(_lodToolsDialog, SIGNAL(closed()), SLOT(lodToolsClosed()));
_lodToolsDialog->show();
if (_hmdToolsDialog) {
@ -1628,7 +1629,7 @@ void Menu::lodToolsClosed() {
void Menu::hmdTools(bool showTools) {
if (showTools) {
if (!_hmdToolsDialog) {
_hmdToolsDialog = new HMDToolsDialog(Application::getInstance()->getGLWidget());
_hmdToolsDialog = new HMDToolsDialog(DependencyManager::get<GLCanvas>().data());
connect(_hmdToolsDialog, SIGNAL(closed()), SLOT(hmdToolsClosed()));
}
_hmdToolsDialog->show();

View file

@ -496,7 +496,7 @@ void MetavoxelSystem::render() {
}
void MetavoxelSystem::refreshVoxelData() {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([](const SharedNodePointer& node){
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
@ -504,7 +504,7 @@ void MetavoxelSystem::refreshVoxelData() {
QMetaObject::invokeMethod(client, "refreshVoxelData");
}
}
}
});
}
class RayVoxelIntersectionVisitor : public RayIntersectionVisitor {
@ -819,7 +819,7 @@ MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
}
void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([&visitor, &render](const SharedNodePointer& node){
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelSystemClient* client = static_cast<MetavoxelSystemClient*>(node->getLinkedData());
@ -833,7 +833,7 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
}
}
}
}
});
}
void MetavoxelSystem::loadSplatProgram(const char* type, ProgramObject& program, SplatLocations& locations) {
@ -1178,7 +1178,7 @@ void VoxelBuffer::render(bool cursor) {
if (!_materials.isEmpty()) {
_networkTextures.resize(_materials.size());
TextureCache* textureCache = DependencyManager::get<TextureCache>();
TextureCache::SharedPointer textureCache = DependencyManager::get<TextureCache>();
for (int i = 0; i < _materials.size(); i++) {
const SharedObjectPointer material = _materials.at(i);
if (material) {
@ -2233,7 +2233,7 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g
const QVector<SharedObjectPointer>& materials = node->getMaterial()->getMaterials();
_networkTextures.resize(materials.size());
TextureCache* textureCache = DependencyManager::get<TextureCache>();
TextureCache::SharedPointer textureCache = DependencyManager::get<TextureCache>();
for (int i = 0; i < materials.size(); i++) {
const SharedObjectPointer& material = materials.at(i);
if (material) {

View file

@ -472,7 +472,7 @@ void ModelUploader::processCheck() {
QString("Your model is now available in the browser."),
QMessageBox::Ok);
DependencyManager::get<GeometryCache>()->refresh(_url);
TextureCache* textureCache = DependencyManager::get<TextureCache>();
TextureCache::SharedPointer textureCache = DependencyManager::get<TextureCache>();
foreach (const QByteArray& filename, _textureFilenames) {
textureCache->refresh(_textureBase + filename);
}

View file

@ -19,12 +19,12 @@
#include <glm/gtx/quaternion.hpp>
#include <glm/detail/func_common.hpp>
#include <SharedUtil.h>
#include <QThread>
#include <SharedUtil.h>
#include <TextRenderer.h>
#include "InterfaceConfig.h"
#include "ui/TextRenderer.h"
#include "VoxelConstants.h"
#include "world.h"
#include "Application.h"
@ -71,7 +71,7 @@ void renderWorldBox() {
glPushMatrix();
glTranslatef(MARKER_DISTANCE, 0, 0);
glColor3fv(red);
GeometryCache* geometryCache = DependencyManager::get<GeometryCache>();
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderSphere(MARKER_RADIUS, 10, 10);
glPopMatrix();
glPushMatrix();

View file

@ -30,6 +30,7 @@
#include <PathUtils.h>
#include <PerfStat.h>
#include <SharedUtil.h>
#include <TextRenderer.h>
#include <TextureCache.h>
#include "Application.h"
@ -42,7 +43,6 @@
#include "Recorder.h"
#include "world.h"
#include "devices/OculusManager.h"
#include "ui/TextRenderer.h"
using namespace std;

View file

@ -72,20 +72,19 @@ void Head::reset() {
}
void Head::simulate(float deltaTime, bool isMine, bool billboard) {
if (isMine) {
MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
// Only use face trackers when not playing back a recording.
if (!myAvatar->isPlaying()) {
FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker();
DdeFaceTracker* dde = DependencyManager::get<DdeFaceTracker>();
Faceshift* faceshift = DependencyManager::get<Faceshift>();
DdeFaceTracker::SharedPointer dde = DependencyManager::get<DdeFaceTracker>();
Faceshift::SharedPointer faceshift = DependencyManager::get<Faceshift>();
if ((_isFaceshiftConnected = (faceshift == faceTracker))) {
_blendshapeCoefficients = faceTracker->getBlendshapeCoefficients();
} else if (dde->isActive()) {
faceTracker = dde;
faceTracker = dde.data();
_blendshapeCoefficients = faceTracker->getBlendshapeCoefficients();
}
}

View file

@ -30,6 +30,7 @@
#include <PerfStat.h>
#include <ShapeCollider.h>
#include <SharedUtil.h>
#include <TextRenderer.h>
#include "Application.h"
#include "Audio.h"
@ -41,7 +42,6 @@
#include "Recorder.h"
#include "devices/Faceshift.h"
#include "devices/OculusManager.h"
#include "ui/TextRenderer.h"
using namespace std;
@ -422,7 +422,7 @@ void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bo
}
void MyAvatar::renderHeadMouse(int screenWidth, int screenHeight) const {
Faceshift* faceshift = DependencyManager::get<Faceshift>();
Faceshift::SharedPointer faceshift = DependencyManager::get<Faceshift>();
float pixelsPerDegree = screenHeight / Menu::getInstance()->getFieldOfView();

View file

@ -554,7 +554,7 @@ void SkeletonModel::renderRagdoll() {
float radius1 = 0.008f;
float radius2 = 0.01f;
glm::vec3 simulationTranslation = _ragdoll->getTranslationInSimulationFrame();
GeometryCache* geometryCache = DependencyManager::get<GeometryCache>();
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
for (int i = 0; i < numPoints; ++i) {
glPushMatrix();
// NOTE: ragdollPoints are in simulation-frame but we want them to be model-relative
@ -914,7 +914,7 @@ void SkeletonModel::renderBoundingCollisionShapes(float alpha) {
endPoint = endPoint - _translation;
glTranslatef(endPoint.x, endPoint.y, endPoint.z);
glColor4f(0.6f, 0.6f, 0.8f, alpha);
GeometryCache* geometryCache = DependencyManager::get<GeometryCache>();
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->renderSphere(_boundingShape.getRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS);
// draw a yellow sphere at the capsule startpoint
@ -950,7 +950,7 @@ void SkeletonModel::renderJointCollisionShapes(float alpha) {
continue;
}
GeometryCache* geometryCache = DependencyManager::get<GeometryCache>();
GeometryCache::SharedPointer geometryCache = DependencyManager::get<GeometryCache>();
glPushMatrix();
// shapes are stored in simulation-frame but we want position to be model-relative

View file

@ -18,8 +18,9 @@
#include "FaceTracker.h"
class DdeFaceTracker : public FaceTracker, public DependencyManager::Dependency {
class DdeFaceTracker : public FaceTracker {
Q_OBJECT
SINGLETON_DEPENDENCY(DdeFaceTracker)
public:
//initialization
@ -58,7 +59,6 @@ private:
DdeFaceTracker();
DdeFaceTracker(const QHostAddress& host, quint16 port);
~DdeFaceTracker();
friend DependencyManager;
float getBlendshapeCoefficient(int index) const;
void decodePacket(const QByteArray& buffer);

View file

@ -24,8 +24,9 @@
#include "FaceTracker.h"
/// Handles interaction with the Faceshift software, which provides head position/orientation and facial features.
class Faceshift : public FaceTracker, public DependencyManager::Dependency {
class Faceshift : public FaceTracker {
Q_OBJECT
SINGLETON_DEPENDENCY(Faceshift)
public:
void init();
@ -89,7 +90,6 @@ private slots:
private:
Faceshift();
virtual ~Faceshift() {}
friend DependencyManager;
float getBlendshapeCoefficient(int index) const;

View file

@ -562,8 +562,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
}
// restore our normal viewport
glViewport(0, 0, Application::getInstance()->getGLWidget()->getDeviceWidth(),
Application::getInstance()->getGLWidget()->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
glViewport(0, 0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@ -581,8 +581,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p
void OculusManager::renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]) {
glLoadIdentity();
gluOrtho2D(0, Application::getInstance()->getGLWidget()->getDeviceWidth(), 0,
Application::getInstance()->getGLWidget()->getDeviceHeight());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
gluOrtho2D(0, glCanvas->getDeviceWidth(), 0, glCanvas->getDeviceHeight());
glDisable(GL_DEPTH_TEST);

View file

@ -14,11 +14,11 @@
#include <FBXReader.h>
#include <PerfStat.h>
#include <TextRenderer.h>
#include "Application.h"
#include "PrioVR.h"
#include "scripting/JoystickScriptingInterface.h"
#include "ui/TextRenderer.h"
#ifdef HAVE_PRIOVR
const unsigned int SERIAL_LIST[] = { 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x0000000A,
@ -215,8 +215,9 @@ void PrioVR::renderCalibrationCountdown() {
static TextRenderer* textRenderer = TextRenderer::getInstance(MONO_FONT_FAMILY, 18, QFont::Bold,
false, TextRenderer::OUTLINE_EFFECT, 2);
QByteArray text = "Assume T-Pose in " + QByteArray::number(secondsRemaining) + "...";
textRenderer->draw((Application::getInstance()->getGLWidget()->width() -
textRenderer->computeWidth(text.constData())) / 2, Application::getInstance()->getGLWidget()->height() / 2,
text);
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
textRenderer->draw((glCanvas->width() - textRenderer->computeWidth(text.constData())) / 2,
glCanvas->height() / 2,
text);
#endif
}

View file

@ -461,7 +461,7 @@ void SixenseManager::updateCalibration(const sixenseControllerData* controllers)
void SixenseManager::emulateMouse(PalmData* palm, int index) {
Application* application = Application::getInstance();
MyAvatar* avatar = application->getAvatar();
GLCanvas* widget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
QPoint pos;
Qt::MouseButton bumperButton;
@ -489,10 +489,10 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) {
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
// Get the pixel range over which the xAngle and yAngle are scaled
float cursorRange = widget->width() * getCursorPixelRangeMult();
float cursorRange = glCanvas->width() * getCursorPixelRangeMult();
pos.setX(widget->width() / 2.0f + cursorRange * xAngle);
pos.setY(widget->height() / 2.0f + cursorRange * yAngle);
pos.setX(glCanvas->width() / 2.0f + cursorRange * xAngle);
pos.setY(glCanvas->height() / 2.0f + cursorRange * yAngle);
}

View file

@ -35,10 +35,10 @@ bool TV3DManager::isConnected() {
}
void TV3DManager::connect() {
Application* app = Application::getInstance();
int width = app->getGLWidget()->getDeviceWidth();
int height = app->getGLWidget()->getDeviceHeight();
Camera& camera = *app->getCamera();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
int width = glCanvas->getDeviceWidth();
int height = glCanvas->getDeviceHeight();
Camera& camera = *Application::getInstance()->getCamera();
configureCamera(camera, width, height);
}
@ -93,7 +93,8 @@ void TV3DManager::display(Camera& whichCamera) {
// left eye portal
int portalX = 0;
int portalY = 0;
QSize deviceSize = Application::getInstance()->getGLWidget()->getDeviceSize() *
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
QSize deviceSize = glCanvas->getDeviceSize() *
Application::getInstance()->getRenderResolutionScale();
int portalW = deviceSize.width() / 2;
int portalH = deviceSize.height();

View file

@ -122,7 +122,7 @@ static const QMultiHash<QByteArray, QPair<int, float> >& getActionUnitNameMap()
const float TRANSLATION_SCALE = 20.0f;
void Visage::init() {
connect(DependencyManager::get<Faceshift>(), SIGNAL(connectionStateChanged()), SLOT(updateEnabled()));
connect(DependencyManager::get<Faceshift>().data(), SIGNAL(connectionStateChanged()), SLOT(updateEnabled()));
updateEnabled();
}

View file

@ -26,8 +26,9 @@ namespace VisageSDK {
}
/// Handles input from the Visage webcam feature tracking software.
class Visage : public FaceTracker, public DependencyManager::Dependency {
class Visage : public FaceTracker {
Q_OBJECT
SINGLETON_DEPENDENCY(Visage)
public:
void init();
@ -44,7 +45,6 @@ public slots:
private:
Visage();
virtual ~Visage();
friend DependencyManager;
#ifdef HAVE_VISAGE
VisageSDK::VisageTracker2* _tracker;

View file

@ -267,9 +267,9 @@ void ControllerScriptingInterface::releaseJoystick(int joystickIndex) {
}
}
glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
GLCanvas* widget = Application::getInstance()->getGLWidget();
return glm::vec2(widget->width(), widget->height());
glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
return glm::vec2(glCanvas->width(), glCanvas->height());
}
AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {

View file

@ -17,6 +17,7 @@
#include <QScriptValue>
#include "Application.h"
#include "MainWindow.h"
#include "Menu.h"
#include "ui/ModelsBrowser.h"
@ -39,7 +40,7 @@ WebWindowClass* WindowScriptingInterface::doCreateWebWindow(const QString& title
}
QScriptValue WindowScriptingInterface::hasFocus() {
return Application::getInstance()->getGLWidget()->hasFocus();
return DependencyManager::get<GLCanvas>()->hasFocus();
}
void WindowScriptingInterface::setCursorVisible(bool visible) {

View file

@ -14,6 +14,7 @@
#include "AddressBarDialog.h"
#include "AddressManager.h"
#include "Application.h"
#include "MainWindow.h"
const QString ADDRESSBAR_GO_BUTTON_ICON = "images/address-bar-submit.svg";
const QString ADDRESSBAR_GO_BUTTON_ACTIVE_ICON = "images/address-bar-submit-active.svg";

View file

@ -22,6 +22,7 @@
#include "AnimationsDialog.h"
#include "Application.h"
#include "MainWindow.h"
AnimationsDialog::AnimationsDialog() :
QDialog(Application::getInstance()->getWindow()) {

View file

@ -147,11 +147,11 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
Application* application = Application::getInstance();
Overlays& overlays = application->getOverlays();
GLCanvas* glWidget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
MyAvatar* myAvatar = application->getAvatar();
_textureFov = glm::radians(Menu::getInstance()->getOculusUIAngularSize());
_textureAspectRatio = (float)application->getGLWidget()->getDeviceWidth() / (float)application->getGLWidget()->getDeviceHeight();
_textureAspectRatio = (float)glCanvas->getDeviceWidth() / (float)glCanvas->getDeviceHeight();
//Handle fading and deactivation/activation of UI
if (Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) {
@ -180,12 +180,12 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
glPushMatrix(); {
glLoadIdentity();
gluOrtho2D(0, glWidget->width(), glWidget->height(), 0);
gluOrtho2D(0, glCanvas->width(), glCanvas->height(), 0);
renderAudioMeter();
if (Menu::getInstance()->isOptionChecked(MenuOption::HeadMouse)) {
myAvatar->renderHeadMouse(glWidget->width(), glWidget->height());
myAvatar->renderHeadMouse(glCanvas->width(), glCanvas->height());
}
renderStatsAndLogs();
@ -215,7 +215,7 @@ void ApplicationOverlay::displayOverlayTexture() {
if (_alpha == 0.0f) {
return;
}
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
@ -224,16 +224,16 @@ void ApplicationOverlay::displayOverlayTexture() {
glMatrixMode(GL_PROJECTION);
glPushMatrix(); {
glLoadIdentity();
gluOrtho2D(0, glWidget->getDeviceWidth(), glWidget->getDeviceHeight(), 0);
gluOrtho2D(0, glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight(), 0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
glBegin(GL_QUADS); {
glColor4f(1.0f, 1.0f, 1.0f, _alpha);
glTexCoord2f(0, 0); glVertex2i(0, glWidget->getDeviceHeight());
glTexCoord2f(1, 0); glVertex2i(glWidget->getDeviceWidth(), glWidget->getDeviceHeight());
glTexCoord2f(1, 1); glVertex2i(glWidget->getDeviceWidth(), 0);
glTexCoord2f(0, 0); glVertex2i(0, glCanvas->getDeviceHeight());
glTexCoord2f(1, 0); glVertex2i(glCanvas->getDeviceWidth(), glCanvas->getDeviceHeight());
glTexCoord2f(1, 1); glVertex2i(glCanvas->getDeviceWidth(), 0);
glTexCoord2f(0, 1); glVertex2i(0, 0);
} glEnd();
} glPopMatrix();
@ -380,18 +380,19 @@ void ApplicationOverlay::displayOverlayTexture3DTV(Camera& whichCamera, float as
glEnd();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
if (_crosshairTexture == 0) {
_crosshairTexture = Application::getInstance()->getGLWidget()->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png"));
_crosshairTexture = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png"));
}
//draw the mouse pointer
glBindTexture(GL_TEXTURE_2D, _crosshairTexture);
const float reticleSize = 40.0f / application->getGLWidget()->width() * quadWidth;
const float reticleSize = 40.0f / glCanvas->width() * quadWidth;
x -= reticleSize / 2.0f;
y += reticleSize / 2.0f;
const float mouseX = (application->getMouseX() / (float)application->getGLWidget()->width()) * quadWidth;
const float mouseY = (1.0 - (application->getMouseY() / (float)application->getGLWidget()->height())) * quadHeight;
const float mouseX = (application->getMouseX() / (float)glCanvas->width()) * quadWidth;
const float mouseY = (1.0 - (application->getMouseY() / (float)glCanvas->height())) * quadHeight;
glBegin(GL_QUADS);
@ -433,7 +434,7 @@ void ApplicationOverlay::computeOculusPickRay(float x, float y, glm::vec3& origi
//Caculate the click location using one of the sixense controllers. Scale is not applied
QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
Application* application = Application::getInstance();
GLCanvas* glWidget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
MyAvatar* myAvatar = application->getAvatar();
glm::vec3 tip = myAvatar->getLaserPointerTipPosition(palm);
@ -464,8 +465,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
float u = asin(collisionPos.x) / (_textureFov)+0.5f;
float v = 1.0 - (asin(collisionPos.y) / (_textureFov)+0.5f);
rv.setX(u * glWidget->width());
rv.setY(v * glWidget->height());
rv.setX(u * glCanvas->width());
rv.setY(v * glCanvas->height());
}
} else {
//if they did not click on the overlay, just set the coords to INT_MAX
@ -482,8 +483,8 @@ QPoint ApplicationOverlay::getPalmClickLocation(const PalmData *palm) const {
ndcSpacePos = glm::vec3(clipSpacePos) / clipSpacePos.w;
}
rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * glWidget->width());
rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * glWidget->height());
rv.setX(((ndcSpacePos.x + 1.0) / 2.0) * glCanvas->width());
rv.setY((1.0 - ((ndcSpacePos.y + 1.0) / 2.0)) * glCanvas->height());
}
return rv;
}
@ -512,10 +513,11 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position,
//Renders optional pointers
void ApplicationOverlay::renderPointers() {
Application* application = Application::getInstance();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
//lazily load crosshair texture
if (_crosshairTexture == 0) {
_crosshairTexture = Application::getInstance()->getGLWidget()->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png"));
_crosshairTexture = glCanvas->bindTexture(QImage(PathUtils::resourcesPath() + "images/sixense-reticle.png"));
}
glEnable(GL_TEXTURE_2D);
@ -538,7 +540,7 @@ void ApplicationOverlay::renderPointers() {
glm::vec2 screenPos = sphericalToScreen(glm::vec2(yaw, -pitch));
position = QPoint(screenPos.x, screenPos.y);
application->getGLWidget()->cursor().setPos(application->getGLWidget()->mapToGlobal(position));
glCanvas->cursor().setPos(glCanvas->mapToGlobal(position));
}
_reticlePosition[MOUSE] = position;
@ -559,7 +561,7 @@ void ApplicationOverlay::renderPointers() {
void ApplicationOverlay::renderControllerPointers() {
Application* application = Application::getInstance();
GLCanvas* glWidget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
MyAvatar* myAvatar = application->getAvatar();
//Static variables used for storing controller state
@ -637,14 +639,14 @@ void ApplicationOverlay::renderControllerPointers() {
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
// Get the pixel range over which the xAngle and yAngle are scaled
float cursorRange = glWidget->width() * SixenseManager::getInstance().getCursorPixelRangeMult();
float cursorRange = glCanvas->width() * SixenseManager::getInstance().getCursorPixelRangeMult();
mouseX = (glWidget->width() / 2.0f + cursorRange * xAngle);
mouseY = (glWidget->height() / 2.0f + cursorRange * yAngle);
mouseX = (glCanvas->width() / 2.0f + cursorRange * xAngle);
mouseY = (glCanvas->height() / 2.0f + cursorRange * yAngle);
}
//If the cursor is out of the screen then don't render it
if (mouseX < 0 || mouseX >= glWidget->width() || mouseY < 0 || mouseY >= glWidget->height()) {
if (mouseX < 0 || mouseX >= glCanvas->width() || mouseY < 0 || mouseY >= glCanvas->height()) {
_reticleActive[index] = false;
continue;
}
@ -704,11 +706,10 @@ void ApplicationOverlay::renderPointersOculus(const glm::vec3& eyePos) {
//Renders a small magnification of the currently bound texture at the coordinates
void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder) const {
Application* application = Application::getInstance();
GLCanvas* glWidget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
const int widgetWidth = glWidget->width();
const int widgetHeight = glWidget->height();
const int widgetWidth = glCanvas->width();
const int widgetHeight = glCanvas->height();
const float halfWidth = (MAGNIFY_WIDTH / _textureAspectRatio) * sizeMult / 2.0f;
const float halfHeight = MAGNIFY_HEIGHT * sizeMult / 2.0f;
@ -762,8 +763,8 @@ void ApplicationOverlay::renderMagnifier(glm::vec2 magPos, float sizeMult, bool
void ApplicationOverlay::renderAudioMeter() {
Application* application = Application::getInstance();
GLCanvas* glWidget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
Audio* audio = application->getAudio();
// Display a single screen-size quad to create an alpha blended 'collision' flash
@ -771,7 +772,7 @@ void ApplicationOverlay::renderAudioMeter() {
float collisionSoundMagnitude = audio->getCollisionSoundMagnitude();
const float VISIBLE_COLLISION_SOUND_MAGNITUDE = 0.5f;
if (collisionSoundMagnitude > VISIBLE_COLLISION_SOUND_MAGNITUDE) {
renderCollisionOverlay(glWidget->width(), glWidget->height(),
renderCollisionOverlay(glCanvas->width(), glCanvas->height(),
audio->getCollisionSoundMagnitude());
}
}
@ -825,14 +826,14 @@ void ApplicationOverlay::renderAudioMeter() {
if ((audio->getTimeSinceLastClip() > 0.0f) && (audio->getTimeSinceLastClip() < CLIPPING_INDICATOR_TIME)) {
const float MAX_MAGNITUDE = 0.7f;
float magnitude = MAX_MAGNITUDE * (1 - audio->getTimeSinceLastClip() / CLIPPING_INDICATOR_TIME);
renderCollisionOverlay(glWidget->width(), glWidget->height(), magnitude, 1.0f);
renderCollisionOverlay(glCanvas->width(), glCanvas->height(), magnitude, 1.0f);
}
audio->renderToolBox(MIRROR_VIEW_LEFT_PADDING + AUDIO_METER_GAP, audioMeterY, boxed);
audio->renderScope(glWidget->width(), glWidget->height());
audio->renderScope(glCanvas->width(), glCanvas->height());
audio->renderStats(WHITE_TEXT, glWidget->width(), glWidget->height());
audio->renderStats(WHITE_TEXT, glCanvas->width(), glCanvas->height());
glBegin(GL_QUADS);
if (isClipping) {
@ -893,8 +894,8 @@ void ApplicationOverlay::renderAudioMeter() {
void ApplicationOverlay::renderStatsAndLogs() {
Application* application = Application::getInstance();
GLCanvas* glWidget = application->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor();
BandwidthMeter* bandwidthMeter = application->getBandwidthMeter();
NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay();
@ -912,8 +913,8 @@ void ApplicationOverlay::renderStatsAndLogs() {
application->getPacketsPerSecond(), application->getBytesPerSecond(), voxelPacketsToProcess);
// Bandwidth meter
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) {
Stats::drawBackground(0x33333399, glWidget->width() - 296, glWidget->height() - 68, 296, 68);
bandwidthMeter->render(glWidget->width(), glWidget->height());
Stats::drawBackground(0x33333399, glCanvas->width() - 296, glCanvas->height() - 68, 296, 68);
bandwidthMeter->render(glCanvas->width(), glCanvas->height());
}
}
@ -926,7 +927,7 @@ void ApplicationOverlay::renderStatsAndLogs() {
(Menu::getInstance()->isOptionChecked(MenuOption::Stats) &&
Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth))
? 80 : 20;
drawText(glWidget->width() - 100, glWidget->height() - timerBottom,
drawText(glCanvas->width() - 100, glCanvas->height() - timerBottom,
0.30f, 0.0f, 0, frameTimer, WHITE_TEXT);
}
nodeBoundsDisplay.drawOverlay();
@ -936,9 +937,9 @@ void ApplicationOverlay::renderDomainConnectionStatusBorder() {
NodeList* nodeList = NodeList::getInstance();
if (nodeList && !nodeList->getDomainHandler().isConnected()) {
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
int right = glWidget->width();
int bottom = glWidget->height();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
int right = glCanvas->width();
int bottom = glCanvas->height();
glColor3f(CONNECTION_STATUS_BORDER_COLOR[0],
CONNECTION_STATUS_BORDER_COLOR[1],
@ -1073,7 +1074,7 @@ void ApplicationOverlay::TexturedHemisphere::cleanupVBO() {
}
void ApplicationOverlay::TexturedHemisphere::buildFramebufferObject() {
QSize size = Application::getInstance()->getGLWidget()->getDeviceSize();
QSize size = DependencyManager::get<GLCanvas>()->getDeviceSize();
if (_framebufferObject != NULL && size == _framebufferObject->size()) {
// Already build
return;
@ -1124,7 +1125,7 @@ void ApplicationOverlay::TexturedHemisphere::render() {
glm::vec2 ApplicationOverlay::screenToSpherical(glm::vec2 screenPos) const {
QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize();
QSize screenSize = DependencyManager::get<GLCanvas>()->getDeviceSize();
float yaw = -(screenPos.x / screenSize.width() - 0.5f) * MOUSE_YAW_RANGE;
float pitch = (screenPos.y / screenSize.height() - 0.5f) * MOUSE_PITCH_RANGE;
@ -1132,7 +1133,7 @@ glm::vec2 ApplicationOverlay::screenToSpherical(glm::vec2 screenPos) const {
}
glm::vec2 ApplicationOverlay::sphericalToScreen(glm::vec2 sphericalPos) const {
QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize();
QSize screenSize = DependencyManager::get<GLCanvas>()->getDeviceSize();
float x = (-sphericalPos.x / MOUSE_YAW_RANGE + 0.5f) * screenSize.width();
float y = (sphericalPos.y / MOUSE_PITCH_RANGE + 0.5f) * screenSize.height();
@ -1140,7 +1141,7 @@ glm::vec2 ApplicationOverlay::sphericalToScreen(glm::vec2 sphericalPos) const {
}
glm::vec2 ApplicationOverlay::sphericalToOverlay(glm::vec2 sphericalPos) const {
QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize();
QSize screenSize = DependencyManager::get<GLCanvas>()->getDeviceSize();
float x = (-sphericalPos.x / (_textureFov * _textureAspectRatio) + 0.5f) * screenSize.width();
float y = (sphericalPos.y / _textureFov + 0.5f) * screenSize.height();
@ -1148,7 +1149,7 @@ glm::vec2 ApplicationOverlay::sphericalToOverlay(glm::vec2 sphericalPos) const {
}
glm::vec2 ApplicationOverlay::overlayToSpherical(glm::vec2 overlayPos) const {
QSize screenSize = Application::getInstance()->getGLWidget()->getDeviceSize();
QSize screenSize = DependencyManager::get<GLCanvas>()->getDeviceSize();
float yaw = -(overlayPos.x / screenSize.width() - 0.5f) * _textureFov * _textureAspectRatio;
float pitch = (overlayPos.y / screenSize.height() - 0.5f) * _textureFov;

View file

@ -20,6 +20,7 @@
#include "Application.h"
#include "AttachmentsDialog.h"
#include "MainWindow.h"
AttachmentsDialog::AttachmentsDialog() :
QDialog(Application::getInstance()->getWindow()) {

View file

@ -16,7 +16,7 @@
#include <glm/glm.hpp>
#include "ui/TextRenderer.h"
#include <TextRenderer.h>
class BandwidthMeter {

View file

@ -16,6 +16,8 @@
#include <QScrollBar>
#include <QSizePolicy>
#include <QTimer>
#include "qtimespan.h"
#include <AddressManager.h>
#include <AccountManager.h>
@ -24,7 +26,7 @@
#include "Application.h"
#include "ChatMessageArea.h"
#include "FlowLayout.h"
#include "qtimespan.h"
#include "MainWindow.h"
#include "UIUtil.h"
#include "XmppClient.h"

View file

@ -21,6 +21,7 @@
#include <VoxelConstants.h>
#include "MainWindow.h"
#include "Menu.h"
#include "devices/OculusManager.h"
#include "ui/HMDToolsDialog.h"

View file

@ -38,6 +38,7 @@
#include <PathUtils.h>
#include "Application.h"
#include "MainWindow.h"
#include "MetavoxelEditor.h"
using namespace std;
@ -138,7 +139,7 @@ MetavoxelEditor::MetavoxelEditor() :
connect(Application::getInstance()->getMetavoxels(), &MetavoxelSystem::rendering,
this, &MetavoxelEditor::renderPreview);
Application::getInstance()->getGLWidget()->installEventFilter(this);
DependencyManager::get<GLCanvas>()->installEventFilter(this);
show();

View file

@ -21,7 +21,7 @@
const int BYTES_PER_KILOBYTE = 1024;
MetavoxelNetworkSimulator::MetavoxelNetworkSimulator() :
QWidget(Application::getInstance()->getGLWidget(), Qt::Dialog) {
QWidget(DependencyManager::get<GLCanvas>().data(), Qt::Dialog) {
setWindowTitle("Metavoxel Network Simulator");
setAttribute(Qt::WA_DeleteOnClose);

View file

@ -49,59 +49,59 @@ void NodeBounds::draw() {
float selectedScale = 0;
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node){
NodeType_t nodeType = node->getType();
if (nodeType == NodeType::VoxelServer && _showVoxelNodes) {
serverJurisdictions = &voxelServerJurisdictions;
} else if (nodeType == NodeType::EntityServer && _showEntityNodes) {
serverJurisdictions = &entityServerJurisdictions;
} else {
continue;
return;
}
QUuid nodeUUID = node->getUUID();
serverJurisdictions->lockForRead();
if (serverJurisdictions->find(nodeUUID) != serverJurisdictions->end()) {
const JurisdictionMap& map = (*serverJurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
serverJurisdictions->unlock();
glm::vec3 location(rootDetails.x, rootDetails.y, rootDetails.z);
location *= (float)TREE_SCALE;
AACube serverBounds(location, rootDetails.s * TREE_SCALE);
glm::vec3 center = serverBounds.getVertex(BOTTOM_RIGHT_NEAR)
+ ((serverBounds.getVertex(TOP_LEFT_FAR) - serverBounds.getVertex(BOTTOM_RIGHT_NEAR)) / 2.0f);
+ ((serverBounds.getVertex(TOP_LEFT_FAR) - serverBounds.getVertex(BOTTOM_RIGHT_NEAR)) / 2.0f);
const float VOXEL_NODE_SCALE = 1.00f;
const float ENTITY_NODE_SCALE = 0.99f;
float scaleFactor = rootDetails.s * TREE_SCALE;
// Scale by 0.92 - 1.00 depending on the scale of the node. This allows smaller nodes to scale in
// a bit and not overlap larger nodes.
scaleFactor *= 0.92 + (rootDetails.s * 0.08);
// Scale different node types slightly differently because it's common for them to overlap.
if (nodeType == NodeType::VoxelServer) {
scaleFactor *= VOXEL_NODE_SCALE;
} else if (nodeType == NodeType::EntityServer) {
scaleFactor *= ENTITY_NODE_SCALE;
}
float red, green, blue;
getColorForNodeType(nodeType, red, green, blue);
drawNodeBorder(center, scaleFactor, red, green, blue);
float distance;
BoxFace face;
bool inside = serverBounds.contains(pickRay.origin);
bool colliding = serverBounds.findRayIntersection(pickRay.origin, pickRay.direction, distance, face);
@ -120,7 +120,7 @@ void NodeBounds::draw() {
} else {
serverJurisdictions->unlock();
}
}
});
if (selectedNode) {
glPushMatrix();

View file

@ -248,8 +248,8 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
QLocale locale(QLocale::English);
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&](const SharedNodePointer& node){
// only send to the NodeTypes that are NodeType_t_VOXEL_SERVER
if (node->getType() == serverType) {
serverCount++;
@ -420,7 +420,7 @@ void OctreeStatsDialog::showOctreeServersOfType(int& serverCount, NodeType_t ser
serverDetails << linkDetails.str();
_labels[_voxelServerLables[serverCount - 1]]->setText(serverDetails.str().c_str());
} // is VOXEL_SERVER
}
});
}
void OctreeStatsDialog::reject() {

View file

@ -11,6 +11,7 @@
#include "Application.h"
#include "MainWindow.h"
#include "Menu.h"
#include "ModelsBrowser.h"
#include "PreferencesDialog.h"
@ -214,8 +215,8 @@ void PreferencesDialog::savePreferences() {
myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value());
Application::getInstance()->getVoxels()->setMaxVoxels(ui.maxVoxelsSpin->value());
Application::getInstance()->resizeGL(Application::getInstance()->getGLWidget()->width(),
Application::getInstance()->getGLWidget()->height());
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height());
Menu::getInstance()->setRealWorldFieldOfView(ui.realWorldFieldOfViewSpin->value());
@ -247,8 +248,7 @@ void PreferencesDialog::savePreferences() {
Menu::getInstance()->setReceivedAudioStreamSettings(streamSettings);
Application::getInstance()->getAudio()->setReceivedAudioStreamSettings(streamSettings);
Application::getInstance()->resizeGL(Application::getInstance()->getGLWidget()->width(),
Application::getInstance()->getGLWidget()->height());
Application::getInstance()->resizeGL(glCanvas->width(), glCanvas->height());
Application::getInstance()->bumpSettings();
}

View file

@ -83,9 +83,8 @@ QTemporaryFile* Snapshot::saveTempSnapshot() {
}
QFile* Snapshot::savedFileForSnapshot(bool isTemporary) {
QGLWidget* widget = Application::getInstance()->getGLWidget();
QImage shot = widget->grabFrameBuffer();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
QImage shot = glCanvas->grabFrameBuffer();
Avatar* avatar = Application::getInstance()->getAvatar();

View file

@ -56,8 +56,8 @@ Stats::Stats():
_metavoxelReceiveProgress(0),
_metavoxelReceiveTotal(0)
{
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
resetWidth(glWidget->width(), 0);
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
resetWidth(glCanvas->width(), 0);
}
void Stats::toggleExpanded() {
@ -67,7 +67,7 @@ void Stats::toggleExpanded() {
// called on mouse click release
// check for clicks over stats in order to expand or contract them
void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseDragStartedY, int horizontalOffset) {
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
if (0 != glm::compMax(glm::abs(glm::ivec2(mouseX - mouseDragStartedX, mouseY - mouseDragStartedY)))) {
// not worried about dragging on stats
@ -114,7 +114,7 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD
// top-right stats click
lines = _expanded ? 11 : 3;
statsHeight = lines * STATS_PELS_PER_LINE + 10;
statsWidth = glWidget->width() - statsX;
statsWidth = glCanvas->width() - statsX;
if (mouseX > statsX && mouseX < statsX + statsWidth && mouseY > statsY && mouseY < statsY + statsHeight) {
toggleExpanded();
return;
@ -122,8 +122,8 @@ void Stats::checkClick(int mouseX, int mouseY, int mouseDragStartedX, int mouseD
}
void Stats::resetWidth(int width, int horizontalOffset) {
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
int extraSpace = glWidget->width() - horizontalOffset -2
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
int extraSpace = glCanvas->width() - horizontalOffset -2
- STATS_GENERAL_MIN_WIDTH
- (Menu::getInstance()->isOptionChecked(MenuOption::TestPing) ? STATS_PING_MIN_WIDTH -1 : 0)
- STATS_GEO_MIN_WIDTH
@ -147,7 +147,7 @@ void Stats::resetWidth(int width, int horizontalOffset) {
_pingStatsWidth += (int) extraSpace / panels;
}
_geoStatsWidth += (int) extraSpace / panels;
_voxelStatsWidth += glWidget->width() - (_generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3);
_voxelStatsWidth += glCanvas->width() - (_generalStatsWidth + _pingStatsWidth + _geoStatsWidth + 3);
}
}
@ -198,7 +198,7 @@ void Stats::display(
int bytesPerSecond,
int voxelPacketsToProcess)
{
GLCanvas* glWidget = Application::getInstance()->getGLWidget();
GLCanvas::SharedPointer glCanvas = DependencyManager::get<GLCanvas>();
unsigned int backgroundColor = 0x33333399;
int verticalOffset = 0, lines = 0;
@ -210,7 +210,7 @@ void Stats::display(
std::stringstream voxelStats;
if (_lastHorizontalOffset != horizontalOffset) {
resetWidth(glWidget->width(), horizontalOffset);
resetWidth(glCanvas->width(), horizontalOffset);
_lastHorizontalOffset = horizontalOffset;
}
@ -328,8 +328,8 @@ void Stats::display(
// Now handle voxel servers, since there could be more than one, we average their ping times
unsigned long totalPingVoxel = 0;
int voxelServerCount = 0;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
nodeList->eachNode([&totalPingVoxel, &pingVoxelMax, &voxelServerCount](const SharedNodePointer& node){
// TODO: this should also support entities
if (node->getType() == NodeType::VoxelServer) {
totalPingVoxel += node->getPingMs();
@ -338,7 +338,7 @@ void Stats::display(
pingVoxelMax = node->getPingMs();
}
}
}
});
if (voxelServerCount) {
pingVoxel = totalPingVoxel/voxelServerCount;
@ -478,7 +478,7 @@ void Stats::display(
lines = _expanded ? 14 : 3;
drawBackground(backgroundColor, horizontalOffset, 0, glWidget->width() - horizontalOffset,
drawBackground(backgroundColor, horizontalOffset, 0, glCanvas->width() - horizontalOffset,
lines * STATS_PELS_PER_LINE + 10);
horizontalOffset += 5;

View file

@ -10,6 +10,7 @@
//
#include "Application.h"
#include "MainWindow.h"
#include "ToolWindow.h"
#include "UIUtil.h"

View file

@ -12,10 +12,10 @@
#ifndef hifi_LocalModelsOverlay_h
#define hifi_LocalModelsOverlay_h
#include "entities/EntityTreeRenderer.h"
#include "Volume3DOverlay.h"
class EntityTreeRenderer;
class LocalModelsOverlay : public Volume3DOverlay {
Q_OBJECT
public:

View file

@ -11,9 +11,10 @@
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <TextRenderer.h>
#include "Application.h"
#include "Text3DOverlay.h"
#include "ui/TextRenderer.h"
const xColor DEFAULT_BACKGROUND_COLOR = { 0, 0, 0 };
const float DEFAULT_BACKGROUND_ALPHA = 0.7f;

View file

@ -13,9 +13,9 @@
#include <QGLWidget>
#include <SharedUtil.h>
#include <TextRenderer.h>
#include "TextOverlay.h"
#include "ui/TextRenderer.h"
TextOverlay::TextOverlay() :
_backgroundColor(DEFAULT_BACKGROUND_COLOR),

View file

@ -24,8 +24,9 @@ class Animation;
typedef QSharedPointer<Animation> AnimationPointer;
/// Scriptable interface for FBX animation loading.
class AnimationCache : public ResourceCache, public DependencyManager::Dependency {
class AnimationCache : public ResourceCache {
Q_OBJECT
SINGLETON_DEPENDENCY(AnimationCache)
public:
Q_INVOKABLE AnimationPointer getAnimation(const QString& url) { return getAnimation(QUrl(url)); }
@ -38,7 +39,6 @@ protected:
private:
AnimationCache(QObject* parent = NULL);
virtual ~AnimationCache() { }
friend class DependencyManager;
};

View file

@ -0,0 +1,11 @@
set(TARGET_NAME entities-renderer)
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
setup_hifi_library(Widgets OpenGL Network Script)
include_glm()
link_hifi_libraries(shared gpu script-engine)
# call macro to link our dependencies and bubble them up via a property on our target
link_shared_dependencies()

View file

@ -9,28 +9,24 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <gpu/GPUConfig.h>
#include <glm/gtx/quaternion.hpp>
#include <QEventLoop>
#include <QScriptSyntaxCheckResult>
#include <FBXReader.h>
#include "InterfaceConfig.h"
#include <BoxEntityItem.h>
#include <AbstractScriptingServicesInterface.h>
#include <AbstractViewStateInterface.h>
#include <DeferredLightingEffect.h>
#include <GlowEffect.h>
#include <ModelEntityItem.h>
#include <MouseEvent.h>
#include <Model.h>
#include <NetworkAccessManager.h>
#include <PerfStat.h>
#include <RenderArgs.h>
#include <ScriptEngine.h>
#include "Menu.h"
#include "NetworkAccessManager.h"
#include "EntityTreeRenderer.h"
#include "devices/OculusManager.h"
#include "RenderableBoxEntityItem.h"
#include "RenderableLightEntityItem.h"
#include "RenderableModelEntityItem.h"
@ -38,15 +34,18 @@
#include "RenderableTextEntityItem.h"
QThread* EntityTreeRenderer::getMainThread() {
return Application::getInstance()->getEntities()->thread();
}
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts) :
EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
AbstractScriptingServicesInterface* scriptingServices) :
OctreeRenderer(),
_wantScripts(wantScripts),
_entitiesScriptEngine(NULL),
_lastMouseEventValid(false)
_lastMouseEventValid(false),
_viewState(viewState),
_scriptingServices(scriptingServices),
_displayElementChildProxies(false),
_displayModelBounds(false),
_displayModelElementProxy(false),
_dontDoPrecisionPicking(false)
{
REGISTER_ENTITY_TYPE_WITH_FACTORY(Model, RenderableModelEntityItem::factory)
REGISTER_ENTITY_TYPE_WITH_FACTORY(Box, RenderableBoxEntityItem::factory)
@ -76,14 +75,14 @@ void EntityTreeRenderer::init() {
entityTree->setFBXService(this);
if (_wantScripts) {
_entitiesScriptEngine = new ScriptEngine(NO_SCRIPT, "Entities",
Application::getInstance()->getControllerScriptingInterface());
Application::getInstance()->registerScriptEngineWithApplicationServices(_entitiesScriptEngine);
_entitiesScriptEngine = new ScriptEngine(NO_SCRIPT, "Entities",
_scriptingServices->getControllerScriptingInterface());
_scriptingServices->registerScriptEngineWithApplicationServices(_entitiesScriptEngine);
}
// make sure our "last avatar position" is something other than our current position, so that on our
// first chance, we'll check for enter/leave entity events.
glm::vec3 avatarPosition = Application::getInstance()->getAvatar()->getPosition();
glm::vec3 avatarPosition = _viewState->getAvatarPosition();
_lastAvatarPosition = avatarPosition + glm::vec3(1.0f, 1.0f, 1.0f);
connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity);
@ -240,7 +239,7 @@ void EntityTreeRenderer::update() {
void EntityTreeRenderer::checkEnterLeaveEntities() {
if (_tree) {
_tree->lockForWrite(); // so that our scripts can do edits if they want
glm::vec3 avatarPosition = Application::getInstance()->getAvatar()->getPosition() / (float) TREE_SCALE;
glm::vec3 avatarPosition = _viewState->getAvatarPosition() / (float) TREE_SCALE;
if (avatarPosition != _lastAvatarPosition) {
float radius = 1.0f / (float) TREE_SCALE; // for now, assume 1 meter radius
@ -289,44 +288,38 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
}
void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
bool dontRenderAsScene = Menu::getInstance()->isOptionChecked(MenuOption::DontRenderEntitiesAsScene);
if (_tree) {
Model::startScene(renderSide);
RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
_tree->lockForRead();
_tree->recurseTreeWithOperation(renderOperation, &args);
Model::RenderMode modelRenderMode = renderMode == RenderArgs::SHADOW_RENDER_MODE
? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
// we must call endScene while we still have the tree locked so that no one deletes a model
// on us while rendering the scene
Model::endScene(modelRenderMode, &args);
_tree->unlock();
if (dontRenderAsScene) {
OctreeRenderer::render(renderMode, renderSide);
} else {
if (_tree) {
Model::startScene(renderSide);
RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
_tree->lockForRead();
_tree->recurseTreeWithOperation(renderOperation, &args);
// stats...
_meshesConsidered = args._meshesConsidered;
_meshesRendered = args._meshesRendered;
_meshesOutOfView = args._meshesOutOfView;
_meshesTooSmall = args._meshesTooSmall;
Model::RenderMode modelRenderMode = renderMode == RenderArgs::SHADOW_RENDER_MODE
? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
_elementsTouched = args._elementsTouched;
_itemsRendered = args._itemsRendered;
_itemsOutOfView = args._itemsOutOfView;
_itemsTooSmall = args._itemsTooSmall;
// we must call endScene while we still have the tree locked so that no one deletes a model
// on us while rendering the scene
Model::endScene(modelRenderMode, &args);
_tree->unlock();
// stats...
_meshesConsidered = args._meshesConsidered;
_meshesRendered = args._meshesRendered;
_meshesOutOfView = args._meshesOutOfView;
_meshesTooSmall = args._meshesTooSmall;
_materialSwitches = args._materialSwitches;
_trianglesRendered = args._trianglesRendered;
_quadsRendered = args._quadsRendered;
_elementsTouched = args._elementsTouched;
_itemsRendered = args._itemsRendered;
_itemsOutOfView = args._itemsOutOfView;
_itemsTooSmall = args._itemsTooSmall;
_materialSwitches = args._materialSwitches;
_trianglesRendered = args._trianglesRendered;
_quadsRendered = args._quadsRendered;
_translucentMeshPartsRendered = args._translucentMeshPartsRendered;
_opaqueMeshPartsRendered = args._opaqueMeshPartsRendered;
}
_translucentMeshPartsRendered = args._translucentMeshPartsRendered;
_opaqueMeshPartsRendered = args._opaqueMeshPartsRendered;
}
deleteReleasedModels(); // seems like as good as any other place to do some memory cleanup
}
@ -358,75 +351,72 @@ const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityI
return result;
}
void renderElementProxy(EntityTreeElement* entityTreeElement) {
void EntityTreeRenderer::renderElementProxy(EntityTreeElement* entityTreeElement) {
glm::vec3 elementCenter = entityTreeElement->getAACube().calcCenter() * (float) TREE_SCALE;
float elementSize = entityTreeElement->getScale() * (float) TREE_SCALE;
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(elementCenter.x, elementCenter.y, elementCenter.z);
glutWireCube(elementSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(elementSize);
glPopMatrix();
bool displayElementChildProxies = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelElementChildProxies);
if (displayElementChildProxies) {
if (_displayElementChildProxies) {
// draw the children
float halfSize = elementSize / 2.0f;
float quarterSize = elementSize / 4.0f;
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(elementCenter.x - quarterSize, elementCenter.y - quarterSize, elementCenter.z - quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(1.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(elementCenter.x + quarterSize, elementCenter.y - quarterSize, elementCenter.z - quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(0.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(elementCenter.x - quarterSize, elementCenter.y + quarterSize, elementCenter.z - quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(0.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(elementCenter.x - quarterSize, elementCenter.y - quarterSize, elementCenter.z + quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(1.0f, 1.0f, 1.0f);
glPushMatrix();
glTranslatef(elementCenter.x + quarterSize, elementCenter.y + quarterSize, elementCenter.z + quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(0.0f, 0.5f, 0.5f);
glPushMatrix();
glTranslatef(elementCenter.x - quarterSize, elementCenter.y + quarterSize, elementCenter.z + quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(0.5f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(elementCenter.x + quarterSize, elementCenter.y - quarterSize, elementCenter.z + quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
glColor3f(0.0f, 0.5f, 0.0f);
glPushMatrix();
glTranslatef(elementCenter.x + quarterSize, elementCenter.y + quarterSize, elementCenter.z - quarterSize);
glutWireCube(halfSize);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(halfSize);
glPopMatrix();
}
}
void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* args) {
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
bool displayModelBounds = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelBounds);
if (!isShadowMode && displayModelBounds) {
if (!isShadowMode && _displayModelBounds) {
PerformanceTimer perfTimer("renderProxies");
AACube maxCube = entity->getMaximumAACube();
@ -446,14 +436,14 @@ void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* arg
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(maxCenter.x, maxCenter.y, maxCenter.z);
glutWireCube(maxCube.getScale());
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(maxCube.getScale());
glPopMatrix();
// draw the min bounding cube
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(minCenter.x, minCenter.y, minCenter.z);
glutWireCube(minCube.getScale());
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(minCube.getScale());
glPopMatrix();
// draw the entityBox bounding box
@ -461,7 +451,7 @@ void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* arg
glPushMatrix();
glTranslatef(entityBoxCenter.x, entityBoxCenter.y, entityBoxCenter.z);
glScalef(entityBoxScale.x, entityBoxScale.y, entityBoxScale.z);
glutWireCube(1.0f);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f);
glPopMatrix();
@ -479,15 +469,13 @@ void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* arg
glm::vec3 positionToCenter = center - position;
glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z);
glScalef(dimensions.x, dimensions.y, dimensions.z);
glutWireCube(1.0f);
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(1.0f);
glPopMatrix();
glPopMatrix();
}
}
void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) {
bool wantDebug = false;
args->_elementsTouched++;
// actually render it here...
// we need to iterate the actual entityItems of the element
@ -499,11 +487,8 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
uint16_t numberOfEntities = entityItems.size();
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
bool displayElementProxy = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelElementProxy);
if (!isShadowMode && displayElementProxy && numberOfEntities > 0) {
if (!isShadowMode && _displayModelElementProxy && numberOfEntities > 0) {
renderElementProxy(entityTreeElement);
}
@ -520,23 +505,9 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
// when they are outside of the view frustum...
float distance = args->_viewFrustum->distanceToCamera(entityBox.calcCenter());
if (wantDebug) {
qDebug() << "------- renderElement() ----------";
qDebug() << " type:" << EntityTypes::getEntityTypeName(entityItem->getType());
if (entityItem->getType() == EntityTypes::Model) {
ModelEntityItem* modelEntity = static_cast<ModelEntityItem*>(entityItem);
qDebug() << " url:" << modelEntity->getModelURL();
}
qDebug() << " entityBox:" << entityItem->getAABox();
qDebug() << " dimensions:" << entityItem->getDimensionsInMeters() << "in meters";
qDebug() << " largestDimension:" << entityBox.getLargestDimension() << "in meters";
qDebug() << " shouldRender:" << Menu::getInstance()->shouldRenderMesh(entityBox.getLargestDimension(), distance);
qDebug() << " in frustum:" << (args->_viewFrustum->boxInFrustum(entityBox) != ViewFrustum::OUTSIDE);
}
bool outOfView = args->_viewFrustum->boxInFrustum(entityBox) == ViewFrustum::OUTSIDE;
if (!outOfView) {
bool bigEnoughToRender = Menu::getInstance()->shouldRenderMesh(entityBox.getLargestDimension(), distance);
bool bigEnoughToRender = _viewState->shouldRenderMesh(entityBox.getLargestDimension(), distance);
if (bigEnoughToRender) {
renderProxies(entityItem, args);
@ -561,11 +532,11 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
}
float EntityTreeRenderer::getSizeScale() const {
return Menu::getInstance()->getVoxelSizeScale();
return _viewState->getSizeScale();
}
int EntityTreeRenderer::getBoundaryLevelAdjust() const {
return Menu::getInstance()->getBoundaryLevelAdjust();
return _viewState->getBoundaryLevelAdjust();
}
@ -640,11 +611,6 @@ void EntityTreeRenderer::deleteReleasedModels() {
}
}
PickRay EntityTreeRenderer::computePickRay(float x, float y) {
return Application::getInstance()->getCamera()->computePickRay(x, y);
}
RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
bool precisionPicking) {
RayToEntityIntersectionResult result;
@ -706,9 +672,9 @@ QScriptValueList EntityTreeRenderer::createEntityArgs(const EntityItemID& entity
void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent");
PickRay ray = computePickRay(event->x(), event->y());
PickRay ray = _viewState->computePickRay(event->x(), event->y());
bool precisionPicking = !Menu::getInstance()->isOptionChecked(MenuOption::DontDoPrecisionPicking);
bool precisionPicking = !_dontDoPrecisionPicking;
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking);
if (rayPickResult.intersects) {
//qDebug() << "mousePressEvent over entity:" << rayPickResult.entityID;
@ -732,8 +698,8 @@ void EntityTreeRenderer::mousePressEvent(QMouseEvent* event, unsigned int device
void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) {
PerformanceTimer perfTimer("EntityTreeRenderer::mouseReleaseEvent");
PickRay ray = computePickRay(event->x(), event->y());
bool precisionPicking = !Menu::getInstance()->isOptionChecked(MenuOption::DontDoPrecisionPicking);
PickRay ray = _viewState->computePickRay(event->x(), event->y());
bool precisionPicking = !_dontDoPrecisionPicking;
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::Lock, precisionPicking);
if (rayPickResult.intersects) {
//qDebug() << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
@ -767,7 +733,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event, unsigned int devi
void EntityTreeRenderer::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
PerformanceTimer perfTimer("EntityTreeRenderer::mouseMoveEvent");
PickRay ray = computePickRay(event->x(), event->y());
PickRay ray = _viewState->computePickRay(event->x(), event->y());
bool precisionPicking = false; // for mouse moves we do not do precision picking
RayToEntityIntersectionResult rayPickResult = findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking);

View file

@ -12,20 +12,17 @@
#ifndef hifi_EntityTreeRenderer_h
#define hifi_EntityTreeRenderer_h
#include <glm/glm.hpp>
#include <stdint.h>
#include <EntityTree.h>
#include <EntityScriptingInterface.h> // for RayToEntityIntersectionResult
#include <Model.h>
#include <Octree.h>
#include <OctreePacketData.h>
#include <MouseEvent.h>
#include <OctreeRenderer.h>
#include <PacketHeaders.h>
#include <RenderArgs.h>
#include <SharedUtil.h>
#include <ViewFrustum.h>
class Model;
class ScriptEngine;
class AbstractViewStateInterface;
class AbstractScriptingServicesInterface;
class ScriptEngine;
class EntityScriptDetails {
public:
@ -37,7 +34,8 @@ public:
class EntityTreeRenderer : public OctreeRenderer, public EntityItemFBXService {
Q_OBJECT
public:
EntityTreeRenderer(bool wantScripts);
EntityTreeRenderer(bool wantScripts, AbstractViewStateInterface* viewState,
AbstractScriptingServicesInterface* scriptingServices);
virtual ~EntityTreeRenderer();
virtual char getMyNodeType() const { return NodeType::EntityServer; }
@ -64,8 +62,6 @@ public:
/// clears the tree
virtual void clear();
static QThread* getMainThread();
/// if a renderable entity item needs a model, we will allocate it for them
Q_INVOKABLE Model* allocateModel(const QString& url);
@ -109,17 +105,22 @@ public slots:
void entityCollisionWithVoxel(const EntityItemID& entityID, const VoxelDetail& voxel, const Collision& collision);
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
// optional slots that can be wired to menu items
void setDisplayElementChildProxies(bool value) { _displayElementChildProxies = value; }
void setDisplayModelBounds(bool value) { _displayModelBounds = value; }
void setDisplayModelElementProxy(bool value) { _displayModelElementProxy = value; }
void setDontDoPrecisionPicking(bool value) { _dontDoPrecisionPicking = value; }
protected:
virtual Octree* createTree() { return new EntityTree(true); }
private:
void renderElementProxy(EntityTreeElement* entityTreeElement);
void checkAndCallPreload(const EntityItemID& entityID);
void checkAndCallUnload(const EntityItemID& entityID);
QList<Model*> _releasedModels;
void renderProxies(const EntityItem* entity, RenderArgs* args);
PickRay computePickRay(float x, float y);
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
bool precisionPicking);
@ -145,6 +146,13 @@ private:
bool _lastMouseEventValid;
MouseEvent _lastMouseEvent;
AbstractViewStateInterface* _viewState;
AbstractScriptingServicesInterface* _scriptingServices;
bool _displayElementChildProxies;
bool _displayModelBounds;
bool _displayModelElementProxy;
bool _dontDoPrecisionPicking;
};
#endif // hifi_EntityTreeRenderer_h

View file

@ -11,21 +11,13 @@
#include <glm/gtx/quaternion.hpp>
#include <FBXReader.h>
#include <gpu/GPUConfig.h>
#include "InterfaceConfig.h"
#include <BoxEntityItem.h>
#include <DeferredLightingEffect.h>
#include <ModelEntityItem.h>
#include <PerfStat.h>
#include "Menu.h"
#include "EntityTreeRenderer.h"
#include "RenderableBoxEntityItem.h"
EntityItem* RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return new RenderableBoxEntityItem(entityID, properties);
}

View file

@ -12,17 +12,6 @@
#ifndef hifi_RenderableBoxEntityItem_h
#define hifi_RenderableBoxEntityItem_h
#include <glm/glm.hpp>
#include <stdint.h>
#include <EntityTree.h>
#include <Octree.h>
#include <OctreePacketData.h>
#include <OctreeRenderer.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <ViewFrustum.h>
#include <BoxEntityItem.h>
class RenderableBoxEntityItem : public BoxEntityItem {

View file

@ -11,21 +11,13 @@
#include <glm/gtx/quaternion.hpp>
#include <FBXReader.h>
#include "InterfaceConfig.h"
#include <gpu/GPUConfig.h>
#include <DeferredLightingEffect.h>
#include <PerfStat.h>
#include <LightEntityItem.h>
#include "Application.h"
#include "Menu.h"
#include "EntityTreeRenderer.h"
#include "RenderableLightEntityItem.h"
EntityItem* RenderableLightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return new RenderableLightEntityItem(entityID, properties);
}
@ -61,17 +53,13 @@ void RenderableLightEntityItem::render(RenderArgs* args) {
float exponent = getExponent();
float cutoff = glm::radians(getCutoff());
bool disableLights = Menu::getInstance()->isOptionChecked(MenuOption::DisableLightEntities);
if (!disableLights) {
if (_isSpotlight) {
DependencyManager::get<DeferredLightingEffect>()->addSpotLight(position, largestDiameter / 2.0f,
ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation,
direction, exponent, cutoff);
} else {
DependencyManager::get<DeferredLightingEffect>()->addPointLight(position, largestDiameter / 2.0f,
ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation);
}
if (_isSpotlight) {
DependencyManager::get<DeferredLightingEffect>()->addSpotLight(position, largestDiameter / 2.0f,
ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation,
direction, exponent, cutoff);
} else {
DependencyManager::get<DeferredLightingEffect>()->addPointLight(position, largestDiameter / 2.0f,
ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation);
}
#ifdef WANT_DEBUG
@ -94,10 +82,11 @@ void RenderableLightEntityItem::render(RenderArgs* args) {
bool RenderableLightEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face,
void** intersectedObject, bool precisionPicking) const {
// TODO: this isn't really correct because we don't know if we actually live in the main tree of the applications's
// EntityTreeRenderer. But we probably do. Technically we could be on the clipboard and someone might be trying to
// use the ray intersection API there. Anyway... if you ever try to do ray intersection testing off of trees other
// than the main tree of the main entity renderer, then you'll need to fix this mechanism.
return Application::getInstance()->getEntities()->getTree()->getLightsArePickable();
// TODO: consider if this is really what we want to do. We've made it so that "lights are pickable" is a global state
// this is probably reasonable since there's typically only one tree you'd be picking on at a time. Technically we could
// be on the clipboard and someone might be trying to use the ray intersection API there. Anyway... if you ever try to
// do ray intersection testing off of trees other than the main tree of the main entity renderer, then we'll need to
// fix this mechanism.
return _lightsArePickable;
}

View file

@ -12,17 +12,6 @@
#ifndef hifi_RenderableLightEntityItem_h
#define hifi_RenderableLightEntityItem_h
#include <glm/glm.hpp>
#include <stdint.h>
#include <EntityTree.h>
#include <Octree.h>
#include <OctreePacketData.h>
#include <OctreeRenderer.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <ViewFrustum.h>
#include <LightEntityItem.h>
class RenderableLightEntityItem : public LightEntityItem {

View file

@ -11,17 +11,14 @@
#include <glm/gtx/quaternion.hpp>
#include <FBXReader.h>
#include <gpu/GPUConfig.h>
#include "InterfaceConfig.h"
#include <QJsonDocument>
#include <BoxEntityItem.h>
#include <DeferredLightingEffect.h>
#include <ModelEntityItem.h>
#include <Model.h>
#include <PerfStat.h>
#include "Menu.h"
#include "EntityTreeRenderer.h"
#include "RenderableModelEntityItem.h"
@ -37,9 +34,9 @@ RenderableModelEntityItem::~RenderableModelEntityItem() {
}
}
bool RenderableModelEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool RenderableModelEntityItem::setProperties(const EntityItemProperties& properties) {
QString oldModelURL = getModelURL();
bool somethingChanged = ModelEntityItem::setProperties(properties, forceCopy);
bool somethingChanged = ModelEntityItem::setProperties(properties);
if (somethingChanged && oldModelURL != getModelURL()) {
_needsModelReload = true;
}
@ -165,28 +162,11 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
_needsInitialSimulation = false;
}
// TODO: should we allow entityItems to have alpha on their models?
Model::RenderMode modelRenderMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE
? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
if (_model->isActive()) {
// TODO: this is the majority of model render time. And rendering of a cube model vs the basic Box render
// is significantly more expensive. Is there a way to call this that doesn't cost us as much?
PerformanceTimer perfTimer("model->render");
bool dontRenderAsScene = Menu::getInstance()->isOptionChecked(MenuOption::DontRenderEntitiesAsScene);
bool displayModelTriangles = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelTriangles);
bool rendered = false;
if (displayModelTriangles) {
rendered = _model->renderTriangleProxies();
}
if (!rendered) {
if (dontRenderAsScene) {
_model->render(alpha, modelRenderMode, args);
} else {
_model->renderInScene(alpha, args);
}
}
_model->renderInScene(alpha, args);
} else {
// if we couldn't get a model, then just draw a cube
glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]);

View file

@ -12,18 +12,13 @@
#ifndef hifi_RenderableModelEntityItem_h
#define hifi_RenderableModelEntityItem_h
#include <glm/glm.hpp>
#include <stdint.h>
#include <QString>
#include <QStringList>
#include <EntityTree.h>
#include <Model.h>
#include <ModelEntityItem.h>
#include <Octree.h>
#include <OctreePacketData.h>
#include <OctreeRenderer.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <ViewFrustum.h>
class Model;
class EntityTreeRenderer;
class RenderableModelEntityItem : public ModelEntityItem {
public:
@ -40,7 +35,7 @@ public:
virtual ~RenderableModelEntityItem();
virtual EntityItemProperties getProperties() const;
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy);
virtual bool setProperties(const EntityItemProperties& properties);
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
ReadBitstreamToTreeParams& args,
EntityPropertyFlags& propertyFlags, bool overwriteLocalData);

View file

@ -11,18 +11,12 @@
#include <glm/gtx/quaternion.hpp>
#include <FBXReader.h>
#include "InterfaceConfig.h"
#include <gpu/GPUConfig.h>
#include <DependencyManager.h>
#include <DeferredLightingEffect.h>
#include <PerfStat.h>
#include <SphereEntityItem.h>
#include "Menu.h"
#include "EntityTreeRenderer.h"
#include "RenderableSphereEntityItem.h"
EntityItem* RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {

View file

@ -12,17 +12,6 @@
#ifndef hifi_RenderableSphereEntityItem_h
#define hifi_RenderableSphereEntityItem_h
#include <glm/glm.hpp>
#include <stdint.h>
#include <EntityTree.h>
#include <Octree.h>
#include <OctreePacketData.h>
#include <OctreeRenderer.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <ViewFrustum.h>
#include <SphereEntityItem.h>
class RenderableSphereEntityItem : public SphereEntityItem {

View file

@ -11,13 +11,10 @@
#include <glm/gtx/quaternion.hpp>
#include "InterfaceConfig.h"
#include <TextEntityItem.h>
#include <gpu/GPUConfig.h>
#include <PerfStat.h>
#include <TextRenderer.h>
#include "Menu.h"
#include "EntityTreeRenderer.h"
#include "RenderableTextEntityItem.h"
const int FIXED_FONT_POINT_SIZE = 40;

View file

@ -12,17 +12,6 @@
#ifndef hifi_RenderableTextEntityItem_h
#define hifi_RenderableTextEntityItem_h
#include <glm/glm.hpp>
#include <stdint.h>
#include <EntityTree.h>
#include <Octree.h>
#include <OctreePacketData.h>
#include <OctreeRenderer.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <ViewFrustum.h>
#include <TextEntityItem.h>
class RenderableTextEntityItem : public TextEntityItem {

View file

@ -29,7 +29,7 @@ BoxEntityItem::BoxEntityItem(const EntityItemID& entityItemID, const EntityItemP
{
_type = EntityTypes::Box;
_created = properties.getCreated();
setProperties(properties, true);
setProperties(properties);
}
EntityItemProperties BoxEntityItem::getProperties() const {
@ -44,9 +44,9 @@ EntityItemProperties BoxEntityItem::getProperties() const {
return properties;
}
bool BoxEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool BoxEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);

View file

@ -24,7 +24,7 @@ public:
// methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties() const;
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
virtual bool setProperties(const EntityItemProperties& properties);
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;

View file

@ -53,14 +53,13 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
_creatorTokenID = entityItemID.creatorTokenID;
// init values with defaults before calling setProperties
//uint64_t now = usecTimestampNow();
quint64 now = usecTimestampNow();
_lastSimulated = now;
_lastUpdated = now;
_lastEdited = 0;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = 0; // TODO: when do we actually want to make this "now"
_created = UNKNOWN_CREATED_TIME;
_changedOnServer = 0;
_position = glm::vec3(0,0,0);
@ -86,12 +85,13 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
EntityItem::EntityItem(const EntityItemID& entityItemID) {
_type = EntityTypes::Unknown;
quint64 now = usecTimestampNow();
_lastSimulated = now;
_lastUpdated = now;
_lastEdited = 0;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = 0;
_created = UNKNOWN_CREATED_TIME;
_dirtyFlags = 0;
_changedOnServer = 0;
initFromEntityItemID(entityItemID);
@ -99,16 +99,17 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) {
EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) {
_type = EntityTypes::Unknown;
quint64 now = usecTimestampNow();
_lastSimulated = now;
_lastUpdated = now;
_lastEdited = 0;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = properties.getCreated();
_created = UNKNOWN_CREATED_TIME;
_dirtyFlags = 0;
_changedOnServer = 0;
initFromEntityItemID(entityItemID);
setProperties(properties, true); // force copy
setProperties(properties);
}
EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
@ -365,9 +366,16 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
memcpy(&createdFromBuffer, dataAt, sizeof(createdFromBuffer));
dataAt += sizeof(createdFromBuffer);
bytesRead += sizeof(createdFromBuffer);
createdFromBuffer -= clockSkew;
_created = createdFromBuffer; // TODO: do we ever want to discard this???
quint64 now = usecTimestampNow();
if (_created == UNKNOWN_CREATED_TIME) {
// we don't yet have a _created timestamp, so we accept this one
createdFromBuffer -= clockSkew;
if (createdFromBuffer > now || createdFromBuffer == UNKNOWN_CREATED_TIME) {
createdFromBuffer = now;
}
_created = createdFromBuffer;
}
if (wantDebug) {
quint64 lastEdited = getLastEdited();
@ -381,7 +389,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
qDebug() << " ago=" << editedAgo << "seconds - " << agoAsString;
}
quint64 now = usecTimestampNow();
quint64 lastEditedFromBuffer = 0;
quint64 lastEditedFromBufferAdjusted = 0;
@ -391,6 +398,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
dataAt += sizeof(lastEditedFromBuffer);
bytesRead += sizeof(lastEditedFromBuffer);
lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew;
if (lastEditedFromBufferAdjusted > now) {
lastEditedFromBufferAdjusted = now;
}
bool fromSameServerEdit = (lastEditedFromBuffer == _lastEditedFromRemoteInRemoteTime);
@ -439,10 +449,13 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
qDebug() << "USING NEW data from server!!! ****************";
}
// don't allow _lastEdited to be in the future
_lastEdited = lastEditedFromBufferAdjusted;
_lastEditedFromRemote = now;
_lastEditedFromRemoteInRemoteTime = lastEditedFromBuffer;
// TODO: only send this notification if something ACTUALLY changed (hint, we haven't yet parsed
// the properties out of the bitstream (see below))
somethingChangedNotification(); // notify derived classes that something has changed
}
@ -451,7 +464,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
ByteCountCoded<quint64> updateDeltaCoder = encodedUpdateDelta;
quint64 updateDelta = updateDeltaCoder;
if (overwriteLocalData) {
_lastSimulated = _lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that for _lastEdited
_lastUpdated = lastEditedFromBufferAdjusted + updateDelta; // don't adjust for clock skew since we already did that
if (wantDebug) {
qDebug() << "_lastUpdated =" << _lastUpdated;
qDebug() << "_lastEdited=" << _lastEdited;
@ -523,6 +536,9 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData);
recalculateCollisionShape();
if (overwriteLocalData && (getDirtyFlags() & EntityItem::DIRTY_POSITION)) {
_lastSimulated = now;
}
}
return bytesRead;
}
@ -576,7 +592,7 @@ void EntityItem::simulate(const quint64& now) {
float timeElapsed = (float)(now - _lastSimulated) / (float)(USECS_PER_SECOND);
if (wantDebug) {
qDebug() << "********** EntityItem::update()";
qDebug() << "********** EntityItem::simulate()";
qDebug() << " entity ID=" << getEntityItemID();
qDebug() << " now=" << now;
qDebug() << " _lastSimulated=" << _lastSimulated;
@ -612,10 +628,8 @@ void EntityItem::simulate(const quint64& now) {
}
}
_lastSimulated = now;
if (wantDebug) {
qDebug() << " ********** EntityItem::update() .... SETTING _lastSimulated=" << _lastSimulated;
qDebug() << " ********** EntityItem::simulate() .... SETTING _lastSimulated=" << _lastSimulated;
}
if (hasAngularVelocity()) {
@ -651,7 +665,7 @@ void EntityItem::simulate(const quint64& now) {
glm::vec3 newPosition = position + (velocity * timeElapsed);
if (wantDebug) {
qDebug() << " EntityItem::update()....";
qDebug() << " EntityItem::simulate()....";
qDebug() << " timeElapsed:" << timeElapsed;
qDebug() << " old AACube:" << getMaximumAACube();
qDebug() << " old position:" << position;
@ -677,15 +691,15 @@ void EntityItem::simulate(const quint64& now) {
}
// handle gravity....
if (hasGravity() && !isRestingOnSurface()) {
velocity += getGravity() * timeElapsed;
}
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
// "ground" plane of the domain, but for now it
if (hasGravity() && isRestingOnSurface()) {
velocity.y = 0.0f;
position.y = getDistanceToBottomOfEntity();
if (hasGravity()) {
// handle resting on surface case, this is definitely a bit of a hack, and it only works on the
// "ground" plane of the domain, but for now it what we've got
if (isRestingOnSurface()) {
velocity.y = 0.0f;
position.y = getDistanceToBottomOfEntity();
} else {
velocity += getGravity() * timeElapsed;
}
}
// handle damping for velocity
@ -721,6 +735,8 @@ void EntityItem::simulate(const quint64& now) {
qDebug() << " old getAABox:" << getAABox();
}
}
_lastSimulated = now;
}
bool EntityItem::isMoving() const {
@ -768,18 +784,9 @@ EntityItemProperties EntityItem::getProperties() const {
return properties;
}
bool EntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool EntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
// handle the setting of created timestamps for the basic new entity case
if (forceCopy) {
if (properties.getCreated() == UNKNOWN_CREATED_TIME) {
_created = usecTimestampNow();
} else if (properties.getCreated() != USE_EXISTING_CREATED_TIME) {
_created = properties.getCreated();
}
}
SET_ENTITY_PROPERTY_FROM_PROPERTIES(position, updatePositionInMeters); // this will call recalculate collision shape if needed
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, updateDimensionsInMeters); // NOTE: radius is obsolete
SET_ENTITY_PROPERTY_FROM_PROPERTIES(rotation, updateRotation);
@ -803,18 +810,49 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
if (somethingChanged) {
somethingChangedNotification(); // notify derived classes that something has changed
bool wantDebug = false;
uint64_t now = usecTimestampNow();
if (wantDebug) {
uint64_t now = usecTimestampNow();
int elapsed = now - getLastEdited();
qDebug() << "EntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
"now=" << now << " getLastEdited()=" << getLastEdited();
}
setLastEdited(properties._lastEdited);
if (_created != UNKNOWN_CREATED_TIME) {
setLastEdited(now);
}
if (getDirtyFlags() & EntityItem::DIRTY_POSITION) {
_lastSimulated = now;
}
}
// timestamps
quint64 timestamp = properties.getCreated();
if (_created == UNKNOWN_CREATED_TIME && timestamp != UNKNOWN_CREATED_TIME) {
quint64 now = usecTimestampNow();
if (timestamp > now) {
timestamp = now;
}
_created = timestamp;
timestamp = properties.getLastEdited();
if (timestamp > now) {
timestamp = now;
} else if (timestamp < _created) {
timestamp = _created;
}
_lastEdited = timestamp;
}
return somethingChanged;
}
void EntityItem::recordCreationTime() {
assert(_created == UNKNOWN_CREATED_TIME);
_created = usecTimestampNow();
_lastEdited = _created;
_lastUpdated = _created;
_lastSimulated = _created;
}
// TODO: is this really correct? how do we use size, does it need to handle rotation?
float EntityItem::getSize() const {

View file

@ -74,18 +74,19 @@ public:
virtual EntityItemProperties getProperties() const;
/// returns true if something changed
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
virtual bool setProperties(const EntityItemProperties& properties);
/// Override this in your derived class if you'd like to be informed when something about the state of the entity
/// has changed. This will be called with properties change or when new data is loaded from a stream
virtual void somethingChangedNotification() { }
void recordCreationTime(); // set _created to 'now'
quint64 getLastSimulated() const { return _lastSimulated; } /// Last simulated time of this entity universal usecs
/// Last edited time of this entity universal usecs
quint64 getLastEdited() const { return _lastEdited; }
void setLastEdited(quint64 lastEdited)
{ _lastEdited = _lastSimulated = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
{ _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
@ -120,9 +121,6 @@ public:
static int expectedBytes();
static bool encodeEntityEditMessageDetails(PacketType command, EntityItemID id, const EntityItemProperties& details,
unsigned char* bufferOut, int sizeIn, int& sizeOut);
static void adjustEditPacketForClockSkew(unsigned char* codeColorBuffer, size_t length, int clockSkew);
// perform update

View file

@ -156,6 +156,17 @@ void EntityItemProperties::debugDump() const {
props.debugDumpBits();
}
void EntityItemProperties::setCreated(quint64 usecTime) {
_created = usecTime;
if (_lastEdited < _created) {
_lastEdited = _created;
}
}
void EntityItemProperties::setLastEdited(quint64 usecTime) {
_lastEdited = usecTime > _created ? usecTime : _created;
}
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
EntityPropertyFlags changedProperties;
@ -652,9 +663,6 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
entityID.creatorTokenID = UNKNOWN_ENTITY_TOKEN;
entityID.isKnownID = true;
valid = true;
// created time is lastEdited time
properties.setCreated(USE_EXISTING_CREATED_TIME);
}
// Entity Type...

View file

@ -95,9 +95,7 @@ enum EntityPropertyList {
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
const quint64 UNKNOWN_CREATED_TIME = (quint64)(-1);
const quint64 USE_EXISTING_CREATED_TIME = (quint64)(-2);
const quint64 UNKNOWN_CREATED_TIME = 0;
/// A collection of properties of an entity item used in the scripting API. Translates between the actual properties of an
/// entity and a JavaScript style hash/QScriptValue storing a set of properties. Used in scripting to set/get the complete
@ -134,7 +132,7 @@ public:
AABox getAABoxInMeters() const;
void debugDump() const;
void setLastEdited(quint64 usecTime) { _lastEdited = usecTime; }
void setLastEdited(quint64 usecTime);
DEFINE_PROPERTY(PROP_VISIBLE, Visible, visible, bool);
DEFINE_PROPERTY_REF_WITH_SETTER(PROP_POSITION, Position, position, glm::vec3);
@ -180,7 +178,7 @@ public:
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
quint64 getCreated() const { return _created; }
void setCreated(quint64 usecTime) { _created = usecTime; }
void setCreated(quint64 usecTime);
bool hasCreatedTime() const { return (_created != UNKNOWN_CREATED_TIME); }
bool containsBoundsProperties() const { return (_positionChanged || _dimensionsChanged); }

View file

@ -137,13 +137,13 @@
}
#define SET_ENTITY_PROPERTY_FROM_PROPERTIES(P,M) \
if (properties._##P##Changed || forceCopy) { \
if (properties._##P##Changed) { \
M(properties._##P); \
somethingChanged = true; \
}
#define SET_ENTITY_PROPERTY_FROM_PROPERTIES_GETTER(C,G,S) \
if (properties.C() || forceCopy) { \
if (properties.C()) { \
S(properties.G()); \
somethingChanged = true; \
}

View file

@ -11,6 +11,7 @@
#include "EntityScriptingInterface.h"
#include "EntityTree.h"
#include "LightEntityItem.h"
#include "ModelEntityItem.h"
EntityScriptingInterface::EntityScriptingInterface() :
@ -226,16 +227,11 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke
}
void EntityScriptingInterface::setLightsArePickable(bool value) {
if (_entityTree) {
_entityTree->setLightsArePickable(value);
}
LightEntityItem::setLightsArePickable(value);
}
bool EntityScriptingInterface::getLightsArePickable() const {
if (_entityTree) {
return _entityTree->getLightsArePickable();
}
return false;
return LightEntityItem::getLightsArePickable();
}

View file

@ -22,7 +22,6 @@
EntityTree::EntityTree(bool shouldReaverage) :
Octree(shouldReaverage),
_fbxService(NULL),
_lightsArePickable(true),
_simulation(NULL)
{
_rootElement = createNewElement();
@ -165,9 +164,17 @@ EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItem
// NOTE: This method is used in the client and the server tree. In the client, it's possible to create EntityItems
// that do not yet have known IDs. In the server tree however we don't want to have entities without known IDs.
if (getIsServer() && !entityID.isKnownID) {
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... (getIsSever() && !entityID.isKnownID)";
return result;
bool recordCreationTime = false;
if (!entityID.isKnownID) {
if (getIsServer()) {
qDebug() << "UNEXPECTED!!! ----- EntityTree::addEntity()... (getIsSever() && !entityID.isKnownID)";
return result;
}
if (properties.getCreated() == UNKNOWN_CREATED_TIME) {
// the entity's creation time was not specified in properties, which means this is a NEW entity
// and we must record its creation time
recordCreationTime = true;
}
}
// You should not call this on existing entities that are already part of the tree! Call updateEntity()
@ -183,6 +190,9 @@ EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItem
result = EntityTypes::constructEntityItem(type, entityID, properties);
if (result) {
if (recordCreationTime) {
result->recordCreationTime();
}
// Recurse the tree and store the entity in the correct tree element
AddEntityOperator theOperator(this, result);
recurseTreeWithOperator(&theOperator);

View file

@ -150,8 +150,6 @@ public:
void emitEntityScriptChanging(const EntityItemID& entityItemID);
bool getLightsArePickable() const { return _lightsArePickable; }
void setLightsArePickable(bool value) { _lightsArePickable = value; }
void setSimulation(EntitySimulation* simulation);
signals:
@ -180,7 +178,6 @@ private:
QHash<EntityItemID, EntityTreeElement*> _entityToElementMap;
bool _lightsArePickable;
EntitySimulation* _simulation;
};

View file

@ -71,22 +71,13 @@ bool EntityTypes::registerEntityType(EntityType entityType, const char* name, En
EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
const EntityItemProperties& properties) {
EntityItem* newEntityItem = NULL;
EntityTypeFactory factory = NULL;
if (entityType >= 0 && entityType <= LAST) {
factory = _factories[entityType];
}
if (factory) {
// NOTE: if someone attempts to create an entity with properties that do not include a proper "created" time
// then set the created time to now
if (!properties.hasCreatedTime()) {
EntityItemProperties mutableProperties = properties;
mutableProperties.setCreated(usecTimestampNow());
newEntityItem = factory(entityID, mutableProperties);
} else {
newEntityItem = factory(entityID, properties);
}
newEntityItem = factory(entityID, properties);
}
return newEntityItem;
}
@ -129,8 +120,6 @@ EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int byte
EntityItemID tempEntityID(actualID);
EntityItemProperties tempProperties;
tempProperties.setCreated(usecTimestampNow()); // this is temporary...
return constructEntityItem(entityType, tempEntityID, tempProperties);
}

View file

@ -18,6 +18,7 @@
#include "EntityTreeElement.h"
#include "LightEntityItem.h"
bool LightEntityItem::_lightsArePickable = false;
EntityItem* LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return new LightEntityItem(entityID, properties);
@ -40,7 +41,7 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID, const EntityI
_exponent = 0.0f;
_cutoff = PI;
setProperties(properties, true);
setProperties(properties);
// a light is not collide-able so we make it's shape be a tiny sphere at origin
_emptyShape.setTranslation(glm::vec3(0.0f, 0.0f, 0.0f));
@ -70,8 +71,8 @@ EntityItemProperties LightEntityItem::getProperties() const {
return properties;
}
bool LightEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
bool LightEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isSpotlight, setIsSpotlight);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(diffuseColor, setDiffuseColor);

View file

@ -28,7 +28,7 @@ public:
// methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties() const;
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
virtual bool setProperties(const EntityItemProperties& properties);
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
@ -99,6 +99,9 @@ public:
void setCutoff(float value) { _cutoff = value; }
virtual const Shape& getCollisionShapeInMeters() const { return _emptyShape; }
static bool getLightsArePickable() { return _lightsArePickable; }
static void setLightsArePickable(bool value) { _lightsArePickable = value; }
protected:
virtual void recalculateCollisionShape() { /* nothing to do */ }
@ -116,6 +119,8 @@ protected:
// used for collision detection
SphereShape _emptyShape;
static bool _lightsArePickable;
};
#endif // hifi_LightEntityItem_h

View file

@ -34,7 +34,7 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI
EntityItem(entityItemID, properties)
{
_type = EntityTypes::Model;
setProperties(properties, true);
setProperties(properties);
_lastAnimated = usecTimestampNow();
_jointMappingCompleted = false;
_color[0] = _color[1] = _color[2] = 0;
@ -55,9 +55,9 @@ EntityItemProperties ModelEntityItem::getProperties() const {
return properties;
}
bool ModelEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(modelURL, setModelURL);

View file

@ -26,7 +26,7 @@ public:
// methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties() const;
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
virtual bool setProperties(const EntityItemProperties& properties);
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;

View file

@ -31,7 +31,7 @@ SphereEntityItem::SphereEntityItem(const EntityItemID& entityItemID, const Entit
EntityItem(entityItemID, properties)
{
_type = EntityTypes::Sphere;
setProperties(properties, true);
setProperties(properties);
}
EntityItemProperties SphereEntityItem::getProperties() const {
@ -40,8 +40,8 @@ EntityItemProperties SphereEntityItem::getProperties() const {
return properties;
}
bool SphereEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
bool SphereEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);

View file

@ -25,7 +25,7 @@ public:
// methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties() const;
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
virtual bool setProperties(const EntityItemProperties& properties);
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;

View file

@ -37,7 +37,7 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityIte
{
_type = EntityTypes::Text;
_created = properties.getCreated();
setProperties(properties, true);
setProperties(properties);
}
void TextEntityItem::setDimensions(const glm::vec3& value) {
@ -57,9 +57,9 @@ EntityItemProperties TextEntityItem::getProperties() const {
return properties;
}
bool TextEntityItem::setProperties(const EntityItemProperties& properties, bool forceCopy) {
bool TextEntityItem::setProperties(const EntityItemProperties& properties) {
bool somethingChanged = false;
somethingChanged = EntityItem::setProperties(properties, forceCopy); // set the properties in our base class
somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
SET_ENTITY_PROPERTY_FROM_PROPERTIES(text, setText);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineHeight, setLineHeight);

View file

@ -27,7 +27,7 @@ public:
// methods for getting/setting all properties of an entity
virtual EntityItemProperties getProperties() const;
virtual bool setProperties(const EntityItemProperties& properties, bool forceCopy = false);
virtual bool setProperties(const EntityItemProperties& properties);
// TODO: eventually only include properties changed since the params.lastViewFrustumSent time
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;

View file

@ -9,7 +9,7 @@ link_hifi_libraries(shared networking octree voxels)
find_package(ZLIB REQUIRED)
include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
list(APPEND ${TARGET_NAME}_LIBRARIES_TO_LINK "${ZLIB_LIBRARIES}")
target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES})
# call macro to link our dependencies and bubble them up via a property on our target
link_shared_dependencies()

View file

@ -6,13 +6,32 @@ setup_hifi_library()
include_glm()
link_hifi_libraries(shared)
if (APPLE)
# link in required OS X frameworks and include the right GL headers
find_library(OpenGL OpenGL)
target_link_libraries(${TARGET_NAME} ${OpenGL})
else (APPLE)
elseif (WIN32)
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
# we're using static GLEW, so define GLEW_STATIC
add_definitions(-DGLEW_STATIC)
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" opengl32.lib)
# need to bubble up the GLEW_INCLUDE_DIRS
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${GLEW_INCLUDE_DIRS}")
# try to find the Nsight package and add it to the build if we find it
find_package(NSIGHT)
if (NSIGHT_FOUND)
include_directories(${NSIGHT_INCLUDE_DIRS})
add_definitions(-DNSIGHT_FOUND)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
else ()
find_package(OpenGL REQUIRED)
if (${OPENGL_INCLUDE_DIR})
@ -21,25 +40,8 @@ else (APPLE)
target_link_libraries(${TARGET_NAME} "${OPENGL_LIBRARY}")
# link target to external libraries
if (WIN32)
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
# we're using static GLEW, so define GLEW_STATIC
add_definitions(-DGLEW_STATIC)
target_link_libraries(${TARGET_NAME} "${GLEW_LIBRARIES}" "${NSIGHT_LIBRARIES}" opengl32.lib)
# try to find the Nsight package and add it to the build if we find it
find_package(NSIGHT)
if (NSIGHT_FOUND)
include_directories(${NSIGHT_INCLUDE_DIRS})
add_definitions(-DNSIGHT_FOUND)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
endif()
# need to bubble up the OPENGL_INCLUDE_DIR
list(APPEND ${TARGET_NAME}_DEPENDENCY_INCLUDES "${OPENGL_INCLUDE_DIR}")
endif (APPLE)
# call macro to link our dependencies and bubble them up via a property on our target

View file

@ -0,0 +1,25 @@
//
// GPUConfig.h
// libraries/gpu/src/gpu
//
// Created by Brad Hefta-Gaub on 12/17/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef gpu__GLUTConfig__
#define gpu__GLUTConfig__
// TODO: remove these once we migrate away from GLUT calls
#if defined(__APPLE__)
#include <GLUT/glut.h>
#elif defined(WIN32)
#include <GL/glut.h>
#else
#include <GL/glut.h>
#endif
#endif // gpu__GLUTConfig__

View file

@ -42,21 +42,24 @@ SharedObjectPointer MetavoxelClientManager::findFirstRaySpannerIntersection(cons
const glm::vec3& direction, const AttributePointer& attribute, float& distance) {
SharedObjectPointer closestSpanner;
float closestDistance = FLT_MAX;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([&](const SharedNodePointer& node){
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
if (client) {
float clientDistance;
SharedObjectPointer clientSpanner = client->getDataCopy().findFirstRaySpannerIntersection(
origin, direction, attribute, clientDistance);
origin, direction, attribute, clientDistance
);
if (clientSpanner && clientDistance < closestDistance) {
closestSpanner = clientSpanner;
closestDistance = clientDistance;
}
}
}
}
});
if (closestSpanner) {
distance = closestDistance;
}
@ -183,7 +186,7 @@ MetavoxelClient* MetavoxelClientManager::createClient(const SharedNodePointer& n
}
void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
NodeList::getInstance()->eachNode([&visitor](const SharedNodePointer& node){
if (node->getType() == NodeType::MetavoxelServer) {
QMutexLocker locker(&node->getMutex());
MetavoxelClient* client = static_cast<MetavoxelClient*>(node->getLinkedData());
@ -191,7 +194,7 @@ void MetavoxelClientManager::guide(MetavoxelVisitor& visitor) {
client->getDataCopy().guide(visitor);
}
}
}
});
}
MetavoxelUpdater::MetavoxelUpdater(MetavoxelClientManager* clientManager) :

Some files were not shown because too many files have changed in this diff Show more