mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
merge upstream, avatar can now fall onto a cube
This commit is contained in:
commit
8eec66c066
108 changed files with 881 additions and 1683 deletions
6
BUILD.md
6
BUILD.md
|
@ -14,12 +14,10 @@
|
|||
* [gverb](https://github.com/highfidelity/gverb)
|
||||
* [Soxr](http://sourceforge.net/projects/soxr/) ~> 0.1.1
|
||||
|
||||
The following external projects are optional dependencies. You can indicate to CMake that you would like to include them by passing -DGET_$NAME=1 when running a clean CMake build. For example, to get CMake to download and compile QXmpp you would pass -DGET_QXMPP=1.
|
||||
The following external projects are optional dependencies. You can indicate to CMake that you would like to include them by passing -DGET_$NAME=1 when running a clean CMake build. For example, to get CMake to download and compile SDL2 you would pass -DGET_SDL2=1.
|
||||
|
||||
* [SDL2](https://www.libsdl.org/download-2.0.php) ~> 2.0.3
|
||||
* Enables game controller support in Interface
|
||||
* [QXmpp](https://github.com/qxmpp-project/qxmpp) ~> 0.7.6
|
||||
* Enables text chat support in Interface
|
||||
|
||||
The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build-ext` directory in each of the subfolders for each external project.
|
||||
|
||||
|
@ -77,5 +75,5 @@ In the examples below the variable $NAME would be replaced by the name of the de
|
|||
|
||||
####Devices
|
||||
|
||||
You can support external input/output devices such as Oculus Rift, Leap Motion, 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.
|
||||
You can support external input/output devices such as Oculus Rift, Leap Motion, Faceshift, 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.
|
||||
|
||||
|
|
|
@ -14,18 +14,14 @@ Or you can start a regular command prompt and then run:
|
|||
|
||||
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`.
|
||||
|
||||
####nmake & msbuild
|
||||
####nmake
|
||||
|
||||
Some of the external projects may require nmake and msbuild to compile and install. If they are not installed at the locations listed below, please ensure that both are in your PATH so CMake can find them when required.
|
||||
Some of the external projects may require nmake to compile and install. If it is not installed at the location listed below, please ensure that it is in your PATH so CMake can find it when required.
|
||||
|
||||
We expect nmake.exe to be located at the following path.
|
||||
|
||||
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin
|
||||
|
||||
We expect msbuild.exe to be located at the following path.
|
||||
|
||||
C:\Program Files (x86)\MSBUILD\12.0\Bin
|
||||
|
||||
###Qt
|
||||
You can use the online installer or the offline installer. If you use the offline installer, be sure to select the "OpenGL" version.
|
||||
|
||||
|
|
|
@ -164,7 +164,6 @@ if (WIN32)
|
|||
endif ()
|
||||
|
||||
option(GET_SDL2 "Get SDL2 library automatically as external project" 0)
|
||||
option(GET_QXMPP "GET Qxmpp library automatically as external project" 0)
|
||||
|
||||
if (WIN32)
|
||||
add_paths_to_fixup_libs("${QT_DIR}/bin")
|
||||
|
|
|
@ -44,7 +44,7 @@ Agent::Agent(const QByteArray& packet) :
|
|||
// be the parent of the script engine so it gets moved when we do
|
||||
_scriptEngine.setParent(this);
|
||||
|
||||
_scriptEngine.getEntityScriptingInterface()->setPacketSender(&_entityEditSender);
|
||||
DependencyManager::get<EntityScriptingInterface>()->setPacketSender(&_entityEditSender);
|
||||
|
||||
DependencyManager::set<ResouceCacheSharedItems>();
|
||||
DependencyManager::set<SoundCache>();
|
||||
|
@ -68,8 +68,8 @@ void Agent::readPendingDatagrams() {
|
|||
// PacketType_JURISDICTION, first byte is the node type...
|
||||
switch (receivedPacket[headerBytes]) {
|
||||
case NodeType::EntityServer:
|
||||
_scriptEngine.getEntityScriptingInterface()->getJurisdictionListener()->
|
||||
queueReceivedPacket(matchedNode, receivedPacket);
|
||||
DependencyManager::get<EntityScriptingInterface>()->getJurisdictionListener()->
|
||||
queueReceivedPacket(matchedNode, receivedPacket);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -211,10 +211,12 @@ void Agent::run() {
|
|||
|
||||
_scriptEngine.registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
|
||||
_scriptEngine.registerGlobalObject("EntityViewer", &_entityViewer);
|
||||
_entityViewer.setJurisdictionListener(_scriptEngine.getEntityScriptingInterface()->getJurisdictionListener());
|
||||
_entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
|
||||
_entityViewer.init();
|
||||
_scriptEngine.getEntityScriptingInterface()->setEntityTree(_entityViewer.getTree());
|
||||
entityScriptingInterface->setEntityTree(_entityViewer.getTree());
|
||||
|
||||
_scriptEngine.setScriptContents(scriptContents);
|
||||
_scriptEngine.run();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <Assignment.h>
|
||||
#include <EntityScriptingInterface.h>
|
||||
#include <LogHandler.h>
|
||||
#include <LogUtils.h>
|
||||
#include <LimitedNodeList.h>
|
||||
|
@ -53,6 +54,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
|
|||
DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
|
||||
auto addressManager = DependencyManager::set<AddressManager>();
|
||||
auto nodeList = DependencyManager::set<NodeList>(NodeType::Unassigned);
|
||||
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
|
||||
|
||||
// make up a uuid for this child so the parent can tell us apart. This id will be changed
|
||||
// when the domain server hands over an assignment.
|
||||
|
|
|
@ -47,7 +47,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen
|
|||
|
||||
connect(&nodeList->getNodeSocket(), &QUdpSocket::readyRead, this, &AssignmentClientMonitor::readPendingDatagrams);
|
||||
|
||||
nodeList->putLocalPortIntoSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, this);
|
||||
nodeList->putLocalPortIntoSharedMemory(ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY, this,
|
||||
nodeList->getNodeSocket().localPort());
|
||||
|
||||
// use QProcess to fork off a process for each of the child assignment clients
|
||||
for (unsigned int i = 0; i < _numAssignmentClientForks; i++) {
|
||||
|
|
47
cmake/externals/bullet/CMakeLists.txt
vendored
47
cmake/externals/bullet/CMakeLists.txt
vendored
|
@ -14,21 +14,12 @@ endif ()
|
|||
|
||||
include(ExternalProject)
|
||||
|
||||
if (WIN32)
|
||||
if (UPPER_CMAKE_BUILD_TYPE MATCHES DEBUG)
|
||||
set(MSBUILD_CONFIGURATION Debug)
|
||||
else ()
|
||||
set(MSBUILD_CONFIGURATION Release)
|
||||
endif ()
|
||||
|
||||
find_program(MSBUILD_COMMAND msbuild PATHS "C:/Program Files (x86)/MSBUILD/12.0/Bin")
|
||||
|
||||
if (WIN32)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://bullet.googlecode.com/files/bullet-2.82-r2704.zip
|
||||
URL_MD5 f5e8914fc9064ad32e0d62d19d33d977
|
||||
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0
|
||||
BUILD_COMMAND ${MSBUILD_COMMAND} ALL_BUILD.vcxproj /p:Configuration=${MSBUILD_CONFIGURATION}
|
||||
CMAKE_ARGS ${PLATFORM_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DBUILD_EXTRAS=0 -DINSTALL_LIBS=1 -DBUILD_DEMOS=0 -DUSE_GLUT=0
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
|
@ -66,28 +57,22 @@ elseif (WIN32)
|
|||
endif ()
|
||||
|
||||
if (DEFINED BULLET_LIB_EXT)
|
||||
if (NOT WIN32 OR UPPER_CMAKE_BUILD_TYPE MATCHES RELEASE)
|
||||
set(_PRESENT_LIB_TYPE RELEASE)
|
||||
set(_MISSING_LIB_TYPE DEBUG)
|
||||
else ()
|
||||
set(_PRESENT_LIB_TYPE DEBUG)
|
||||
set(_MISSING_LIB_TYPE RELEASE)
|
||||
set(_LIB_NAME_SUFFIX _Debug)
|
||||
endif ()
|
||||
set(_BULLET_LIB_PAIRS "DYNAMICS_LIBRARY\;BulletDynamics" "COLLISION_LIBRARY\;BulletCollision" "MATH_LIBRARY\;LinearMath" "SOFTBODY_LIBRARY\;BulletSoftBody")
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}BulletDynamics${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet dynamics ${_PRESENT_LIB_TYPE} library location")
|
||||
set(${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet dynamics ${_MISSING_LIB_TYPE} library location")
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_COLLISION_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}BulletCollision${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet collision ${_PRESENT_LIB_TYPE} library location")
|
||||
set(${EXTERNAL_NAME_UPPER}_COLLISION_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet collision ${_MISSING_LIB_TYPE} library location")
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_MATH_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}LinearMath${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet math ${_PRESENT_LIB_TYPE} library location")
|
||||
set(${EXTERNAL_NAME_UPPER}_MATH_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet math ${_MISSING_LIB_TYPE} library location")
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_SOFTBODY_LIBRARY_${_PRESENT_LIB_TYPE} ${BULLET_LIB_DIR}/${LIB_PREFIX}BulletSoftBody${_LIB_NAME_SUFFIX}.${BULLET_LIB_EXT} CACHE FILEPATH "Bullet softbody ${_PRESENT_LIB_TYPE} library location")
|
||||
set(${EXTERNAL_NAME_UPPER}_SOFTBODY_LIBRARY_${_MISSING_LIB_TYPE} "" CACHE FILEPATH "Bullet softbody ${_MISSING_LIB_TYPE} library location")
|
||||
foreach(_LIB_PAIR ${_BULLET_LIB_PAIRS})
|
||||
list(GET _LIB_PAIR 0 _LIB_VAR_NAME)
|
||||
list(GET _LIB_PAIR 1 _LIB_NAME)
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_${_LIB_VAR_NAME}_RELEASE ${BULLET_LIB_DIR}/${LIB_PREFIX}${_LIB_NAME}.${BULLET_LIB_EXT} CACHE FILEPATH "${_LIB_NAME} release library location")
|
||||
|
||||
if (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_${_LIB_VAR_NAME}_DEBUG ${BULLET_LIB_DIR}/${LIB_PREFIX}${_LIB_NAME}_Debug.${BULLET_LIB_EXT} CACHE FILEPATH "${_LIB_NAME} debug library location")
|
||||
else ()
|
||||
set(${EXTERNAL_NAME_UPPER}_${_LIB_VAR_NAME}_DEBUG "" CACHE FILEPATH "${_LIB_NAME} debug library location")
|
||||
endif ()
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
if (DEFINED ${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_${_PRESENT_LIB_TYPE})
|
||||
if (DEFINED ${EXTERNAL_NAME_UPPER}_DYNAMICS_LIBRARY_RELEASE)
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INSTALL_DIR}/include/bullet CACHE PATH "Path to bullet include directory")
|
||||
endif ()
|
2
cmake/externals/qxmpp/CMakeLists.txt
vendored
2
cmake/externals/qxmpp/CMakeLists.txt
vendored
|
@ -1,7 +1,7 @@
|
|||
set(EXTERNAL_NAME qxmpp)
|
||||
|
||||
# we need to find qmake inside QT_DIR
|
||||
find_program(QMAKE_COMMAND NAME qmake PATHS ${QT_DIR}/bin NO_DEFAULT_PATH)
|
||||
find_program(QMAKE_COMMAND NAME qmake PATHS ${QT_DIR}/bin $ENV{QTTOOLDIR} NO_DEFAULT_PATH)
|
||||
|
||||
if (NOT QMAKE_COMMAND)
|
||||
message(FATAL_ERROR "Could not find qmake. Qxmpp cannot be compiled without qmake.")
|
||||
|
|
13
cmake/externals/qxmpp/qxmpp.patch
vendored
13
cmake/externals/qxmpp/qxmpp.patch
vendored
|
@ -1,13 +0,0 @@
|
|||
diff --git a/qxmpp-0.7.6/src/src.pro b/qxmpp-0.7.6-patch/src/src.pro
|
||||
index 954738c..8404c8c 100644
|
||||
--- a/qxmpp-0.7.6/src/src.pro
|
||||
+++ b/qxmpp-0.7.6-patch/src/src.pro
|
||||
@@ -4,7 +4,7 @@ QT -= gui
|
||||
|
||||
TEMPLATE = lib
|
||||
|
||||
-CONFIG += $$QXMPP_LIBRARY_TYPE
|
||||
+CONFIG += $$QXMPP_LIBRARY_TYPE c++11
|
||||
DEFINES += QXMPP_BUILD
|
||||
DEFINES += $$QXMPP_INTERNAL_DEFINES
|
||||
INCLUDEPATH += $$QXMPP_INCLUDEPATH $$QXMPP_INTERNAL_INCLUDES
|
|
@ -15,12 +15,21 @@ function(AUTOSCRIBE_SHADER SHADER_FILE)
|
|||
list(APPEND SHADER_INCLUDE_FILES ${includeFile})
|
||||
endforeach()
|
||||
|
||||
#Extract the unique include shader paths
|
||||
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
|
||||
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
|
||||
endforeach()
|
||||
|
||||
|
||||
#Extract the unique include shader paths
|
||||
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
|
||||
#message(Hifi for includes ${INCLUDES})
|
||||
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
|
||||
#message(ready for includes ${SHADER_INCLUDES_PATHS})
|
||||
|
||||
# make the scribe include arguments
|
||||
set(SCRIBE_INCLUDES)
|
||||
|
@ -64,6 +73,17 @@ endfunction()
|
|||
|
||||
|
||||
macro(AUTOSCRIBE_SHADER_LIB)
|
||||
|
||||
file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
|
||||
foreach(HIFI_LIBRARY ${ARGN})
|
||||
#if (NOT TARGET ${HIFI_LIBRARY})
|
||||
# file(GLOB_RECURSE HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}/src/)
|
||||
#endif ()
|
||||
|
||||
#file(GLOB_RECURSE HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src/*.slh)
|
||||
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src)
|
||||
endforeach()
|
||||
#message(${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
|
||||
|
||||
file(GLOB_RECURSE SHADER_INCLUDE_FILES src/*.slh)
|
||||
file(GLOB_RECURSE SHADER_SOURCE_FILES src/*.slv src/*.slf)
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# Try to find the PrioVR library
|
||||
#
|
||||
# You must provide a PRIOVR_ROOT_DIR which contains lib and include directories
|
||||
#
|
||||
# Once done this will define
|
||||
#
|
||||
# PRIOVR_FOUND - system found PrioVR
|
||||
# PRIOVR_INCLUDE_DIRS - the PrioVR include directory
|
||||
# PRIOVR_LIBRARIES - Link this to use PrioVR
|
||||
#
|
||||
# Created on 5/12/2014 by Andrzej Kapolka
|
||||
# Copyright (c) 2014 High Fidelity
|
||||
#
|
||||
|
||||
find_path(PRIOVR_INCLUDE_DIRS yei_skeletal_api.h ${PRIOVR_ROOT_DIR}/include)
|
||||
|
||||
if (WIN32)
|
||||
find_library(PRIOVR_LIBRARIES Skeletal_API.lib ${PRIOVR_ROOT_DIR}/lib)
|
||||
endif (WIN32)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(PrioVR DEFAULT_MSG PRIOVR_INCLUDE_DIRS PRIOVR_LIBRARIES)
|
||||
|
||||
mark_as_advanced(PRIOVR_INCLUDE_DIRS PRIOVR_LIBRARIES)
|
|
@ -1,45 +0,0 @@
|
|||
#
|
||||
# FindQxmpp.cmake
|
||||
#
|
||||
# Try to find the qxmpp library
|
||||
#
|
||||
# You can provide a QXMPP_ROOT_DIR which contains lib and include directories
|
||||
#
|
||||
# Once done this will define
|
||||
#
|
||||
# QXMPP_FOUND - system found qxmpp
|
||||
# QXMPP_INCLUDE_DIRS - the qxmpp include directory
|
||||
# QXMPP_LIBRARIES - Link this to use qxmpp
|
||||
#
|
||||
# Created on 3/10/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("qxmpp")
|
||||
|
||||
find_path(QXMPP_INCLUDE_DIRS qxmpp/QXmppClient.h PATH_SUFFIXES include HINTS ${QXMPP_SEARCH_DIRS})
|
||||
|
||||
find_library(QXMPP_LIBRARY_RELEASE NAMES qxmpp PATH_SUFFIXES lib HINTS ${QXMPP_SEARCH_DIRS})
|
||||
find_library(QXMPP_LIBRARY_DEBUG NAMES qxmpp_d PATH_SUFFIXES lib HINTS ${QXMPP_SEARCH_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
find_path(QXMPP_DLL_PATH NAMES qxmpp.dll PATH_SUFFIXES lib HINTS ${QXMPP_SEARCH_DIRS})
|
||||
endif ()
|
||||
|
||||
find_package(Qt5 COMPONENTS Xml REQUIRED)
|
||||
|
||||
include(SelectLibraryConfigurations)
|
||||
select_library_configurations(QXMPP)
|
||||
|
||||
set(QXMPP_LIBRARIES "${QXMPP_LIBRARY}" Qt5::Xml)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(QXmpp DEFAULT_MSG QXMPP_INCLUDE_DIRS QXMPP_LIBRARIES QXMPP_LIBRARY)
|
||||
|
||||
if (QXMPP_DLL_PATH)
|
||||
add_paths_to_fixup_libs(${QXMPP_DLL_PATH})
|
||||
endif ()
|
|
@ -247,7 +247,14 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
|||
auto nodeList = DependencyManager::set<LimitedNodeList>(domainServerPort, domainServerDTLSPort);
|
||||
|
||||
// no matter the local port, save it to shared mem so that local assignment clients can ask what it is
|
||||
nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this);
|
||||
nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, nodeList->getNodeSocket().localPort());
|
||||
|
||||
// store our local http ports in shared memory
|
||||
quint16 localHttpPort = DOMAIN_SERVER_HTTP_PORT;
|
||||
nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_HTTP_PORT_SMEM_KEY, this, localHttpPort);
|
||||
quint16 localHttpsPort = DOMAIN_SERVER_HTTPS_PORT;
|
||||
nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_HTTPS_PORT_SMEM_KEY, this, localHttpsPort);
|
||||
|
||||
|
||||
// set our LimitedNodeList UUID to match the UUID from our config
|
||||
// nodes will currently use this to add resources to data-web that relate to our domain
|
||||
|
|
|
@ -81,6 +81,8 @@ var SETTING_INSPECT_TOOL_ENABLED = "inspectToolEnabled";
|
|||
var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect";
|
||||
var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
|
||||
|
||||
var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to edit on this domain."
|
||||
|
||||
var modelURLs = [
|
||||
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Alder.fbx",
|
||||
HIFI_PUBLIC_BUCKET + "models/entities/2-Terrain:%20Bush1.fbx",
|
||||
|
@ -177,25 +179,29 @@ var toolBar = (function () {
|
|||
|
||||
that.setActive = function(active) {
|
||||
if (active != isActive) {
|
||||
isActive = active;
|
||||
if (!isActive) {
|
||||
entityListTool.setVisible(false);
|
||||
gridTool.setVisible(false);
|
||||
grid.setEnabled(false);
|
||||
propertiesTool.setVisible(false);
|
||||
selectionManager.clearSelections();
|
||||
cameraManager.disable();
|
||||
if (active && !Entities.canAdjustLocks()) {
|
||||
Window.alert(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
|
||||
} else {
|
||||
hasShownPropertiesTool = false;
|
||||
cameraManager.enable();
|
||||
entityListTool.setVisible(true);
|
||||
gridTool.setVisible(true);
|
||||
grid.setEnabled(true);
|
||||
propertiesTool.setVisible(true);
|
||||
Window.setFocus();
|
||||
isActive = active;
|
||||
if (!isActive) {
|
||||
entityListTool.setVisible(false);
|
||||
gridTool.setVisible(false);
|
||||
grid.setEnabled(false);
|
||||
propertiesTool.setVisible(false);
|
||||
selectionManager.clearSelections();
|
||||
cameraManager.disable();
|
||||
} else {
|
||||
hasShownPropertiesTool = false;
|
||||
cameraManager.enable();
|
||||
entityListTool.setVisible(true);
|
||||
gridTool.setVisible(true);
|
||||
grid.setEnabled(true);
|
||||
propertiesTool.setVisible(true);
|
||||
Window.setFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
toolBar.selectTool(activeButton, active);
|
||||
toolBar.selectTool(activeButton, isActive);
|
||||
};
|
||||
|
||||
var RESIZE_INTERVAL = 50;
|
||||
|
@ -400,6 +406,12 @@ var toolBar = (function () {
|
|||
that.setActive(false);
|
||||
});
|
||||
|
||||
Entities.canAdjustLocksChanged.connect(function(canAdjustLocks) {
|
||||
if (isActive && !canAdjustLocks) {
|
||||
that.setActive(false);
|
||||
}
|
||||
});
|
||||
|
||||
that.cleanup = function () {
|
||||
toolBar.cleanup();
|
||||
};
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
//
|
||||
// globalServicesExample.js
|
||||
// examples
|
||||
//
|
||||
// Created by Thijs Wenker on 9/12/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Example usage of the GlobalServices object. You could use it to make your own chatbox.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
function onConnected() {
|
||||
if (GlobalServices.onlineUsers.length > 0) {
|
||||
sendMessageForm()
|
||||
return;
|
||||
}
|
||||
Script.setTimeout(function() { sendMessageForm(); }, 5000);
|
||||
}
|
||||
|
||||
function onDisconnected(reason) {
|
||||
switch(reason) {
|
||||
case "logout":
|
||||
Window.alert("logged out!");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function onOnlineUsersChanged(users) {
|
||||
print(users);
|
||||
}
|
||||
|
||||
function onIncommingMessage(user, message) {
|
||||
print(user + ": " + message);
|
||||
if (message === "hello") {
|
||||
GlobalServices.chat("hello, @" + user + "!");
|
||||
}
|
||||
}
|
||||
|
||||
function sendMessageForm() {
|
||||
var form =
|
||||
[
|
||||
{ label: "To:", options: ["(noone)"].concat(GlobalServices.onlineUsers) },
|
||||
{ label: "Message:", value: "Enter message here" }
|
||||
];
|
||||
if (Window.form("Send message on public chat", form)) {
|
||||
GlobalServices.chat(form[0].value == "(noone)" ? form[1].value : "@" + form[0].value + ", " + form[1].value);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GlobalServices.connected.connect(onConnected);
|
||||
GlobalServices.disconnected.connect(onDisconnected);
|
||||
GlobalServices.onlineUsersChanged.connect(onOnlineUsersChanged);
|
||||
GlobalServices.incomingMessage.connect(onIncommingMessage);
|
|
@ -1,27 +0,0 @@
|
|||
//
|
||||
// loadScriptFromMessage.js
|
||||
// examples
|
||||
//
|
||||
// Created by Thijs Wenker on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Filters script links out of incomming messages and prompts you to run the script.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
//Javascript link RegEX
|
||||
const JS_LINK_REGEX = /https?:\/\/[^ ]+\.js/i;
|
||||
|
||||
function onIncomingMessage(user, message) {
|
||||
var script_link = JS_LINK_REGEX.exec(message);
|
||||
if (script_link == null) {
|
||||
return;
|
||||
}
|
||||
if (Window.confirm("@" + user + " sent the following script:\n" + script_link + "\nwould you like to run it?")) {
|
||||
Script.load(script_link);
|
||||
}
|
||||
}
|
||||
|
||||
GlobalServices.incomingMessage.connect(onIncomingMessage);
|
|
@ -14,32 +14,28 @@
|
|||
// This script generates notifications created via a number of ways, such as:
|
||||
// keystroke:
|
||||
//
|
||||
// "q" returns number of users currently online (for debug purposes)
|
||||
|
||||
// CTRL/s for snapshot.
|
||||
// CTRL/m for mic mute and unmute.
|
||||
|
||||
// System generated notifications:
|
||||
// Displays users online at startup.
|
||||
// If Screen is resized.
|
||||
// Triggers notification if @MyUserName is mentioned in chat.
|
||||
// Announces existing user logging out.
|
||||
// Announces new user logging in.
|
||||
// If mic is muted for any reason.
|
||||
//
|
||||
// To add a new System notification type:
|
||||
//
|
||||
// 1. Set the Event Connector at the bottom of the script.
|
||||
// example:
|
||||
// GlobalServices.incomingMessage.connect(onIncomingMessage);
|
||||
// AudioDevice.muteToggled.connect(onMuteStateChanged);
|
||||
//
|
||||
// 2. Create a new function to produce a text string, do not include new line returns.
|
||||
// example:
|
||||
// function onIncomingMessage(user, message) {
|
||||
// //do stuff here;
|
||||
// var text = "This is a notification";
|
||||
// var wrappedText = wordWrap(text);
|
||||
// createNotification(wrappedText, NotificationType.SNAPSHOT);
|
||||
// function onMuteStateChanged() {
|
||||
// var muteState,
|
||||
// muteString;
|
||||
//
|
||||
// muteState = AudioDevice.getMuted() ? "muted" : "unmuted";
|
||||
// muteString = "Microphone is now " + muteState;
|
||||
// createNotification(muteString, NotificationType.MUTE_TOGGLE);
|
||||
// }
|
||||
//
|
||||
// This new function must call wordWrap(text) if the length of message is longer than 42 chars or unknown.
|
||||
|
@ -54,11 +50,12 @@
|
|||
// 2. Declare a text string.
|
||||
// 3. Call createNotifications(text, NotificationType) parsing the text.
|
||||
// example:
|
||||
// var welcome;
|
||||
// if (key.text == "q") { //queries number of users online
|
||||
// var welcome = "There are " + GlobalServices.onlineUsers.length + " users online now.";
|
||||
// createNotification(welcome, NotificationType.USERS_ONLINE);
|
||||
// }
|
||||
// if (key.text === "s") {
|
||||
// if (ctrlIsPressed === true) {
|
||||
// noteString = "Snapshot taken.";
|
||||
// createNotification(noteString, NotificationType.SNAPSHOT);
|
||||
// }
|
||||
// }
|
||||
Script.include("./libraries/globals.js");
|
||||
Script.include("./libraries/soundArray.js");
|
||||
|
||||
|
@ -81,8 +78,6 @@ var frame = 0;
|
|||
var ourWidth = Window.innerWidth;
|
||||
var ourHeight = Window.innerHeight;
|
||||
var text = "placeholder";
|
||||
var last_users = GlobalServices.onlineUsers;
|
||||
var users = [];
|
||||
var ctrlIsPressed = false;
|
||||
var ready = true;
|
||||
var MENU_NAME = 'Tools > Notifications';
|
||||
|
@ -93,19 +88,11 @@ var PLAY_NOTIFICATION_SOUNDS_TYPE_SETTING_PRE = "play_notification_sounds_type_"
|
|||
|
||||
var NotificationType = {
|
||||
UNKNOWN: 0,
|
||||
USER_JOINS: 1,
|
||||
USER_LEAVES: 2,
|
||||
MUTE_TOGGLE: 3,
|
||||
CHAT_MENTION: 4,
|
||||
USERS_ONLINE: 5,
|
||||
SNAPSHOT: 6,
|
||||
WINDOW_RESIZE: 7,
|
||||
MUTE_TOGGLE: 1,
|
||||
SNAPSHOT: 2,
|
||||
WINDOW_RESIZE: 3,
|
||||
properties: [
|
||||
{ text: "User Join" },
|
||||
{ text: "User Leave" },
|
||||
{ text: "Mute Toggle" },
|
||||
{ text: "Chat Mention" },
|
||||
{ text: "Users Online" },
|
||||
{ text: "Snapshot" },
|
||||
{ text: "Window Resize" }
|
||||
],
|
||||
|
@ -476,15 +463,9 @@ var STARTUP_TIMEOUT = 500, // ms
|
|||
startingUp = true,
|
||||
startupTimer = null;
|
||||
|
||||
// This reports the number of users online at startup
|
||||
function reportUsers() {
|
||||
createNotification("Welcome! There are " + GlobalServices.onlineUsers.length + " users online now.", NotificationType.USERS_ONLINE);
|
||||
}
|
||||
|
||||
function finishStartup() {
|
||||
startingUp = false;
|
||||
Script.clearTimeout(startupTimer);
|
||||
reportUsers();
|
||||
}
|
||||
|
||||
function isStartingUp() {
|
||||
|
@ -498,42 +479,6 @@ function isStartingUp() {
|
|||
return startingUp;
|
||||
}
|
||||
|
||||
// Triggers notification if a user logs on or off
|
||||
function onOnlineUsersChanged(users) {
|
||||
var i;
|
||||
|
||||
if (!isStartingUp()) { // Skip user notifications at startup.
|
||||
for (i = 0; i < users.length; i += 1) {
|
||||
if (last_users.indexOf(users[i]) === -1.0) {
|
||||
createNotification(users[i] + " has joined", NotificationType.USER_JOINS);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < last_users.length; i += 1) {
|
||||
if (users.indexOf(last_users[i]) === -1.0) {
|
||||
createNotification(last_users[i] + " has left", NotificationType.USER_LEAVES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_users = users;
|
||||
}
|
||||
|
||||
// Triggers notification if @MyUserName is mentioned in chat and returns the message to the notification.
|
||||
function onIncomingMessage(user, message) {
|
||||
var myMessage,
|
||||
alertMe,
|
||||
thisAlert;
|
||||
|
||||
myMessage = message;
|
||||
alertMe = "@" + GlobalServices.myUsername;
|
||||
thisAlert = user + ": " + myMessage;
|
||||
|
||||
if (myMessage.indexOf(alertMe) > -1.0) {
|
||||
CreateNotification(wordWrap(thisAlert), NotificationType.CHAT_MENTION);
|
||||
}
|
||||
}
|
||||
|
||||
// Triggers mic mute notification
|
||||
function onMuteStateChanged() {
|
||||
var muteState,
|
||||
|
@ -573,20 +518,12 @@ function keyReleaseEvent(key) {
|
|||
|
||||
// Triggers notification on specific key driven events
|
||||
function keyPressEvent(key) {
|
||||
var numUsers,
|
||||
welcome,
|
||||
noteString;
|
||||
var noteString;
|
||||
|
||||
if (key.key === 16777249) {
|
||||
ctrlIsPressed = true;
|
||||
}
|
||||
|
||||
if (key.text === "q") { //queries number of users online
|
||||
numUsers = GlobalServices.onlineUsers.length;
|
||||
welcome = "There are " + numUsers + " users online now.";
|
||||
createNotification(welcome, NotificationType.USERS_ONLINE);
|
||||
}
|
||||
|
||||
if (key.text === "s") {
|
||||
if (ctrlIsPressed === true) {
|
||||
noteString = "Snapshot taken.";
|
||||
|
@ -641,8 +578,6 @@ function menuItemEvent(menuItem) {
|
|||
AudioDevice.muteToggled.connect(onMuteStateChanged);
|
||||
Controller.keyPressEvent.connect(keyPressEvent);
|
||||
Controller.mousePressEvent.connect(mousePressEvent);
|
||||
GlobalServices.onlineUsersChanged.connect(onOnlineUsersChanged);
|
||||
GlobalServices.incomingMessage.connect(onIncomingMessage);
|
||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||
Script.update.connect(update);
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
|
|
@ -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" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "RSSDK")
|
||||
set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "Sixense" "LeapMotion" "RtMidi" "SDL2" "RSSDK")
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||
|
@ -119,7 +119,7 @@ link_hifi_libraries(shared octree environment gpu model fbx metavoxels networkin
|
|||
audio audio-client animation script-engine physics
|
||||
render-utils entities-renderer)
|
||||
|
||||
add_dependency_external_projects(sdl2 qxmpp)
|
||||
add_dependency_external_projects(sdl2)
|
||||
|
||||
# perform standard include and linking for found externals
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
|
@ -175,16 +175,6 @@ if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI AND APPLE)
|
|||
target_link_libraries(${TARGET_NAME} ${CoreMIDI})
|
||||
endif ()
|
||||
|
||||
if (QXMPP_FOUND AND NOT DISABLE_QXMPP AND WIN32)
|
||||
if (NOT QXMPP_DLL_PATH)
|
||||
# if we have no QXmpp DLL path, assume we're linking a static QXmpp on windows
|
||||
add_definitions(-DQXMPP_STATIC)
|
||||
else ()
|
||||
# otherwise assume we are linking a dynamic QXmpp
|
||||
add_definitions(-DQXMPP_SHARED)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# include headers for interface and InterfaceConfig.
|
||||
include_directories("${PROJECT_SOURCE_DIR}/src" "${PROJECT_BINARY_DIR}/includes")
|
||||
|
||||
|
|
16
interface/external/priovr/readme.txt
vendored
16
interface/external/priovr/readme.txt
vendored
|
@ -1,16 +0,0 @@
|
|||
|
||||
Instructions for adding the PrioVR driver to Interface
|
||||
Andrzej Kapolka, May 12, 2014
|
||||
|
||||
1. Download and install the YEI drivers from https://www.yeitechnology.com/yei-3-space-sensor-software-suite. If using
|
||||
Window 8+, follow the workaround instructions at http://forum.yeitechnology.com/viewtopic.php?f=3&t=24.
|
||||
|
||||
2. Get the PrioVR skeleton API, open ts_c_api2_priovr2/visual_studio/ThreeSpace_API_2/ThreeSpace_API_2.sln
|
||||
in Visual Studio, and build it.
|
||||
|
||||
3. Copy ts_c_api2_priovr2/visual_studio/ThreeSpace_API_2/Skeletal_API/yei_skeletal_api.h to interface/external/priovr/include,
|
||||
ts_c_api2_priovr2/visual_studio/ThreeSpace_API_2/Debug/Skeletal_API.lib to interface/external/priovr/lib, and
|
||||
ts_c_api2_priovr2/visual_studio/ThreeSpace_API_2/Debug/*.dll to your path.
|
||||
|
||||
4. Delete your build directory, run cmake and build, and you should be all set.
|
||||
|
|
@ -241,6 +241,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
auto dialogsManager = DependencyManager::set<DialogsManager>();
|
||||
auto bandwidthRecorder = DependencyManager::set<BandwidthRecorder>();
|
||||
auto resouceCacheSharedItems = DependencyManager::set<ResouceCacheSharedItems>();
|
||||
auto entityScriptingInterface = DependencyManager::set<EntityScriptingInterface>();
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
auto speechRecognizer = DependencyManager::set<SpeechRecognizer>();
|
||||
#endif
|
||||
|
@ -1141,6 +1142,10 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Comma: {
|
||||
_myAvatar->togglePhysicsEnabled();
|
||||
}
|
||||
|
||||
default:
|
||||
event->ignore();
|
||||
|
@ -1766,10 +1771,14 @@ void Application::init() {
|
|||
tree->setSimulation(&_physicsEngine);
|
||||
_physicsEngine.init(&_entityEditSender);
|
||||
|
||||
|
||||
_physicsEngine.setAvatarData(_myAvatar);
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
|
||||
|
||||
connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity,
|
||||
ScriptEngine::getEntityScriptingInterface(), &EntityScriptingInterface::entityCollisionWithEntity);
|
||||
entityScriptingInterface.data(), &EntityScriptingInterface::entityCollisionWithEntity);
|
||||
|
||||
// connect the _entityCollisionSystem to our EntityTreeRenderer since that's what handles running entity scripts
|
||||
connect(&_physicsEngine, &EntitySimulation::entityCollisionWithEntity,
|
||||
|
@ -1777,7 +1786,7 @@ void Application::init() {
|
|||
|
||||
// connect the _entities (EntityTreeRenderer) to our script engine's EntityScriptingInterface for firing
|
||||
// of events related clicking, hovering over, and entering entities
|
||||
_entities.connectSignalsToSlots(ScriptEngine::getEntityScriptingInterface());
|
||||
_entities.connectSignalsToSlots(entityScriptingInterface.data());
|
||||
|
||||
_entityClipboardRenderer.init();
|
||||
_entityClipboardRenderer.setViewFrustum(getViewFrustum());
|
||||
|
@ -2047,7 +2056,6 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
SixenseManager::getInstance().update(deltaTime);
|
||||
JoystickScriptingInterface::getInstance().update();
|
||||
_prioVR.update(deltaTime);
|
||||
}
|
||||
|
||||
// Dispatch input events
|
||||
|
@ -2547,7 +2555,9 @@ void Application::updateShadowMap() {
|
|||
glm::ortho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z) * glm::mat4_cast(inverseRotation));
|
||||
|
||||
// update the shadow view frustum
|
||||
_shadowViewFrustum.setPosition(rotation * ((minima + maxima) * 0.5f));
|
||||
// glm::vec3 shadowFrustumCenter = glm::vec3((minima.x + maxima.x) * 0.5f, (minima.y + maxima.y) * 0.5f, (minima.z + maxima.z) * 0.5f);
|
||||
glm::vec3 shadowFrustumCenter = rotation * ((minima + maxima) * 0.5f);
|
||||
_shadowViewFrustum.setPosition(shadowFrustumCenter);
|
||||
_shadowViewFrustum.setOrientation(rotation);
|
||||
_shadowViewFrustum.setOrthographic(true);
|
||||
_shadowViewFrustum.setWidth(maxima.x - minima.x);
|
||||
|
@ -2577,8 +2587,10 @@ void Application::updateShadowMap() {
|
|||
// this is what is used for rendering the Entities and avatars
|
||||
Transform viewTransform;
|
||||
viewTransform.setRotation(rotation);
|
||||
// viewTransform.postTranslate(shadowFrustumCenter);
|
||||
setViewTransform(viewTransform);
|
||||
|
||||
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(1.1f, 4.0f); // magic numbers courtesy http://www.eecs.berkeley.edu/~ravir/6160/papers/shadowmaps.ppt
|
||||
|
||||
|
@ -3109,7 +3121,6 @@ void Application::resetSensors() {
|
|||
|
||||
OculusManager::reset();
|
||||
|
||||
_prioVR.reset();
|
||||
//_leapmotion.reset();
|
||||
|
||||
QScreen* currentScreen = _window->windowHandle()->screen();
|
||||
|
@ -3443,8 +3454,9 @@ void joystickFromScriptValue(const QScriptValue &object, Joystick* &out) {
|
|||
void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) {
|
||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||
// we can use the same ones from the application.
|
||||
scriptEngine->getEntityScriptingInterface()->setPacketSender(&_entityEditSender);
|
||||
scriptEngine->getEntityScriptingInterface()->setEntityTree(_entities.getTree());
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
entityScriptingInterface->setPacketSender(&_entityEditSender);
|
||||
entityScriptingInterface->setEntityTree(_entities.getTree());
|
||||
|
||||
// AvatarManager has some custom types
|
||||
AvatarManager::registerMetaTypes(scriptEngine);
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "Stars.h"
|
||||
#include "avatar/Avatar.h"
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include "devices/PrioVR.h"
|
||||
#include "devices/SixenseManager.h"
|
||||
#include "scripting/ControllerScriptingInterface.h"
|
||||
#include "ui/BandwidthDialog.h"
|
||||
|
@ -182,7 +181,6 @@ public:
|
|||
MetavoxelSystem* getMetavoxels() { return &_metavoxels; }
|
||||
EntityTreeRenderer* getEntities() { return &_entities; }
|
||||
Environment* getEnvironment() { return &_environment; }
|
||||
PrioVR* getPrioVR() { return &_prioVR; }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
MainWindow* getWindow() { return _window; }
|
||||
OctreeQuery& getOctreeQuery() { return _octreeQuery; }
|
||||
|
@ -490,8 +488,6 @@ private:
|
|||
|
||||
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
|
||||
|
||||
PrioVR _prioVR;
|
||||
|
||||
Camera _myCamera; // My view onto the world
|
||||
Camera _mirrorCamera; // Cammera for mirror view
|
||||
QRect _mirrorViewRect;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <PathUtils.h>
|
||||
#include <SettingHandle.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <XmppClient.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "AccountManager.h"
|
||||
|
@ -162,12 +161,9 @@ Menu::Menu() {
|
|||
SLOT(setEnabled(bool)));
|
||||
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
|
||||
addActionToQMenuAndActionHash(toolsMenu, MenuOption::Chat, Qt::Key_Backslash,
|
||||
dialogsManager.data(), SLOT(showChat()));
|
||||
dialogsManager->setupChat();
|
||||
#endif
|
||||
dialogsManager.data(), SLOT(showIRCLink()));
|
||||
|
||||
addActionToQMenuAndActionHash(toolsMenu,
|
||||
MenuOption::ToolWindow,
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
//
|
||||
// XmppClient.cpp
|
||||
// interface/src
|
||||
//
|
||||
// Created by Dimitar Dobrev on 10/3/14.
|
||||
// Copyright 2013 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 <AccountManager.h>
|
||||
|
||||
#include "XmppClient.h"
|
||||
|
||||
const QString DEFAULT_XMPP_SERVER = "chat.highfidelity.io";
|
||||
const QString DEFAULT_CHAT_ROOM = "public@public-chat.highfidelity.io";
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
XmppClient::XmppClient() :
|
||||
_xmppClient(),
|
||||
_xmppMUCManager()
|
||||
{
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
connect(&accountManager, SIGNAL(profileChanged()), this, SLOT(connectToServer()));
|
||||
connect(&accountManager, SIGNAL(logoutComplete()), this, SLOT(disconnectFromServer()));
|
||||
}
|
||||
#else
|
||||
XmppClient::XmppClient() {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
XmppClient& XmppClient::getInstance() {
|
||||
static XmppClient sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
void XmppClient::xmppConnected() {
|
||||
#ifdef HAVE_QXMPP
|
||||
_publicChatRoom = _xmppMUCManager.addRoom(DEFAULT_CHAT_ROOM);
|
||||
_publicChatRoom->setNickName(AccountManager::getInstance().getAccountInfo().getUsername());
|
||||
_publicChatRoom->join();
|
||||
emit joinedPublicChatRoom();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
void XmppClient::xmppError(QXmppClient::Error error) {
|
||||
qDebug() << "Error connnecting to XMPP for user "
|
||||
<< AccountManager::getInstance().getAccountInfo().getUsername() << ": " << error;
|
||||
}
|
||||
#endif
|
||||
|
||||
void XmppClient::connectToServer() {
|
||||
#ifdef HAVE_QXMPP
|
||||
disconnectFromServer();
|
||||
|
||||
if (_xmppClient.addExtension(&_xmppMUCManager)) {
|
||||
connect(&_xmppClient, SIGNAL(connected()), this, SLOT(xmppConnected()));
|
||||
connect(&_xmppClient, SIGNAL(error(QXmppClient::Error)), this, SLOT(xmppError(QXmppClient::Error)));
|
||||
}
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
QString user = accountManager.getAccountInfo().getUsername();
|
||||
const QString& password = accountManager.getAccountInfo().getXMPPPassword();
|
||||
_xmppClient.connectToServer(user + "@" + DEFAULT_XMPP_SERVER, password);
|
||||
#endif
|
||||
}
|
||||
|
||||
void XmppClient::disconnectFromServer() {
|
||||
#ifdef HAVE_QXMPP
|
||||
if (_xmppClient.isConnected()) {
|
||||
_xmppClient.disconnectFromServer();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
XmppClient::XmppClient(const XmppClient& other) {
|
||||
Q_UNUSED(other);
|
||||
}
|
||||
|
||||
void XmppClient::operator =(XmppClient const& other) {
|
||||
Q_UNUSED(other);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
//
|
||||
// XmppClient.h
|
||||
// interface/src
|
||||
//
|
||||
// Created by Dimitar Dobrev on 10/3/14.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_XmppClient_h
|
||||
#define hifi_XmppClient_h
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
#include <qxmpp/QXmppClient.h>
|
||||
#include <qxmpp/QXmppMucManager.h>
|
||||
#endif
|
||||
|
||||
/// Generalized threaded processor for handling received inbound packets.
|
||||
class XmppClient : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static XmppClient& getInstance();
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
QXmppClient& getXMPPClient() { return _xmppClient; }
|
||||
const QXmppMucRoom* getPublicChatRoom() const { return _publicChatRoom; }
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void joinedPublicChatRoom();
|
||||
|
||||
private slots:
|
||||
void xmppConnected();
|
||||
#ifdef HAVE_QXMPP
|
||||
void xmppError(QXmppClient::Error error);
|
||||
#endif
|
||||
|
||||
void connectToServer();
|
||||
void disconnectFromServer();
|
||||
|
||||
private:
|
||||
XmppClient();
|
||||
XmppClient(XmppClient const& other); // not implemented
|
||||
void operator=(XmppClient const& other); // not implemented
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
QXmppClient _xmppClient;
|
||||
QXmppMucManager _xmppMUCManager;
|
||||
QXmppMucRoom* _publicChatRoom;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // hifi_XmppClient_h
|
|
@ -77,7 +77,8 @@ Avatar::Avatar() :
|
|||
_moving(false),
|
||||
_collisionGroups(0),
|
||||
_initialized(false),
|
||||
_shouldRenderBillboard(true)
|
||||
_shouldRenderBillboard(true),
|
||||
_voiceSphereID(GeometryCache::UNKNOWN_ID)
|
||||
{
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
moveToThread(Application::getInstance()->thread());
|
||||
|
@ -366,7 +367,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
|
|||
|
||||
// render body
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
|
||||
renderBody(renderMode, postLighting, glowLevel);
|
||||
renderBody(frustum, renderMode, postLighting, glowLevel);
|
||||
}
|
||||
|
||||
if (!postLighting && renderMode != SHADOW_RENDER_MODE) {
|
||||
|
@ -438,8 +439,13 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
|
|||
glPushMatrix();
|
||||
glTranslatef(_position.x, _position.y, _position.z);
|
||||
glScalef(height, height, height);
|
||||
|
||||
if (_voiceSphereID == GeometryCache::UNKNOWN_ID) {
|
||||
_voiceSphereID = DependencyManager::get<GeometryCache>()->allocateID();
|
||||
}
|
||||
DependencyManager::get<GeometryCache>()->renderSphere(sphereRadius, 15, 15,
|
||||
glm::vec4(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.0f - angle / MAX_SPHERE_ANGLE));
|
||||
glm::vec4(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.0f - angle / MAX_SPHERE_ANGLE), true,
|
||||
_voiceSphereID);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
@ -471,7 +477,7 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {
|
|||
return glm::angleAxis(angle * proportion, axis);
|
||||
}
|
||||
|
||||
void Avatar::renderBody(RenderMode renderMode, bool postLighting, float glowLevel) {
|
||||
void Avatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, bool postLighting, float glowLevel) {
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
{
|
||||
|
@ -488,11 +494,13 @@ void Avatar::renderBody(RenderMode renderMode, bool postLighting, float glowLeve
|
|||
if (postLighting) {
|
||||
getHand()->render(false, modelRenderMode);
|
||||
} else {
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
RenderArgs args;
|
||||
args._viewFrustum = renderFrustum;
|
||||
_skeletonModel.render(1.0f, modelRenderMode, &args);
|
||||
renderAttachments(renderMode, &args);
|
||||
}
|
||||
}
|
||||
getHead()->render(1.0f, modelRenderMode, postLighting);
|
||||
getHead()->render(1.0f, renderFrustum, modelRenderMode, postLighting);
|
||||
}
|
||||
|
||||
bool Avatar::shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const {
|
||||
|
@ -519,11 +527,11 @@ void Avatar::simulateAttachments(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
void Avatar::renderAttachments(RenderMode renderMode) {
|
||||
void Avatar::renderAttachments(RenderMode renderMode, RenderArgs* args) {
|
||||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
foreach (Model* model, _attachmentModels) {
|
||||
model->render(1.0f, modelRenderMode);
|
||||
model->render(1.0f, modelRenderMode, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,11 +223,11 @@ protected:
|
|||
|
||||
float calculateDisplayNameScaleFactor(const glm::vec3& textPosition, bool inHMD);
|
||||
void renderDisplayName();
|
||||
virtual void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
virtual void renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||
|
||||
void simulateAttachments(float deltaTime);
|
||||
virtual void renderAttachments(RenderMode renderMode);
|
||||
virtual void renderAttachments(RenderMode renderMode, RenderArgs* args);
|
||||
|
||||
virtual void updateJointMappings();
|
||||
|
||||
|
@ -243,6 +243,8 @@ private:
|
|||
float getBillboardSize() const;
|
||||
|
||||
static int _jointConesID;
|
||||
|
||||
int _voiceSphereID;
|
||||
};
|
||||
|
||||
#endif // hifi_Avatar_h
|
||||
|
|
|
@ -39,6 +39,8 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) {
|
|||
setPupilDilation(_owningHead->getPupilDilation());
|
||||
setBlendshapeCoefficients(_owningHead->getBlendshapeCoefficients());
|
||||
|
||||
invalidCalculatedMeshBoxes();
|
||||
|
||||
if (isActive()) {
|
||||
setOffset(-_geometry->getFBXGeometry().neckPivot);
|
||||
Model::simulateInternal(deltaTime);
|
||||
|
|
|
@ -243,13 +243,15 @@ void Head::relaxLean(float deltaTime) {
|
|||
_deltaLeanForward *= relaxationFactor;
|
||||
}
|
||||
|
||||
void Head::render(float alpha, Model::RenderMode mode, bool postLighting) {
|
||||
void Head::render(float alpha, ViewFrustum* renderFrustum, Model::RenderMode mode, bool postLighting) {
|
||||
if (postLighting) {
|
||||
if (_renderLookatVectors) {
|
||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, getCorrectedLookAtPosition());
|
||||
}
|
||||
} else {
|
||||
_faceModel.render(alpha, mode);
|
||||
RenderArgs args;
|
||||
args._viewFrustum = renderFrustum;
|
||||
_faceModel.render(alpha, mode, &args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
void init();
|
||||
void reset();
|
||||
void simulate(float deltaTime, bool isMine, bool billboard = false);
|
||||
void render(float alpha, Model::RenderMode mode, bool postLighting);
|
||||
void render(float alpha, ViewFrustum* renderFrustum, Model::RenderMode mode, bool postLighting);
|
||||
void setScale(float scale);
|
||||
void setPosition(glm::vec3 position) { _position = position; }
|
||||
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
|
||||
|
|
|
@ -293,12 +293,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (Application::getInstance()->getPrioVR()->hasHeadRotation()) {
|
||||
estimatedRotation = glm::degrees(safeEulerAngles(Application::getInstance()->getPrioVR()->getHeadRotation()));
|
||||
estimatedRotation.x *= -1.0f;
|
||||
estimatedRotation.z *= -1.0f;
|
||||
|
||||
} else if (OculusManager::isConnected()) {
|
||||
if (OculusManager::isConnected()) {
|
||||
estimatedPosition = OculusManager::getRelativePosition();
|
||||
estimatedPosition.x *= -1.0f;
|
||||
_trackedHeadPosition = estimatedPosition;
|
||||
|
@ -348,13 +343,6 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
|||
}
|
||||
head->setDeltaRoll(estimatedRotation.z);
|
||||
|
||||
// the priovr can give us exact lean
|
||||
if (Application::getInstance()->getPrioVR()->isActive()) {
|
||||
glm::vec3 eulers = glm::degrees(safeEulerAngles(Application::getInstance()->getPrioVR()->getTorsoRotation()));
|
||||
head->setLeanSideways(eulers.z);
|
||||
head->setLeanForward(eulers.x);
|
||||
return;
|
||||
}
|
||||
// Update torso lean distance based on accelerometer data
|
||||
const float TORSO_LENGTH = 0.5f;
|
||||
glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f);
|
||||
|
@ -1078,7 +1066,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g
|
|||
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(RenderMode renderMode, bool postLighting, float glowLevel) {
|
||||
void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, bool postLighting, float glowLevel) {
|
||||
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||
return; // wait until both models are loaded
|
||||
}
|
||||
|
@ -1087,15 +1075,17 @@ void MyAvatar::renderBody(RenderMode renderMode, bool postLighting, float glowLe
|
|||
Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ?
|
||||
Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||
if (!postLighting) {
|
||||
_skeletonModel.render(1.0f, modelRenderMode);
|
||||
renderAttachments(renderMode);
|
||||
RenderArgs args;
|
||||
args._viewFrustum = renderFrustum;
|
||||
_skeletonModel.render(1.0f, modelRenderMode, &args);
|
||||
renderAttachments(renderMode, &args);
|
||||
}
|
||||
|
||||
// Render head so long as the camera isn't inside it
|
||||
const Camera *camera = Application::getInstance()->getCamera();
|
||||
const glm::vec3 cameraPos = camera->getPosition();
|
||||
if (shouldRenderHead(cameraPos, renderMode)) {
|
||||
getHead()->render(1.0f, modelRenderMode, postLighting);
|
||||
getHead()->render(1.0f, renderFrustum, modelRenderMode, postLighting);
|
||||
}
|
||||
if (postLighting) {
|
||||
getHand()->render(true, modelRenderMode);
|
||||
|
@ -1886,9 +1876,9 @@ void MyAvatar::onToggleRagdoll() {
|
|||
}
|
||||
}
|
||||
|
||||
void MyAvatar::renderAttachments(RenderMode renderMode) {
|
||||
void MyAvatar::renderAttachments(RenderMode renderMode, RenderArgs* args) {
|
||||
if (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON || renderMode == MIRROR_RENDER_MODE) {
|
||||
Avatar::renderAttachments(renderMode);
|
||||
Avatar::renderAttachments(renderMode, args);
|
||||
return;
|
||||
}
|
||||
const FBXGeometry& geometry = _skeletonModel.getGeometry()->getFBXGeometry();
|
||||
|
@ -1898,7 +1888,7 @@ void MyAvatar::renderAttachments(RenderMode renderMode) {
|
|||
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||
const QString& jointName = _attachmentData.at(i).jointName;
|
||||
if (jointName != headJointName && jointName != "Head") {
|
||||
_attachmentModels.at(i)->render(1.0f, modelRenderMode);
|
||||
_attachmentModels.at(i)->render(1.0f, modelRenderMode, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
void updateFromTrackers(float deltaTime);
|
||||
|
||||
void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE, bool postLighting = false);
|
||||
void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
void renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, bool postLighting, float glowLevel = 0.0f);
|
||||
bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const;
|
||||
void renderDebugBodyPoints();
|
||||
|
||||
|
@ -189,7 +189,7 @@ signals:
|
|||
void transformChanged();
|
||||
|
||||
protected:
|
||||
virtual void renderAttachments(RenderMode renderMode);
|
||||
virtual void renderAttachments(RenderMode renderMode, RenderArgs* args);
|
||||
|
||||
private:
|
||||
float _turningKeyPressTime;
|
||||
|
|
|
@ -106,21 +106,6 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
|||
}
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
PrioVR* prioVR = Application::getInstance()->getPrioVR();
|
||||
if (prioVR->isActive()) {
|
||||
for (int i = 0; i < prioVR->getJointRotations().size(); i++) {
|
||||
int humanIKJointIndex = prioVR->getHumanIKJointIndices().at(i);
|
||||
if (humanIKJointIndex == -1) {
|
||||
continue;
|
||||
}
|
||||
int jointIndex = geometry.humanIKJointIndices.at(humanIKJointIndex);
|
||||
if (jointIndex != -1) {
|
||||
JointState& state = _jointStates[jointIndex];
|
||||
state.setRotationInBindFrame(prioVR->getJointRotations().at(i), PALM_PRIORITY);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// find the left and rightmost active palms
|
||||
int leftPalmIndex, rightPalmIndex;
|
||||
|
@ -294,7 +279,7 @@ void SkeletonModel::updateJointState(int index) {
|
|||
}
|
||||
|
||||
void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, JointState& state) {
|
||||
if (!_owningAvatar->isMyAvatar() || Application::getInstance()->getPrioVR()->isActive()) {
|
||||
if (!_owningAvatar->isMyAvatar()) {
|
||||
return;
|
||||
}
|
||||
// get the rotation axes in joint space and use them to adjust the rotation
|
||||
|
|
|
@ -1,224 +0,0 @@
|
|||
//
|
||||
// PrioVR.cpp
|
||||
// interface/src/devices
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/12/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
|
||||
//
|
||||
|
||||
#include <QTimer>
|
||||
#include <QtDebug>
|
||||
|
||||
#include <avatar/AvatarManager.h>
|
||||
#include <FBXReader.h>
|
||||
#include <PerfStat.h>
|
||||
#include <TextRenderer.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "PrioVR.h"
|
||||
#include "scripting/JoystickScriptingInterface.h"
|
||||
|
||||
#ifdef HAVE_PRIOVR
|
||||
const unsigned int SERIAL_LIST[] = { 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x0000000A,
|
||||
0x0000000C, 0x0000000D, 0x0000000E, 0x00000004, 0x00000005, 0x00000010, 0x00000011 };
|
||||
const unsigned char AXIS_LIST[] = { 9, 43, 37, 37, 37, 13, 13, 13, 52, 52, 28, 28 };
|
||||
const int LIST_LENGTH = sizeof(SERIAL_LIST) / sizeof(SERIAL_LIST[0]);
|
||||
|
||||
const char* JOINT_NAMES[] = { "Neck", "Spine", "LeftArm", "LeftForeArm", "LeftHand", "RightArm",
|
||||
"RightForeArm", "RightHand", "LeftUpLeg", "LeftLeg", "RightUpLeg", "RightLeg" };
|
||||
|
||||
static int indexOfHumanIKJoint(const char* jointName) {
|
||||
for (int i = 0;; i++) {
|
||||
QByteArray humanIKJoint = HUMANIK_JOINTS[i];
|
||||
if (humanIKJoint.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
if (humanIKJoint == jointName) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void setPalm(float deltaTime, int index) {
|
||||
MyAvatar* avatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
Hand* hand = avatar->getHand();
|
||||
PalmData* palm;
|
||||
bool foundHand = false;
|
||||
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
||||
if (hand->getPalms()[j].getSixenseID() == index) {
|
||||
palm = &(hand->getPalms()[j]);
|
||||
foundHand = true;
|
||||
}
|
||||
}
|
||||
if (!foundHand) {
|
||||
PalmData newPalm(hand);
|
||||
hand->getPalms().push_back(newPalm);
|
||||
palm = &(hand->getPalms()[hand->getNumPalms() - 1]);
|
||||
palm->setSixenseID(index);
|
||||
}
|
||||
|
||||
palm->setActive(true);
|
||||
|
||||
// Read controller buttons and joystick into the hand
|
||||
const QString PRIO_JOYSTICK_NAME = "PrioVR";
|
||||
Joystick* prioJoystick = JoystickScriptingInterface::getInstance().joystickWithName(PRIO_JOYSTICK_NAME);
|
||||
if (prioJoystick) {
|
||||
const QVector<float> axes = prioJoystick->getAxes();
|
||||
const QVector<bool> buttons = prioJoystick->getButtons();
|
||||
|
||||
if (axes.size() >= 4 && buttons.size() >= 4) {
|
||||
if (index == LEFT_HAND_INDEX) {
|
||||
palm->setControllerButtons(buttons[1] ? BUTTON_FWD : 0);
|
||||
palm->setTrigger(buttons[0] ? 1.0f : 0.0f);
|
||||
palm->setJoystick(axes[0], -axes[1]);
|
||||
|
||||
} else {
|
||||
palm->setControllerButtons(buttons[3] ? BUTTON_FWD : 0);
|
||||
palm->setTrigger(buttons[2] ? 1.0f : 0.0f);
|
||||
palm->setJoystick(axes[2], -axes[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: this math is done in the worl-frame with unecessary complexity.
|
||||
// TODO: transfom this to stay in the model-frame.
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
SkeletonModel* skeletonModel = &DependencyManager::get<AvatarManager>()->getMyAvatar()->getSkeletonModel();
|
||||
int jointIndex;
|
||||
glm::quat inverseRotation = glm::inverse(DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation());
|
||||
if (index == LEFT_HAND_INDEX) {
|
||||
jointIndex = skeletonModel->getLeftHandJointIndex();
|
||||
skeletonModel->getJointRotationInWorldFrame(jointIndex, rotation);
|
||||
rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, PI_OVER_TWO, 0.0f));
|
||||
|
||||
} else {
|
||||
jointIndex = skeletonModel->getRightHandJointIndex();
|
||||
skeletonModel->getJointRotationInWorldFrame(jointIndex, rotation);
|
||||
rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, -PI_OVER_TWO, 0.0f));
|
||||
}
|
||||
skeletonModel->getJointPositionInWorldFrame(jointIndex, position);
|
||||
position = inverseRotation * (position - skeletonModel->getTranslation());
|
||||
|
||||
palm->setRawRotation(rotation);
|
||||
|
||||
// Compute current velocity from position change
|
||||
glm::vec3 rawVelocity;
|
||||
if (deltaTime > 0.0f) {
|
||||
rawVelocity = (position - palm->getRawPosition()) / deltaTime;
|
||||
} else {
|
||||
rawVelocity = glm::vec3(0.0f);
|
||||
}
|
||||
palm->setRawVelocity(rawVelocity);
|
||||
palm->setRawPosition(position);
|
||||
|
||||
// Store the one fingertip in the palm structure so we can track velocity
|
||||
const float FINGER_LENGTH = 0.3f; // meters
|
||||
const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
|
||||
const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
|
||||
glm::vec3 oldTipPosition = palm->getTipRawPosition();
|
||||
if (deltaTime > 0.0f) {
|
||||
palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
|
||||
} else {
|
||||
palm->setTipVelocity(glm::vec3(0.0f));
|
||||
}
|
||||
palm->setTipPosition(newTipPosition);
|
||||
}
|
||||
#endif
|
||||
|
||||
PrioVR::PrioVR() {
|
||||
#ifdef HAVE_PRIOVR
|
||||
char jointsDiscovered[LIST_LENGTH];
|
||||
_skeletalDevice = yei_setUpPrioVRSensors(0x00000000, const_cast<unsigned int*>(SERIAL_LIST),
|
||||
const_cast<unsigned char*>(AXIS_LIST), jointsDiscovered, LIST_LENGTH, YEI_TIMESTAMP_SYSTEM);
|
||||
if (!_skeletalDevice) {
|
||||
return;
|
||||
}
|
||||
_jointRotations.resize(LIST_LENGTH);
|
||||
_lastJointRotations.resize(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) {
|
||||
_humanIKJointIndices.append(jointsDiscovered[i] ? indexOfHumanIKJoint(JOINT_NAMES[i]) : -1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PrioVR::~PrioVR() {
|
||||
#ifdef HAVE_PRIOVR
|
||||
if (_skeletalDevice) {
|
||||
yei_stopStreaming(_skeletalDevice);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const int HEAD_ROTATION_INDEX = 0;
|
||||
|
||||
bool PrioVR::hasHeadRotation() const {
|
||||
return _humanIKJointIndices.size() > HEAD_ROTATION_INDEX && _humanIKJointIndices.at(HEAD_ROTATION_INDEX) != -1;
|
||||
}
|
||||
|
||||
glm::quat PrioVR::getHeadRotation() const {
|
||||
return _jointRotations.size() > HEAD_ROTATION_INDEX ? _jointRotations.at(HEAD_ROTATION_INDEX) : glm::quat();
|
||||
}
|
||||
|
||||
glm::quat PrioVR::getTorsoRotation() const {
|
||||
const int TORSO_ROTATION_INDEX = 1;
|
||||
return _jointRotations.size() > TORSO_ROTATION_INDEX ? _jointRotations.at(TORSO_ROTATION_INDEX) : glm::quat();
|
||||
}
|
||||
|
||||
void PrioVR::update(float deltaTime) {
|
||||
#ifdef HAVE_PRIOVR
|
||||
if (!_skeletalDevice) {
|
||||
return;
|
||||
}
|
||||
PerformanceTimer perfTimer("PrioVR");
|
||||
unsigned int timestamp;
|
||||
yei_getLastStreamDataAll(_skeletalDevice, (char*)_jointRotations.data(),
|
||||
_jointRotations.size() * sizeof(glm::quat), ×tamp);
|
||||
|
||||
// convert to our expected coordinate system, average with last rotations to smooth
|
||||
for (int i = 0; i < _jointRotations.size(); i++) {
|
||||
_jointRotations[i].y *= -1.0f;
|
||||
_jointRotations[i].z *= -1.0f;
|
||||
|
||||
glm::quat lastRotation = _lastJointRotations.at(i);
|
||||
_lastJointRotations[i] = _jointRotations.at(i);
|
||||
_jointRotations[i] = safeMix(lastRotation, _jointRotations.at(i), 0.5f);
|
||||
}
|
||||
|
||||
// convert the joysticks into palm data
|
||||
setPalm(deltaTime, LEFT_HAND_INDEX);
|
||||
setPalm(deltaTime, RIGHT_HAND_INDEX);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrioVR::reset() {
|
||||
#ifdef HAVE_PRIOVR
|
||||
if (!_skeletalDevice) {
|
||||
return;
|
||||
}
|
||||
connect(Application::getInstance(), SIGNAL(renderingOverlay()), SLOT(renderCalibrationCountdown()));
|
||||
_calibrationCountdownStarted = QDateTime::currentDateTime();
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrioVR::renderCalibrationCountdown() {
|
||||
#ifdef HAVE_PRIOVR
|
||||
const int COUNTDOWN_SECONDS = 3;
|
||||
int secondsRemaining = COUNTDOWN_SECONDS - _calibrationCountdownStarted.secsTo(QDateTime::currentDateTime());
|
||||
if (secondsRemaining == 0) {
|
||||
yei_tareSensors(_skeletalDevice);
|
||||
Application::getInstance()->disconnect(this);
|
||||
return;
|
||||
}
|
||||
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) + "...";
|
||||
auto glCanvas = Application::getInstance()->getGLWidget();
|
||||
textRenderer->draw((glCanvas->width() - textRenderer->computeExtent(text.constData()).x) / 2,
|
||||
glCanvas->height() / 2,
|
||||
text, glm::vec4(1,1,1,1));
|
||||
#endif
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
//
|
||||
// PrioVR.h
|
||||
// interface/src/devices
|
||||
//
|
||||
// Created by Andrzej Kapolka on 5/12/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 hifi_PrioVR_h
|
||||
#define hifi_PrioVR_h
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#ifdef HAVE_PRIOVR
|
||||
extern "C" {
|
||||
#include <yei_skeletal_api.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Handles interaction with the PrioVR skeleton tracking suit.
|
||||
class PrioVR : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
PrioVR();
|
||||
virtual ~PrioVR();
|
||||
|
||||
bool isActive() const { return !_jointRotations.isEmpty(); }
|
||||
|
||||
bool hasHeadRotation() const;
|
||||
|
||||
glm::quat getHeadRotation() const;
|
||||
glm::quat getTorsoRotation() const;
|
||||
|
||||
const QVector<int>& getHumanIKJointIndices() const { return _humanIKJointIndices; }
|
||||
const QVector<glm::quat>& getJointRotations() const { return _jointRotations; }
|
||||
|
||||
void update(float deltaTime);
|
||||
void reset();
|
||||
|
||||
private slots:
|
||||
|
||||
void renderCalibrationCountdown();
|
||||
|
||||
private:
|
||||
#ifdef HAVE_PRIOVR
|
||||
YEI_Device_Id _skeletalDevice;
|
||||
#endif
|
||||
|
||||
QVector<int> _humanIKJointIndices;
|
||||
QVector<glm::quat> _jointRotations;
|
||||
QVector<glm::quat> _lastJointRotations;
|
||||
|
||||
QDateTime _calibrationCountdownStarted;
|
||||
};
|
||||
|
||||
#endif // hifi_PrioVR_h
|
|
@ -12,7 +12,6 @@
|
|||
#include "AccountManager.h"
|
||||
#include "Application.h"
|
||||
#include "ResourceCache.h"
|
||||
#include "XmppClient.h"
|
||||
|
||||
#include "GlobalServicesScriptingInterface.h"
|
||||
|
||||
|
@ -20,13 +19,6 @@ GlobalServicesScriptingInterface::GlobalServicesScriptingInterface() {
|
|||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
connect(&accountManager, &AccountManager::usernameChanged, this, &GlobalServicesScriptingInterface::myUsernameChanged);
|
||||
connect(&accountManager, &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut);
|
||||
#ifdef HAVE_QXMPP
|
||||
const XmppClient& xmppClient = XmppClient::getInstance();
|
||||
connect(&xmppClient, &XmppClient::joinedPublicChatRoom, this, &GlobalServicesScriptingInterface::connected);
|
||||
connect(&xmppClient, &XmppClient::joinedPublicChatRoom, this, &GlobalServicesScriptingInterface::onConnected);
|
||||
const QXmppClient& qxmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
connect(&qxmppClient, &QXmppClient::messageReceived, this, &GlobalServicesScriptingInterface::messageReceived);
|
||||
#endif // HAVE_QXMPP
|
||||
|
||||
_downloading = false;
|
||||
connect(Application::getInstance(), &Application::renderingInWorldInterface,
|
||||
|
@ -37,30 +29,6 @@ GlobalServicesScriptingInterface::~GlobalServicesScriptingInterface() {
|
|||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
disconnect(&accountManager, &AccountManager::usernameChanged, this, &GlobalServicesScriptingInterface::myUsernameChanged);
|
||||
disconnect(&accountManager, &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut);
|
||||
#ifdef HAVE_QXMPP
|
||||
const XmppClient& xmppClient = XmppClient::getInstance();
|
||||
disconnect(&xmppClient, &XmppClient::joinedPublicChatRoom, this, &GlobalServicesScriptingInterface::connected);
|
||||
disconnect(&xmppClient, &XmppClient::joinedPublicChatRoom, this, &GlobalServicesScriptingInterface::onConnected);
|
||||
const QXmppClient& qxmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
disconnect(&qxmppClient, &QXmppClient::messageReceived, this, &GlobalServicesScriptingInterface::messageReceived);
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
disconnect(publicChatRoom, &QXmppMucRoom::participantsChanged,
|
||||
this, &GlobalServicesScriptingInterface::participantsChanged);
|
||||
#endif // HAVE_QXMPP
|
||||
}
|
||||
|
||||
void GlobalServicesScriptingInterface::onConnected() {
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
connect(publicChatRoom, &QXmppMucRoom::participantsChanged,
|
||||
this, &GlobalServicesScriptingInterface::participantsChanged, Qt::UniqueConnection);
|
||||
#endif // HAVE_QXMPP
|
||||
}
|
||||
|
||||
void GlobalServicesScriptingInterface::participantsChanged() {
|
||||
#ifdef HAVE_QXMPP
|
||||
emit GlobalServicesScriptingInterface::onlineUsersChanged(this->getOnlineUsers());
|
||||
#endif // HAVE_QXMPP
|
||||
}
|
||||
|
||||
GlobalServicesScriptingInterface* GlobalServicesScriptingInterface::getInstance() {
|
||||
|
@ -68,62 +36,14 @@ GlobalServicesScriptingInterface* GlobalServicesScriptingInterface::getInstance(
|
|||
return &sharedInstance;
|
||||
}
|
||||
|
||||
bool GlobalServicesScriptingInterface::isConnected() {
|
||||
#ifdef HAVE_QXMPP
|
||||
return XmppClient::getInstance().getXMPPClient().isConnected();
|
||||
#else
|
||||
return false;
|
||||
#endif // HAVE_QXMPP
|
||||
}
|
||||
|
||||
QScriptValue GlobalServicesScriptingInterface::chat(const QString& message) {
|
||||
#ifdef HAVE_QXMPP
|
||||
if (XmppClient::getInstance().getXMPPClient().isConnected()) {
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
QXmppMessage messageObject;
|
||||
messageObject.setTo(publicChatRoom->jid());
|
||||
messageObject.setType(QXmppMessage::GroupChat);
|
||||
messageObject.setBody(message);
|
||||
return XmppClient::getInstance().getXMPPClient().sendPacket(messageObject);
|
||||
}
|
||||
#endif // HAVE_QXMPP
|
||||
return false;
|
||||
}
|
||||
|
||||
QString GlobalServicesScriptingInterface::getMyUsername() {
|
||||
return AccountManager::getInstance().getAccountInfo().getUsername();
|
||||
}
|
||||
|
||||
QStringList GlobalServicesScriptingInterface::getOnlineUsers() {
|
||||
#ifdef HAVE_QXMPP
|
||||
if (XmppClient::getInstance().getXMPPClient().isConnected()) {
|
||||
QStringList usernames;
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
foreach(const QString& participant, XmppClient::getInstance().getPublicChatRoom()->participants()) {
|
||||
usernames.append(participant.right(participant.count() - 1 - publicChatRoom->jid().count()));
|
||||
}
|
||||
return usernames;
|
||||
}
|
||||
#endif // HAVE_QXMPP
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
void GlobalServicesScriptingInterface::loggedOut() {
|
||||
emit GlobalServicesScriptingInterface::disconnected(QString("logout"));
|
||||
}
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
void GlobalServicesScriptingInterface::messageReceived(const QXmppMessage& message) {
|
||||
if (message.type() != QXmppMessage::GroupChat) {
|
||||
return;
|
||||
}
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
QString username = message.from().right(message.from().count() - 1 - publicChatRoom->jid().count());
|
||||
emit GlobalServicesScriptingInterface::incomingMessage(username, message.body());
|
||||
}
|
||||
#endif // HAVE_QXMPP
|
||||
|
||||
|
||||
DownloadInfoResult::DownloadInfoResult() :
|
||||
downloading(QList<float>()),
|
||||
pending(0.0f)
|
||||
|
|
|
@ -19,13 +19,6 @@
|
|||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
|
||||
#include <qxmpp/QXmppClient.h>
|
||||
#include <qxmpp/QXmppMessage.h>
|
||||
|
||||
#endif // HAVE_QXMPP
|
||||
|
||||
class DownloadInfoResult {
|
||||
public:
|
||||
DownloadInfoResult();
|
||||
|
@ -41,30 +34,20 @@ void DownloadInfoResultFromScriptValue(const QScriptValue& object, DownloadInfoR
|
|||
|
||||
class GlobalServicesScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool isConnected READ isConnected)
|
||||
Q_PROPERTY(QString myUsername READ getMyUsername)
|
||||
Q_PROPERTY(QStringList onlineUsers READ getOnlineUsers)
|
||||
GlobalServicesScriptingInterface();
|
||||
~GlobalServicesScriptingInterface();
|
||||
public:
|
||||
static GlobalServicesScriptingInterface* getInstance();
|
||||
|
||||
bool isConnected();
|
||||
QString getMyUsername();
|
||||
QStringList getOnlineUsers();
|
||||
|
||||
|
||||
public slots:
|
||||
QScriptValue chat(const QString& message);
|
||||
DownloadInfoResult getDownloadInfo();
|
||||
void updateDownloadInfo();
|
||||
|
||||
private slots:
|
||||
void loggedOut();
|
||||
void onConnected();
|
||||
void participantsChanged();
|
||||
#ifdef HAVE_QXMPP
|
||||
void messageReceived(const QXmppMessage& message);
|
||||
#endif // HAVE_QXMPP
|
||||
void checkDownloadInfo();
|
||||
|
||||
signals:
|
||||
|
|
|
@ -1,420 +0,0 @@
|
|||
//
|
||||
// ChatWindow.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Dimitar Dobrev on 3/6/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
|
||||
//
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QFrame>
|
||||
#include <QLayoutItem>
|
||||
#include <QPalette>
|
||||
#include <QScrollBar>
|
||||
#include <QSizePolicy>
|
||||
#include <QTimer>
|
||||
#include "qtimespan.h"
|
||||
|
||||
|
||||
#include <AddressManager.h>
|
||||
#include <AccountManager.h>
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ChatMessageArea.h"
|
||||
#include "FlowLayout.h"
|
||||
#include "MainWindow.h"
|
||||
#include "UIUtil.h"
|
||||
#include "XmppClient.h"
|
||||
|
||||
#include "ui_chatWindow.h"
|
||||
#include "ChatWindow.h"
|
||||
|
||||
|
||||
const int NUM_MESSAGES_TO_TIME_STAMP = 20;
|
||||
|
||||
const QRegularExpression regexLinks("((?:(?:ftp)|(?:https?)|(?:hifi))://\\S+)");
|
||||
const QRegularExpression regexHifiLinks("([#@]\\S+)");
|
||||
const QString mentionSoundsPath("/mention-sounds/");
|
||||
const QString mentionRegex("@(\\b%1\\b)");
|
||||
|
||||
ChatWindow::ChatWindow(QWidget* parent) :
|
||||
QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint |
|
||||
Qt::WindowCloseButtonHint),
|
||||
_ui(new Ui::ChatWindow),
|
||||
_numMessagesAfterLastTimeStamp(0),
|
||||
_mousePressed(false),
|
||||
_mouseStartPosition(),
|
||||
_trayIcon(parent),
|
||||
_effectPlayer(),
|
||||
_usernameMentionTimestamp("MentionTimestamp", QDateTime())
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
|
||||
_ui->setupUi(this);
|
||||
|
||||
FlowLayout* flowLayout = new FlowLayout(0, 4, 4);
|
||||
_ui->usersWidget->setLayout(flowLayout);
|
||||
|
||||
_ui->messagePlainTextEdit->installEventFilter(this);
|
||||
_ui->messagePlainTextEdit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||
|
||||
QTextCursor cursor(_ui->messagePlainTextEdit->textCursor());
|
||||
|
||||
cursor.movePosition(QTextCursor::Start);
|
||||
|
||||
QTextBlockFormat format = cursor.blockFormat();
|
||||
format.setLineHeight(130, QTextBlockFormat::ProportionalHeight);
|
||||
|
||||
cursor.setBlockFormat(format);
|
||||
|
||||
_ui->messagePlainTextEdit->setTextCursor(cursor);
|
||||
|
||||
if (!AccountManager::getInstance().isLoggedIn()) {
|
||||
_ui->connectingToXMPPLabel->setText(tr("You must be logged in to chat with others."));
|
||||
}
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
if (xmppClient.isConnected()) {
|
||||
participantsChanged();
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
connect(publicChatRoom, SIGNAL(participantsChanged()), this, SLOT(participantsChanged()));
|
||||
_ui->connectingToXMPPLabel->hide();
|
||||
startTimerForTimeStamps();
|
||||
} else {
|
||||
_ui->numOnlineLabel->hide();
|
||||
_ui->usersArea->hide();
|
||||
_ui->messagesScrollArea->hide();
|
||||
_ui->messagePlainTextEdit->hide();
|
||||
connect(&XmppClient::getInstance(), SIGNAL(joinedPublicChatRoom()), this, SLOT(connected()));
|
||||
}
|
||||
connect(&xmppClient, SIGNAL(messageReceived(QXmppMessage)), this, SLOT(messageReceived(QXmppMessage)));
|
||||
connect(&_trayIcon, SIGNAL(messageClicked()), this, SLOT(notificationClicked()));
|
||||
#endif // HAVE_QXMPP
|
||||
|
||||
QDir mentionSoundsDir(PathUtils::resourcesPath() + mentionSoundsPath);
|
||||
_mentionSounds = mentionSoundsDir.entryList(QDir::Files);
|
||||
_trayIcon.setIcon(QIcon( PathUtils::resourcesPath() + "/images/hifi-logo.svg"));
|
||||
}
|
||||
|
||||
ChatWindow::~ChatWindow() {
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
disconnect(&xmppClient, SIGNAL(joinedPublicChatRoom()), this, SLOT(connected()));
|
||||
disconnect(&xmppClient, SIGNAL(messageReceived(QXmppMessage)), this, SLOT(messageReceived(QXmppMessage)));
|
||||
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
disconnect(publicChatRoom, SIGNAL(participantsChanged()), this, SLOT(participantsChanged()));
|
||||
#endif // HAVE_QXMPP
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
void ChatWindow::keyPressEvent(QKeyEvent* event) {
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
Application::getInstance()->getWindow()->activateWindow();
|
||||
hide();
|
||||
} else {
|
||||
QWidget::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatWindow::showEvent(QShowEvent* event) {
|
||||
QWidget::showEvent(event);
|
||||
|
||||
if (!event->spontaneous()) {
|
||||
_ui->messagePlainTextEdit->setFocus();
|
||||
}
|
||||
QRect parentGeometry = Application::getInstance()->getDesirableApplicationGeometry();
|
||||
int titleBarHeight = UIUtil::getWindowTitleBarHeight(this);
|
||||
int menuBarHeight = Menu::getInstance()->geometry().height();
|
||||
int topMargin = titleBarHeight + menuBarHeight;
|
||||
|
||||
setGeometry(parentGeometry.topRight().x() - size().width() + 1, parentGeometry.topRight().y() + topMargin,
|
||||
size().width(), parentWidget()->height() - topMargin);
|
||||
|
||||
Application::processEvents();
|
||||
|
||||
scrollToBottom();
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
if (xmppClient.isConnected()) {
|
||||
participantsChanged();
|
||||
}
|
||||
#endif // HAVE_QXMPP
|
||||
}
|
||||
|
||||
bool ChatWindow::eventFilter(QObject* sender, QEvent* event) {
|
||||
if (sender == _ui->messagePlainTextEdit) {
|
||||
if (event->type() != QEvent::KeyPress) {
|
||||
return false;
|
||||
}
|
||||
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
|
||||
if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) &&
|
||||
(keyEvent->modifiers() & Qt::ShiftModifier) == 0) {
|
||||
QString messageText = _ui->messagePlainTextEdit->document()->toPlainText().trimmed();
|
||||
if (!messageText.isEmpty()) {
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
QXmppMessage message;
|
||||
message.setTo(publicChatRoom->jid());
|
||||
message.setType(QXmppMessage::GroupChat);
|
||||
message.setBody(messageText);
|
||||
XmppClient::getInstance().getXMPPClient().sendPacket(message);
|
||||
#endif // HAVE_QXMPP
|
||||
QTextCursor cursor = _ui->messagePlainTextEdit->textCursor();
|
||||
cursor.select(QTextCursor::Document);
|
||||
cursor.removeSelectedText();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonRelease) {
|
||||
QVariant userVar = sender->property("user");
|
||||
if (userVar.isValid()) {
|
||||
DependencyManager::get<AddressManager>()->goToUser(userVar.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(sender, event);
|
||||
}
|
||||
|
||||
void ChatWindow::addTimeStamp() {
|
||||
QTimeSpan timePassed = QDateTime::currentDateTime() - _lastMessageStamp;
|
||||
int times[] = { timePassed.daysPart(), timePassed.hoursPart(), timePassed.minutesPart() };
|
||||
QString strings[] = { tr("%n day(s)", 0, times[0]), tr("%n hour(s)", 0, times[1]), tr("%n minute(s)", 0, times[2]) };
|
||||
QString timeString = "";
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (times[i] > 0) {
|
||||
timeString += strings[i] + " ";
|
||||
}
|
||||
}
|
||||
timeString.chop(1);
|
||||
if (!timeString.isEmpty()) {
|
||||
QLabel* timeLabel = new QLabel(timeString);
|
||||
timeLabel->setStyleSheet("color: #333333;"
|
||||
"background-color: white;"
|
||||
"font-size: 14px;"
|
||||
"padding: 4px;");
|
||||
timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
timeLabel->setAlignment(Qt::AlignLeft);
|
||||
|
||||
bool atBottom = isNearBottom();
|
||||
|
||||
_ui->messagesVBoxLayout->addWidget(timeLabel);
|
||||
_ui->messagesVBoxLayout->parentWidget()->updateGeometry();
|
||||
|
||||
Application::processEvents();
|
||||
_numMessagesAfterLastTimeStamp = 0;
|
||||
|
||||
if (atBottom) {
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChatWindow::startTimerForTimeStamps() {
|
||||
QTimer* timer = new QTimer(this);
|
||||
timer->setInterval(10 * 60 * 1000);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void ChatWindow::connected() {
|
||||
_ui->connectingToXMPPLabel->hide();
|
||||
_ui->numOnlineLabel->show();
|
||||
_ui->usersArea->show();
|
||||
_ui->messagesScrollArea->show();
|
||||
_ui->messagePlainTextEdit->show();
|
||||
_ui->messagePlainTextEdit->setFocus();
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
connect(publicChatRoom, SIGNAL(participantsChanged()), this, SLOT(participantsChanged()));
|
||||
#endif // HAVE_QXMPP
|
||||
startTimerForTimeStamps();
|
||||
}
|
||||
|
||||
void ChatWindow::timeout() {
|
||||
if (_numMessagesAfterLastTimeStamp >= NUM_MESSAGES_TO_TIME_STAMP) {
|
||||
addTimeStamp();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
void ChatWindow::notificationClicked() {
|
||||
if (parentWidget()->isMinimized()) {
|
||||
parentWidget()->showNormal();
|
||||
}
|
||||
if (isHidden()) {
|
||||
show();
|
||||
}
|
||||
|
||||
// find last mention
|
||||
int messageCount = _ui->messagesVBoxLayout->count();
|
||||
for (unsigned int i = messageCount; i > 0; i--) {
|
||||
ChatMessageArea* area = (ChatMessageArea*)_ui->messagesVBoxLayout->itemAt(i - 1)->widget();
|
||||
QRegularExpression usernameMention(mentionRegex.arg(AccountManager::getInstance().getAccountInfo().getUsername()));
|
||||
if (area->toPlainText().contains(usernameMention)) {
|
||||
int top = area->geometry().top();
|
||||
int height = area->geometry().height();
|
||||
|
||||
QScrollBar* verticalScrollBar = _ui->messagesScrollArea->verticalScrollBar();
|
||||
verticalScrollBar->setSliderPosition(top - verticalScrollBar->size().height() + height);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Application::processEvents();
|
||||
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
QString ChatWindow::getParticipantName(const QString& participant) {
|
||||
const QXmppMucRoom* publicChatRoom = XmppClient::getInstance().getPublicChatRoom();
|
||||
return participant.right(participant.count() - 1 - publicChatRoom->jid().count());
|
||||
}
|
||||
|
||||
void ChatWindow::error(QXmppClient::Error error) {
|
||||
_ui->connectingToXMPPLabel->setText(QString::number(error));
|
||||
}
|
||||
|
||||
void ChatWindow::participantsChanged() {
|
||||
bool atBottom = isNearBottom();
|
||||
|
||||
QStringList participants = XmppClient::getInstance().getPublicChatRoom()->participants();
|
||||
_ui->numOnlineLabel->setText(tr("%1 online now:").arg(participants.count()));
|
||||
|
||||
while (QLayoutItem* item = _ui->usersWidget->layout()->takeAt(0)) {
|
||||
delete item->widget();
|
||||
delete item;
|
||||
}
|
||||
foreach (const QString& participant, participants) {
|
||||
QString participantName = getParticipantName(participant);
|
||||
QLabel* userLabel = new QLabel();
|
||||
userLabel->setText(participantName);
|
||||
userLabel->setStyleSheet("background-color: palette(light);"
|
||||
"border-radius: 5px;"
|
||||
"color: #267077;"
|
||||
"padding-top: 3px;"
|
||||
"padding-right: 2px;"
|
||||
"padding-bottom: 2px;"
|
||||
"padding-left: 2px;"
|
||||
"border: 1px solid palette(shadow);"
|
||||
"font-size: 14px;"
|
||||
"font-weight: bold");
|
||||
userLabel->setProperty("user", participantName);
|
||||
userLabel->setCursor(Qt::PointingHandCursor);
|
||||
userLabel->installEventFilter(this);
|
||||
_ui->usersWidget->layout()->addWidget(userLabel);
|
||||
}
|
||||
Application::processEvents();
|
||||
|
||||
if (atBottom) {
|
||||
scrollToBottom();
|
||||
}
|
||||
}
|
||||
|
||||
void ChatWindow::messageReceived(const QXmppMessage& message) {
|
||||
if (message.type() != QXmppMessage::GroupChat) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update background if this is a message from the current user
|
||||
bool fromSelf = getParticipantName(message.from()) == AccountManager::getInstance().getAccountInfo().getUsername();
|
||||
|
||||
// Create message area
|
||||
ChatMessageArea* messageArea = new ChatMessageArea(true);
|
||||
messageArea->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
|
||||
messageArea->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
messageArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
messageArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
messageArea->setReadOnly(true);
|
||||
|
||||
messageArea->setStyleSheet("QTextBrowser{ padding-bottom: 2px;"
|
||||
"padding-left: 2px;"
|
||||
"padding-top: 2px;"
|
||||
"padding-right: 20px;"
|
||||
"margin: 0px;"
|
||||
"color: #333333;"
|
||||
"font-size: 14px;"
|
||||
"background-color: rgba(0, 0, 0, 0%);"
|
||||
"border: 0; }"
|
||||
"QMenu{ border: 2px outset gray; }");
|
||||
|
||||
QString userLabel = getParticipantName(message.from());
|
||||
if (fromSelf) {
|
||||
userLabel = "<b style=\"color: #4a6f91\">" + userLabel + ": </b>";
|
||||
messageArea->setStyleSheet(messageArea->styleSheet() + "background-color: #e1e8ea");
|
||||
} else {
|
||||
userLabel = "<b>" + userLabel + ": </b>";
|
||||
}
|
||||
|
||||
messageArea->document()->setDefaultStyleSheet("a { text-decoration: none; font-weight: bold; color: #267077;}");
|
||||
QString messageText = message.body().toHtmlEscaped();
|
||||
messageText = messageText.replace(regexLinks, "<a href=\"\\1\">\\1</a>");
|
||||
messageText = messageText.replace(regexHifiLinks, "<a href=\"hifi://\\1\">\\1</a>");
|
||||
messageArea->setHtml(userLabel + messageText);
|
||||
|
||||
bool atBottom = isNearBottom();
|
||||
|
||||
_ui->messagesVBoxLayout->addWidget(messageArea);
|
||||
_ui->messagesVBoxLayout->parentWidget()->updateGeometry();
|
||||
Application::processEvents();
|
||||
|
||||
if (atBottom || fromSelf) {
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
++_numMessagesAfterLastTimeStamp;
|
||||
if (message.stamp().isValid()) {
|
||||
_lastMessageStamp = message.stamp().toLocalTime();
|
||||
} else {
|
||||
_lastMessageStamp = QDateTime::currentDateTime();
|
||||
}
|
||||
|
||||
QRegularExpression usernameMention(mentionRegex.arg(AccountManager::getInstance().getAccountInfo().getUsername()));
|
||||
if (message.body().contains(usernameMention)) {
|
||||
|
||||
// Don't show messages already seen in icon tray at start-up.
|
||||
bool showMessage = _usernameMentionTimestamp.get() < _lastMessageStamp;
|
||||
if (showMessage) {
|
||||
_usernameMentionTimestamp.set(_lastMessageStamp);
|
||||
}
|
||||
|
||||
if (isHidden() && showMessage) {
|
||||
|
||||
if (_effectPlayer.state() != QMediaPlayer::PlayingState) {
|
||||
// get random sound
|
||||
QFileInfo inf = QFileInfo(PathUtils::resourcesPath() +
|
||||
mentionSoundsPath +
|
||||
_mentionSounds.at(rand() % _mentionSounds.size()));
|
||||
_effectPlayer.setMedia(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
||||
_effectPlayer.play();
|
||||
}
|
||||
|
||||
_trayIcon.show();
|
||||
_trayIcon.showMessage(windowTitle(), message.body());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // HAVE_QXMPP
|
||||
|
||||
bool ChatWindow::isNearBottom() {
|
||||
QScrollBar* verticalScrollBar = _ui->messagesScrollArea->verticalScrollBar();
|
||||
return verticalScrollBar->value() >= verticalScrollBar->maximum() - Ui::AUTO_SCROLL_THRESHOLD;
|
||||
}
|
||||
|
||||
// Scroll chat message area to bottom.
|
||||
void ChatWindow::scrollToBottom() {
|
||||
QScrollBar* verticalScrollBar = _ui->messagesScrollArea->verticalScrollBar();
|
||||
verticalScrollBar->setValue(verticalScrollBar->maximum());
|
||||
}
|
||||
|
||||
bool ChatWindow::event(QEvent* event) {
|
||||
if (event->type() == QEvent::WindowActivate) {
|
||||
_ui->messagePlainTextEdit->setFocus();
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
//
|
||||
// ChatWindow.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Dimitar Dobrev on 3/6/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 hifi_ChatWindow_h
|
||||
#define hifi_ChatWindow_h
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QDockWidget>
|
||||
#include <QMediaPlayer>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QTimer>
|
||||
|
||||
#include <Application.h>
|
||||
#include <SettingHandle.h>
|
||||
|
||||
#include "FramelessDialog.h"
|
||||
|
||||
#ifdef HAVE_QXMPP
|
||||
|
||||
#include <qxmpp/QXmppClient.h>
|
||||
#include <qxmpp/QXmppMessage.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
|
||||
|
||||
// Maximum amount the chat can be scrolled up in order to auto scroll.
|
||||
const int AUTO_SCROLL_THRESHOLD = 20;
|
||||
|
||||
|
||||
class ChatWindow;
|
||||
}
|
||||
|
||||
class ChatWindow : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChatWindow(QWidget* parent);
|
||||
~ChatWindow();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* sender, QEvent* event);
|
||||
|
||||
virtual void keyPressEvent(QKeyEvent *event);
|
||||
virtual void showEvent(QShowEvent* event);
|
||||
virtual bool event(QEvent* event);
|
||||
|
||||
private:
|
||||
#ifdef HAVE_QXMPP
|
||||
QString getParticipantName(const QString& participant);
|
||||
#endif
|
||||
void startTimerForTimeStamps();
|
||||
void addTimeStamp();
|
||||
bool isNearBottom();
|
||||
void scrollToBottom();
|
||||
|
||||
Ui::ChatWindow* _ui;
|
||||
int _numMessagesAfterLastTimeStamp;
|
||||
QDateTime _lastMessageStamp;
|
||||
bool _mousePressed;
|
||||
QPoint _mouseStartPosition;
|
||||
QSystemTrayIcon _trayIcon;
|
||||
QStringList _mentionSounds;
|
||||
QMediaPlayer _effectPlayer;
|
||||
|
||||
Setting::Handle<QDateTime> _usernameMentionTimestamp;
|
||||
|
||||
private slots:
|
||||
void connected();
|
||||
void timeout();
|
||||
#ifdef HAVE_QXMPP
|
||||
void error(QXmppClient::Error error);
|
||||
void participantsChanged();
|
||||
void messageReceived(const QXmppMessage& message);
|
||||
void notificationClicked();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // hifi_ChatWindow_h
|
|
@ -9,17 +9,17 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <AccountManager.h>
|
||||
#include <MainWindow.h>
|
||||
#include <PathUtils.h>
|
||||
#include <XmppClient.h>
|
||||
|
||||
#include "AddressBarDialog.h"
|
||||
#include "AnimationsDialog.h"
|
||||
#include "AttachmentsDialog.h"
|
||||
#include "BandwidthDialog.h"
|
||||
#include "CachesSizeDialog.h"
|
||||
#include "ChatWindow.h"
|
||||
#include "HMDToolsDialog.h"
|
||||
#include "LodToolsDialog.h"
|
||||
#include "LoginDialog.h"
|
||||
|
@ -163,53 +163,16 @@ void DialogsManager::showScriptEditor() {
|
|||
_scriptEditor->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::setupChat() {
|
||||
#ifdef HAVE_QXMPP
|
||||
const QXmppClient& xmppClient = XmppClient::getInstance().getXMPPClient();
|
||||
connect(&xmppClient, &QXmppClient::connected, this, &DialogsManager::toggleChat);
|
||||
connect(&xmppClient, &QXmppClient::disconnected, this, &DialogsManager::toggleChat);
|
||||
|
||||
QDir::setCurrent(PathUtils::resourcesPath());
|
||||
// init chat window to listen chat
|
||||
maybeCreateDialog(_chatWindow);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DialogsManager::showChat() {
|
||||
if (AccountManager::getInstance().isLoggedIn()) {
|
||||
maybeCreateDialog(_chatWindow);
|
||||
|
||||
if (_chatWindow->isHidden()) {
|
||||
_chatWindow->show();
|
||||
}
|
||||
_chatWindow->raise();
|
||||
_chatWindow->activateWindow();
|
||||
_chatWindow->setFocus();
|
||||
} else {
|
||||
qApp->getTrayIcon()->showMessage("Interface",
|
||||
"You need to login to be able to chat with others on this domain.");
|
||||
void DialogsManager::showIRCLink() {
|
||||
if (!_ircInfoBox) {
|
||||
_ircInfoBox = new QMessageBox(QMessageBox::NoIcon,
|
||||
"High Fidelity IRC",
|
||||
"High Fidelity has an IRC channel on irc.freenode.net at #highfidelity.<br/><br/>Web chat is available at <a href='http://webchat.freenode.net/?channels=highfidelity&uio=d4'>http://webchat.freenode.net/?channels=highfidelity&uio=d4</a>",
|
||||
QMessageBox::Ok);
|
||||
_ircInfoBox->setTextFormat(Qt::RichText);
|
||||
_ircInfoBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||
_ircInfoBox->show();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::toggleChat() {
|
||||
#ifdef HAVE_QXMPP
|
||||
QAction* chatAction = Menu::getInstance()->getActionForOption(MenuOption::Login);
|
||||
Q_CHECK_PTR(chatAction);
|
||||
|
||||
chatAction->setEnabled(XmppClient::getInstance().getXMPPClient().isConnected());
|
||||
if (!chatAction->isEnabled() && _chatWindow && AccountManager::getInstance().isLoggedIn()) {
|
||||
if (_chatWindow->isHidden()) {
|
||||
_chatWindow->show();
|
||||
_chatWindow->raise();
|
||||
_chatWindow->activateWindow();
|
||||
_chatWindow->setFocus();
|
||||
} else {
|
||||
_chatWindow->hide();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
_ircInfoBox->raise();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ class AddressBarDialog;
|
|||
class AnimationsDialog;
|
||||
class AttachmentsDialog;
|
||||
class CachesSizeDialog;
|
||||
class ChatWindow;
|
||||
class BandwidthDialog;
|
||||
class LodToolsDialog;
|
||||
class LoginDialog;
|
||||
|
@ -34,6 +33,7 @@ class MetavoxelNetworkSimulator;
|
|||
class OctreeStatsDialog;
|
||||
class PreferencesDialog;
|
||||
class ScriptEditorWindow;
|
||||
class QMessageBox;
|
||||
|
||||
class DialogsManager : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
|
@ -45,8 +45,6 @@ public:
|
|||
QPointer<LodToolsDialog> getLodToolsDialog() const { return _lodToolsDialog; }
|
||||
QPointer<OctreeStatsDialog> getOctreeStatsDialog() const { return _octreeStatsDialog; }
|
||||
|
||||
void setupChat();
|
||||
|
||||
public slots:
|
||||
void toggleAddressBar();
|
||||
void toggleLoginDialog();
|
||||
|
@ -62,12 +60,11 @@ public slots:
|
|||
void showMetavoxelEditor();
|
||||
void showMetavoxelNetworkSimulator();
|
||||
void showScriptEditor();
|
||||
void showChat();
|
||||
|
||||
void showIRCLink();
|
||||
|
||||
private slots:
|
||||
void toggleToolWindow();
|
||||
void hmdToolsClosed();
|
||||
void toggleChat();
|
||||
|
||||
private:
|
||||
DialogsManager() {}
|
||||
|
@ -91,7 +88,7 @@ private:
|
|||
QPointer<AttachmentsDialog> _attachmentsDialog;
|
||||
QPointer<BandwidthDialog> _bandwidthDialog;
|
||||
QPointer<CachesSizeDialog> _cachesSizeDialog;
|
||||
QPointer<ChatWindow> _chatWindow;
|
||||
QPointer<QMessageBox> _ircInfoBox;
|
||||
QPointer<HMDToolsDialog> _hmdToolsDialog;
|
||||
QPointer<LodToolsDialog> _lodToolsDialog;
|
||||
QPointer<LoginDialog> _loginDialog;
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef unsigned long long quint64;
|
|||
#include <QVariantMap>
|
||||
#include <QVector>
|
||||
#include <QtScript/QScriptable>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
#include <CollisionInfo.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
@ -300,6 +301,17 @@ public:
|
|||
|
||||
const Referential* getReferential() const { return _referential; }
|
||||
|
||||
void togglePhysicsEnabled() { _enablePhysics = !_enablePhysics; }
|
||||
bool isPhysicsEnabled() { return _enablePhysics; }
|
||||
void setPhysicsEnabled(bool enablePhysics) { _enablePhysics = enablePhysics; }
|
||||
|
||||
void lockForRead() { _lock.lockForRead(); }
|
||||
bool tryLockForRead() { return _lock.tryLockForRead(); }
|
||||
void lockForWrite() { _lock.lockForWrite(); }
|
||||
bool tryLockForWrite() { return _lock.tryLockForWrite(); }
|
||||
void unlock() { _lock.unlock(); }
|
||||
|
||||
|
||||
public slots:
|
||||
void sendAvatarDataPacket();
|
||||
void sendIdentityPacket();
|
||||
|
@ -393,6 +405,9 @@ private:
|
|||
// privatize the copy constructor and assignment operator so they cannot be called
|
||||
AvatarData(const AvatarData&);
|
||||
AvatarData& operator= (const AvatarData&);
|
||||
|
||||
QReadWriteLock _lock;
|
||||
bool _enablePhysics = false; // XXX
|
||||
};
|
||||
Q_DECLARE_METATYPE(AvatarData*)
|
||||
|
||||
|
|
|
@ -348,8 +348,14 @@ void EntityTreeRenderer::leaveAllEntities() {
|
|||
void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) {
|
||||
if (_tree && !_shuttingDown) {
|
||||
Model::startScene(renderSide);
|
||||
RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
|
||||
|
||||
ViewFrustum* frustum = (renderMode == RenderArgs::SHADOW_RENDER_MODE) ?
|
||||
_viewState->getShadowViewFrustum() : _viewState->getCurrentViewFrustum();
|
||||
|
||||
RenderArgs args = { this, frustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
_tree->lockForRead();
|
||||
_tree->recurseTreeWithOperation(renderOperation, &args);
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ EntityScriptingInterface::EntityScriptingInterface() :
|
|||
_nextCreatorTokenID(0),
|
||||
_entityTree(NULL)
|
||||
{
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
connect(nodeList.data(), &NodeList::canAdjustLocksChanged, this, &EntityScriptingInterface::canAdjustLocksChanged);
|
||||
}
|
||||
|
||||
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QtCore/QObject>
|
||||
|
||||
#include <CollisionInfo.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <Octree.h>
|
||||
#include <OctreeScriptingInterface.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
@ -48,7 +49,7 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra
|
|||
|
||||
|
||||
/// handles scripting of Entity commands from JS passed to assigned clients
|
||||
class EntityScriptingInterface : public OctreeScriptingInterface {
|
||||
class EntityScriptingInterface : public OctreeScriptingInterface, public Dependency {
|
||||
Q_OBJECT
|
||||
public:
|
||||
EntityScriptingInterface();
|
||||
|
@ -111,6 +112,8 @@ public slots:
|
|||
signals:
|
||||
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
||||
|
||||
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||
|
||||
void mousePressOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
||||
void mouseMoveOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
||||
void mouseReleaseOnEntity(const EntityItemID& entityItemID, const MouseEvent& event);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
set(TARGET_NAME gpu)
|
||||
|
||||
AUTOSCRIBE_SHADER_LIB(gpu)
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library()
|
||||
|
||||
|
|
|
@ -153,10 +153,10 @@ void Batch::setViewTransform(const Transform& view) {
|
|||
_params.push_back(_transforms.cache(view));
|
||||
}
|
||||
|
||||
void Batch::setProjectionTransform(const Transform& proj) {
|
||||
void Batch::setProjectionTransform(const Mat4& proj) {
|
||||
ADD_COMMAND(setProjectionTransform);
|
||||
|
||||
_params.push_back(_transforms.cache(proj));
|
||||
_params.push_back(cacheData(sizeof(Mat4), &proj));
|
||||
}
|
||||
|
||||
void Batch::setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size) {
|
||||
|
|
|
@ -53,6 +53,11 @@ enum Primitive {
|
|||
NUM_PRIMITIVES,
|
||||
};
|
||||
|
||||
enum ReservedSlot {
|
||||
TRANSFORM_OBJECT_SLOT = 6,
|
||||
TRANSFORM_CAMERA_SLOT = 7,
|
||||
};
|
||||
|
||||
class Batch {
|
||||
public:
|
||||
typedef Stream::Slot Slot;
|
||||
|
@ -89,7 +94,7 @@ public:
|
|||
// with the ModelTransformu to create the equivalent of the glModelViewMatrix
|
||||
void setModelTransform(const Transform& model);
|
||||
void setViewTransform(const Transform& view);
|
||||
void setProjectionTransform(const Transform& proj);
|
||||
void setProjectionTransform(const Mat4& proj);
|
||||
|
||||
// Shader Stage
|
||||
void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size);
|
||||
|
|
4
libraries/render-utils/src/Config.slh → libraries/gpu/src/gpu/Config.slh
Executable file → Normal file
4
libraries/render-utils/src/Config.slh → libraries/gpu/src/gpu/Config.slh
Executable file → Normal file
|
@ -8,8 +8,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
!>
|
||||
<@if not CONFIG_SLH@>
|
||||
<@def CONFIG_SLH@>
|
||||
<@if not GPU_CONFIG_SLH@>
|
||||
<@def GPU_CONFIG_SLH@>
|
||||
|
||||
<@if GLPROFILE == PC_GL @>
|
||||
<@def VERSION_HEADER #version 330 compatibility@>
|
|
@ -29,6 +29,21 @@ class Batch;
|
|||
class Backend {
|
||||
public:
|
||||
|
||||
class TransformObject {
|
||||
public:
|
||||
Mat4 _model;
|
||||
Mat4 _modelInverse;
|
||||
};
|
||||
|
||||
class TransformCamera {
|
||||
public:
|
||||
Mat4 _view;
|
||||
Mat4 _viewInverse;
|
||||
Mat4 _projectionViewUntranslated;
|
||||
Mat4 _projection;
|
||||
Vec4 _viewport;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
static void setGPUObject(const Buffer& buffer, T* bo) {
|
||||
buffer.setGPUObject(reinterpret_cast<GPUObject*>(bo));
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#ifndef hifi_gpu_Format_h
|
||||
#define hifi_gpu_Format_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <assert.h>
|
||||
|
||||
namespace gpu {
|
||||
|
@ -24,6 +25,12 @@ typedef char int8;
|
|||
|
||||
typedef uint32 Offset;
|
||||
|
||||
typedef glm::mat4 Mat4;
|
||||
typedef glm::mat3 Mat3;
|
||||
typedef glm::vec4 Vec4;
|
||||
typedef glm::vec3 Vec3;
|
||||
typedef glm::vec2 Vec2;
|
||||
|
||||
// Description of a scalar type
|
||||
enum Type {
|
||||
|
||||
|
|
|
@ -73,28 +73,32 @@ GLBackend::GLBackend() :
|
|||
_input(),
|
||||
_transform()
|
||||
{
|
||||
|
||||
initTransform();
|
||||
}
|
||||
|
||||
GLBackend::~GLBackend() {
|
||||
|
||||
killTransform();
|
||||
}
|
||||
|
||||
void GLBackend::renderBatch(Batch& batch) {
|
||||
void GLBackend::render(Batch& batch) {
|
||||
|
||||
uint32 numCommands = batch.getCommands().size();
|
||||
const Batch::Commands::value_type* command = batch.getCommands().data();
|
||||
const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data();
|
||||
|
||||
GLBackend backend;
|
||||
|
||||
for (unsigned int i = 0; i < numCommands; i++) {
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(backend.*(call))(batch, *offset);
|
||||
(this->*(call))(batch, *offset);
|
||||
command++;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
void GLBackend::renderBatch(Batch& batch) {
|
||||
GLBackend backend;
|
||||
backend.render(batch);
|
||||
}
|
||||
|
||||
void GLBackend::checkGLError() {
|
||||
GLenum error = glGetError();
|
||||
if (!error) {
|
||||
|
@ -386,18 +390,93 @@ void GLBackend::do_setViewTransform(Batch& batch, uint32 paramOffset) {
|
|||
}
|
||||
|
||||
void GLBackend::do_setProjectionTransform(Batch& batch, uint32 paramOffset) {
|
||||
_transform._projection = batch._transforms.get(batch._params[paramOffset]._uint);
|
||||
memcpy(&_transform._projection, batch.editData(batch._params[paramOffset]._uint), sizeof(Mat4));
|
||||
_transform._invalidProj = true;
|
||||
}
|
||||
|
||||
void GLBackend::initTransform() {
|
||||
#if defined(Q_OS_WIN)
|
||||
glGenBuffers(1, &_transform._transformObjectBuffer);
|
||||
glGenBuffers(1, &_transform._transformCameraBuffer);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, _transform._transformObjectBuffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(_transform._transformObject), (const void*) &_transform._transformObject, GL_DYNAMIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, _transform._transformCameraBuffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW);
|
||||
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLBackend::killTransform() {
|
||||
#if defined(Q_OS_WIN)
|
||||
glDeleteBuffers(1, &_transform._transformObjectBuffer);
|
||||
glDeleteBuffers(1, &_transform._transformCameraBuffer);
|
||||
#else
|
||||
#endif
|
||||
}
|
||||
void GLBackend::updateTransform() {
|
||||
// Check all the dirty flags and update the state accordingly
|
||||
if (_transform._invalidProj) {
|
||||
// TODO: implement the projection matrix assignment to gl state
|
||||
/* if (_transform._lastMode != GL_PROJECTION) {
|
||||
_transform._transformCamera._projection = _transform._projection;
|
||||
}
|
||||
|
||||
if (_transform._invalidView) {
|
||||
_transform._view.getInverseMatrix(_transform._transformCamera._view);
|
||||
_transform._view.getMatrix(_transform._transformCamera._viewInverse);
|
||||
}
|
||||
|
||||
if (_transform._invalidModel) {
|
||||
_transform._model.getMatrix(_transform._transformObject._model);
|
||||
_transform._model.getInverseMatrix(_transform._transformObject._modelInverse);
|
||||
}
|
||||
|
||||
if (_transform._invalidView || _transform._invalidProj) {
|
||||
Mat4 viewUntranslated = _transform._transformCamera._view;
|
||||
viewUntranslated[3] = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_transform._transformCamera._projectionViewUntranslated = _transform._transformCamera._projection * viewUntranslated;
|
||||
}
|
||||
|
||||
if (_transform._invalidView || _transform._invalidProj) {
|
||||
#if defined(Q_OS_WIN)
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformCameraBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformCamera), (const void*) &_transform._transformCamera, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
CHECK_GL_ERROR();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_transform._invalidModel) {
|
||||
#if defined(Q_OS_WIN)
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _transform._transformObjectBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_transform._transformObject), (const void*) &_transform._transformObject, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
CHECK_GL_ERROR();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, _transform._transformObjectBuffer);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, _transform._transformCameraBuffer);
|
||||
CHECK_GL_ERROR();
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
|
||||
// Do it again for fixed pipeline until we can get rid of it
|
||||
if (_transform._invalidProj) {
|
||||
if (_transform._lastMode != GL_PROJECTION) {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
_transform._lastMode = GL_PROJECTION;
|
||||
}
|
||||
CHECK_GL_ERROR();*/
|
||||
glLoadMatrixf(reinterpret_cast< const GLfloat* >(&_transform._projection));
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
if (_transform._invalidModel || _transform._invalidView) {
|
||||
|
@ -430,10 +509,11 @@ void GLBackend::updateTransform() {
|
|||
}
|
||||
}
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
_transform._invalidModel = false;
|
||||
_transform._invalidView = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flags are clean
|
||||
_transform._invalidView = _transform._invalidProj = _transform._invalidModel = false;
|
||||
}
|
||||
|
||||
void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) {
|
||||
|
|
|
@ -27,10 +27,13 @@ public:
|
|||
GLBackend();
|
||||
~GLBackend();
|
||||
|
||||
void render(Batch& batch);
|
||||
|
||||
static void renderBatch(Batch& batch);
|
||||
|
||||
static void checkGLError();
|
||||
|
||||
|
||||
|
||||
class GLBuffer : public GPUObject {
|
||||
public:
|
||||
|
@ -113,11 +116,17 @@ protected:
|
|||
void do_setViewTransform(Batch& batch, uint32 paramOffset);
|
||||
void do_setProjectionTransform(Batch& batch, uint32 paramOffset);
|
||||
|
||||
void initTransform();
|
||||
void killTransform();
|
||||
void updateTransform();
|
||||
struct TransformStageState {
|
||||
TransformObject _transformObject;
|
||||
TransformCamera _transformCamera;
|
||||
GLuint _transformObjectBuffer;
|
||||
GLuint _transformCameraBuffer;
|
||||
Transform _model;
|
||||
Transform _view;
|
||||
Transform _projection;
|
||||
Mat4 _projection;
|
||||
bool _invalidModel;
|
||||
bool _invalidView;
|
||||
bool _invalidProj;
|
||||
|
@ -125,12 +134,14 @@ protected:
|
|||
GLenum _lastMode;
|
||||
|
||||
TransformStageState() :
|
||||
_transformObjectBuffer(0),
|
||||
_transformCameraBuffer(0),
|
||||
_model(),
|
||||
_view(),
|
||||
_projection(),
|
||||
_invalidModel(true),
|
||||
_invalidView(true),
|
||||
_invalidProj(true),
|
||||
_invalidProj(false),
|
||||
_lastMode(GL_TEXTURE) {}
|
||||
} _transform;
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ static const GLenum _elementTypeToGLType[NUM_TYPES]= {
|
|||
GL_UNSIGNED_BYTE
|
||||
};
|
||||
|
||||
//#define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError()
|
||||
#define CHECK_GL_ERROR()
|
||||
#define CHECK_GL_ERROR() ::gpu::GLBackend::checkGLError()
|
||||
//#define CHECK_GL_ERROR()
|
||||
|
||||
#endif
|
||||
|
|
95
libraries/gpu/src/gpu/Transform.slh
Normal file
95
libraries/gpu/src/gpu/Transform.slh
Normal file
|
@ -0,0 +1,95 @@
|
|||
<!
|
||||
// gpu/TransformState.slh
|
||||
//
|
||||
// Created by Sam Gateau on 2/10/15.
|
||||
// Copyright 2013 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
|
||||
!>
|
||||
<@if not GPU_TRANSFORM_STATE_SLH@>
|
||||
<@def GPU_TRANSFORM_STATE_SLH@>
|
||||
|
||||
struct TransformObject {
|
||||
mat4 _model;
|
||||
mat4 _modelInverse;
|
||||
};
|
||||
|
||||
struct TransformCamera {
|
||||
mat4 _view;
|
||||
mat4 _viewInverse;
|
||||
mat4 _projectionViewUntranslated;
|
||||
mat4 _projection;
|
||||
vec4 _viewport;
|
||||
};
|
||||
|
||||
vec4 transformModelToClipPos(TransformCamera camera, TransformObject object, vec4 pos) {
|
||||
<@if GLPROFILE == MAC_GL@>
|
||||
return gl_ModelViewProjectionMatrix * pos;
|
||||
<@elif GLPROFILE == PC_GL@>
|
||||
vec4 epos = (object._model * pos) + vec4(-pos.w * camera._viewInverse[3].xyz, 0.0);
|
||||
return camera._projectionViewUntranslated * epos;
|
||||
// Equivalent to the following but hoppefully a bit more accurate
|
||||
// return camera._projection * camera._view * object._model * pos;
|
||||
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
vec3 transformModelToEyeDir(TransformCamera camera, TransformObject object, vec3 dir) {
|
||||
<@if GLPROFILE == MAC_GL@>
|
||||
return gl_NormalMatrix * dir;
|
||||
<@elif GLPROFILE == PC_GL@>
|
||||
vec3 mr0 = vec3(object._modelInverse[0].x, object._modelInverse[1].x, object._modelInverse[2].x);
|
||||
vec3 mr1 = vec3(object._modelInverse[0].y, object._modelInverse[1].y, object._modelInverse[2].y);
|
||||
vec3 mr2 = vec3(object._modelInverse[0].z, object._modelInverse[1].z, object._modelInverse[2].z);
|
||||
|
||||
vec3 mvc0 = vec3(dot(camera._viewInverse[0].xyz, mr0), dot(camera._viewInverse[0].xyz, mr1), dot(camera._viewInverse[0].xyz, mr2));
|
||||
vec3 mvc1 = vec3(dot(camera._viewInverse[1].xyz, mr0), dot(camera._viewInverse[1].xyz, mr1), dot(camera._viewInverse[1].xyz, mr2));
|
||||
vec3 mvc2 = vec3(dot(camera._viewInverse[2].xyz, mr0), dot(camera._viewInverse[2].xyz, mr1), dot(camera._viewInverse[2].xyz, mr2));
|
||||
|
||||
vec3 result = vec3(dot(mvc0, dir), dot(mvc1, dir), dot(mvc2, dir));
|
||||
|
||||
return result;
|
||||
<@endif@>
|
||||
}
|
||||
|
||||
<@if GLPROFILE == PC_GL@>
|
||||
uniform transformObjectBuffer {
|
||||
TransformObject object;
|
||||
};
|
||||
TransformObject getTransformObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
uniform transformCameraBuffer {
|
||||
TransformCamera camera;
|
||||
};
|
||||
TransformCamera getTransformCamera() {
|
||||
return camera;
|
||||
}
|
||||
<@elif GLPROFILE == MAC_GL@>
|
||||
TransformObject getTransformObject() {
|
||||
TransformObject object;
|
||||
return object;
|
||||
}
|
||||
|
||||
TransformCamera getTransformCamera() {
|
||||
TransformCamera camera;
|
||||
return camera;
|
||||
}
|
||||
<@else@>
|
||||
|
||||
TransformObject getTransformObject() {
|
||||
TransformObject object;
|
||||
return object;
|
||||
}
|
||||
|
||||
TransformCamera getTransformCamera() {
|
||||
TransformCamera camera;
|
||||
return camera;
|
||||
}
|
||||
|
||||
<@endif@>
|
||||
|
||||
|
||||
<@endif@>
|
|
@ -1,4 +1,6 @@
|
|||
set(TARGET_NAME model)
|
||||
|
||||
AUTOSCRIBE_SHADER_LIB(gpu)
|
||||
|
||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||
setup_hifi_library()
|
||||
|
|
4
libraries/render-utils/src/Light.slh → libraries/model/src/model/Light.slh
Executable file → Normal file
4
libraries/render-utils/src/Light.slh → libraries/model/src/model/Light.slh
Executable file → Normal file
|
@ -8,8 +8,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
!>
|
||||
<@if not LIGHT_SLH@>
|
||||
<@def LIGHT_SLH@>
|
||||
<@if not MODEL_LIGHT_SLH@>
|
||||
<@def MODEL_LIGHT_SLH@>
|
||||
|
||||
struct Light {
|
||||
vec4 _position;
|
8
libraries/render-utils/src/Material.slh → libraries/model/src/model/Material.slh
Executable file → Normal file
8
libraries/render-utils/src/Material.slh → libraries/model/src/model/Material.slh
Executable file → Normal file
|
@ -8,8 +8,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
!>
|
||||
<@if not MATERIAL_SLH@>
|
||||
<@def MATERIAL_SLH@>
|
||||
<@if not MODEL_MATERIAL_SLH@>
|
||||
<@def MODEL_MATERIAL_SLH@>
|
||||
|
||||
struct Material {
|
||||
vec4 _diffuse;
|
||||
|
@ -26,10 +26,10 @@ float getMaterialShininess(Material m) { return m._specular.a; }
|
|||
|
||||
<@if GLPROFILE == PC_GL@>
|
||||
uniform materialBuffer {
|
||||
Material mat;
|
||||
Material _mat;
|
||||
};
|
||||
Material getMaterial() {
|
||||
return mat;
|
||||
return _mat;
|
||||
}
|
||||
<@elif GLPROFILE == MAC_GL@>
|
||||
uniform vec4 materialBuffer[2];
|
|
@ -34,7 +34,8 @@ AddressManager::AddressManager() :
|
|||
_rootPlaceName(),
|
||||
_rootPlaceID(),
|
||||
_positionGetter(NULL),
|
||||
_orientationGetter(NULL)
|
||||
_orientationGetter(NULL),
|
||||
_localDSPortSharedMem(NULL)
|
||||
{
|
||||
connect(qApp, &QCoreApplication::aboutToQuit, this, &AddressManager::storeCurrentAddress);
|
||||
}
|
||||
|
@ -152,8 +153,15 @@ void AddressManager::handleLookupString(const QString& lookupString) {
|
|||
if (!lookupString.startsWith('/')) {
|
||||
const QRegExp HIFI_SCHEME_REGEX = QRegExp(HIFI_URL_SCHEME + ":\\/{1,2}", Qt::CaseInsensitive);
|
||||
sanitizedString = sanitizedString.remove(HIFI_SCHEME_REGEX);
|
||||
|
||||
quint16 localDomainServerPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
if (sanitizedString == "localhost") {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
nodeList->getLocalServerPortFromSharedMemory
|
||||
(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, _localDSPortSharedMem, localDomainServerPort);
|
||||
}
|
||||
|
||||
lookupURL = QUrl(HIFI_URL_SCHEME + "://" + sanitizedString);
|
||||
lookupURL = QUrl(HIFI_URL_SCHEME + "://" + sanitizedString + ":" + QString::number(localDomainServerPort));
|
||||
} else {
|
||||
lookupURL = QUrl(lookupString);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#define hifi_AddressManager_h
|
||||
|
||||
#include <qobject.h>
|
||||
#include <QSharedMemory>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
@ -94,6 +95,8 @@ private:
|
|||
QUuid _rootPlaceID;
|
||||
PositionGetter _positionGetter;
|
||||
OrientationGetter _orientationGetter;
|
||||
|
||||
QSharedMemory* _localDSPortSharedMem; // memory shared with domain server
|
||||
};
|
||||
|
||||
#endif // hifi_AddressManager_h
|
||||
#endif // hifi_AddressManager_h
|
||||
|
|
|
@ -96,6 +96,13 @@ void LimitedNodeList::setSessionUUID(const QUuid& sessionUUID) {
|
|||
}
|
||||
}
|
||||
|
||||
void LimitedNodeList::setThisNodeCanAdjustLocks(bool canAdjustLocks) {
|
||||
if (_thisNodeCanAdjustLocks != canAdjustLocks) {
|
||||
_thisNodeCanAdjustLocks = canAdjustLocks;
|
||||
emit canAdjustLocksChanged(canAdjustLocks);
|
||||
}
|
||||
}
|
||||
|
||||
QUdpSocket& LimitedNodeList::getDTLSSocket() {
|
||||
if (!_dtlsSocket) {
|
||||
// DTLS socket getter called but no DTLS socket exists, create it now
|
||||
|
@ -670,10 +677,9 @@ void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSock
|
|||
writeUnverifiedDatagram(iceRequestByteArray, iceServerSockAddr);
|
||||
}
|
||||
|
||||
void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* parent) {
|
||||
void LimitedNodeList::putLocalPortIntoSharedMemory(const QString key, QObject* parent, quint16 localPort) {
|
||||
// save our local port to shared memory so that assignment client children know how to talk to this parent
|
||||
QSharedMemory* sharedPortMem = new QSharedMemory(key, parent);
|
||||
quint16 localPort = getNodeSocket().localPort();
|
||||
|
||||
// attempt to create the shared memory segment
|
||||
if (sharedPortMem->create(sizeof(localPort)) || sharedPortMem->attach()) {
|
||||
|
|
|
@ -50,6 +50,8 @@ const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io";
|
|||
const unsigned short STUN_SERVER_PORT = 3478;
|
||||
|
||||
const QString DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY = "domain-server.local-port";
|
||||
const QString DOMAIN_SERVER_LOCAL_HTTP_PORT_SMEM_KEY = "domain-server.local-http-port";
|
||||
const QString DOMAIN_SERVER_LOCAL_HTTPS_PORT_SMEM_KEY = "domain-server.local-https-port";
|
||||
const QString ASSIGNMENT_CLIENT_MONITOR_LOCAL_PORT_SMEM_KEY = "assignment-client-monitor.local-port";
|
||||
|
||||
const char DEFAULT_ASSIGNMENT_CLIENT_MONITOR_HOSTNAME[] = "localhost";
|
||||
|
@ -82,8 +84,8 @@ public:
|
|||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||
void setSessionUUID(const QUuid& sessionUUID);
|
||||
|
||||
bool getThisNodeCanAdjustLocks() { return _thisNodeCanAdjustLocks; }
|
||||
void setThisNodeCanAdjustLocks(bool canAdjustLocks) { _thisNodeCanAdjustLocks = canAdjustLocks; }
|
||||
bool getThisNodeCanAdjustLocks() const { return _thisNodeCanAdjustLocks; }
|
||||
void setThisNodeCanAdjustLocks(bool canAdjustLocks);
|
||||
|
||||
void rebindNodeSocket();
|
||||
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
||||
|
@ -174,7 +176,7 @@ public:
|
|||
return SharedNodePointer();
|
||||
}
|
||||
|
||||
void putLocalPortIntoSharedMemory(const QString key, QObject* parent);
|
||||
void putLocalPortIntoSharedMemory(const QString key, QObject* parent, quint16 localPort);
|
||||
bool getLocalServerPortFromSharedMemory(const QString key, QSharedMemory*& sharedMem, quint16& localPort);
|
||||
|
||||
public slots:
|
||||
|
@ -194,6 +196,8 @@ signals:
|
|||
void localSockAddrChanged(const HifiSockAddr& localSockAddr);
|
||||
void publicSockAddrChanged(const HifiSockAddr& publicSockAddr);
|
||||
|
||||
void canAdjustLocksChanged(bool canAdjustLocks);
|
||||
|
||||
void dataSent(const quint8 channel_type, const int bytes);
|
||||
void dataReceived(const quint8 channel_type, const int bytes);
|
||||
|
||||
|
|
|
@ -577,6 +577,10 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom
|
|||
// compute our dimensions the usual way
|
||||
float hheight = _nearClip * tanf(_fieldOfView * 0.5f * RADIANS_PER_DEGREE);
|
||||
float hwidth = _aspectRatio * hheight;
|
||||
if (isOrthographic()) {
|
||||
hheight = getHeight();
|
||||
hwidth = getWidth();
|
||||
}
|
||||
|
||||
// get our frustum corners in view space
|
||||
glm::mat4 eyeMatrix = glm::mat4_cast(glm::inverse(_eyeOffsetOrientation)) * glm::translate(-_eyeOffsetPosition);
|
||||
|
@ -866,4 +870,20 @@ float ViewFrustum::distanceToCamera(const glm::vec3& point) const {
|
|||
return distanceToPoint;
|
||||
}
|
||||
|
||||
void ViewFrustum::evalProjectionMatrix(glm::mat4& proj) const {
|
||||
if (isOrthographic()) {
|
||||
glm::vec3 frustumCenter = glm::inverse( _orientation) * _position;
|
||||
|
||||
proj = glm::ortho(frustumCenter.x -0.5f * getWidth(),
|
||||
frustumCenter.x +0.5f * getWidth(),
|
||||
frustumCenter.y -0.5f * getHeight(),
|
||||
frustumCenter.y +0.5f * getHeight(),
|
||||
-getFarClip(), -getNearClip());
|
||||
} else {
|
||||
float left, right, bottom, top, near, far;
|
||||
glm::vec4 clip0, clip1;
|
||||
computeOffAxisFrustum(left, right, bottom, top, near, far, clip0, clip1);
|
||||
proj = glm::perspective(glm::radians(getFieldOfView()), getAspectRatio(), getNearClip(), getFarClip());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ public:
|
|||
|
||||
float distanceToCamera(const glm::vec3& point) const;
|
||||
|
||||
void evalProjectionMatrix(glm::mat4& proj) const;
|
||||
private:
|
||||
// Used for keyhole calculations
|
||||
ViewFrustum::location pointInKeyhole(const glm::vec3& point) const;
|
||||
|
|
|
@ -281,6 +281,11 @@ void PhysicsEngine::stepSimulation() {
|
|||
// This is step (1).
|
||||
relayIncomingChangesToSimulation();
|
||||
|
||||
if (_avatarData->isPhysicsEnabled()) {
|
||||
_avatarGhostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()),
|
||||
glmToBullet(_avatarData->getPosition())));
|
||||
}
|
||||
|
||||
const int MAX_NUM_SUBSTEPS = 4;
|
||||
const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP;
|
||||
float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds());
|
||||
|
@ -303,9 +308,18 @@ void PhysicsEngine::stepSimulation() {
|
|||
//
|
||||
// TODO: untangle these lock sequences.
|
||||
_entityTree->lockForWrite();
|
||||
_avatarData->lockForWrite();
|
||||
lock();
|
||||
_dynamicsWorld->synchronizeMotionStates();
|
||||
|
||||
if (_avatarData->isPhysicsEnabled()) {
|
||||
const btTransform& avatarTransform = _avatarGhostObject->getWorldTransform();
|
||||
_avatarData->setOrientation(bulletToGLM(avatarTransform.getRotation()));
|
||||
_avatarData->setPosition(bulletToGLM(avatarTransform.getOrigin()));
|
||||
}
|
||||
|
||||
unlock();
|
||||
_avatarData->unlock();
|
||||
_entityTree->unlock();
|
||||
|
||||
computeCollisionEvents();
|
||||
|
@ -348,6 +362,48 @@ void PhysicsEngine::computeCollisionEvents() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// avatar collisions
|
||||
btManifoldArray manifoldArray;
|
||||
btBroadphasePairArray& pairArray = _avatarGhostObject->getOverlappingPairCache()->getOverlappingPairArray();
|
||||
int numPairs = pairArray.size();
|
||||
|
||||
for (int i=0;i<numPairs;i++) {
|
||||
manifoldArray.clear();
|
||||
const btBroadphasePair& pair = pairArray[i];
|
||||
// unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
|
||||
btBroadphasePair* collisionPair = _dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0, pair.m_pProxy1);
|
||||
if (!collisionPair) {
|
||||
continue;
|
||||
}
|
||||
if (collisionPair->m_algorithm) {
|
||||
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
|
||||
}
|
||||
|
||||
for (int j=0;j<manifoldArray.size();j++) {
|
||||
btPersistentManifold* manifold = manifoldArray[j];
|
||||
btScalar directionSign = manifold->getBody0() == _avatarGhostObject ? btScalar(-1.0) : btScalar(1.0);
|
||||
for (int p=0; p<manifold->getNumContacts(); p++) {
|
||||
const btManifoldPoint& pt = manifold->getContactPoint(p);
|
||||
if (pt.getDistance() < 0.f) {
|
||||
|
||||
|
||||
const btVector3& ptA = pt.getPositionWorldOnA();
|
||||
const btVector3& ptB = pt.getPositionWorldOnB();
|
||||
const btVector3& normalOnB = pt.m_normalWorldOnB;
|
||||
/// work here
|
||||
qDebug() << "HERE";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// We harvest collision callbacks every few frames, which contributes the following effects:
|
||||
//
|
||||
|
@ -587,35 +643,33 @@ bool PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio
|
|||
|
||||
|
||||
void PhysicsEngine::setAvatarData(AvatarData *avatarData) {
|
||||
btTransform startTransform = btTransform (glmToBullet(avatarData->getOrientation()),
|
||||
glmToBullet(avatarData->getPosition()));
|
||||
|
||||
class btPairCachingGhostObject* m_ghostObject = new btPairCachingGhostObject();
|
||||
m_ghostObject->setWorldTransform(startTransform);
|
||||
_avatarData = avatarData;
|
||||
_avatarGhostObject = new btPairCachingGhostObject();
|
||||
_avatarGhostObject->setWorldTransform(btTransform(glmToBullet(_avatarData->getOrientation()),
|
||||
glmToBullet(_avatarData->getPosition())));
|
||||
|
||||
btScalar characterHeight = 1.75;
|
||||
btScalar characterWidth = 1.75;
|
||||
btScalar stepHeight = btScalar(0.35);
|
||||
|
||||
btConvexShape* capsule = new btCapsuleShape(characterWidth, characterHeight);
|
||||
m_ghostObject->setCollisionShape(capsule);
|
||||
m_ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
_avatarGhostObject->setCollisionShape(capsule);
|
||||
_avatarGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
|
||||
_characterController = new btKinematicCharacterController(m_ghostObject, capsule, stepHeight);
|
||||
_characterController = new btKinematicCharacterController(_avatarGhostObject, capsule, stepHeight);
|
||||
|
||||
// PhysicsSimulation _physicsSimulation
|
||||
// PhysicsEngine --> ThreadSafeDynamicsWorld* _dynamicsWorld = NULL;
|
||||
// PhysicsEngine Application::_physicsEngine
|
||||
|
||||
// ThreadSafeDynamicsWorld* dynamicsWorld;
|
||||
// dynamicsWorld = Application::getInstance()->_physicsEngine;
|
||||
_dynamicsWorld->addCollisionObject(m_ghostObject, btBroadphaseProxy::CharacterFilter,
|
||||
_dynamicsWorld->addCollisionObject(_avatarGhostObject, btBroadphaseProxy::CharacterFilter,
|
||||
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
|
||||
_dynamicsWorld->addAction(_characterController);
|
||||
_characterController->reset (_dynamicsWorld);
|
||||
// _characterController->warp (btVector3(10.210001,-2.0306311,16.576973));
|
||||
|
||||
btGhostPairCallback* ghostPairCallback = new btGhostPairCallback();
|
||||
_dynamicsWorld->getPairCache()->setInternalGhostPairCallback(ghostPairCallback);
|
||||
}
|
||||
|
||||
|
||||
// void PhysicsEngine::setAvatarMotion(AvatarData *avatarData) {
|
||||
// void PhysicsEngine::setAvatarMotion() {
|
||||
/*
|
||||
float dt = getDeltaTimeMicroseconds() * 0.000001f;
|
||||
btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
|
||||
|
|
|
@ -123,7 +123,9 @@ private:
|
|||
uint32_t _lastNumSubstepsAtUpdateInternal = 0;
|
||||
|
||||
/// character collisions
|
||||
btCharacterControllerInterface* _characterController;
|
||||
btCharacterControllerInterface* _characterController = 0;
|
||||
class btPairCachingGhostObject* _avatarGhostObject = 0;
|
||||
AvatarData *_avatarData = 0;
|
||||
};
|
||||
|
||||
#endif // hifi_PhysicsEngine_h
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME render-utils)
|
||||
|
||||
AUTOSCRIBE_SHADER_LIB()
|
||||
AUTOSCRIBE_SHADER_LIB(gpu model)
|
||||
|
||||
# pull in the resources.qrc file
|
||||
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
|
||||
|
|
|
@ -32,6 +32,9 @@ public:
|
|||
|
||||
/// gets the current view frustum for rendering the view state
|
||||
virtual ViewFrustum* getCurrentViewFrustum() = 0;
|
||||
|
||||
/// gets the shadow view frustum for rendering the view state
|
||||
virtual ViewFrustum* getShadowViewFrustum() = 0;
|
||||
|
||||
virtual bool getShadowsEnabled() = 0;
|
||||
virtual bool getCascadeShadowsEnabled() = 0;
|
||||
|
|
|
@ -49,7 +49,7 @@ vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) {
|
|||
uniform SphericalHarmonics ambientSphere;
|
||||
|
||||
// Everything about light
|
||||
<@include Light.slh@>
|
||||
<@include model/Light.slh@>
|
||||
|
||||
// The view Matrix
|
||||
uniform mat4 invViewMat;
|
||||
|
@ -95,13 +95,15 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no
|
|||
vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) {
|
||||
|
||||
Light light = getLight();
|
||||
|
||||
vec3 fragNormal = vec3(invViewMat * vec4(normal, 0.0));
|
||||
float diffuseDot = dot(fragNormal, -getLightDirection(light));
|
||||
|
||||
|
||||
// need to catch normals perpendicular to the projection plane hence the magic number for the threshold
|
||||
// it should be just 0, but we have innacurracy so we need to overshoot
|
||||
const float PERPENDICULAR_THRESHOLD = -0.005;
|
||||
float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
|
||||
//float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot);
|
||||
|
||||
// evaluate the shadow test but only relevant for light facing fragments
|
||||
float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation;
|
||||
|
|
|
@ -53,18 +53,33 @@ const int NUM_COORDS_PER_VERTEX = 3;
|
|||
const int NUM_BYTES_PER_VERTEX = NUM_COORDS_PER_VERTEX * sizeof(GLfloat);
|
||||
const int NUM_BYTES_PER_INDEX = sizeof(GLushort);
|
||||
|
||||
void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm::vec4& color, bool solid) {
|
||||
void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm::vec4& color, bool solid, int id) {
|
||||
bool registered = (id != UNKNOWN_ID);
|
||||
|
||||
Vec2Pair radiusKey(glm::vec2(radius, slices), glm::vec2(stacks, 0));
|
||||
IntPair slicesStacksKey(slices, stacks);
|
||||
Vec3Pair colorKey(glm::vec3(color.x, color.y, slices), glm::vec3(color.z, color.y, stacks));
|
||||
Vec3Pair colorKey(glm::vec3(color.x, color.y, slices), glm::vec3(color.z, color.w, stacks));
|
||||
|
||||
int vertices = slices * (stacks - 1) + 2;
|
||||
int indices = slices * (stacks - 1) * NUM_VERTICES_PER_TRIANGULATED_QUAD;
|
||||
|
||||
if (!_sphereVertices.contains(radiusKey)) {
|
||||
if (registered && (!_registeredSphereVertices.contains(id) || _lastRegisteredSphereVertices[id] != radiusKey)
|
||||
|| !registered && !_sphereVertices.contains(radiusKey)) {
|
||||
|
||||
if (registered && _registeredSphereVertices.contains(id)) {
|
||||
_registeredSphereVertices[id].clear();
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "renderSphere()... RELEASING REGISTERED VERTICES BUFFER";
|
||||
#endif
|
||||
}
|
||||
|
||||
gpu::BufferPointer verticesBuffer(new gpu::Buffer());
|
||||
_sphereVertices[radiusKey] = verticesBuffer;
|
||||
if (registered) {
|
||||
_registeredSphereVertices[id] = verticesBuffer;
|
||||
_lastRegisteredSphereVertices[id] = radiusKey;
|
||||
} else {
|
||||
_sphereVertices[radiusKey] = verticesBuffer;
|
||||
}
|
||||
|
||||
GLfloat* vertexData = new GLfloat[vertices * NUM_COORDS_PER_VERTEX];
|
||||
GLfloat* vertex = vertexData;
|
||||
|
@ -106,10 +121,29 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
qDebug() << " _sphereVertices.size():" << _sphereVertices.size();
|
||||
#endif
|
||||
}
|
||||
#ifdef WANT_DEBUG
|
||||
else if (registered) {
|
||||
qDebug() << "renderSphere()... REUSING PREVIOUSLY REGISTERED VERTICES BUFFER";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!_sphereIndices.contains(slicesStacksKey)) {
|
||||
if (registered && (!_registeredSphereIndices.contains(id) || _lastRegisteredSphereIndices[id] != slicesStacksKey)
|
||||
|| !registered && !_sphereIndices.contains(slicesStacksKey)) {
|
||||
|
||||
if (registered && _registeredSphereIndices.contains(id)) {
|
||||
_registeredSphereIndices[id].clear();
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "renderSphere()... RELEASING REGISTERED INDICES BUFFER";
|
||||
#endif
|
||||
}
|
||||
|
||||
gpu::BufferPointer indicesBuffer(new gpu::Buffer());
|
||||
_sphereIndices[slicesStacksKey] = indicesBuffer;
|
||||
if (registered) {
|
||||
_registeredSphereIndices[id] = indicesBuffer;
|
||||
_lastRegisteredSphereIndices[id] = slicesStacksKey;
|
||||
} else {
|
||||
_sphereIndices[slicesStacksKey] = indicesBuffer;
|
||||
}
|
||||
|
||||
GLushort* indexData = new GLushort[indices];
|
||||
GLushort* index = indexData;
|
||||
|
@ -164,7 +198,7 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
delete[] indexData;
|
||||
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "GeometryCache::renderSphere()... --- CREATING INDEX BUFFER";
|
||||
qDebug() << "GeometryCache::renderSphere()... --- CREATING INDICES BUFFER";
|
||||
qDebug() << " radius:" << radius;
|
||||
qDebug() << " slices:" << slices;
|
||||
qDebug() << " stacks:" << stacks;
|
||||
|
@ -173,10 +207,29 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
qDebug() << " _sphereIndices.size():" << _sphereIndices.size();
|
||||
#endif
|
||||
}
|
||||
#ifdef WANT_DEBUG
|
||||
else if (registered) {
|
||||
qDebug() << "renderSphere()... REUSING PREVIOUSLY REGISTERED INDICES BUFFER";
|
||||
}
|
||||
#endif
|
||||
|
||||
if (registered && (!_registeredSphereColors.contains(id) || _lastRegisteredSphereColors[id] != colorKey)
|
||||
|| !registered && !_sphereColors.contains(colorKey)) {
|
||||
|
||||
if (registered && _registeredSphereColors.contains(id)) {
|
||||
_registeredSphereColors[id].clear();
|
||||
#ifdef WANT_DEBUG
|
||||
qDebug() << "renderSphere()... RELEASING REGISTERED COLORS BUFFER";
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!_sphereColors.contains(colorKey)) {
|
||||
gpu::BufferPointer colorBuffer(new gpu::Buffer());
|
||||
_sphereColors[colorKey] = colorBuffer;
|
||||
if (registered) {
|
||||
_registeredSphereColors[id] = colorBuffer;
|
||||
_lastRegisteredSphereColors[id] = colorKey;
|
||||
} else {
|
||||
_sphereColors[colorKey] = colorBuffer;
|
||||
}
|
||||
|
||||
int compactColor = ((int(color.x * 255.0f) & 0xFF)) |
|
||||
((int(color.y * 255.0f) & 0xFF) << 8) |
|
||||
|
@ -201,11 +254,16 @@ void GeometryCache::renderSphere(float radius, int slices, int stacks, const glm
|
|||
qDebug() << " stacks:" << stacks;
|
||||
qDebug() << " _sphereColors.size():" << _sphereColors.size();
|
||||
#endif
|
||||
|
||||
}
|
||||
gpu::BufferPointer verticesBuffer = _sphereVertices[radiusKey];
|
||||
gpu::BufferPointer indicesBuffer = _sphereIndices[slicesStacksKey];
|
||||
gpu::BufferPointer colorBuffer = _sphereColors[colorKey];
|
||||
#ifdef WANT_DEBUG
|
||||
else if (registered) {
|
||||
qDebug() << "renderSphere()... REUSING PREVIOUSLY REGISTERED COLORS BUFFER";
|
||||
}
|
||||
#endif
|
||||
|
||||
gpu::BufferPointer verticesBuffer = registered ? _registeredSphereVertices[id] : _sphereVertices[radiusKey];
|
||||
gpu::BufferPointer indicesBuffer = registered ? _registeredSphereIndices[id] : _sphereIndices[slicesStacksKey];
|
||||
gpu::BufferPointer colorBuffer = registered ? _registeredSphereColors[id] : _sphereColors[colorKey];
|
||||
|
||||
const int VERTICES_SLOT = 0;
|
||||
const int NORMALS_SLOT = 1;
|
||||
|
|
|
@ -134,10 +134,10 @@ public:
|
|||
|
||||
void renderCone(float base, float height, int slices, int stacks);
|
||||
|
||||
void renderSphere(float radius, int slices, int stacks, const glm::vec3& color, bool solid = true)
|
||||
{ renderSphere(radius, slices, stacks, glm::vec4(color, 1.0f), solid); }
|
||||
void renderSphere(float radius, int slices, int stacks, const glm::vec3& color, bool solid = true, int id = UNKNOWN_ID)
|
||||
{ renderSphere(radius, slices, stacks, glm::vec4(color, 1.0f), solid, id); }
|
||||
|
||||
void renderSphere(float radius, int slices, int stacks, const glm::vec4& color, bool solid = true);
|
||||
void renderSphere(float radius, int slices, int stacks, const glm::vec4& color, bool solid = true, int id = UNKNOWN_ID);
|
||||
void renderGrid(int xDivisions, int yDivisions, const glm::vec4& color);
|
||||
void renderGrid(int x, int y, int width, int height, int rows, int cols, const glm::vec4& color, int id = UNKNOWN_ID);
|
||||
void renderSolidCube(float size, const glm::vec4& color);
|
||||
|
@ -290,10 +290,15 @@ private:
|
|||
QHash<Vec3Pair, gpu::BufferPointer> _gridColors;
|
||||
|
||||
QHash<Vec2Pair, gpu::BufferPointer> _sphereVertices;
|
||||
QHash<int, gpu::BufferPointer> _registeredSphereVertices;
|
||||
QHash<int, Vec2Pair> _lastRegisteredSphereVertices;
|
||||
QHash<IntPair, gpu::BufferPointer> _sphereIndices;
|
||||
QHash<int, gpu::BufferPointer> _registeredSphereIndices;
|
||||
QHash<int, IntPair> _lastRegisteredSphereIndices;
|
||||
QHash<Vec3Pair, gpu::BufferPointer> _sphereColors;
|
||||
|
||||
|
||||
QHash<int, gpu::BufferPointer> _registeredSphereColors;
|
||||
QHash<int, Vec3Pair> _lastRegisteredSphereColors;
|
||||
|
||||
QHash<QUrl, QWeakPointer<NetworkGeometry> > _networkGeometry;
|
||||
};
|
||||
|
||||
|
|
|
@ -223,6 +223,23 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
loc = glGetUniformBlockIndex(program.programId(), "transformObjectBuffer");
|
||||
if (loc >= 0) {
|
||||
glUniformBlockBinding(program.programId(), loc, gpu::TRANSFORM_OBJECT_SLOT);
|
||||
// locations.materialBufferUnit = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
loc = glGetUniformBlockIndex(program.programId(), "transformCameraBuffer");
|
||||
if (loc >= 0) {
|
||||
glUniformBlockBinding(program.programId(), loc, gpu::TRANSFORM_CAMERA_SLOT);
|
||||
// locations.materialBufferUnit = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
//program.link();
|
||||
if (!program.isLinked()) {
|
||||
program.release();
|
||||
}
|
||||
|
@ -323,6 +340,9 @@ void Model::init() {
|
|||
|
||||
_shadowProgram.addShaderFromSourceCode(QGLShader::Vertex, model_shadow_vert);
|
||||
_shadowProgram.addShaderFromSourceCode(QGLShader::Fragment, model_shadow_frag);
|
||||
// Shadow program uses the same locations as standard rendering path but we still need to set the bindings
|
||||
Model::Locations tempLoc;
|
||||
initProgram(_shadowProgram, tempLoc);
|
||||
|
||||
_skinProgram.addShaderFromSourceCode(QGLShader::Vertex, skin_model_vert);
|
||||
_skinProgram.addShaderFromSourceCode(QGLShader::Fragment, model_frag);
|
||||
|
@ -667,7 +687,7 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
// render the attachments
|
||||
foreach (Model* attachment, _attachments) {
|
||||
attachment->render(alpha, mode);
|
||||
attachment->render(alpha, mode, args);
|
||||
}
|
||||
if (_meshStates.isEmpty()) {
|
||||
return false;
|
||||
|
@ -687,6 +707,13 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
_renderBatch.clear();
|
||||
gpu::Batch& batch = _renderBatch;
|
||||
|
||||
// Setup the projection matrix
|
||||
if (args && args->_viewFrustum) {
|
||||
glm::mat4 proj;
|
||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||
batch.setProjectionTransform(proj);
|
||||
}
|
||||
|
||||
// Capture the view matrix once for the rendering of this model
|
||||
if (_transforms.empty()) {
|
||||
_transforms.push_back(Transform());
|
||||
|
@ -1659,11 +1686,26 @@ void Model::setupBatchTransform(gpu::Batch& batch) {
|
|||
void Model::endScene(RenderMode mode, RenderArgs* args) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
#if defined(ANDROID)
|
||||
#else
|
||||
glPushMatrix();
|
||||
#endif
|
||||
|
||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO;
|
||||
if (args) {
|
||||
renderSide = args->_renderSide;
|
||||
}
|
||||
|
||||
gpu::GLBackend backend;
|
||||
|
||||
if (args) {
|
||||
glm::mat4 proj;
|
||||
args->_viewFrustum->evalProjectionMatrix(proj);
|
||||
gpu::Batch batch;
|
||||
batch.setProjectionTransform(proj);
|
||||
backend.render(batch);
|
||||
}
|
||||
|
||||
// Do the rendering batch creation for mono or left eye, not for right eye
|
||||
if (renderSide != RenderArgs::STEREO_RIGHT) {
|
||||
// Let's introduce a gpu::Batch to capture all the calls to the graphics api
|
||||
|
@ -1818,19 +1860,15 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
// Render!
|
||||
{
|
||||
PROFILE_RANGE("render Batch");
|
||||
#if defined(ANDROID)
|
||||
#else
|
||||
glPushMatrix();
|
||||
#endif
|
||||
|
||||
::gpu::GLBackend::renderBatch(_sceneRenderBatch);
|
||||
|
||||
#if defined(ANDROID)
|
||||
#else
|
||||
glPopMatrix();
|
||||
#endif
|
||||
backend.render(_sceneRenderBatch);
|
||||
}
|
||||
|
||||
|
||||
#if defined(ANDROID)
|
||||
#else
|
||||
glPopMatrix();
|
||||
#endif
|
||||
|
||||
// restore all the default material settings
|
||||
_viewState->setupWorldLight();
|
||||
|
||||
|
|
|
@ -269,6 +269,9 @@ protected:
|
|||
/// first free ancestor.
|
||||
float getLimbLength(int jointIndex) const;
|
||||
|
||||
/// Allow sub classes to force invalidating the bboxes
|
||||
void invalidCalculatedMeshBoxes() { _calculatedMeshBoxesValid = false; }
|
||||
|
||||
private:
|
||||
|
||||
friend class AnimationHandle;
|
||||
|
|
|
@ -31,6 +31,8 @@ uniform vec3 shadowDistances;
|
|||
// the inverse of the size of the shadow map
|
||||
uniform float shadowScale;
|
||||
|
||||
uniform mat4 shadowMatrices[4];
|
||||
|
||||
vec2 samples[8] = vec2[8](
|
||||
vec2(-2.0, -2.0),
|
||||
vec2(2.0, -2.0),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.frag
|
||||
|
@ -13,7 +13,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// model.vert
|
||||
|
@ -11,6 +11,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
@ -19,16 +20,19 @@ uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
|||
varying vec4 normal;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal for interpolation
|
||||
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color;
|
||||
|
||||
// and the texture coordinates
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
||||
// use standard pipeline transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
gl_Position = transformModelToClipPos(cam, obj, gl_Vertex);
|
||||
|
||||
// transform and store the normal for interpolation
|
||||
normal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -12,6 +12,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
@ -25,9 +27,6 @@ varying vec4 normal;
|
|||
varying vec2 interpolatedTexcoord1;
|
||||
|
||||
void main(void) {
|
||||
// transform and store the normal for interpolation
|
||||
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color;
|
||||
|
||||
|
@ -35,8 +34,13 @@ void main(void) {
|
|||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||
// interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0)).xy;
|
||||
interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(texcoord1.xy, 0.0, 1.0)).xy;
|
||||
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
gl_Position = transformModelToClipPos(cam, obj, gl_Vertex);
|
||||
|
||||
// transform and store the normal for interpolation
|
||||
normal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -12,6 +12,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
@ -32,8 +34,8 @@ varying vec2 interpolatedTexcoord1;
|
|||
|
||||
void main(void) {
|
||||
// transform and store the normal and tangent for interpolation
|
||||
interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
//interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
//interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color;
|
||||
|
@ -43,5 +45,11 @@ void main(void) {
|
|||
interpolatedTexcoord1 = vec2(texcoordMatrices[1] * vec4(texcoord1.xy, 0.0, 1.0)).xy;
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
gl_Position = transformModelToClipPos(cam, obj, gl_Vertex);
|
||||
|
||||
// transform and store the normal for interpolation
|
||||
interpolatedNormal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0);
|
||||
interpolatedTangent = vec4(normalize(transformModelToEyeDir(cam, obj, tangent)), 0.0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -12,6 +12,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
||||
uniform mat4 texcoordMatrices[MAX_TEXCOORDS];
|
||||
|
@ -27,8 +29,8 @@ varying vec4 interpolatedTangent;
|
|||
|
||||
void main(void) {
|
||||
// transform and store the normal and tangent for interpolation
|
||||
interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
//interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0);
|
||||
//interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0);
|
||||
|
||||
// pass along the diffuse color
|
||||
gl_FrontColor = gl_Color;
|
||||
|
@ -36,6 +38,12 @@ void main(void) {
|
|||
// and the texture coordinates
|
||||
gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);
|
||||
|
||||
// use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
// use standard pipeline transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
gl_Position = transformModelToClipPos(cam, obj, gl_Vertex);
|
||||
|
||||
// transform and store the normal for interpolation
|
||||
interpolatedNormal = vec4(normalize(transformModelToEyeDir(cam, obj, gl_Normal)), 0.0);
|
||||
interpolatedTangent = vec4(normalize(transformModelToEyeDir(cam, obj, tangent)), 0.0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -11,8 +11,11 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
void main(void) {
|
||||
// just use standard pipeline transform
|
||||
gl_Position = ftransform();
|
||||
// use standard pipeline transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
gl_Position = transformModelToClipPos(cam, obj, gl_Vertex);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -14,7 +14,7 @@
|
|||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
<@include Material.slh@>
|
||||
<@include model/Material.slh@>
|
||||
|
||||
// the diffuse texture
|
||||
uniform sampler2D diffuseMap;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
@ -19,7 +19,7 @@
|
|||
<@include DeferredLighting.slh@>
|
||||
|
||||
// Everything about light
|
||||
<@include Light.slh@>
|
||||
<@include model/Light.slh@>
|
||||
|
||||
// The view Matrix
|
||||
uniform mat4 invViewMat;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// sdf_text.frag
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
// sdf_text.vert
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<@include Config.slh@>
|
||||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue