Merge branch 'master' of github.com:highfidelity/hifi into safe-teleport-target

This commit is contained in:
sabrina-shanman 2018-08-13 14:51:37 -07:00
commit e5cb078133
506 changed files with 12153 additions and 7590 deletions

View file

@ -1,3 +1,10 @@
### OS Specific Build Guides
* [BUILD_WIN.md](BUILD_WIN.md) - complete instructions for Windows.
* [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X.
* [BUILD_LINUX.md](BUILD_LINUX.md) - additional instructions for Linux.
* [BUILD_ANDROID.md](BUILD_ANDROID.md) - additional instructions for Android
### Dependencies
- [cmake](https://cmake.org/download/): 3.9
@ -27,14 +34,7 @@ These are not placed in your normal build tree when doing an out of source build
If you would like to use a specific install of a dependency instead of the version that would be grabbed as a CMake ExternalProject, you can pass -DUSE\_LOCAL\_$NAME=0 (where $NAME is the name of the subfolder in [cmake/externals](cmake/externals)) when you run CMake to tell it not to get that dependency as an external project.
### OS Specific Build Guides
* [BUILD_OSX.md](BUILD_OSX.md) - additional instructions for OS X.
* [BUILD_LINUX.md](BUILD_LINUX.md) - additional instructions for Linux.
* [BUILD_WIN.md](BUILD_WIN.md) - additional instructions for Windows.
* [BUILD_ANDROID.md](BUILD_ANDROID.md) - additional instructions for Android
### CMake
#### CMake
Hifi uses CMake to generate build files and project files for your platform.
@ -80,6 +80,7 @@ In the examples below the variable $NAME would be replaced by the name of the de
* $NAME_ROOT_DIR - set this variable in your ENV
* HIFI_LIB_DIR - set this variable in your ENV to your High Fidelity lib folder, should contain a folder '$name'
### Optional Components
#### Devices

View file

@ -15,6 +15,7 @@ include("cmake/compiler.cmake")
if (BUILD_SCRIBE_ONLY)
add_subdirectory(tools/scribe)
add_subdirectory(tools/shader_reflect)
return()
endif()

View file

@ -24,6 +24,7 @@ android {
'-DANDROID_STL=c++_shared',
'-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake',
'-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX,
'-DNATIVE_SHREFLECT=' + HIFI_ANDROID_PRECOMPILED + '/shreflect' + EXEC_SUFFIX,
'-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED,
'-DRELEASE_NUMBER=' + RELEASE_NUMBER,
'-DRELEASE_TYPE=' + RELEASE_TYPE,

View file

@ -164,18 +164,29 @@ def packages = [
def scribeLocalFile='scribe' + EXEC_SUFFIX
def scribeFile='scribe_linux_x86_64'
def scribeChecksum='ca4b904f52f4f993c29175ba96798fa6'
def scribeVersion='u_iTrJDaE95i2abTPXOpPZckGBIim53G'
def shreflectLocalFile='shreflect' + EXEC_SUFFIX
def shreflectFile='shreflect_linux_x86_64'
def shreflectChecksum='d6094a8580066c0b6f4e80b5adfb1d98'
def shreflectVersion='jnrpudh6fptIg6T2.Z6fgKP2ultAdKmE'
if (Os.isFamily(Os.FAMILY_MAC)) {
scribeFile = 'scribe_osx_x86_64'
scribeChecksum='72db9d32d4e1e50add755570ac5eb749'
scribeVersion='DAW0DmnjCRib4MD8x93bgc2Z2MpPojZC'
shreflectFile='shreflect_osx_x86_64'
shreflectChecksum='d613ef0703c21371fee93fd2e54b964f'
shreflectVersion='.rYNzjSFq6WtWDnE5KIKRIAGyJtr__ad'
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
scribeFile = 'scribe_win32_x86_64.exe'
scribeChecksum='678e43d290c90fda670c6fefe038a06d'
scribeVersion='PuullrA_bPlO9kXZRt8rLe536X1UI.m7'
shreflectFile='shreflect_win32_x86_64.exe'
shreflectChecksum='6f4a77b8cceb3f1bbc655132c3665060'
shreflectVersion='iIyCyza1nelkbI7ihybF59bBlwrfAC3D'
}
def options = [
@ -450,11 +461,27 @@ task fixScribePermissions(type: Exec, dependsOn: verifyScribe) {
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + scribeLocalFile
}
task setupScribe(dependsOn: verifyScribe) { }
task downloadShreflect(type: Download) {
src baseUrl + shreflectFile + '?versionId=' + shreflectVersion
dest new File(baseFolder, shreflectLocalFile)
onlyIfNewer true
}
task verifyShreflect(type: Verify, dependsOn: downloadShreflect) {
src new File(baseFolder, shreflectLocalFile);
checksum shreflectChecksum
}
task fixShreflectPermissions(type: Exec, dependsOn: verifyShreflect) {
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + shreflectLocalFile
}
task setupScribe(dependsOn: [verifyScribe, verifyShreflect]) { }
// On Windows, we don't need to set the executable bit, but on OSX and Unix we do
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
setupScribe.dependsOn fixScribePermissions
setupScribe.dependsOn fixShreflectPermissions
}
task extractGvrBinaries(dependsOn: extractDependencies) {

View file

@ -368,7 +368,6 @@ void Agent::executeScript() {
// give scripts access to the Users object
_scriptEngine->registerGlobalObject("Users", DependencyManager::get<UsersScriptingInterface>().data());
auto player = DependencyManager::get<recording::Deck>();
connect(player.data(), &recording::Deck::playbackStateChanged, [=] {
if (player->isPlaying()) {

View file

@ -11,6 +11,8 @@
#include "AssignmentClientApp.h"
#include <iostream>
#include <QtCore/QCommandLineParser>
#include <QtCore/QDir>
#include <QtCore/QStandardPaths>
@ -42,9 +44,8 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
// parse command-line
QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity Assignment Client");
parser.addHelpOption();
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
QString typeDescription = "run single assignment client of given type\n# | Type\n============================";
for (Assignment::Type type = Assignment::FirstType;
@ -97,11 +98,16 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
parser.addOption(parentPIDOption);
if (!parser.parse(QCoreApplication::arguments())) {
qCritical() << parser.errorText() << endl;
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam
parser.showHelp();
Q_UNREACHABLE();
}
if (parser.isSet(versionOption)) {
parser.showVersion();
Q_UNREACHABLE();
}
if (parser.isSet(helpOption)) {
parser.showHelp();
Q_UNREACHABLE();

View file

@ -643,6 +643,7 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage>
auto start = usecTimestampNow();
auto nodeList = DependencyManager::get<NodeList>();
AvatarMixerClientData* nodeData = reinterpret_cast<AvatarMixerClientData*>(senderNode->getLinkedData());
bool addToIgnore;
message->readPrimitive(&addToIgnore);
while (message->getBytesLeftToRead()) {
@ -650,17 +651,22 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer<ReceivedMessage>
QUuid ignoredUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
if (nodeList->nodeWithUUID(ignoredUUID)) {
// Reset the lastBroadcastTime for the ignored avatar to 0
// so the AvatarMixer knows it'll have to send identity data about the ignored avatar
// to the ignorer if the ignorer unignores.
nodeData->setLastBroadcastTime(ignoredUUID, 0);
if (nodeData) {
// Reset the lastBroadcastTime for the ignored avatar to 0
// so the AvatarMixer knows it'll have to send identity data about the ignored avatar
// to the ignorer if the ignorer unignores.
nodeData->setLastBroadcastTime(ignoredUUID, 0);
}
// Reset the lastBroadcastTime for the ignorer (FROM THE PERSPECTIVE OF THE IGNORED) to 0
// so the AvatarMixer knows it'll have to send identity data about the ignorer
// to the ignored if the ignorer unignores.
auto ignoredNode = nodeList->nodeWithUUID(ignoredUUID);
AvatarMixerClientData* ignoredNodeData = reinterpret_cast<AvatarMixerClientData*>(ignoredNode->getLinkedData());
ignoredNodeData->setLastBroadcastTime(senderNode->getUUID(), 0);
if (ignoredNodeData) {
ignoredNodeData->setLastBroadcastTime(senderNode->getUUID(), 0);
}
}
if (addToIgnore) {

View file

@ -1,10 +1,12 @@
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if (NOT "${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
message( FATAL_ERROR "Only 64 bit builds supported." )
endif()
if (WIN32)
if (NOT "${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
message( FATAL_ERROR "Only 64 bit builds supported." )
endif()
add_definitions(-DNOMINMAX -D_CRT_SECURE_NO_WARNINGS)
if (NOT WINDOW_SDK_PATH)
@ -52,32 +54,27 @@ endif()
if (ANDROID)
# assume that the toolchain selected for android has C++11 support
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
elseif(APPLE)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --stdlib=libc++")
if (CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
set(CMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Release] "YES")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Release] "dwarf-with-dsym")
set(CMAKE_XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING[variant=Release] "YES")
endif()
elseif ((NOT MSVC12) AND (NOT MSVC14))
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
if (COMPILER_SUPPORTS_CXX14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
endif ()
if (CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
set(CMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Release] "YES")
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Release] "dwarf-with-dsym")
set(CMAKE_XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING[variant=Release] "YES")
endif()
if (APPLE)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --stdlib=libc++")
endif ()
if (NOT ANDROID_LIB_DIR)
set(ANDROID_LIB_DIR $ENV{ANDROID_LIB_DIR})
@ -110,4 +107,4 @@ if (APPLE)
# set that as the SDK to use
set(CMAKE_OSX_SYSROOT ${_OSX_DESIRED_SDK_PATH}/MacOSX${OSX_SDK}.sdk)
endif ()
endif ()
endif ()

22
cmake/externals/json/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,22 @@
set(EXTERNAL_NAME json)
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL https://hifi-public.s3.amazonaws.com/dependencies/json_3.1.2.zip
URL_MD5 94dbf6ea25a7569ddc0ab6e20862cf16
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EXTERNAL_ARGS}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD 1
)
# Hide this external target (for ide users)
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR} CACHE PATH "List of json include directories")

View file

@ -8,6 +8,12 @@
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
function(global_append varName varValue)
get_property(LOCAL_LIST GLOBAL PROPERTY ${varName})
list(APPEND LOCAL_LIST ${varValue})
set_property(GLOBAL PROPERTY ${varName} ${LOCAL_LIST})
endfunction()
function(AUTOSCRIBE_SHADER SHADER_FILE)
# Grab include files
foreach(includeFile ${ARGN})
@ -45,11 +51,8 @@ function(AUTOSCRIBE_SHADER SHADER_FILE)
elseif(${SHADER_EXT} STREQUAL .slg)
set(SHADER_TYPE geom)
endif()
set(SHADER_TARGET ${SHADER_TARGET}_${SHADER_TYPE})
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_TARGET}")
set(SHADER_TARGET_HEADER ${SHADER_TARGET}.h)
set(SHADER_TARGET_SOURCE ${SHADER_TARGET}.cpp)
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_TARGET}.${SHADER_TYPE}")
set(SCRIBE_COMMAND scribe)
# Target dependant Custom rule on the SHADER_FILE
@ -63,65 +66,232 @@ function(AUTOSCRIBE_SHADER SHADER_FILE)
else ()
set(GLPROFILE PC_GL)
endif()
set(SCRIBE_ARGS -c++ -T ${SHADER_TYPE} -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
set(SCRIBE_ARGS -T ${SHADER_TYPE} -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
add_custom_command(
OUTPUT ${SHADER_TARGET_HEADER} ${SHADER_TARGET_SOURCE}
OUTPUT ${SHADER_TARGET}
COMMAND ${SCRIBE_COMMAND} ${SCRIBE_ARGS}
DEPENDS ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES} ${SHADER_FILE}
DEPENDS ${SHADER_FILE} ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES}
)
#output the generated file name
set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET_HEADER} ${SHADER_TARGET_SOURCE} PARENT_SCOPE)
file(GLOB INCLUDE_FILES ${SHADER_TARGET_HEADER})
set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET} PARENT_SCOPE)
endfunction()
macro(AUTOSCRIBE_APPEND_SHADER_SOURCES)
if (NOT("${ARGN}" STREQUAL ""))
set_property(GLOBAL PROPERTY ${TARGET_NAME}_SHADER_SOURCES "${ARGN}")
global_append(GLOBAL_SHADER_LIBS ${TARGET_NAME})
global_append(GLOBAL_SHADER_SOURCES "${ARGN}")
endif()
endmacro()
macro(AUTOSCRIBE_SHADER_LIB)
set(HIFI_LIBRARIES_SHADER_INCLUDE_FILES "")
unset(HIFI_LIBRARIES_SHADER_INCLUDE_FILES)
set(SRC_FOLDER "${CMAKE_SOURCE_DIR}/libraries/${TARGET_NAME}/src")
file(GLOB_RECURSE SHADER_INCLUDE_FILES ${SRC_FOLDER}/*.slh)
file(GLOB_RECURSE SHADER_VERTEX_FILES ${SRC_FOLDER}/*.slv)
file(GLOB_RECURSE SHADER_FRAGMENT_FILES ${SRC_FOLDER}/*.slf)
file(GLOB_RECURSE SHADER_GEOMETRY_FILES ${SRC_FOLDER}/*.slg)
file(GLOB_RECURSE SHADER_COMPUTE_FILES ${SRC_FOLDER}/*.slc)
unset(SHADER_SOURCE_FILES)
list(APPEND SHADER_SOURCE_FILES ${SHADER_VERTEX_FILES})
list(APPEND SHADER_SOURCE_FILES ${SHADER_FRAGMENT_FILES})
list(APPEND SHADER_SOURCE_FILES ${SHADER_GEOMETRY_FILES})
list(APPEND SHADER_SOURCE_FILES ${SHADER_COMPUTE_FILES})
unset(LOCAL_SHADER_SOURCES)
list(APPEND LOCAL_SHADER_SOURCES ${SHADER_SOURCE_FILES})
list(APPEND LOCAL_SHADER_SOURCES ${SHADER_INCLUDE_FILES})
AUTOSCRIBE_APPEND_SHADER_SOURCES(${LOCAL_SHADER_SOURCES})
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("${TARGET_NAME} ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES}")
endmacro()
file(GLOB_RECURSE SHADER_INCLUDE_FILES src/*.slh)
file(GLOB_RECURSE SHADER_SOURCE_FILES src/*.slv src/*.slf src/*.slg)
macro(AUTOSCRIBE_PROGRAM)
set(oneValueArgs NAME VERTEX FRAGMENT GEOMETRY COMPUTE)
cmake_parse_arguments(AUTOSCRIBE_PROGRAM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT (DEFINED AUTOSCRIBE_PROGRAM_NAME))
message(FATAL_ERROR "Programs must have a name and both a vertex and fragment shader")
endif()
if (NOT (DEFINED AUTOSCRIBE_PROGRAM_VERTEX))
set(AUTOSCRIBE_PROGRAM_VERTEX ${AUTOSCRIBE_PROGRAM_NAME})
endif()
if (NOT (DEFINED AUTOSCRIBE_PROGRAM_FRAGMENT))
set(AUTOSCRIBE_PROGRAM_FRAGMENT ${AUTOSCRIBE_PROGRAM_NAME})
endif()
#make the shader folder
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders/${TARGET_NAME}")
file(MAKE_DIRECTORY ${SHADERS_DIR})
if (NOT (${AUTOSCRIBE_PROGRAM_VERTEX} MATCHES ".*::.*"))
set(AUTOSCRIBE_PROGRAM_VERTEX "vertex::${AUTOSCRIBE_PROGRAM_VERTEX}")
endif()
if (NOT (${AUTOSCRIBE_PROGRAM_FRAGMENT} MATCHES ".*::.*"))
set(AUTOSCRIBE_PROGRAM_FRAGMENT "fragment::${AUTOSCRIBE_PROGRAM_FRAGMENT}")
endif()
#message("${TARGET_NAME} ${SHADER_INCLUDE_FILES}")
set(AUTOSCRIBE_SHADER_SRC "")
foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
unset(AUTOSCRIBE_PROGRAM_MAP)
list(APPEND AUTOSCRIBE_PROGRAM_MAP AUTOSCRIBE_PROGRAM_VERTEX)
list(APPEND AUTOSCRIBE_PROGRAM_MAP ${AUTOSCRIBE_PROGRAM_VERTEX})
list(APPEND AUTOSCRIBE_PROGRAM_MAP AUTOSCRIBE_PROGRAM_FRAGMENT)
list(APPEND AUTOSCRIBE_PROGRAM_MAP ${AUTOSCRIBE_PROGRAM_FRAGMENT})
global_append(${TARGET_NAME}_PROGRAMS ${AUTOSCRIBE_PROGRAM_NAME})
set_property(GLOBAL PROPERTY ${AUTOSCRIBE_PROGRAM_NAME} "${AUTOSCRIBE_PROGRAM_MAP}")
endmacro()
macro(unpack_map)
set(MAP_VAR "${ARGN}")
list(LENGTH MAP_VAR MAP_SIZE)
MATH(EXPR MAP_ENTRY_RANGE "(${MAP_SIZE} / 2) - 1")
foreach(INDEX RANGE ${MAP_ENTRY_RANGE})
MATH(EXPR INDEX_NAME "${INDEX} * 2")
MATH(EXPR INDEX_VAL "${INDEX_NAME} + 1")
list(GET MAP_VAR ${INDEX_NAME} VAR_NAME)
list(GET MAP_VAR ${INDEX_VAL} VAR_VAL)
set(${VAR_NAME} ${VAR_VAL})
endforeach()
endmacro()
macro(PROCESS_SHADER_FILE)
AUTOSCRIBE_SHADER(${SHADER} ${ALL_SHADER_HEADERS} ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
file(TO_CMAKE_PATH "${AUTOSCRIBE_SHADER_RETURN}" AUTOSCRIBE_GENERATED_FILE)
set_property(SOURCE ${AUTOSCRIBE_GENERATED_FILE} PROPERTY SKIP_AUTOMOC ON)
list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_GENERATED_FILE})
endforeach()
#message(${TARGET_NAME} ${AUTOSCRIBE_SHADER_SRC})
if (WIN32)
source_group("Shaders" FILES ${SHADER_INCLUDE_FILES})
source_group("Shaders" FILES ${SHADER_SOURCE_FILES})
source_group("Shaders\\generated" FILES ${AUTOSCRIBE_SHADER_SRC})
endif()
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${SHADER_INCLUDE_FILES})
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${SHADER_SOURCE_FILES})
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${AUTOSCRIBE_SHADER_SRC})
# Link library shaders, if they exist
include_directories("${SHADERS_DIR}")
# Add search directory to find gpu/Shader.h
include_directories("${HIFI_LIBRARY_DIR}/gpu/src")
source_group("Compiled/${SHADER_LIB}" FILES ${AUTOSCRIBE_GENERATED_FILE})
set(REFLECTED_SHADER "${AUTOSCRIBE_GENERATED_FILE}.json")
source_group("Reflected/${SHADER_LIB}" FILES ${REFLECTED_SHADER})
list(APPEND COMPILED_SHADERS ${AUTOSCRIBE_GENERATED_FILE})
get_filename_component(ENUM_NAME ${SHADER} NAME_WE)
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "${ENUM_NAME} = ${SHADER_COUNT},\n")
MATH(EXPR SHADER_COUNT "${SHADER_COUNT}+1")
endmacro()
macro(AUTOSCRIBE_SHADER_FINISH)
get_property(GLOBAL_SHADER_LIBS GLOBAL PROPERTY GLOBAL_SHADER_LIBS)
list(REMOVE_DUPLICATES GLOBAL_SHADER_LIBS)
set(SHADER_COUNT 0)
set(PROGRAM_COUNT 0)
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
set(SHADER_ENUMS "")
file(MAKE_DIRECTORY ${SHADERS_DIR})
unset(COMPILED_SHADERS)
foreach(SHADER_LIB ${GLOBAL_SHADER_LIBS})
get_property(LIB_SHADER_SOURCES GLOBAL PROPERTY ${SHADER_LIB}_SHADER_SOURCES)
get_property(LIB_PROGRAMS GLOBAL PROPERTY ${SHADER_LIB}_PROGRAMS)
list(REMOVE_DUPLICATES LIB_SHADER_SOURCES)
string(REGEX REPLACE "[-]" "_" SHADER_NAMESPACE ${SHADER_LIB})
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES "${CMAKE_SOURCE_DIR}/libraries/${SHADER_LIB}/src")
unset(VERTEX_SHADERS)
unset(FRAGMENT_SHADERS)
unset(SHADER_HEADERS)
foreach(SHADER_FILE ${LIB_SHADER_SOURCES})
if (SHADER_FILE MATCHES ".*\\.slv")
list(APPEND VERTEX_SHADERS ${SHADER_FILE})
elseif (SHADER_FILE MATCHES ".*\\.slf")
list(APPEND FRAGMENT_SHADERS ${SHADER_FILE})
elseif (SHADER_FILE MATCHES ".*\\.slh")
list(APPEND SHADER_HEADERS ${SHADER_FILE})
endif()
endforeach()
if (DEFINED SHADER_HEADERS)
list(REMOVE_DUPLICATES SHADER_HEADERS)
source_group("${SHADER_LIB}/Headers" FILES ${SHADER_HEADERS})
list(APPEND ALL_SHADER_HEADERS ${SHADER_HEADERS})
list(APPEND ALL_SCRIBE_SHADERS ${SHADER_HEADERS})
endif()
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace ${SHADER_NAMESPACE} {\n")
if (DEFINED VERTEX_SHADERS)
list(REMOVE_DUPLICATES VERTEX_SHADERS)
source_group("${SHADER_LIB}/Vertex" FILES ${VERTEX_SHADERS})
list(APPEND ALL_SCRIBE_SHADERS ${VERTEX_SHADERS})
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace vertex { enum {\n")
foreach(SHADER ${VERTEX_SHADERS})
process_shader_file()
endforeach()
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "}; } // vertex \n")
endif()
if (DEFINED FRAGMENT_SHADERS)
list(REMOVE_DUPLICATES FRAGMENT_SHADERS)
source_group("${SHADER_LIB}/Fragment" FILES ${FRAGMENT_SHADERS})
list(APPEND ALL_SCRIBE_SHADERS ${FRAGMENT_SHADERS})
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace fragment { enum {\n")
foreach(SHADER ${FRAGMENT_SHADERS})
process_shader_file()
endforeach()
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "}; } // fragment \n")
endif()
if (DEFINED LIB_PROGRAMS)
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace program { enum {\n")
foreach(LIB_PROGRAM ${LIB_PROGRAMS})
get_property(LIB_PROGRAM_MAP GLOBAL PROPERTY ${LIB_PROGRAM})
unpack_map(${LIB_PROGRAM_MAP})
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "${LIB_PROGRAM} = (${AUTOSCRIBE_PROGRAM_VERTEX} << 16) | ${AUTOSCRIBE_PROGRAM_FRAGMENT},\n")
MATH(EXPR PROGRAM_COUNT "${PROGRAM_COUNT}+1")
list(APPEND SHADER_ALL_PROGRAMS "${SHADER_NAMESPACE}::program::${LIB_PROGRAM}")
endforeach()
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "}; } // program \n")
endif()
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "} // namespace ${SHADER_NAMESPACE}\n")
endforeach()
set(SHADER_PROGRAMS_ARRAY "")
foreach(SHADER_PROGRAM ${SHADER_ALL_PROGRAMS})
string(CONCAT SHADER_PROGRAMS_ARRAY "${SHADER_PROGRAMS_ARRAY}" " ${SHADER_PROGRAM},\n")
endforeach()
set(SHREFLECT_COMMAND shreflect)
set(SHREFLECT_DEPENDENCY shreflect)
if (ANDROID)
set(SHREFLECT_COMMAND ${NATIVE_SHREFLECT})
unset(SHREFLECT_DEPENDENCY)
endif()
set(SHADER_COUNT 0)
foreach(COMPILED_SHADER ${COMPILED_SHADERS})
set(REFLECTED_SHADER "${COMPILED_SHADER}.json")
list(APPEND COMPILED_SHADER_REFLECTIONS ${REFLECTED_SHADER})
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}\">${COMPILED_SHADER}</file>\n")
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}_reflection\">${REFLECTED_SHADER}</file>\n")
MATH(EXPR SHADER_COUNT "${SHADER_COUNT}+1")
add_custom_command(
OUTPUT ${REFLECTED_SHADER}
COMMAND ${SHREFLECT_COMMAND} ${COMPILED_SHADER}
DEPENDS ${SHREFLECT_DEPENDENCY} ${COMPILED_SHADER}
)
endforeach()
# Custom targets required to force generation of the shaders via scribe
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS})
add_custom_target(compiled_shaders SOURCES ${COMPILED_SHADERS})
add_custom_target(reflected_shaders SOURCES ${COMPILED_SHADER_REFLECTIONS})
set_target_properties(scribe_shaders PROPERTIES FOLDER "Shaders")
set_target_properties(compiled_shaders PROPERTIES FOLDER "Shaders")
set_target_properties(reflected_shaders PROPERTIES FOLDER "Shaders")
configure_file(
ShaderEnums.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp
)
configure_file(
ShaderEnums.h.in
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h
)
configure_file(
shaders.qrc.in
${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc
)
set(AUTOSCRIBE_SHADER_LIB_SRC "${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h;${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp")
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${COMPILED_SHADERS})
set(QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
get_property(GLOBAL_SHADER_SOURCES GLOBAL PROPERTY GLOBAL_SHADER_SOURCES)
list(REMOVE_DUPLICATES GLOBAL_SHADER_SOURCES)
endmacro()

View file

@ -19,12 +19,8 @@ function(LINK_HIFI_LIBRARIES)
endforeach()
foreach(HIFI_LIBRARY ${LIBRARIES_TO_LINK})
include_directories("${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src")
include_directories("${CMAKE_BINARY_DIR}/libraries/${HIFI_LIBRARY}/shaders")
#add_dependencies(${TARGET_NAME} ${HIFI_LIBRARY})
include_directories("${CMAKE_BINARY_DIR}/libraries/${HIFI_LIBRARY}")
# link the actual library - it is static so don't bubble it up
target_link_libraries(${TARGET_NAME} ${HIFI_LIBRARY})
endforeach()

View file

@ -0,0 +1,13 @@
#
# Created by Bradley Austin Davis on 2018/07/22
# Copyright 2013-2018 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
#
macro(TARGET_JSON)
add_dependency_external_projects(json)
find_package(JSON REQUIRED)
message("JSON_INCLUDE_DIRS ${JSON_INCLUDE_DIRS}")
target_include_directories(${TARGET_NAME} PUBLIC ${JSON_INCLUDE_DIRS})
endmacro()

View file

@ -0,0 +1,19 @@
#
# Created by Bradley Austin Davis on 2018/07/22
# Copyright 2013-2018 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
#
# setup hints for JSON search
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
hifi_library_search_hints("json")
# locate header
find_path(JSON_INCLUDE_DIRS "json/json.hpp" HINTS ${JSON_SEARCH_DIRS})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(JSON DEFAULT_MSG JSON_INCLUDE_DIRS)
mark_as_advanced(JSON_INCLUDE_DIRS JSON_SEARCH_DIRS)

View file

@ -13,6 +13,7 @@
#include <memory>
#include <random>
#include <iostream>
#include <QDir>
#include <QJsonDocument>
@ -69,6 +70,14 @@ const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.com";
const QString ICE_SERVER_DEFAULT_HOSTNAME = "dev-ice.highfidelity.com";
#endif
QString DomainServer::_iceServerAddr { ICE_SERVER_DEFAULT_HOSTNAME };
int DomainServer::_iceServerPort { ICE_SERVER_DEFAULT_PORT };
bool DomainServer::_overrideDomainID { false };
QUuid DomainServer::_overridingDomainID;
bool DomainServer::_getTempName { false };
QString DomainServer::_userConfigFilename;
int DomainServer::_parentPID { -1 };
bool DomainServer::forwardMetaverseAPIRequest(HTTPConnection* connection,
const QString& metaversePath,
const QString& requestSubobjectKey,
@ -148,24 +157,13 @@ bool DomainServer::forwardMetaverseAPIRequest(HTTPConnection* connection,
DomainServer::DomainServer(int argc, char* argv[]) :
QCoreApplication(argc, argv),
_gatekeeper(this),
_httpManager(QHostAddress::AnyIPv4, DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
_allAssignments(),
_unfulfilledAssignments(),
_isUsingDTLS(false),
_oauthProviderURL(),
_oauthClientID(),
_hostname(),
_ephemeralACScripts(),
_webAuthenticationStateSet(),
_cookieSessionHash(),
_automaticNetworkingSetting(),
_settingsManager(),
_iceServerAddr(ICE_SERVER_DEFAULT_HOSTNAME),
_iceServerPort(ICE_SERVER_DEFAULT_PORT)
_httpManager(QHostAddress::AnyIPv4, DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this)
{
PathUtils::removeTemporaryApplicationDirs();
if (_parentPID != -1) {
watchParentProcess(_parentPID);
}
parseCommandLine();
PathUtils::removeTemporaryApplicationDirs();
DependencyManager::set<tracing::Tracer>();
DependencyManager::set<StatTracker>();
@ -185,9 +183,16 @@ DomainServer::DomainServer(int argc, char* argv[]) :
// (need this since domain-server can restart itself and maintain static variables)
DependencyManager::set<AccountManager>();
auto args = arguments();
_settingsManager.setupConfigMap(args);
// load the user config
QString userConfigFilename;
if (!_userConfigFilename.isEmpty()) {
userConfigFilename = _userConfigFilename;
} else {
// we weren't passed a user config path
static const QString USER_CONFIG_FILE_NAME = "config.json";
userConfigFilename = PathUtils::getAppDataFilePath(USER_CONFIG_FILE_NAME);
}
_settingsManager.setupConfigMap(userConfigFilename);
// setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
#ifdef _WIN32
@ -246,8 +251,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
}
// check for the temporary name parameter
const QString GET_TEMPORARY_NAME_SWITCH = "--get-temp-name";
if (args.contains(GET_TEMPORARY_NAME_SWITCH)) {
if (_getTempName) {
getTemporaryName();
}
@ -316,28 +320,45 @@ DomainServer::DomainServer(int argc, char* argv[]) :
connect(_contentManager.get(), &DomainContentBackupManager::recoveryCompleted, this, &DomainServer::restart);
}
void DomainServer::parseCommandLine() {
void DomainServer::parseCommandLine(int argc, char* argv[]) {
QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity Domain Server");
parser.addHelpOption();
const QCommandLineOption versionOption = parser.addVersionOption();
const QCommandLineOption helpOption = parser.addHelpOption();
const QCommandLineOption iceServerAddressOption("i", "ice-server address", "IP:PORT or HOSTNAME:PORT");
parser.addOption(iceServerAddressOption);
const QCommandLineOption domainIDOption("d", "domain-server uuid");
const QCommandLineOption domainIDOption("d", "domain-server uuid", "uuid");
parser.addOption(domainIDOption);
const QCommandLineOption getTempNameOption("get-temp-name", "Request a temporary domain-name");
parser.addOption(getTempNameOption);
const QCommandLineOption masterConfigOption("master-config", "Deprecated config-file option");
parser.addOption(masterConfigOption);
const QCommandLineOption userConfigOption("user-config", "Pass user config file pass", "path");
parser.addOption(userConfigOption);
const QCommandLineOption parentPIDOption(PARENT_PID_OPTION, "PID of the parent process", "parent-pid");
parser.addOption(parentPIDOption);
if (!parser.parse(QCoreApplication::arguments())) {
qWarning() << parser.errorText() << endl;
QStringList arguments;
for (int i = 0; i < argc; ++i) {
arguments << argv[i];
}
if (!parser.parse(arguments)) {
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam
QCoreApplication mockApp(argc, argv); // required for call to showHelp()
parser.showHelp();
Q_UNREACHABLE();
}
if (parser.isSet(versionOption)) {
parser.showVersion();
Q_UNREACHABLE();
}
if (parser.isSet(helpOption)) {
QCoreApplication mockApp(argc, argv); // required for call to showHelp()
parser.showHelp();
Q_UNREACHABLE();
}
@ -354,7 +375,7 @@ void DomainServer::parseCommandLine() {
if (_iceServerAddr.isEmpty()) {
qWarning() << "Could not parse an IP address and port combination from" << hostnamePortString;
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
::exit(0);
}
}
@ -364,14 +385,21 @@ void DomainServer::parseCommandLine() {
qDebug() << "domain-server ID is" << _overridingDomainID;
}
if (parser.isSet(getTempNameOption)) {
_getTempName = true;
}
if (parser.isSet(userConfigOption)) {
_userConfigFilename = parser.value(userConfigOption);
}
if (parser.isSet(parentPIDOption)) {
bool ok = false;
int parentPID = parser.value(parentPIDOption).toInt(&ok);
if (ok) {
qDebug() << "Parent process PID is" << parentPID;
watchParentProcess(parentPID);
_parentPID = parentPID;
qDebug() << "Parent process PID is" << _parentPID;
}
}
}

View file

@ -59,6 +59,8 @@ public:
DomainServer(int argc, char* argv[]);
~DomainServer();
static void parseCommandLine(int argc, char* argv[]);
enum DomainType {
NonMetaverse,
MetaverseDomain,
@ -138,7 +140,6 @@ signals:
private:
QUuid getID();
void parseCommandLine();
QString getContentBackupDir();
QString getEntitiesDirPath();
@ -228,7 +229,7 @@ private:
QQueue<SharedAssignmentPointer> _unfulfilledAssignments;
TransactionHash _pendingAssignmentCredits;
bool _isUsingDTLS;
bool _isUsingDTLS { false };
QUrl _oauthProviderURL;
QString _oauthClientID;
@ -265,10 +266,13 @@ private:
friend class DomainGatekeeper;
friend class DomainMetadata;
QString _iceServerAddr;
int _iceServerPort;
bool _overrideDomainID { false }; // should we override the domain-id from settings?
QUuid _overridingDomainID { QUuid() }; // what should we override it with?
static QString _iceServerAddr;
static int _iceServerPort;
static bool _overrideDomainID; // should we override the domain-id from settings?
static QUuid _overridingDomainID; // what should we override it with?
static bool _getTempName;
static QString _userConfigFilename;
static int _parentPID;
bool _sendICEServerAddressToMetaverseAPIInProgress { false };
bool _sendICEServerAddressToMetaverseAPIRedo { false };

View file

@ -191,13 +191,12 @@ void DomainServerSettingsManager::processSettingsRequestPacket(QSharedPointer<Re
nodeList->sendPacketList(std::move(packetList), message->getSenderSockAddr());
}
void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList) {
void DomainServerSettingsManager::setupConfigMap(const QString& userConfigFilename) {
// since we're called from the DomainServerSettingsManager constructor, we don't take a write lock here
// even though we change the underlying config map
_argumentList = argumentList;
_configMap.loadConfig(_argumentList);
_configMap.setUserConfigFilename(userConfigFilename);
_configMap.loadConfig();
static const auto VERSION_SETTINGS_KEYPATH = "version";
QVariant* versionVariant = _configMap.valueForKeyPath(VERSION_SETTINGS_KEYPATH);
@ -1736,7 +1735,7 @@ void DomainServerSettingsManager::persistToFile() {
// failed to write, reload whatever the current config state is
// with a write lock since we're about to overwrite the config map
QWriteLocker locker(&_settingsLock);
_configMap.loadConfig(_argumentList);
_configMap.loadConfig();
}
}

View file

@ -49,7 +49,7 @@ public:
DomainServerSettingsManager();
bool handleAuthenticatedHTTPRequest(HTTPConnection* connection, const QUrl& url);
void setupConfigMap(const QStringList& argumentList);
void setupConfigMap(const QString& userConfigFilename);
// each of the three methods in this group takes a read lock of _settingsLock
// and cannot be called when the a write lock is held by the same thread
@ -144,8 +144,6 @@ private slots:
void processUsernameFromIDRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
private:
QStringList _argumentList;
QJsonArray filteredDescriptionArray(bool isContentSettings);
void updateSetting(const QString& key, const QJsonValue& newValue, QVariantMap& settingMap,
const QJsonObject& settingDescription);

View file

@ -24,6 +24,8 @@
int main(int argc, char* argv[]) {
setupHifiApplication(BuildInfo::DOMAIN_SERVER_NAME);
DomainServer::parseCommandLine(argc, argv);
Setting::init();
int currentExitCode = 0;

View file

@ -214,6 +214,7 @@ link_hifi_libraries(
controllers plugins image trackers
ui-plugins display-plugins input-plugins
${PLATFORM_GL_BACKEND}
shaders
)
# include the binary directory of render-utils for shader includes

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -585,8 +585,9 @@
"states": [
{
"id": "idle",
"interpTarget": 10,
"interpDuration": 10,
"interpTarget": 0,
"interpDuration": 4,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isMovingForward", "state": "idleToWalkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
@ -598,13 +599,16 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "idleToWalkFwd",
"interpTarget": 3,
"interpDuration": 3,
"interpTarget": 10,
"interpDuration": 4,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "idleToWalkFwdOnDone", "state": "walkFwd" },
{ "var": "isNotMoving", "state": "idle" },
@ -617,6 +621,30 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "idleSettle",
"interpTarget": 10,
"interpDuration": 10,
"interpType": "snapshotPrev",
"transitions": [
{"var": "idleSettleOnDone", "state": "idle" },
{"var": "isMovingForward", "state": "idleToWalkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
]
},
@ -624,8 +652,9 @@
"id": "walkFwd",
"interpTarget": 16,
"interpDuration": 6,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
@ -635,15 +664,18 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "walkBwd",
"interpTarget": 6,
"interpTarget": 8,
"interpDuration": 6,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
@ -653,15 +685,18 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "strafeRight",
"interpTarget": 6,
"interpDuration": 6,
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
@ -671,18 +706,65 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "strafeLeft",
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "strafeRightHmd",
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
]
},
{
"id": "strafeLeft",
"interpTarget": 6,
"interpDuration": 6,
"id": "strafeLeftHmd",
"interpTarget": 5,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotMoving", "state": "idle" },
{ "var": "isNotMoving", "state": "idleSettle" },
{ "var": "isMovingForward", "state": "walkFwd" },
{ "var": "isMovingBackward", "state": "walkBwd" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isFlying", "state": "fly" },
@ -695,7 +777,8 @@
{
"id": "turnRight",
"interpTarget": 6,
"interpDuration": 6,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotTurning", "state": "idle" },
{ "var": "isMovingForward", "state": "walkFwd" },
@ -707,13 +790,16 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
"id": "turnLeft",
"interpTarget": 6,
"interpDuration": 6,
"interpDuration": 8,
"interpType": "snapshotPrev",
"transitions": [
{ "var": "isNotTurning", "state": "idle" },
{ "var": "isMovingForward", "state": "walkFwd" },
@ -725,7 +811,9 @@
{ "var": "isTakeoffStand", "state": "takeoffStand" },
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" }
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
@ -733,7 +821,7 @@
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "isNotFlying", "state": "idle" }
{ "var": "isNotFlying", "state": "idleSettle" }
]
},
{
@ -797,7 +885,9 @@
{ "var": "isTakeoffRun", "state": "takeoffRun" },
{ "var": "isInAirStand", "state": "inAirStand" },
{ "var": "isInAirRun", "state": "inAirRun" },
{ "var": "landStandOnDone", "state": "idle" }
{ "var": "landStandOnDone", "state": "idle" },
{ "var": "isMovingRightHmd", "state": "strafeRightHmd" },
{ "var": "isMovingLeftHmd", "state": "strafeLeftHmd" }
]
},
{
@ -871,13 +961,13 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.5, 1.4, 4.5],
"characteristicSpeeds": [0.5, 1.5, 2.5, 3.2, 4.5],
"alphaVar": "moveForwardAlpha",
"desiredSpeedVar": "moveForwardSpeed"
},
"children": [
{
"id": "walkFwdShort",
"id": "walkFwdShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_short_fwd.fbx",
@ -889,7 +979,7 @@
"children": []
},
{
"id": "walkFwdNormal",
"id": "walkFwdNormal_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_fwd.fbx",
@ -901,7 +991,31 @@
"children": []
},
{
"id": "walkFwdRun",
"id": "walkFwdFast_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_fwd_fast.fbx",
"startFrame": 0.0,
"endFrame": 25.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "walkFwdJog_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_fwd.fbx",
"startFrame": 0.0,
"endFrame": 25.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "walkFwdRun_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/run_fwd.fbx",
@ -926,13 +1040,25 @@
},
"children": []
},
{
"id": "idleSettle",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/settle_to_idle.fbx",
"startFrame": 1.0,
"endFrame": 48.0,
"timeScale": 1.0,
"loopFlag": false
},
"children": []
},
{
"id": "walkBwd",
"type": "blendLinearMove",
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.6, 1.45],
"characteristicSpeeds": [0.6, 1.7],
"alphaVar": "moveBackwardAlpha",
"desiredSpeedVar": "moveBackwardSpeed"
},
@ -953,9 +1079,9 @@
"id": "walkBwdNormal",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_bwd.fbx",
"url": "qrc:///avatar/animations/walk_bwd_fast.fbx",
"startFrame": 0.0,
"endFrame": 36.0,
"endFrame": 27.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -969,7 +1095,7 @@
"data": {
"url": "qrc:///avatar/animations/turn_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"endFrame": 32.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -981,7 +1107,7 @@
"data": {
"url": "qrc:///avatar/animations/turn_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"endFrame": 32.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
@ -994,30 +1120,66 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.2, 0.65],
"characteristicSpeeds": [0, 0.5, 1.5, 2.6, 3.0],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [
{
"id": "strafeLeftShort",
"id": "strafeLeftShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftNormal",
"id": "strafeLeft_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftAnim_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left.fbx",
"startFrame": 0.0,
"endFrame": 33.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftFast_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 21.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftJog_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_left.fbx",
"startFrame": 0.0,
"endFrame": 24.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -1031,34 +1193,175 @@
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0.2, 0.65],
"characteristicSpeeds": [0, 0.5, 1.5, 2.6, 3.0],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [ {
"id": "stepRightShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "stepRight_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRight_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left.fbx",
"startFrame": 0.0,
"endFrame": 33.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRightFast_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/walk_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 21.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRightJog_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/jog_left.fbx",
"startFrame": 0.0,
"endFrame": 24.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
}
]
},
{
"id": "strafeLeftHmd",
"type": "blendLinearMove",
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0, 0.5, 2.5],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [
{
"id": "strafeRightShort",
"id": "stepLeftShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_right.fbx",
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 28.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeRightNormal",
"id": "stepLeft_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_right.fbx",
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 30.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "strafeLeftAnim_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 16.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "strafeRightHmd",
"type": "blendLinearMove",
"data": {
"alpha": 0.0,
"desiredSpeed": 1.4,
"characteristicSpeeds": [0, 0.5, 2.5],
"alphaVar": "moveLateralAlpha",
"desiredSpeedVar": "moveLateralSpeed"
},
"children": [
{
"id": "stepRightShort_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_short_left.fbx",
"startFrame": 0.0,
"endFrame": 29.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "stepRight_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left.fbx",
"startFrame": 0.0,
"endFrame": 20.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
},
{
"id": "strafeRightAnim_c",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/side_step_left_fast.fbx",
"startFrame": 0.0,
"endFrame": 16.0,
"timeScale": 1.0,
"loopFlag": true,
"mirrorFlag": true
},
"children": []
}
]
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -173,6 +173,21 @@ Item {
StatText {
text: "Yaw: " + root.yaw.toFixed(1)
}
StatText {
visible: root.animStackNames.length > 0;
text: "Anim Stack Names:"
}
ListView {
width: geoCol.width
height: root.animStackNames.length * 15
visible: root.animStackNames.length > 0;
model: root.animStackNames
delegate: StatText {
text: modelData.length > 30
? modelData.substring(0, 5) + "..." + modelData.substring(modelData.length - 22)
: modelData
}
}
StatText {
visible: root.expanded;
text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " +

View file

@ -526,11 +526,13 @@ Item {
anchors.left: nameCardVUMeter.left;
// Properties
visible: (isMyCard || (selected && pal.activeTab == "nearbyTab")) && isPresent;
value: Users.getAvatarGain(uuid)
minimumValue: -60.0
maximumValue: 20.0
stepSize: 5
updateValueWhileDragging: true
Component.onCompleted: {
value = Users.getAvatarGain(uuid);
}
onValueChanged: {
updateGainFromQML(uuid, value, false);
}
@ -587,9 +589,11 @@ Item {
}
function updateGainFromQML(avatarUuid, sliderValue, isReleased) {
Users.setAvatarGain(avatarUuid, sliderValue);
if (isReleased) {
UserActivityLogger.palAction("avatar_gain_changed", avatarUuid);
if (Users.getAvatarGain(avatarUuid) != sliderValue) {
Users.setAvatarGain(avatarUuid, sliderValue);
if (isReleased) {
UserActivityLogger.palAction("avatar_gain_changed", avatarUuid);
}
}
}

View file

@ -57,9 +57,9 @@ ListModel {
// Not normally set directly, but rather by giving a truthy argument to getFirstPage(true);
property bool delayedClear: false;
function resetModel() {
if (!delayedClear) { root.clear(); }
currentPageToRetrieve = 1;
retrievedAtLeastOnePage = false;
if (!delayedClear) { root.clear(); }
totalPages = 0;
totalEntries = 0;
}
@ -94,11 +94,13 @@ ListModel {
function needsMoreHorizontalResults() {
return flickable
&& currentPageToRetrieve > 0
&& retrievedAtLeastOnePage
&& flickable.contentWidth < flickable.width;
}
function needsMoreVerticalResults() {
return flickable
&& currentPageToRetrieve > 0
&& retrievedAtLeastOnePage
&& flickable.contentHeight < flickable.height;
}
function getNextPageIfNotEnoughHorizontalResults() {

View file

@ -299,7 +299,7 @@ Item {
anchors.fill: stackView
id: controllerPrefereneces
objectName: "TabletControllerPreferences"
showCategories: [( (HMD.active) ? "VR Movement" : "Movement"), "Game Controller", "Sixense Controllers", "Perception Neuron", "Leap Motion"]
showCategories: ["VR Movement", "Game Controller", "Sixense Controllers", "Perception Neuron", "Leap Motion"]
categoryProperties: {
"VR Movement" : {
"User real-world height (meters)" : { "anchors.right" : "undefined" },

View file

@ -1247,7 +1247,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
// use our MyAvatar position and quat for address manager path
addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldPosition(); });
addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldFeetPosition(); });
addressManager->setOrientationGetter([this]{ return getMyAvatar()->getWorldOrientation(); });
connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle);
@ -2703,8 +2703,6 @@ void Application::initializeGL() {
// contexts
_glWidget->makeCurrent();
gpu::Context::init<gpu::gl::GLBackend>();
qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK,
QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram)));
_glWidget->makeCurrent();
_gpuContext = std::make_shared<gpu::Context>();
@ -4574,11 +4572,14 @@ void Application::idle() {
_lastTimeUpdated.start();
// If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus.
if (_keyboardDeviceHasFocus && offscreenUi && offscreenUi->getWindow()->activeFocusItem() != offscreenUi->getRootItem()) {
_keyboardMouseDevice->pluginFocusOutEvent();
_keyboardDeviceHasFocus = false;
} else if (offscreenUi && offscreenUi->getWindow()->activeFocusItem() == offscreenUi->getRootItem()) {
_keyboardDeviceHasFocus = true;
if (offscreenUi && offscreenUi->getWindow()) {
auto activeFocusItem = offscreenUi->getWindow()->activeFocusItem();
if (_keyboardDeviceHasFocus && activeFocusItem != offscreenUi->getRootItem()) {
_keyboardMouseDevice->pluginFocusOutEvent();
_keyboardDeviceHasFocus = false;
} else if (activeFocusItem == offscreenUi->getRootItem()) {
_keyboardDeviceHasFocus = true;
}
}
checkChangeCursor();
@ -5284,6 +5285,7 @@ void Application::reloadResourceCaches() {
queryOctree(NodeType::EntityServer, PacketType::EntityQuery);
DependencyManager::get<AssetClient>()->clearCache();
DependencyManager::get<ScriptCache>()->clearCache();
DependencyManager::get<AnimationCache>()->refreshAll();
DependencyManager::get<ModelCache>()->refreshAll();

View file

@ -205,7 +205,9 @@ void SecondaryCameraRenderTask::build(JobModel& task, const render::Varying& inp
const auto items = task.addJob<RenderFetchCullSortTask>("FetchCullSort", cullFunctor, render::ItemKey::TAG_BITS_1, render::ItemKey::TAG_BITS_1);
assert(items.canCast<RenderFetchCullSortTask::Output>());
if (isDeferred) {
task.addJob<RenderDeferredTask>("RenderDeferredTask", items, false);
const render::Varying cascadeSceneBBoxes;
const auto renderInput = RenderDeferredTask::Input(items, cascadeSceneBBoxes).asVarying();
task.addJob<RenderDeferredTask>("RenderDeferredTask", renderInput, false);
} else {
task.addJob<RenderForwardTask>("Forward", items);
}

View file

@ -277,21 +277,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
sortedAvatars.pop();
}
if (_shouldRender) {
if (!_avatarsToFade.empty()) {
QReadLocker lock(&_hashLock);
QVector<AvatarSharedPointer>::iterator itr = _avatarsToFade.begin();
while (itr != _avatarsToFade.end() && usecTimestampNow() > updateExpiry) {
auto avatar = std::static_pointer_cast<Avatar>(*itr);
avatar->animateScaleChanges(deltaTime);
avatar->simulate(deltaTime, true);
avatar->updateRenderItem(transaction);
++itr;
}
}
qApp->getMain3DScene()->enqueueTransaction(transaction);
}
_numAvatarsUpdated = numAvatarsUpdated;
_numAvatarsNotUpdated = numAVatarsNotUpdated;
@ -365,8 +350,6 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
}
avatarItr = _avatarsToFade.erase(avatarItr);
} else {
const bool inView = true; // HACK
avatar->simulate(deltaTime, inView);
++avatarItr;
}
}

View file

@ -139,6 +139,12 @@ MyAvatar::MyAvatar(QThread* thread) :
auto geometry = getSkeletonModel()->getFBXGeometry();
qApp->loadAvatarScripts(geometry.scripts);
_shouldLoadScripts = false;
}
// Load and convert old attachments to avatar entities
if (_oldAttachmentData.size() > 0) {
setAttachmentData(_oldAttachmentData);
_oldAttachmentData.clear();
_attachmentData.clear();
}
});
connect(_skeletonModel.get(), &Model::rigReady, this, &Avatar::rigReady);
@ -154,7 +160,7 @@ MyAvatar::MyAvatar(QThread* thread) :
// connect to AddressManager signal for location jumps
connect(DependencyManager::get<AddressManager>().data(), &AddressManager::locationChangeRequired,
this, static_cast<SlotType>(&MyAvatar::goToLocation));
this, static_cast<SlotType>(&MyAvatar::goToFeetLocation));
// handle scale constraints imposed on us by the domain-server
auto& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
@ -1135,7 +1141,6 @@ void MyAvatar::saveData() {
settings.setValue("collisionSoundURL", _collisionSoundURL);
settings.setValue("useSnapTurn", _useSnapTurn);
settings.setValue("userHeight", getUserHeight());
settings.setValue("flyingDesktop", getFlyingDesktopPref());
settings.setValue("flyingHMD", getFlyingHMDPref());
settings.endGroup();
@ -1250,7 +1255,6 @@ void MyAvatar::loadData() {
useFullAvatarURL(_fullAvatarURLFromPreferences, _fullAvatarModelName);
QVector<AttachmentData> attachmentData;
int attachmentCount = settings.beginReadArray("attachmentData");
for (int i = 0; i < attachmentCount; i++) {
settings.setArrayIndex(i);
@ -1267,10 +1271,10 @@ void MyAvatar::loadData() {
attachment.rotation = glm::quat(eulers);
attachment.scale = loadSetting(settings, "scale", 1.0f);
attachment.isSoft = settings.value("isSoft").toBool();
attachmentData.append(attachment);
// old attachments are stored and loaded/converted later when rig is ready
_oldAttachmentData.append(attachment);
}
settings.endArray();
setAttachmentData(attachmentData);
int avatarEntityCount = settings.beginReadArray("avatarEntityData");
for (int i = 0; i < avatarEntityCount; i++) {
@ -1289,7 +1293,6 @@ void MyAvatar::loadData() {
// Flying preferences must be loaded before calling setFlyingEnabled()
Setting::Handle<bool> firstRunVal { Settings::firstRun, true };
setFlyingDesktopPref(firstRunVal.get() ? true : settings.value("flyingDesktop").toBool());
setFlyingHMDPref(firstRunVal.get() ? false : settings.value("flyingHMD").toBool());
setFlyingEnabled(getFlyingEnabled());
@ -1690,16 +1693,6 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN
markIdentityDataChanged();
}
void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "setAttachmentData",
Q_ARG(const QVector<AttachmentData>, attachmentData));
return;
}
Avatar::setAttachmentData(attachmentData);
emit attachmentsChanged();
}
glm::vec3 MyAvatar::getSkeletonPosition() const {
CameraMode mode = qApp->getCamera().getMode();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
@ -1970,20 +1963,164 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName,
float scale, bool isSoft,
bool allowDuplicates, bool useSaved) {
if (QThread::currentThread() != thread()) {
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
BLOCKING_INVOKE_METHOD(this, "attach",
Q_ARG(const QString&, modelURL),
Q_ARG(const QString&, jointName),
Q_ARG(const glm::vec3&, translation),
Q_ARG(const glm::quat&, rotation),
Q_ARG(float, scale),
Q_ARG(bool, isSoft),
Q_ARG(bool, allowDuplicates),
Q_ARG(bool, useSaved)
);
return;
}
if (useSaved) {
AttachmentData attachment = loadAttachmentData(modelURL, jointName);
if (attachment.isValid()) {
Avatar::attach(modelURL, attachment.jointName,
attachment.translation, attachment.rotation,
attachment.scale, attachment.isSoft,
allowDuplicates, useSaved);
return;
AttachmentData data;
data.modelURL = modelURL;
data.jointName = jointName;
data.translation = translation;
data.rotation = rotation;
data.scale = scale;
data.isSoft = isSoft;
EntityItemProperties properties;
attachmentDataToEntityProperties(data, properties);
DependencyManager::get<EntityScriptingInterface>()->addEntity(properties, true);
emit attachmentsChanged();
}
void MyAvatar::detachOne(const QString& modelURL, const QString& jointName) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "detachOne",
Q_ARG(const QString&, modelURL),
Q_ARG(const QString&, jointName)
);
return;
}
QUuid entityID;
if (findAvatarEntity(modelURL, jointName, entityID)) {
DependencyManager::get<EntityScriptingInterface>()->deleteEntity(entityID);
}
emit attachmentsChanged();
}
void MyAvatar::detachAll(const QString& modelURL, const QString& jointName) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "detachAll",
Q_ARG(const QString&, modelURL),
Q_ARG(const QString&, jointName)
);
return;
}
QUuid entityID;
while (findAvatarEntity(modelURL, jointName, entityID)) {
DependencyManager::get<EntityScriptingInterface>()->deleteEntity(entityID);
}
emit attachmentsChanged();
}
void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "setAttachmentData",
Q_ARG(const QVector<AttachmentData>&, attachmentData));
return;
}
std::vector<EntityItemProperties> newEntitiesProperties;
for (auto& data : attachmentData) {
QUuid entityID;
EntityItemProperties properties;
if (findAvatarEntity(data.modelURL.toString(), data.jointName, entityID)) {
properties = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityID);
}
attachmentDataToEntityProperties(data, properties);
newEntitiesProperties.push_back(properties);
}
removeAvatarEntities();
for (auto& properties : newEntitiesProperties) {
DependencyManager::get<EntityScriptingInterface>()->addEntity(properties, true);
}
emit attachmentsChanged();
}
QVector<AttachmentData> MyAvatar::getAttachmentData() const {
QVector<AttachmentData> avatarData;
auto avatarEntities = getAvatarEntityData();
AvatarEntityMap::const_iterator dataItr = avatarEntities.begin();
while (dataItr != avatarEntities.end()) {
QUuid entityID = dataItr.key();
auto properties = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityID);
AttachmentData data = entityPropertiesToAttachmentData(properties);
avatarData.append(data);
dataItr++;
}
return avatarData;
}
QVariantList MyAvatar::getAttachmentsVariant() const {
QVariantList result;
for (const auto& attachment : getAttachmentData()) {
result.append(attachment.toVariant());
}
return result;
}
void MyAvatar::setAttachmentsVariant(const QVariantList& variant) {
if (QThread::currentThread() != thread()) {
BLOCKING_INVOKE_METHOD(this, "setAttachmentsVariant",
Q_ARG(const QVariantList&, variant));
return;
}
QVector<AttachmentData> newAttachments;
newAttachments.reserve(variant.size());
for (const auto& attachmentVar : variant) {
AttachmentData attachment;
if (attachment.fromVariant(attachmentVar)) {
newAttachments.append(attachment);
}
}
Avatar::attach(modelURL, jointName, translation, rotation, scale, isSoft, allowDuplicates, useSaved);
setAttachmentData(newAttachments);
}
bool MyAvatar::findAvatarEntity(const QString& modelURL, const QString& jointName, QUuid& entityID) {
auto avatarEntities = getAvatarEntityData();
AvatarEntityMap::const_iterator dataItr = avatarEntities.begin();
while (dataItr != avatarEntities.end()) {
entityID = dataItr.key();
auto props = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityID);
if (props.getModelURL() == modelURL &&
(jointName.isEmpty() || props.getParentJointIndex() == getJointIndex(jointName))) {
return true;
}
dataItr++;
}
return false;
}
AttachmentData MyAvatar::entityPropertiesToAttachmentData(const EntityItemProperties& properties) const {
AttachmentData data;
data.modelURL = properties.getModelURL();
data.translation = properties.getLocalPosition();
data.rotation = properties.getLocalRotation();
data.isSoft = properties.getRelayParentJoints();
int jointIndex = (int)properties.getParentJointIndex();
if (jointIndex > -1 && jointIndex < getJointNames().size()) {
data.jointName = getJointNames()[jointIndex];
}
return data;
}
void MyAvatar::attachmentDataToEntityProperties(const AttachmentData& data, EntityItemProperties& properties) {
QString url = data.modelURL.toString();
properties.setName(QFileInfo(url).baseName());
properties.setType(EntityTypes::Model);
properties.setParentID(AVATAR_SELF_ID);
properties.setLocalPosition(data.translation);
properties.setLocalRotation(data.rotation);
if (!data.isSoft) {
properties.setParentJointIndex(getJointIndex(data.jointName));
} else {
properties.setRelayParentJoints(true);
}
properties.setModelURL(url);
}
void MyAvatar::initHeadBones() {
@ -2338,6 +2475,23 @@ void MyAvatar::updateOrientation(float deltaTime) {
}
}
static float scaleSpeedByDirection(const glm::vec2 velocityDirection, const float forwardSpeed, const float backwardSpeed) {
// for the elipse function --> (x^2)/(backwardSpeed*backwardSpeed) + y^2/(forwardSpeed*forwardSpeed) = 1, scale == y^2 when x is 0
float fwdScale = forwardSpeed * forwardSpeed;
float backScale = backwardSpeed * backwardSpeed;
float scaledX = velocityDirection.x * backwardSpeed;
float scaledSpeed = forwardSpeed;
if (velocityDirection.y < 0.0f) {
if (backScale > 0.0f) {
float yValue = sqrtf(fwdScale * (1.0f - ((scaledX * scaledX) / backScale)));
scaledSpeed = sqrtf((scaledX * scaledX) + (yValue * yValue));
}
} else {
scaledSpeed = backwardSpeed;
}
return scaledSpeed;
}
void MyAvatar::updateActionMotor(float deltaTime) {
bool thrustIsPushing = (glm::length2(_thrust) > EPSILON);
bool scriptedMotorIsPushing = (_motionBehaviors & AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED)
@ -2399,7 +2553,10 @@ void MyAvatar::updateActionMotor(float deltaTime) {
_actionMotorVelocity = motorSpeed * direction;
} else {
// we're interacting with a floor --> simple horizontal speed and exponential decay
_actionMotorVelocity = getSensorToWorldScale() * (_walkSpeed.get() * _walkSpeedScalar) * direction;
const glm::vec2 currentVel = { direction.x, direction.z };
float scaledSpeed = scaleSpeedByDirection(currentVel, _walkSpeed.get(), _walkBackwardSpeed.get());
// _walkSpeedScalar is a multiplier if we are in sprint mode, otherwise 1.0
_actionMotorVelocity = getSensorToWorldScale() * (scaledSpeed * _walkSpeedScalar) * direction;
}
float previousBoomLength = _boomLength;
@ -2625,6 +2782,49 @@ void MyAvatar::goToLocation(const QVariant& propertiesVar) {
}
}
void MyAvatar::goToFeetLocation(const glm::vec3& newPosition,
bool hasOrientation, const glm::quat& newOrientation,
bool shouldFaceLocation) {
qCDebug(interfaceapp).nospace() << "MyAvatar goToFeetLocation - moving to " << newPosition.x << ", "
<< newPosition.y << ", " << newPosition.z;
ShapeInfo shapeInfo;
computeShapeInfo(shapeInfo);
glm::vec3 halfExtents = shapeInfo.getHalfExtents();
glm::vec3 localFeetPos = shapeInfo.getOffset() - glm::vec3(0.0f, halfExtents.y + halfExtents.x, 0.0f);
glm::mat4 localFeet = createMatFromQuatAndPos(Quaternions::IDENTITY, localFeetPos);
glm::mat4 worldFeet = createMatFromQuatAndPos(Quaternions::IDENTITY, newPosition);
glm::mat4 avatarMat = worldFeet * glm::inverse(localFeet);
glm::vec3 adjustedPosition = extractTranslation(avatarMat);
_goToPending = true;
_goToPosition = adjustedPosition;
_goToOrientation = getWorldOrientation();
if (hasOrientation) {
qCDebug(interfaceapp).nospace() << "MyAvatar goToFeetLocation - new orientation is "
<< newOrientation.x << ", " << newOrientation.y << ", " << newOrientation.z << ", " << newOrientation.w;
// orient the user to face the target
glm::quat quatOrientation = cancelOutRollAndPitch(newOrientation);
if (shouldFaceLocation) {
quatOrientation = newOrientation * glm::angleAxis(PI, Vectors::UP);
// move the user a couple units away
const float DISTANCE_TO_USER = 2.0f;
_goToPosition = adjustedPosition - quatOrientation * IDENTITY_FORWARD * DISTANCE_TO_USER;
}
_goToOrientation = quatOrientation;
}
emit transformChanged();
}
void MyAvatar::goToLocation(const glm::vec3& newPosition,
bool hasOrientation, const glm::quat& newOrientation,
bool shouldFaceLocation) {
@ -3408,18 +3608,34 @@ float MyAvatar::getWalkSpeed() const {
return _walkSpeed.get() * _walkSpeedScalar;
}
float MyAvatar::getWalkBackwardSpeed() const {
return _walkSpeed.get() * _walkSpeedScalar;
}
bool MyAvatar::isReadyForPhysics() const {
return qApp->isServerlessMode() || _haveReceivedHeightLimitsFromDomain;
}
void MyAvatar::setSprintMode(bool sprint) {
_walkSpeedScalar = sprint ? AVATAR_SPRINT_SPEED_SCALAR : AVATAR_WALK_SPEED_SCALAR;
_walkSpeedScalar = sprint ? _sprintSpeed.get() : AVATAR_WALK_SPEED_SCALAR;
}
void MyAvatar::setWalkSpeed(float value) {
_walkSpeed.set(value);
}
void MyAvatar::setWalkBackwardSpeed(float value) {
_walkBackwardSpeed.set(value);
}
void MyAvatar::setSprintSpeed(float value) {
_sprintSpeed.set(value);
}
float MyAvatar::getSprintSpeed() const {
return _sprintSpeed.get();
}
QVector<QString> MyAvatar::getScriptUrls() {
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getFBXGeometry().scripts : QVector<QString>();
return scripts;

View file

@ -138,12 +138,14 @@ class MyAvatar : public Avatar {
* where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain). Note: Likely to be deprecated.
* <em>Read-only.</em>
* @property {number} walkSpeed
* @property {number} walkBackwardSpeed
* @property {number} sprintSpeed
*
* @property {Vec3} skeletonOffset - Can be used to apply a translation offset between the avatar's position and the
* registration point of the 3D model.
*
* @property {Vec3} position
* @property {number} scale
* @property {number} scale - Returns the clamped scale of the avatar.
* @property {number} density <em>Read-only.</em>
* @property {Vec3} handPosition
* @property {number} bodyYaw - The rotation left or right about an axis running from the head to the feet of the avatar.
@ -233,6 +235,8 @@ class MyAvatar : public Avatar {
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed);
Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed);
Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed);
const QString DOMINANT_LEFT_HAND = "left";
const QString DOMINANT_RIGHT_HAND = "right";
@ -865,8 +869,6 @@ public:
void resetFullAvatarURL();
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
MyCharacterController* getCharacterController() { return &_characterController; }
const MyCharacterController* getCharacterController() const { return &_characterController; }
@ -982,7 +984,7 @@ public:
/**jsdoc
* @function MyAvatar.getAvatarScale
* @returns {number}
* @returns {number}
*/
Q_INVOKABLE float getAvatarScale();
@ -1074,6 +1076,10 @@ public:
void setWalkSpeed(float value);
float getWalkSpeed() const;
void setWalkBackwardSpeed(float value);
float getWalkBackwardSpeed() const;
void setSprintSpeed(float value);
float getSprintSpeed() const;
QVector<QString> getScriptUrls();
@ -1082,6 +1088,12 @@ public:
float computeStandingHeightMode(const controller::Pose& head);
glm::quat computeAverageHeadRotation(const controller::Pose& head);
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData) override;
virtual QVector<AttachmentData> getAttachmentData() const override;
virtual QVariantList getAttachmentsVariant() const override;
virtual void setAttachmentsVariant(const QVariantList& variant) override;
public slots:
/**jsdoc
@ -1133,6 +1145,20 @@ public slots:
*/
float getGravity();
/**jsdoc
* Move the avatar to a new position and/or orientation in the domain, while taking into account Avatar leg-length.
* @function MyAvatar.goToFeetLocation
* @param {Vec3} position - The new position for the avatar, in world coordinates.
* @param {boolean} [hasOrientation=false] - Set to <code>true</code> to set the orientation of the avatar.
* @param {Quat} [orientation=Quat.IDENTITY] - The new orientation for the avatar.
* @param {boolean} [shouldFaceLocation=false] - Set to <code>true</code> to position the avatar a short distance away from
* the new position and orientate the avatar to face the position.
*/
void goToFeetLocation(const glm::vec3& newPosition,
bool hasOrientation, const glm::quat& newOrientation,
bool shouldFaceLocation);
/**jsdoc
* Move the avatar to a new position and/or orientation in the domain.
* @function MyAvatar.goToLocation
@ -1506,11 +1532,21 @@ private:
void setScriptedMotorTimescale(float timescale);
void setScriptedMotorFrame(QString frame);
void setScriptedMotorMode(QString mode);
// Attachments
virtual void attach(const QString& modelURL, const QString& jointName = QString(),
const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(),
float scale = 1.0f, bool isSoft = false,
bool allowDuplicates = false, bool useSaved = true) override;
virtual void detachOne(const QString& modelURL, const QString& jointName = QString()) override;
virtual void detachAll(const QString& modelURL, const QString& jointName = QString()) override;
// Attachments/Avatar Entity
void attachmentDataToEntityProperties(const AttachmentData& data, EntityItemProperties& properties);
AttachmentData entityPropertiesToAttachmentData(const EntityItemProperties& properties) const;
bool findAvatarEntity(const QString& modelURL, const QString& jointName, QUuid& entityID);
bool cameraInsideHead(const glm::vec3& cameraPosition) const;
void updateEyeContactTarget(float deltaTime);
@ -1731,6 +1767,8 @@ private:
// max unscaled forward movement speed
ThreadSafeValueCache<float> _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED };
ThreadSafeValueCache<float> _walkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED };
ThreadSafeValueCache<float> _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR };
float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR };
// load avatar scripts once when rig is ready

View file

@ -42,6 +42,48 @@ extern "C" {
int main(int argc, const char* argv[]) {
setupHifiApplication(BuildInfo::INTERFACE_NAME);
QStringList arguments;
for (int i = 0; i < argc; ++i) {
arguments << argv[i];
}
QCommandLineParser parser;
parser.setApplicationDescription("High Fidelity Interface");
QCommandLineOption versionOption = parser.addVersionOption();
QCommandLineOption helpOption = parser.addHelpOption();
QCommandLineOption urlOption("url", "", "value");
QCommandLineOption noUpdaterOption("no-updater", "Do not show auto-updater");
QCommandLineOption checkMinSpecOption("checkMinSpec", "Check if machine meets minimum specifications");
QCommandLineOption runServerOption("runServer", "Whether to run the server");
QCommandLineOption serverContentPathOption("serverContentPath", "Where to find server content", "serverContentPath");
QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run");
QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache <dir>", "dir");
QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts <path>", "path");
parser.addOption(urlOption);
parser.addOption(noUpdaterOption);
parser.addOption(checkMinSpecOption);
parser.addOption(runServerOption);
parser.addOption(serverContentPathOption);
parser.addOption(overrideAppLocalDataPathOption);
parser.addOption(overrideScriptsPathOption);
parser.addOption(allowMultipleInstancesOption);
if (!parser.parse(arguments)) {
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam
}
if (parser.isSet(versionOption)) {
parser.showVersion();
Q_UNREACHABLE();
}
if (parser.isSet(helpOption)) {
QCoreApplication mockApp(argc, const_cast<char**>(argv)); // required for call to showHelp()
parser.showHelp();
Q_UNREACHABLE();
}
// Early check for --traceFile argument
auto tracer = DependencyManager::set<tracing::Tracer>();
const char * traceFile = nullptr;
@ -95,30 +137,6 @@ int main(int argc, const char* argv[]) {
qDebug() << "Crash handler started:" << crashHandlerStarted;
}
QStringList arguments;
for (int i = 0; i < argc; ++i) {
arguments << argv[i];
}
QCommandLineParser parser;
QCommandLineOption urlOption("url", "", "value");
QCommandLineOption noUpdaterOption("no-updater", "Do not show auto-updater");
QCommandLineOption checkMinSpecOption("checkMinSpec", "Check if machine meets minimum specifications");
QCommandLineOption runServerOption("runServer", "Whether to run the server");
QCommandLineOption serverContentPathOption("serverContentPath", "Where to find server content", "serverContentPath");
QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run");
QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache <dir>", "dir");
QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts <path>", "path");
parser.addOption(urlOption);
parser.addOption(noUpdaterOption);
parser.addOption(checkMinSpecOption);
parser.addOption(runServerOption);
parser.addOption(serverContentPathOption);
parser.addOption(overrideAppLocalDataPathOption);
parser.addOption(overrideScriptsPathOption);
parser.addOption(allowMultipleInstancesOption);
parser.parse(arguments);
const QString& applicationName = getInterfaceSharedMemoryName();
bool instanceMightBeRunning = true;

View file

@ -12,11 +12,9 @@
#include <StencilMaskPass.h>
#include <DependencyManager.h>
#include <shaders/Shaders.h>
#include "ParabolaPick.h"
#include "render-utils/parabola_vert.h"
#include "render-utils/parabola_frag.h"
const glm::vec4 ParabolaPointer::RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_COLOR { 1.0f };
const float ParabolaPointer::RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_WIDTH { 0.01f };
const bool ParabolaPointer::RenderState::ParabolaRenderItem::DEFAULT_PARABOLA_ISVISIBLEINSECONDARYCAMERA { false };
@ -117,8 +115,6 @@ ParabolaPointer::RenderState::RenderState(const OverlayID& startID, const Overla
_pathWidth = pathWidth;
if (render::Item::isValidID(_pathID)) {
auto renderItem = std::make_shared<ParabolaRenderItem>(pathColor, pathAlpha, pathWidth, isVisibleInSecondaryCamera, pathEnabled);
// TODO: update bounds properly
renderItem->editBound().setBox(glm::vec3(-16000.0f), 32000.0f);
transaction.resetItem(_pathID, std::make_shared<ParabolaRenderItem::Payload>(renderItem));
scene->enqueueTransaction(transaction);
}
@ -182,6 +178,7 @@ void ParabolaPointer::RenderState::update(const glm::vec3& origin, const glm::ve
item.setAcceleration(acceleration);
item.setParabolicDistance(parabolicDistance);
item.setWidth(width);
item.updateBounds();
});
scene->enqueueTransaction(transaction);
}
@ -304,10 +301,10 @@ void ParabolaPointer::RenderState::ParabolaRenderItem::setVisible(bool visible)
}
void ParabolaPointer::RenderState::ParabolaRenderItem::updateKey() {
// FIXME: There's no way to designate a render item as non-shadow-reciever, and since a parabola's bounding box covers the entire domain,
// it seems to block all shadows. I think this is a bug with shadows.
//auto builder = _parabolaData.color.a < 1.0f ? render::ItemKey::Builder::transparentShape() : render::ItemKey::Builder::opaqueShape();
auto builder = render::ItemKey::Builder::transparentShape();
auto builder = _parabolaData.color.a < 1.0f ? render::ItemKey::Builder::transparentShape() : render::ItemKey::Builder::opaqueShape();
// TODO: parabolas should cast shadows, but they're so thin that the cascaded shadow maps make them look pretty bad
//builder.withShadowCaster();
if (_enabled && _visible) {
builder.withVisible();
@ -324,15 +321,36 @@ void ParabolaPointer::RenderState::ParabolaRenderItem::updateKey() {
_key = builder.build();
}
void ParabolaPointer::RenderState::ParabolaRenderItem::updateBounds() {
glm::vec3 max = _origin;
glm::vec3 min = _origin;
glm::vec3 end = _origin + _parabolaData.velocity * _parabolaData.parabolicDistance +
0.5f * _parabolaData.acceleration * _parabolaData.parabolicDistance * _parabolaData.parabolicDistance;
max = glm::max(max, end);
min = glm::min(min, end);
for (int i = 0; i < 3; i++) {
if (fabsf(_parabolaData.velocity[i]) > EPSILON && fabsf(_parabolaData.acceleration[i]) > EPSILON) {
float maxT = -_parabolaData.velocity[i] / _parabolaData.acceleration[i];
if (maxT > 0.0f && maxT < _parabolaData.parabolicDistance) {
glm::vec3 maxPoint = _origin + _parabolaData.velocity * maxT + 0.5f * _parabolaData.acceleration * maxT * maxT;
max = glm::max(max, maxPoint);
min = glm::min(min, maxPoint);
}
}
}
glm::vec3 halfWidth = glm::vec3(0.5f * _parabolaData.width);
max += halfWidth;
min -= halfWidth;
_bound = AABox(min, max - min);
}
const gpu::PipelinePointer ParabolaPointer::RenderState::ParabolaRenderItem::getParabolaPipeline() {
if (!_parabolaPipeline || !_transparentParabolaPipeline) {
auto vs = parabola_vert::getShader();
auto ps = parabola_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("parabolaData"), 0));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::parabola);
{
auto state = std::make_shared<gpu::State>();

View file

@ -36,6 +36,7 @@ public:
void setVisible(bool visible);
void updateKey();
void updateUniformBuffer() { _uniformBuffer->setSubData(0, _parabolaData); }
void updateBounds();
void setColor(const glm::vec3& color) { _parabolaData.color = glm::vec4(color, _parabolaData.color.a); }
void setAlpha(const float& alpha) { _parabolaData.color.a = alpha; }

View file

@ -140,7 +140,7 @@ public:
* @property {Vec3} intersection The intersection point in world-space.
* @property {Vec3} surfaceNormal The surface normal at the intersected point. All NANs if type == INTERSECTED_HUD.
* @property {Variant} extraInfo Additional intersection details when available for Model objects.
* @property {StylusTip} parabola The PickParabola that was used. Valid even if there was no intersection.
* @property {PickParabola} parabola The PickParabola that was used. Valid even if there was no intersection.
*/
/**jsdoc

View file

@ -92,7 +92,7 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
* @typedef {object} Pointers.LaserPointerProperties
* @property {boolean} [faceAvatar=false] If true, the end of the Pointer will always rotate to face the avatar.
* @property {boolean} [centerEndY=true] If false, the end of the Pointer will be moved up by half of its height.
* @property {boolean} [lockEnd=false] If true, the end of the Pointer will lock on to the center of the object at which the laser is pointing.
* @property {boolean} [lockEnd=false] If true, the end of the Pointer will lock on to the center of the object at which the pointer is pointing.
* @property {boolean} [distanceScaleEnd=false] If true, the dimensions of the end of the Pointer will scale linearly with distance.
* @property {boolean} [scaleWithAvatar=false] If true, the width of the Pointer's path will scale linearly with your avatar's scale.
* @property {boolean} [followNormal=false] If true, the end of the Pointer will rotate to follow the normal of the intersected surface.
@ -207,9 +207,10 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
* The rendering properties of the parabolic path
*
* @typedef {object} Pointers.ParabolaProperties
* @property {Color} color The color of the parabola.
* @property {number} alpha The alpha of the parabola.
* @property {number} width The width of the parabola, in meters.
* @property {Color} color=255,255,255 The color of the parabola.
* @property {number} alpha=1.0 The alpha of the parabola.
* @property {number} width=0.01 The width of the parabola, in meters.
* @property {boolean} isVisibleInSecondaryCamera=false The width of the parabola, in meters.
*/
/**jsdoc
* A set of properties used to define the visual aspect of a Parabola Pointer in the case that the Pointer is not intersecting something. Same as a {@link Pointers.ParabolaPointerRenderState},
@ -232,10 +233,10 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope
*/
/**jsdoc
* A set of properties that can be passed to {@link Pointers.createPointer} to create a new Pointer. Contains the relevant {@link Picks.PickProperties} to define the underlying Pick.
* @typedef {object} Pointers.LaserPointerProperties
* @typedef {object} Pointers.ParabolaPointerProperties
* @property {boolean} [faceAvatar=false] If true, the end of the Pointer will always rotate to face the avatar.
* @property {boolean} [centerEndY=true] If false, the end of the Pointer will be moved up by half of its height.
* @property {boolean} [lockEnd=false] If true, the end of the Pointer will lock on to the center of the object at which the laser is pointing.
* @property {boolean} [lockEnd=false] If true, the end of the Pointer will lock on to the center of the object at which the pointer is pointing.
* @property {boolean} [distanceScaleEnd=false] If true, the dimensions of the end of the Pointer will scale linearly with distance.
* @property {boolean} [scaleWithAvatar=false] If true, the width of the Pointer's path will scale linearly with your avatar's scale.
* @property {boolean} [followNormal=false] If true, the end of the Pointer will rotate to follow the normal of the intersected surface.

View file

@ -56,8 +56,7 @@ class QScriptEngine;
* @property {Uuid} tabletID - The UUID of the tablet body model overlay.
* @property {Uuid} tabletScreenID - The UUID of the tablet's screen overlay.
* @property {Uuid} homeButtonID - The UUID of the tablet's "home" button overlay.
* @property {Uuid} homeButtonHighlightMaterialID - The UUID of the material entity used to highlight tablet button
* @property {Uuid} homeButtonUnhighlightMaterialID - The UUID of the material entity use to unhighlight the entity
* @property {Uuid} homeButtonHighlightID - The UUID of the tablet's "home" button highlight overlay.
*/
class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Dependency {
Q_OBJECT
@ -69,11 +68,10 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen
Q_PROPERTY(QUuid tabletID READ getCurrentTabletFrameID WRITE setCurrentTabletFrameID)
Q_PROPERTY(QUuid homeButtonID READ getCurrentHomeButtonID WRITE setCurrentHomeButtonID)
Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID)
Q_PROPERTY(QUuid homeButtonHighlightMaterialID READ getCurrentHomeButtonHighlightMaterialID WRITE setCurrentHomeButtonHighlightMaterialID)
Q_PROPERTY(QUuid homeButtonUnhighlightMaterialID READ getCurrentHomeButtonUnhighlightMaterialID WRITE setCurrentHomeButtonUnhighlightMaterialID)
Q_PROPERTY(QUuid homeButtonHighlightID READ getCurrentHomeButtonHighlightID WRITE setCurrentHomeButtonHighlightID)
public:
/**jsdoc
* Calculate the intersection of a ray with the HUD overlay.
* @function HMD.calculateRayUICollisionPoint
@ -365,15 +363,12 @@ public:
void setCurrentHomeButtonID(QUuid homeButtonID) { _homeButtonID = homeButtonID; }
QUuid getCurrentHomeButtonID() const { return _homeButtonID; }
void setCurrentHomeButtonHighlightID(QUuid homeButtonHighlightID) { _homeButtonHighlightID = homeButtonHighlightID; }
QUuid getCurrentHomeButtonHighlightID() const { return _homeButtonHighlightID; }
void setCurrentTabletScreenID(QUuid tabletID) { _tabletScreenID = tabletID; }
QUuid getCurrentTabletScreenID() const { return _tabletScreenID; }
void setCurrentHomeButtonHighlightMaterialID(QUuid homeButtonHighlightMaterialID) { _homeButtonHighlightMaterialID = homeButtonHighlightMaterialID; }
QUuid getCurrentHomeButtonHighlightMaterialID() { return _homeButtonHighlightMaterialID; }
void setCurrentHomeButtonUnhighlightMaterialID(QUuid homeButtonUnhighlightMaterialID) { _homeButtonUnhighlightMaterialID = homeButtonUnhighlightMaterialID; }
QUuid getCurrentHomeButtonUnhighlightMaterialID() { return _homeButtonUnhighlightMaterialID; }
private:
bool _showTablet { false };
bool _tabletContextualMode { false };
@ -381,8 +376,7 @@ private:
QUuid _tabletScreenID; // this is the overlayID which is part of (a child of) the tablet-ui.
QUuid _homeButtonID;
QUuid _tabletEntityID;
QUuid _homeButtonHighlightMaterialID;
QUuid _homeButtonUnhighlightMaterialID;
QUuid _homeButtonHighlightID;
// Get the position of the HMD
glm::vec3 getPosition() const;

View file

@ -266,42 +266,6 @@ void setupPreferences() {
preferences->addPreference(new SliderPreference(FACE_TRACKING, "Eye Deflection", getter, setter));
}
static const QString MOVEMENT{ "Movement" };
{
static const QString movementsControlChannel = QStringLiteral("Hifi-Advanced-Movement-Disabler");
auto getter = [=]()->bool { return myAvatar->useAdvancedMovementControls(); };
auto setter = [=](bool value) { myAvatar->setUseAdvancedMovementControls(value); };
preferences->addPreference(new CheckPreference(MOVEMENT,
QStringLiteral("Advanced movement for hand controllers"),
getter, setter));
}
{
auto getter = [=]()->int { return myAvatar->getSnapTurn() ? 0 : 1; };
auto setter = [=](int value) { myAvatar->setSnapTurn(value == 0); };
auto preference = new RadioButtonsPreference(MOVEMENT, "Snap turn / Smooth turn", getter, setter);
QStringList items;
items << "Snap turn" << "Smooth turn";
preference->setItems(items);
preferences->addPreference(preference);
}
{
auto getter = [=]()->float { return myAvatar->getUserHeight(); };
auto setter = [=](float value) { myAvatar->setUserHeight(value); };
auto preference = new SpinnerPreference(MOVEMENT, "User real-world height (meters)", getter, setter);
preference->setMin(1.0f);
preference->setMax(2.2f);
preference->setDecimals(3);
preference->setStep(0.001f);
preferences->addPreference(preference);
}
{
auto preference = new ButtonPreference(MOVEMENT, "RESET SENSORS", [] {
qApp->resetSensors();
});
preferences->addPreference(preference);
}
static const QString VR_MOVEMENT{ "VR Movement" };
{
@ -315,7 +279,7 @@ void setupPreferences() {
{
auto getter = [=]()->bool { return myAvatar->getFlyingHMDPref(); };
auto setter = [=](bool value) { myAvatar->setFlyingHMDPref(value); };
preferences->addPreference(new CheckPreference(VR_MOVEMENT, "Flying & jumping", getter, setter));
preferences->addPreference(new CheckPreference(VR_MOVEMENT, "Flying & jumping (HMD)", getter, setter));
}
{
auto getter = [=]()->int { return myAvatar->getSnapTurn() ? 0 : 1; };

View file

@ -191,6 +191,14 @@ void Stats::updateStats(bool force) {
// Third column, avatar stats
auto myAvatar = avatarManager->getMyAvatar();
auto animStack = myAvatar->getSkeletonModel()->getRig().getAnimStack();
_animStackNames.clear();
for (auto animStackIterator = animStack.begin(); animStackIterator != animStack.end(); ++animStackIterator) {
_animStackNames << animStackIterator->first + ": " + QString::number(animStackIterator->second,'f',3);
}
emit animStackNamesChanged();
glm::vec3 avatarPos = myAvatar->getWorldPosition();
STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f);
@ -251,7 +259,6 @@ void Stats::updateStats(bool force) {
STAT_UPDATE(downloadsPending, ResourceCache::getPendingRequestCount());
STAT_UPDATE(processing, DependencyManager::get<StatTracker>()->getStat("Processing").toInt());
STAT_UPDATE(processingPending, DependencyManager::get<StatTracker>()->getStat("PendingProcessing").toInt());
// See if the active download urls have changed
bool shouldUpdateUrls = _downloads != _downloadUrls.size();
@ -346,7 +353,6 @@ void Stats::updateStats(bool force) {
auto config = qApp->getRenderEngine()->getConfiguration().get();
STAT_UPDATE(engineFrameTime, (float) config->getCPURunTime());
STAT_UPDATE(avatarSimulationTime, (float)avatarManager->getAvatarSimulationTime());
STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount());
STAT_UPDATE(gpuBufferMemory, (int)BYTES_TO_MB(gpu::Context::getBufferGPUMemSize()));
@ -431,7 +437,7 @@ void Stats::updateStats(bool force) {
// a new Map sorted by average time...
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
QMap<float, QString> sortedRecords;
const QMap<QString, PerformanceTimerRecord>& allRecords = PerformanceTimer::getAllTimerRecords();
auto allRecords = PerformanceTimer::getAllTimerRecords();
QMapIterator<QString, PerformanceTimerRecord> i(allRecords);
while (i.hasNext()) {
@ -479,7 +485,7 @@ void Stats::updateStats(bool force) {
bool operator<(const SortableStat& other) const { return priority < other.priority; }
};
const QMap<QString, PerformanceTimerRecord>& allRecords = PerformanceTimer::getAllTimerRecords();
auto allRecords = PerformanceTimer::getAllTimerRecords();
std::priority_queue<SortableStat> idleUpdateStats;
auto itr = allRecords.find("/idle/update");
if (itr != allRecords.end()) {
@ -496,7 +502,7 @@ void Stats::updateStats(bool force) {
};
for (int32_t j = 0; j < categories.size(); ++j) {
QString recordKey = "/idle/update/" + categories[j];
auto record = PerformanceTimer::getTimerRecord(recordKey);
auto& record = allRecords[recordKey];
if (record.getCount()) {
float dt = (float) record.getMovingAverage() / (float)USECS_PER_MSEC;
QString message = QString("\n %1 = %2").arg(categories[j]).arg(dt);

View file

@ -135,6 +135,7 @@ private: \
* @property {number} batchFrameTime - <em>Read-only.</em>
* @property {number} engineFrameTime - <em>Read-only.</em>
* @property {number} avatarSimulationTime - <em>Read-only.</em>
* @property {string[]} animStackNames - <em>Read-only.</em>
*
*
* @property {number} x
@ -282,6 +283,7 @@ class Stats : public QQuickItem {
STATS_PROPERTY(float, batchFrameTime, 0)
STATS_PROPERTY(float, engineFrameTime, 0)
STATS_PROPERTY(float, avatarSimulationTime, 0)
Q_PROPERTY(QStringList animStackNames READ animStackNames NOTIFY animStackNamesChanged)
public:
static Stats* getInstance();
@ -306,6 +308,7 @@ public:
}
QStringList downloadUrls () { return _downloadUrls; }
QStringList animStackNames() { return _animStackNames; }
public slots:
void forceUpdateStats() { updateStats(true); }
@ -999,6 +1002,13 @@ signals:
*/
void avatarSimulationTimeChanged();
/**jsdoc
* Triggered when the value of the <code>animStackNames</code> property changes.
* @function Stats.animStackNamesChanged
* @returns {Signal}
*/
void animStackNamesChanged();
/**jsdoc
* Triggered when the value of the <code>rectifiedTextureCount</code> property changes.
* @function Stats.rectifiedTextureCountChanged
@ -1244,6 +1254,7 @@ private:
QString _monospaceFont;
const AudioIOStats* _audioStats;
QStringList _downloadUrls = QStringList();
QStringList _animStackNames = QStringList();
};
#endif // hifi_Stats_h

View file

@ -14,11 +14,7 @@
#include <StencilMaskPass.h>
#include <GeometryCache.h>
#include "render-utils/drawWorkloadProxy_vert.h"
#include "render-utils/drawWorkloadView_vert.h"
#include "render-utils/drawWorkloadProxy_frag.h"
#include "render-utils/drawWorkloadView_frag.h"
#include <shaders/Shaders.h>
void GameSpaceToRender::configure(const Config& config) {
@ -101,7 +97,7 @@ namespace render {
}
}
GameWorkloadRenderItem::GameWorkloadRenderItem() : _key(render::ItemKey::Builder::opaqueShape().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1)) {
GameWorkloadRenderItem::GameWorkloadRenderItem() : _key(render::ItemKey::Builder::opaqueShape().withoutShadowCaster().withTagBits(render::ItemKey::TAG_BITS_0 | render::ItemKey::TAG_BITS_1)) {
}
render::ItemKey GameWorkloadRenderItem::getKey() const {
@ -149,14 +145,7 @@ void GameWorkloadRenderItem::setAllViews(const workload::Views& views) {
const gpu::PipelinePointer GameWorkloadRenderItem::getProxiesPipeline() {
if (!_drawAllProxiesPipeline) {
auto vs = drawWorkloadProxy_vert::getShader();
auto ps = drawWorkloadProxy_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("workloadProxiesBuffer", 0));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::drawWorkloadProxy);
auto state = std::make_shared<gpu::State>();
state->setDepthTest(true, true, gpu::LESS_EQUAL);
/* state->setBlendFunction(true,
@ -173,15 +162,7 @@ const gpu::PipelinePointer GameWorkloadRenderItem::getProxiesPipeline() {
const gpu::PipelinePointer GameWorkloadRenderItem::getViewsPipeline() {
if (!_drawAllViewsPipeline) {
auto vs = drawWorkloadView_vert::getShader();
auto ps = drawWorkloadView_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("workloadViewsBuffer", 1));
slotBindings.insert(gpu::Shader::Binding("drawMeshBuffer", 0));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::drawWorkloadView);
auto state = std::make_shared<gpu::State>();
state->setDepthTest(true, true, gpu::LESS_EQUAL);
/* state->setBlendFunction(true,
@ -192,6 +173,7 @@ const gpu::PipelinePointer GameWorkloadRenderItem::getViewsPipeline() {
state->setCullMode(gpu::State::CULL_NONE);
_drawAllViewsPipeline = gpu::Pipeline::create(program, state);
}
return _drawAllViewsPipeline;
}

View file

@ -27,6 +27,7 @@ AnimBlendLinear::~AnimBlendLinear() {
const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
_alpha = animVars.lookup(_alphaVar, _alpha);
float parentAlpha = _animStack[_id];
if (_children.size() == 0) {
for (auto&& pose : _poses) {
@ -34,16 +35,27 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con
}
} else if (_children.size() == 1) {
_poses = _children[0]->evaluate(animVars, context, dt, triggersOut);
_animStack[_children[0]->getID()] = parentAlpha;
} else {
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
size_t prevPoseIndex = glm::floor(clampedAlpha);
size_t nextPoseIndex = glm::ceil(clampedAlpha);
float alpha = glm::fract(clampedAlpha);
auto alpha = glm::fract(clampedAlpha);
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, dt);
}
// weights are for animation stack debug purposes only.
float weight1 = 0.0f;
float weight2 = 0.0f;
if (prevPoseIndex == nextPoseIndex) {
weight2 = 1.0f;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
} else {
weight2 = alpha;
weight1 = 1.0f - weight2;
_animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
}
}
processOutputJoints(triggersOut);
return _poses;

View file

@ -26,13 +26,46 @@ AnimBlendLinearMove::~AnimBlendLinearMove() {
}
static float calculateAlpha(const float speed, const std::vector<float>& characteristicSpeeds) {
assert(characteristicSpeeds.size() > 0);
// calculate alpha from linear combination of referenceSpeeds.
float alpha = 0.0f;
if (speed <= characteristicSpeeds.front()) {
alpha = 0.0f;
} else if (speed > characteristicSpeeds.back()) {
alpha = (float)(characteristicSpeeds.size() - 1);
} else {
for (size_t i = 0; i < characteristicSpeeds.size() - 1; i++) {
if (characteristicSpeeds[i] < speed && speed < characteristicSpeeds[i + 1]) {
alpha = (float)i + ((speed - characteristicSpeeds[i]) / (characteristicSpeeds[i + 1] - characteristicSpeeds[i]));
break;
}
}
}
return alpha;
}
const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
assert(_children.size() == _characteristicSpeeds.size());
_alpha = animVars.lookup(_alphaVar, _alpha);
_desiredSpeed = animVars.lookup(_desiredSpeedVar, _desiredSpeed);
float speed = 0.0f;
if (_alphaVar.contains("Lateral")) {
speed = animVars.lookup("moveLateralSpeed", speed);
} else if (_alphaVar.contains("Backward")) {
speed = animVars.lookup("moveBackwardSpeed", speed);
} else {
//this is forward movement
speed = animVars.lookup("moveForwardSpeed", speed);
}
_alpha = calculateAlpha(speed, _characteristicSpeeds);
float parentAlpha = _animStack[_id];
_animStack["speed"] = speed;
if (_children.size() == 0) {
for (auto&& pose : _poses) {
pose = AnimPose::identity;
@ -44,8 +77,8 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
float prevDeltaTime, nextDeltaTime;
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
_animStack[_children[0]->getID()] = parentAlpha;
} else {
auto clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
auto prevPoseIndex = glm::floor(clampedAlpha);
auto nextPoseIndex = glm::ceil(clampedAlpha);
@ -53,6 +86,19 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars,
float prevDeltaTime, nextDeltaTime;
setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut);
evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime);
// weights are for animation stack debug purposes only.
float weight1 = 0.0f;
float weight2 = 0.0f;
if (prevPoseIndex == nextPoseIndex) {
weight2 = 1.0f;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
} else {
weight2 = alpha;
weight1 = 1.0f - weight2;
_animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha;
_animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha;
}
}
processOutputJoints(triggersOut);

View file

@ -481,29 +481,6 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const
// reduce angle by a flexCoefficient
angle *= target.getFlexCoefficient(chainDepth);
deltaRotation = glm::angleAxis(angle, axis);
// The swing will re-orient the tip but there will tend to be be a non-zero delta between the tip's
// new orientation and its target. This is the final parent-relative orientation that the tip joint have
// make to achieve its target orientation.
glm::quat tipRelativeRotation = glm::inverse(deltaRotation * tipParentOrientation) * target.getRotation();
// enforce tip's constraint
RotationConstraint* constraint = getConstraint(tipIndex);
if (constraint) {
bool constrained = constraint->apply(tipRelativeRotation);
if (constrained) {
// The tip's final parent-relative rotation would violate its constraint
// so we try to pre-twist this pivot to compensate.
glm::quat constrainedTipRotation = deltaRotation * tipParentOrientation * tipRelativeRotation;
glm::quat missingRotation = target.getRotation() * glm::inverse(constrainedTipRotation);
glm::quat swingPart;
glm::quat twistPart;
glm::vec3 axis = glm::normalize(deltaRotation * leverArm);
swingTwistDecomposition(missingRotation, axis, swingPart, twistPart);
const float LIMIT_LEAK_FRACTION = 0.1f;
deltaRotation = safeLerp(glm::quat(), twistPart, LIMIT_LEAK_FRACTION);
}
}
}
}
} else if (targetType == IKTarget::Type::HmdHead) {
@ -1255,48 +1232,7 @@ void AnimInverseKinematics::initConstraints() {
constraint = static_cast<RotationConstraint*>(stConstraint);
} else if (0 == baseName.compare("Hand", Qt::CaseSensitive)) {
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
stConstraint->setTwistLimits(0.0f, 0.0f); // max == min, disables twist limits
/* KEEP THIS CODE for future experimentation -- twist limits for hands
const float MAX_HAND_TWIST = 3.0f * PI / 5.0f;
const float MIN_HAND_TWIST = -PI / 2.0f;
if (isLeft) {
stConstraint->setTwistLimits(-MAX_HAND_TWIST, -MIN_HAND_TWIST);
} else {
stConstraint->setTwistLimits(MIN_HAND_TWIST, MAX_HAND_TWIST);
}
*/
/* KEEP THIS CODE for future experimentation -- non-symmetrical swing limits for wrist
* a more complicated wrist with asymmetric cone
// these directions are approximate swing limits in parent-frame
// NOTE: they don't need to be normalized
std::vector<glm::vec3> swungDirections;
swungDirections.push_back(glm::vec3(1.0f, 1.0f, 0.0f));
swungDirections.push_back(glm::vec3(0.75f, 1.0f, -1.0f));
swungDirections.push_back(glm::vec3(-0.75f, 1.0f, -1.0f));
swungDirections.push_back(glm::vec3(-1.0f, 1.0f, 0.0f));
swungDirections.push_back(glm::vec3(-0.75f, 1.0f, 1.0f));
swungDirections.push_back(glm::vec3(0.75f, 1.0f, 1.0f));
// rotate directions into joint-frame
glm::quat invRelativeRotation = glm::inverse(_defaultRelativePoses[i].rot);
int numDirections = (int)swungDirections.size();
for (int j = 0; j < numDirections; ++j) {
swungDirections[j] = invRelativeRotation * swungDirections[j];
}
stConstraint->setSwingLimits(swungDirections);
*/
// simple cone
std::vector<float> minDots;
const float MAX_HAND_SWING = PI / 2.0f;
minDots.push_back(cosf(MAX_HAND_SWING));
stConstraint->setSwingLimits(minDots);
constraint = static_cast<RotationConstraint*>(stConstraint);
// hand/wrist constraints have been disabled.
} else if (baseName.startsWith("Shoulder", Qt::CaseSensitive)) {
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());

View file

@ -12,6 +12,10 @@
#include <QtGlobal>
std::map<QString, float> AnimNode::_animStack = {
{"none", 0.0f}
};
AnimNode::Pointer AnimNode::getParent() {
return _parent.lock();
}

View file

@ -84,6 +84,7 @@ public:
}
void setCurrentFrame(float frame);
const std::map<QString, float> getAnimStack() { return _animStack; }
template <typename F>
bool traverse(F func) {
@ -126,6 +127,9 @@ protected:
std::weak_ptr<AnimNode> _parent;
std::vector<QString> _outputJointNames;
// global available to Stats.h
static std::map<QString, float> _animStack;
// no copies
AnimNode(const AnimNode&) = delete;
AnimNode& operator=(const AnimNode&) = delete;

View file

@ -661,7 +661,7 @@ bool processStateMachineNode(AnimNode::Pointer node, const QJsonObject& jsonObj,
return false;
}
AnimStateMachine::InterpType interpTypeEnum = AnimStateMachine::InterpType::SnapshotBoth; // default value
AnimStateMachine::InterpType interpTypeEnum = AnimStateMachine::InterpType::SnapshotPrev; // default value
if (!interpType.isEmpty()) {
interpTypeEnum = stringToInterpType(interpType);
if (interpTypeEnum == AnimStateMachine::InterpType::NumTypes) {

View file

@ -23,12 +23,18 @@ AnimStateMachine::~AnimStateMachine() {
const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
if (_id.contains("userAnimStateMachine")) {
_animStack.clear();
}
QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID());
if (_currentState->getID() != desiredStateID) {
// switch states
bool foundState = false;
for (auto& state : _states) {
if (state->getID() == desiredStateID) {
// parenthesis means previous state, which is a snapshot.
_previousStateID = "(" + _currentState->getID() + ")";
switchState(animVars, context, state);
foundState = true;
break;
@ -42,6 +48,8 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
// evaluate currentState transitions
auto desiredState = evaluateTransitions(animVars);
if (desiredState != _currentState) {
// parenthesis means previous state, which is a snapshot.
_previousStateID = "(" + _currentState->getID() + ")";
switchState(animVars, context, desiredState);
}
@ -49,8 +57,17 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
auto currentStateNode = _children[_currentState->getChildIndex()];
assert(currentStateNode);
if (!_previousStateID.contains("none")) {
_animStack[_previousStateID] = 1.0f - _alpha;
}
if (_duringInterp) {
_alpha += _alphaVel * dt;
if (_alpha > 1.0f) {
_animStack[_currentState->getID()] = 1.0f;
} else {
_animStack[_currentState->getID()] = _alpha;
}
if (_alpha < 1.0f) {
AnimPoseVec* nextPoses = nullptr;
AnimPoseVec* prevPoses = nullptr;
@ -68,20 +85,23 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
} else {
assert(false);
}
if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) {
::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]);
}
} else {
_duringInterp = false;
if (_animStack.count(_previousStateID) > 0) {
_animStack.erase(_previousStateID);
}
_previousStateID = "none";
_prevPoses.clear();
_nextPoses.clear();
}
}
if (!_duringInterp) {
_animStack[_currentState->getID()] = 1.0f;
_poses = currentStateNode->evaluate(animVars, context, dt, triggersOut);
}
processOutputJoints(triggersOut);
return _poses;

View file

@ -133,11 +133,12 @@ protected:
// interpolation state
bool _duringInterp = false;
InterpType _interpType { InterpType::SnapshotBoth };
InterpType _interpType { InterpType::SnapshotPrev };
float _alphaVel = 0.0f;
float _alpha = 0.0f;
AnimPoseVec _prevPoses;
AnimPoseVec _nextPoses;
QString _previousStateID { "none" };
State::Pointer _currentState;
std::vector<State::Pointer> _states;

View file

@ -590,28 +590,6 @@ bool Rig::getAbsoluteJointPoseInRigFrame(int jointIndex, AnimPose& returnPose) c
}
}
void Rig::calcAnimAlpha(float speed, const std::vector<float>& referenceSpeeds, float* alphaOut) const {
ASSERT(referenceSpeeds.size() > 0);
// calculate alpha from linear combination of referenceSpeeds.
float alpha = 0.0f;
if (speed <= referenceSpeeds.front()) {
alpha = 0.0f;
} else if (speed > referenceSpeeds.back()) {
alpha = (float)(referenceSpeeds.size() - 1);
} else {
for (size_t i = 0; i < referenceSpeeds.size() - 1; i++) {
if (referenceSpeeds[i] < speed && speed < referenceSpeeds[i + 1]) {
alpha = (float)i + ((speed - referenceSpeeds[i]) / (referenceSpeeds[i + 1] - referenceSpeeds[i]));
break;
}
}
}
*alphaOut = alpha;
}
void Rig::setEnableInverseKinematics(bool enable) {
_enableInverseKinematics = enable;
}
@ -651,11 +629,6 @@ bool Rig::getRelativeDefaultJointTranslation(int index, glm::vec3& translationOu
}
}
// animation reference speeds.
static const std::vector<float> FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s
static const std::vector<float> BACKWARD_SPEEDS = { 0.6f, 1.45f }; // m/s
static const std::vector<float> LATERAL_SPEEDS = { 0.2f, 0.65f }; // m/s
void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation, CharacterControllerState ccState) {
glm::vec3 forward = worldRotation * IDENTITY_FORWARD;
@ -675,24 +648,9 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// sine wave LFO var for testing.
static float t = 0.0f;
_animVars.set("sine", 2.0f * 0.5f * sinf(t) + 0.5f);
float moveForwardAlpha = 0.0f;
float moveBackwardAlpha = 0.0f;
float moveLateralAlpha = 0.0f;
// calcuate the animation alpha and timeScale values based on current speeds and animation reference speeds.
calcAnimAlpha(_averageForwardSpeed.getAverage(), FORWARD_SPEEDS, &moveForwardAlpha);
calcAnimAlpha(-_averageForwardSpeed.getAverage(), BACKWARD_SPEEDS, &moveBackwardAlpha);
calcAnimAlpha(fabsf(_averageLateralSpeed.getAverage()), LATERAL_SPEEDS, &moveLateralAlpha);
_animVars.set("moveForwardSpeed", _averageForwardSpeed.getAverage());
_animVars.set("moveForwardAlpha", moveForwardAlpha);
_animVars.set("moveBackwardSpeed", -_averageForwardSpeed.getAverage());
_animVars.set("moveBackwardAlpha", moveBackwardAlpha);
_animVars.set("moveLateralSpeed", fabsf(_averageLateralSpeed.getAverage()));
_animVars.set("moveLateralAlpha", moveLateralAlpha);
const float MOVE_ENTER_SPEED_THRESHOLD = 0.2f; // m/sec
const float MOVE_EXIT_SPEED_THRESHOLD = 0.07f; // m/sec
@ -777,6 +735,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", false);
} else {
@ -785,28 +745,48 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isMovingForward", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", false);
}
} else {
if (lateralSpeed > 0.0f) {
// right
_animVars.set("isMovingRight", true);
_animVars.set("isMovingLeft", false);
if (!_headEnabled) {
_animVars.set("isMovingRight", true);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
} else {
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", true);
_animVars.set("isMovingLeftHmd", false);
}
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isNotMoving", false);
} else {
// left
_animVars.set("isMovingLeft", true);
_animVars.set("isMovingRight", false);
if (!_headEnabled) {
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", true);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
} else {
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", true);
}
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isNotMoving", false);
}
}
}
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -825,14 +805,16 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isNotTurning", false);
} else {
// turning left
_animVars.set("isTurningLeft", true);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", true);
_animVars.set("isNotTurning", false);
}
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -843,15 +825,17 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isInAirRun", false);
_animVars.set("isNotInAir", true);
} else if (_state == RigRole::Idle ) {
} else if (_state == RigRole::Idle) {
// default anim vars to notMoving and notTurning
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -866,11 +850,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// flying.
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", true);
_animVars.set("isNotFlying", false);
@ -885,11 +871,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// jumping in-air
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -912,11 +900,13 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
// jumping in-air
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRightHmd", false);
_animVars.set("isMovingLeftHmd", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isTurningLeft", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
@ -1547,16 +1537,18 @@ bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex,
glm::vec3 backVector = oppositeArmPose.trans() - armPose.trans();
glm::vec3 backCenter = armPose.trans() + 0.5f * backVector;
const float OVER_BACK_HEAD_PERCENTAGE = 0.2f;
glm::vec3 frontVector = glm::normalize(glm::cross(backVector, Vectors::UNIT_Y));
glm::vec3 topVector = glm::normalize(glm::cross(frontVector, backVector));
glm::vec3 centerToHand = handPose.trans() - backCenter;
glm::vec3 headCenter = backCenter + glm::length(backVector) * topVector;
glm::vec3 headCenter = backCenter + glm::vec3(0, OVER_BACK_HEAD_PERCENTAGE * backVector.length(), 0);
glm::vec3 frontVector = glm::normalize(glm::cross(backVector, glm::vec3(0, 1, 0)));
// Make sure is pointing forward
frontVector = frontVector.z < 0 ? -frontVector : frontVector;
float horizontalModule = glm::dot(armToHand, glm::vec3(0, -1, 0));
glm::vec3 headForward = headCenter + horizontalModule * frontVector;
float horizontalModule = glm::dot(centerToHand, -topVector);
glm::vec3 headForward = headCenter + glm::max(0.0f, horizontalModule) * frontVector;
glm::vec3 armToHead = headForward - armPose.trans();
float armToHandDistance = glm::length(armToHand);
@ -1570,8 +1562,10 @@ bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex,
// How much the hand is reaching for the opposite side
float oppositeProjection = glm::dot(armToHandDir, glm::normalize(backVector));
// Don't use pole vector when the hands are behind
if (glm::dot(frontVector, armToHand) < 0 && oppositeProjection < 0.5f * armTotalDistance) {
bool isCrossed = glm::dot(centerToHand, backVector) > 0;
bool isBehind = glm::dot(frontVector, armToHand) < 0;
// Don't use pole vector when the hands are behind the back and the arms are not crossed
if (isBehind && !isCrossed) {
return false;
}
@ -1585,7 +1579,7 @@ bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex,
glm::vec3 correctionVector = glm::vec3(0, 0, 0);
const float FORWARD_TRIGGER_PERCENTAGE = 0.2f;
const float FORWARD_CORRECTOR_WEIGHT = 3.0f;
const float FORWARD_CORRECTOR_WEIGHT = 2.3f;
float elbowForwardTrigger = FORWARD_TRIGGER_PERCENTAGE * armToHandDistance;
@ -1619,7 +1613,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
_animVars.set("isTalking", params.isTalking);
_animVars.set("notIsTalking", !params.isTalking);
bool headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
_headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
bool leftHandEnabled = params.primaryControllerFlags[PrimaryControllerType_LeftHand] & (uint8_t)ControllerFlags::Enabled;
bool rightHandEnabled = params.primaryControllerFlags[PrimaryControllerType_RightHand] & (uint8_t)ControllerFlags::Enabled;
bool hipsEnabled = params.primaryControllerFlags[PrimaryControllerType_Hips] & (uint8_t)ControllerFlags::Enabled;
@ -1631,18 +1625,18 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
bool rightArmEnabled = params.secondaryControllerFlags[SecondaryControllerType_RightArm] & (uint8_t)ControllerFlags::Enabled;
glm::mat4 sensorToRigMatrix = glm::inverse(params.rigToSensorMatrix);
updateHead(headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]);
updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]);
updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, headEnabled, dt,
updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt,
params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand],
params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo,
params.rigToSensorMatrix, sensorToRigMatrix);
updateFeet(leftFootEnabled, rightFootEnabled, headEnabled,
updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled,
params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot],
params.rigToSensorMatrix, sensorToRigMatrix);
if (headEnabled) {
if (_headEnabled) {
// Blend IK chains toward the joint limit centers, this should stablize head and hand ik.
_animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses);
} else {

View file

@ -221,6 +221,9 @@ public:
// input assumed to be in rig space
void computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut) const;
const std::map<QString, float> getAnimStack() { return _animNode->getAnimStack(); }
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
signals:
void onLoadComplete();
@ -298,6 +301,7 @@ protected:
std::shared_ptr<AnimSkeleton> _animSkeleton;
std::unique_ptr<AnimNodeLoader> _animLoader;
AnimVariantMap _animVars;
enum class RigRole {
Idle = 0,
Turn,
@ -383,6 +387,7 @@ protected:
bool _smoothPoleVectors { false };
int _rigId;
bool _headEnabled { false };
};
#endif /* defined(__hifi__Rig__) */

View file

@ -840,7 +840,7 @@ static void nearFieldGainCorrection(float azimuth, float distance, float& gainL,
// normalized distance factor = [0,1] as distance = [HRTF_NEARFIELD_MAX,HRTF_HEAD_RADIUS]
assert(distance < HRTF_NEARFIELD_MAX);
assert(distance > HRTF_HEAD_RADIUS);
float d = (HRTF_NEARFIELD_MAX - distance) * ( 1.0f / (HRTF_NEARFIELD_MAX - HRTF_HEAD_RADIUS));
float d = (HRTF_NEARFIELD_MAX - distance) * (1.0f / (HRTF_NEARFIELD_MAX - HRTF_HEAD_RADIUS));
// angle of incidence at each ear
float angleL = azimuth + HALFPI;
@ -919,6 +919,9 @@ static void azimuthToIndex(float azimuth, int& index0, int& index1, float& frac)
index1 = index0 + 1;
frac = azimuth - (float)index0;
if (index0 >= HRTF_AZIMUTHS) {
index0 -= HRTF_AZIMUTHS;
}
if (index1 >= HRTF_AZIMUTHS) {
index1 -= HRTF_AZIMUTHS;
}

View file

@ -1577,6 +1577,14 @@ void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) {
radius = halfExtents.x;
}
glm::vec3 Avatar::getWorldFeetPosition() {
ShapeInfo shapeInfo;
computeShapeInfo(shapeInfo);
glm::vec3 halfExtents = shapeInfo.getHalfExtents(); // x = radius, y = halfHeight
glm::vec3 localFeet(0.0f, shapeInfo.getOffset().y - halfExtents.y - halfExtents.x, 0.0f);
return getWorldOrientation() * localFeet + getWorldPosition();
}
float Avatar::computeMass() {
float radius;
glm::vec3 start, end;

View file

@ -249,6 +249,12 @@ public:
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
void getCapsule(glm::vec3& start, glm::vec3& end, float& radius);
float computeMass();
/**jsdoc
* Get the position of the current avatar's feet (or rather, bottom of its collision capsule) in world coordinates.
* @function MyAvatar.getWorldFeetPosition
* @returns {Vec3} The position of the avatar's feet in world coordinates.
*/
Q_INVOKABLE glm::vec3 getWorldFeetPosition();
void setPositionViaScript(const glm::vec3& position) override;
void setOrientationViaScript(const glm::quat& orientation) override;

View file

@ -363,7 +363,7 @@ class AvatarData : public QObject, public SpatiallyNestable {
// The following properties have JSDoc in MyAvatar.h and ScriptableAvatar.h
Q_PROPERTY(glm::vec3 position READ getWorldPosition WRITE setPositionViaScript)
Q_PROPERTY(float scale READ getTargetScale WRITE setTargetScale)
Q_PROPERTY(float scale READ getDomainLimitedScale WRITE setTargetScale)
Q_PROPERTY(float density READ getDensity)
Q_PROPERTY(glm::vec3 handPosition READ getHandPosition WRITE setHandPosition)
Q_PROPERTY(float bodyYaw READ getBodyYaw WRITE setBodyYaw)
@ -895,14 +895,14 @@ public:
* @returns {object}
*/
// FIXME: Can this name be improved? Can it be deprecated?
Q_INVOKABLE QVariantList getAttachmentsVariant() const;
Q_INVOKABLE virtual QVariantList getAttachmentsVariant() const;
/**jsdoc
* @function MyAvatar.setAttachmentsVariant
* @param {object} variant
*/
// FIXME: Can this name be improved? Can it be deprecated?
Q_INVOKABLE void setAttachmentsVariant(const QVariantList& variant);
Q_INVOKABLE virtual void setAttachmentsVariant(const QVariantList& variant);
/**jsdoc
@ -969,7 +969,7 @@ public:
* print (attachments[i].modelURL);
* }
*/
Q_INVOKABLE QVector<AttachmentData> getAttachmentData() const;
Q_INVOKABLE virtual QVector<AttachmentData> getAttachmentData() const;
/**jsdoc
* Set all models currently attached to your avatar. For example, if you retrieve attachment data using
@ -1040,7 +1040,7 @@ public:
* @param {string} [jointName=""] - The name of the joint to detach the model from. If <code>""</code>, then the most
* recently attached model is removed from which ever joint it was attached to.
*/
Q_INVOKABLE void detachOne(const QString& modelURL, const QString& jointName = QString());
Q_INVOKABLE virtual void detachOne(const QString& modelURL, const QString& jointName = QString());
/**jsdoc
* Detach all instances of a particular model from either a specific joint or all joints.
@ -1049,7 +1049,7 @@ public:
* @param {string} [jointName=""] - The name of the joint to detach the model from. If <code>""</code>, then the model is
* detached from all joints.
*/
Q_INVOKABLE void detachAll(const QString& modelURL, const QString& jointName = QString());
Q_INVOKABLE virtual void detachAll(const QString& modelURL, const QString& jointName = QString());
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
@ -1317,6 +1317,7 @@ protected:
bool _firstSkeletonCheck { true };
QUrl _skeletonFBXURL;
QVector<AttachmentData> _attachmentData;
QVector<AttachmentData> _oldAttachmentData;
QString _displayName;
QString _sessionDisplayName { };
bool _lookAtSnappingEnabled { true };

View file

@ -1,7 +1,7 @@
set(TARGET_NAME display-plugins)
AUTOSCRIBE_SHADER_LIB(gpu display-plugins)
setup_hifi_library(Gui)
link_hifi_libraries(shared plugins ui-plugins gl ui render-utils ${PLATFORM_GL_BACKEND})
link_hifi_libraries(shared shaders plugins ui-plugins gl ui render-utils ${PLATFORM_GL_BACKEND})
include_hifi_library_headers(gpu)
include_hifi_library_headers(model-networking)
include_hifi_library_headers(networking)

View file

@ -0,0 +1,21 @@
struct TextureData {
ivec2 textureSize;
};
layout(std140, binding=0) uniform textureDataBuffer {
TextureData textureData;
};
layout(binding=0) uniform sampler2D colorMap;
layout(location=0) in vec2 varTexCoord0;
layout(location=0) out vec4 outFragColor;
void main(void) {
ivec2 texCoord = ivec2(floor(varTexCoord0 * textureData.textureSize));
texCoord.x /= 2;
int row = int(floor(gl_FragCoord.y));
if (row % 2 > 0) {
texCoord.x += (textureData.textureSize.x / 2);
}
outFragColor = vec4(pow(texelFetch(colorMap, texCoord, 0).rgb, vec3(2.2)), 1.0);
}

View file

@ -30,7 +30,7 @@
#include <gl/OffscreenGLCanvas.h>
#include <gpu/Texture.h>
#include <gpu/StandardShaderLib.h>
#include <shaders/Shaders.h>
#include <gpu/gl/GLShared.h>
#include <gpu/gl/GLBackend.h>
#include <GeometryCache.h>
@ -44,33 +44,6 @@
#include "CompositorHelper.h"
#include "Logging.h"
const char* SRGB_TO_LINEAR_FRAG = R"SCRIBE(
// OpenGLDisplayPlugin_present.frag
uniform sampler2D colorMap;
in vec2 varTexCoord0;
out vec4 outFragColor;
float sRGBFloatToLinear(float value) {
const float SRGB_ELBOW = 0.04045;
return (value <= SRGB_ELBOW) ? value / 12.92 : pow((value + 0.055) / 1.055, 2.4);
}
vec3 colorToLinearRGB(vec3 srgb) {
return vec3(sRGBFloatToLinear(srgb.r), sRGBFloatToLinear(srgb.g), sRGBFloatToLinear(srgb.b));
}
void main(void) {
outFragColor.a = 1.0;
outFragColor.rgb = colorToLinearRGB(texture(colorMap, varTexCoord0).rgb);
}
)SCRIBE";
extern QThread* RENDER_THREAD;
class PresentThread : public QThread, public Dependency {
@ -391,10 +364,7 @@ void OpenGLDisplayPlugin::customizeContext() {
if (!_presentPipeline) {
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::StandardShaderLib::getDrawTexturePS();
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::drawTexture);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(false));
state->setScissorEnable(true);
@ -402,10 +372,7 @@ void OpenGLDisplayPlugin::customizeContext() {
}
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(SRGB_TO_LINEAR_FRAG));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::SrgbToLinear);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(false));
state->setScissorEnable(true);
@ -413,10 +380,9 @@ void OpenGLDisplayPlugin::customizeContext() {
}
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::StandardShaderLib::getDrawTexturePS();
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord);
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture);
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(false));
state->setBlendFunction(true,
@ -426,10 +392,9 @@ void OpenGLDisplayPlugin::customizeContext() {
}
{
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::StandardShaderLib::getDrawTextureMirroredXPS();
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord);
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTextureMirroredX);
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(false));
state->setBlendFunction(true,
@ -439,10 +404,9 @@ void OpenGLDisplayPlugin::customizeContext() {
}
{
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
auto ps = gpu::StandardShaderLib::getDrawTexturePS();
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawTransformUnitQuad);
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture);
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(false));
state->setBlendFunction(true,

View file

@ -0,0 +1,22 @@
// OpenGLDisplayPlugin_present.frag
layout(binding = 0) uniform sampler2D colorMap;
layout(location = 0) in vec2 varTexCoord0;
layout(location = 0) out vec4 outFragColor;
float sRGBFloatToLinear(float value) {
const float SRGB_ELBOW = 0.04045;
return (value <= SRGB_ELBOW) ? value / 12.92 : pow((value + 0.055) / 1.055, 2.4);
}
vec3 colorToLinearRGB(vec3 srgb) {
return vec3(sRGBFloatToLinear(srgb.r), sRGBFloatToLinear(srgb.g), sRGBFloatToLinear(srgb.b));
}
void main(void) {
outFragColor.a = 1.0;
outFragColor.rgb = colorToLinearRGB(texture(colorMap, varTexCoord0).rgb);
}

View file

@ -24,8 +24,8 @@
#include <gl/GLWidget.h>
#include <shared/NsightHelpers.h>
#include <gpu/Context.h>
#include <gpu/StandardShaderLib.h>
#include <gpu/gl/GLBackend.h>
#include <shaders/Shaders.h>
#include <TextureCache.h>
#include <PathUtils.h>
@ -34,8 +34,6 @@
#include "../CompositorHelper.h"
#include "DesktopPreviewProvider.h"
#include "render-utils/hmd_ui_vert.h"
#include "render-utils/hmd_ui_frag.h"
static const QString MONO_PREVIEW = "Mono Preview";
static const QString DISABLE_PREVIEW = "Disable Preview";
@ -409,12 +407,7 @@ void HmdDisplayPlugin::HUDRenderer::build() {
void HmdDisplayPlugin::HUDRenderer::updatePipeline() {
if (!pipeline) {
auto vs = hmd_ui_vert::getShader();
auto ps = hmd_ui_frag::getShader();
auto program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program, gpu::Shader::BindingSet());
uniformsLocation = program->getUniformBuffers().findLocation("hudBuffer");
auto program = gpu::Shader::createProgram(shader::render_utils::program::hmd_ui);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(true, true, gpu::LESS_EQUAL));
state->setBlendFunction(true,
@ -437,9 +430,8 @@ std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> HmdDis
batch.setInputBuffer(gpu::Stream::POSITION, posView);
batch.setInputBuffer(gpu::Stream::TEXCOORD, uvView);
batch.setIndexBuffer(gpu::UINT16, indices, 0);
uniformsBuffer->setSubData(0, uniforms);
batch.setUniformBuffer(uniformsLocation, uniformsBuffer);
batch.setUniformBuffer(0, uniformsBuffer);
auto compositorHelper = DependencyManager::get<CompositorHelper>();
glm::mat4 modelTransform = compositorHelper->getUiTransform();

View file

@ -102,7 +102,6 @@ private:
gpu::BufferPointer indices;
uint32_t indexCount { 0 };
gpu::PipelinePointer pipeline;
int32_t uniformsLocation { -1 };
gpu::BufferPointer uniformsBuffer;

View file

@ -8,48 +8,17 @@
#include "InterleavedStereoDisplayPlugin.h"
#include <gpu/StandardShaderLib.h>
#include <gpu/Pipeline.h>
#include <gpu/Batch.h>
#include <gpu/Context.h>
static const char* INTERLEAVED_SRGB_TO_LINEAR_FRAG = R"SCRIBE(
struct TextureData {
ivec2 textureSize;
};
layout(std140) uniform textureDataBuffer {
TextureData textureData;
};
uniform sampler2D colorMap;
in vec2 varTexCoord0;
out vec4 outFragColor;
void main(void) {
ivec2 texCoord = ivec2(floor(varTexCoord0 * textureData.textureSize));
texCoord.x /= 2;
int row = int(floor(gl_FragCoord.y));
if (row % 2 > 0) {
texCoord.x += (textureData.textureSize.x / 2);
}
outFragColor = vec4(pow(texelFetch(colorMap, texCoord, 0).rgb, vec3(2.2)), 1.0);
}
)SCRIBE";
#include <shaders/Shaders.h>
const QString InterleavedStereoDisplayPlugin::NAME("3D TV - Interleaved");
void InterleavedStereoDisplayPlugin::customizeContext() {
StereoDisplayPlugin::customizeContext();
if (!_interleavedPresentPipeline) {
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(INTERLEAVED_SRGB_TO_LINEAR_FRAG));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::makeProgram(*program);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::InterleavedSrgbToLinear);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(false));
_interleavedPresentPipeline = gpu::Pipeline::create(program, state);

View file

@ -1,7 +1,6 @@
set(TARGET_NAME entities-renderer)
AUTOSCRIBE_SHADER_LIB(gpu graphics procedural render render-utils)
setup_hifi_library(Network Script)
link_hifi_libraries(shared workload gpu procedural graphics model-networking script-engine render render-utils image qml ui pointers)
link_hifi_libraries(shared workload gpu shaders procedural graphics model-networking script-engine render render-utils image qml ui pointers)
include_hifi_library_headers(networking)
include_hifi_library_headers(gl)
include_hifi_library_headers(ktx)
@ -18,3 +17,4 @@ include_hifi_library_headers(graphics-scripting) # for Forward.h
target_bullet()
target_polyvox()

View file

@ -40,7 +40,7 @@
#include <PointerManager.h>
std::function<bool()> EntityTreeRenderer::_entitiesShouldFadeFunction;
std::function<bool()> EntityTreeRenderer::_entitiesShouldFadeFunction = []() { return true; };
QString resolveScriptURL(const QString& scriptUrl) {
auto normalizedScriptUrl = DependencyManager::get<ResourceManager>()->normalizeURL(scriptUrl);

View file

@ -14,7 +14,6 @@
#include <ObjectMotionState.h>
#include "EntityTreeRenderer.h"
#include "RenderableLightEntityItem.h"
#include "RenderableLineEntityItem.h"
#include "RenderableModelEntityItem.h"
@ -44,8 +43,6 @@ enum class RenderItemStatusIcon {
NONE = 255
};
std::function<bool()> EntityRenderer::_entitiesShouldFadeFunction = []() { return true; };
void EntityRenderer::initEntityRenderers() {
REGISTER_ENTITY_TYPE_WITH_FACTORY(Model, RenderableModelEntityItem::factory)
REGISTER_ENTITY_TYPE_WITH_FACTORY(PolyVox, RenderablePolyVoxEntityItem::factory)
@ -336,6 +333,11 @@ bool EntityRenderer::needsRenderUpdate() const {
if (_needsRenderUpdate) {
return true;
}
if (isFading()) {
return true;
}
if (_prevIsTransparent != isTransparent()) {
return true;
}
@ -381,8 +383,12 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
withWriteLock([&] {
auto transparent = isTransparent();
if (_prevIsTransparent && !transparent) {
_isFading = false;
auto fading = isFading();
if (fading || _prevIsTransparent != transparent) {
emit requestRenderUpdate();
}
if (fading) {
_isFading = Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f;
}
_prevIsTransparent = transparent;

View file

@ -19,6 +19,7 @@
#include "EntitiesRendererLogging.h"
#include <graphics-scripting/Forward.h>
#include <RenderHifi.h>
#include "EntityTreeRenderer.h"
class EntityTreeRenderer;
@ -96,7 +97,7 @@ protected:
// Called by the `render` method after `needsRenderUpdate`
virtual void doRender(RenderArgs* args) = 0;
bool isFading() const { return _isFading; }
virtual bool isFading() const { return _isFading; }
void updateModelTransformAndBound();
virtual bool isTransparent() const { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; }
inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; }
@ -121,7 +122,6 @@ protected:
static void makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters);
static std::function<bool()> _entitiesShouldFadeFunction;
const Transform& getModelTransform() const;
Item::Bound _bound;
@ -131,7 +131,7 @@ protected:
ItemIDs _subRenderItemIDs;
uint64_t _fadeStartTime{ usecTimestampNow() };
uint64_t _updateTime{ usecTimestampNow() }; // used when sorting/throttling render updates
bool _isFading{ _entitiesShouldFadeFunction() };
bool _isFading { EntityTreeRenderer::getEntitiesShouldFadeFunction()() };
bool _prevIsTransparent { false };
bool _visible { false };
bool _isVisibleInSecondaryCamera { false };

View file

@ -112,11 +112,14 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
}
batch.setModelTransform(renderTransform);
drawMaterial->setTextureTransforms(textureTransform);
// bind the material
RenderPipelines::bindMaterial(drawMaterial, batch, args->_enableTexturing);
args->_details._materialSwitches++;
if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
drawMaterial->setTextureTransforms(textureTransform);
// bind the material
RenderPipelines::bindMaterial(drawMaterial, batch, args->_enableTexturing);
args->_details._materialSwitches++;
}
// Draw!
DependencyManager::get<GeometryCache>()->renderSphere(batch);

View file

@ -146,6 +146,9 @@ public:
void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) override;
void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) override;
// FIXME: model mesh parts should fade individually
bool isFading() const override { return false; }
protected:
virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override;
virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override;

View file

@ -13,9 +13,8 @@
#include <StencilMaskPass.h>
#include <GeometryCache.h>
#include <shaders/Shaders.h>
#include "textured_particle_vert.h"
#include "textured_particle_frag.h"
using namespace render;
using namespace render::entities;
@ -23,8 +22,6 @@ using namespace render::entities;
static uint8_t CUSTOM_PIPELINE_NUMBER = 0;
static gpu::Stream::FormatPointer _vertexFormat;
static std::weak_ptr<gpu::Pipeline> _texturedPipeline;
// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 12 to avoid collisions
static int32_t PARTICLE_UNIFORM_SLOT { 12 };
static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) {
auto texturedPipeline = _texturedPipeline.lock();
@ -36,17 +33,8 @@ static ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, co
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
PrepareStencil::testMask(*state);
auto vertShader = textured_particle_vert::getShader();
auto fragShader = textured_particle_frag::getShader();
auto program = gpu::Shader::createProgram(vertShader, fragShader);
auto program = gpu::Shader::createProgram(shader::entities_renderer::program::textured_particle);
_texturedPipeline = texturedPipeline = gpu::Pipeline::create(program, state);
batch.runLambda([program] {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("particleBuffer"), PARTICLE_UNIFORM_SLOT));
gpu::Shader::makeProgram(*program, slotBindings);
});
}
return std::make_shared<render::ShapePipeline>(texturedPipeline, nullptr, nullptr, nullptr);
@ -346,7 +334,7 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
transform.setRotation(_renderTransform.getRotation());
});
batch.setModelTransform(transform);
batch.setUniformBuffer(PARTICLE_UNIFORM_SLOT, _uniformBuffer);
batch.setUniformBuffer(0, _uniformBuffer);
batch.setInputFormat(_vertexFormat);
batch.setInputBuffer(0, _particleBuffer, 0, sizeof(GpuParticle));

View file

@ -17,60 +17,32 @@
#include <TextureCache.h>
#include <PathUtils.h>
#include <PerfStat.h>
#include <shaders/Shaders.h>
//#define POLYLINE_ENTITY_USE_FADE_EFFECT
#ifdef POLYLINE_ENTITY_USE_FADE_EFFECT
# include <FadeEffect.h>
#endif
#include "paintStroke_vert.h"
#include "paintStroke_frag.h"
#include "paintStroke_fade_vert.h"
#include "paintStroke_fade_frag.h"
using namespace render;
using namespace render::entities;
static uint8_t CUSTOM_PIPELINE_NUMBER { 0 };
static const int32_t PAINTSTROKE_TEXTURE_SLOT { 0 };
// FIXME: This is interfering with the uniform buffers in DeferredLightingEffect.cpp, so use 12 to avoid collisions
static const int32_t PAINTSTROKE_UNIFORM_SLOT { 12 };
static gpu::Stream::FormatPointer polylineFormat;
static gpu::PipelinePointer polylinePipeline;
#ifdef POLYLINE_ENTITY_USE_FADE_EFFECT
static gpu::PipelinePointer polylineFadePipeline;
#endif
struct PolyLineUniforms {
glm::vec3 color;
};
static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key, gpu::Batch& batch) {
if (!polylinePipeline) {
auto VS = paintStroke_vert::getShader();
auto PS = paintStroke_frag::getShader();
gpu::ShaderPointer program = gpu::Shader::createProgram(VS, PS);
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke);
#ifdef POLYLINE_ENTITY_USE_FADE_EFFECT
auto fadeVS = gpu::Shader::createVertex(std::string(paintStroke_fade_vert));
auto fadePS = gpu::Shader::createPixel(std::string(paintStroke_fade_frag));
gpu::ShaderPointer fadeProgram = gpu::Shader::createProgram(fadeVS, fadePS);
#endif
batch.runLambda([program
#ifdef POLYLINE_ENTITY_USE_FADE_EFFECT
, fadeProgram
#endif
] {
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("originalTexture"), PAINTSTROKE_TEXTURE_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("polyLineBuffer"), PAINTSTROKE_UNIFORM_SLOT));
gpu::Shader::makeProgram(*program, slotBindings);
#ifdef POLYLINE_ENTITY_USE_FADE_EFFECT
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), PAINTSTROKE_TEXTURE_SLOT + 1));
slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), PAINTSTROKE_UNIFORM_SLOT + 1));
gpu::Shader::makeProgram(*fadeProgram, slotBindings);
#endif
});
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(true, true, gpu::LESS_EQUAL);
PrepareStencil::testMask(*state);
@ -106,8 +78,6 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity)
polylineFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB), offsetof(Vertex, color));
});
PolyLineUniforms uniforms;
_uniformBuffer = std::make_shared<gpu::Buffer>(sizeof(PolyLineUniforms), (const gpu::Byte*) &uniforms);
_verticesBuffer = std::make_shared<gpu::Buffer>();
}
@ -148,9 +118,6 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
}
void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
PolyLineUniforms uniforms;
uniforms.color = toGlm(entity->getXColor());
memcpy(&_uniformBuffer.edit<PolyLineUniforms>(), &uniforms, sizeof(PolyLineUniforms));
auto pointsChanged = entity->pointsChanged();
auto strokeWidthsChanged = entity->strokeWidthsChanged();
auto normalsChanged = entity->normalsChanged();
@ -296,7 +263,6 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
gpu::Batch& batch = *args->_batch;
batch.setModelTransform(_polylineTransform);
batch.setUniformBuffer(PAINTSTROKE_UNIFORM_SLOT, _uniformBuffer);
if (_texture && _texture->isLoaded()) {
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, _texture->getGPUTexture());

View file

@ -65,7 +65,6 @@ protected:
QVector<glm::vec3> _lastStrokeColors;
QVector<float> _lastStrokeWidths;
gpu::BufferPointer _verticesBuffer;
gpu::BufferView _uniformBuffer;
uint32_t _numVertices { 0 };
bool _empty{ true };

View file

@ -25,14 +25,15 @@
#include <EntityEditPacketSender.h>
#include <PhysicalEntitySimulation.h>
#include <StencilMaskPass.h>
#include <graphics/ShaderConstants.h>
#include <render/ShapePipeline.h>
#include "entities-renderer/ShaderConstants.h"
#include <shaders/Shaders.h>
#include "EntityTreeRenderer.h"
#include "polyvox_vert.h"
#include "polyvox_frag.h"
#include "polyvox_fade_vert.h"
#include "polyvox_fade_frag.h"
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
# include <FadeEffect.h>
#endif
@ -72,11 +73,6 @@
#include "EntityTreeRenderer.h"
#include "polyvox_vert.h"
#include "polyvox_frag.h"
#include "polyvox_fade_vert.h"
#include "polyvox_fade_frag.h"
#include "RenderablePolyVoxEntityItem.h"
#include "EntityEditPacketSender.h"
#include "PhysicalEntitySimulation.h"
@ -1564,7 +1560,6 @@ scriptable::ScriptableModelBase RenderablePolyVoxEntityItem::getScriptableModel(
using namespace render;
using namespace render::entities;
static const int MATERIAL_GPU_SLOT { 3 };
static uint8_t CUSTOM_PIPELINE_NUMBER;
static gpu::PipelinePointer _pipelines[2];
static gpu::PipelinePointer _wireframePipelines[2];
@ -1572,17 +1567,8 @@ static gpu::Stream::FormatPointer _vertexFormat;
ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, gpu::Batch& batch) {
if (!_pipelines[0]) {
gpu::ShaderPointer vertexShaders[2] = { polyvox_vert::getShader(), polyvox_fade_vert::getShader() };
gpu::ShaderPointer pixelShaders[2] = { polyvox_frag::getShader(), polyvox_fade_frag::getShader() };
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("xMap"), 0));
slotBindings.insert(gpu::Shader::Binding(std::string("yMap"), 1));
slotBindings.insert(gpu::Shader::Binding(std::string("zMap"), 2));
#ifdef POLYVOX_ENTITY_USE_FADE_EFFECT
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), 3));
#endif
using namespace shader::entities_renderer::program;
int programsIds[2] = { polyvox, polyvox_fade };
auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_BACK);
@ -1597,12 +1583,7 @@ ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const Sha
// Two sets of pipelines: normal and fading
for (auto i = 0; i < 2; i++) {
gpu::ShaderPointer program = gpu::Shader::createProgram(vertexShaders[i], pixelShaders[i]);
batch.runLambda([program, slotBindings] {
gpu::Shader::makeProgram(*program, slotBindings);
});
gpu::ShaderPointer program = gpu::Shader::createProgram(programsIds[i]);
_pipelines[i] = gpu::Pipeline::create(program, state);
_wireframePipelines[i] = gpu::Pipeline::create(program, wireframeState);
}
@ -1737,8 +1718,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) {
}
}
int voxelVolumeSizeLocation = args->_shapePipeline->pipeline->getProgram()->getUniforms().findLocation("voxelVolumeSize");
batch._glUniform3f(voxelVolumeSizeLocation, _lastVoxelVolumeSize.x, _lastVoxelVolumeSize.y, _lastVoxelVolumeSize.z);
batch._glUniform3f(entities_renderer::slot::uniform::PolyvoxVoxelSize, _lastVoxelVolumeSize.x, _lastVoxelVolumeSize.y, _lastVoxelVolumeSize.z);
batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_mesh->getNumIndices(), 0);
}

View file

@ -15,12 +15,7 @@
#include <StencilMaskPass.h>
#include <GeometryCache.h>
#include <PerfStat.h>
#include "render-utils/simple_vert.h"
#include "render-utils/simple_frag.h"
#include "render-utils/simple_transparent_frag.h"
#include "render-utils/forward_simple_frag.h"
#include "render-utils/forward_simple_transparent_frag.h"
#include <shaders/Shaders.h>
#include "RenderPipelines.h"
@ -37,12 +32,10 @@ static const float SPHERE_ENTITY_SCALE = 0.5f;
ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
_procedural._vertexSource = simple_vert::getSource();
_procedural._vertexSource = gpu::Shader::getVertexShaderSource(shader::render_utils::vertex::simple);
// FIXME: Setup proper uniform slots and use correct pipelines for forward rendering
_procedural._opaquefragmentSource = simple_frag::getSource();
// FIXME: Transparent procedural entities only seem to work if they use the opaque pipelines
//_procedural._transparentfragmentSource = simple_transparent_frag::getSource();
_procedural._transparentfragmentSource = simple_frag::getSource();
_procedural._opaquefragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple);
_procedural._transparentfragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple_transparent);
_procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
_procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
@ -216,7 +209,14 @@ ShapeKey ShapeEntityRenderer::getShapeKey() {
return builder.build();
} else {
return Parent::getShapeKey();
ShapeKey::Builder builder;
if (_procedural.isReady()) {
builder.withOwnPipeline();
}
if (isTransparent()) {
builder.withTranslucent();
}
return builder.build();
}
}
@ -266,8 +266,10 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
geometryCache->renderSolidShapeInstance(args, batch, geometryShape, outColor, pipeline);
}
} else {
RenderPipelines::bindMaterial(mat, batch, args->_enableTexturing);
args->_details._materialSwitches++;
if (args->_renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
RenderPipelines::bindMaterial(mat, batch, args->_enableTexturing);
args->_details._materialSwitches++;
}
geometryCache->renderShape(batch, geometryShape);
}

View file

@ -0,0 +1,61 @@
// <!
// Created by Bradley Austin Davis on 2018/05/25
// Copyright 2013-2018 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 ENTITIES_SHADER_CONSTANTS_H@>
// <@def ENTITIES_SHADER_CONSTANTS_H@>
// Hack comment to absorb the extra '//' scribe prepends
#ifndef ENTITIES_SHADER_CONSTANTS_H
#define ENTITIES_SHADER_CONSTANTS_H
// Polyvox
#define ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE 0
#define ENTITIES_TEXTURE_POLYVOX_XMAP 0
#define ENTITIES_TEXTURE_POLYVOX_YMAP 1
#define ENTITIES_TEXTURE_POLYVOX_ZMAP 2
// <!
namespace entities_renderer { namespace slot {
namespace uniform {
enum Uniform {
PolyvoxVoxelSize = ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE,
};
}
namespace buffer {
enum Buffer {
};
} // namespace buffer
namespace texture {
enum Texture {
PolyvoxXMap = ENTITIES_TEXTURE_POLYVOX_XMAP,
PolyvoxYMap = ENTITIES_TEXTURE_POLYVOX_YMAP,
PolyvoxZMap = ENTITIES_TEXTURE_POLYVOX_ZMAP,
};
} // namespace texture
} } // namespace entities::slot
// !>
// Hack Comment
#endif // ENTITIES_SHADER_CONSTANTS_H
// <@if 1@>
// Trigger Scribe include
// <@endif@> <!def that !>
// <@endif@>
// Hack Comment

View file

@ -14,26 +14,15 @@
<@include DeferredBufferWrite.slh@>
// the albedo texture
uniform sampler2D originalTexture;
layout(binding=0) uniform sampler2D originalTexture;
// the interpolated normal
in vec3 interpolatedNormal;
in vec2 varTexcoord;
in vec4 varColor;
struct PolyLineUniforms {
vec3 color;
};
uniform polyLineBuffer {
PolyLineUniforms polyline;
};
layout(location=0) in vec3 interpolatedNormal;
layout(location=1) in vec2 varTexcoord;
layout(location=2) in vec4 varColor;
void main(void) {
vec4 texel = texture(originalTexture, varTexcoord);
int frontCondition = 1 -int(gl_FrontFacing) * 2;
vec3 color = varColor.rgb;

View file

@ -18,21 +18,19 @@
<$declareStandardTransform()$>
// the interpolated normal
out vec3 interpolatedNormal;
layout(location=0) out vec3 interpolatedNormal;
//the diffuse texture
out vec2 varTexcoord;
layout(location=1) out vec2 varTexcoord;
out vec4 varColor;
layout(location=2) out vec4 varColor;
void main(void) {
varTexcoord = inTexCoord0.st;
// pass along the diffuse color
varColor = color_sRGBAToLinear(inColor);
// standard transform
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();

View file

@ -2,7 +2,7 @@
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// paintStroke_fade.slf
// paintStroke_fade.frag
// fragment shader
//
// Created by Olivier Prat on 19/07/17.
@ -18,19 +18,19 @@
<$declareFadeFragment()$>
// the albedo texture
uniform sampler2D originalTexture;
layout(binding=0) uniform sampler2D originalTexture;
// the interpolated normal
in vec3 interpolatedNormal;
in vec2 varTexcoord;
in vec4 varColor;
in vec4 _worldPosition;
layout(location=0) in vec3 interpolatedNormal;
layout(location=1) in vec2 varTexcoord;
layout(location=2) in vec4 varColor;
layout(location=3) in vec4 _worldPosition;
struct PolyLineUniforms {
vec3 color;
};
uniform polyLineBuffer {
layout(binding=0) uniform polyLineBuffer {
PolyLineUniforms polyline;
};

View file

@ -2,7 +2,7 @@
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// paintStroke_fade.slv
// paintStroke_fade.vert
// vertex shader
//
// Created by Olivier Prat on 19/07/17.
@ -18,13 +18,13 @@
<$declareStandardTransform()$>
// the interpolated normal
out vec3 interpolatedNormal;
layout(location=0) out vec3 interpolatedNormal;
//the diffuse texture
out vec2 varTexcoord;
layout(location=1) out vec2 varTexcoord;
out vec4 varColor;
out vec4 _worldPosition;
layout(location=2) out vec4 varColor;
layout(location=3) out vec4 _worldPosition;
void main(void) {

View file

@ -13,15 +13,17 @@
<@include graphics/Material.slh@>
<@include DeferredBufferWrite.slh@>
<@include render-utils/ShaderConstants.h@>
<@include entities-renderer/ShaderConstants.h@>
in vec3 _normal;
in vec4 _position;
in vec4 _worldPosition;
layout(location=RENDER_UTILS_ATTR_NORMAL_MS) in vec3 _normal;
layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec4 _position;
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition;
uniform sampler2D xMap;
uniform sampler2D yMap;
uniform sampler2D zMap;
uniform vec3 voxelVolumeSize;
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
layout(location=ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE) uniform vec3 voxelVolumeSize;
void main(void) {
vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz));

View file

@ -11,14 +11,14 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Transform.slh@>
<@include render-utils/ShaderConstants.h@>
<$declareStandardTransform()$>
out vec4 _position;
out vec4 _worldPosition;
out vec3 _normal;
layout(location=RENDER_UTILS_ATTR_POSITION_MS) out vec4 _position;
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _worldPosition;
layout(location=RENDER_UTILS_ATTR_NORMAL_MS) out vec3 _normal;
void main(void) {
// standard transform

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