Merge branch 'master' of https://github.com/highfidelity/hifi into hdr

This commit is contained in:
samcake 2016-01-22 18:31:30 -08:00
commit 483d20d7a3
34 changed files with 343 additions and 172 deletions

View file

@ -25,6 +25,11 @@ macro(GENERATE_INSTALLERS)
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME}) set(CPACK_PACKAGE_INSTALL_DIRECTORY ${_DISPLAY_NAME})
if (WIN32) if (WIN32)
# include CMake module that will install compiler system libraries
# so that we have msvcr120 and msvcp120 installed with targets
set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ${INTERFACE_INSTALL_DIR})
include(InstallRequiredSystemLibraries)
set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico") set(CPACK_NSIS_MUI_ICON "${HF_CMAKE_DIR}/installer/installer.ico")
# install and reference the Add/Remove icon # install and reference the Add/Remove icon

View file

@ -12,24 +12,17 @@
macro(install_beside_console) macro(install_beside_console)
if (WIN32 OR APPLE) if (WIN32 OR APPLE)
# install this component beside the installed server-console executable # install this component beside the installed server-console executable
if (APPLE)
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
set(COMPONENT_DESTINATION "${CONSOLE_APP_CONTENTS}/MacOS/Components.app/Contents/MacOS")
else ()
set(COMPONENT_DESTINATION ${CONSOLE_INSTALL_DIR})
endif ()
if (APPLE) if (APPLE)
install( install(
TARGETS ${TARGET_NAME} TARGETS ${TARGET_NAME}
RUNTIME DESTINATION ${COMPONENT_DESTINATION} RUNTIME DESTINATION ${COMPONENT_INSTALL_DIR}
COMPONENT ${SERVER_COMPONENT} COMPONENT ${SERVER_COMPONENT}
) )
else () else ()
# setup install of executable and things copied by fixup/windeployqt # setup install of executable and things copied by fixup/windeployqt
install( install(
FILES "$<TARGET_FILE_DIR:${TARGET_NAME}>/" FILES "$<TARGET_FILE_DIR:${TARGET_NAME}>/"
DESTINATION ${COMPONENT_DESTINATION} DESTINATION ${COMPONENT_INSTALL_DIR}
COMPONENT ${SERVER_COMPONENT} COMPONENT ${SERVER_COMPONENT}
) )
@ -39,33 +32,42 @@ macro(install_beside_console)
endif () endif ()
if (TARGET_NAME STREQUAL domain-server) if (TARGET_NAME STREQUAL domain-server)
if (APPLE)
set(RESOURCES_DESTINATION ${COMPONENT_DESTINATION})
else ()
set(RESOURCES_DESTINATION ${CONSOLE_INSTALL_DIR})
endif ()
# install the resources folder for the domain-server where its executable will be # install the resources folder for the domain-server where its executable will be
install( install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/resources
DESTINATION ${RESOURCES_DESTINATION} DESTINATION ${COMPONENT_INSTALL_DIR}
USE_SOURCE_PERMISSIONS USE_SOURCE_PERMISSIONS
COMPONENT ${SERVER_COMPONENT} COMPONENT ${SERVER_COMPONENT}
) )
endif () endif ()
if (APPLE) if (APPLE)
# during the install phase, call fixup to drop the shared libraries for these components in the right place find_program(MACDEPLOYQT_COMMAND macdeployqt PATHS "${QT_DIR}/bin" NO_DEFAULT_PATH)
set(EXECUTABLE_NEEDING_FIXUP "\${CMAKE_INSTALL_PREFIX}/${COMPONENT_DESTINATION}/${TARGET_NAME}")
if (NOT MACDEPLOYQT_COMMAND AND (PRODUCTION_BUILD OR PR_BUILD))
message(FATAL_ERROR "Could not find macdeployqt at ${QT_DIR}/bin.\
It is required to produce a relocatable interface application.\
Check that the environment variable QT_DIR points to your Qt installation.\
")
endif ()
# during the install phase, call macdeployqt to drop the shared libraries for these components in the right place
set(COMPONENTS_BUNDLE_PATH "\${CMAKE_INSTALL_PREFIX}/${COMPONENT_APP_PATH}")
string(REPLACE " " "\\ " ESCAPED_BUNDLE_NAME ${COMPONENTS_BUNDLE_PATH})
set(EXECUTABLE_NEEDING_FIXUP "\${CMAKE_INSTALL_PREFIX}/${COMPONENT_INSTALL_DIR}/${TARGET_NAME}")
string(REPLACE " " "\\ " ESCAPED_EXECUTABLE_NAME ${EXECUTABLE_NEEDING_FIXUP})
install(CODE " install(CODE "
include(BundleUtilities) execute_process(COMMAND ${MACDEPLOYQT_COMMAND} ${ESCAPED_BUNDLE_NAME} -verbose=2 -executable=${ESCAPED_EXECUTABLE_NAME})"
fixup_bundle(\"${EXECUTABLE_NEEDING_FIXUP}\" \"\" \"${FIXUP_LIBS}\") COMPONENT ${SERVER_COMPONENT}
" COMPONENT ${SERVER_COMPONENT}) )
endif () endif()
endif () endif ()
# set variables used by manual ssleay library copy # set variables used by manual ssleay library copy
set(TARGET_INSTALL_DIR ${COMPONENT_DESTINATION}) set(TARGET_INSTALL_DIR ${COMPONENT_INSTALL_DIR})
set(TARGET_INSTALL_COMPONENT ${SERVER_COMPONENT}) set(TARGET_INSTALL_COMPONENT ${SERVER_COMPONENT})
manually_install_ssl_eay() manually_install_ssl_eay()

View file

@ -52,8 +52,24 @@ macro(SET_PACKAGING_PARAMETERS)
set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME}) set(CONSOLE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME}) set(INTERFACE_INSTALL_DIR ${DMG_SUBFOLDER_NAME})
set(CONSOLE_EXEC_NAME "Server Console.app")
set(CONSOLE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
set(CONSOLE_APP_CONTENTS "${CONSOLE_INSTALL_APP_PATH}/Contents")
set(COMPONENT_APP_PATH "${CONSOLE_APP_CONTENTS}/MacOS/Components.app")
set(COMPONENT_INSTALL_DIR "${COMPONENT_APP_PATH}/Contents/MacOS")
set(INTERFACE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${INTERFACE_BUNDLE_NAME}.app")
set(INTERFACE_ICON_FILENAME "${INTERFACE_ICON_PREFIX}.icns")
else () else ()
set(CONSOLE_INSTALL_DIR ".") if (WIN32)
set(CONSOLE_INSTALL_DIR "server-console")
else ()
set(CONSOLE_INSTALL_DIR ".")
endif ()
set(COMPONENT_INSTALL_DIR ".")
set(INTERFACE_INSTALL_DIR ".") set(INTERFACE_INSTALL_DIR ".")
endif () endif ()
@ -88,15 +104,6 @@ macro(SET_PACKAGING_PARAMETERS)
set(LAUNCH_NOW_REG_KEY "LaunchAfterInstall") set(LAUNCH_NOW_REG_KEY "LaunchAfterInstall")
endif () endif ()
if (APPLE)
set(CONSOLE_EXEC_NAME "Server Console.app")
set(CONSOLE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${CONSOLE_EXEC_NAME}")
set(INTERFACE_INSTALL_APP_PATH "${CONSOLE_INSTALL_DIR}/${INTERFACE_BUNDLE_NAME}.app")
set(INTERFACE_ICON_FILENAME "${INTERFACE_ICON_PREFIX}.icns")
endif()
# setup component categories for installer # setup component categories for installer
set(DDE_COMPONENT dde) set(DDE_COMPONENT dde)
set(CLIENT_COMPONENT client) set(CLIENT_COMPONENT client)

View file

@ -11,6 +11,7 @@
set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SM_SHORTCUT_NAME@") set(INTERFACE_SHORTCUT_NAME "@INTERFACE_SM_SHORTCUT_NAME@")
set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe") set(INTERFACE_WIN_EXEC_NAME "@INTERFACE_EXEC_PREFIX@.exe")
set(CONSOLE_INSTALL_SUBDIR "@CONSOLE_INSTALL_DIR@")
set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SM_SHORTCUT_NAME@") set(CONSOLE_SHORTCUT_NAME "@CONSOLE_SM_SHORTCUT_NAME@")
set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@") set(CONSOLE_WIN_EXEC_NAME "@CONSOLE_EXEC_NAME@")
set(DS_EXEC_NAME "@DS_EXEC_NAME@") set(DS_EXEC_NAME "@DS_EXEC_NAME@")

View file

@ -685,6 +685,31 @@ FunctionEnd
;Installer Sections ;Installer Sections
Section "-Core installation" Section "-Core installation"
;The following delete blocks are temporary and can be removed once users who had the initial installer have updated
;Delete any server-console files installed before it was placed in sub-folder
Delete "$INSTDIR\server-console.exe"
RMDir /r "$INSTDIR\locales"
RMDir /r "$INSTDIR\resources\app"
Delete "$INSTDIR\resources\atom.asar"
Delete "$INSTDIR\build-info.json"
Delete "$INSTDIR\content_resources_200_percent.pak"
Delete "$INSTDIR\content_shell.pak"
Delete "$INSTDIR\LICENSE"
Delete "$INSTDIR\LICENSES.chromium.html"
Delete "$INSTDIR\natives_blob.bin"
Delete "$INSTDIR\node.dll"
Delete "$INSTDIR\pdf.dll"
Delete "$INSTDIR\snapshot_blob.bin"
Delete "$INSTDIR\ui_resources_200_percent.pak"
Delete "$INSTDIR\vccorlib120.dll"
Delete "$INSTDIR\version"
Delete "$INSTDIR\xinput1_3.dll"
; Remove the Old Interface directory and vcredist_x64.exe (from installs prior to Server Console)
RMDir /r "$INSTDIR\Interface"
Delete "$INSTDIR\vcredist_x64.exe"
;Use the entire tree produced by the INSTALL target. Keep the ;Use the entire tree produced by the INSTALL target. Keep the
;list of directories here in sync with the RMDir commands below. ;list of directories here in sync with the RMDir commands below.
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
@ -769,7 +794,7 @@ Section "-Core installation"
; Conditional handling for server console shortcut ; Conditional handling for server console shortcut
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@}
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\@CONSOLE_SHORTCUT_NAME@.lnk" \
"$INSTDIR\@CONSOLE_WIN_EXEC_NAME@" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
${EndIf} ${EndIf}
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@UNINSTALLER_NAME@" CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@UNINSTALLER_NAME@"
@ -958,7 +983,7 @@ Function HandlePostInstallOptions
${NSD_GetState} $DesktopServerCheckbox $DesktopServerState ${NSD_GetState} $DesktopServerCheckbox $DesktopServerState
${If} $DesktopServerState == ${BST_CHECKED} ${If} $DesktopServerState == ${BST_CHECKED}
CreateShortCut "$DESKTOP\@CONSOLE_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_WIN_EXEC_NAME@" CreateShortCut "$DESKTOP\@CONSOLE_SHORTCUT_NAME@.lnk" "$INSTDIR\\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES !insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ YES
${Else} ${Else}
!insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO !insertmacro WritePostInstallOption @CONSOLE_DESKTOP_SHORTCUT_REG_KEY@ NO
@ -968,7 +993,7 @@ Function HandlePostInstallOptions
${NSD_GetState} $ServerStartupCheckbox $ServerStartupState ${NSD_GetState} $ServerStartupCheckbox $ServerStartupState
${If} $ServerStartupState == ${BST_CHECKED} ${If} $ServerStartupState == ${BST_CHECKED}
CreateShortCut "$SMSTARTUP\@CONSOLE_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_WIN_EXEC_NAME@" CreateShortCut "$SMSTARTUP\@CONSOLE_SHORTCUT_NAME@.lnk" "$INSTDIR\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"
!insertmacro WritePostInstallOption @CONSOLE_STARTUP_REG_KEY@ YES !insertmacro WritePostInstallOption @CONSOLE_STARTUP_REG_KEY@ YES
${Else} ${Else}
@ -1012,7 +1037,7 @@ Function HandlePostInstallOptions
; both launches use the explorer trick in case the user has elevated permissions for the installer ; both launches use the explorer trick in case the user has elevated permissions for the installer
; it won't be possible to use this approach if either application should be launched with a command line param ; it won't be possible to use this approach if either application should be launched with a command line param
${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@} ${If} ${SectionIsSelected} ${@SERVER_COMPONENT_NAME@}
Exec '"$WINDIR\explorer.exe" "$INSTDIR\@CONSOLE_WIN_EXEC_NAME@"' Exec '"$WINDIR\explorer.exe" "$INSTDIR\\@CONSOLE_INSTALL_SUBDIR@\@CONSOLE_WIN_EXEC_NAME@"'
${Else} ${Else}
Exec '"$WINDIR\explorer.exe" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"' Exec '"$WINDIR\explorer.exe" "$INSTDIR\@INTERFACE_WIN_EXEC_NAME@"'
${EndIf} ${EndIf}

View file

@ -1148,13 +1148,22 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
return nodeJson; return nodeJson;
} }
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment"; QDir pathForAssignmentScriptsDirectory() {
static const QString SCRIPTS_DIRECTORY_NAME = "/scripts/";
QDir directory(ServerPathUtils::getDataDirectory() + SCRIPTS_DIRECTORY_NAME);
if (!directory.exists()) {
directory.mkpath(".");
qInfo() << "Created path to " << directory.path();
}
return directory;
}
QString pathForAssignmentScript(const QUuid& assignmentUUID) { QString pathForAssignmentScript(const QUuid& assignmentUUID) {
QString newPath { ServerPathUtils::getDataDirectory() + "/" + QString(ASSIGNMENT_SCRIPT_HOST_LOCATION) }; QDir directory = pathForAssignmentScriptsDirectory();
newPath += "/scripts/";
// append the UUID for this script as the new filename, remove the curly braces // append the UUID for this script as the new filename, remove the curly braces
newPath += uuidStringWithoutCurlyBraces(assignmentUUID); return directory.absoluteFilePath(uuidStringWithoutCurlyBraces(assignmentUUID));
return newPath;
} }
const QString URI_OAUTH = "/oauth"; const QString URI_OAUTH = "/oauth";
@ -1162,7 +1171,6 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
const QString JSON_MIME_TYPE = "application/json"; const QString JSON_MIME_TYPE = "application/json";
const QString URI_ASSIGNMENT = "/assignment"; const QString URI_ASSIGNMENT = "/assignment";
const QString URI_ASSIGNMENT_SCRIPTS = URI_ASSIGNMENT + "/scripts";
const QString URI_NODES = "/nodes"; const QString URI_NODES = "/nodes";
const QString URI_SETTINGS = "/settings"; const QString URI_SETTINGS = "/settings";
@ -1203,13 +1211,14 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
if (matchingAssignment && matchingAssignment->getType() == Assignment::AgentType) { if (matchingAssignment && matchingAssignment->getType() == Assignment::AgentType) {
// we have a matching assignment and it is for the right type, have the HTTP manager handle it // we have a matching assignment and it is for the right type, have the HTTP manager handle it
// via correct URL for the script so the client can download // via correct URL for the script so the client can download
QFile scriptFile(pathForAssignmentScript(matchingAssignment->getUUID()));
QUrl scriptURL = url;
scriptURL.setPath(URI_ASSIGNMENT + "/scripts/" if (scriptFile.exists() && scriptFile.open(QIODevice::ReadOnly)) {
+ uuidStringWithoutCurlyBraces(matchingAssignment->getUUID())); connection->respond(HTTPConnection::StatusCode200, scriptFile.readAll(), "application/javascript");
} else {
// have the HTTPManager serve the appropriate script file connection->respond(HTTPConnection::StatusCode404, "Resource not found.");
return _httpManager.handleHTTPRequest(connection, scriptURL, true); }
return true;
} }
// request not handled // request not handled

View file

@ -165,6 +165,7 @@ var STATE_EQUIP_SPRING = 16;
// "collidesWith" is specified by comma-separated list of group names // "collidesWith" is specified by comma-separated list of group names
// the possible group names are: static, dynamic, kinematic, myAvatar, otherAvatar // the possible group names are: static, dynamic, kinematic, myAvatar, otherAvatar
var COLLIDES_WITH_WHILE_GRABBED = "dynamic,otherAvatar"; var COLLIDES_WITH_WHILE_GRABBED = "dynamic,otherAvatar";
var COLLIDES_WITH_WHILE_MULTI_GRABBED = "dynamic";
function stateToName(state) { function stateToName(state) {
switch (state) { switch (state) {
@ -1636,6 +1637,13 @@ function MyController(hand) {
"collidesWith": COLLIDES_WITH_WHILE_GRABBED "collidesWith": COLLIDES_WITH_WHILE_GRABBED
}; };
Entities.editEntity(entityID, whileHeldProperties); Entities.editEntity(entityID, whileHeldProperties);
} else if (data["refCount"] > 1) {
// if an object is being grabbed by more than one person (or the same person twice, but nevermind), switch
// the collision groups so that it wont collide with "other" avatars. This avoids a situation where two
// people are holding something and one of them will be able (if the other releases at the right time) to
// bootstrap themselves with the held object. This happens because the meaning of "otherAvatar" in
// the collision mask hinges on who the physics simulation owner is.
Entities.editEntity(entityID, {"collidesWith": COLLIDES_WITH_WHILE_MULTI_GRABBED});
} }
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
@ -1746,4 +1754,4 @@ function cleanup() {
} }
Script.scriptEnding.connect(cleanup); Script.scriptEnding.connect(cleanup);
Script.update.connect(update); Script.update.connect(update);

View file

@ -246,7 +246,8 @@
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -261,7 +262,8 @@
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -275,7 +277,8 @@
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -289,7 +292,8 @@
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -303,7 +307,8 @@
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -317,7 +322,8 @@
{ "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -331,7 +337,8 @@
{ "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningLeft", "state": "turnLeft" }, { "var": "isTurningLeft", "state": "turnLeft" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -345,7 +352,8 @@
{ "var": "isMovingRight", "state": "strafeRight" }, { "var": "isMovingRight", "state": "strafeRight" },
{ "var": "isMovingLeft", "state": "strafeLeft" }, { "var": "isMovingLeft", "state": "strafeLeft" },
{ "var": "isTurningRight", "state": "turnRight" }, { "var": "isTurningRight", "state": "turnRight" },
{ "var": "isAway", "state": "awayIntro" } { "var": "isAway", "state": "awayIntro" },
{ "var": "isFlying", "state": "fly" }
] ]
}, },
{ {
@ -371,6 +379,14 @@
"transitions": [ "transitions": [
{ "var": "awayOutroOnDone", "state": "idle" } { "var": "awayOutroOnDone", "state": "idle" }
] ]
},
{
"id": "fly",
"interpTarget": 6,
"interpDuration": 6,
"transitions": [
{ "var": "isNotFlying", "state": "idle" }
]
} }
] ]
}, },
@ -657,6 +673,18 @@
"loopFlag": false "loopFlag": false
}, },
"children": [] "children": []
},
{
"id": "fly",
"type": "clip",
"data": {
"url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims/fly.fbx",
"startFrame": 1.0,
"endFrame": 80.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
} }
] ]
} }

View file

@ -99,6 +99,7 @@
#include <plugins/PluginContainer.h> #include <plugins/PluginContainer.h>
#include <plugins/PluginManager.h> #include <plugins/PluginManager.h>
#include <RenderableWebEntityItem.h> #include <RenderableWebEntityItem.h>
#include <RenderShadowTask.h>
#include <RenderDeferredTask.h> #include <RenderDeferredTask.h>
#include <ResourceCache.h> #include <ResourceCache.h>
#include <RenderScriptingInterface.h> #include <RenderScriptingInterface.h>
@ -673,7 +674,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
initializeGL(); initializeGL();
// Start rendering // Start rendering
_renderEngine->addTask(make_shared<RenderDeferredTask>(LODManager::shouldRender)); render::CullFunctor cullFunctor = LODManager::shouldRender;
_renderEngine->addTask(make_shared<RenderShadowTask>(cullFunctor));
_renderEngine->addTask(make_shared<RenderDeferredTask>(cullFunctor));
_renderEngine->registerScene(_main3DScene); _renderEngine->registerScene(_main3DScene);
_offscreenContext->makeCurrent(); _offscreenContext->makeCurrent();
@ -3760,9 +3763,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
renderContext.setArgs(renderArgs); renderContext.setArgs(renderArgs);
bool occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion); bool occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
bool shadowStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugShadows);
bool antialiasingStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing); bool antialiasingStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
bool showOwnedStatus = Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned); bool showOwnedStatus = Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned);
renderContext.setOptions(occlusionStatus, antialiasingStatus, showOwnedStatus); renderContext.setOptions(occlusionStatus, antialiasingStatus, showOwnedStatus, shadowStatus);
_renderEngine->setRenderContext(renderContext); _renderEngine->setRenderContext(renderContext);

View file

@ -325,6 +325,7 @@ Menu::Menu() {
MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render"); MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render");
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::WorldAxes); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::WorldAxes);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugAmbientOcclusion); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugAmbientOcclusion);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugShadows);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Antialiasing); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Antialiasing);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, 0, true); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, 0, true);

View file

@ -186,6 +186,7 @@ namespace MenuOption {
const QString CopyPath = "Copy Path to Clipboard"; const QString CopyPath = "Copy Path to Clipboard";
const QString CoupleEyelids = "Couple Eyelids"; const QString CoupleEyelids = "Couple Eyelids";
const QString CrashInterface = "Crash Interface"; const QString CrashInterface = "Crash Interface";
const QString DebugShadows = "Shadows";
const QString DebugAmbientOcclusion = "Ambient Occlusion"; const QString DebugAmbientOcclusion = "Ambient Occlusion";
const QString DecreaseAvatarSize = "Decrease Avatar Size"; const QString DecreaseAvatarSize = "Decrease Avatar Size";
const QString DeleteBookmark = "Delete Bookmark..."; const QString DeleteBookmark = "Delete Bookmark...";

View file

@ -1468,9 +1468,7 @@ void MyAvatar::updatePosition(float deltaTime) {
// rotate velocity into camera frame // rotate velocity into camera frame
glm::quat rotation = getHead()->getCameraOrientation(); glm::quat rotation = getHead()->getCameraOrientation();
glm::vec3 localVelocity = glm::inverse(rotation) * _targetVelocity; glm::vec3 localVelocity = glm::inverse(rotation) * _targetVelocity;
glm::vec3 newLocalVelocity = applyKeyboardMotor(deltaTime, localVelocity, isHovering());
bool isHovering = _characterController.isHovering();
glm::vec3 newLocalVelocity = applyKeyboardMotor(deltaTime, localVelocity, isHovering);
newLocalVelocity = applyScriptedMotor(deltaTime, newLocalVelocity); newLocalVelocity = applyScriptedMotor(deltaTime, newLocalVelocity);
// rotate back into world-frame // rotate back into world-frame
@ -1566,6 +1564,10 @@ void MyAvatar::doUpdateBillboard() {
sendBillboardPacket(); sendBillboardPacket();
} }
bool MyAvatar::isHovering() const {
return _characterController.isHovering();
}
void MyAvatar::increaseSize() { void MyAvatar::increaseSize() {
if ((1.0f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) { if ((1.0f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) {
_targetScale *= (1.0f + SCALING_RATIO); _targetScale *= (1.0f + SCALING_RATIO);

View file

@ -233,6 +233,8 @@ public:
glm::quat getCustomListenOrientation() { return _customListenOrientation; } glm::quat getCustomListenOrientation() { return _customListenOrientation; }
void setCustomListenOrientation(glm::quat customListenOrientation) { _customListenOrientation = customListenOrientation; } void setCustomListenOrientation(glm::quat customListenOrientation) { _customListenOrientation = customListenOrientation; }
bool isHovering() const;
public slots: public slots:
void increaseSize(); void increaseSize();
void decreaseSize(); void decreaseSize();

View file

@ -133,7 +133,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
_rig->updateFromHandParameters(handParams, deltaTime); _rig->updateFromHandParameters(handParams, deltaTime);
_rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation()); _rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation(), myAvatar->isHovering());
// evaluate AnimGraph animation and update jointStates. // evaluate AnimGraph animation and update jointStates.
Model::updateRig(deltaTime, parentTransform); Model::updateRig(deltaTime, parentTransform);

View file

@ -500,7 +500,7 @@ 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> BACKWARD_SPEEDS = { 0.6f, 1.45f }; // m/s
static const std::vector<float> LATERAL_SPEEDS = { 0.2f, 0.65f }; // 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) { void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation, bool isHovering) {
glm::vec3 front = worldRotation * IDENTITY_FRONT; glm::vec3 front = worldRotation * IDENTITY_FRONT;
@ -568,36 +568,43 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
const float TURN_ENTER_SPEED_THRESHOLD = 0.5f; // rad/sec const float TURN_ENTER_SPEED_THRESHOLD = 0.5f; // rad/sec
const float TURN_EXIT_SPEED_THRESHOLD = 0.2f; // rad/sec const float TURN_EXIT_SPEED_THRESHOLD = 0.2f; // rad/sec
float moveThresh; if (isHovering) {
if (_state != RigRole::Move) { if (_desiredState != RigRole::Hover) {
moveThresh = MOVE_ENTER_SPEED_THRESHOLD;
} else {
moveThresh = MOVE_EXIT_SPEED_THRESHOLD;
}
float turnThresh;
if (_state != RigRole::Turn) {
turnThresh = TURN_ENTER_SPEED_THRESHOLD;
} else {
turnThresh = TURN_EXIT_SPEED_THRESHOLD;
}
if (glm::length(localVel) > moveThresh) {
if (_desiredState != RigRole::Move) {
_desiredStateAge = 0.0f; _desiredStateAge = 0.0f;
} }
_desiredState = RigRole::Move; _desiredState = RigRole::Hover;
} else { } else {
if (fabsf(turningSpeed) > turnThresh) { float moveThresh;
if (_desiredState != RigRole::Turn) { if (_state != RigRole::Move) {
moveThresh = MOVE_ENTER_SPEED_THRESHOLD;
} else {
moveThresh = MOVE_EXIT_SPEED_THRESHOLD;
}
float turnThresh;
if (_state != RigRole::Turn) {
turnThresh = TURN_ENTER_SPEED_THRESHOLD;
} else {
turnThresh = TURN_EXIT_SPEED_THRESHOLD;
}
if (glm::length(localVel) > moveThresh) {
if (_desiredState != RigRole::Move) {
_desiredStateAge = 0.0f; _desiredStateAge = 0.0f;
} }
_desiredState = RigRole::Turn; _desiredState = RigRole::Move;
} else { // idle } else {
if (_desiredState != RigRole::Idle) { if (fabsf(turningSpeed) > turnThresh) {
_desiredStateAge = 0.0f; if (_desiredState != RigRole::Turn) {
_desiredStateAge = 0.0f;
}
_desiredState = RigRole::Turn;
} else { // idle
if (_desiredState != RigRole::Idle) {
_desiredStateAge = 0.0f;
}
_desiredState = RigRole::Idle;
} }
_desiredState = RigRole::Idle;
} }
} }
@ -649,6 +656,8 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isTurningLeft", false); _animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false); _animVars.set("isTurningRight", false);
_animVars.set("isNotTurning", true); _animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
} }
} else if (_state == RigRole::Turn) { } else if (_state == RigRole::Turn) {
if (turningSpeed > 0.0f) { if (turningSpeed > 0.0f) {
@ -667,7 +676,9 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isMovingRight", false); _animVars.set("isMovingRight", false);
_animVars.set("isMovingLeft", false); _animVars.set("isMovingLeft", false);
_animVars.set("isNotMoving", true); _animVars.set("isNotMoving", true);
} else { _animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
} else if (_state == RigRole::Idle ) {
// default anim vars to notMoving and notTurning // default anim vars to notMoving and notTurning
_animVars.set("isMovingForward", false); _animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false); _animVars.set("isMovingBackward", false);
@ -677,6 +688,20 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
_animVars.set("isTurningLeft", false); _animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false); _animVars.set("isTurningRight", false);
_animVars.set("isNotTurning", true); _animVars.set("isNotTurning", true);
_animVars.set("isFlying", false);
_animVars.set("isNotFlying", true);
} else {
// flying.
_animVars.set("isMovingForward", false);
_animVars.set("isMovingBackward", false);
_animVars.set("isMovingLeft", false);
_animVars.set("isMovingRight", false);
_animVars.set("isNotMoving", true);
_animVars.set("isTurningLeft", false);
_animVars.set("isTurningRight", false);
_animVars.set("isNotTurning", true);
_animVars.set("isFlying", true);
_animVars.set("isNotFlying", false);
} }
t += deltaTime; t += deltaTime;

View file

@ -141,7 +141,7 @@ public:
glm::mat4 getJointTransform(int jointIndex) const; glm::mat4 getJointTransform(int jointIndex) const;
// Start or stop animations as needed. // Start or stop animations as needed.
void computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation); void computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation, bool isHovering);
// Regardless of who started the animations or how many, update the joints. // Regardless of who started the animations or how many, update the joints.
void updateAnimations(float deltaTime, glm::mat4 rootTransform); void updateAnimations(float deltaTime, glm::mat4 rootTransform);
@ -268,7 +268,8 @@ public:
enum class RigRole { enum class RigRole {
Idle = 0, Idle = 0,
Turn, Turn,
Move Move,
Hover
}; };
RigRole _state { RigRole::Idle }; RigRole _state { RigRole::Idle };
RigRole _desiredState { RigRole::Idle }; RigRole _desiredState { RigRole::Idle };

View file

@ -63,10 +63,6 @@ Framebuffer* Framebuffer::createShadowmap(uint16 width) {
depthTexture->setSampler(Sampler(samplerDesc)); depthTexture->setSampler(Sampler(samplerDesc));
framebuffer->setDepthStencilBuffer(depthTexture, depthFormat); framebuffer->setDepthStencilBuffer(depthTexture, depthFormat);
// Use a render buffer to allow use of the DebugDeferredBuffer Job
gpu::TexturePointer colorbuffer{gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, width)};
framebuffer->setRenderBuffer(0, colorbuffer);
return framebuffer; return framebuffer;
} }

View file

@ -70,12 +70,16 @@ static const std::string DEFAULT_LIGHTING_SHADER {
" return vec4(pow(texture(lightingMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);" " return vec4(pow(texture(lightingMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);"
" }" " }"
}; };
static const std::string DEFAULT_SHADOW_SHADER {
static const std::string DEFAULT_SHADOW_SHADER{ "uniform sampler2DShadow shadowMap;"
"uniform sampler2D shadowMapColor;"
// The actual shadowMap is a sampler2DShadow, so we cannot normally sample it
"vec4 getFragmentColor() {" "vec4 getFragmentColor() {"
" return vec4(texture(shadowMapColor, uv).xyz, 1.0);" " for (int i = 255; i >= 0; --i) {"
" float depth = i / 255.0;"
" if (texture(shadowMap, vec3(uv, depth)) > 0.5) {"
" return vec4(vec3(depth), 1.0);"
" }"
" }"
" return vec4(vec3(0.0), 1.0);"
" }" " }"
}; };
@ -194,7 +198,7 @@ const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Modes mode, std::st
slotBindings.insert(gpu::Shader::Binding("specularMap", Specular)); slotBindings.insert(gpu::Shader::Binding("specularMap", Specular));
slotBindings.insert(gpu::Shader::Binding("depthMap", Depth)); slotBindings.insert(gpu::Shader::Binding("depthMap", Depth));
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting)); slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
slotBindings.insert(gpu::Shader::Binding("shadowMapColor", Shadow)); slotBindings.insert(gpu::Shader::Binding("shadowMap", Shadow));
slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid)); slotBindings.insert(gpu::Shader::Binding("pyramidMap", Pyramid));
slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion)); slotBindings.insert(gpu::Shader::Binding("occlusionMap", AmbientOcclusion));
slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred)); slotBindings.insert(gpu::Shader::Binding("occlusionBlurredMap", AmbientOcclusionBlurred));
@ -253,7 +257,7 @@ void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const Ren
batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture()); batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture());
batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture()); batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture());
batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture()); batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture());
batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getRenderBuffer(0)); batch.setResourceTexture(Shadow, lightStage.lights[0]->shadow.framebuffer->getDepthStencilBuffer());
batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture()); batch.setResourceTexture(Pyramid, framebufferCache->getDepthPyramidTexture());
batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture()); batch.setResourceTexture(AmbientOcclusion, framebufferCache->getOcclusionTexture());
batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture()); batch.setResourceTexture(AmbientOcclusionBlurred, framebufferCache->getOcclusionBlurredTexture());

View file

@ -64,14 +64,21 @@ void DeferredLightingEffect::init() {
_directionalAmbientSphereLightLocations = std::make_shared<LightLocations>(); _directionalAmbientSphereLightLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightLocations = std::make_shared<LightLocations>(); _directionalSkyboxLightLocations = std::make_shared<LightLocations>();
_directionalLightShadowLocations = std::make_shared<LightLocations>();
_directionalAmbientSphereLightShadowLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightShadowLocations = std::make_shared<LightLocations>();
_pointLightLocations = std::make_shared<LightLocations>(); _pointLightLocations = std::make_shared<LightLocations>();
_spotLightLocations = std::make_shared<LightLocations>(); _spotLightLocations = std::make_shared<LightLocations>();
// TODO: To use shadowmaps, replace directional_*_light_frag with directional_*_light_shadow_frag shaders.
loadLightProgram(deferred_light_vert, directional_light_frag, false, _directionalLight, _directionalLightLocations); loadLightProgram(deferred_light_vert, directional_light_frag, false, _directionalLight, _directionalLightLocations);
loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations); loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations);
loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations); loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations);
loadLightProgram(deferred_light_vert, directional_light_shadow_frag, false, _directionalLightShadow, _directionalLightShadowLocations);
loadLightProgram(deferred_light_vert, directional_ambient_light_shadow_frag, false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations);
loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_frag, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations);
loadLightProgram(deferred_light_limited_vert, point_light_frag, true, _pointLight, _pointLightLocations); loadLightProgram(deferred_light_limited_vert, point_light_frag, true, _pointLight, _pointLightLocations);
loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations); loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations);
@ -306,18 +313,27 @@ void DeferredLightingEffect::render(const render::RenderContextPointer& renderCo
{ {
bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap());
auto& program = _directionalLight; auto& program = _shadowMapStatus ? _directionalLightShadow : _directionalLight;
LightLocationsPtr locations = _directionalLightLocations; LightLocationsPtr locations = _shadowMapStatus ? _directionalLightShadowLocations : _directionalLightLocations;
// TODO: At some point bring back the shadows...
// Setup the global directional pass pipeline // Setup the global directional pass pipeline
{ {
if (useSkyboxCubemap) { if (_shadowMapStatus) {
program = _directionalSkyboxLight; if (useSkyboxCubemap) {
locations = _directionalSkyboxLightLocations; program = _directionalSkyboxLightShadow;
} else if (_ambientLightMode > -1) { locations = _directionalSkyboxLightShadowLocations;
program = _directionalAmbientSphereLight; } else if (_ambientLightMode > -1) {
locations = _directionalAmbientSphereLightLocations; program = _directionalAmbientSphereLightShadow;
locations = _directionalAmbientSphereLightShadowLocations;
}
} else {
if (useSkyboxCubemap) {
program = _directionalSkyboxLight;
locations = _directionalSkyboxLightLocations;
} else if (_ambientLightMode > -1) {
program = _directionalAmbientSphereLight;
locations = _directionalAmbientSphereLightLocations;
}
} }
if (locations->shadowTransformBuffer >= 0) { if (locations->shadowTransformBuffer >= 0) {

View file

@ -54,27 +54,37 @@ public:
void setGlobalSkybox(const model::SkyboxPointer& skybox); void setGlobalSkybox(const model::SkyboxPointer& skybox);
const LightStage& getLightStage() { return _lightStage; } const LightStage& getLightStage() { return _lightStage; }
void setShadowMapStatus(bool enable) { _shadowMapStatus = enable; };
private: private:
LightStage _lightStage; LightStage _lightStage;
bool _shadowMapStatus{ false };
DeferredLightingEffect() = default; DeferredLightingEffect() = default;
model::MeshPointer _spotLightMesh; model::MeshPointer _spotLightMesh;
model::MeshPointer getSpotLightMesh(); model::MeshPointer getSpotLightMesh();
gpu::PipelinePointer _directionalSkyboxLight; gpu::PipelinePointer _directionalSkyboxLight;
LightLocationsPtr _directionalSkyboxLightLocations;
gpu::PipelinePointer _directionalAmbientSphereLight; gpu::PipelinePointer _directionalAmbientSphereLight;
LightLocationsPtr _directionalAmbientSphereLightLocations;
gpu::PipelinePointer _directionalLight; gpu::PipelinePointer _directionalLight;
LightLocationsPtr _directionalLightLocations;
gpu::PipelinePointer _directionalSkyboxLightShadow;
gpu::PipelinePointer _directionalAmbientSphereLightShadow;
gpu::PipelinePointer _directionalLightShadow;
gpu::PipelinePointer _pointLight; gpu::PipelinePointer _pointLight;
LightLocationsPtr _pointLightLocations;
gpu::PipelinePointer _spotLight; gpu::PipelinePointer _spotLight;
LightLocationsPtr _directionalSkyboxLightLocations;
LightLocationsPtr _directionalAmbientSphereLightLocations;
LightLocationsPtr _directionalLightLocations;
LightLocationsPtr _directionalSkyboxLightShadowLocations;
LightLocationsPtr _directionalAmbientSphereLightShadowLocations;
LightLocationsPtr _directionalLightShadowLocations;
LightLocationsPtr _pointLightLocations;
LightLocationsPtr _spotLightLocations; LightLocationsPtr _spotLightLocations;
using Lights = std::vector<model::LightPointer>; using Lights = std::vector<model::LightPointer>;

View file

@ -27,7 +27,9 @@ void LightStage::Shadow::setKeylightFrustum(ViewFrustum* viewFrustum, float near
const auto& direction = glm::normalize(_light->getDirection()); const auto& direction = glm::normalize(_light->getDirection());
glm::quat orientation; glm::quat orientation;
if (direction == IDENTITY_UP) { if (direction == IDENTITY_UP) {
orientation = glm::quat(glm::mat3(IDENTITY_RIGHT, IDENTITY_UP, IDENTITY_FRONT)); orientation = glm::quat(glm::mat3(-IDENTITY_RIGHT, IDENTITY_FRONT, -IDENTITY_UP));
} else if (direction == -IDENTITY_UP) {
orientation = glm::quat(glm::mat3(IDENTITY_RIGHT, IDENTITY_FRONT, IDENTITY_UP));
} else { } else {
auto side = glm::normalize(glm::cross(direction, IDENTITY_UP)); auto side = glm::normalize(glm::cross(direction, IDENTITY_UP));
auto up = glm::normalize(glm::cross(side, direction)); auto up = glm::normalize(glm::cross(side, direction));
@ -70,6 +72,9 @@ void LightStage::Shadow::setKeylightFrustum(ViewFrustum* viewFrustum, float near
glm::mat4 ortho = glm::ortho<float>(min.x, max.x, min.y, max.y, -max.z, -min.z); glm::mat4 ortho = glm::ortho<float>(min.x, max.x, min.y, max.y, -max.z, -min.z);
_frustum->setProjection(ortho); _frustum->setProjection(ortho);
// Calculate the frustum's internal state
_frustum->calculate();
// Update the buffer // Update the buffer
_schemaBuffer.edit<Schema>().projection = ortho; _schemaBuffer.edit<Schema>().projection = ortho;
_schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix(); _schemaBuffer.edit<Schema>().viewInverse = viewInverse.getMatrix();

View file

@ -215,7 +215,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
} }
} }
void MeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations) const { void MeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool canCauterize) const {
batch.setModelTransform(_drawTransform); batch.setModelTransform(_drawTransform);
} }
@ -442,25 +442,25 @@ void ModelMeshPartPayload::bindMesh(gpu::Batch& batch) const {
} }
} }
void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations) const { void ModelMeshPartPayload::bindTransform(gpu::Batch& batch, const ShapePipeline::LocationsPointer locations, bool canCauterize) const {
// Still relying on the raw data from the model // Still relying on the raw data from the model
const Model::MeshState& state = _model->_meshStates.at(_meshIndex); const Model::MeshState& state = _model->_meshStates.at(_meshIndex);
Transform transform; Transform transform;
if (state.clusterBuffer) { if (state.clusterBuffer) {
if (_model->_cauterizeBones) { if (canCauterize && _model->getCauterizeBones()) {
batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_GPU, state.cauterizedClusterBuffer); batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_GPU, state.cauterizedClusterBuffer);
} else { } else {
batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_GPU, state.clusterBuffer); batch.setUniformBuffer(ShapePipeline::Slot::SKINNING_GPU, state.clusterBuffer);
} }
} else { } else {
if (_model->_cauterizeBones) { if (canCauterize && _model->getCauterizeBones()) {
transform = Transform(state.cauterizedClusterMatrices[0]); transform = Transform(state.cauterizedClusterMatrices[0]);
} else { } else {
transform = Transform(state.clusterMatrices[0]); transform = Transform(state.clusterMatrices[0]);
} }
} }
// transform.preTranslate(_modelPosition);
transform.preTranslate(_transform.getTranslation()); transform.preTranslate(_transform.getTranslation());
batch.setModelTransform(transform); batch.setModelTransform(transform);
} }
@ -507,8 +507,9 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
assert(locations); assert(locations);
// Bind the model transform and the skinCLusterMatrices if needed // Bind the model transform and the skinCLusterMatrices if needed
bool canCauterize = args->_renderMode != RenderArgs::SHADOW_RENDER_MODE;
_model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation()); _model->updateClusterMatrices(_transform.getTranslation(), _transform.getRotation());
bindTransform(batch, locations); bindTransform(batch, locations, canCauterize);
//Bind the index buffer and vertex buffer and Blend shapes if needed //Bind the index buffer and vertex buffer and Blend shapes if needed
bindMesh(batch); bindMesh(batch);

View file

@ -46,7 +46,7 @@ public:
void drawCall(gpu::Batch& batch) const; void drawCall(gpu::Batch& batch) const;
virtual void bindMesh(gpu::Batch& batch) const; virtual void bindMesh(gpu::Batch& batch) const;
virtual void bindMaterial(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations) const; virtual void bindMaterial(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations) const;
virtual void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations) const; virtual void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, bool canCauterize = true) const;
// Payload resource cached values // Payload resource cached values
model::MeshPointer _drawMesh; model::MeshPointer _drawMesh;
@ -88,15 +88,17 @@ public:
// ModelMeshPartPayload functions to perform render // ModelMeshPartPayload functions to perform render
void bindMesh(gpu::Batch& batch) const override; void bindMesh(gpu::Batch& batch) const override;
void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations) const override; void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, bool canCauterize) const override;
void initCache(); void initCache();
Model* _model; Model* _model;
int _meshIndex; int _meshIndex;
int _shapeID; int _shapeID;
bool _isSkinned = false;
bool _isBlendShaped = false; bool _isSkinned{ false };
bool _isBlendShaped{ false };
}; };
#endif // hifi_MeshPartPayload_h #endif // hifi_MeshPartPayload_h

View file

@ -191,6 +191,9 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
setToneMappingToneCurve(renderContext->getTone().toneCurve); setToneMappingToneCurve(renderContext->getTone().toneCurve);
// TODO: Allow runtime manipulation of culling ShouldRenderFunctor // TODO: Allow runtime manipulation of culling ShouldRenderFunctor
// TODO: For now, lighting is controlled through a singleton, so it is distinct
DependencyManager::get<DeferredLightingEffect>()->setShadowMapStatus(renderContext->getShadowMapStatus());
renderContext->getArgs()->_context->syncCache(); renderContext->getArgs()->_context->syncCache();
for (auto job : _jobs) { for (auto job : _jobs) {

View file

@ -124,15 +124,12 @@ public:
void setDrawHitEffect(bool draw) { enableJob(_drawHitEffectJobIndex, draw); } void setDrawHitEffect(bool draw) { enableJob(_drawHitEffectJobIndex, draw); }
bool doDrawHitEffect() const { return getEnableJob(_drawHitEffectJobIndex); } bool doDrawHitEffect() const { return getEnableJob(_drawHitEffectJobIndex); }
void setOcclusionStatus(bool draw) { enableJob(_occlusionJobIndex, draw); } void setOcclusionStatus(bool draw) { enableJob(_occlusionJobIndex, draw); }
bool doOcclusionStatus() const { return getEnableJob(_occlusionJobIndex); } bool doOcclusionStatus() const { return getEnableJob(_occlusionJobIndex); }
void setAntialiasingStatus(bool draw) { enableJob(_antialiasingJobIndex, draw); } void setAntialiasingStatus(bool draw) { enableJob(_antialiasingJobIndex, draw); }
bool doAntialiasingStatus() const { return getEnableJob(_antialiasingJobIndex); } bool doAntialiasingStatus() const { return getEnableJob(_antialiasingJobIndex); }
void setToneMappingExposure(float exposure); void setToneMappingExposure(float exposure);
float getToneMappingExposure() const; float getToneMappingExposure() const;

View file

@ -123,6 +123,11 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
assert(sceneContext); assert(sceneContext);
RenderArgs* args = renderContext->getArgs(); RenderArgs* args = renderContext->getArgs();
// This feature is in a debugging stage - it must be turned on explicitly
if (!renderContext->getShadowMapStatus()) {
return;
}
// sanity checks // sanity checks
if (!sceneContext->_scene || !args) { if (!sceneContext->_scene || !args) {
return; return;
@ -136,21 +141,26 @@ void RenderShadowTask::run(const SceneContextPointer& sceneContext, const render
return; return;
} }
// Cache old render args
ViewFrustum* viewFrustum = args->_viewFrustum; ViewFrustum* viewFrustum = args->_viewFrustum;
RenderArgs::RenderMode mode = args->_renderMode;
auto nearClip = viewFrustum->getNearClip(); auto nearClip = viewFrustum->getNearClip();
const int SHADOW_NEAR_DEPTH = -2; const int SHADOW_NEAR_DEPTH = -2;
const int SHADOW_FAR_DEPTH = 20; const int SHADOW_FAR_DEPTH = 20;
globalLight->shadow.setKeylightFrustum(viewFrustum, nearClip + SHADOW_NEAR_DEPTH, nearClip + SHADOW_FAR_DEPTH); globalLight->shadow.setKeylightFrustum(viewFrustum, nearClip + SHADOW_NEAR_DEPTH, nearClip + SHADOW_FAR_DEPTH);
// Set the keylight frustum // Set the keylight render args
args->_viewFrustum = globalLight->shadow.getFrustum().get(); args->_viewFrustum = globalLight->shadow.getFrustum().get();
args->_renderMode = RenderArgs::SHADOW_RENDER_MODE;
// TODO: Allow runtime manipulation of culling ShouldRenderFunctor // TODO: Allow runtime manipulation of culling ShouldRenderFunctor
for (auto job : _jobs) { for (auto job : _jobs) {
job.run(sceneContext, renderContext); job.run(sceneContext, renderContext);
} }
// Reset the view frustum // Reset the render args
args->_viewFrustum = viewFrustum; args->_viewFrustum = viewFrustum;
args->_renderMode = mode;
}; };

View file

@ -60,44 +60,39 @@ float fetchShadow(vec3 shadowTexcoord) {
return texture(shadowMap, shadowTexcoord); return texture(shadowMap, shadowTexcoord);
} }
vec2 samples[8] = vec2[8]( vec2 PCFkernel[4] = vec2[4](
vec2(-2.0, -2.0), vec2(-1.5, 0.5),
vec2(2.0, -2.0), vec2(0.5, 0.5),
vec2(2.0, 2.0), vec2(-1.5, -1.5),
vec2(-2.0, 2.0), vec2(0.5, -1.5)
vec2(1.0, 0.0),
vec2(0.0, 1.0),
vec2(-1.0, 0.0),
vec2(0.0, -1.0)
); );
float evalShadowAttenuationSampling(vec4 shadowTexcoord) { float evalShadowAttenuationPCF(vec4 position, vec4 shadowTexcoord) {
float pcfRadius = 3.0;
float shadowScale = getShadowScale(); float shadowScale = getShadowScale();
float shadowAttenuation = (0.25 * ( // Offset for efficient PCF, see http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[0], 0.0)) + vec2 offset = pcfRadius * step(fract(position.xy), vec2(0.5, 0.5));
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[1], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[2], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[3], 0.0))
));
// Check for early bailing float shadowAttenuation = (0.25 * (
if ((shadowAttenuation > 0) && (shadowAttenuation < 1.0)) { fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[0], 0.0)) +
shadowAttenuation = 0.5 * shadowAttenuation + (0.125 * ( fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[1], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[4], 0.0)) + fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[2], 0.0)) +
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[5], 0.0)) + fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[3], 0.0))
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[6], 0.0)) + ));
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(samples[7], 0.0))
));
}
return shadowAttenuation; return shadowAttenuation;
} }
float evalShadowAttenuation(vec4 position) { float evalShadowAttenuation(vec4 position) {
vec4 shadowTexcoord = evalShadowTexcoord(position); vec4 shadowTexcoord = evalShadowTexcoord(position);
if (shadowTexcoord.x < 0.0 || shadowTexcoord.x > 1.0 ||
shadowTexcoord.y < 0.0 || shadowTexcoord.y > 1.0) {
// If a point is not in the map, do not attenuate
return 1.0;
}
return evalShadowAttenuationSampling(shadowTexcoord); return evalShadowAttenuationPCF(position, shadowTexcoord);
} }
<@endif@> <@endif@>

View file

@ -15,6 +15,6 @@
layout(location = 0) out vec4 _fragColor; layout(location = 0) out vec4 _fragColor;
void main(void) { void main(void) {
// stencil in solid color for debugging // pass-through to set z-buffer
_fragColor = vec4(0.0, 0.0, 1.0, 1.0); _fragColor = vec4(1.0, 1.0, 1.0, 0.0);
} }

View file

@ -15,6 +15,6 @@
layout(location = 0) out vec4 _fragColor; layout(location = 0) out vec4 _fragColor;
void main(void) { void main(void) {
// stencil in solid color for debugging // pass-through to set z-buffer
_fragColor = vec4(1.0, 0.0, 0.0, 1.0); _fragColor = vec4(1.0, 1.0, 1.0, 0.0);
} }

View file

@ -19,9 +19,10 @@ RenderContext::RenderContext(ItemsConfig items, Tone tone, AmbientOcclusion ao,
_drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect }, _drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect },
_items{ items }, _tone{ tone }, _ambientOcclusion{ ao } {} _items{ items }, _tone{ tone }, _ambientOcclusion{ ao } {}
void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) { void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned, bool shadowMap) {
_occlusionStatus = occlusion; _occlusionStatus = occlusion;
_fxaaStatus = fxaa; _fxaaStatus = fxaa;
_shadowMapStatus = shadowMap;
if (showOwned) { if (showOwned) {
_drawStatus |= render::showNetworkStatusFlag; _drawStatus |= render::showNetworkStatusFlag;

View file

@ -100,7 +100,8 @@ public:
bool getDrawHitEffect() { return _drawHitEffect; } bool getDrawHitEffect() { return _drawHitEffect; }
bool getOcclusionStatus() { return _occlusionStatus; } bool getOcclusionStatus() { return _occlusionStatus; }
bool getFxaaStatus() { return _fxaaStatus; } bool getFxaaStatus() { return _fxaaStatus; }
void setOptions(bool occlusion, bool fxaa, bool showOwned); bool getShadowMapStatus() { return _shadowMapStatus; }
void setOptions(bool occlusion, bool fxaa, bool showOwned, bool shadowMap);
// Debugging // Debugging
int _deferredDebugMode; int _deferredDebugMode;
@ -114,6 +115,7 @@ protected:
bool _drawHitEffect; bool _drawHitEffect;
bool _occlusionStatus { false }; bool _occlusionStatus { false };
bool _fxaaStatus { false }; bool _fxaaStatus { false };
bool _shadowMapStatus { false };
ItemsConfig _items; ItemsConfig _items;
Tone _tone; Tone _tone;

View file

@ -236,6 +236,9 @@ void PipelineSortShapes::run(const SceneContextPointer& sceneContext, const Rend
} }
void DepthSortShapes::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapesIDsBounds& inShapes, ShapesIDsBounds& outShapes) { void DepthSortShapes::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ShapesIDsBounds& inShapes, ShapesIDsBounds& outShapes) {
outShapes.clear();
outShapes.reserve(inShapes.size());
for (auto& pipeline : inShapes) { for (auto& pipeline : inShapes) {
auto& inItems = pipeline.second; auto& inItems = pipeline.second;
auto outItems = outShapes.find(pipeline.first); auto outItems = outShapes.find(pipeline.first);

View file

@ -82,7 +82,6 @@ ul.tabs li.current {
} }
.search { .search {
display: none;
float: right; float: right;
margin: 10px; margin: 10px;
} }

View file

@ -23,9 +23,10 @@ exports.searchPaths = function(name, binaryType, releaseType) {
if (!releaseType) { if (!releaseType) {
// check in the developer build tree for binaries // check in the developer build tree for binaries
var typeSpecificPath = (binaryType == "local-release" ? "Release/" : "Debug/")
paths = [ paths = [
devBasePath + name + extension, devBasePath + name + extension,
devBasePath + (binaryType == "local-release" ? "Release/" : "Debug/") + name + extension devBasePath + typeSpecificPath + name + extension
] ]
} else { } else {
// check directly beside the binary // check directly beside the binary
@ -33,6 +34,11 @@ exports.searchPaths = function(name, binaryType, releaseType) {
path.join(path.dirname(process.execPath), name + extension) path.join(path.dirname(process.execPath), name + extension)
]; ];
if (process.platform == "win32") {
// check a level back in case we're packaged on windows
paths.push(path.resolve(path.dirname(process.execPath), '../' + name + extension))
}
// assume we're inside an app bundle on OS X // assume we're inside an app bundle on OS X
if (process.platform == "darwin") { if (process.platform == "darwin") {
var contentPath = ".app/Contents/"; var contentPath = ".app/Contents/";