mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 08:43:40 +02:00
Merge remote-tracking branch 'upstream/master' into offscreen
Conflicts: interface/src/Menu.cpp
This commit is contained in:
commit
7a33474245
50 changed files with 1033 additions and 936 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -4,6 +4,7 @@ CMakeFiles/
|
|||
CMakeScripts/
|
||||
cmake_install.cmake
|
||||
build*/
|
||||
ext/
|
||||
Makefile
|
||||
*.user
|
||||
|
||||
|
@ -32,10 +33,6 @@ DerivedData
|
|||
interface/external/*/*
|
||||
!interface/external/*/readme.txt
|
||||
|
||||
# ignore interface optional resources
|
||||
interface/resources/visage/*
|
||||
!interface/resources/visage/tracker.cfg
|
||||
|
||||
# Ignore interfaceCache for Linux users
|
||||
interface/interfaceCache/
|
||||
|
||||
|
|
4
BUILD.md
4
BUILD.md
|
@ -19,9 +19,9 @@ The following external projects are optional dependencies. You can indicate to C
|
|||
* [SDL2](https://www.libsdl.org/download-2.0.php) ~> 2.0.3
|
||||
* Enables game controller support in Interface
|
||||
|
||||
The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build-ext` directory in each of the subfolders for each external project.
|
||||
The above dependencies will be downloaded, built, linked and included automatically by CMake where we require them. The CMakeLists files that handle grabbing each of the following external dependencies can be found in the [cmake/externals folder](cmake/externals). The resulting downloads, source files and binaries will be placed in the `build/ext` folder in each of the subfolders for each external project.
|
||||
|
||||
These are not placed in your normal build tree when doing an out of source build so that they do not need to be re-downloaded and re-compiled every time the CMake build folder is cleared. Should you want to force a re-download and re-compile of a specific external, you can simply remove that directory from the appropriate subfolder in `build-ext`. Should you want to force a re-download and re-compile of all externals, just remove the `build-ext` folder.
|
||||
These are not placed in your normal build tree when doing an out of source build so that they do not need to be re-downloaded and re-compiled every time the CMake build folder is cleared. Should you want to force a re-download and re-compile of a specific external, you can simply remove that directory from the appropriate subfolder in `build/ext`. Should you want to force a re-download and re-compile of all externals, just remove the `build/ext` folder.
|
||||
|
||||
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 -DGET_$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.
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ option(GET_SOXR "Get Soxr library automatically as external project" 1)
|
|||
option(GET_TBB "Get Threading Building Blocks library automatically as external project" 1)
|
||||
option(GET_LIBOVR "Get LibOVR library automatically as external project" 1)
|
||||
option(USE_NSIGHT "Attempt to find the nSight libraries" 1)
|
||||
option(GET_VHACD "Get V-HACD library automatically as external project" 1)
|
||||
|
||||
if (WIN32)
|
||||
option(GET_GLEW "Get GLEW library automatically as external project" 1)
|
||||
|
|
31
cmake/externals/vhacd/CMakeLists.txt
vendored
Normal file
31
cmake/externals/vhacd/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
set(EXTERNAL_NAME vhacd)
|
||||
|
||||
if (ANDROID)
|
||||
set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19")
|
||||
endif ()
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://hifi-public.s3.amazonaws.com/dependencies/v-hacd-master.zip
|
||||
URL_MD5 3bfc94f8dd3dfbfe8f4dc088f4820b3e
|
||||
CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
BINARY_DIR ${EXTERNAL_PROJECT_PREFIX}/build
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
if (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/Debug/VHACD_LIB.lib CACHE FILEPATH "Path to V-HACD debug library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/Release/VHACD_LIB.lib CACHE FILEPATH "Path to V-HACD release library")
|
||||
else ()
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "Path to V-HACD debug library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libVHACD.a CACHE FILEPATH "Path to V-HACD release library")
|
||||
endif ()
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to V-HACD include directory")
|
|
@ -22,11 +22,11 @@ macro(SETUP_EXTERNALS_BINARY_DIR)
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
set(EXTERNALS_BINARY_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/build-ext")
|
||||
set(EXTERNALS_BINARY_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/ext")
|
||||
if (ANDROID)
|
||||
set(EXTERNALS_BINARY_DIR "${EXTERNALS_BINARY_ROOT_DIR}/android/${CMAKE_GENERATOR_FOLDER_NAME}")
|
||||
else ()
|
||||
set(EXTERNALS_BINARY_DIR "${EXTERNALS_BINARY_ROOT_DIR}/${CMAKE_GENERATOR_FOLDER_NAME}")
|
||||
endif ()
|
||||
|
||||
endmacro()
|
||||
endmacro()
|
||||
|
|
|
@ -19,40 +19,16 @@
|
|||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("vhacd")
|
||||
|
||||
macro(_FIND_VHACD_LIBRARY _var)
|
||||
set(_${_var}_NAMES ${ARGN})
|
||||
find_library(${_var}_LIBRARY_RELEASE
|
||||
NAMES ${_${_var}_NAMES}
|
||||
HINTS
|
||||
${VHACD_SEARCH_DIRS}
|
||||
$ENV{VHACD_ROOT_DIR}
|
||||
PATH_SUFFIXES lib lib/Release
|
||||
)
|
||||
|
||||
find_library(${_var}_LIBRARY_DEBUG
|
||||
NAMES ${_${_var}_NAMES}
|
||||
HINTS
|
||||
${VHACD_SEARCH_DIRS}
|
||||
$ENV{VHACD_ROOT_DIR}
|
||||
PATH_SUFFIXES lib lib/Debug
|
||||
)
|
||||
|
||||
select_library_configurations(${_var})
|
||||
|
||||
mark_as_advanced(${_var}_LIBRARY)
|
||||
mark_as_advanced(${_var}_LIBRARY)
|
||||
endmacro()
|
||||
|
||||
find_path(VHACD_INCLUDE_DIRS VHACD.h PATH_SUFFIXES include HINTS ${VHACD_SEARCH_DIRS})
|
||||
|
||||
find_path(VHACD_INCLUDE_DIRS VHACD.h PATH_SUFFIXES include HINTS ${VHACD_SEARCH_DIRS} $ENV{VHACD_ROOT_DIR})
|
||||
if(NOT WIN32)
|
||||
_FIND_VHACD_LIBRARY(VHACD libVHACD.a)
|
||||
else()
|
||||
_FIND_VHACD_LIBRARY(VHACD VHACD_LIB)
|
||||
endif()
|
||||
find_library(VHACD_LIBRARY_DEBUG NAMES VHACD VHACD_LIB PATH_SUFFIXES lib/Debug HINTS ${VHACD_SEARCH_DIRS})
|
||||
find_library(VHACD_LIBRARY_RELEASE NAMES VHACD VHACD_LIB PATH_SUFFIXES lib/Release lib HINTS ${VHACD_SEARCH_DIRS})
|
||||
|
||||
include(SelectLibraryConfigurations)
|
||||
select_library_configurations(VHACD)
|
||||
|
||||
set(VHACD_LIBRARIES ${VHACD_LIBRARY})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(VHACD "Could NOT find VHACD, try to set the path to VHACD root folder in the system variable VHACD_ROOT_DIR or create a directory vhacd in HIFI_LIB_DIR and paste the necessary files there"
|
||||
VHACD_INCLUDE_DIRS VHACD_LIBRARIES)
|
||||
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
#
|
||||
# FindVisage.cmake
|
||||
#
|
||||
# Try to find the Visage controller library
|
||||
#
|
||||
# You must provide a VISAGE_ROOT_DIR which contains lib and include directories
|
||||
#
|
||||
# Once done this will define
|
||||
#
|
||||
# VISAGE_FOUND - system found Visage
|
||||
# VISAGE_INCLUDE_DIRS - the Visage include directory
|
||||
# VISAGE_LIBRARIES - Link this to use Visage
|
||||
#
|
||||
# Created on 2/11/2014 by Andrzej Kapolka
|
||||
# Copyright 2014 High Fidelity, Inc.
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("visage")
|
||||
|
||||
find_path(VISAGE_BASE_INCLUDE_DIR VisageTracker2.h PATH_SUFFIXES include HINTS ${VISAGE_SEARCH_DIRS})
|
||||
|
||||
if (APPLE)
|
||||
find_path(VISAGE_XML_INCLUDE_DIR libxml/xmlreader.h HINTS /usr/include/libxml2 ${VISAGE_SEARCH_DIRS})
|
||||
find_path(VISAGE_OPENCV_INCLUDE_DIR cv.h PATH_SUFFIXES dependencies/OpenCV_MacOSX/include HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_path(VISAGE_OPENCV2_INCLUDE_DIR opencv.hpp PATH_SUFFIXES dependencies/OpenCV_MacOSX/include/opencv2 HINTS ${VISAGE_SEARCH_DIRS})
|
||||
|
||||
find_library(VISAGE_CORE_LIBRARY NAME vscore PATH_SUFFIXES lib HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_library(VISAGE_VISION_LIBRARY NAME vsvision PATH_SUFFIXES lib HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_library(VISAGE_OPENCV_LIBRARY NAME OpenCV PATH_SUFFIXES dependencies/OpenCV_MacOSX/lib HINTS ${VISAGE_SEARCH_DIRS})
|
||||
|
||||
find_library(CoreVideo CoreVideo)
|
||||
find_library(QTKit QTKit)
|
||||
find_library(IOKit IOKit)
|
||||
|
||||
elseif (WIN32)
|
||||
find_path(VISAGE_XML_INCLUDE_DIR libxml/xmlreader.h PATH_SUFFIXES dependencies/libxml2/include HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_path(VISAGE_OPENCV_INCLUDE_DIR opencv/cv.h PATH_SUFFIXES dependencies/OpenCV/include HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_path(VISAGE_OPENCV2_INCLUDE_DIR cv.h PATH_SUFFIXES dependencies/OpenCV/include/opencv HINTS ${VISAGE_SEARCH_DIRS})
|
||||
|
||||
find_library(VISAGE_CORE_LIBRARY NAME vscore PATH_SUFFIXES lib HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_library(VISAGE_VISION_LIBRARY NAME vsvision PATH_SUFFIXES lib HINTS ${VISAGE_SEARCH_DIRS})
|
||||
find_library(VISAGE_OPENCV_LIBRARY NAME opencv_core243 PATH_SUFFIXES dependencies/OpenCV/lib HINTS ${VISAGE_SEARCH_DIRS})
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
list(APPEND VISAGE_ARGS_LIST VISAGE_BASE_INCLUDE_DIR VISAGE_XML_INCLUDE_DIR
|
||||
VISAGE_OPENCV_INCLUDE_DIR VISAGE_OPENCV2_INCLUDE_DIR
|
||||
VISAGE_CORE_LIBRARY VISAGE_VISION_LIBRARY)
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND VISAGE_ARGS_LIST CoreVideo QTKit IOKit)
|
||||
endif ()
|
||||
|
||||
find_package_handle_standard_args(Visage DEFAULT_MSG ${VISAGE_ARGS_LIST})
|
||||
|
||||
set(VISAGE_INCLUDE_DIRS "${VISAGE_XML_INCLUDE_DIR}" "${VISAGE_OPENCV_INCLUDE_DIR}" "${VISAGE_OPENCV2_INCLUDE_DIR}" "${VISAGE_BASE_INCLUDE_DIR}")
|
||||
set(VISAGE_LIBRARIES "${VISAGE_CORE_LIBRARY}" "${VISAGE_VISION_LIBRARY}")
|
||||
|
||||
if (APPLE)
|
||||
list(APPEND VISAGE_LIBRARIES "${CoreVideo}" "${QTKit}" "${IOKit}")
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(VISAGE_INCLUDE_DIRS VISAGE_LIBRARIES)
|
|
@ -302,6 +302,9 @@ bool DomainServer::didSetupAccountManagerWithAccessToken() {
|
|||
<< "at keypath metaverse.access_token or in your ENV at key DOMAIN_SERVER_ACCESS_TOKEN";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Using access token from DOMAIN_SERVER_ACCESS_TOKEN in env. This overrides any access token present"
|
||||
<< " in the user or master config.";
|
||||
}
|
||||
|
||||
// give this access token to the AccountManager
|
||||
|
|
163
examples/acScripts/rain.js
Normal file
163
examples/acScripts/rain.js
Normal file
|
@ -0,0 +1,163 @@
|
|||
//
|
||||
// rain.js
|
||||
// examples
|
||||
//
|
||||
// Created by David Rowe on 9 Apr 2015.
|
||||
// Copyright 2015 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
|
||||
//
|
||||
|
||||
var RainSquall = function (properties) {
|
||||
var // Properties
|
||||
squallOrigin,
|
||||
squallRadius,
|
||||
dropsPerMinute = 60,
|
||||
dropSize = { x: 0.1, y: 0.1, z: 0.1 },
|
||||
dropFallSpeed = 1, // m/s
|
||||
dropLifetime = 60, // Seconds
|
||||
dropSpinMax = 0, // Maximum angular velocity per axis; deg/s
|
||||
debug = false, // Display origin circle; don't use running on Stack Manager
|
||||
// Other
|
||||
squallCircle,
|
||||
SQUALL_CIRCLE_COLOR = { red: 255, green: 0, blue: 0 },
|
||||
SQUALL_CIRCLE_ALPHA = 0.5,
|
||||
SQUALL_CIRCLE_ROTATION = Quat.fromPitchYawRollDegrees(90, 0, 0),
|
||||
raindropProperties,
|
||||
RAINDROP_MODEL_URL = "https://s3.amazonaws.com/hifi-public/ozan/Polyworld/Sets/sky/tetrahedron_v1-Faceted2.fbx",
|
||||
raindropTimer,
|
||||
raindrops = [], // HACK: Work around raindrops not always getting velocities
|
||||
raindropVelocities = [], // HACK: Work around raindrops not always getting velocities
|
||||
DEGREES_TO_RADIANS = Math.PI / 180;
|
||||
|
||||
function processProperties() {
|
||||
if (!properties.hasOwnProperty("origin")) {
|
||||
print("ERROR: Rain squall origin must be specified");
|
||||
return;
|
||||
}
|
||||
squallOrigin = properties.origin;
|
||||
|
||||
if (!properties.hasOwnProperty("radius")) {
|
||||
print("ERROR: Rain squall radius must be specified");
|
||||
return;
|
||||
}
|
||||
squallRadius = properties.radius;
|
||||
|
||||
if (properties.hasOwnProperty("dropsPerMinute")) {
|
||||
dropsPerMinute = properties.dropsPerMinute;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("dropSize")) {
|
||||
dropSize = properties.dropSize;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("dropFallSpeed")) {
|
||||
dropFallSpeed = properties.dropFallSpeed;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("dropLifetime")) {
|
||||
dropLifetime = properties.dropLifetime;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("dropSpinMax")) {
|
||||
dropSpinMax = properties.dropSpinMax;
|
||||
}
|
||||
|
||||
if (properties.hasOwnProperty("debug")) {
|
||||
debug = properties.debug;
|
||||
}
|
||||
|
||||
raindropProperties = {
|
||||
type: "Model",
|
||||
modelURL: RAINDROP_MODEL_URL,
|
||||
lifetime: dropLifetime,
|
||||
dimensions: dropSize,
|
||||
velocity: { x: 0, y: -dropFallSpeed, z: 0 },
|
||||
damping: 0,
|
||||
angularDamping: 0,
|
||||
ignoreForCollisions: true
|
||||
};
|
||||
}
|
||||
|
||||
function createRaindrop() {
|
||||
var angle,
|
||||
radius,
|
||||
offset,
|
||||
drop,
|
||||
spin = { x: 0, y: 0, z: 0 },
|
||||
maxSpinRadians = properties.dropSpinMax * DEGREES_TO_RADIANS,
|
||||
i;
|
||||
|
||||
// HACK: Work around rain drops not always getting velocities set at creation
|
||||
for (i = 0; i < raindrops.length; i += 1) {
|
||||
Entities.editEntity(raindrops[i], raindropVelocities[i]);
|
||||
}
|
||||
|
||||
angle = Math.random() * 360;
|
||||
radius = Math.random() * squallRadius;
|
||||
offset = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, angle, 0), { x: 0, y: -0.1, z: radius });
|
||||
raindropProperties.position = Vec3.sum(squallOrigin, offset);
|
||||
if (properties.dropSpinMax > 0) {
|
||||
spin = {
|
||||
x: Math.random() * maxSpinRadians,
|
||||
y: Math.random() * maxSpinRadians,
|
||||
z: Math.random() * maxSpinRadians
|
||||
};
|
||||
raindropProperties.angularVelocity = spin;
|
||||
}
|
||||
drop = Entities.addEntity(raindropProperties);
|
||||
|
||||
// HACK: Work around rain drops not always getting velocities set at creation
|
||||
raindrops.push(drop);
|
||||
raindropVelocities.push({
|
||||
velocity: raindropProperties.velocity,
|
||||
angularVelocity: spin
|
||||
});
|
||||
if (raindrops.length > 5) {
|
||||
raindrops.shift();
|
||||
raindropVelocities.shift();
|
||||
}
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
if (debug) {
|
||||
squallCircle = Overlays.addOverlay("circle3d", {
|
||||
size: { x: 2 * squallRadius, y: 2 * squallRadius },
|
||||
color: SQUALL_CIRCLE_COLOR,
|
||||
alpha: SQUALL_CIRCLE_ALPHA,
|
||||
solid: true,
|
||||
visible: debug,
|
||||
position: squallOrigin,
|
||||
rotation: SQUALL_CIRCLE_ROTATION
|
||||
});
|
||||
}
|
||||
|
||||
raindropTimer = Script.setInterval(createRaindrop, 60000 / dropsPerMinute);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
Script.clearInterval(raindropTimer);
|
||||
if (debug) {
|
||||
Overlays.deleteOverlay(squallCircle);
|
||||
}
|
||||
}
|
||||
|
||||
processProperties();
|
||||
setUp();
|
||||
Script.scriptEnding.connect(tearDown);
|
||||
|
||||
return {
|
||||
};
|
||||
};
|
||||
|
||||
var rainSquall1 = new RainSquall({
|
||||
origin: { x: 1195, y: 1223, z: 1020 },
|
||||
radius: 25,
|
||||
dropsPerMinute: 120,
|
||||
dropSize: { x: 0.1, y: 0.1, z: 0.1 },
|
||||
dropFallSpeed: 3,
|
||||
dropLifetime: 30,
|
||||
dropSpinMax: 180,
|
||||
debug: false
|
||||
});
|
|
@ -41,7 +41,8 @@ panel.newSlider("Year Time", 0, 364,
|
|||
);
|
||||
|
||||
panel.newSlider("Day Time", 0, 24,
|
||||
function(value) { Scene.setStageDayTime(value); },
|
||||
|
||||
function(value) { Scene.setStageDayTime(value); panel.update("Light Direction"); },
|
||||
function() { return Scene.getStageDayTime(); },
|
||||
function(value) {
|
||||
var hour = Math.floor(value);
|
||||
|
@ -72,12 +73,36 @@ function runStageTime() {
|
|||
}
|
||||
Script.setInterval(runStageTime, tickTackPeriod);
|
||||
|
||||
panel.newCheckbox("Enable Sun Model",
|
||||
function(value) { Scene.setStageSunModelEnable((value != 0)); },
|
||||
function() { return Scene.isStageSunModelEnabled(); },
|
||||
function(value) { return (value); }
|
||||
);
|
||||
|
||||
panel.newDirectionBox("Light Direction",
|
||||
function(value) { Scene.setKeyLightDirection(value); },
|
||||
function() { return Scene.getKeyLightDirection(); },
|
||||
function(value) { return value.x.toFixed(2) + "," + value.y.toFixed(2) + "," + value.z.toFixed(2); }
|
||||
);
|
||||
|
||||
panel.newSlider("Light Intensity", 0.0, 5,
|
||||
function(value) { Scene.setSunIntensity(value); },
|
||||
function() { return Scene.getSunIntensity(); },
|
||||
function(value) { Scene.setKeyLightIntensity(value); },
|
||||
function() { return Scene.getKeyLightIntensity(); },
|
||||
function(value) { return (value).toFixed(2); }
|
||||
);
|
||||
|
||||
panel.newSlider("Ambient Light Intensity", 0.0, 1.0,
|
||||
function(value) { Scene.setKeyLightAmbientIntensity(value); },
|
||||
function() { return Scene.getKeyLightAmbientIntensity(); },
|
||||
function(value) { return (value).toFixed(2); }
|
||||
);
|
||||
|
||||
panel.newColorBox("Light Color",
|
||||
function(value) { Scene.setKeyLightColor(value); },
|
||||
function() { return Scene.getKeyLightColor(); },
|
||||
function(value) { return (value); } // "(" + value.x + "," = value.y + "," + value.z + ")"; }
|
||||
);
|
||||
|
||||
Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); });
|
||||
Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); });
|
||||
Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); });
|
||||
|
|
|
@ -12,6 +12,129 @@
|
|||
|
||||
// The Slider class
|
||||
Slider = function(x,y,width,thumbSize) {
|
||||
this.background = Overlays.addOverlay("text", {
|
||||
backgroundColor: { red: 125, green: 125, blue: 255 },
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: thumbSize,
|
||||
alpha: 1.0,
|
||||
backgroundAlpha: 0.5,
|
||||
visible: true
|
||||
});
|
||||
this.thumb = Overlays.addOverlay("text", {
|
||||
backgroundColor: { red: 255, green: 255, blue: 255 },
|
||||
x: x,
|
||||
y: y,
|
||||
width: thumbSize,
|
||||
height: thumbSize,
|
||||
alpha: 1.0,
|
||||
backgroundAlpha: 1.0,
|
||||
visible: true
|
||||
});
|
||||
|
||||
|
||||
this.thumbSize = thumbSize;
|
||||
this.thumbHalfSize = 0.5 * thumbSize;
|
||||
|
||||
this.minThumbX = x + this.thumbHalfSize;
|
||||
this.maxThumbX = x + width - this.thumbHalfSize;
|
||||
this.thumbX = this.minThumbX;
|
||||
|
||||
this.minValue = 0.0;
|
||||
this.maxValue = 1.0;
|
||||
|
||||
this.clickOffsetX = 0;
|
||||
this.isMoving = false;
|
||||
|
||||
this.updateThumb = function() {
|
||||
thumbTruePos = this.thumbX - 0.5 * this.thumbSize;
|
||||
Overlays.editOverlay(this.thumb, { x: thumbTruePos } );
|
||||
};
|
||||
|
||||
this.isClickableOverlayItem = function(item) {
|
||||
return (item == this.thumb) || (item == this.background);
|
||||
};
|
||||
|
||||
this.onMouseMoveEvent = function(event) {
|
||||
if (this.isMoving) {
|
||||
newThumbX = event.x - this.clickOffsetX;
|
||||
if (newThumbX < this.minThumbX) {
|
||||
newThumbX = this.minThumbX;
|
||||
}
|
||||
if (newThumbX > this.maxThumbX) {
|
||||
newThumbX = this.maxThumbX;
|
||||
}
|
||||
this.thumbX = newThumbX;
|
||||
this.updateThumb();
|
||||
this.onValueChanged(this.getValue());
|
||||
}
|
||||
};
|
||||
|
||||
this.onMousePressEvent = function(event, clickedOverlay) {
|
||||
if (!this.isClickableOverlayItem(clickedOverlay)) {
|
||||
this.isMoving = false;
|
||||
return;
|
||||
}
|
||||
this.isMoving = true;
|
||||
var clickOffset = event.x - this.thumbX;
|
||||
if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) {
|
||||
this.clickOffsetX = clickOffset;
|
||||
} else {
|
||||
this.clickOffsetX = 0;
|
||||
this.thumbX = event.x;
|
||||
this.updateThumb();
|
||||
this.onValueChanged(this.getValue());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.onMouseReleaseEvent = function(event) {
|
||||
this.isMoving = false;
|
||||
};
|
||||
|
||||
// Public members:
|
||||
|
||||
this.setNormalizedValue = function(value) {
|
||||
if (value < 0.0) {
|
||||
this.thumbX = this.minThumbX;
|
||||
} else if (value > 1.0) {
|
||||
this.thumbX = this.maxThumbX;
|
||||
} else {
|
||||
this.thumbX = value * (this.maxThumbX - this.minThumbX) + this.minThumbX;
|
||||
}
|
||||
this.updateThumb();
|
||||
};
|
||||
this.getNormalizedValue = function() {
|
||||
return (this.thumbX - this.minThumbX) / (this.maxThumbX - this.minThumbX);
|
||||
};
|
||||
|
||||
this.setValue = function(value) {
|
||||
var normValue = (value - this.minValue) / (this.maxValue - this.minValue);
|
||||
this.setNormalizedValue(normValue);
|
||||
};
|
||||
|
||||
this.getValue = function() {
|
||||
return this.getNormalizedValue() * (this.maxValue - this.minValue) + this.minValue;
|
||||
};
|
||||
|
||||
this.onValueChanged = function(value) {};
|
||||
|
||||
this.destroy = function() {
|
||||
Overlays.deleteOverlay(this.background);
|
||||
Overlays.deleteOverlay(this.thumb);
|
||||
};
|
||||
|
||||
this.setThumbColor = function(color) {
|
||||
Overlays.editOverlay(this.thumb, {backgroundColor: { red: color.x*255, green: color.y*255, blue: color.z*255 }});
|
||||
};
|
||||
this.setBackgroundColor = function(color) {
|
||||
Overlays.editOverlay(this.background, {backgroundColor: { red: color.x*255, green: color.y*255, blue: color.z*255 }});
|
||||
};
|
||||
}
|
||||
|
||||
// The Checkbox class
|
||||
Checkbox = function(x,y,width,thumbSize) {
|
||||
|
||||
this.thumb = Overlays.addOverlay("text", {
|
||||
backgroundColor: { red: 255, green: 255, blue: 255 },
|
||||
|
@ -52,6 +175,10 @@ Slider = function(x,y,width,thumbSize) {
|
|||
Overlays.editOverlay(this.thumb, { x: thumbTruePos } );
|
||||
};
|
||||
|
||||
this.isClickableOverlayItem = function(item) {
|
||||
return item == this.background;
|
||||
};
|
||||
|
||||
this.onMouseMoveEvent = function(event) {
|
||||
if (this.isMoving) {
|
||||
newThumbX = event.x - this.clickOffsetX;
|
||||
|
@ -67,7 +194,11 @@ Slider = function(x,y,width,thumbSize) {
|
|||
}
|
||||
};
|
||||
|
||||
this.onMousePressEvent = function(event) {
|
||||
this.onMousePressEvent = function(event, clickedOverlay) {
|
||||
if (this.background != clickedOverlay) {
|
||||
this.isMoving = false;
|
||||
return;
|
||||
}
|
||||
this.isMoving = true;
|
||||
var clickOffset = event.x - this.thumbX;
|
||||
if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) {
|
||||
|
@ -118,6 +249,167 @@ Slider = function(x,y,width,thumbSize) {
|
|||
};
|
||||
}
|
||||
|
||||
// The ColorBox class
|
||||
ColorBox = function(x,y,width,thumbSize) {
|
||||
var self = this;
|
||||
|
||||
var slideHeight = thumbSize / 3;
|
||||
var sliderWidth = width;
|
||||
this.red = new Slider(x, y, width, slideHeight);
|
||||
this.green = new Slider(x, y + slideHeight, width, slideHeight);
|
||||
this.blue = new Slider(x, y + 2 * slideHeight, width, slideHeight);
|
||||
this.red.setBackgroundColor({x: 1, y: 0, z: 0});
|
||||
this.green.setBackgroundColor({x: 0, y: 1, z: 0});
|
||||
this.blue.setBackgroundColor({x: 0, y: 0, z: 1});
|
||||
|
||||
this.isClickableOverlayItem = function(item) {
|
||||
return this.red.isClickableOverlayItem(item)
|
||||
|| this.green.isClickableOverlayItem(item)
|
||||
|| this.blue.isClickableOverlayItem(item);
|
||||
};
|
||||
|
||||
this.onMouseMoveEvent = function(event) {
|
||||
this.red.onMouseMoveEvent(event);
|
||||
this.green.onMouseMoveEvent(event);
|
||||
this.blue.onMouseMoveEvent(event);
|
||||
};
|
||||
|
||||
this.onMousePressEvent = function(event, clickedOverlay) {
|
||||
this.red.onMousePressEvent(event, clickedOverlay);
|
||||
if (this.red.isMoving) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.green.onMousePressEvent(event, clickedOverlay);
|
||||
if (this.green.isMoving) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.blue.onMousePressEvent(event, clickedOverlay);
|
||||
};
|
||||
|
||||
this.onMouseReleaseEvent = function(event) {
|
||||
this.red.onMouseReleaseEvent(event);
|
||||
this.green.onMouseReleaseEvent(event);
|
||||
this.blue.onMouseReleaseEvent(event);
|
||||
};
|
||||
|
||||
this.setterFromWidget = function(value) {
|
||||
var color = self.getValue();
|
||||
self.onValueChanged(color);
|
||||
self.updateRGBSliders(color);
|
||||
};
|
||||
|
||||
this.red.onValueChanged = this.setterFromWidget;
|
||||
this.green.onValueChanged = this.setterFromWidget;
|
||||
this.blue.onValueChanged = this.setterFromWidget;
|
||||
|
||||
this.updateRGBSliders = function(color) {
|
||||
this.red.setThumbColor({x: color.x, y: 0, z: 0});
|
||||
this.green.setThumbColor({x: 0, y: color.y, z: 0});
|
||||
this.blue.setThumbColor({x: 0, y: 0, z: color.z});
|
||||
};
|
||||
|
||||
// Public members:
|
||||
this.setValue = function(value) {
|
||||
this.red.setValue(value.x);
|
||||
this.green.setValue(value.y);
|
||||
this.blue.setValue(value.z);
|
||||
this.updateRGBSliders(value);
|
||||
};
|
||||
|
||||
this.getValue = function() {
|
||||
var value = {x:this.red.getValue(), y:this.green.getValue(),z:this.blue.getValue()};
|
||||
return value;
|
||||
};
|
||||
|
||||
this.destroy = function() {
|
||||
this.red.destroy();
|
||||
this.green.destroy();
|
||||
this.blue.destroy();
|
||||
};
|
||||
|
||||
this.onValueChanged = function(value) {};
|
||||
}
|
||||
|
||||
// The DirectionBox class
|
||||
DirectionBox = function(x,y,width,thumbSize) {
|
||||
var self = this;
|
||||
|
||||
var slideHeight = thumbSize / 2;
|
||||
var sliderWidth = width;
|
||||
this.yaw = new Slider(x, y, width, slideHeight);
|
||||
this.pitch = new Slider(x, y + slideHeight, width, slideHeight);
|
||||
|
||||
this.yaw.setThumbColor({x: 1, y: 0, z: 0});
|
||||
this.yaw.minValue = -180;
|
||||
this.yaw.maxValue = +180;
|
||||
|
||||
this.pitch.setThumbColor({x: 0, y: 0, z: 1});
|
||||
this.pitch.minValue = -1;
|
||||
this.pitch.maxValue = +1;
|
||||
|
||||
this.isClickableOverlayItem = function(item) {
|
||||
return this.yaw.isClickableOverlayItem(item)
|
||||
|| this.pitch.isClickableOverlayItem(item);
|
||||
};
|
||||
|
||||
this.onMouseMoveEvent = function(event) {
|
||||
this.yaw.onMouseMoveEvent(event);
|
||||
this.pitch.onMouseMoveEvent(event);
|
||||
};
|
||||
|
||||
this.onMousePressEvent = function(event, clickedOverlay) {
|
||||
this.yaw.onMousePressEvent(event, clickedOverlay);
|
||||
if (this.yaw.isMoving) {
|
||||
return;
|
||||
}
|
||||
this.pitch.onMousePressEvent(event, clickedOverlay);
|
||||
};
|
||||
|
||||
this.onMouseReleaseEvent = function(event) {
|
||||
this.yaw.onMouseReleaseEvent(event);
|
||||
this.pitch.onMouseReleaseEvent(event);
|
||||
};
|
||||
|
||||
this.setterFromWidget = function(value) {
|
||||
var yawPitch = self.getValue();
|
||||
self.onValueChanged(yawPitch);
|
||||
};
|
||||
|
||||
this.yaw.onValueChanged = this.setterFromWidget;
|
||||
this.pitch.onValueChanged = this.setterFromWidget;
|
||||
|
||||
// Public members:
|
||||
this.setValue = function(direction) {
|
||||
var flatXZ = Math.sqrt(direction.x * direction.x + direction.z * direction.z);
|
||||
if (flatXZ > 0.0) {
|
||||
var flatX = direction.x / flatXZ;
|
||||
var flatZ = direction.z / flatXZ;
|
||||
var yaw = Math.acos(flatX) * 180 / Math.PI;
|
||||
if (flatZ < 0) {
|
||||
yaw = -yaw;
|
||||
}
|
||||
this.yaw.setValue(yaw);
|
||||
}
|
||||
this.pitch.setValue(direction.y);
|
||||
};
|
||||
|
||||
this.getValue = function() {
|
||||
var dirZ = this.pitch.getValue();
|
||||
var yaw = this.yaw.getValue() * Math.PI / 180;
|
||||
var cosY = Math.sqrt(1 - dirZ*dirZ);
|
||||
var value = {x:cosY * Math.cos(yaw), y:dirZ, z: cosY * Math.sin(yaw)};
|
||||
return value;
|
||||
};
|
||||
|
||||
this.destroy = function() {
|
||||
this.yaw.destroy();
|
||||
this.pitch.destroy();
|
||||
};
|
||||
|
||||
this.onValueChanged = function(value) {};
|
||||
}
|
||||
|
||||
var textFontSize = 16;
|
||||
|
||||
|
@ -167,7 +459,12 @@ function PanelItem(name, setter, getter, displayer, x, y, textWidth, valueWidth,
|
|||
};
|
||||
this.setterFromWidget = function(value) {
|
||||
setter(value);
|
||||
Overlays.editOverlay(this.value, {text: this.displayer(getter())});
|
||||
// ANd loop back the value after the final setter has been called
|
||||
var value = getter();
|
||||
if (this.widget) {
|
||||
this.widget.setValue(value);
|
||||
}
|
||||
Overlays.editOverlay(this.value, {text: this.displayer(value)});
|
||||
};
|
||||
|
||||
|
||||
|
@ -219,9 +516,9 @@ Panel = function(x, y) {
|
|||
for (var i in this.items) {
|
||||
var widget = this.items[i].widget;
|
||||
|
||||
if (clickedOverlay == widget.background) {
|
||||
if (widget.isClickableOverlayItem(clickedOverlay)) {
|
||||
this.activeWidget = widget;
|
||||
this.activeWidget.onMousePressEvent(event);
|
||||
this.activeWidget.onMousePressEvent(event, clickedOverlay);
|
||||
// print("clicked... widget=" + i);
|
||||
break;
|
||||
}
|
||||
|
@ -237,21 +534,63 @@ Panel = function(x, y) {
|
|||
|
||||
this.newSlider = function(name, minValue, maxValue, setValue, getValue, displayValue) {
|
||||
|
||||
var sliderItem = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
||||
var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
||||
|
||||
var slider = new Slider(this.widgetX, this.nextY, widgetWidth, rawHeight);
|
||||
slider.minValue = minValue;
|
||||
slider.maxValue = maxValue;
|
||||
slider.onValueChanged = function(value) { sliderItem.setterFromWidget(value); };
|
||||
|
||||
|
||||
sliderItem.widget = slider;
|
||||
sliderItem.setter(getValue());
|
||||
this.items[name] = sliderItem;
|
||||
item.widget = slider;
|
||||
item.widget.onValueChanged = function(value) { item.setterFromWidget(value); };
|
||||
item.setter(getValue());
|
||||
this.items[name] = item;
|
||||
this.nextY += rawYDelta;
|
||||
// print("created Item... slider=" + name);
|
||||
};
|
||||
|
||||
this.newCheckbox = function(name, setValue, getValue, displayValue) {
|
||||
|
||||
var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
||||
|
||||
var checkbox = new Checkbox(this.widgetX, this.nextY, widgetWidth, rawHeight);
|
||||
|
||||
item.widget = checkbox;
|
||||
item.widget.onValueChanged = function(value) { item.setterFromWidget(value); };
|
||||
item.setter(getValue());
|
||||
this.items[name] = item;
|
||||
this.nextY += rawYDelta;
|
||||
// print("created Item... slider=" + name);
|
||||
};
|
||||
|
||||
this.newColorBox = function(name, setValue, getValue, displayValue) {
|
||||
|
||||
var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
||||
|
||||
var colorBox = new ColorBox(this.widgetX, this.nextY, widgetWidth, rawHeight);
|
||||
|
||||
item.widget = colorBox;
|
||||
item.widget.onValueChanged = function(value) { item.setterFromWidget(value); };
|
||||
item.setter(getValue());
|
||||
this.items[name] = item;
|
||||
this.nextY += rawYDelta;
|
||||
// print("created Item... colorBox=" + name);
|
||||
};
|
||||
|
||||
this.newDirectionBox= function(name, setValue, getValue, displayValue) {
|
||||
|
||||
var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight);
|
||||
|
||||
var directionBox = new DirectionBox(this.widgetX, this.nextY, widgetWidth, rawHeight);
|
||||
|
||||
item.widget = directionBox;
|
||||
item.widget.onValueChanged = function(value) { item.setterFromWidget(value); };
|
||||
item.setter(getValue());
|
||||
this.items[name] = item;
|
||||
this.nextY += rawYDelta;
|
||||
// print("created Item... directionBox=" + name);
|
||||
};
|
||||
|
||||
this.destroy = function() {
|
||||
for (var i in this.items) {
|
||||
this.items[i].destroy();
|
||||
|
@ -273,6 +612,15 @@ Panel = function(x, y) {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
this.update = function(name) {
|
||||
var item = this.items[name];
|
||||
if (item != null) {
|
||||
return item.setter(item.getter());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -170,15 +170,6 @@ foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
|||
endif ()
|
||||
endforeach()
|
||||
|
||||
# special APPLE modifications for Visage library
|
||||
if (VISAGE_FOUND AND NOT DISABLE_VISAGE AND APPLE)
|
||||
add_definitions(-DMAC_OS_X)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-comment")
|
||||
find_library(AVFoundation AVFoundation)
|
||||
find_library(CoreMedia CoreMedia)
|
||||
target_link_libraries(${TARGET_NAME} ${AVFoundation} ${CoreMedia} ${NEW_STD_LIBRARY})
|
||||
endif ()
|
||||
|
||||
# special OS X modifications for RtMidi library
|
||||
if (RTMIDI_FOUND AND NOT DISABLE_RTMIDI AND APPLE)
|
||||
find_library(CoreMIDI CoreMIDI)
|
||||
|
|
14
interface/external/visage/readme.txt
vendored
14
interface/external/visage/readme.txt
vendored
|
@ -1,14 +0,0 @@
|
|||
|
||||
Instructions for adding the Visage driver to Interface
|
||||
Andrzej Kapolka, February 11, 2014
|
||||
|
||||
1. Copy the Visage sdk folders (lib, include, dependencies) into the interface/external/visage folder.
|
||||
This readme.txt should be there as well.
|
||||
|
||||
2. Copy the contents of the Visage configuration data folder (visageSDK-MacOS/Samples/MacOSX/data/) to
|
||||
interface/resources/visage (i.e., so that interface/resources/visage/candide3.wfm is accessible)
|
||||
|
||||
3. Copy the Visage license file to interface/resources/visage/license.vlc.
|
||||
|
||||
4. Delete your build directory, run cmake and build, and you should be all set.
|
||||
|
|
@ -108,7 +108,6 @@
|
|||
#include "devices/MIDIManager.h"
|
||||
#include "devices/OculusManager.h"
|
||||
#include "devices/TV3DManager.h"
|
||||
#include "devices/Visage.h"
|
||||
|
||||
#include "gpu/Batch.h"
|
||||
#include "gpu/GLBackend.h"
|
||||
|
@ -247,7 +246,6 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
auto ambientOcclusionEffect = DependencyManager::set<AmbientOcclusionEffect>();
|
||||
auto textureCache = DependencyManager::set<TextureCache>();
|
||||
auto animationCache = DependencyManager::set<AnimationCache>();
|
||||
auto visage = DependencyManager::set<Visage>();
|
||||
auto ddeFaceTracker = DependencyManager::set<DdeFaceTracker>();
|
||||
auto modelBlender = DependencyManager::set<ModelBlender>();
|
||||
auto audioToolBox = DependencyManager::set<AudioToolBox>();
|
||||
|
@ -1834,12 +1832,10 @@ int Application::getMouseDragStartedY() const {
|
|||
|
||||
FaceTracker* Application::getActiveFaceTracker() {
|
||||
auto faceshift = DependencyManager::get<Faceshift>();
|
||||
auto visage = DependencyManager::get<Visage>();
|
||||
auto dde = DependencyManager::get<DdeFaceTracker>();
|
||||
|
||||
return (dde->isActive() ? static_cast<FaceTracker*>(dde.data()) :
|
||||
(faceshift->isActive() ? static_cast<FaceTracker*>(faceshift.data()) :
|
||||
(visage->isActive() ? static_cast<FaceTracker*>(visage.data()) : NULL)));
|
||||
(faceshift->isActive() ? static_cast<FaceTracker*>(faceshift.data()) : NULL));
|
||||
}
|
||||
|
||||
void Application::setActiveFaceTracker() {
|
||||
|
@ -1847,10 +1843,11 @@ void Application::setActiveFaceTracker() {
|
|||
DependencyManager::get<Faceshift>()->setTCPEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift));
|
||||
#endif
|
||||
#ifdef HAVE_DDE
|
||||
DependencyManager::get<DdeFaceTracker>()->setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression));
|
||||
#endif
|
||||
#ifdef HAVE_VISAGE
|
||||
DependencyManager::get<Visage>()->updateEnabled();
|
||||
bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::UseAudioForMouth)->setVisible(isUsingDDE);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::DDEFiltering)->setVisible(isUsingDDE);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE);
|
||||
DependencyManager::get<DdeFaceTracker>()->setEnabled(isUsingDDE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2025,7 +2022,6 @@ void Application::init() {
|
|||
// initialize our face trackers after loading the menu settings
|
||||
DependencyManager::get<Faceshift>()->init();
|
||||
DependencyManager::get<DdeFaceTracker>()->init();
|
||||
DependencyManager::get<Visage>()->init();
|
||||
|
||||
Leapmotion::init();
|
||||
RealSense::init();
|
||||
|
@ -3144,7 +3140,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
|
|||
{
|
||||
DependencyManager::get<DeferredLightingEffect>()->setAmbientLightMode(getRenderAmbientLight());
|
||||
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity());
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity());
|
||||
DependencyManager::get<DeferredLightingEffect>()->setGlobalAtmosphere(skyStage->getAtmosphere());
|
||||
|
||||
PROFILE_RANGE("DeferredLighting");
|
||||
|
@ -3359,7 +3355,6 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
|
|||
|
||||
void Application::resetSensors() {
|
||||
DependencyManager::get<Faceshift>()->reset();
|
||||
DependencyManager::get<Visage>()->reset();
|
||||
DependencyManager::get<DdeFaceTracker>()->reset();
|
||||
|
||||
OculusManager::reset();
|
||||
|
@ -3966,6 +3961,9 @@ void Application::stopAllScripts(bool restart) {
|
|||
// stops all current running scripts
|
||||
for (QHash<QString, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();
|
||||
it != _scriptEnginesHash.constEnd(); it++) {
|
||||
if (it.value()->isFinished()) {
|
||||
continue;
|
||||
}
|
||||
if (restart && it.value()->isUserLoaded()) {
|
||||
connect(it.value(), SIGNAL(finished(const QString&)), SLOT(loadScript(const QString&)));
|
||||
}
|
||||
|
|
|
@ -213,7 +213,6 @@ public:
|
|||
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
|
||||
|
||||
FaceTracker* getActiveFaceTracker();
|
||||
void setActiveFaceTracker();
|
||||
|
||||
QSystemTrayIcon* getTrayIcon() { return _trayIcon; }
|
||||
ApplicationOverlay& getApplicationOverlay() { return _applicationOverlay; }
|
||||
|
@ -388,6 +387,8 @@ public slots:
|
|||
void setVSyncEnabled();
|
||||
|
||||
void resetSensors();
|
||||
void setActiveFaceTracker();
|
||||
|
||||
void aboutApp();
|
||||
void showEditEntitiesHelp();
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <UUID.h>
|
||||
|
||||
#include "DiscoverabilityManager.h"
|
||||
#include "Menu.h"
|
||||
|
||||
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::All;
|
||||
|
||||
|
@ -96,4 +97,32 @@ void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discov
|
|||
|
||||
emit discoverabilityModeChanged(discoverabilityMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoverabilityManager::setVisibility() {
|
||||
Menu* menu = Menu::getInstance();
|
||||
|
||||
if (menu->isOptionChecked(MenuOption::VisibleToEveryone)) {
|
||||
this->setDiscoverabilityMode(Discoverability::All);
|
||||
} else if (menu->isOptionChecked(MenuOption::VisibleToFriends)) {
|
||||
this->setDiscoverabilityMode(Discoverability::Friends);
|
||||
} else if (menu->isOptionChecked(MenuOption::VisibleToNoOne)) {
|
||||
this->setDiscoverabilityMode(Discoverability::None);
|
||||
} else {
|
||||
qDebug() << "ERROR DiscoverabilityManager::setVisibility() called with unrecognized value.";
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoverabilityManager::visibilityChanged(Discoverability::Mode discoverabilityMode) {
|
||||
Menu* menu = Menu::getInstance();
|
||||
|
||||
if (discoverabilityMode == Discoverability::All) {
|
||||
menu->setIsOptionChecked(MenuOption::VisibleToEveryone, true);
|
||||
} else if (discoverabilityMode == Discoverability::Friends) {
|
||||
menu->setIsOptionChecked(MenuOption::VisibleToFriends, true);
|
||||
} else if (discoverabilityMode == Discoverability::None) {
|
||||
menu->setIsOptionChecked(MenuOption::VisibleToNoOne, true);
|
||||
} else {
|
||||
qDebug() << "ERROR DiscoverabilityManager::visibilityChanged() called with unrecognized value.";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ public slots:
|
|||
Discoverability::Mode getDiscoverabilityMode() { return static_cast<Discoverability::Mode>(_mode.get()); }
|
||||
void setDiscoverabilityMode(Discoverability::Mode discoverabilityMode);
|
||||
|
||||
void setVisibility();
|
||||
void visibilityChanged(Discoverability::Mode discoverabilityMode);
|
||||
|
||||
signals:
|
||||
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "devices/Faceshift.h"
|
||||
#include "devices/RealSense.h"
|
||||
#include "devices/SixenseManager.h"
|
||||
#include "devices/Visage.h"
|
||||
#include "MainWindow.h"
|
||||
#include "scripting/MenuScriptingInterface.h"
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
|
@ -164,21 +163,21 @@ Menu::Menu() {
|
|||
|
||||
QAction* visibleToEveryone = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToEveryone,
|
||||
0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::All,
|
||||
this, SLOT(setVisibility()));
|
||||
discoverabilityManager.data(), SLOT(setVisibility()));
|
||||
visibilityGroup->addAction(visibleToEveryone);
|
||||
|
||||
QAction* visibleToFriends = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToFriends,
|
||||
0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::Friends,
|
||||
this, SLOT(setVisibility()));
|
||||
discoverabilityManager.data(), SLOT(setVisibility()));
|
||||
visibilityGroup->addAction(visibleToFriends);
|
||||
|
||||
QAction* visibleToNoOne = addCheckableActionToQMenuAndActionHash(visibilityMenu, MenuOption::VisibleToNoOne,
|
||||
0, discoverabilityManager->getDiscoverabilityMode() == Discoverability::None,
|
||||
this, SLOT(setVisibility()));
|
||||
discoverabilityManager.data(), SLOT(setVisibility()));
|
||||
visibilityGroup->addAction(visibleToNoOne);
|
||||
|
||||
connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged,
|
||||
this, &Menu::visibilityChanged);
|
||||
discoverabilityManager.data(), &DiscoverabilityManager::visibilityChanged);
|
||||
}
|
||||
|
||||
addActionToQMenuAndActionHash(toolsMenu,
|
||||
|
@ -236,17 +235,13 @@ Menu::Menu() {
|
|||
|
||||
QMenu* viewMenu = addMenu("View");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||
MenuOption::Fullscreen,
|
||||
#ifdef Q_OS_MAC
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||
MenuOption::Fullscreen,
|
||||
Qt::CTRL | Qt::META | Qt::Key_F,
|
||||
false,
|
||||
qApp,
|
||||
SLOT(setFullscreen(bool)));
|
||||
#else
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu,
|
||||
MenuOption::Fullscreen,
|
||||
Qt::CTRL | Qt::Key_F,
|
||||
#endif
|
||||
false,
|
||||
qApp,
|
||||
SLOT(setFullscreen(bool)));
|
||||
|
@ -261,12 +256,16 @@ Menu::Menu() {
|
|||
0, // QML Qt::Key_H,
|
||||
false, qApp, SLOT(cameraMenuChanged()));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools, Qt::CTRL | Qt::SHIFT | Qt::Key_H,
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HMDTools,
|
||||
#ifdef Q_OS_MAC
|
||||
Qt::META | Qt::Key_H,
|
||||
#else
|
||||
Qt::CTRL | Qt::Key_H,
|
||||
#endif
|
||||
false,
|
||||
dialogsManager.data(),
|
||||
SLOT(hmdTools(bool)));
|
||||
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::EnableVRMode, 0,
|
||||
false,
|
||||
qApp,
|
||||
|
@ -376,30 +375,28 @@ Menu::Menu() {
|
|||
|
||||
QAction* noFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::NoFaceTracking,
|
||||
0, true,
|
||||
this, SLOT(setActiveFaceTracker()));
|
||||
qApp, SLOT(setActiveFaceTracker()));
|
||||
faceTrackerGroup->addAction(noFaceTracker);
|
||||
|
||||
#ifdef HAVE_FACESHIFT
|
||||
QAction* faceshiftFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Faceshift,
|
||||
0, false,
|
||||
this, SLOT(setActiveFaceTracker()));
|
||||
qApp, SLOT(setActiveFaceTracker()));
|
||||
faceTrackerGroup->addAction(faceshiftFaceTracker);
|
||||
#endif
|
||||
#ifdef HAVE_DDE
|
||||
QAction* ddeFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFaceRegression,
|
||||
0, false,
|
||||
this, SLOT(setActiveFaceTracker()));
|
||||
qApp, SLOT(setActiveFaceTracker()));
|
||||
faceTrackerGroup->addAction(ddeFaceTracker);
|
||||
#endif
|
||||
#ifdef HAVE_VISAGE
|
||||
QAction* visageFaceTracker = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::Visage,
|
||||
0, false,
|
||||
this, SLOT(setActiveFaceTracker()));
|
||||
faceTrackerGroup->addAction(visageFaceTracker);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_DDE
|
||||
faceTrackingMenu->addSeparator();
|
||||
QAction* useAudioForMouth = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::UseAudioForMouth, 0, true);
|
||||
useAudioForMouth->setVisible(false);
|
||||
QAction* ddeFiltering = addCheckableActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::DDEFiltering, 0, true);
|
||||
ddeFiltering->setVisible(false);
|
||||
QAction* ddeFaceTrackerReset = addActionToQMenuAndActionHash(faceTrackingMenu, MenuOption::ResetDDETracking,
|
||||
Qt::CTRL | Qt::Key_Apostrophe,
|
||||
DependencyManager::get<DdeFaceTracker>().data(), SLOT(resetTracking()));
|
||||
|
@ -975,37 +972,3 @@ bool Menu::menuItemExists(const QString& menu, const QString& menuitem) {
|
|||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
void Menu::setVisibility() {
|
||||
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToEveryone)) {
|
||||
discoverabilityManager->setDiscoverabilityMode(Discoverability::All);
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToFriends)) {
|
||||
discoverabilityManager->setDiscoverabilityMode(Discoverability::Friends);
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VisibleToNoOne)) {
|
||||
discoverabilityManager->setDiscoverabilityMode(Discoverability::None);
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "ERROR Menu::setVisibility() called with unrecognized value.";
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::visibilityChanged(Discoverability::Mode discoverabilityMode) {
|
||||
if (discoverabilityMode == Discoverability::All) {
|
||||
setIsOptionChecked(MenuOption::VisibleToEveryone, true);
|
||||
} else if (discoverabilityMode == Discoverability::Friends) {
|
||||
setIsOptionChecked(MenuOption::VisibleToFriends, true);
|
||||
} else if (discoverabilityMode == Discoverability::None) {
|
||||
setIsOptionChecked(MenuOption::VisibleToNoOne, true);
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "ERROR Menu::visibilityChanged() called with unrecognized value.";
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::setActiveFaceTracker() {
|
||||
#ifdef HAVE_DDE
|
||||
bool isUsingDDE = Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression);
|
||||
Menu::getInstance()->getActionForOption(MenuOption::ResetDDETracking)->setVisible(isUsingDDE);
|
||||
#endif
|
||||
qApp->setActiveFaceTracker();
|
||||
}
|
||||
|
|
|
@ -66,10 +66,6 @@ public slots:
|
|||
bool isOptionChecked(const QString& menuOption) const;
|
||||
void setIsOptionChecked(const QString& menuOption, bool isChecked);
|
||||
|
||||
private slots:
|
||||
void setVisibility();
|
||||
void setActiveFaceTracker();
|
||||
|
||||
private:
|
||||
static Menu* _instance;
|
||||
Menu();
|
||||
|
@ -100,8 +96,6 @@ private:
|
|||
int findPositionOfMenuItem(QMenu* menu, const QString& searchMenuItem);
|
||||
int positionBeforeSeparatorIfNeeded(QMenu* menu, int requestedPosition);
|
||||
|
||||
void visibilityChanged(Discoverability::Mode discoverabilityMode);
|
||||
|
||||
QHash<QString, QAction*> _actionHash;
|
||||
};
|
||||
|
||||
|
@ -137,6 +131,7 @@ namespace MenuOption {
|
|||
const QString CopyAddress = "Copy Address to Clipboard";
|
||||
const QString CopyPath = "Copy Path to Clipboard";
|
||||
const QString DDEFaceRegression = "DDE Face Regression";
|
||||
const QString DDEFiltering = "DDE Filtering";
|
||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||
const QString DeleteBookmark = "Delete Bookmark...";
|
||||
const QString DisableActivityLogger = "Disable Activity Logger";
|
||||
|
@ -192,6 +187,7 @@ namespace MenuOption {
|
|||
const QString OctreeStats = "Entity Statistics";
|
||||
const QString OffAxisProjection = "Off-Axis Projection";
|
||||
const QString OnlyDisplayTopTen = "Only Display Top Ten";
|
||||
const QString PackageModel = "Package Model...";
|
||||
const QString Pair = "Pair";
|
||||
const QString PipelineWarnings = "Log Render Pipeline Warnings";
|
||||
const QString Preferences = "Preferences...";
|
||||
|
@ -250,8 +246,7 @@ namespace MenuOption {
|
|||
const QString ToolWindow = "Tool Window";
|
||||
const QString TransmitterDrive = "Transmitter Drive";
|
||||
const QString TurnWithHead = "Turn using Head";
|
||||
const QString PackageModel = "Package Model...";
|
||||
const QString Visage = "Visage";
|
||||
const QString UseAudioForMouth = "Use Audio for Mouth";
|
||||
const QString VisibleToEveryone = "Everyone";
|
||||
const QString VisibleToFriends = "Friends";
|
||||
const QString VisibleToNoOne = "No one";
|
||||
|
|
|
@ -76,12 +76,41 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
if (isMine) {
|
||||
MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
|
||||
|
||||
// Update audio trailing average for rendering facial animations
|
||||
const float AUDIO_AVERAGING_SECS = 0.05f;
|
||||
const float AUDIO_LONG_TERM_AVERAGING_SECS = 30.0f;
|
||||
_averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f));
|
||||
|
||||
if (_longTermAverageLoudness == -1.0) {
|
||||
_longTermAverageLoudness = _averageLoudness;
|
||||
} else {
|
||||
_longTermAverageLoudness = glm::mix(_longTermAverageLoudness, _averageLoudness, glm::min(deltaTime / AUDIO_LONG_TERM_AVERAGING_SECS, 1.0f));
|
||||
}
|
||||
|
||||
// Only use face trackers when not playing back a recording.
|
||||
if (!myAvatar->isPlaying()) {
|
||||
FaceTracker* faceTracker = Application::getInstance()->getActiveFaceTracker();
|
||||
_isFaceTrackerConnected = faceTracker != NULL;
|
||||
if (_isFaceTrackerConnected) {
|
||||
_blendshapeCoefficients = faceTracker->getBlendshapeCoefficients();
|
||||
|
||||
if (typeid(*faceTracker) == typeid(DdeFaceTracker)
|
||||
&& Menu::getInstance()->isOptionChecked(MenuOption::UseAudioForMouth)) {
|
||||
|
||||
calculateMouthShapes();
|
||||
|
||||
const int JAW_OPEN_BLENDSHAPE = 21;
|
||||
const int MMMM_BLENDSHAPE = 34;
|
||||
const int FUNNEL_BLENDSHAPE = 40;
|
||||
const int SMILE_LEFT_BLENDSHAPE = 28;
|
||||
const int SMILE_RIGHT_BLENDSHAPE = 29;
|
||||
_blendshapeCoefficients[JAW_OPEN_BLENDSHAPE] += _audioJawOpen;
|
||||
_blendshapeCoefficients[SMILE_LEFT_BLENDSHAPE] += _mouth4;
|
||||
_blendshapeCoefficients[SMILE_RIGHT_BLENDSHAPE] += _mouth4;
|
||||
_blendshapeCoefficients[MMMM_BLENDSHAPE] += _mouth2;
|
||||
_blendshapeCoefficients[FUNNEL_BLENDSHAPE] += _mouth3;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// Twist the upper body to follow the rotation of the head, but only do this with my avatar,
|
||||
|
@ -92,17 +121,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
setTorsoTwist(currentTwist + (getFinalYaw() * BODY_FOLLOW_HEAD_FACTOR - currentTwist) * BODY_FOLLOW_HEAD_YAW_RATE);
|
||||
}
|
||||
|
||||
// Update audio trailing average for rendering facial animations
|
||||
const float AUDIO_AVERAGING_SECS = 0.05f;
|
||||
const float AUDIO_LONG_TERM_AVERAGING_SECS = 30.0f;
|
||||
_averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f));
|
||||
|
||||
if (_longTermAverageLoudness == -1.0) {
|
||||
_longTermAverageLoudness = _averageLoudness;
|
||||
} else {
|
||||
_longTermAverageLoudness = glm::mix(_longTermAverageLoudness, _averageLoudness, glm::min(deltaTime / AUDIO_LONG_TERM_AVERAGING_SECS, 1.0f));
|
||||
}
|
||||
|
||||
if (!(_isFaceTrackerConnected || billboard)) {
|
||||
// Update eye saccades
|
||||
const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f;
|
||||
|
@ -177,33 +195,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
}
|
||||
|
||||
// use data to update fake Faceshift blendshape coefficients
|
||||
|
||||
const float JAW_OPEN_SCALE = 0.015f;
|
||||
const float JAW_OPEN_RATE = 0.9f;
|
||||
const float JAW_CLOSE_RATE = 0.90f;
|
||||
float audioDelta = sqrtf(glm::max(_averageLoudness - _longTermAverageLoudness, 0.0f)) * JAW_OPEN_SCALE;
|
||||
if (audioDelta > _audioJawOpen) {
|
||||
_audioJawOpen += (audioDelta - _audioJawOpen) * JAW_OPEN_RATE;
|
||||
} else {
|
||||
_audioJawOpen *= JAW_CLOSE_RATE;
|
||||
}
|
||||
_audioJawOpen = glm::clamp(_audioJawOpen, 0.0f, 1.0f);
|
||||
|
||||
// _mouth2 = "mmmm" shape
|
||||
// _mouth3 = "funnel" shape
|
||||
// _mouth4 = "smile" shape
|
||||
const float FUNNEL_PERIOD = 0.985f;
|
||||
const float FUNNEL_RANDOM_PERIOD = 0.01f;
|
||||
const float MMMM_POWER = 0.25f;
|
||||
const float MMMM_PERIOD = 0.91f;
|
||||
const float MMMM_RANDOM_PERIOD = 0.15f;
|
||||
const float SMILE_PERIOD = 0.925f;
|
||||
const float SMILE_RANDOM_PERIOD = 0.05f;
|
||||
|
||||
_mouth3 = glm::mix(_audioJawOpen, _mouth3, FUNNEL_PERIOD + randFloat() * FUNNEL_RANDOM_PERIOD);
|
||||
_mouth2 = glm::mix(_audioJawOpen * MMMM_POWER, _mouth2, MMMM_PERIOD + randFloat() * MMMM_RANDOM_PERIOD);
|
||||
_mouth4 = glm::mix(_audioJawOpen, _mouth4, SMILE_PERIOD + randFloat() * SMILE_RANDOM_PERIOD);
|
||||
|
||||
calculateMouthShapes();
|
||||
DependencyManager::get<Faceshift>()->updateFakeCoefficients(_leftEyeBlink,
|
||||
_rightEyeBlink,
|
||||
_browAudioLift,
|
||||
|
@ -230,6 +222,34 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) {
|
|||
|
||||
}
|
||||
|
||||
void Head::calculateMouthShapes() {
|
||||
const float JAW_OPEN_SCALE = 0.015f;
|
||||
const float JAW_OPEN_RATE = 0.9f;
|
||||
const float JAW_CLOSE_RATE = 0.90f;
|
||||
float audioDelta = sqrtf(glm::max(_averageLoudness - _longTermAverageLoudness, 0.0f)) * JAW_OPEN_SCALE;
|
||||
if (audioDelta > _audioJawOpen) {
|
||||
_audioJawOpen += (audioDelta - _audioJawOpen) * JAW_OPEN_RATE;
|
||||
} else {
|
||||
_audioJawOpen *= JAW_CLOSE_RATE;
|
||||
}
|
||||
_audioJawOpen = glm::clamp(_audioJawOpen, 0.0f, 1.0f);
|
||||
|
||||
// _mouth2 = "mmmm" shape
|
||||
// _mouth3 = "funnel" shape
|
||||
// _mouth4 = "smile" shape
|
||||
const float FUNNEL_PERIOD = 0.985f;
|
||||
const float FUNNEL_RANDOM_PERIOD = 0.01f;
|
||||
const float MMMM_POWER = 0.25f;
|
||||
const float MMMM_PERIOD = 0.91f;
|
||||
const float MMMM_RANDOM_PERIOD = 0.15f;
|
||||
const float SMILE_PERIOD = 0.925f;
|
||||
const float SMILE_RANDOM_PERIOD = 0.05f;
|
||||
|
||||
_mouth3 = glm::mix(_audioJawOpen, _mouth3, FUNNEL_PERIOD + randFloat() * FUNNEL_RANDOM_PERIOD);
|
||||
_mouth2 = glm::mix(_audioJawOpen * MMMM_POWER, _mouth2, MMMM_PERIOD + randFloat() * MMMM_RANDOM_PERIOD);
|
||||
_mouth4 = glm::mix(_audioJawOpen, _mouth4, SMILE_PERIOD + randFloat() * SMILE_RANDOM_PERIOD);
|
||||
}
|
||||
|
||||
void Head::relaxLean(float deltaTime) {
|
||||
// restore rotation, lean to neutral positions
|
||||
const float LEAN_RELAXATION_PERIOD = 0.25f; // seconds
|
||||
|
|
|
@ -154,6 +154,7 @@ private:
|
|||
|
||||
// private methods
|
||||
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
||||
void calculateMouthShapes();
|
||||
|
||||
friend class FaceModel;
|
||||
};
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include <QJsonObject>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#include "DdeFaceTracker.h"
|
||||
#include "FaceshiftConstants.h"
|
||||
#include "InterfaceLogging.h"
|
||||
|
@ -27,9 +29,9 @@ static const QHostAddress DDE_SERVER_ADDR("127.0.0.1");
|
|||
static const quint16 DDE_SERVER_PORT = 64204;
|
||||
static const quint16 DDE_CONTROL_PORT = 64205;
|
||||
#if defined(Q_OS_WIN)
|
||||
static const QString DDE_PROGRAM_PATH = QCoreApplication::applicationDirPath() + "/dde/dde.exe";
|
||||
static const QString DDE_PROGRAM_PATH = "/dde/dde.exe";
|
||||
#elif defined(Q_OS_MAC)
|
||||
static const QString DDE_PROGRAM_PATH = QCoreApplication::applicationDirPath() + "/dde.app/Contents/MacOS/dde";
|
||||
static const QString DDE_PROGRAM_PATH = "/dde.app/Contents/MacOS/dde";
|
||||
#endif
|
||||
static const QStringList DDE_ARGUMENTS = QStringList()
|
||||
<< "--udp=" + DDE_SERVER_ADDR.toString() + ":" + QString::number(DDE_SERVER_PORT)
|
||||
|
@ -132,6 +134,8 @@ struct Packet {
|
|||
char name[MAX_NAME_SIZE + 1];
|
||||
};
|
||||
|
||||
const float STARTING_DDE_MESSAGE_TIME = 0.033f;
|
||||
|
||||
DdeFaceTracker::DdeFaceTracker() :
|
||||
DdeFaceTracker(QHostAddress::Any, DDE_SERVER_PORT, DDE_CONTROL_PORT)
|
||||
{
|
||||
|
@ -157,11 +161,16 @@ DdeFaceTracker::DdeFaceTracker(const QHostAddress& host, quint16 serverPort, qui
|
|||
_mouthSmileLeftIndex(28),
|
||||
_mouthSmileRightIndex(29),
|
||||
_jawOpenIndex(21),
|
||||
_previousTranslation(glm::vec3()),
|
||||
_previousRotation(glm::quat())
|
||||
_lastMessageReceived(0),
|
||||
_averageMessageTime(STARTING_DDE_MESSAGE_TIME),
|
||||
_lastHeadTranslation(glm::vec3(0.0f)),
|
||||
_filteredHeadTranslation(glm::vec3(0.0f)),
|
||||
_lastLeftEyeBlink(0.0f),
|
||||
_filteredLeftEyeBlink(0.0f),
|
||||
_lastRightEyeBlink(0.0f),
|
||||
_filteredRightEyeBlink(0.0f)
|
||||
{
|
||||
_coefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||
_previousCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||
|
||||
_blendshapeCoefficients.resize(NUM_FACESHIFT_BLENDSHAPES);
|
||||
|
||||
|
@ -182,9 +191,10 @@ void DdeFaceTracker::setEnabled(bool enabled) {
|
|||
_udpSocket.bind(_host, _serverPort);
|
||||
}
|
||||
|
||||
const char* DDE_EXIT_COMMAND = "exit";
|
||||
|
||||
if (enabled && !_ddeProcess) {
|
||||
// Terminate any existing DDE process, perhaps left running after an Interface crash
|
||||
const char* DDE_EXIT_COMMAND = "exit";
|
||||
_udpSocket.writeDatagram(DDE_EXIT_COMMAND, DDE_SERVER_ADDR, _controlPort);
|
||||
|
||||
qDebug() << "[Info] DDE Face Tracker Starting";
|
||||
|
@ -194,7 +204,8 @@ void DdeFaceTracker::setEnabled(bool enabled) {
|
|||
}
|
||||
|
||||
if (!enabled && _ddeProcess) {
|
||||
_ddeProcess->kill(); // More robust than trying to send an "exit" command to DDE
|
||||
_udpSocket.writeDatagram(DDE_EXIT_COMMAND, DDE_SERVER_ADDR, _controlPort);
|
||||
delete _ddeProcess;
|
||||
_ddeProcess = NULL;
|
||||
qDebug() << "[Info] DDE Face Tracker Stopped";
|
||||
}
|
||||
|
@ -270,6 +281,8 @@ float DdeFaceTracker::getBlendshapeCoefficient(int index) const {
|
|||
|
||||
void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
||||
if(buffer.size() > MIN_PACKET_SIZE) {
|
||||
bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::DDEFiltering);
|
||||
|
||||
Packet packet;
|
||||
int bytesToCopy = glm::min((int)sizeof(packet), buffer.size());
|
||||
memset(&packet.name, '\n', MAX_NAME_SIZE + 1);
|
||||
|
@ -290,13 +303,36 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
translation -= _referenceTranslation;
|
||||
translation /= LEAN_DAMPING_FACTOR;
|
||||
translation.x *= -1;
|
||||
_headTranslation = (translation + _previousTranslation) / 2.0f;
|
||||
_previousTranslation = translation;
|
||||
if (isFiltering) {
|
||||
glm::vec3 linearVelocity = (translation - _lastHeadTranslation) / _averageMessageTime;
|
||||
const float LINEAR_VELOCITY_FILTER_STRENGTH = 0.3f;
|
||||
float velocityFilter = glm::clamp(1.0f - glm::length(linearVelocity) *
|
||||
LINEAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredHeadTranslation = velocityFilter * _filteredHeadTranslation + (1.0f - velocityFilter) * translation;
|
||||
_lastHeadTranslation = translation;
|
||||
_headTranslation = _filteredHeadTranslation;
|
||||
} else {
|
||||
_headTranslation = translation;
|
||||
}
|
||||
|
||||
// Compute relative rotation
|
||||
rotation = glm::inverse(_referenceRotation) * rotation;
|
||||
_headRotation = (rotation + _previousRotation) / 2.0f;
|
||||
_previousRotation = rotation;
|
||||
if (isFiltering) {
|
||||
glm::quat r = rotation * glm::inverse(_headRotation);
|
||||
float theta = 2 * acos(r.w);
|
||||
glm::vec3 angularVelocity;
|
||||
if (theta > EPSILON) {
|
||||
float rMag = glm::length(glm::vec3(r.x, r.y, r.z));
|
||||
angularVelocity = theta / _averageMessageTime * glm::vec3(r.x, r.y, r.z) / rMag;
|
||||
} else {
|
||||
angularVelocity = glm::vec3(0, 0, 0);
|
||||
}
|
||||
const float ANGULAR_VELOCITY_FILTER_STRENGTH = 0.3f;
|
||||
_headRotation = safeMix(_headRotation, rotation, glm::clamp(glm::length(angularVelocity) *
|
||||
ANGULAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f));
|
||||
} else {
|
||||
_headRotation = rotation;
|
||||
}
|
||||
|
||||
// Translate DDE coefficients to Faceshift compatible coefficients
|
||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
||||
|
@ -305,8 +341,23 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
|
||||
// Use EyeBlink values to control both EyeBlink and EyeOpen
|
||||
static const float RELAXED_EYE_VALUE = 0.1f;
|
||||
float leftEye = (_coefficients[_leftBlinkIndex] + _previousCoefficients[_leftBlinkIndex]) / 2.0f;
|
||||
float rightEye = (_coefficients[_rightBlinkIndex] + _previousCoefficients[_rightBlinkIndex]) / 2.0f;
|
||||
float leftEye = _coefficients[_leftBlinkIndex];
|
||||
float rightEye = _coefficients[_rightBlinkIndex];
|
||||
if (isFiltering) {
|
||||
const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
|
||||
|
||||
float velocity = fabs(leftEye - _lastLeftEyeBlink) / _averageMessageTime;
|
||||
float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredLeftEyeBlink = velocityFilter * leftEye + (1.0f - velocityFilter) * _filteredLeftEyeBlink;
|
||||
_lastLeftEyeBlink = leftEye;
|
||||
leftEye = _filteredLeftEyeBlink;
|
||||
|
||||
velocity = fabs(rightEye - _lastRightEyeBlink) / _averageMessageTime;
|
||||
velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
|
||||
_filteredRightEyeBlink = velocityFilter * rightEye + (1.0f - velocityFilter) * _filteredRightEyeBlink;
|
||||
_lastRightEyeBlink = rightEye;
|
||||
rightEye = _filteredRightEyeBlink;
|
||||
}
|
||||
if (leftEye > RELAXED_EYE_VALUE) {
|
||||
_coefficients[_leftBlinkIndex] = leftEye - RELAXED_EYE_VALUE;
|
||||
_coefficients[_leftEyeOpenIndex] = 0.0f;
|
||||
|
@ -341,10 +392,18 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
// Scale all coefficients
|
||||
for (int i = 0; i < NUM_EXPRESSIONS; i += 1) {
|
||||
_blendshapeCoefficients[i]
|
||||
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * (_coefficients[i] + _previousCoefficients[i]) / 2.0f, 0.0f, 1.0f);
|
||||
_previousCoefficients[i] = _coefficients[i];
|
||||
= glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
// Calculate average frame time
|
||||
const float FRAME_AVERAGING_FACTOR = 0.99f;
|
||||
quint64 usecsNow = usecTimestampNow();
|
||||
if (_lastMessageReceived != 0) {
|
||||
_averageMessageTime = FRAME_AVERAGING_FACTOR * _averageMessageTime
|
||||
+ (1.0f - FRAME_AVERAGING_FACTOR) * (float)(usecsNow - _lastMessageReceived) / 1000000.0f;
|
||||
}
|
||||
_lastMessageReceived = usecsNow;
|
||||
|
||||
} else {
|
||||
qCDebug(interfaceapp) << "[Error] DDE Face Tracker Decode Error";
|
||||
}
|
||||
|
|
|
@ -101,10 +101,14 @@ private:
|
|||
|
||||
QVector<float> _coefficients;
|
||||
|
||||
// Previous values for simple smoothing
|
||||
glm::vec3 _previousTranslation;
|
||||
glm::quat _previousRotation;
|
||||
QVector<float> _previousCoefficients;
|
||||
quint64 _lastMessageReceived;
|
||||
float _averageMessageTime;
|
||||
glm::vec3 _lastHeadTranslation;
|
||||
glm::vec3 _filteredHeadTranslation;
|
||||
float _lastLeftEyeBlink;
|
||||
float _filteredLeftEyeBlink;
|
||||
float _lastRightEyeBlink;
|
||||
float _filteredRightEyeBlink;
|
||||
};
|
||||
|
||||
#endif // hifi_DdeFaceTracker_h
|
|
@ -18,7 +18,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
/// Base class for face trackers (Faceshift, Visage, DDE).
|
||||
/// Base class for face trackers (Faceshift, DDE).
|
||||
class FaceTracker : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
@ -1,191 +0,0 @@
|
|||
//
|
||||
// Visage.cpp
|
||||
// interface/src/devices
|
||||
//
|
||||
// Created by Andrzej Kapolka on 2/11/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QHash>
|
||||
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <FBXReader.h>
|
||||
#include <PathUtils.h>
|
||||
#include <PerfStat.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Faceshift.h"
|
||||
#include "Visage.h"
|
||||
|
||||
// this has to go after our normal includes, because its definition of HANDLE conflicts with Qt's
|
||||
#ifdef HAVE_VISAGE
|
||||
#include <VisageTracker2.h>
|
||||
#endif
|
||||
|
||||
namespace VisageSDK {
|
||||
#ifdef WIN32
|
||||
void __declspec(dllimport) initializeLicenseManager(char* licenseKeyFileName);
|
||||
#else
|
||||
void initializeLicenseManager(char* licenseKeyFileName);
|
||||
#endif
|
||||
}
|
||||
|
||||
using namespace VisageSDK;
|
||||
|
||||
const glm::vec3 DEFAULT_HEAD_ORIGIN(0.0f, 0.0f, 0.7f);
|
||||
|
||||
Visage::Visage() :
|
||||
_enabled(false),
|
||||
_headOrigin(DEFAULT_HEAD_ORIGIN) {
|
||||
|
||||
#ifdef HAVE_VISAGE
|
||||
#ifdef WIN32
|
||||
QByteArray licensePath = PathUtils::resourcesPath().toLatin1() + "visage";
|
||||
#else
|
||||
QByteArray licensePath = PathUtils::resourcesPath().toLatin1() + "visage/license.vlc";
|
||||
#endif
|
||||
initializeLicenseManager(licensePath.data());
|
||||
_tracker = new VisageTracker2(PathUtils::resourcesPath().toLatin1() + "visage/tracker.cfg");
|
||||
_data = new FaceData();
|
||||
#endif
|
||||
}
|
||||
|
||||
Visage::~Visage() {
|
||||
#ifdef HAVE_VISAGE
|
||||
_tracker->stop();
|
||||
// deleting the tracker crashes windows; disable for now
|
||||
//delete _tracker;
|
||||
delete _data;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_VISAGE
|
||||
static int leftEyeBlinkIndex = 0;
|
||||
static int rightEyeBlinkIndex = 1;
|
||||
|
||||
static QMultiHash<QByteArray, QPair<int, float> > createActionUnitNameMap() {
|
||||
QMultiHash<QByteArray, QPair<QByteArray, float> > blendshapeMap;
|
||||
blendshapeMap.insert("JawFwd", QPair<QByteArray, float>("au_jaw_z_push", 1.0f));
|
||||
blendshapeMap.insert("JawLeft", QPair<QByteArray, float>("au_jaw_x_push", 1.0f));
|
||||
blendshapeMap.insert("JawOpen", QPair<QByteArray, float>("au_jaw_drop", 1.0f));
|
||||
blendshapeMap.insert("LipsLowerDown", QPair<QByteArray, float>("au_lower_lip_drop", 1.0f));
|
||||
blendshapeMap.insert("LipsUpperOpen", QPair<QByteArray, float>("au_upper_lip_raiser", 1.0f));
|
||||
blendshapeMap.insert("LipsStretch_R", QPair<QByteArray, float>("au_lip_stretcher_left", 0.5f));
|
||||
blendshapeMap.insert("MouthSmile_L", QPair<QByteArray, float>("au_lip_corner_depressor", -1.0f));
|
||||
blendshapeMap.insert("MouthSmile_R", QPair<QByteArray, float>("au_lip_corner_depressor", -1.0f));
|
||||
blendshapeMap.insert("BrowsU_R", QPair<QByteArray, float>("au_left_outer_brow_raiser", 1.0f));
|
||||
blendshapeMap.insert("BrowsU_C", QPair<QByteArray, float>("au_left_inner_brow_raiser", 1.0f));
|
||||
blendshapeMap.insert("BrowsD_R", QPair<QByteArray, float>("au_left_brow_lowerer", 1.0f));
|
||||
blendshapeMap.insert("EyeBlink_L", QPair<QByteArray, float>("au_leye_closed", 1.0f));
|
||||
blendshapeMap.insert("EyeBlink_R", QPair<QByteArray, float>("au_reye_closed", 1.0f));
|
||||
blendshapeMap.insert("EyeOpen_L", QPair<QByteArray, float>("au_upper_lid_raiser", 1.0f));
|
||||
blendshapeMap.insert("EyeOpen_R", QPair<QByteArray, float>("au_upper_lid_raiser", 1.0f));
|
||||
blendshapeMap.insert("LipLowerOpen", QPair<QByteArray, float>("au_lower_lip_x_push", 1.0f));
|
||||
blendshapeMap.insert("LipsStretch_L", QPair<QByteArray, float>("au_lip_stretcher_right", 0.5f));
|
||||
blendshapeMap.insert("BrowsU_L", QPair<QByteArray, float>("au_right_outer_brow_raiser", 1.0f));
|
||||
blendshapeMap.insert("BrowsU_C", QPair<QByteArray, float>("au_right_inner_brow_raiser", 1.0f));
|
||||
blendshapeMap.insert("BrowsD_L", QPair<QByteArray, float>("au_right_brow_lowerer", 1.0f));
|
||||
|
||||
QMultiHash<QByteArray, QPair<int, float> > actionUnitNameMap;
|
||||
for (int i = 0;; i++) {
|
||||
QByteArray blendshape = FACESHIFT_BLENDSHAPES[i];
|
||||
if (blendshape.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
if (blendshape == "EyeBlink_L") {
|
||||
leftEyeBlinkIndex = i;
|
||||
|
||||
} else if (blendshape == "EyeBlink_R") {
|
||||
rightEyeBlinkIndex = i;
|
||||
}
|
||||
for (QMultiHash<QByteArray, QPair<QByteArray, float> >::const_iterator it = blendshapeMap.constFind(blendshape);
|
||||
it != blendshapeMap.constEnd() && it.key() == blendshape; it++) {
|
||||
actionUnitNameMap.insert(it.value().first, QPair<int, float>(i, it.value().second));
|
||||
}
|
||||
}
|
||||
|
||||
return actionUnitNameMap;
|
||||
}
|
||||
|
||||
static const QMultiHash<QByteArray, QPair<int, float> >& getActionUnitNameMap() {
|
||||
static QMultiHash<QByteArray, QPair<int, float> > actionUnitNameMap = createActionUnitNameMap();
|
||||
return actionUnitNameMap;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_VISAGE
|
||||
const float TRANSLATION_SCALE = 20.0f;
|
||||
void Visage::init() {
|
||||
connect(DependencyManager::get<Faceshift>().data(), SIGNAL(connectionStateChanged()), SLOT(updateEnabled()));
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
void Visage::update(float deltaTime) {
|
||||
if (!isActive()) {
|
||||
return;
|
||||
}
|
||||
FaceTracker::update(deltaTime);
|
||||
|
||||
_headRotation = glm::quat(glm::vec3(-_data->faceRotation[0], -_data->faceRotation[1], _data->faceRotation[2]));
|
||||
_headTranslation = (glm::vec3(_data->faceTranslation[0], _data->faceTranslation[1], _data->faceTranslation[2]) -
|
||||
_headOrigin) * TRANSLATION_SCALE;
|
||||
_estimatedEyePitch = glm::degrees(-_data->gazeDirection[1]);
|
||||
_estimatedEyeYaw = glm::degrees(-_data->gazeDirection[0]);
|
||||
|
||||
if (_actionUnitIndexMap.isEmpty()) {
|
||||
int maxIndex = -1;
|
||||
for (int i = 0; i < _data->actionUnitCount; i++) {
|
||||
QByteArray name = _data->actionUnitsNames[i];
|
||||
for (QMultiHash<QByteArray, QPair<int, float> >::const_iterator it = getActionUnitNameMap().constFind(name);
|
||||
it != getActionUnitNameMap().constEnd() && it.key() == name; it++) {
|
||||
_actionUnitIndexMap.insert(i, it.value());
|
||||
maxIndex = qMax(maxIndex, it.value().first);
|
||||
}
|
||||
}
|
||||
_blendshapeCoefficients.resize(maxIndex + 1);
|
||||
}
|
||||
|
||||
qFill(_blendshapeCoefficients.begin(), _blendshapeCoefficients.end(), 0.0f);
|
||||
for (int i = 0; i < _data->actionUnitCount; i++) {
|
||||
if (!_data->actionUnitsUsed[i]) {
|
||||
continue;
|
||||
}
|
||||
for (QMultiHash<int, QPair<int, float> >::const_iterator it = _actionUnitIndexMap.constFind(i);
|
||||
it != _actionUnitIndexMap.constEnd() && it.key() == i; it++) {
|
||||
_blendshapeCoefficients[it.value().first] += _data->actionUnits[i] * it.value().second;
|
||||
}
|
||||
}
|
||||
_blendshapeCoefficients[leftEyeBlinkIndex] = 1.0f - _data->eyeClosure[1];
|
||||
_blendshapeCoefficients[rightEyeBlinkIndex] = 1.0f - _data->eyeClosure[0];
|
||||
}
|
||||
|
||||
void Visage::reset() {
|
||||
_headOrigin += _headTranslation / TRANSLATION_SCALE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Visage::updateEnabled() {
|
||||
setEnabled(Menu::getInstance()->isOptionChecked(MenuOption::Visage) &&
|
||||
!(Menu::getInstance()->isOptionChecked(MenuOption::Faceshift) &&
|
||||
DependencyManager::get<Faceshift>()->isConnectedOrConnecting()) &&
|
||||
!Menu::getInstance()->isOptionChecked(MenuOption::DDEFaceRegression));
|
||||
}
|
||||
|
||||
void Visage::setEnabled(bool enabled) {
|
||||
#ifdef HAVE_VISAGE
|
||||
if (_enabled == enabled) {
|
||||
return;
|
||||
}
|
||||
if ((_enabled = enabled)) {
|
||||
_tracker->trackFromCam();
|
||||
} else {
|
||||
_tracker->stop();
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
//
|
||||
// Visage.h
|
||||
// interface/src/devices
|
||||
//
|
||||
// Created by Andrzej Kapolka on 2/11/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_Visage_h
|
||||
#define hifi_Visage_h
|
||||
|
||||
#include <QMultiHash>
|
||||
#include <QPair>
|
||||
#include <QVector>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include "FaceTracker.h"
|
||||
|
||||
namespace VisageSDK {
|
||||
class VisageTracker2;
|
||||
struct FaceData;
|
||||
}
|
||||
|
||||
/// Handles input from the Visage webcam feature tracking software.
|
||||
class Visage : public FaceTracker, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
#ifdef HAVE_VISAGE
|
||||
virtual void init();
|
||||
virtual void update(float deltaTime);
|
||||
virtual void reset();
|
||||
|
||||
virtual bool isActive() const { return _tracker->getTrackingData(_data) == TRACK_STAT_OK; }
|
||||
virtual bool isTracking() const { return isActive(); }
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void updateEnabled();
|
||||
|
||||
private:
|
||||
Visage();
|
||||
virtual ~Visage();
|
||||
|
||||
#ifdef HAVE_VISAGE
|
||||
VisageSDK::VisageTracker2* _tracker;
|
||||
VisageSDK::FaceData* _data;
|
||||
QMultiHash<int, QPair<int, float> > _actionUnitIndexMap;
|
||||
#endif
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
bool _enabled;
|
||||
|
||||
glm::vec3 _headOrigin;
|
||||
};
|
||||
|
||||
#endif // hifi_Visage_h
|
|
@ -1705,7 +1705,12 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
material._material->setDiffuse(material.diffuse);
|
||||
material._material->setSpecular(material.specular);
|
||||
material._material->setShininess(material.shininess);
|
||||
material._material->setOpacity(material.opacity);
|
||||
|
||||
if (material.opacity <= 0.0f) {
|
||||
material._material->setOpacity(1.0f);
|
||||
} else {
|
||||
material._material->setOpacity(material.opacity);
|
||||
}
|
||||
|
||||
materials.insert(material.id, material);
|
||||
|
||||
|
|
|
@ -64,6 +64,10 @@ void Light::setIntensity(float intensity) {
|
|||
editSchema()._intensity = intensity;
|
||||
}
|
||||
|
||||
void Light::setAmbientIntensity(float intensity) {
|
||||
editSchema()._ambientIntensity = intensity;
|
||||
}
|
||||
|
||||
void Light::setMaximumRadius(float radius) {
|
||||
if (radius <= 0.f) {
|
||||
radius = 1.0f;
|
||||
|
|
|
@ -244,6 +244,10 @@ public:
|
|||
void setShowContour(float show);
|
||||
float getShowContour() const { return getSchema()._control.w; }
|
||||
|
||||
// If the light has an ambient (Indirect) component, then the Ambientintensity can be used to control its contribution to the lighting
|
||||
void setAmbientIntensity(float intensity);
|
||||
float getAmbientIntensity() const { return getSchema()._ambientIntensity; }
|
||||
|
||||
// Spherical Harmonics storing the Ambien lighting approximation used for the Sun typed light
|
||||
void setAmbientSphere(const SphericalHarmonics& sphere) { _ambientSphere = sphere; }
|
||||
const SphericalHarmonics& getAmbientSphere() const { return _ambientSphere; }
|
||||
|
@ -254,14 +258,14 @@ public:
|
|||
public:
|
||||
Vec4 _position{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
Vec3 _direction{0.0f, 0.0f, -1.0f};
|
||||
float _spare0{0.0f};
|
||||
float _ambientIntensity{0.0f};
|
||||
Color _color{1.0f};
|
||||
float _intensity{1.0f};
|
||||
Vec4 _attenuation{1.0f};
|
||||
Vec4 _spot{0.0f, 0.0f, 0.0f, 3.0f};
|
||||
Vec4 _shadow{0.0f};
|
||||
|
||||
Vec4 _control{0.0f};
|
||||
Vec4 _control{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
Schema() {}
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ vec3 getLightDirection(Light l) { return l._direction.xyz; } // direction is -Z
|
|||
|
||||
vec3 getLightColor(Light l) { return l._color.rgb; }
|
||||
float getLightIntensity(Light l) { return l._color.w; }
|
||||
float getLightAmbientIntensity(Light l) { return l._direction.w; }
|
||||
|
||||
float evalLightAttenuation(Light l, float r) {
|
||||
float d = max(r - l._attenuation.x, 0.0);
|
||||
|
|
|
@ -203,6 +203,7 @@ SunSkyStage::SunSkyStage() :
|
|||
_sunLight->setType(Light::SUN);
|
||||
|
||||
setSunIntensity(1.0f);
|
||||
setSunAmbientIntensity(0.5f);
|
||||
setSunColor(Vec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
// Default origin location is a special place in the world...
|
||||
|
@ -249,12 +250,26 @@ void SunSkyStage::setOriginLocation(float longitude, float latitude, float altit
|
|||
invalidate();
|
||||
}
|
||||
|
||||
void SunSkyStage::setSunModelEnable(bool isEnabled) {
|
||||
_sunModelEnable = isEnabled;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void SunSkyStage::setSunColor(const Vec3& color) {
|
||||
_sunLight->setColor(color);
|
||||
}
|
||||
void SunSkyStage::setSunIntensity(float intensity) {
|
||||
_sunLight->setIntensity(intensity);
|
||||
}
|
||||
void SunSkyStage::setSunAmbientIntensity(float intensity) {
|
||||
_sunLight->setAmbientIntensity(intensity);
|
||||
}
|
||||
|
||||
void SunSkyStage::setSunDirection(const Vec3& direction) {
|
||||
if (!isSunModelEnabled()) {
|
||||
_sunLight->setDirection(direction);
|
||||
}
|
||||
}
|
||||
|
||||
// THe sun declinaison calculus is taken from https://en.wikipedia.org/wiki/Position_of_the_Sun
|
||||
double evalSunDeclinaison(double dayNumber) {
|
||||
|
@ -271,19 +286,19 @@ void SunSkyStage::updateGraphicsObject() const {
|
|||
// And update the sunLAtitude as the declinaison depending of the time of the year
|
||||
_earthSunModel.setSunLatitude(evalSunDeclinaison(_yearTime));
|
||||
|
||||
Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir();
|
||||
_sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z));
|
||||
if (isSunModelEnabled()) {
|
||||
Vec3d sunLightDir = -_earthSunModel.getSurfaceSunDir();
|
||||
_sunLight->setDirection(Vec3(sunLightDir.x, sunLightDir.y, sunLightDir.z));
|
||||
|
||||
double originAlt = _earthSunModel.getAltitude();
|
||||
_sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f));
|
||||
double originAlt = _earthSunModel.getAltitude();
|
||||
_sunLight->setPosition(Vec3(0.0f, originAlt, 0.0f));
|
||||
}
|
||||
|
||||
static int firstTime = 0;
|
||||
if (firstTime == 0) {
|
||||
firstTime++;
|
||||
gpu::Shader::makeProgram(*(_skyPipeline->getProgram()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SunSkyStage::setSkybox(const SkyboxPointer& skybox) {
|
||||
|
|
|
@ -203,12 +203,22 @@ public:
|
|||
float getOriginLongitude() const { return _earthSunModel.getLongitude(); }
|
||||
float getOriginSurfaceAltitude() const { return _earthSunModel.getAltitude(); }
|
||||
|
||||
// Enable / disable the effect of the time and location on the sun direction and color
|
||||
void setSunModelEnable(bool isEnabled);
|
||||
bool isSunModelEnabled() const { return _sunModelEnable; }
|
||||
|
||||
// Sun properties
|
||||
void setSunColor(const Vec3& color);
|
||||
const Vec3& getSunColor() const { return getSunLight()->getColor(); }
|
||||
void setSunIntensity(float intensity);
|
||||
float getSunIntensity() const { return getSunLight()->getIntensity(); }
|
||||
void setSunAmbientIntensity(float intensity);
|
||||
float getSunAmbientIntensity() const { return getSunLight()->getAmbientIntensity(); }
|
||||
|
||||
// The sun direction is expressed in the world space
|
||||
void setSunDirection(const Vec3& direction);
|
||||
const Vec3& getSunDirection() const { return getSunLight()->getDirection(); }
|
||||
|
||||
LightPointer getSunLight() const { valid(); return _sunLight; }
|
||||
AtmospherePointer getAtmosphere() const { valid(); return _atmosphere; }
|
||||
|
||||
|
@ -223,10 +233,10 @@ protected:
|
|||
|
||||
gpu::PipelinePointer _skyPipeline;
|
||||
|
||||
float _dayTime;
|
||||
int _yearTime;
|
||||
|
||||
float _dayTime = 12.0f;
|
||||
int _yearTime = 0;
|
||||
mutable EarthSunModel _earthSunModel;
|
||||
bool _sunModelEnable = true;
|
||||
|
||||
mutable bool _invalid = true;
|
||||
void invalidate() const { _invalid = true; }
|
||||
|
|
|
@ -366,7 +366,7 @@ void AccountManager::setAccessTokenForCurrentAuthURL(const QString& accessToken)
|
|||
OAuthAccessToken newOAuthToken;
|
||||
newOAuthToken.token = accessToken;
|
||||
|
||||
qCDebug(networking) << "Setting new account manager access token to" << accessToken;
|
||||
qCDebug(networking) << "Setting new account manager access token. F2C:" << accessToken.left(2) << "L2C:" << accessToken.right(2);
|
||||
|
||||
_accountInfo.setAccessToken(newOAuthToken);
|
||||
}
|
||||
|
|
|
@ -12,4 +12,16 @@ add_dependency_external_projects(glm)
|
|||
find_package(GLM REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
if (USE_NSIGHT)
|
||||
# try to find the Nsight package and add it to the build if we find it
|
||||
find_package(NSIGHT)
|
||||
if (NSIGHT_FOUND)
|
||||
include_directories(${NSIGHT_INCLUDE_DIRS})
|
||||
add_definitions(-DNSIGHT_FOUND)
|
||||
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
|
||||
endif ()
|
||||
endif()
|
||||
endif (WIN32)
|
||||
|
||||
link_hifi_libraries(animation fbx shared gpu)
|
|
@ -66,7 +66,7 @@ vec3 evalAmbienGlobalColor(float shadowAttenuation, vec3 position, vec3 normal,
|
|||
vec4 fragEyeVector = invViewMat * vec4(-position, 0.0);
|
||||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
vec3 color = diffuse.rgb * getLightColor(light) * 0.5;
|
||||
vec3 color = diffuse.rgb * getLightColor(light) * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
|
@ -83,7 +83,7 @@ vec3 evalAmbienSphereGlobalColor(float shadowAttenuation, vec3 position, vec3 no
|
|||
vec3 fragEyeDir = normalize(fragEyeVector.xyz);
|
||||
|
||||
vec3 ambientNormal = fragNormal.xyz;
|
||||
vec3 color = diffuse.rgb * 0.5 * evalSphericalLight(ambientSphere, ambientNormal).xyz;
|
||||
vec3 color = diffuse.rgb * evalSphericalLight(ambientSphere, ambientNormal).xyz * getLightAmbientIntensity(light);
|
||||
|
||||
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
|
||||
|
||||
|
@ -112,7 +112,7 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve
|
|||
vec3 diffuseLight = lightAttenuation * lightmap;
|
||||
|
||||
// ambient is a tiny percentage of the lightmap and only when in the shadow
|
||||
vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap;
|
||||
vec3 ambientLight = (1 - lightAttenuation) * lightmap * getLightAmbientIntensity(light);
|
||||
|
||||
return diffuse * (ambientLight + diffuseLight);
|
||||
}
|
||||
|
|
|
@ -554,11 +554,12 @@ void DeferredLightingEffect::setAmbientLightMode(int preset) {
|
|||
}
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity) {
|
||||
void DeferredLightingEffect::setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity, float ambientIntensity) {
|
||||
auto light = _allocatedLights.front();
|
||||
light->setDirection(direction);
|
||||
light->setColor(diffuse);
|
||||
light->setIntensity(intensity);
|
||||
light->setAmbientIntensity(ambientIntensity);
|
||||
}
|
||||
|
||||
void DeferredLightingEffect::setGlobalSkybox(const model::SkyboxPointer& skybox) {
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
|
||||
// update global lighting
|
||||
void setAmbientLightMode(int preset);
|
||||
void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity);
|
||||
void setGlobalLight(const glm::vec3& direction, const glm::vec3& diffuse, float intensity, float ambientIntensity);
|
||||
void setGlobalAtmosphere(const model::AtmospherePointer& atmosphere) { _atmosphere = atmosphere; }
|
||||
|
||||
void setGlobalSkybox(const model::SkyboxPointer& skybox);
|
||||
|
|
|
@ -244,13 +244,6 @@ void Model::initJointTransforms() {
|
|||
|
||||
void Model::init() {
|
||||
if (_renderPipelineLib.empty()) {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("materialBuffer"), MATERIAL_GPU_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("diffuseMap"), 0));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("emissiveMap"), 3));
|
||||
|
||||
// Vertex shaders
|
||||
auto modelVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_vert)));
|
||||
auto modelNormalMapVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(model_normal_map_vert)));
|
||||
|
@ -291,10 +284,24 @@ void Model::init() {
|
|||
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_TRANSLUCENT),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::HAS_LIGHTMAP),
|
||||
modelLightmapVertex, modelLightmapPixel);
|
||||
|
@ -310,6 +317,7 @@ void Model::init() {
|
|||
RenderKey(RenderKey::HAS_LIGHTMAP | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_SKINNED),
|
||||
skinModelVertex, modelPixel);
|
||||
|
@ -326,15 +334,29 @@ void Model::init() {
|
|||
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR),
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_TRANSLUCENT),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::IS_TRANSLUCENT),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::HAS_TANGENTS | RenderKey::HAS_SPECULAR | RenderKey::IS_TRANSLUCENT),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
|
||||
modelShadowVertex, modelShadowPixel);
|
||||
|
||||
|
||||
_renderPipelineLib.addRenderPipeline(
|
||||
RenderKey(RenderKey::IS_SKINNED | RenderKey::IS_DEPTH_ONLY | RenderKey::IS_SHADOW),
|
||||
skinModelShadowVertex, modelShadowPixel);
|
||||
|
@ -1732,6 +1754,12 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) {
|
|||
void Model::endScene(RenderMode mode, RenderArgs* args) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
|
||||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY)
|
||||
// with legacy transform profile, we still to protect that transform stack...
|
||||
glPushMatrix();
|
||||
#endif
|
||||
|
||||
RenderArgs::RenderSide renderSide = RenderArgs::MONO;
|
||||
if (args) {
|
||||
renderSide = args->_renderSide;
|
||||
|
@ -1899,6 +1927,12 @@ void Model::endScene(RenderMode mode, RenderArgs* args) {
|
|||
backend.render(_sceneRenderBatch);
|
||||
}
|
||||
|
||||
|
||||
#if (GPU_TRANSFORM_PROFILE == GPU_LEGACY)
|
||||
// with legacy transform profile, we still to protect that transform stack...
|
||||
glPopMatrix();
|
||||
#endif
|
||||
|
||||
// restore all the default material settings
|
||||
_viewState->setupWorldLight();
|
||||
|
||||
|
@ -1935,55 +1969,7 @@ bool Model::renderInScene(float alpha, RenderArgs* args) {
|
|||
}
|
||||
|
||||
void Model::segregateMeshGroups() {
|
||||
_meshesTranslucentTangents.clear();
|
||||
_meshesTranslucent.clear();
|
||||
_meshesTranslucentTangentsSpecular.clear();
|
||||
_meshesTranslucentSpecular.clear();
|
||||
|
||||
_meshesTranslucentTangentsSkinned.clear();
|
||||
_meshesTranslucentSkinned.clear();
|
||||
_meshesTranslucentTangentsSpecularSkinned.clear();
|
||||
_meshesTranslucentSpecularSkinned.clear();
|
||||
|
||||
_meshesOpaqueTangents.clear();
|
||||
_meshesOpaque.clear();
|
||||
_meshesOpaqueTangentsSpecular.clear();
|
||||
_meshesOpaqueSpecular.clear();
|
||||
|
||||
_meshesOpaqueTangentsSkinned.clear();
|
||||
_meshesOpaqueSkinned.clear();
|
||||
_meshesOpaqueTangentsSpecularSkinned.clear();
|
||||
_meshesOpaqueSpecularSkinned.clear();
|
||||
|
||||
_meshesOpaqueLightmapTangents.clear();
|
||||
_meshesOpaqueLightmap.clear();
|
||||
_meshesOpaqueLightmapTangentsSpecular.clear();
|
||||
_meshesOpaqueLightmapSpecular.clear();
|
||||
|
||||
_unsortedMeshesTranslucentTangents.clear();
|
||||
_unsortedMeshesTranslucent.clear();
|
||||
_unsortedMeshesTranslucentTangentsSpecular.clear();
|
||||
_unsortedMeshesTranslucentSpecular.clear();
|
||||
|
||||
_unsortedMeshesTranslucentTangentsSkinned.clear();
|
||||
_unsortedMeshesTranslucentSkinned.clear();
|
||||
_unsortedMeshesTranslucentTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesTranslucentSpecularSkinned.clear();
|
||||
|
||||
_unsortedMeshesOpaqueTangents.clear();
|
||||
_unsortedMeshesOpaque.clear();
|
||||
_unsortedMeshesOpaqueTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueSpecular.clear();
|
||||
|
||||
_unsortedMeshesOpaqueTangentsSkinned.clear();
|
||||
_unsortedMeshesOpaqueSkinned.clear();
|
||||
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueSpecularSkinned.clear();
|
||||
|
||||
_unsortedMeshesOpaqueLightmapTangents.clear();
|
||||
_unsortedMeshesOpaqueLightmap.clear();
|
||||
_unsortedMeshesOpaqueLightmapTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueLightmapSpecular.clear();
|
||||
_renderBuckets.clear();
|
||||
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||
|
@ -2017,201 +2003,19 @@ void Model::segregateMeshGroups() {
|
|||
qCDebug(renderutils) << "materialID:" << materialID << "parts:" << mesh.parts.size();
|
||||
}
|
||||
|
||||
if (!hasLightmap) {
|
||||
if (translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
RenderKey key(translucentMesh, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
||||
_unsortedMeshesTranslucent.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentTangents.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentTangentsSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && hasTangents && !hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentTangentsSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && hasTangents && hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentTangentsSpecularSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (translucentMesh && !hasTangents && hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesTranslucentSpecularSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaque.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueTangents.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueTangentsSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && !hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueTangentsSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueTangentsSpecularSkinned.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && hasSpecular && isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueSpecularSkinned.insertMulti(materialID, i);
|
||||
} else {
|
||||
qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???";
|
||||
}
|
||||
} else {
|
||||
if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueLightmap.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueLightmapTangents.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueLightmapTangentsSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
|
||||
|
||||
_unsortedMeshesOpaqueLightmapSpecular.insertMulti(materialID, i);
|
||||
|
||||
} else {
|
||||
qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???";
|
||||
}
|
||||
}
|
||||
// reuse or create the bucket corresponding to that key and insert the mesh as unsorted
|
||||
_renderBuckets[key.getRaw()]._unsortedMeshes.insertMulti(materialID, i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucent) {
|
||||
_meshesTranslucent.append(i);
|
||||
for(auto& b : _renderBuckets) {
|
||||
foreach(auto i, b.second._unsortedMeshes) {
|
||||
b.second._meshes.append(i);
|
||||
b.second._unsortedMeshes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentTangents) {
|
||||
_meshesTranslucentTangents.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentTangentsSpecular) {
|
||||
_meshesTranslucentTangentsSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentSpecular) {
|
||||
_meshesTranslucentSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentSkinned) {
|
||||
_meshesTranslucentSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentTangentsSkinned) {
|
||||
_meshesTranslucentTangentsSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentTangentsSpecularSkinned) {
|
||||
_meshesTranslucentTangentsSpecularSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesTranslucentSpecularSkinned) {
|
||||
_meshesTranslucentSpecularSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaque) {
|
||||
_meshesOpaque.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueTangents) {
|
||||
_meshesOpaqueTangents.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueTangentsSpecular) {
|
||||
_meshesOpaqueTangentsSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueSpecular) {
|
||||
_meshesOpaqueSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueSkinned) {
|
||||
_meshesOpaqueSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueTangentsSkinned) {
|
||||
_meshesOpaqueTangentsSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueTangentsSpecularSkinned) {
|
||||
_meshesOpaqueTangentsSpecularSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueSpecularSkinned) {
|
||||
_meshesOpaqueSpecularSkinned.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmap) {
|
||||
_meshesOpaqueLightmap.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmapTangents) {
|
||||
_meshesOpaqueLightmapTangents.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmapTangentsSpecular) {
|
||||
_meshesOpaqueLightmapTangentsSpecular.append(i);
|
||||
}
|
||||
|
||||
foreach(int i, _unsortedMeshesOpaqueLightmapSpecular) {
|
||||
_meshesOpaqueLightmapSpecular.append(i);
|
||||
}
|
||||
|
||||
_unsortedMeshesTranslucentTangents.clear();
|
||||
_unsortedMeshesTranslucent.clear();
|
||||
_unsortedMeshesTranslucentTangentsSpecular.clear();
|
||||
_unsortedMeshesTranslucentSpecular.clear();
|
||||
|
||||
_unsortedMeshesTranslucentTangentsSkinned.clear();
|
||||
_unsortedMeshesTranslucentSkinned.clear();
|
||||
_unsortedMeshesTranslucentTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesTranslucentSpecularSkinned.clear();
|
||||
|
||||
_unsortedMeshesOpaqueTangents.clear();
|
||||
_unsortedMeshesOpaque.clear();
|
||||
_unsortedMeshesOpaqueTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueSpecular.clear();
|
||||
|
||||
_unsortedMeshesOpaqueTangentsSkinned.clear();
|
||||
_unsortedMeshesOpaqueSkinned.clear();
|
||||
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
|
||||
_unsortedMeshesOpaqueSpecularSkinned.clear();
|
||||
|
||||
_unsortedMeshesOpaqueLightmapTangents.clear();
|
||||
_unsortedMeshesOpaqueLightmap.clear();
|
||||
_unsortedMeshesOpaqueLightmapTangentsSpecular.clear();
|
||||
_unsortedMeshesOpaqueLightmapSpecular.clear();
|
||||
|
||||
_meshGroupsKnown = true;
|
||||
}
|
||||
|
||||
|
@ -2220,52 +2024,14 @@ QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool h
|
|||
|
||||
// depending on which parameters we were called with, pick the correct mesh group to render
|
||||
QVector<int>* whichList = NULL;
|
||||
if (translucent && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesTranslucent;
|
||||
} else if (translucent && hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesTranslucentTangents;
|
||||
} else if (translucent && hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesTranslucentTangentsSpecular;
|
||||
} else if (translucent && !hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesTranslucentSpecular;
|
||||
} else if (translucent && hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesTranslucentTangentsSkinned;
|
||||
} else if (translucent && !hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesTranslucentSkinned;
|
||||
} else if (translucent && hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesTranslucentTangentsSpecularSkinned;
|
||||
} else if (translucent && !hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesTranslucentSpecularSkinned;
|
||||
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaque;
|
||||
} else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueTangents;
|
||||
} else if (!translucent && !hasLightmap && hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueTangentsSpecular;
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueSpecular;
|
||||
} else if (!translucent && !hasLightmap && hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueTangentsSkinned;
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && !hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueSkinned;
|
||||
} else if (!translucent && !hasLightmap && hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueTangentsSpecularSkinned;
|
||||
} else if (!translucent && !hasLightmap && !hasTangents && hasSpecular && isSkinned) {
|
||||
whichList = &_meshesOpaqueSpecularSkinned;
|
||||
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
||||
} else if (!translucent && hasLightmap && !hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmap;
|
||||
} else if (!translucent && hasLightmap && hasTangents && !hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmapTangents;
|
||||
} else if (!translucent && hasLightmap && hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmapTangentsSpecular;
|
||||
} else if (!translucent && hasLightmap && !hasTangents && hasSpecular && !isSkinned) {
|
||||
whichList = &_meshesOpaqueLightmapSpecular;
|
||||
|
||||
} else {
|
||||
qCDebug(renderutils) << "unexpected!!! this mesh didn't fall into any or our groups???";
|
||||
auto bucket = _renderBuckets.find(key.getRaw());
|
||||
if (bucket != _renderBuckets.end()) {
|
||||
whichList = &(*bucket).second._meshes;
|
||||
}
|
||||
|
||||
return whichList;
|
||||
}
|
||||
|
||||
|
@ -2277,6 +2043,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
|
|||
auto pipeline = _renderPipelineLib.find(key.getRaw());
|
||||
if (pipeline == _renderPipelineLib.end()) {
|
||||
qDebug() << "No good, couldn't find a pipeline from the key ?" << key.getRaw();
|
||||
locations = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2303,7 +2070,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool
|
|||
int meshPartsRendered = 0;
|
||||
|
||||
bool pickProgramsNeeded = true;
|
||||
Locations* locations;
|
||||
Locations* locations = nullptr;
|
||||
|
||||
foreach(Model* model, _modelsInScene) {
|
||||
QVector<int>* whichList = model->pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
@ -2331,20 +2098,19 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl
|
|||
PROFILE_RANGE(__FUNCTION__);
|
||||
int meshPartsRendered = 0;
|
||||
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
|
||||
//Pick the mesh list with the requested render flags
|
||||
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned);
|
||||
if (!whichList) {
|
||||
qCDebug(renderutils) << "unexpected!!! we don't know which list of meshes to render...";
|
||||
return 0;
|
||||
}
|
||||
QVector<int>& list = *whichList;
|
||||
|
||||
// If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs
|
||||
if (list.size() == 0) {
|
||||
if (list.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Locations* locations;
|
||||
Locations* locations = nullptr;
|
||||
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned,
|
||||
args, locations);
|
||||
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
|
||||
|
|
|
@ -350,58 +350,6 @@ private:
|
|||
|
||||
bool _meshGroupsKnown;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesTranslucent;
|
||||
QMap<QString, int> _unsortedMeshesTranslucentTangents;
|
||||
QMap<QString, int> _unsortedMeshesTranslucentTangentsSpecular;
|
||||
QMap<QString, int> _unsortedMeshesTranslucentSpecular;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesTranslucentSkinned;
|
||||
QMap<QString, int> _unsortedMeshesTranslucentTangentsSkinned;
|
||||
QMap<QString, int> _unsortedMeshesTranslucentTangentsSpecularSkinned;
|
||||
QMap<QString, int> _unsortedMeshesTranslucentSpecularSkinned;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesOpaque;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueTangents;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecular;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueSpecular;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesOpaqueSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueTangentsSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecularSkinned;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueSpecularSkinned;
|
||||
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmap;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmapTangents;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmapTangentsSpecular;
|
||||
QMap<QString, int> _unsortedMeshesOpaqueLightmapSpecular;
|
||||
|
||||
typedef std::unordered_map<int, QVector<int>> MeshListMap;
|
||||
MeshListMap _sortedMeshes;
|
||||
|
||||
QVector<int> _meshesTranslucent;
|
||||
QVector<int> _meshesTranslucentTangents;
|
||||
QVector<int> _meshesTranslucentTangentsSpecular;
|
||||
QVector<int> _meshesTranslucentSpecular;
|
||||
|
||||
QVector<int> _meshesTranslucentSkinned;
|
||||
QVector<int> _meshesTranslucentTangentsSkinned;
|
||||
QVector<int> _meshesTranslucentTangentsSpecularSkinned;
|
||||
QVector<int> _meshesTranslucentSpecularSkinned;
|
||||
|
||||
QVector<int> _meshesOpaque;
|
||||
QVector<int> _meshesOpaqueTangents;
|
||||
QVector<int> _meshesOpaqueTangentsSpecular;
|
||||
QVector<int> _meshesOpaqueSpecular;
|
||||
|
||||
QVector<int> _meshesOpaqueSkinned;
|
||||
QVector<int> _meshesOpaqueTangentsSkinned;
|
||||
QVector<int> _meshesOpaqueTangentsSpecularSkinned;
|
||||
QVector<int> _meshesOpaqueSpecularSkinned;
|
||||
|
||||
QVector<int> _meshesOpaqueLightmap;
|
||||
QVector<int> _meshesOpaqueLightmapTangents;
|
||||
QVector<int> _meshesOpaqueLightmapTangentsSpecular;
|
||||
QVector<int> _meshesOpaqueLightmapSpecular;
|
||||
|
||||
// debug rendering support
|
||||
void renderDebugMeshBoxes();
|
||||
|
@ -490,6 +438,17 @@ private:
|
|||
|
||||
int getRaw() { return *reinterpret_cast<int*>(this); }
|
||||
|
||||
|
||||
RenderKey(
|
||||
bool translucent, bool hasLightmap,
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||
RenderKey( (translucent ? IS_TRANSLUCENT : 0)
|
||||
| (hasLightmap ? HAS_LIGHTMAP : 0)
|
||||
| (hasTangents ? HAS_TANGENTS : 0)
|
||||
| (hasSpecular ? HAS_SPECULAR : 0)
|
||||
| (isSkinned ? IS_SKINNED : 0)
|
||||
) {}
|
||||
|
||||
RenderKey(RenderArgs::RenderMode mode,
|
||||
bool translucent, float alphaThreshold, bool hasLightmap,
|
||||
bool hasTangents, bool hasSpecular, bool isSkinned) :
|
||||
|
@ -527,6 +486,19 @@ private:
|
|||
};
|
||||
static RenderPipelineLib _renderPipelineLib;
|
||||
|
||||
|
||||
class RenderBucket {
|
||||
public:
|
||||
QVector<int> _meshes;
|
||||
QMap<QString, int> _unsortedMeshes;
|
||||
};
|
||||
typedef std::unordered_map<int, RenderBucket> BaseRenderBucketMap;
|
||||
class RenderBucketMap : public BaseRenderBucketMap {
|
||||
public:
|
||||
typedef RenderKey Key;
|
||||
};
|
||||
RenderBucketMap _renderBuckets;
|
||||
|
||||
bool _renderCollisionHull;
|
||||
};
|
||||
|
||||
|
|
|
@ -46,22 +46,46 @@ int SceneScriptingInterface::getStageYearTime() const {
|
|||
return _skyStage->getYearTime();
|
||||
}
|
||||
|
||||
void SceneScriptingInterface::setSunColor(const glm::vec3& color) {
|
||||
void SceneScriptingInterface::setKeyLightColor(const glm::vec3& color) {
|
||||
_skyStage->setSunColor(color);
|
||||
}
|
||||
|
||||
const glm::vec3& SceneScriptingInterface::getSunColor() const {
|
||||
glm::vec3 SceneScriptingInterface::getKeyLightColor() const {
|
||||
return _skyStage->getSunColor();
|
||||
}
|
||||
|
||||
void SceneScriptingInterface::setSunIntensity(float intensity) {
|
||||
void SceneScriptingInterface::setKeyLightIntensity(float intensity) {
|
||||
_skyStage->setSunIntensity(intensity);
|
||||
}
|
||||
|
||||
float SceneScriptingInterface::getSunIntensity() const {
|
||||
float SceneScriptingInterface::getKeyLightIntensity() const {
|
||||
return _skyStage->getSunIntensity();
|
||||
}
|
||||
|
||||
void SceneScriptingInterface::setKeyLightAmbientIntensity(float intensity) {
|
||||
_skyStage->setSunAmbientIntensity(intensity);
|
||||
}
|
||||
|
||||
float SceneScriptingInterface::getKeyLightAmbientIntensity() const {
|
||||
return _skyStage->getSunAmbientIntensity();
|
||||
}
|
||||
|
||||
void SceneScriptingInterface::setKeyLightDirection(const glm::vec3& direction) {
|
||||
_skyStage->setSunDirection(direction);
|
||||
}
|
||||
|
||||
glm::vec3 SceneScriptingInterface::getKeyLightDirection() const {
|
||||
return _skyStage->getSunDirection();
|
||||
}
|
||||
|
||||
void SceneScriptingInterface::setStageSunModelEnable(bool isEnabled) {
|
||||
_skyStage->setSunModelEnable(isEnabled);
|
||||
}
|
||||
|
||||
bool SceneScriptingInterface::isStageSunModelEnabled() const {
|
||||
return _skyStage->isSunModelEnabled();
|
||||
}
|
||||
|
||||
model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const {
|
||||
return _skyStage;
|
||||
}
|
||||
|
|
|
@ -38,10 +38,26 @@ public:
|
|||
Q_INVOKABLE void setStageYearTime(int day);
|
||||
Q_INVOKABLE int getStageYearTime() const;
|
||||
|
||||
Q_INVOKABLE void setSunColor(const glm::vec3& color);
|
||||
Q_INVOKABLE const glm::vec3& getSunColor() const;
|
||||
Q_INVOKABLE void setSunIntensity(float intensity);
|
||||
Q_INVOKABLE float getSunIntensity() const;
|
||||
// Enable/disable the stage sun model which uses the key light to simulate
|
||||
// the sun light based on the location of the stage trelative to earth and the current time
|
||||
Q_INVOKABLE void setStageSunModelEnable(bool isEnabled);
|
||||
Q_INVOKABLE bool isStageSunModelEnabled() const;
|
||||
|
||||
|
||||
Q_INVOKABLE void setKeyLightColor(const glm::vec3& color);
|
||||
Q_INVOKABLE glm::vec3 getKeyLightColor() const;
|
||||
Q_INVOKABLE void setKeyLightIntensity(float intensity);
|
||||
Q_INVOKABLE float getKeyLightIntensity() const;
|
||||
Q_INVOKABLE void setKeyLightAmbientIntensity(float intensity);
|
||||
Q_INVOKABLE float getKeyLightAmbientIntensity() const;
|
||||
|
||||
// setKeyLightDIrection is only effective if stage Sun model is disabled
|
||||
Q_INVOKABLE void setKeyLightDirection(const glm::vec3& direction);
|
||||
|
||||
Q_INVOKABLE glm::vec3 getKeyLightDirection() const;
|
||||
|
||||
|
||||
|
||||
|
||||
model::SunSkyStagePointer getSkyStage() const;
|
||||
|
||||
|
|
|
@ -647,8 +647,10 @@ void ScriptEngine::stopAllTimers() {
|
|||
}
|
||||
|
||||
void ScriptEngine::stop() {
|
||||
_isFinished = true;
|
||||
emit runningStateChanged();
|
||||
if (!_isFinished) {
|
||||
_isFinished = true;
|
||||
emit runningStateChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEngine::timerFired() {
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
# add the tool directories
|
||||
add_subdirectory(mtc)
|
||||
set_target_properties(mtc PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(scribe)
|
||||
set_target_properties(scribe PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(vhacd-util)
|
||||
set_target_properties(vhacd-util PROPERTIES FOLDER "Tools")
|
||||
|
||||
find_package(VHACD)
|
||||
if(VHACD_FOUND)
|
||||
add_subdirectory(vhacd)
|
||||
# set_target_properties(vhacd PROPERTIES FOLDER "Tools")
|
||||
endif()
|
||||
|
|
18
tools/vhacd-util/CMakeLists.txt
Normal file
18
tools/vhacd-util/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
set(TARGET_NAME vhacd-util)
|
||||
setup_hifi_project(Core Widgets)
|
||||
link_hifi_libraries(shared fbx model gpu)
|
||||
|
||||
add_dependency_external_projects(vhacd)
|
||||
|
||||
find_package(VHACD REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${VHACD_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${VHACD_LIBRARIES})
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
include(FindOpenMP)
|
||||
if(OPENMP_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif ()
|
|
@ -1,23 +0,0 @@
|
|||
set(TARGET_NAME vhacd-util)
|
||||
setup_hifi_project(Core Widgets)
|
||||
link_hifi_libraries(shared model fbx gpu networking octree)
|
||||
|
||||
#find_package(VHACD REQUIRED) done in CMakeList.txt in parent directory
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${VHACD_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${VHACD_LIBRARIES})
|
||||
|
||||
if(NOT WIN32)
|
||||
find_package( Threads)
|
||||
target_link_libraries(${TARGET_NAME} ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
include(FindOpenMP)
|
||||
if(OPENMP_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_dependency_external_projects(glm)
|
||||
find_package(GLM REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})
|
Loading…
Reference in a new issue