Merge branch 'master' of git://github.com/highfidelity/hifi into outline
39
.clang-format
Normal file
|
@ -0,0 +1,39 @@
|
|||
Language: Cpp
|
||||
Standard: Cpp11
|
||||
BasedOnStyle: "Chromium"
|
||||
ColumnLimit: 128
|
||||
IndentWidth: 4
|
||||
UseTab: Never
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterEnum: true
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyNamespace: true
|
||||
|
||||
|
||||
AccessModifierOffset: -4
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
IndentCaseLabels: true
|
||||
ReflowComments: false
|
||||
Cpp11BracedListStyle: false
|
||||
ContinuationIndentWidth: 4
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
CompactNamespaces: true
|
||||
SortIncludes: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||
PenaltyBreakBeforeFirstCallParameter: 1000
|
||||
|
|
@ -118,6 +118,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
|||
foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
|
||||
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
|
||||
file(TO_CMAKE_PATH "${AUTOSCRIBE_SHADER_RETURN}" AUTOSCRIBE_GENERATED_FILE)
|
||||
set_property(SOURCE ${AUTOSCRIBE_GENERATED_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_GENERATED_FILE})
|
||||
endforeach()
|
||||
#message(${TARGET_NAME} ${AUTOSCRIBE_SHADER_SRC})
|
||||
|
|
20
cmake/macros/GenerateQrc.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
function(GENERATE_QRC)
|
||||
set(oneValueArgs OUTPUT PREFIX PATH)
|
||||
set(multiValueArgs GLOBS)
|
||||
cmake_parse_arguments(GENERATE_QRC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
|
||||
if ("${GENERATE_QRC_PREFIX}" STREQUAL "")
|
||||
set(QRC_PREFIX_PATH /)
|
||||
else()
|
||||
set(QRC_PREFIX_PATH ${GENERATE_QRC_PREFIX})
|
||||
endif()
|
||||
|
||||
foreach(GLOB ${GENERATE_QRC_GLOBS})
|
||||
file(GLOB_RECURSE FOUND_FILES RELATIVE ${GENERATE_QRC_PATH} ${GLOB})
|
||||
foreach(FILENAME ${FOUND_FILES})
|
||||
set(QRC_CONTENTS "${QRC_CONTENTS}<file alias=\"${FILENAME}\">${GENERATE_QRC_PATH}/${FILENAME}</file>\n")
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
configure_file("${HF_CMAKE_DIR}/templates/resources.qrc.in" ${GENERATE_QRC_OUTPUT})
|
||||
endfunction()
|
|
@ -7,10 +7,12 @@
|
|||
#
|
||||
|
||||
function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE)
|
||||
if ("$ENV{${_ENV_VAR_NAME}}" STREQUAL "")
|
||||
set (${_RESULT_NAME} ${_DEFAULT_VALUE} PARENT_SCOPE)
|
||||
else()
|
||||
set (${_RESULT_NAME} $ENV{${_ENV_VAR_NAME}} PARENT_SCOPE)
|
||||
if (NOT DEFINED ${_RESULT_NAME})
|
||||
if ("$ENV{${_ENV_VAR_NAME}}" STREQUAL "")
|
||||
set (${_RESULT_NAME} ${_DEFAULT_VALUE} PARENT_SCOPE)
|
||||
else()
|
||||
set (${_RESULT_NAME} $ENV{${_ENV_VAR_NAME}} PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
|
5
cmake/templates/resources.qrc.in
Normal file
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="@QRC_PREFIX_PATH@">
|
||||
@QRC_CONTENTS@
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -1,6 +1,20 @@
|
|||
set(TARGET_NAME interface)
|
||||
project(${TARGET_NAME})
|
||||
|
||||
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
|
||||
add_custom_target(qml SOURCES ${QML_SRC})
|
||||
GroupSources("resources/qml")
|
||||
|
||||
function(JOIN VALUES GLUE OUTPUT)
|
||||
string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
|
||||
string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
|
||||
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
set(INTERFACE_QML_QRC ${CMAKE_CURRENT_BINARY_DIR}/qml.qrc)
|
||||
generate_qrc(OUTPUT ${INTERFACE_QML_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources GLOBS *.qml *.qss *.js *.html *.ttf *.gif *.svg *.png *.jpg)
|
||||
|
||||
# set a default root dir for each of our optional externals if it was not passed
|
||||
set(OPTIONAL_EXTERNALS "LeapMotion")
|
||||
|
||||
|
@ -66,9 +80,7 @@ qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
|||
# add them to the interface source files
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
||||
|
||||
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
|
||||
add_custom_target(qml SOURCES ${QML_SRC})
|
||||
GroupSources("resources/qml")
|
||||
list(APPEND INTERFACE_SRCS ${INTERFACE_QML_QRC})
|
||||
|
||||
if (UNIX)
|
||||
install(
|
||||
|
@ -131,10 +143,10 @@ if (APPLE)
|
|||
|
||||
# append the discovered resources to our list of interface sources
|
||||
list(APPEND INTERFACE_SRCS ${DISCOVERED_RESOURCES})
|
||||
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
|
||||
list(APPEND INTERFACE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME})
|
||||
endif()
|
||||
|
||||
|
||||
# create the executable, make it a bundle on OS X
|
||||
if (APPLE)
|
||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
||||
|
|
Before Width: | Height: | Size: 312 KiB After Width: | Height: | Size: 604 KiB |
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 503 KiB |
Before Width: | Height: | Size: 307 KiB After Width: | Height: | Size: 585 KiB |
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 547 KiB |
|
@ -18,7 +18,7 @@
|
|||
function shouldRaiseKeyboard() {
|
||||
var nodeName = document.activeElement.nodeName;
|
||||
var nodeType = document.activeElement.type;
|
||||
if (nodeName === "INPUT" && ["email", "number", "password", "tel", "text", "url"].indexOf(nodeType) !== -1
|
||||
if (nodeName === "INPUT" && ["email", "number", "password", "tel", "text", "url", "search"].indexOf(nodeType) !== -1
|
||||
|| document.activeElement.nodeName === "TEXTAREA") {
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -13,6 +13,7 @@ import "."
|
|||
|
||||
Rectangle {
|
||||
id: keyboardBase
|
||||
objectName: "keyboard"
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
@ -27,6 +28,8 @@ Rectangle {
|
|||
|
||||
readonly property int mirrorTextHeight: keyboardRowHeight
|
||||
|
||||
property bool password: false
|
||||
property alias mirroredText: mirrorText.text
|
||||
property bool showMirrorText: true
|
||||
readonly property int raisedHeight: 200
|
||||
|
||||
|
@ -112,16 +115,20 @@ Rectangle {
|
|||
color: "#252525"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
TextEdit {
|
||||
TextInput {
|
||||
id: mirrorText
|
||||
visible: showMirrorText
|
||||
size: 13.5
|
||||
FontLoader { id: ralewaySemiBold; source: "../../fonts/Raleway-SemiBold.ttf"; }
|
||||
font.family: ralewaySemiBold.name
|
||||
font.pointSize: 13.5
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: "#FFFFFF";
|
||||
anchors.fill: parent
|
||||
wrapMode: Text.WordWrap
|
||||
readOnly: false // we need to leave this property read-only to allow control to accept QKeyEvent
|
||||
readOnly: false // we need this to allow control to accept QKeyEvent
|
||||
selectByMouse: false
|
||||
echoMode: password ? TextInput.Password : TextInput.Normal
|
||||
|
||||
Keys.onPressed: {
|
||||
if (event.key == Qt.Key_Return || event.key == Qt.Key_Space) {
|
||||
|
|
|
@ -200,12 +200,6 @@ Rectangle {
|
|||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
}
|
||||
FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; }
|
||||
TextMetrics {
|
||||
id: textMetrics;
|
||||
font.family: ralewayRegular.name
|
||||
text: root.itemOwner;
|
||||
}
|
||||
RalewayRegular {
|
||||
id: ownedBy;
|
||||
text: root.itemOwner;
|
||||
|
@ -215,8 +209,7 @@ Rectangle {
|
|||
anchors.top: ownedByHeader.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.left: ownedByHeader.left;
|
||||
height: textMetrics.height;
|
||||
width: root.isMyCert ? textMetrics.width + 25 : ownedByHeader.width;
|
||||
height: paintedHeight;
|
||||
// Style
|
||||
color: hifi.colors.darkGray;
|
||||
elide: Text.ElideRight;
|
||||
|
@ -231,7 +224,7 @@ Rectangle {
|
|||
anchors.topMargin: 4;
|
||||
anchors.bottom: ownedBy.bottom;
|
||||
anchors.left: ownedBy.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.leftMargin: 6;
|
||||
anchors.right: ownedByHeader.right;
|
||||
// Style
|
||||
color: hifi.colors.lightGray;
|
||||
|
|
|
@ -90,17 +90,22 @@ Item {
|
|||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What are private keys?"
|
||||
answer: qsTr("A private key is a secret piece of text that is used to decrypt code.<br><br>In High Fidelity, <b>your private keys are used to decrypt the contents of your Wallet and Purchases.</b>");
|
||||
answer: qsTr("A private key is a secret piece of text that is used to prove ownership, unlock confidential information, and sign transactions.<br><br>In High Fidelity, <b>your private keys are used to securely access the contents of your Wallet and Purchases.</b>");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "Where are my private keys stored?"
|
||||
answer: qsTr('Your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the file path of your hifikey in your file explorer.</a></font></b><br><br> You may backup this file by copying it to a USB flash drive, or to a service like Dropbox or Google Drive. Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.');
|
||||
answer: qsTr('By default, your private keys are <b>only stored on your hard drive</b> in High Fidelity Interface\'s AppData directory.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the file path of your hifikey in your file explorer.</a></font></b>');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "How can I backup my private keys?"
|
||||
answer: qsTr('You may backup the file containing your private keys by copying it to a USB flash drive, or to a service like Dropbox or Google Drive.<br><br>Restore your backup by replacing the file in Interface\'s AppData directory with your backed-up copy.<br><br><b><font color="#0093C5"><a href="#privateKeyPath">Tap here to open the file path of your hifikey in your file explorer.</a></font></b>');
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
question: "What happens if I lose my passphrase?"
|
||||
answer: qsTr("If you lose your passphrase, you will no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
|
||||
answer: qsTr("Your passphrase is used to encrypt your private keys. If you lose your passphrase, you will no longer be able to decrypt your private key file. You will also no longer have access to the contents of your Wallet or My Purchases.<br><br><b>Nobody can help you recover your passphrase, including High Fidelity.</b> Please write it down and store it securely.");
|
||||
}
|
||||
ListElement {
|
||||
isExpanded: false;
|
||||
|
|
|
@ -679,7 +679,7 @@ Item {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: 40;
|
||||
text: "Open Instructions for Later";
|
||||
text: "Open Backup Instructions for Later";
|
||||
onClicked: {
|
||||
instructions01Container.visible = false;
|
||||
instructions02Container.visible = true;
|
||||
|
|
|
@ -207,6 +207,17 @@
|
|||
#if defined(Q_OS_WIN)
|
||||
#include <VersionHelpers.h>
|
||||
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
// This is a HACK that uses private headers included with the qt source distrubution.
|
||||
// To use this feature you need to add these directores to your include path:
|
||||
// E:/Qt/5.9.1/Src/qtbase/include/QtCore/5.9.1/QtCore
|
||||
// E:/Qt/5.9.1/Src/qtbase/include/QtCore/5.9.1
|
||||
#define QT_BOOTSTRAPPED
|
||||
#include <private/qthread_p.h>
|
||||
#include <private/qobject_p.h>
|
||||
#undef QT_BOOTSTRAPPED
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||
}
|
||||
|
@ -264,9 +275,7 @@ private:
|
|||
switch ((int)event->type()) {
|
||||
case ApplicationEvent::Render:
|
||||
render();
|
||||
// Ensure we never back up the render events. Each render should be triggered only in response
|
||||
// to the NEXT render event after the last render occured
|
||||
QCoreApplication::removePostedEvents(this, ApplicationEvent::Render);
|
||||
qApp->_pendingRenderEvent.store(false);
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
@ -2246,7 +2255,7 @@ void Application::initializeUi() {
|
|||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
||||
// support the window management and scripting proxies for VR use
|
||||
offscreenUi->createDesktop(QString("hifi/Desktop.qml"));
|
||||
offscreenUi->createDesktop(QString("qrc:///qml/hifi/Desktop.qml"));
|
||||
|
||||
// FIXME either expose so that dialogs can set this themselves or
|
||||
// do better detection in the offscreen UI of what has focus
|
||||
|
@ -2712,9 +2721,14 @@ bool Application::importFromZIP(const QString& filePath) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
void Application::onPresent(quint32 frameCount) {
|
||||
postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority);
|
||||
if (_renderEventHandler && !isAboutToQuit()) {
|
||||
bool expected = false;
|
||||
if (_pendingIdleEvent.compare_exchange_strong(expected, true)) {
|
||||
postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority);
|
||||
}
|
||||
expected = false;
|
||||
if (_renderEventHandler && !isAboutToQuit() && _pendingRenderEvent.compare_exchange_strong(expected, true)) {
|
||||
postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render));
|
||||
}
|
||||
}
|
||||
|
@ -2781,7 +2795,26 @@ bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) {
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
static int getEventQueueSize(QThread* thread) {
|
||||
auto threadData = QThreadData::get2(thread);
|
||||
QMutexLocker locker(&threadData->postEventList.mutex);
|
||||
return threadData->postEventList.size();
|
||||
}
|
||||
|
||||
static void dumpEventQueue(QThread* thread) {
|
||||
auto threadData = QThreadData::get2(thread);
|
||||
QMutexLocker locker(&threadData->postEventList.mutex);
|
||||
qDebug() << "AJT: event list, size =" << threadData->postEventList.size();
|
||||
for (auto& postEvent : threadData->postEventList) {
|
||||
QEvent::Type type = (postEvent.event ? postEvent.event->type() : QEvent::None);
|
||||
qDebug() << "AJT: " << type;
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_EVENT_QUEUE
|
||||
|
||||
bool Application::event(QEvent* event) {
|
||||
|
||||
if (!Menu::getInstance()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2801,8 +2834,18 @@ bool Application::event(QEvent* event) {
|
|||
// see (windowMinimizedChanged)
|
||||
case ApplicationEvent::Idle:
|
||||
idle();
|
||||
// Don't process extra idle events that arrived in the event queue while we were doing this idle
|
||||
QCoreApplication::removePostedEvents(this, ApplicationEvent::Idle);
|
||||
|
||||
#ifdef DEBUG_EVENT_QUEUE
|
||||
{
|
||||
int count = getEventQueueSize(QThread::currentThread());
|
||||
if (count > 400) {
|
||||
dumpEventQueue(QThread::currentThread());
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_EVENT_QUEUE
|
||||
|
||||
_pendingIdleEvent.store(false);
|
||||
|
||||
return true;
|
||||
|
||||
case QEvent::MouseMove:
|
||||
|
@ -7203,7 +7246,7 @@ void Application::updateDisplayMode() {
|
|||
_offscreenContext->makeCurrent();
|
||||
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
||||
_displayPlugin = newDisplayPlugin;
|
||||
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
|
||||
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);
|
||||
auto desktop = offscreenUi->getDesktop();
|
||||
if (desktop) {
|
||||
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
||||
|
|
|
@ -717,5 +717,8 @@ private:
|
|||
LaserPointerManager _laserPointerManager;
|
||||
|
||||
friend class RenderEventHandler;
|
||||
|
||||
std::atomic<bool> _pendingIdleEvent { false };
|
||||
std::atomic<bool> _pendingRenderEvent { false };
|
||||
};
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -72,6 +72,12 @@ void Application::paintGL() {
|
|||
{
|
||||
QMutexLocker viewLocker(&_renderArgsMutex);
|
||||
renderArgs = _appRenderArgs._renderArgs;
|
||||
|
||||
// don't render if there is no context.
|
||||
if (!_appRenderArgs._renderArgs._context) {
|
||||
return;
|
||||
}
|
||||
|
||||
HMDSensorPose = _appRenderArgs._headPose;
|
||||
eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||
sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QUuid>
|
||||
|
||||
#include <SettingHandle.h>
|
||||
#include <Rig.h>
|
||||
#include <Sound.h>
|
||||
|
@ -106,6 +108,8 @@ class MyAvatar : public Avatar {
|
|||
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
|
||||
* @property userHeight {number} The height of the user in sensor space. (meters).
|
||||
* @property userEyeHeight {number} Estimated height of the users eyes in sensor space. (meters)
|
||||
* @property SELF_ID {string} READ-ONLY. UUID representing "my avatar". Only use for local-only entities and overlays in situations where MyAvatar.sessionUUID is not available (e.g., if not connected to a domain).
|
||||
* Note: Likely to be deprecated.
|
||||
*/
|
||||
|
||||
// FIXME: `glm::vec3 position` is not accessible from QML, so this exposes position in a QML-native type
|
||||
|
@ -152,6 +156,8 @@ class MyAvatar : public Avatar {
|
|||
|
||||
Q_PROPERTY(float userHeight READ getUserHeight WRITE setUserHeight)
|
||||
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
|
||||
|
||||
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
|
||||
|
||||
const QString DOMINANT_LEFT_HAND = "left";
|
||||
const QString DOMINANT_RIGHT_HAND = "right";
|
||||
|
@ -546,6 +552,8 @@ public:
|
|||
|
||||
virtual SpatialParentTree* getParentTree() const override;
|
||||
|
||||
const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
|
||||
|
||||
public slots:
|
||||
void increaseSize();
|
||||
void decreaseSize();
|
||||
|
@ -648,8 +656,6 @@ private:
|
|||
|
||||
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
|
||||
|
||||
private:
|
||||
|
||||
virtual void updatePalms() override {}
|
||||
void lateUpdatePalms();
|
||||
|
||||
|
|
|
@ -105,19 +105,19 @@ RSA* readKeys(const char* filename) {
|
|||
return key;
|
||||
}
|
||||
|
||||
bool writeBackupInstructions() {
|
||||
bool Wallet::writeBackupInstructions() {
|
||||
QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html");
|
||||
QString filename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
||||
QFile outputFile(filename);
|
||||
QString outputFilename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
||||
QFile outputFile(outputFilename);
|
||||
bool retval = false;
|
||||
|
||||
if (QFile::exists(filename))
|
||||
if (QFile::exists(outputFilename) || getKeyFilePath() == "")
|
||||
{
|
||||
QFile::remove(filename);
|
||||
return false;
|
||||
}
|
||||
QFile::copy(inputFilename, filename);
|
||||
QFile::copy(inputFilename, outputFilename);
|
||||
|
||||
if (QFile::exists(filename) && outputFile.open(QIODevice::ReadWrite)) {
|
||||
if (QFile::exists(outputFilename) && outputFile.open(QIODevice::ReadWrite)) {
|
||||
|
||||
QByteArray fileData = outputFile.readAll();
|
||||
QString text(fileData);
|
||||
|
@ -132,7 +132,7 @@ bool writeBackupInstructions() {
|
|||
retval = true;
|
||||
qCDebug(commerce) << "wrote html file successfully";
|
||||
} else {
|
||||
qCDebug(commerce) << "failed to open output html file" << filename;
|
||||
qCDebug(commerce) << "failed to open output html file" << outputFilename;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
@ -154,8 +154,6 @@ bool writeKeys(const char* filename, RSA* keys) {
|
|||
QFile(QString(filename)).remove();
|
||||
return retval;
|
||||
}
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
retval = true;
|
||||
qCDebug(commerce) << "wrote keys successfully";
|
||||
|
@ -359,6 +357,8 @@ bool Wallet::setPassphrase(const QString& passphrase) {
|
|||
|
||||
_publicKeys.clear();
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -526,6 +526,8 @@ bool Wallet::generateKeyPair() {
|
|||
qCInfo(commerce) << "Generating keypair.";
|
||||
auto keyPair = generateRSAKeypair();
|
||||
|
||||
writeBackupInstructions();
|
||||
|
||||
// TODO: redo this soon -- need error checking and so on
|
||||
writeSecurityImage(_securityImage, keyFilePath());
|
||||
QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last();
|
||||
|
|
|
@ -80,6 +80,7 @@ private:
|
|||
void updateImageProvider();
|
||||
bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath);
|
||||
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
||||
bool writeBackupInstructions();
|
||||
|
||||
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);
|
||||
|
||||
|
|
|
@ -15,13 +15,14 @@
|
|||
#include "avatar/AvatarManager.h"
|
||||
|
||||
LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) :
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) :
|
||||
_renderingEnabled(enabled),
|
||||
_renderStates(renderStates),
|
||||
_defaultRenderStates(defaultRenderStates),
|
||||
_faceAvatar(faceAvatar),
|
||||
_centerEndY(centerEndY),
|
||||
_lockEnd(lockEnd)
|
||||
_lockEnd(lockEnd),
|
||||
_distanceScaleEnd(distanceScaleEnd)
|
||||
{
|
||||
_rayPickUID = DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps);
|
||||
|
||||
|
@ -86,6 +87,10 @@ void LaserPointer::editRenderState(const std::string& state, const QVariant& sta
|
|||
updateRenderStateOverlay(_renderStates[state].getStartID(), startProps);
|
||||
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
||||
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
||||
QVariant endDim = endProps.toMap()["dimensions"];
|
||||
if (endDim.isValid()) {
|
||||
_renderStates[state].setEndDim(vec3FromVariant(endDim));
|
||||
}
|
||||
}
|
||||
|
||||
void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& props) {
|
||||
|
@ -154,10 +159,14 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter
|
|||
if (!renderState.getEndID().isNull()) {
|
||||
QVariantMap endProps;
|
||||
glm::quat faceAvatarRotation = DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f)));
|
||||
glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(renderState.getEndID(), "dimensions").value);
|
||||
if (_distanceScaleEnd) {
|
||||
dim = renderState.getEndDim() * glm::distance(pickRay.origin, endVec) * DependencyManager::get<AvatarManager>()->getMyAvatar()->getSensorToWorldScale();
|
||||
endProps.insert("dimensions", vec3toVariant(dim));
|
||||
}
|
||||
if (_centerEndY) {
|
||||
endProps.insert("position", end);
|
||||
} else {
|
||||
glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(renderState.getEndID(), "dimensions").value);
|
||||
glm::vec3 currentUpVector = faceAvatarRotation * Vectors::UP;
|
||||
endProps.insert("position", vec3toVariant(endVec + glm::vec3(currentUpVector.x * 0.5f * dim.y, currentUpVector.y * 0.5f * dim.y, currentUpVector.z * 0.5f * dim.y)));
|
||||
}
|
||||
|
@ -264,6 +273,7 @@ RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, cons
|
|||
_pathIgnoreRays = qApp->getOverlays().getProperty(_pathID, "ignoreRayIntersection").value.toBool();
|
||||
}
|
||||
if (!_endID.isNull()) {
|
||||
_endDim = vec3FromVariant(qApp->getOverlays().getProperty(_endID, "dimensions").value);
|
||||
_endIgnoreRays = qApp->getOverlays().getProperty(_endID, "ignoreRayIntersection").value.toBool();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ public:
|
|||
const bool& doesPathIgnoreRays() const { return _pathIgnoreRays; }
|
||||
const bool& doesEndIgnoreRays() const { return _endIgnoreRays; }
|
||||
|
||||
void setEndDim(const glm::vec3& endDim) { _endDim = endDim; }
|
||||
const glm::vec3& getEndDim() const { return _endDim; }
|
||||
|
||||
void deleteOverlays();
|
||||
|
||||
private:
|
||||
|
@ -41,6 +44,8 @@ private:
|
|||
bool _startIgnoreRays;
|
||||
bool _pathIgnoreRays;
|
||||
bool _endIgnoreRays;
|
||||
|
||||
glm::vec3 _endDim;
|
||||
};
|
||||
|
||||
|
||||
|
@ -52,7 +57,7 @@ public:
|
|||
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
|
||||
|
||||
LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
|
||||
~LaserPointer();
|
||||
|
||||
QUuid getRayUID() { return _rayPickUID; }
|
||||
|
@ -88,6 +93,7 @@ private:
|
|||
bool _faceAvatar;
|
||||
bool _centerEndY;
|
||||
bool _lockEnd;
|
||||
bool _distanceScaleEnd;
|
||||
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||
|
||||
QUuid _rayPickUID;
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include "LaserPointerManager.h"
|
||||
|
||||
QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled) {
|
||||
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled) {
|
||||
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
||||
if (!laserPointer->getRayUID().isNull()) {
|
||||
QWriteLocker containsLock(&_containsLock);
|
||||
QUuid id = QUuid::createUuid();
|
||||
|
|
|
@ -22,7 +22,7 @@ class LaserPointerManager {
|
|||
|
||||
public:
|
||||
QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool enabled);
|
||||
const bool faceAvatar, const bool centerEndY, const bool lockEnd, const bool distanceScaleEnd, const bool enabled);
|
||||
void removeLaserPointer(const QUuid uid);
|
||||
void enableLaserPointer(const QUuid uid);
|
||||
void disableLaserPointer(const QUuid uid);
|
||||
|
|
|
@ -32,6 +32,11 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
|
|||
lockEnd = propertyMap["lockEnd"].toBool();
|
||||
}
|
||||
|
||||
bool distanceScaleEnd = false;
|
||||
if (propertyMap["distanceScaleEnd"].isValid()) {
|
||||
distanceScaleEnd = propertyMap["distanceScaleEnd"].toBool();
|
||||
}
|
||||
|
||||
bool enabled = false;
|
||||
if (propertyMap["enabled"].isValid()) {
|
||||
enabled = propertyMap["enabled"].toBool();
|
||||
|
@ -66,7 +71,7 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
|
|||
}
|
||||
}
|
||||
|
||||
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, enabled);
|
||||
return qApp->getLaserPointerManager().createLaserPointer(properties, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
||||
}
|
||||
|
||||
void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& renderState, const QVariant& properties) {
|
||||
|
|
|
@ -135,6 +135,7 @@ static const int32_t exp2Table[1 << EXP2_TABBITS][3] = {
|
|||
|
||||
static const int IEEE754_FABS_MASK = 0x7fffffff;
|
||||
static const int IEEE754_MANT_BITS = 23;
|
||||
static const int IEEE754_EXPN_BITS = 8;
|
||||
static const int IEEE754_EXPN_BIAS = 127;
|
||||
|
||||
//
|
||||
|
@ -152,7 +153,7 @@ static inline int32_t peaklog2(float* input) {
|
|||
|
||||
// split into e and x - 1.0
|
||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
||||
int32_t x = (peak << (31 - IEEE754_MANT_BITS)) & 0x7fffffff;
|
||||
int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff;
|
||||
|
||||
// saturate
|
||||
if (e > 31) {
|
||||
|
@ -191,7 +192,7 @@ static inline int32_t peaklog2(float* input0, float* input1) {
|
|||
|
||||
// split into e and x - 1.0
|
||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
||||
int32_t x = (peak << (31 - IEEE754_MANT_BITS)) & 0x7fffffff;
|
||||
int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff;
|
||||
|
||||
// saturate
|
||||
if (e > 31) {
|
||||
|
@ -234,7 +235,7 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
|
|||
|
||||
// split into e and x - 1.0
|
||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
||||
int32_t x = (peak << (31 - IEEE754_MANT_BITS)) & 0x7fffffff;
|
||||
int32_t x = (peak << IEEE754_EXPN_BITS) & 0x7fffffff;
|
||||
|
||||
// saturate
|
||||
if (e > 31) {
|
||||
|
@ -259,30 +260,30 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
|
|||
// Count Leading Zeros
|
||||
// Emulates the CLZ (ARM) and LZCNT (x86) instruction
|
||||
//
|
||||
static inline int CLZ(uint32_t x) {
|
||||
static inline int CLZ(uint32_t u) {
|
||||
|
||||
if (x == 0) {
|
||||
if (u == 0) {
|
||||
return 32;
|
||||
}
|
||||
|
||||
int e = 0;
|
||||
if (x < 0x00010000) {
|
||||
x <<= 16;
|
||||
if (u < 0x00010000) {
|
||||
u <<= 16;
|
||||
e += 16;
|
||||
}
|
||||
if (x < 0x01000000) {
|
||||
x <<= 8;
|
||||
if (u < 0x01000000) {
|
||||
u <<= 8;
|
||||
e += 8;
|
||||
}
|
||||
if (x < 0x10000000) {
|
||||
x <<= 4;
|
||||
if (u < 0x10000000) {
|
||||
u <<= 4;
|
||||
e += 4;
|
||||
}
|
||||
if (x < 0x40000000) {
|
||||
x <<= 2;
|
||||
if (u < 0x40000000) {
|
||||
u <<= 2;
|
||||
e += 2;
|
||||
}
|
||||
if (x < 0x80000000) {
|
||||
if (u < 0x80000000) {
|
||||
e += 1;
|
||||
}
|
||||
return e;
|
||||
|
@ -290,19 +291,19 @@ static inline int CLZ(uint32_t x) {
|
|||
|
||||
//
|
||||
// Compute -log2(x) for x=[0,1] in Q31, result in Q26
|
||||
// x = 0 returns 0x7fffffff
|
||||
// x < 0 undefined
|
||||
// x <= 0 returns 0x7fffffff
|
||||
//
|
||||
static inline int32_t fixlog2(int32_t x) {
|
||||
|
||||
if (x == 0) {
|
||||
if (x <= 0) {
|
||||
return 0x7fffffff;
|
||||
}
|
||||
|
||||
// split into e and x - 1.0
|
||||
int e = CLZ((uint32_t)x);
|
||||
x <<= e; // normalize to [0x80000000, 0xffffffff]
|
||||
x &= 0x7fffffff; // x - 1.0
|
||||
uint32_t u = (uint32_t)x;
|
||||
int e = CLZ(u);
|
||||
u <<= e; // normalize to [0x80000000, 0xffffffff]
|
||||
x = u & 0x7fffffff; // x - 1.0
|
||||
|
||||
int k = x >> (31 - LOG2_TABBITS);
|
||||
|
||||
|
@ -320,13 +321,18 @@ static inline int32_t fixlog2(int32_t x) {
|
|||
|
||||
//
|
||||
// Compute exp2(-x) for x=[0,32] in Q26, result in Q31
|
||||
// x < 0 undefined
|
||||
// x <= 0 returns 0x7fffffff
|
||||
//
|
||||
static inline int32_t fixexp2(int32_t x) {
|
||||
|
||||
if (x <= 0) {
|
||||
return 0x7fffffff;
|
||||
}
|
||||
|
||||
// split into e and 1.0 - x
|
||||
int e = x >> LOG2_FRACBITS;
|
||||
x = ~(x << LOG2_INTBITS) & 0x7fffffff;
|
||||
uint32_t u = (uint32_t)x;
|
||||
int e = u >> LOG2_FRACBITS;
|
||||
x = ~(u << LOG2_INTBITS) & 0x7fffffff;
|
||||
|
||||
int k = x >> (31 - EXP2_TABBITS);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class MonoDCBlock {
|
|||
public:
|
||||
void process(int32_t& x) {
|
||||
|
||||
x <<= 15; // scale to Q30
|
||||
x *= (1 << 15); // scale to Q30
|
||||
x -= _dcOffset; // remove DC
|
||||
_dcOffset += x >> 13; // pole = (1.0 - 2^-13) = 0.9999
|
||||
}
|
||||
|
@ -53,8 +53,8 @@ class StereoDCBlock {
|
|||
public:
|
||||
void process(int32_t& x0, int32_t& x1) {
|
||||
|
||||
x0 <<= 15;
|
||||
x1 <<= 15;
|
||||
x0 *= (1 << 15);
|
||||
x1 *= (1 << 15);
|
||||
|
||||
x0 -= _dcOffset[0];
|
||||
x1 -= _dcOffset[1];
|
||||
|
@ -71,10 +71,10 @@ class QuadDCBlock {
|
|||
public:
|
||||
void process(int32_t& x0, int32_t& x1, int32_t& x2, int32_t& x3) {
|
||||
|
||||
x0 <<= 15;
|
||||
x1 <<= 15;
|
||||
x2 <<= 15;
|
||||
x3 <<= 15;
|
||||
x0 *= (1 << 15);
|
||||
x1 *= (1 << 15);
|
||||
x2 *= (1 << 15);
|
||||
x3 *= (1 << 15);
|
||||
|
||||
x0 -= _dcOffset[0];
|
||||
x1 -= _dcOffset[1];
|
||||
|
@ -100,10 +100,10 @@ protected:
|
|||
int _histogram[NHIST] = {};
|
||||
|
||||
// peakhold
|
||||
int32_t _holdMin = 0x7fffffff;
|
||||
int32_t _holdInc = 0x7fffffff;
|
||||
uint32_t _holdMin = 0x7fffffff;
|
||||
uint32_t _holdInc = 0x7fffffff;
|
||||
uint32_t _holdMax = 0x7fffffff;
|
||||
int32_t _holdRel = 0x7fffffff;
|
||||
uint32_t _holdRel = 0x7fffffff;
|
||||
int32_t _holdPeak = 0x7fffffff;
|
||||
|
||||
// hysteresis
|
||||
|
@ -177,18 +177,23 @@ void GateImpl::setThreshold(float threshold) {
|
|||
void GateImpl::setHold(float hold) {
|
||||
|
||||
const double RELEASE = 100.0; // release = 100ms
|
||||
const double PROGHOLD = 0.100; // progressive hold = 100ms
|
||||
const double PROGHOLD = 100.0; // progressive hold = 100ms
|
||||
|
||||
// pure hold = 1 to 1000ms
|
||||
hold = MAX(hold, 1.0f);
|
||||
hold = MIN(hold, 1000.0f);
|
||||
|
||||
// compute final tc
|
||||
_holdMin = msToTc(RELEASE, _sampleRate);
|
||||
|
||||
_holdInc = (int32_t)((_holdMin - 0x7fffffff) / (PROGHOLD * _sampleRate));
|
||||
_holdInc = MIN(_holdInc, -1); // prevent 0 on long releases
|
||||
|
||||
_holdMax = 0x7fffffff - (uint32_t)(_holdInc * (double)hold/1000.0 * _sampleRate);
|
||||
// compute tc increment, to progress from 0x7fffffff to _holdMin in PROGHOLD ms
|
||||
double progSamples = PROGHOLD/1000.0 * _sampleRate;
|
||||
_holdInc = (uint32_t)((0x7fffffff - _holdMin) / progSamples);
|
||||
_holdInc = MAX(_holdInc, 1); // prevent 0 on long releases
|
||||
|
||||
// compute initial tc, to progress from _holdMax to 0x7fffffff in hold ms
|
||||
double holdSamples = (double)hold/1000.0 * _sampleRate;
|
||||
_holdMax = 0x7fffffff + (uint32_t)(_holdInc * holdSamples);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -318,8 +323,6 @@ void GateImpl::processHistogram(int numFrames) {
|
|||
|
||||
// smooth threshold update
|
||||
_threshAdapt = threshold + MULQ31((_threshAdapt - threshold), tcThreshold);
|
||||
|
||||
//printf("threshold = %0.1f\n", (_threshAdapt - (LOG2_HEADROOM_Q15 << LOG2_FRACBITS)) * -6.02f / (1 << LOG2_FRACBITS));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -336,10 +339,8 @@ int32_t GateImpl::peakhold(int32_t peak) {
|
|||
// (_holdRel > _holdMin) progressive hold
|
||||
// (_holdRel = _holdMin) release
|
||||
|
||||
_holdRel += _holdInc; // update progressive hold
|
||||
_holdRel = MAX((uint32_t)_holdRel, (uint32_t)_holdMin); // saturate at final value
|
||||
|
||||
int32_t tc = MIN((uint32_t)_holdRel, 0x7fffffff);
|
||||
_holdRel -= _holdInc; // update progressive hold
|
||||
int32_t tc = MIN(MAX(_holdRel, _holdMin), 0x7fffffff); // saturate to [_holdMin, 0x7fffffff]
|
||||
peak += MULQ31((_holdPeak - peak), tc); // apply release
|
||||
|
||||
} else {
|
||||
|
|
|
@ -46,6 +46,10 @@ static const int STATS_FOR_STATS_PACKET_WINDOW_SECONDS = 30;
|
|||
// _currentJitterBufferFrames is updated with the time-weighted avg and the running time-weighted avg is reset.
|
||||
static const quint64 FRAMES_AVAILABLE_STAT_WINDOW_USECS = 10 * USECS_PER_SECOND;
|
||||
|
||||
// When the audio codec is switched, temporary codec mismatch is expected due to packets in-flight.
|
||||
// A SelectedAudioFormat packet is not sent until this threshold is exceeded.
|
||||
static const int MAX_MISMATCHED_AUDIO_CODEC_COUNT = 10;
|
||||
|
||||
InboundAudioStream::InboundAudioStream(int numChannels, int numFrames, int numBlocks, int numStaticJitterBlocks) :
|
||||
_ringBuffer(numChannels * numFrames, numBlocks),
|
||||
_numChannels(numChannels),
|
||||
|
@ -153,6 +157,7 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
|||
// If we recieved a SilentAudioFrame from our sender, we might want to drop
|
||||
// some of the samples in order to catch up to our desired jitter buffer size.
|
||||
writeDroppableSilentFrames(networkFrames);
|
||||
|
||||
} else {
|
||||
// note: PCM and no codec are identical
|
||||
bool selectedPCM = _selectedCodecName == "pcm" || _selectedCodecName == "";
|
||||
|
@ -160,20 +165,33 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
|||
if (codecInPacket == _selectedCodecName || (packetPCM && selectedPCM)) {
|
||||
auto afterProperties = message.readWithoutCopy(message.getBytesLeftToRead());
|
||||
parseAudioData(message.getType(), afterProperties);
|
||||
_mismatchedAudioCodecCount = 0;
|
||||
|
||||
} else {
|
||||
qDebug(audio) << "Codec mismatch: expected" << _selectedCodecName << "got" << codecInPacket << "writing silence";
|
||||
_mismatchedAudioCodecCount++;
|
||||
qDebug(audio) << "Codec mismatch: expected" << _selectedCodecName << "got" << codecInPacket;
|
||||
|
||||
// Since the data in the stream is using a codec that we aren't prepared for,
|
||||
// we need to let the codec know that we don't have data for it, this will
|
||||
// allow the codec to interpolate missing data and produce a fade to silence.
|
||||
lostAudioData(1);
|
||||
|
||||
// inform others of the mismatch
|
||||
auto sendingNode = DependencyManager::get<NodeList>()->nodeWithUUID(message.getSourceID());
|
||||
if (sendingNode) {
|
||||
emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket);
|
||||
if (packetPCM) {
|
||||
// If there are PCM packets in-flight after the codec is changed, use them.
|
||||
auto afterProperties = message.readWithoutCopy(message.getBytesLeftToRead());
|
||||
_ringBuffer.writeData(afterProperties.data(), afterProperties.size());
|
||||
} else {
|
||||
// Since the data in the stream is using a codec that we aren't prepared for,
|
||||
// we need to let the codec know that we don't have data for it, this will
|
||||
// allow the codec to interpolate missing data and produce a fade to silence.
|
||||
lostAudioData(1);
|
||||
}
|
||||
|
||||
if (_mismatchedAudioCodecCount > MAX_MISMATCHED_AUDIO_CODEC_COUNT) {
|
||||
_mismatchedAudioCodecCount = 0;
|
||||
|
||||
// inform others of the mismatch
|
||||
auto sendingNode = DependencyManager::get<NodeList>()->nodeWithUUID(message.getSourceID());
|
||||
if (sendingNode) {
|
||||
emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket);
|
||||
qDebug(audio) << "Codec mismatch threshold exceeded, SelectedAudioFormat(" << _selectedCodecName << " ) sent";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -186,6 +186,7 @@ protected:
|
|||
CodecPluginPointer _codec;
|
||||
QString _selectedCodecName;
|
||||
Decoder* _decoder { nullptr };
|
||||
int _mismatchedAudioCodecCount { 0 };
|
||||
};
|
||||
|
||||
float calculateRepeatedFrameFadeFactor(int indexOfRepeat);
|
||||
|
|
|
@ -994,10 +994,12 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
|
|||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||
return glmExtractRotation(finalMat);
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
|
||||
case CONTROLLER_LEFTHAND_INDEX: {
|
||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||
return controllerLeftHandTransform.getRotation();
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
|
||||
case CONTROLLER_RIGHTHAND_INDEX: {
|
||||
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
||||
return controllerRightHandTransform.getRotation();
|
||||
|
@ -1032,10 +1034,12 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
|||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||
return extractTranslation(finalMat);
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
|
||||
case CONTROLLER_LEFTHAND_INDEX: {
|
||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||
return controllerLeftHandTransform.getTranslation();
|
||||
}
|
||||
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
|
||||
case CONTROLLER_RIGHTHAND_INDEX: {
|
||||
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
||||
return controllerRightHandTransform.getTranslation();
|
||||
|
|
|
@ -237,19 +237,7 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||
tree->update(simulate);
|
||||
|
||||
if (simulate) {
|
||||
// Handle enter/leave entity logic
|
||||
checkEnterLeaveEntities();
|
||||
|
||||
// Even if we're not moving the mouse, if we started clicking on an entity and we have
|
||||
// not yet released the hold then this is still considered a holdingClickOnEntity event
|
||||
// and we want to simulate this message here as well as in mouse move
|
||||
if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) {
|
||||
emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the rendereable entities as needed
|
||||
{
|
||||
PerformanceTimer sceneTimer("scene");
|
||||
auto scene = _viewState->getMain3DScene();
|
||||
|
@ -269,6 +257,20 @@ void EntityTreeRenderer::update(bool simulate) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (simulate) {
|
||||
// Handle enter/leave entity logic
|
||||
checkEnterLeaveEntities();
|
||||
|
||||
// Even if we're not moving the mouse, if we started clicking on an entity and we have
|
||||
// not yet released the hold then this is still considered a holdingClickOnEntity event
|
||||
// and we want to simulate this message here as well as in mouse move
|
||||
if (_lastPointerEventValid && !_currentClickingOnEntityID.isInvalidID()) {
|
||||
emit holdingClickOnEntity(_currentClickingOnEntityID, _lastPointerEvent);
|
||||
_entitiesScriptEngine->callEntityScriptMethod(_currentClickingOnEntityID, "holdingClickOnEntity", _lastPointerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,12 @@ void ZoneEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity
|
|||
_backgroundStage->removeBackground(_backgroundIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (_hazeStage) {
|
||||
if (!HazeStage::isIndexInvalid(_hazeIndex)) {
|
||||
_hazeStage->removeHaze(_hazeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
||||
|
@ -95,6 +101,11 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
assert(_backgroundStage);
|
||||
}
|
||||
|
||||
if (!_hazeStage) {
|
||||
_hazeStage = args->_scene->getStage<HazeStage>();
|
||||
assert(_hazeStage);
|
||||
}
|
||||
|
||||
{ // Sun
|
||||
// Need an update ?
|
||||
if (_needSunUpdate) {
|
||||
|
@ -136,6 +147,15 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
}
|
||||
}
|
||||
|
||||
{
|
||||
if (_needHazeUpdate) {
|
||||
if (HazeStage::isIndexInvalid(_hazeIndex)) {
|
||||
_hazeIndex = _hazeStage->addHaze(_haze);
|
||||
}
|
||||
_needHazeUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_visible) {
|
||||
// FInally, push the light visible in the frame
|
||||
// THe directional key light for sure
|
||||
|
@ -150,6 +170,11 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
|||
if (_backgroundMode != BACKGROUND_MODE_INHERIT) {
|
||||
_backgroundStage->_currentFrame.pushBackground(_backgroundIndex);
|
||||
}
|
||||
|
||||
// Haze only if the mode is not inherit
|
||||
if (_hazeMode != COMPONENT_MODE_INHERIT) {
|
||||
_hazeStage->_currentFrame.pushHaze(_hazeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,15 +196,17 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
|||
bool sunChanged = entity->keyLightPropertiesChanged();
|
||||
bool backgroundChanged = entity->backgroundPropertiesChanged();
|
||||
bool skyboxChanged = entity->skyboxPropertiesChanged();
|
||||
bool hazeChanged = entity->hazePropertiesChanged();
|
||||
|
||||
entity->resetRenderingPropertiesChanged();
|
||||
_lastPosition = entity->getPosition();
|
||||
_lastRotation = entity->getRotation();
|
||||
_lastDimensions = entity->getDimensions();
|
||||
|
||||
_keyLightProperties = entity->getKeyLightProperties();
|
||||
_stageProperties = entity->getStageProperties();
|
||||
_skyboxProperties = entity->getSkyboxProperties();
|
||||
|
||||
_hazeProperties = entity->getHazeProperties();
|
||||
_stageProperties = entity->getStageProperties();
|
||||
|
||||
#if 0
|
||||
if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) {
|
||||
|
@ -209,9 +236,14 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
|||
if (sunChanged || skyboxChanged) {
|
||||
updateKeyAmbientFromEntity();
|
||||
}
|
||||
|
||||
if (backgroundChanged || skyboxChanged) {
|
||||
updateKeyBackgroundFromEntity(entity);
|
||||
}
|
||||
|
||||
if (hazeChanged) {
|
||||
updateHazeFromEntity(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||
|
@ -228,6 +260,7 @@ ItemKey ZoneEntityRenderer::getKey() {
|
|||
bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||
if (entity->keyLightPropertiesChanged() ||
|
||||
entity->backgroundPropertiesChanged() ||
|
||||
entity->hazePropertiesChanged() ||
|
||||
entity->skyboxPropertiesChanged()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -298,6 +331,36 @@ void ZoneEntityRenderer::updateKeyAmbientFromEntity() {
|
|||
}
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity) {
|
||||
setHazeMode((ComponentMode)entity->getHazeMode());
|
||||
|
||||
const auto& haze = editHaze();
|
||||
|
||||
const uint32_t hazeMode = entity->getHazeMode();
|
||||
haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED);
|
||||
haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect());
|
||||
|
||||
haze->setHazeRangeFactor(model::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange()));
|
||||
xColor hazeColor = _hazeProperties.getHazeColor();
|
||||
haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0));
|
||||
xColor hazeGlareColor = _hazeProperties.getHazeGlareColor();
|
||||
haze->setDirectionalLightColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0));
|
||||
haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare());
|
||||
haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(_hazeProperties.getHazeGlareAngle()));
|
||||
|
||||
float hazeAltitude = _hazeProperties.getHazeCeiling() - _hazeProperties.getHazeBaseRef();
|
||||
haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude));
|
||||
haze->setHazeBaseReference(_hazeProperties.getHazeBaseRef());
|
||||
|
||||
haze->setHazeBackgroundBlendValue(_hazeProperties.getHazeBackgroundBlend());
|
||||
|
||||
haze->setHazeAttenuateKeyLight(_hazeProperties.getHazeAttenuateKeyLight());
|
||||
haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange()));
|
||||
haze->setHazeKeyLightAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(_hazeProperties.getHazeKeyLightAltitude()));
|
||||
|
||||
haze->setZoneTransform(entity->getTransform().getMatrix());
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& entity) {
|
||||
editBackground();
|
||||
setBackgroundMode(entity->getBackgroundMode());
|
||||
|
@ -408,6 +471,10 @@ void ZoneEntityRenderer::setBackgroundMode(BackgroundMode mode) {
|
|||
_backgroundMode = mode;
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::setHazeMode(ComponentMode mode) {
|
||||
_hazeMode = mode;
|
||||
}
|
||||
|
||||
void ZoneEntityRenderer::setSkyboxColor(const glm::vec3& color) {
|
||||
editSkybox()->setColor(color);
|
||||
}
|
||||
|
|
|
@ -14,11 +14,15 @@
|
|||
|
||||
#include <ZoneEntityItem.h>
|
||||
#include <model/Skybox.h>
|
||||
#include <model/Haze.h>
|
||||
#include <model/Stage.h>
|
||||
#include <LightStage.h>
|
||||
#include <BackgroundStage.h>
|
||||
#include <HazeStage.h>
|
||||
#include <TextureCache.h>
|
||||
#include "RenderableEntityItem.h"
|
||||
#include <ComponentMode.h>
|
||||
|
||||
#if 0
|
||||
#include <Model.h>
|
||||
#endif
|
||||
|
@ -44,12 +48,14 @@ private:
|
|||
void updateKeyZoneItemFromEntity();
|
||||
void updateKeySunFromEntity();
|
||||
void updateKeyAmbientFromEntity();
|
||||
void updateHazeFromEntity(const TypedEntityPointer& entity);
|
||||
void updateKeyBackgroundFromEntity(const TypedEntityPointer& entity);
|
||||
void updateAmbientMap();
|
||||
void updateSkyboxMap();
|
||||
void setAmbientURL(const QString& ambientUrl);
|
||||
void setSkyboxURL(const QString& skyboxUrl);
|
||||
void setBackgroundMode(BackgroundMode mode);
|
||||
void setHazeMode(ComponentMode mode);
|
||||
void setSkyboxColor(const glm::vec3& color);
|
||||
void setProceduralUserData(const QString& userData);
|
||||
|
||||
|
@ -57,7 +63,7 @@ private:
|
|||
model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; }
|
||||
model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; }
|
||||
model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
|
||||
|
||||
model::HazePointer editHaze() { _needHazeUpdate = true; return _haze; }
|
||||
|
||||
bool _needsInitialSimulation{ true };
|
||||
glm::vec3 _lastPosition;
|
||||
|
@ -76,7 +82,10 @@ private:
|
|||
const model::LightPointer _sunLight{ std::make_shared<model::Light>() };
|
||||
const model::LightPointer _ambientLight{ std::make_shared<model::Light>() };
|
||||
const model::SunSkyStagePointer _background{ std::make_shared<model::SunSkyStage>() };
|
||||
const model::HazePointer _haze{ std::make_shared<model::Haze>() };
|
||||
|
||||
BackgroundMode _backgroundMode{ BACKGROUND_MODE_INHERIT };
|
||||
ComponentMode _hazeMode{ COMPONENT_MODE_INHERIT };
|
||||
|
||||
indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX };
|
||||
indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX };
|
||||
|
@ -84,12 +93,17 @@ private:
|
|||
BackgroundStagePointer _backgroundStage;
|
||||
BackgroundStage::Index _backgroundIndex{ BackgroundStage::INVALID_INDEX };
|
||||
|
||||
HazeStagePointer _hazeStage;
|
||||
HazeStage::Index _hazeIndex{ HazeStage::INVALID_INDEX };
|
||||
|
||||
bool _needUpdate{ true };
|
||||
bool _needSunUpdate{ true };
|
||||
bool _needAmbientUpdate{ true };
|
||||
bool _needBackgroundUpdate{ true };
|
||||
bool _needHazeUpdate{ true };
|
||||
|
||||
KeyLightPropertyGroup _keyLightProperties;
|
||||
HazePropertyGroup _hazeProperties;
|
||||
StagePropertyGroup _stageProperties;
|
||||
SkyboxPropertyGroup _skyboxProperties;
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
AnimationPropertyGroup EntityItemProperties::_staticAnimation;
|
||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||
HazePropertyGroup EntityItemProperties::_staticHaze;
|
||||
StagePropertyGroup EntityItemProperties::_staticStage;
|
||||
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
||||
|
||||
|
@ -71,6 +72,7 @@ void EntityItemProperties::debugDump() const {
|
|||
|
||||
getAnimation().debugDump();
|
||||
getSkybox().debugDump();
|
||||
getHaze().debugDump();
|
||||
getKeyLight().debugDump();
|
||||
|
||||
qCDebug(entities) << " changed properties...";
|
||||
|
@ -218,6 +220,32 @@ void EntityItemProperties::setBackgroundModeFromString(const QString& background
|
|||
}
|
||||
}
|
||||
|
||||
using ComponentPair = std::pair<const ComponentMode, const QString>;
|
||||
const std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT> COMPONENT_MODES = { {
|
||||
ComponentPair{ COMPONENT_MODE_INHERIT,{ "inherit" } },
|
||||
ComponentPair{ COMPONENT_MODE_DISABLED,{ "disabled" } },
|
||||
ComponentPair{ COMPONENT_MODE_ENABLED,{ "enabled" } }
|
||||
} };
|
||||
|
||||
QString EntityItemProperties::getHazeModeAsString() const {
|
||||
return COMPONENT_MODES[_hazeMode].second;
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getHazeModeString(uint32_t mode) {
|
||||
return COMPONENT_MODES[mode].second;
|
||||
}
|
||||
|
||||
void EntityItemProperties::setHazeModeFromString(const QString& hazeMode) {
|
||||
auto result = std::find_if(COMPONENT_MODES.begin(), COMPONENT_MODES.end(), [&](const ComponentPair& pair) {
|
||||
return (pair.second == hazeMode);
|
||||
});
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_hazeMode = result->first;
|
||||
_hazeModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
|
@ -303,6 +331,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
|
||||
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
||||
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_MODE, hazeMode);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_SOURCE_URL, sourceUrl);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_DATA, voxelData);
|
||||
|
@ -350,6 +381,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
changedProperties += _keyLight.getChangedProperties();
|
||||
changedProperties += _skybox.getChangedProperties();
|
||||
changedProperties += _stage.getChangedProperties();
|
||||
changedProperties += _haze.getChangedProperties();
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
@ -529,6 +561,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
|
||||
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_HAZE_MODE, hazeMode, getHazeModeAsString());
|
||||
_haze.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||
}
|
||||
|
||||
// Web only
|
||||
|
@ -712,6 +747,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(hazeMode, HazeMode);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(sourceUrl, QString, setSourceUrl);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, glmVec3, setVoxelVolumeSize);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelData, QByteArray, setVoxelData);
|
||||
|
@ -739,6 +777,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
|||
_keyLight.copyFromScriptValue(object, _defaultSettings);
|
||||
_skybox.copyFromScriptValue(object, _defaultSettings);
|
||||
_stage.copyFromScriptValue(object, _defaultSettings);
|
||||
_haze.copyFromScriptValue(object, _defaultSettings);
|
||||
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
|
||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
|
||||
|
@ -862,6 +901,9 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(collisionSoundURL);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(backgroundMode);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeMode);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(sourceUrl);
|
||||
COPY_PROPERTY_IF_CHANGED(voxelVolumeSize);
|
||||
COPY_PROPERTY_IF_CHANGED(voxelData);
|
||||
|
@ -880,6 +922,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
|||
_keyLight.merge(other._keyLight);
|
||||
_skybox.merge(other._skybox);
|
||||
_stage.merge(other._stage);
|
||||
_haze.merge(other._haze);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(xTextureURL);
|
||||
COPY_PROPERTY_IF_CHANGED(yTextureURL);
|
||||
|
@ -1110,6 +1153,24 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
|||
ADD_PROPERTY_TO_MAP(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool);
|
||||
ADD_PROPERTY_TO_MAP(PROP_FILTER_URL, FilterURL, filterURL, QString);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_HAZE_MODE, HazeMode, hazeMode, uint32_t);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ENABLE_GLARE, Haze, haze, HazeEnableGlare, hazeEnableGlare);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_GLARE_ANGLE, Haze, haze, HazeGlareAngle, hazeGlareAngle);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ALTITUDE_EFFECT, Haze, haze, HazeAltitudeEffect, hazeAltitudeEfect);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_CEILING, Haze, haze, HazeCeiling, hazeCeiling);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_BASE_REF, Haze, haze, HazeBaseRef, hazeBaseRef);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_BACKGROUND_BLEND, Haze, haze, HazeBackgroundBlend, hazeBackgroundBlend);
|
||||
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_ATTENUATE_KEYLIGHT, Haze, haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_KEYLIGHT_RANGE, Haze, haze, HazeKeyLightRange, hazeKeyLightRange);
|
||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_HAZE_KEYLIGHT_ALTITUDE, Haze, haze, HazeKeyLightAltitude, hazeKeyLightAltitude);
|
||||
|
||||
ADD_PROPERTY_TO_MAP(PROP_DPI, DPI, dpi, uint16_t);
|
||||
|
||||
// FIXME - these are not yet handled
|
||||
|
@ -1358,6 +1419,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
|||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, properties.getFilterURL());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, (uint32_t)properties.getHazeMode());
|
||||
_staticHaze.setProperties(properties);
|
||||
_staticHaze.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyVox) {
|
||||
|
@ -1664,7 +1729,10 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FILTER_URL, QString, setFilterURL);
|
||||
}
|
||||
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_HAZE_MODE, uint32_t, setHazeMode);
|
||||
properties.getHaze().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
}
|
||||
|
||||
if (properties.getType() == EntityTypes::PolyVox) {
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize);
|
||||
|
@ -1843,10 +1911,12 @@ void EntityItemProperties::markAllChanged() {
|
|||
_keyLight.markAllChanged();
|
||||
|
||||
_backgroundModeChanged = true;
|
||||
_hazeModeChanged = true;
|
||||
|
||||
_animation.markAllChanged();
|
||||
_skybox.markAllChanged();
|
||||
_stage.markAllChanged();
|
||||
_haze.markAllChanged();
|
||||
|
||||
_sourceUrlChanged = true;
|
||||
_voxelVolumeSizeChanged = true;
|
||||
|
@ -2181,6 +2251,11 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
if (backgroundModeChanged()) {
|
||||
out += "backgroundMode";
|
||||
}
|
||||
|
||||
if (hazeModeChanged()) {
|
||||
out += "hazeMode";
|
||||
}
|
||||
|
||||
if (voxelVolumeSizeChanged()) {
|
||||
out += "voxelVolumeSize";
|
||||
}
|
||||
|
@ -2276,6 +2351,7 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
|||
getKeyLight().listChangedProperties(out);
|
||||
getSkybox().listChangedProperties(out);
|
||||
getStage().listChangedProperties(out);
|
||||
getHaze().listChangedProperties(out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "PolyVoxEntityItem.h"
|
||||
#include "SimulationOwner.h"
|
||||
#include "SkyboxPropertyGroup.h"
|
||||
#include "HazePropertyGroup.h"
|
||||
#include "StagePropertyGroup.h"
|
||||
#include "TextEntityItem.h"
|
||||
#include "ZoneEntityItem.h"
|
||||
|
@ -177,7 +178,11 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString, ENTITY_ITEM_DEFAULT_NAME);
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode, BACKGROUND_MODE_INHERIT);
|
||||
DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup);
|
||||
|
||||
DEFINE_PROPERTY_REF_ENUM(PROP_HAZE_MODE, HazeMode, hazeMode, uint32_t, (uint32_t)COMPONENT_MODE_INHERIT);
|
||||
|
||||
DEFINE_PROPERTY_GROUP(Skybox, skybox, SkyboxPropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Haze, haze, HazePropertyGroup);
|
||||
DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup);
|
||||
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, "");
|
||||
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH);
|
||||
|
@ -239,6 +244,7 @@ public:
|
|||
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
|
||||
|
||||
static QString getBackgroundModeString(BackgroundMode mode);
|
||||
static QString getHazeModeString(uint32_t mode);
|
||||
|
||||
|
||||
public:
|
||||
|
@ -451,6 +457,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
|||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CertificateID, certificateID, "");
|
||||
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, HazeMode, hazeMode, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelData, voxelData, "");
|
||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, "");
|
||||
|
|
|
@ -231,6 +231,25 @@ enum EntityPropertyList {
|
|||
PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
||||
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
||||
|
||||
PROP_HAZE_MODE = PROP_COLOR,
|
||||
|
||||
PROP_HAZE_RANGE = PROP_INTENSITY,
|
||||
PROP_HAZE_COLOR = PROP_CUTOFF,
|
||||
PROP_HAZE_GLARE_COLOR = PROP_EXPONENT,
|
||||
PROP_HAZE_ENABLE_GLARE = PROP_IS_SPOTLIGHT,
|
||||
PROP_HAZE_GLARE_ANGLE = PROP_DIFFUSE_COLOR,
|
||||
|
||||
PROP_HAZE_ALTITUDE_EFFECT = PROP_AMBIENT_COLOR_UNUSED,
|
||||
PROP_HAZE_CEILING = PROP_SPECULAR_COLOR_UNUSED,
|
||||
PROP_HAZE_BASE_REF = PROP_LINEAR_ATTENUATION_UNUSED,
|
||||
|
||||
PROP_HAZE_BACKGROUND_BLEND = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
||||
|
||||
PROP_HAZE_ATTENUATE_KEYLIGHT = PROP_ANIMATION_FRAME_INDEX,
|
||||
PROP_HAZE_KEYLIGHT_RANGE = PROP_MODEL_URL,
|
||||
PROP_HAZE_KEYLIGHT_ALTITUDE = PROP_ANIMATION_URL,
|
||||
|
||||
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,
|
||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||
PROP_KEYLIGHT_AMBIENT_URL = PROP_ANIMATION_PLAYING,
|
||||
|
|
373
libraries/entities/src/HazePropertyGroup.cpp
Normal file
|
@ -0,0 +1,373 @@
|
|||
//
|
||||
// HazePropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Nissim hadar on 9/21/17.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <OctreePacketData.h>
|
||||
|
||||
#include "HazePropertyGroup.h"
|
||||
#include "EntityItemProperties.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_RANGE{ 1000.0f };
|
||||
const xColor HazePropertyGroup::DEFAULT_HAZE_COLOR{ 128, 154, 179 }; // Bluish
|
||||
const xColor HazePropertyGroup::DEFAULT_HAZE_GLARE_COLOR{ 255, 229, 179 }; // Yellowish
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_GLARE_ANGLE{ 20.0 };
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_CEILING{ 200.0f };
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_BASE_REF{ 0.0f };
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_BACKGROUND_BLEND{ 0.0f };
|
||||
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_RANGE{ 1000.0 };
|
||||
const float HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_ALTITUDE{ 200.0f };
|
||||
|
||||
void HazePropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_RANGE, Haze, haze, HazeRange, hazeRange);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_COLOR, Haze, haze, HazeColor, hazeColor);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_GLARE_COLOR, Haze, haze, HazeGlareColor, hazeGlareColor);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ENABLE_GLARE, Haze, haze, HazeEnableGlare, hazeEnableGlare);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_GLARE_ANGLE, Haze, haze, HazeGlareAngle, hazeGlareAngle);
|
||||
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ALTITUDE_EFFECT, Haze, haze, HazeAltitudeEffect, hazeAltitudeEffect);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_CEILING, Haze, haze, HazeCeiling, hazeCeiling);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_BASE_REF, Haze, haze, HazeBaseRef, hazeBaseRef);
|
||||
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_BACKGROUND_BLEND, Haze, haze, HazeBackgroundBlend, hazeBackgroundBlend);
|
||||
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_ATTENUATE_KEYLIGHT, Haze, haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_KEYLIGHT_RANGE, Haze, haze, HazeKeyLightRange, hazeKeyLightRange);
|
||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_HAZE_KEYLIGHT_ALTITUDE, Haze, haze, HazeKeyLightAltitude, hazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
void HazePropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) {
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeRange, float, setHazeRange);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeColor, xColor, setHazeColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareColor, xColor, setHazeGlareColor);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeEnableGlare, bool, setHazeEnableGlare);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeGlareAngle, float, setHazeGlareAngle);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeAltitudeEffect, bool, setHazeAltitudeEffect);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeCeiling, float, setHazeCeiling);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeBaseRef, float, setHazeBaseRef);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeBackgroundBlend, float, setHazeBackgroundBlend);
|
||||
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeAttenuateKeyLight, bool, setHazeAttenuateKeyLight);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeKeyLightRange, float, setHazeKeyLightRange);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(haze, hazeKeyLightAltitude, float, setHazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
void HazePropertyGroup::merge(const HazePropertyGroup& other) {
|
||||
COPY_PROPERTY_IF_CHANGED(hazeRange);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeColor);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeGlareColor);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeEnableGlare);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeGlareAngle);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeAltitudeEffect);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeCeiling);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeBaseRef);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeBackgroundBlend);
|
||||
|
||||
COPY_PROPERTY_IF_CHANGED(hazeAttenuateKeyLight);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeKeyLightRange);
|
||||
COPY_PROPERTY_IF_CHANGED(hazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
void HazePropertyGroup::debugDump() const {
|
||||
qCDebug(entities) << " HazePropertyGroup: ---------------------------------------------";
|
||||
|
||||
qCDebug(entities) << " _hazeRange:" << _hazeRange;
|
||||
qCDebug(entities) << " _hazeColor:" << _hazeColor;
|
||||
qCDebug(entities) << " _hazeGlareColor:" << _hazeGlareColor;
|
||||
qCDebug(entities) << " _hazeEnableGlare:" << _hazeEnableGlare;
|
||||
qCDebug(entities) << " _hazeGlareAngle:" << _hazeGlareAngle;
|
||||
|
||||
qCDebug(entities) << " _hazeAltitudeEffect:" << _hazeAltitudeEffect;
|
||||
qCDebug(entities) << " _hazeCeiling:" << _hazeCeiling;
|
||||
qCDebug(entities) << " _hazeBaseRef:" << _hazeBaseRef;
|
||||
|
||||
qCDebug(entities) << " _hazeBackgroundBlend:" << _hazeBackgroundBlend;
|
||||
|
||||
qCDebug(entities) << " _hazeAttenuateKeyLight:" << _hazeAttenuateKeyLight;
|
||||
qCDebug(entities) << " _hazeKeyLightRange:" << _hazeKeyLightRange;
|
||||
qCDebug(entities) << " _hazeKeyLightAltitude:" << _hazeKeyLightAltitude;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
if (hazeRangeChanged()) {
|
||||
out << "haze-hazeRange";
|
||||
}
|
||||
if (hazeColorChanged()) {
|
||||
out << "haze-hazeColor";
|
||||
}
|
||||
if (hazeGlareColorChanged()) {
|
||||
out << "haze-hazeGlareColor";
|
||||
}
|
||||
if (hazeEnableGlareChanged()) {
|
||||
out << "haze-hazeEnableGlare";
|
||||
}
|
||||
if (hazeGlareAngleChanged()) {
|
||||
out << "haze-hazeGlareAngle";
|
||||
}
|
||||
|
||||
if (hazeAltitudeEffectChanged()) {
|
||||
out << "haze-hazeAltitudeEffect";
|
||||
}
|
||||
if (hazeCeilingChanged()) {
|
||||
out << "haze-hazeCeiling";
|
||||
}
|
||||
if (hazeBaseRefChanged()) {
|
||||
out << "haze-hazeBaseRef";
|
||||
}
|
||||
|
||||
if (hazeBackgroundBlendChanged()) {
|
||||
out << "haze-hazeBackgroundBlend";
|
||||
}
|
||||
|
||||
if (hazeAttenuateKeyLightChanged()) {
|
||||
out << "haze-hazeAttenuateKeyLight";
|
||||
}
|
||||
if (hazeKeyLightRangeChanged()) {
|
||||
out << "haze-hazeKeyLightRange";
|
||||
}
|
||||
if (hazeKeyLightAltitudeChanged()) {
|
||||
out << "haze-hazeKeyLightAltitude";
|
||||
}
|
||||
}
|
||||
|
||||
bool HazePropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_RANGE, getHazeRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_COLOR, getHazeColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, getHazeGlareColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, getHazeEnableGlare());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, getHazeGlareAngle());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, getHazeAltitudeEffect());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_CEILING, getHazeCeiling());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, getHazeBaseRef());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, getHazeBackgroundBlend());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, getHazeAttenuateKeyLight());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, getHazeKeyLightRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, getHazeKeyLightAltitude());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HazePropertyGroup::decodeFromEditPacket(EntityPropertyFlags& propertyFlags, const unsigned char*& dataAt , int& processedBytes) {
|
||||
|
||||
int bytesRead = 0;
|
||||
bool overwriteLocalData = true;
|
||||
bool somethingChanged = false;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_RANGE, float, setHazeRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setHazeColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, xColor, setHazeGlareColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, bool, setHazeEnableGlare);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, float, setHazeGlareAngle);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, bool, setHazeAltitudeEffect);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_CEILING, float, setHazeCeiling);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, float, setHazeBaseRef);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, float, setHazeBackgroundBlend);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, bool, setHazeAttenuateKeyLight);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, float, setHazeKeyLightRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, float, setHazeKeyLightAltitude);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_RANGE, HazeRange);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_COLOR, HazeColor);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_GLARE_COLOR, HazeGlareColor);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_ENABLE_GLARE, HazeEnableGlare);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_ALTITUDE_EFFECT, HazeAltitudeEffect);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_CEILING, HazeCeiling);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_BASE_REF, HazeBaseRef);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_BACKGROUND_BLEND, HazeBackgroundBlend);
|
||||
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_ATTENUATE_KEYLIGHT, HazeAttenuateKeyLight);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_KEYLIGHT_RANGE, HazeKeyLightRange);
|
||||
DECODE_GROUP_PROPERTY_HAS_CHANGED(PROP_HAZE_KEYLIGHT_ALTITUDE, HazeKeyLightAltitude);
|
||||
|
||||
processedBytes += bytesRead;
|
||||
|
||||
Q_UNUSED(somethingChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::markAllChanged() {
|
||||
_hazeRangeChanged = true;
|
||||
_hazeColorChanged = true;
|
||||
_hazeGlareColorChanged = true;
|
||||
_hazeEnableGlareChanged = true;
|
||||
_hazeGlareAngleChanged = true;
|
||||
|
||||
_hazeAltitudeEffectChanged = true;
|
||||
_hazeCeilingChanged = true;
|
||||
_hazeBaseRefChanged = true;
|
||||
|
||||
_hazeBackgroundBlendChanged = true;
|
||||
|
||||
_hazeAttenuateKeyLightChanged = true;
|
||||
_hazeKeyLightRangeChanged = true;
|
||||
_hazeKeyLightAltitudeChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags HazePropertyGroup::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_RANGE, hazeRange);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_COLOR, hazeColor);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_GLARE_COLOR, hazeGlareColor);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_ENABLE_GLARE, hazeEnableGlare);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_GLARE_ANGLE, hazeGlareAngle);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_ALTITUDE_EFFECT, hazeAltitudeEffect);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_CEILING, hazeCeiling);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_BASE_REF, hazeBaseRef);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_BACKGROUND_BLEND, hazeBackgroundBlend);
|
||||
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_ATTENUATE_KEYLIGHT, hazeAttenuateKeyLight);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_KEYLIGHT_RANGE, hazeKeyLightRange);
|
||||
CHECK_PROPERTY_CHANGE(PROP_HAZE_KEYLIGHT_ALTITUDE, hazeKeyLightAltitude);
|
||||
|
||||
return changedProperties;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::getProperties(EntityItemProperties& properties) const {
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeRange, getHazeRange);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeColor, getHazeColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeGlareColor, getHazeGlareColor);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeEnableGlare, getHazeEnableGlare);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeGlareAngle, getHazeGlareAngle);
|
||||
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeAltitudeEffect, getHazeAltitudeEffect);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeCeiling, getHazeCeiling);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeBaseRef, getHazeBaseRef);
|
||||
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeBackgroundBlend, getHazeBackgroundBlend);
|
||||
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeAttenuateKeyLight, getHazeAttenuateKeyLight);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeKeyLightRange, getHazeKeyLightRange);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Haze, HazeKeyLightAltitude, getHazeKeyLightAltitude);
|
||||
}
|
||||
|
||||
bool HazePropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
bool somethingChanged = false;
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeRange, hazeRange, setHazeRange);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeColor, hazeColor, setHazeColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeGlareColor, hazeGlareColor, setHazeGlareColor);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeEnableGlare, hazeEnableGlare, setHazeEnableGlare);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeGlareAngle, hazeGlareAngle, setHazeGlareAngle);
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeAltitudeEffect, hazeAltitudeEffect, setHazeAltitudeEffect);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeCeiling, hazeCeiling, setHazeCeiling);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeBaseRef, hazeBaseRef, setHazeBaseRef);
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeBackgroundBlend, hazeBackgroundBlend, setHazeBackgroundBlend);
|
||||
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeAttenuateKeyLight, hazeAttenuateKeyLight, setHazeAttenuateKeyLight);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeKeyLightRange, hazeKeyLightRange, setHazeKeyLightRange);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Haze, HazeKeyLightAltitude, hazeKeyLightAltitude, setHazeKeyLightAltitude);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
EntityPropertyFlags HazePropertyGroup::getEntityProperties(EncodeBitstreamParams& params) const {
|
||||
EntityPropertyFlags requestedProperties;
|
||||
|
||||
requestedProperties += PROP_HAZE_RANGE;
|
||||
requestedProperties += PROP_HAZE_COLOR;
|
||||
requestedProperties += PROP_HAZE_GLARE_COLOR;
|
||||
requestedProperties += PROP_HAZE_ENABLE_GLARE;
|
||||
requestedProperties += PROP_HAZE_GLARE_ANGLE;
|
||||
|
||||
requestedProperties += PROP_HAZE_CEILING;
|
||||
requestedProperties += PROP_HAZE_BASE_REF;
|
||||
|
||||
requestedProperties += PROP_HAZE_BACKGROUND_BLEND;
|
||||
|
||||
requestedProperties += PROP_HAZE_ATTENUATE_KEYLIGHT;
|
||||
requestedProperties += PROP_HAZE_KEYLIGHT_RANGE;
|
||||
requestedProperties += PROP_HAZE_KEYLIGHT_ALTITUDE;
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
void HazePropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const {
|
||||
|
||||
bool successPropertyFits = true;
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_RANGE, getHazeRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_COLOR, getHazeColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, getHazeGlareColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, getHazeEnableGlare());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, getHazeGlareAngle());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, getHazeAltitudeEffect());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_CEILING, getHazeCeiling());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, getHazeBaseRef());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, getHazeBackgroundBlend());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, getHazeAttenuateKeyLight());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, getHazeKeyLightRange());
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, getHazeKeyLightAltitude());
|
||||
}
|
||||
|
||||
int HazePropertyGroup::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) {
|
||||
|
||||
int bytesRead = 0;
|
||||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_RANGE, float, setHazeRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_COLOR, xColor, setHazeColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_COLOR, xColor, setHazeGlareColor);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ENABLE_GLARE, bool, setHazeEnableGlare);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_GLARE_ANGLE, float, setHazeGlareAngle);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, bool, setHazeAltitudeEffect);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_CEILING, float, setHazeCeiling);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BASE_REF, float, setHazeBaseRef);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_BACKGROUND_BLEND, float, setHazeBackgroundBlend);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, bool, setHazeAttenuateKeyLight);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_RANGE, float, setHazeKeyLightRange);
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_KEYLIGHT_ALTITUDE, float, setHazeKeyLightAltitude);
|
||||
|
||||
return bytesRead;
|
||||
}
|
111
libraries/entities/src/HazePropertyGroup.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// HazePropertyGroup.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Nissim hadar on 9/21/17.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_HazePropertyGroup_h
|
||||
#define hifi_HazePropertyGroup_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QtScript/QScriptEngine>
|
||||
|
||||
#include "PropertyGroup.h"
|
||||
#include "EntityItemPropertiesMacros.h"
|
||||
|
||||
class EntityItemProperties;
|
||||
class EncodeBitstreamParams;
|
||||
class OctreePacketData;
|
||||
class EntityTreeElementExtraEncodeData;
|
||||
class ReadBitstreamToTreeParams;
|
||||
|
||||
class HazePropertyGroup : public PropertyGroup {
|
||||
public:
|
||||
// EntityItemProperty related helpers
|
||||
virtual void copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties,
|
||||
QScriptEngine* engine, bool skipDefaults,
|
||||
EntityItemProperties& defaultEntityProperties) const override;
|
||||
virtual void copyFromScriptValue(const QScriptValue& object, bool& _defaultSettings) override;
|
||||
|
||||
void merge(const HazePropertyGroup& other);
|
||||
|
||||
virtual void debugDump() const override;
|
||||
virtual void listChangedProperties(QList<QString>& out) override;
|
||||
|
||||
virtual bool appendToEditPacket(OctreePacketData* packetData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual bool decodeFromEditPacket(EntityPropertyFlags& propertyFlags,
|
||||
const unsigned char*& dataAt, int& processedBytes) override;
|
||||
virtual void markAllChanged() override;
|
||||
virtual EntityPropertyFlags getChangedProperties() const override;
|
||||
|
||||
// EntityItem related helpers
|
||||
// methods for getting/setting all properties of an entity
|
||||
virtual void getProperties(EntityItemProperties& propertiesOut) const override;
|
||||
|
||||
/// returns true if something changed
|
||||
virtual bool setProperties(const EntityItemProperties& properties) override;
|
||||
|
||||
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const override;
|
||||
|
||||
virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params,
|
||||
EntityTreeElementExtraEncodeDataPointer entityTreeElementExtraEncodeData,
|
||||
EntityPropertyFlags& requestedProperties,
|
||||
EntityPropertyFlags& propertyFlags,
|
||||
EntityPropertyFlags& propertiesDidntFit,
|
||||
int& propertyCount,
|
||||
OctreeElement::AppendState& appendState) const override;
|
||||
|
||||
virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead,
|
||||
ReadBitstreamToTreeParams& args,
|
||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||
bool& somethingChanged) override;
|
||||
|
||||
static const float DEFAULT_HAZE_RANGE;
|
||||
static const xColor DEFAULT_HAZE_COLOR;
|
||||
static const xColor DEFAULT_HAZE_GLARE_COLOR;
|
||||
static const float DEFAULT_HAZE_GLARE_ANGLE;
|
||||
|
||||
static const float DEFAULT_HAZE_CEILING;
|
||||
static const float DEFAULT_HAZE_BASE_REF;
|
||||
|
||||
static const float DEFAULT_HAZE_BACKGROUND_BLEND;
|
||||
|
||||
static const float DEFAULT_HAZE_KEYLIGHT_RANGE;
|
||||
static const float DEFAULT_HAZE_KEYLIGHT_ALTITUDE;
|
||||
|
||||
// Range only parameters
|
||||
DEFINE_PROPERTY(PROP_HAZE_RANGE, HazeRange, hazeRange, float, DEFAULT_HAZE_RANGE);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_COLOR, HazeColor, hazeColor, xColor, DEFAULT_HAZE_COLOR);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_COLOR, HazeGlareColor, hazeGlareColor, xColor, DEFAULT_HAZE_GLARE_COLOR);
|
||||
DEFINE_PROPERTY(PROP_HAZE_ENABLE_GLARE, HazeEnableGlare, hazeEnableGlare, bool, false);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_GLARE_ANGLE, HazeGlareAngle, hazeGlareAngle, float, DEFAULT_HAZE_GLARE_ANGLE);
|
||||
|
||||
// Altitude parameters
|
||||
DEFINE_PROPERTY(PROP_HAZE_ALTITUDE_EFFECT, HazeAltitudeEffect, hazeAltitudeEffect, bool, false);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_CEILING, HazeCeiling, hazeCeiling, float, DEFAULT_HAZE_CEILING);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_BASE_REF, HazeBaseRef, hazeBaseRef, float, DEFAULT_HAZE_BASE_REF);
|
||||
|
||||
// Background (skybox) blend value
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_BACKGROUND_BLEND, HazeBackgroundBlend, hazeBackgroundBlend, float, DEFAULT_HAZE_BACKGROUND_BLEND);
|
||||
|
||||
// hazeDirectional light attenuation
|
||||
DEFINE_PROPERTY(PROP_HAZE_ATTENUATE_KEYLIGHT, HazeAttenuateKeyLight, hazeAttenuateKeyLight, bool, false);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_RANGE, HazeKeyLightRange, hazeKeyLightRange, float, DEFAULT_HAZE_KEYLIGHT_RANGE);
|
||||
DEFINE_PROPERTY_REF(PROP_HAZE_KEYLIGHT_ALTITUDE, HazeKeyLightAltitude, hazeKeyLightAltitude, float, DEFAULT_HAZE_KEYLIGHT_ALTITUDE);
|
||||
};
|
||||
|
||||
#endif // hifi_HazePropertyGroup_h
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// KeyLightPropertyGroup.h
|
||||
// KeyLightPropertyGroup.cpp
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Sam Gateau on 2015/10/23.
|
||||
|
|
|
@ -69,6 +69,9 @@ EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredPr
|
|||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(filterURL, getFilterURL);
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(hazeMode, getHazeMode);
|
||||
_hazeProperties.getProperties(properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
@ -104,16 +107,19 @@ bool ZoneEntityItem::setSubClassProperties(const EntityItemProperties& propertie
|
|||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(filterURL, setFilterURL);
|
||||
|
||||
// Contains a QString property, must be synchronized
|
||||
withWriteLock([&] {
|
||||
_skyboxPropertiesChanged = _skyboxProperties.setProperties(properties);
|
||||
});
|
||||
|
||||
somethingChanged = somethingChanged || _keyLightPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged;
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(filterURL, setFilterURL);
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(hazeMode, setHazeMode);
|
||||
_hazePropertiesChanged = _hazeProperties.setProperties(properties);
|
||||
|
||||
somethingChanged = somethingChanged || _keyLightPropertiesChanged || _stagePropertiesChanged || _skyboxPropertiesChanged || _hazePropertiesChanged;
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
@ -158,6 +164,15 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
|||
READ_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||
READ_ENTITY_PROPERTY(PROP_FILTER_URL, QString, setFilterURL);
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_HAZE_MODE, uint32_t, setHazeMode);
|
||||
|
||||
int bytesFromHaze = _hazeProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args,
|
||||
propertyFlags, overwriteLocalData, _hazePropertiesChanged);
|
||||
|
||||
somethingChanged = somethingChanged || _hazePropertiesChanged;
|
||||
bytesRead += bytesFromHaze;
|
||||
dataAt += bytesFromHaze;
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
|
@ -170,10 +185,11 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += _keyLightProperties.getEntityProperties(params);
|
||||
});
|
||||
|
||||
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||
|
||||
requestedProperties += PROP_SHAPE_TYPE;
|
||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||
requestedProperties += PROP_BACKGROUND_MODE;
|
||||
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||
|
||||
withReadLock([&] {
|
||||
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
||||
|
@ -183,6 +199,9 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
|||
requestedProperties += PROP_GHOSTING_ALLOWED;
|
||||
requestedProperties += PROP_FILTER_URL;
|
||||
|
||||
requestedProperties += PROP_HAZE_MODE;
|
||||
requestedProperties += _hazeProperties.getEntityProperties(params);
|
||||
|
||||
return requestedProperties;
|
||||
}
|
||||
|
||||
|
@ -208,11 +227,15 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
|||
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
||||
|
||||
_skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, getFlyingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
|
||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, getFilterURL());
|
||||
|
||||
APPEND_ENTITY_PROPERTY(PROP_HAZE_MODE, (uint32_t)getHazeMode());
|
||||
_hazeProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||
}
|
||||
|
||||
void ZoneEntityItem::debugDump() const {
|
||||
|
@ -222,10 +245,12 @@ void ZoneEntityItem::debugDump() const {
|
|||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
||||
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode);
|
||||
|
||||
_keyLightProperties.debugDump();
|
||||
_stageProperties.debugDump();
|
||||
_skyboxProperties.debugDump();
|
||||
_hazeProperties.debugDump();
|
||||
_stageProperties.debugDump();
|
||||
}
|
||||
|
||||
ShapeType ZoneEntityItem::getShapeType() const {
|
||||
|
@ -289,7 +314,117 @@ void ZoneEntityItem::resetRenderingPropertiesChanged() {
|
|||
withWriteLock([&] {
|
||||
_keyLightPropertiesChanged = false;
|
||||
_backgroundPropertiesChanged = false;
|
||||
_stagePropertiesChanged = false;
|
||||
_skyboxPropertiesChanged = false;
|
||||
_hazePropertiesChanged = false;
|
||||
_stagePropertiesChanged = false;
|
||||
});
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeMode(const uint32_t value) {
|
||||
_hazeMode = value;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
uint32_t ZoneEntityItem::getHazeMode() const {
|
||||
return _hazeMode;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeRange(const float hazeRange) {
|
||||
_hazeRange = hazeRange;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeRange() const {
|
||||
return _hazeRange;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeColor(const xColor hazeColor) {
|
||||
_hazeColor = hazeColor;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
xColor ZoneEntityItem::getHazeColor() const {
|
||||
return _hazeColor;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeGlareColor(const xColor hazeGlareColor) {
|
||||
_hazeGlareColor = hazeGlareColor;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
xColor ZoneEntityItem::getHazeGlareColor()const {
|
||||
return _hazeGlareColor;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeEnableGlare(const bool hazeEnableGlare) {
|
||||
_hazeEnableGlare = hazeEnableGlare;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
bool ZoneEntityItem::getHazeEnableGlare()const {
|
||||
return _hazeEnableGlare;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeGlareAngle(const float hazeGlareAngle) {
|
||||
_hazeGlareAngle = hazeGlareAngle;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeGlareAngle() const {
|
||||
return _hazeGlareAngle;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeCeiling(const float hazeCeiling) {
|
||||
_hazeCeiling = hazeCeiling;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeCeiling() const {
|
||||
return _hazeCeiling;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeBaseRef(const float hazeBaseRef) {
|
||||
_hazeBaseRef = hazeBaseRef;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeBaseRef() const {
|
||||
return _hazeBaseRef;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeBackgroundBlend(const float hazeBackgroundBlend) {
|
||||
_hazeBackgroundBlend = hazeBackgroundBlend;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeBackgroundBlend() const {
|
||||
return _hazeBackgroundBlend;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeAttenuateKeyLight(const bool hazeAttenuateKeyLight) {
|
||||
_hazeAttenuateKeyLight = hazeAttenuateKeyLight;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
bool ZoneEntityItem::getHazeAttenuateKeyLight() const {
|
||||
return _hazeAttenuateKeyLight;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeKeyLightRange(const float hazeKeyLightRange) {
|
||||
_hazeKeyLightRange = hazeKeyLightRange;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeKeyLightRange() const {
|
||||
return _hazeKeyLightRange;
|
||||
}
|
||||
|
||||
void ZoneEntityItem::setHazeKeyLightAltitude(const float hazeKeyLightAltitude) {
|
||||
_hazeKeyLightAltitude = hazeKeyLightAltitude;
|
||||
_hazePropertiesChanged = true;
|
||||
}
|
||||
|
||||
float ZoneEntityItem::getHazeKeyLightAltitude() const {
|
||||
return _hazeKeyLightAltitude;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
#include "EntityItem.h"
|
||||
#include "EntityTree.h"
|
||||
#include "SkyboxPropertyGroup.h"
|
||||
#include "HazePropertyGroup.h"
|
||||
#include "StagePropertyGroup.h"
|
||||
#include <ComponentMode.h>
|
||||
|
||||
class ZoneEntityItem : public EntityItem {
|
||||
public:
|
||||
|
@ -68,7 +70,39 @@ public:
|
|||
void setBackgroundMode(BackgroundMode value) { _backgroundMode = value; _backgroundPropertiesChanged = true; }
|
||||
BackgroundMode getBackgroundMode() const { return _backgroundMode; }
|
||||
|
||||
void setHazeMode(const uint32_t value);
|
||||
uint32_t getHazeMode() const;
|
||||
|
||||
void setHazeRange(const float hazeRange);
|
||||
float getHazeRange() const;
|
||||
void setHazeColor(const xColor hazeColor);
|
||||
xColor getHazeColor() const;
|
||||
void setHazeGlareColor(const xColor hazeGlareColor);
|
||||
xColor getHazeGlareColor() const;
|
||||
void setHazeEnableGlare(const bool hazeEnableGlare);
|
||||
bool getHazeEnableGlare() const;
|
||||
void setHazeGlareAngle(const float hazeGlareAngle);
|
||||
float getHazeGlareAngle() const;
|
||||
|
||||
void setHazeCeiling(const float hazeCeiling);
|
||||
float getHazeCeiling() const;
|
||||
void setHazeBaseRef(const float hazeBaseRef);
|
||||
float getHazeBaseRef() const;
|
||||
|
||||
void setHazeBackgroundBlend(const float hazeBackgroundBlend);
|
||||
float getHazeBackgroundBlend() const;
|
||||
|
||||
void setHazeAttenuateKeyLight(const bool hazeAttenuateKeyLight);
|
||||
bool getHazeAttenuateKeyLight() const;
|
||||
void setHazeKeyLightRange(const float hazeKeyLightRange);
|
||||
float getHazeKeyLightRange() const;
|
||||
void setHazeKeyLightAltitude(const float hazeKeyLightAltitude);
|
||||
float getHazeKeyLightAltitude() const;
|
||||
|
||||
SkyboxPropertyGroup getSkyboxProperties() const { return resultWithReadLock<SkyboxPropertyGroup>([&] { return _skyboxProperties; }); }
|
||||
|
||||
const HazePropertyGroup& getHazeProperties() const { return _hazeProperties; }
|
||||
|
||||
const StagePropertyGroup& getStageProperties() const { return _stageProperties; }
|
||||
|
||||
bool getFlyingAllowed() const { return _flyingAllowed; }
|
||||
|
@ -80,9 +114,14 @@ public:
|
|||
|
||||
bool keyLightPropertiesChanged() const { return _keyLightPropertiesChanged; }
|
||||
bool backgroundPropertiesChanged() const { return _backgroundPropertiesChanged; }
|
||||
bool stagePropertiesChanged() const { return _stagePropertiesChanged; }
|
||||
bool skyboxPropertiesChanged() const { return _skyboxPropertiesChanged; }
|
||||
|
||||
bool hazePropertiesChanged() const {
|
||||
return _hazePropertiesChanged;
|
||||
}
|
||||
|
||||
bool stagePropertiesChanged() const { return _stagePropertiesChanged; }
|
||||
|
||||
void resetRenderingPropertiesChanged();
|
||||
|
||||
virtual bool supportsDetailedRayIntersection() const override { return true; }
|
||||
|
@ -107,8 +146,26 @@ protected:
|
|||
|
||||
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
||||
|
||||
StagePropertyGroup _stageProperties;
|
||||
uint8_t _hazeMode{ (uint8_t)COMPONENT_MODE_INHERIT };
|
||||
|
||||
float _hazeRange{ HazePropertyGroup::DEFAULT_HAZE_RANGE };
|
||||
xColor _hazeColor{ HazePropertyGroup::DEFAULT_HAZE_COLOR };
|
||||
xColor _hazeGlareColor{ HazePropertyGroup::DEFAULT_HAZE_GLARE_COLOR };
|
||||
bool _hazeEnableGlare{ false };
|
||||
float _hazeGlareAngle{ HazePropertyGroup::DEFAULT_HAZE_GLARE_ANGLE };
|
||||
|
||||
float _hazeCeiling{ HazePropertyGroup::DEFAULT_HAZE_CEILING };
|
||||
float _hazeBaseRef{ HazePropertyGroup::DEFAULT_HAZE_BASE_REF };
|
||||
|
||||
float _hazeBackgroundBlend{ HazePropertyGroup::DEFAULT_HAZE_BACKGROUND_BLEND };
|
||||
|
||||
bool _hazeAttenuateKeyLight{ false };
|
||||
float _hazeKeyLightRange{ HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_RANGE };
|
||||
float _hazeKeyLightAltitude{ HazePropertyGroup::DEFAULT_HAZE_KEYLIGHT_ALTITUDE };
|
||||
|
||||
SkyboxPropertyGroup _skyboxProperties;
|
||||
HazePropertyGroup _hazeProperties;
|
||||
StagePropertyGroup _stageProperties;
|
||||
|
||||
bool _flyingAllowed { DEFAULT_FLYING_ALLOWED };
|
||||
bool _ghostingAllowed { DEFAULT_GHOSTING_ALLOWED };
|
||||
|
@ -116,8 +173,9 @@ protected:
|
|||
|
||||
// Dirty flags turn true when either keylight properties is changing values.
|
||||
bool _keyLightPropertiesChanged { false };
|
||||
bool _backgroundPropertiesChanged { false };
|
||||
bool _backgroundPropertiesChanged{ false };
|
||||
bool _skyboxPropertiesChanged { false };
|
||||
bool _hazePropertiesChanged{ false };
|
||||
bool _stagePropertiesChanged { false };
|
||||
|
||||
static bool _drawZoneBoundaries;
|
||||
|
|
|
@ -983,6 +983,9 @@ public:
|
|||
glm::vec2 dstCoord;
|
||||
glm::ivec2 srcPixel;
|
||||
for (int y = 0; y < faceWidth; ++y) {
|
||||
QRgb* destScanLineBegin = reinterpret_cast<QRgb*>( image.scanLine(y) );
|
||||
QRgb* destPixelIterator = destScanLineBegin;
|
||||
|
||||
dstCoord.y = 1.0f - (y + 0.5f) * dstInvSize.y; // Fill cube face images from top to bottom
|
||||
for (int x = 0; x < faceWidth; ++x) {
|
||||
dstCoord.x = (x + 0.5f) * dstInvSize.x;
|
||||
|
@ -995,13 +998,19 @@ public:
|
|||
srcPixel.y = floor((1.0f - srcCoord.y) * srcFaceHeight);
|
||||
|
||||
if (((uint32)srcPixel.x < (uint32)source.width()) && ((uint32)srcPixel.y < (uint32)source.height())) {
|
||||
image.setPixel(x, y, source.pixel(QPoint(srcPixel.x, srcPixel.y)));
|
||||
// We can't directly use the pixel() method because that launches a pixel color conversion to output
|
||||
// a correct RGBA8 color. But in our case we may have stored HDR values encoded in a RGB30 format which
|
||||
// are not convertible by Qt. The same goes with the setPixel method, by the way.
|
||||
const QRgb* sourcePixelIterator = reinterpret_cast<const QRgb*>(source.scanLine(srcPixel.y));
|
||||
sourcePixelIterator += srcPixel.x;
|
||||
*destPixelIterator = *sourcePixelIterator;
|
||||
|
||||
// Keep for debug, this is showing the dir as a color
|
||||
// glm::u8vec4 rgba((xyzDir.x + 1.0)*0.5 * 256, (xyzDir.y + 1.0)*0.5 * 256, (xyzDir.z + 1.0)*0.5 * 256, 256);
|
||||
// unsigned int val = 0xff000000 | (rgba.r) | (rgba.g << 8) | (rgba.b << 16);
|
||||
// image.setPixel(x, y, val);
|
||||
// *destPixelIterator = val;
|
||||
}
|
||||
++destPixelIterator;
|
||||
}
|
||||
}
|
||||
return image;
|
||||
|
@ -1192,6 +1201,10 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage&
|
|||
if ((srcImage.width() > 0) && (srcImage.height() > 0)) {
|
||||
QImage image = processSourceImage(srcImage, true);
|
||||
|
||||
if (image.format() != QIMAGE_HDR_FORMAT) {
|
||||
image = convertToHDRFormat(image, HDR_FORMAT);
|
||||
}
|
||||
|
||||
gpu::Element formatMip;
|
||||
gpu::Element formatGPU;
|
||||
if (isCubeTexturesCompressionEnabled()) {
|
||||
|
@ -1229,13 +1242,6 @@ gpu::TexturePointer TextureUsage::processCubeTextureColorFromImage(const QImage&
|
|||
faces.push_back(faceImage);
|
||||
}
|
||||
}
|
||||
|
||||
if (image.format() != QIMAGE_HDR_FORMAT) {
|
||||
for (auto& face : faces) {
|
||||
face = convertToHDRFormat(face, HDR_FORMAT);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
qCDebug(imagelogging) << "Failed to find a known cube map layout from this image:" << QString(srcImageName.c_str());
|
||||
return nullptr;
|
||||
|
|
174
libraries/model/src/model/Haze.cpp
Normal file
|
@ -0,0 +1,174 @@
|
|||
//
|
||||
// Haze.cpp
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Nissim Hadar on 9/13/2017.
|
||||
// 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 <memory>
|
||||
#include <gpu/Resource.h>
|
||||
|
||||
#include "Haze.h"
|
||||
|
||||
using namespace model;
|
||||
|
||||
Haze::Haze() {
|
||||
Parameters parameters;
|
||||
_hazeParametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
}
|
||||
|
||||
enum HazeModes {
|
||||
HAZE_MODE_IS_ACTIVE = 1 << 0,
|
||||
HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1,
|
||||
HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED = 1 << 2,
|
||||
HAZE_MODE_IS_MODULATE_COLOR = 1 << 3,
|
||||
HAZE_MODE_IS_ENABLE_LIGHT_BLEND = 1 << 4
|
||||
};
|
||||
|
||||
// For color modulated mode, the colour values are used as range values, which are then converted to range factors
|
||||
// This is separate for each colour.
|
||||
// The colour value is converted from [0.0 .. 1.0] to [5.0 .. 3000.0]
|
||||
const float OFFSET = 5.0f;
|
||||
const float BIAS = (3000.0f - 5.0f) / (1.0f - 0.0f);
|
||||
void Haze::setHazeColor(const glm::vec3 hazeColor) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeColor != hazeColor) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeColor = hazeColor;
|
||||
|
||||
glm::vec3 range = hazeColor * BIAS + OFFSET;
|
||||
glm::vec3 factor = convertHazeRangeToHazeRangeFactor(range);
|
||||
_hazeParametersBuffer.edit<Parameters>().colorModulationFactor = factor;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeEnableGlare(const bool isHazeEnableGlare) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (((params.hazeMode & HAZE_MODE_IS_ENABLE_LIGHT_BLEND) == HAZE_MODE_IS_ENABLE_LIGHT_BLEND) && !isHazeEnableGlare) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_ENABLE_LIGHT_BLEND;
|
||||
} else if (((params.hazeMode & HAZE_MODE_IS_ENABLE_LIGHT_BLEND) != HAZE_MODE_IS_ENABLE_LIGHT_BLEND) && isHazeEnableGlare) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_ENABLE_LIGHT_BLEND;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setDirectionalLightBlend(const float hazeDirectionalLightBlend) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.directionalLightBlend != hazeDirectionalLightBlend) {
|
||||
_hazeParametersBuffer.edit<Parameters>().directionalLightBlend = hazeDirectionalLightBlend;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setDirectionalLightColor(const glm::vec3 hazeDirectionalLightColor) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.directionalLightColor.r != hazeDirectionalLightColor.r) {
|
||||
_hazeParametersBuffer.edit<Parameters>().directionalLightColor.r = hazeDirectionalLightColor.r;
|
||||
}
|
||||
if (params.directionalLightColor.g != hazeDirectionalLightColor.g) {
|
||||
_hazeParametersBuffer.edit<Parameters>().directionalLightColor.g = hazeDirectionalLightColor.g;
|
||||
}
|
||||
if (params.directionalLightColor.b != hazeDirectionalLightColor.b) {
|
||||
_hazeParametersBuffer.edit<Parameters>().directionalLightColor.b = hazeDirectionalLightColor.b;
|
||||
}
|
||||
}
|
||||
void Haze::setHazeActive(const bool isHazeActive) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE )&& !isHazeActive) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_ACTIVE;
|
||||
} else if (((params.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) && isHazeActive) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setAltitudeBased(const bool isAltitudeBased) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (((params.hazeMode & HAZE_MODE_IS_ALTITUDE_BASED) == HAZE_MODE_IS_ALTITUDE_BASED )&& !isAltitudeBased) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_ALTITUDE_BASED;
|
||||
} else if (((params.hazeMode & HAZE_MODE_IS_ALTITUDE_BASED) != HAZE_MODE_IS_ALTITUDE_BASED) && isAltitudeBased) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_ALTITUDE_BASED;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeAttenuateKeyLight(const bool isHazeAttenuateKeyLight) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (((params.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) == HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED ) && !isHazeAttenuateKeyLight) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED;
|
||||
} else if (((params.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) != HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) && isHazeAttenuateKeyLight) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setModulateColorActive(const bool isModulateColorActive) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (((params.hazeMode & HAZE_MODE_IS_MODULATE_COLOR) == HAZE_MODE_IS_MODULATE_COLOR ) && !isModulateColorActive) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode &= ~HAZE_MODE_IS_MODULATE_COLOR;
|
||||
} else if (((params.hazeMode & HAZE_MODE_IS_MODULATE_COLOR) != HAZE_MODE_IS_MODULATE_COLOR) && isModulateColorActive) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeMode |= HAZE_MODE_IS_MODULATE_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeRangeFactor(const float hazeRangeFactor) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeRangeFactor != hazeRangeFactor) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeRangeFactor = hazeRangeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeAltitudeFactor(const float hazeAltitudeFactor) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeAltitudeFactor != hazeAltitudeFactor) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeAltitudeFactor = hazeAltitudeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeKeyLightRangeFactor(const float hazeKeyLightRangeFactor) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeKeyLightRangeFactor != hazeKeyLightRangeFactor) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeKeyLightRangeFactor = hazeKeyLightRangeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeKeyLightAltitudeFactor(const float hazeKeyLightAltitudeFactor) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeKeyLightAltitudeFactor != hazeKeyLightAltitudeFactor) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeKeyLightAltitudeFactor = hazeKeyLightAltitudeFactor;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeBaseReference(const float hazeBaseReference) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeBaseReference != hazeBaseReference) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeBaseReference = hazeBaseReference;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setHazeBackgroundBlendValue(const float hazeBackgroundBlendValue) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.hazeBackgroundBlendValue != hazeBackgroundBlendValue) {
|
||||
_hazeParametersBuffer.edit<Parameters>().hazeBackgroundBlendValue = hazeBackgroundBlendValue;
|
||||
}
|
||||
}
|
||||
|
||||
void Haze::setZoneTransform(const glm::mat4& zoneTransform) {
|
||||
auto& params = _hazeParametersBuffer.get<Parameters>();
|
||||
|
||||
if (params.zoneTransform == zoneTransform) {
|
||||
_hazeParametersBuffer.edit<Parameters>().zoneTransform = zoneTransform;
|
||||
}
|
||||
}
|
||||
|
136
libraries/model/src/model/Haze.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
//
|
||||
// MakeHaze.h
|
||||
// libraries/model/src/model
|
||||
//
|
||||
// Created by Nissim Hadar on 9/13/2017.
|
||||
// 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_model_Haze_h
|
||||
#define hifi_model_Haze_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include "Transform.h"
|
||||
#include "NumericalConstants.h"
|
||||
|
||||
namespace model {
|
||||
const float LOG_P_005 = (float)log(0.05);
|
||||
const float LOG_P_05 = (float)log(0.5);
|
||||
|
||||
// Derivation (d is distance, b is haze coefficient, f is attenuation, solve for f = 0.05
|
||||
// f = exp(-d * b)
|
||||
// ln(f) = -d * b
|
||||
// b = -ln(f)/d
|
||||
inline glm::vec3 convertHazeRangeToHazeRangeFactor(const glm::vec3 hazeRange_m) {
|
||||
return glm::vec3(
|
||||
-LOG_P_005 / hazeRange_m.x,
|
||||
-LOG_P_005 / hazeRange_m.y,
|
||||
-LOG_P_005 / hazeRange_m.z);
|
||||
}
|
||||
|
||||
inline float convertHazeRangeToHazeRangeFactor(const float hazeRange_m) { return (-LOG_P_005 / hazeRange_m); }
|
||||
|
||||
inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeAltitude_m) {
|
||||
return -LOG_P_005 / hazeAltitude_m;
|
||||
}
|
||||
|
||||
// Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5
|
||||
// s = dot(lookAngle, sunAngle) = cos(a)
|
||||
// m = pow(s, p)
|
||||
// log(m) = p * log(s)
|
||||
// p = log(m) / log(s)
|
||||
inline float convertDirectionalLightAngleToPower(const float directionalLightAngle) {
|
||||
return LOG_P_05 / (float)log(cos(RADIANS_PER_DEGREE * directionalLightAngle));
|
||||
}
|
||||
|
||||
const glm::vec3 initialHazeColor{ 0.5f, 0.6f, 0.7f };
|
||||
const float initialDirectionalLightAngle_degs{ 30.0f };
|
||||
|
||||
const glm::vec3 initialDirectionalLightColor{ 1.0f, 0.9f, 0.7f };
|
||||
const float initialHazeBaseReference{ 0.0f };
|
||||
|
||||
// Haze range is defined here as the range the visibility is reduced by 95%
|
||||
// Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95%
|
||||
const float initialHazeRange_m{ 150.0f };
|
||||
const float initialHazeAltitude_m{ 150.0f };
|
||||
|
||||
const float initialHazeKeyLightRange_m{ 150.0f };
|
||||
const float initialHazeKeyLightAltitude_m{ 150.0f };
|
||||
|
||||
const float initialHazeBackgroundBlendValue{ 0.0f };
|
||||
|
||||
const glm::vec3 initialColorModulationFactor{
|
||||
convertHazeRangeToHazeRangeFactor(initialHazeRange_m),
|
||||
convertHazeRangeToHazeRangeFactor(initialHazeRange_m),
|
||||
convertHazeRangeToHazeRangeFactor(initialHazeRange_m)
|
||||
};
|
||||
|
||||
class Haze {
|
||||
public:
|
||||
using UniformBufferView = gpu::BufferView;
|
||||
|
||||
Haze();
|
||||
|
||||
void setHazeColor(const glm::vec3 hazeColor);
|
||||
void setDirectionalLightBlend(const float directionalLightBlend);
|
||||
|
||||
void setDirectionalLightColor(const glm::vec3 directionalLightColor);
|
||||
void setHazeBaseReference(const float hazeBaseReference);
|
||||
|
||||
void setHazeActive(const bool isHazeActive);
|
||||
void setAltitudeBased(const bool isAltitudeBased);
|
||||
void setHazeAttenuateKeyLight(const bool isHazeAttenuateKeyLight);
|
||||
void setModulateColorActive(const bool isModulateColorActive);
|
||||
void setHazeEnableGlare(const bool isHazeEnableGlare);
|
||||
|
||||
void setHazeRangeFactor(const float hazeRange);
|
||||
void setHazeAltitudeFactor(const float hazeAltitude);
|
||||
|
||||
void setHazeKeyLightRangeFactor(const float hazeKeyLightRange);
|
||||
void setHazeKeyLightAltitudeFactor(const float hazeKeyLightAltitude);
|
||||
|
||||
void setHazeBackgroundBlendValue(const float hazeBackgroundBlendValue);
|
||||
|
||||
void setZoneTransform(const glm::mat4& zoneTransform);
|
||||
|
||||
UniformBufferView getHazeParametersBuffer() const { return _hazeParametersBuffer; }
|
||||
|
||||
protected:
|
||||
class Parameters {
|
||||
public:
|
||||
// DO NOT CHANGE ORDER HERE WITHOUT UNDERSTANDING THE std140 LAYOUT
|
||||
glm::vec3 hazeColor{ initialHazeColor };
|
||||
float directionalLightBlend{ convertDirectionalLightAngleToPower(initialDirectionalLightAngle_degs) };
|
||||
|
||||
glm::vec3 directionalLightColor{ initialDirectionalLightColor };
|
||||
float hazeBaseReference{ initialHazeBaseReference };
|
||||
|
||||
glm::vec3 colorModulationFactor{ initialColorModulationFactor };
|
||||
int hazeMode{ 0 }; // bit 0 - set to activate haze attenuation of fragment color
|
||||
// bit 1 - set to add the effect of altitude to the haze attenuation
|
||||
// bit 2 - set to activate directional light attenuation mode
|
||||
// bit 3 - set to blend between blend-in and blend-out colours
|
||||
|
||||
glm::mat4 zoneTransform;
|
||||
|
||||
// Amount of background (skybox) to display, overriding the haze effect for the background
|
||||
float hazeBackgroundBlendValue{ initialHazeBackgroundBlendValue };
|
||||
|
||||
// The haze attenuation exponents used by both fragment and directional light attenuation
|
||||
float hazeRangeFactor{ convertHazeRangeToHazeRangeFactor(initialHazeRange_m) };
|
||||
float hazeAltitudeFactor{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeAltitude_m) };
|
||||
|
||||
float hazeKeyLightRangeFactor{ convertHazeRangeToHazeRangeFactor(initialHazeKeyLightRange_m) };
|
||||
float hazeKeyLightAltitudeFactor{ convertHazeAltitudeToHazeAltitudeFactor(initialHazeKeyLightAltitude_m) };
|
||||
|
||||
Parameters() {}
|
||||
};
|
||||
|
||||
UniformBufferView _hazeParametersBuffer;
|
||||
};
|
||||
|
||||
using HazePointer = std::shared_ptr<Haze>;
|
||||
}
|
||||
#endif // hifi_model_Haze_h
|
|
@ -58,7 +58,7 @@ void Light::setOrientation(const glm::quat& orientation) {
|
|||
}
|
||||
|
||||
void Light::setDirection(const Vec3& direction) {
|
||||
_lightSchemaBuffer.edit().volume.direction = (direction);
|
||||
_lightSchemaBuffer.edit().volume.direction = (_transform.getRotation() * direction);
|
||||
}
|
||||
|
||||
const Vec3& Light::getDirection() const {
|
||||
|
|
|
@ -255,3 +255,9 @@ void SunSkyStage::setSkybox(const SkyboxPointer& skybox) {
|
|||
_skybox = skybox;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// Haze
|
||||
void SunSkyStage::setHazeMode(uint32_t mode) {
|
||||
_hazeMode = mode;
|
||||
invalidate();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "Light.h"
|
||||
#include "Skybox.h"
|
||||
#include "Haze.h"
|
||||
|
||||
namespace model {
|
||||
|
||||
|
@ -174,8 +175,65 @@ public:
|
|||
void setSkybox(const SkyboxPointer& skybox);
|
||||
const SkyboxPointer& getSkybox() const { valid(); return _skybox; }
|
||||
|
||||
// Haze
|
||||
enum HazeMode {
|
||||
HAZE_OFF,
|
||||
HAZE_ON,
|
||||
|
||||
NUM_HAZE_MODES
|
||||
};
|
||||
|
||||
void setHazeMode(uint32_t mode);
|
||||
uint32_t getHazeMode() const { return _hazeMode; }
|
||||
|
||||
void setHazeRange(float hazeRange) { _hazeRange = hazeRange; }
|
||||
float getHazeRange() const { return _hazeRange; }
|
||||
void setHazeColor(const xColor hazeColor) { _hazeColor = hazeColor; }
|
||||
xColor getHazeColor() { return _hazeColor; }
|
||||
void setHazeGlareColor(const xColor hazeGlareColor) { _hazeGlareColor = hazeGlareColor; }
|
||||
xColor getHazeGlareColor() const { return _hazeGlareColor; }
|
||||
void setHazeEnableGlare(bool hazeEnableGlare) { _hazeEnableGlare = hazeEnableGlare; }
|
||||
bool getHazeEnableGlare() const { return _hazeEnableGlare; }
|
||||
void setHazeGlareAngle(float hazeGlareAngle) { _hazeGlareAngle = hazeGlareAngle; }
|
||||
float getHazeGlareAngle() const { return _hazeGlareAngle; }
|
||||
|
||||
void setHazeAltitudeEffect(bool hazeAltitudeEffect) { _hazeAltitudeEffect = hazeAltitudeEffect; }
|
||||
bool getHazeAltitudeEffect() const { return _hazeAltitudeEffect; }
|
||||
void setHazeCeiling(float hazeCeiling) { _hazeCeiling = hazeCeiling; }
|
||||
float getHazeCeiling() const { return _hazeCeiling; }
|
||||
void setHazeBaseRef(float hazeBaseRef) { _hazeBaseRef = hazeBaseRef; }
|
||||
float getHazeBaseRef() const { return _hazeBaseRef; }
|
||||
|
||||
void setHazeBackgroundBlend(float hazeBackgroundBlend) { _hazeBackgroundBlend = hazeBackgroundBlend; }
|
||||
float getHazeBackgroundBlend() const { return _hazeBackgroundBlend; }
|
||||
|
||||
void setHazeAttenuateKeyLight(bool hazeAttenuateKeyLight) { _hazeAttenuateKeyLight = hazeAttenuateKeyLight; }
|
||||
bool getHazeAttenuateKeyLight() const { return _hazeAttenuateKeyLight; }
|
||||
void setHazeKeyLightRange(float hazeKeyLightRange) { _hazeKeyLightRange = hazeKeyLightRange; }
|
||||
float getHazeKeyLightRange() const { return _hazeKeyLightRange; }
|
||||
void setHazeKeyLightAltitude(float hazeKeyLightAltitude) { _hazeKeyLightAltitude = hazeKeyLightAltitude; }
|
||||
float getHazeKeyLightAltitude() const { return _hazeKeyLightAltitude; }
|
||||
|
||||
protected:
|
||||
BackgroundMode _backgroundMode = SKY_DEFAULT;
|
||||
|
||||
uint8_t _hazeMode = (uint8_t)HAZE_OFF;
|
||||
|
||||
float _hazeRange;
|
||||
xColor _hazeColor;
|
||||
xColor _hazeGlareColor;
|
||||
bool _hazeEnableGlare;
|
||||
float _hazeGlareAngle;
|
||||
|
||||
bool _hazeAltitudeEffect;
|
||||
float _hazeCeiling;
|
||||
float _hazeBaseRef;
|
||||
|
||||
float _hazeBackgroundBlend;
|
||||
|
||||
bool _hazeAttenuateKeyLight;
|
||||
float _hazeKeyLightRange;
|
||||
float _hazeKeyLightAltitude;
|
||||
|
||||
LightPointer _sunLight;
|
||||
mutable SkyboxPointer _skybox;
|
||||
|
|
|
@ -30,7 +30,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::EntityEdit:
|
||||
case PacketType::EntityData:
|
||||
case PacketType::EntityPhysics:
|
||||
return VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES;
|
||||
return VERSION_ENTITIES_HAZE;
|
||||
case PacketType::EntityQuery:
|
||||
return static_cast<PacketVersion>(EntityQueryPacketVersion::JSONFilterWithFamilyTree);
|
||||
case PacketType::AvatarIdentity:
|
||||
|
|
|
@ -268,6 +268,7 @@ const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71;
|
|||
const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72;
|
||||
const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73;
|
||||
const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74;
|
||||
const PacketVersion VERSION_ENTITIES_HAZE = 75;
|
||||
|
||||
enum class EntityQueryPacketVersion: PacketVersion {
|
||||
JSONFilter = 18,
|
||||
|
|
|
@ -101,6 +101,8 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
|
|||
<$declareDeferredCurvature()$>
|
||||
<@endif@>
|
||||
|
||||
<@include Haze.slh@>
|
||||
|
||||
vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
|
||||
vec3 albedo, vec3 fresnel, float metallic, float roughness
|
||||
<@if supportScattering@>
|
||||
|
@ -120,7 +122,6 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
color += ambientDiffuse;
|
||||
color += ambientSpecular;
|
||||
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
|
@ -132,6 +133,56 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
color += directionalDiffuse;
|
||||
color += directionalSpecular;
|
||||
|
||||
// Attenuate the light if haze effect selected
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) == HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED) {
|
||||
// Directional light attenuation is simulated by assuming the light source is at a fixed height above the
|
||||
// fragment. This height is where the haze density is reduced by 95% from the haze at the fragment's height
|
||||
//
|
||||
// The distance is computed from the height and the directional light orientation
|
||||
// The distance is limited to height * 1,000, which gives an angle of ~0.057 degrees
|
||||
|
||||
// Get directional light
|
||||
Light light = getLight();
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
|
||||
// Height at which haze density is reduced by 95% (default set to 2000.0 for safety ,this should never happen)
|
||||
float height_95p = 2000.0;
|
||||
if (hazeParams.hazeAltitudeFactorKeyLight > 0.0f) {
|
||||
height_95p = -log(0.05) / hazeParams.hazeAltitudeFactorKeyLight;
|
||||
}
|
||||
|
||||
// Note that the sine will always be positive
|
||||
float sin_pitch = sqrt(1.0 - lightDirection.y * lightDirection.y);
|
||||
|
||||
float distance;
|
||||
const float minimumSinPitch = 0.001;
|
||||
if (sin_pitch < minimumSinPitch) {
|
||||
distance = height_95p / minimumSinPitch;
|
||||
} else {
|
||||
distance = height_95p / sin_pitch;
|
||||
}
|
||||
|
||||
// Position of fragment in world coordinates
|
||||
vec4 worldFragPos = invViewMat * vec4(position, 0.0);
|
||||
|
||||
// Integration is from the fragment towards the light source
|
||||
// Note that the haze base reference affects only the haze density as function of altitude
|
||||
float hazeDensityDistribution =
|
||||
hazeParams.hazeRangeFactorKeyLight *
|
||||
exp(-hazeParams.hazeAltitudeFactorKeyLight * (worldFragPos.y - hazeParams.hazeBaseReference));
|
||||
|
||||
float hazeIntegral = hazeDensityDistribution * distance;
|
||||
|
||||
// Note that t is constant and equal to -log(0.05)
|
||||
// float t = hazeParams.hazeAltitudeFactor * height_95p;
|
||||
// hazeIntegral *= (1.0 - exp (-t)) / t;
|
||||
hazeIntegral *= 0.3171178;
|
||||
|
||||
float hazeAmount = 1.0 - exp(-hazeIntegral);
|
||||
|
||||
color = mix(color, vec3(0.0, 0.0, 0.0), hazeAmount);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ enum DeferredShader_BufferSlot {
|
|||
LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
|
||||
LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
|
||||
LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
|
||||
|
||||
HAZE_MODEL_BUFFER_SLOT
|
||||
};
|
||||
|
||||
static void loadLightProgram(const char* vertSource, const char* fragSource, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
|
||||
|
@ -169,6 +169,7 @@ static gpu::ShaderPointer makeLightProgram(const char* vertSource, const char* f
|
|||
slotBindings.insert(gpu::Shader::Binding(std::string("cameraCorrectionBuffer"), CAMERA_CORRECTION_BUFFER_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), LIGHTING_MODEL_BUFFER_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), HAZE_MODEL_BUFFER_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("subsurfaceScatteringParametersBuffer"), SCATTERING_PARAMETERS_BUFFER_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), LIGHT_AMBIENT_SLOT));
|
||||
|
@ -438,6 +439,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
const DeferredFrameTransformPointer& frameTransform,
|
||||
const DeferredFramebufferPointer& deferredFramebuffer,
|
||||
const LightingModelPointer& lightingModel,
|
||||
const model::HazePointer& haze,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource) {
|
||||
|
@ -538,6 +540,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
batch.setUniformBuffer(locations->shadowTransformBuffer, globalShadow->getBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
batch.setPipeline(program);
|
||||
}
|
||||
|
||||
|
@ -547,7 +550,12 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
|
|||
|
||||
// Setup the global lighting
|
||||
deferredLightingEffect->setupKeyLightBatch(args, batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
|
||||
|
||||
// Haze
|
||||
if (haze) {
|
||||
batch.setUniformBuffer(HAZE_MODEL_BUFFER_SLOT, haze->getHazeParametersBuffer());
|
||||
}
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
deferredLightingEffect->unsetKeyLightBatch(batch, locations->lightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
|
||||
|
@ -566,7 +574,8 @@ void RenderDeferredLocals::run(const render::RenderContextPointer& renderContext
|
|||
const DeferredFrameTransformPointer& frameTransform,
|
||||
const DeferredFramebufferPointer& deferredFramebuffer,
|
||||
const LightingModelPointer& lightingModel,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer, const LightClustersPointer& lightClusters) {
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const LightClustersPointer& lightClusters) {
|
||||
|
||||
bool points = lightingModel->isPointLightEnabled();
|
||||
bool spots = lightingModel->isSpotLightEnabled();
|
||||
|
@ -675,6 +684,8 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
|
|||
auto lightClusters = inputs.get6();
|
||||
auto args = renderContext->args;
|
||||
|
||||
const auto haze = inputs.get7();
|
||||
|
||||
if (!_gpuTimer) {
|
||||
_gpuTimer = std::make_shared < gpu::RangeTimer>(__FUNCTION__);
|
||||
}
|
||||
|
@ -684,7 +695,7 @@ void RenderDeferred::run(const RenderContextPointer& renderContext, const Inputs
|
|||
args->_batch = &batch;
|
||||
_gpuTimer->begin(batch);
|
||||
|
||||
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource);
|
||||
setupJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, haze, surfaceGeometryFramebuffer, ssaoFramebuffer, subsurfaceScatteringResource);
|
||||
|
||||
lightsJob.run(renderContext, deferredTransform, deferredFramebuffer, lightingModel, surfaceGeometryFramebuffer, lightClusters);
|
||||
|
||||
|
@ -759,5 +770,16 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
|
|||
_defaultBackgroundID = backgroundStage->addBackground(_defaultBackground);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_defaultHaze) {
|
||||
auto hazeStage = renderContext->_scene->getStage<HazeStage>();
|
||||
if (hazeStage) {
|
||||
|
||||
auto haze = std::make_shared<model::Haze>();
|
||||
|
||||
_defaultHaze = haze;
|
||||
_defaultHazeID = hazeStage->addHaze(_defaultHaze);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "LightStage.h"
|
||||
#include "LightClusters.h"
|
||||
#include "BackgroundStage.h"
|
||||
#include "HazeStage.h"
|
||||
|
||||
#include "SurfaceGeometryPass.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
|
@ -120,6 +121,7 @@ public:
|
|||
const DeferredFrameTransformPointer& frameTransform,
|
||||
const DeferredFramebufferPointer& deferredFramebuffer,
|
||||
const LightingModelPointer& lightingModel,
|
||||
const model::HazePointer& haze,
|
||||
const SurfaceGeometryFramebufferPointer& surfaceGeometryFramebuffer,
|
||||
const AmbientOcclusionFramebufferPointer& ambientOcclusionFramebuffer,
|
||||
const SubsurfaceScatteringResourcePointer& subsurfaceScatteringResource);
|
||||
|
@ -154,7 +156,10 @@ using RenderDeferredConfig = render::GPUJobConfig;
|
|||
|
||||
class RenderDeferred {
|
||||
public:
|
||||
using Inputs = render::VaryingSet7 < DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer, AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer>;
|
||||
using Inputs = render::VaryingSet8 <
|
||||
DeferredFrameTransformPointer, DeferredFramebufferPointer, LightingModelPointer, SurfaceGeometryFramebufferPointer,
|
||||
AmbientOcclusionFramebufferPointer, SubsurfaceScatteringResourcePointer, LightClustersPointer, model::HazePointer>;
|
||||
|
||||
using Config = RenderDeferredConfig;
|
||||
using JobModel = render::Job::ModelI<RenderDeferred, Inputs, Config>;
|
||||
|
||||
|
@ -183,6 +188,8 @@ protected:
|
|||
LightStage::Index _defaultLightID{ LightStage::INVALID_INDEX };
|
||||
model::SunSkyStagePointer _defaultBackground;
|
||||
BackgroundStage::Index _defaultBackgroundID{ BackgroundStage::INVALID_INDEX };
|
||||
model::HazePointer _defaultHaze{ nullptr };
|
||||
HazeStage::Index _defaultHazeID{ HazeStage::INVALID_INDEX };
|
||||
model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() };
|
||||
gpu::TexturePointer _defaultSkyboxTexture;
|
||||
gpu::TexturePointer _defaultSkyboxAmbientTexture;
|
||||
|
|
207
libraries/render-utils/src/DrawHaze.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
//
|
||||
// DrawHaze.cpp
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Nissim Hadar on 9/1/2017.
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "DrawHaze.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
#include <gpu/StandardShaderLib.h>
|
||||
|
||||
#include "StencilMaskPass.h"
|
||||
#include "FramebufferCache.h"
|
||||
#include "HazeStage.h"
|
||||
#include "LightStage.h"
|
||||
|
||||
#include "Haze_frag.h"
|
||||
|
||||
void HazeConfig::setHazeColorR(const float value) {
|
||||
hazeColorR = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeColorG(const float value) {
|
||||
hazeColorG = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeColorB(const float value) {
|
||||
hazeColorB = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setDirectionalLightAngle_degs(const float value) {
|
||||
hazeDirectionalLightAngle_degs = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setDirectionalLightColorR(const float value) {
|
||||
hazeDirectionalLightColorR = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setDirectionalLightColorG(const float value) {
|
||||
hazeDirectionalLightColorG = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setDirectionalLightColorB(const float value) {
|
||||
hazeDirectionalLightColorB = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeBaseReference(const float value) {
|
||||
hazeBaseReference = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeActive(const bool active) {
|
||||
isHazeActive = active;
|
||||
}
|
||||
|
||||
void HazeConfig::setAltitudeBased(const bool active) {
|
||||
isAltitudeBased = active;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeAttenuateKeyLight(const bool active) {
|
||||
isHazeAttenuateKeyLight = active;
|
||||
}
|
||||
|
||||
void HazeConfig::setModulateColorActive(const bool active) {
|
||||
isModulateColorActive = active;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeEnableGlare(const bool active) {
|
||||
isHazeEnableGlare = active;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeRange_m(const float value) {
|
||||
hazeRange_m = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeAltitude_m(const float value) {
|
||||
hazeAltitude_m = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeKeyLightRange_m(const float value) {
|
||||
hazeKeyLightRange_m = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeKeyLightAltitude_m(const float value) {
|
||||
hazeKeyLightAltitude_m = value;
|
||||
}
|
||||
|
||||
void HazeConfig::setHazeBackgroundBlendValue(const float value) {
|
||||
hazeBackgroundBlendValue = value;
|
||||
}
|
||||
|
||||
MakeHaze::MakeHaze() {
|
||||
_haze = std::make_shared<model::Haze>();
|
||||
}
|
||||
|
||||
void MakeHaze::configure(const Config& config) {
|
||||
_haze->setHazeColor(glm::vec3(config.hazeColorR, config.hazeColorG, config.hazeColorB));
|
||||
_haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(config.hazeDirectionalLightAngle_degs));
|
||||
|
||||
_haze->setDirectionalLightColor(glm::vec3(config.hazeDirectionalLightColorR, config.hazeDirectionalLightColorG, config.hazeDirectionalLightColorB));
|
||||
_haze->setHazeBaseReference(config.hazeBaseReference);
|
||||
|
||||
_haze->setHazeActive(config.isHazeActive);
|
||||
_haze->setAltitudeBased(config.isAltitudeBased);
|
||||
_haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight);
|
||||
_haze->setModulateColorActive(config.isModulateColorActive);
|
||||
_haze->setHazeEnableGlare(config.isHazeEnableGlare);
|
||||
|
||||
_haze->setHazeRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeRange_m));
|
||||
_haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeAltitude_m));
|
||||
|
||||
_haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange_m));
|
||||
_haze->setHazeKeyLightAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude_m));
|
||||
|
||||
_haze->setHazeBackgroundBlendValue(config.hazeBackgroundBlendValue);
|
||||
}
|
||||
|
||||
void MakeHaze::run(const render::RenderContextPointer& renderContext, model::HazePointer& haze) {
|
||||
haze = _haze;
|
||||
}
|
||||
|
||||
const int HazeEffect_ParamsSlot = 0;
|
||||
const int HazeEffect_TransformBufferSlot = 1;
|
||||
const int HazeEffect_ColorMapSlot = 2;
|
||||
const int HazeEffect_LinearDepthMapSlot = 3;
|
||||
const int HazeEffect_LightingMapSlot = 4;
|
||||
|
||||
void DrawHaze::configure(const Config& config) {
|
||||
}
|
||||
|
||||
void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
const auto haze = inputs.get0();
|
||||
if (haze == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto inputBuffer = inputs.get1()->getRenderBuffer(0);
|
||||
const auto framebuffer = inputs.get2();
|
||||
const auto transformBuffer = inputs.get3();
|
||||
|
||||
auto outputBuffer = inputs.get4();
|
||||
|
||||
auto depthBuffer = framebuffer->getLinearDepthTexture();
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
if (!_hazePipeline) {
|
||||
gpu::ShaderPointer ps = gpu::Shader::createPixel(std::string(Haze_frag));
|
||||
gpu::ShaderPointer vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// Mask out haze on the tablet
|
||||
PrepareStencil::testNoAA(*state);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), HazeEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), HazeEffect_TransformBufferSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), HazeEffect_ColorMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), HazeEffect_LinearDepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), HazeEffect_LightingMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_hazePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
|
||||
auto sourceFramebufferSize = glm::ivec2(inputBuffer->getDimensions());
|
||||
|
||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
batch.setFramebuffer(outputBuffer);
|
||||
|
||||
batch.setViewportTransform(args->_viewport);
|
||||
batch.setProjectionTransform(glm::mat4());
|
||||
batch.resetViewTransform();
|
||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(sourceFramebufferSize, args->_viewport));
|
||||
|
||||
batch.setPipeline(_hazePipeline);
|
||||
|
||||
auto hazeStage = args->_scene->getStage<HazeStage>();
|
||||
if (hazeStage && hazeStage->_currentFrame._hazes.size() > 0) {
|
||||
model::HazePointer hazePointer = hazeStage->getHaze(hazeStage->_currentFrame._hazes.front());
|
||||
batch.setUniformBuffer(HazeEffect_ParamsSlot, hazePointer->getHazeParametersBuffer());
|
||||
}
|
||||
|
||||
batch.setUniformBuffer(HazeEffect_TransformBufferSlot, transformBuffer->getFrameTransformBuffer());
|
||||
|
||||
auto lightStage = args->_scene->getStage<LightStage>();
|
||||
if (lightStage && lightStage->_currentFrame._sunLights.size() > 0) {
|
||||
model::LightPointer keyLight;
|
||||
keyLight = lightStage->getLight(lightStage->_currentFrame._sunLights.front());
|
||||
if (keyLight != nullptr) {
|
||||
batch.setUniformBuffer(HazeEffect_LightingMapSlot, keyLight->getLightSchemaBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
batch.setResourceTexture(HazeEffect_ColorMapSlot, inputBuffer);
|
||||
batch.setResourceTexture(HazeEffect_LinearDepthMapSlot, depthBuffer);
|
||||
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
194
libraries/render-utils/src/DrawHaze.h
Normal file
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// DrawHaze.h
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Nissim Hadar on 9/1/2017.
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_render_utils_DrawHaze_h
|
||||
#define hifi_render_utils_DrawHaze_h
|
||||
|
||||
#include <DependencyManager.h>
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
#include <gpu/Resource.h>
|
||||
#include <gpu/Pipeline.h>
|
||||
#include <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
|
||||
#include "SurfaceGeometryPass.h"
|
||||
|
||||
#include "model/Haze.h"
|
||||
|
||||
using LinearDepthFramebufferPointer = std::shared_ptr<LinearDepthFramebuffer>;
|
||||
|
||||
class MakeHazeConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(float hazeColorR MEMBER hazeColorR WRITE setHazeColorR NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeColorG MEMBER hazeColorG WRITE setHazeColorG NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeColorB MEMBER hazeColorB WRITE setHazeColorB NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeDirectionalLightAngle_degs MEMBER hazeDirectionalLightAngle_degs WRITE setDirectionalLightAngle_degs NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeDirectionalLightColorR MEMBER hazeDirectionalLightColorR WRITE setDirectionalLightColorR NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeDirectionalLightColorG MEMBER hazeDirectionalLightColorG WRITE setDirectionalLightColorG NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeDirectionalLightColorB MEMBER hazeDirectionalLightColorB WRITE setDirectionalLightColorB NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty);
|
||||
Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty);
|
||||
Q_PROPERTY(bool isHazeAttenuateKeyLight MEMBER isHazeAttenuateKeyLight WRITE setHazeAttenuateKeyLight NOTIFY dirty);
|
||||
Q_PROPERTY(bool isModulateColorActive MEMBER isModulateColorActive WRITE setModulateColorActive NOTIFY dirty);
|
||||
Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeRange_m MEMBER hazeRange_m WRITE setHazeRange_m NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeAltitude_m MEMBER hazeAltitude_m WRITE setHazeAltitude_m NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeKeyLightRange_m MEMBER hazeKeyLightRange_m WRITE setHazeKeyLightRange_m NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeKeyLightAltitude_m MEMBER hazeKeyLightAltitude_m WRITE setHazeKeyLightAltitude_m NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeBackgroundBlendValue MEMBER hazeBackgroundBlendValue WRITE setHazeBackgroundBlendValue NOTIFY dirty);
|
||||
|
||||
public:
|
||||
MakeHazeConfig() : render::Job::Config() {}
|
||||
|
||||
float hazeColorR{ model::initialHazeColor.r };
|
||||
float hazeColorG{ model::initialHazeColor.g };
|
||||
float hazeColorB{ model::initialHazeColor.b };
|
||||
float hazeDirectionalLightAngle_degs{ model::initialDirectionalLightAngle_degs };
|
||||
|
||||
float hazeDirectionalLightColorR{ model::initialDirectionalLightColor.r };
|
||||
float hazeDirectionalLightColorG{ model::initialDirectionalLightColor.g };
|
||||
float hazeDirectionalLightColorB{ model::initialDirectionalLightColor.b };
|
||||
float hazeBaseReference{ model::initialHazeBaseReference };
|
||||
|
||||
bool isHazeActive{ false };
|
||||
bool isAltitudeBased{ false };
|
||||
bool isHazeAttenuateKeyLight{ false };
|
||||
bool isModulateColorActive{ false };
|
||||
bool isHazeEnableGlare{ false };
|
||||
|
||||
float hazeRange_m{ model::initialHazeRange_m };
|
||||
float hazeAltitude_m{ model::initialHazeAltitude_m };
|
||||
|
||||
float hazeKeyLightRange_m{ model::initialHazeKeyLightRange_m };
|
||||
float hazeKeyLightAltitude_m{ model::initialHazeKeyLightAltitude_m };
|
||||
|
||||
float hazeBackgroundBlendValue{ model::initialHazeBackgroundBlendValue };
|
||||
|
||||
public slots:
|
||||
void setHazeColorR(const float value) { hazeColorR = value; emit dirty(); }
|
||||
void setHazeColorG(const float value) { hazeColorG = value; emit dirty(); }
|
||||
void setHazeColorB(const float value) { hazeColorB = value; emit dirty(); }
|
||||
void setDirectionalLightAngle_degs(const float value) { hazeDirectionalLightAngle_degs = value; emit dirty(); }
|
||||
|
||||
void setDirectionalLightColorR(const float value) { hazeDirectionalLightColorR = value; emit dirty(); }
|
||||
void setDirectionalLightColorG(const float value) { hazeDirectionalLightColorG = value; emit dirty(); }
|
||||
void setDirectionalLightColorB(const float value) { hazeDirectionalLightColorB = value; emit dirty(); }
|
||||
void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); }
|
||||
|
||||
void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); }
|
||||
void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); }
|
||||
void setHazeAttenuateKeyLight(const bool active) { isHazeAttenuateKeyLight = active; emit dirty(); }
|
||||
void setModulateColorActive(const bool active) { isModulateColorActive = active; emit dirty(); }
|
||||
void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); }
|
||||
|
||||
void setHazeRange_m(const float value) { hazeRange_m = value; emit dirty(); }
|
||||
void setHazeAltitude_m(const float value) { hazeAltitude_m = value; emit dirty(); }
|
||||
|
||||
void setHazeKeyLightRange_m(const float value) { hazeKeyLightRange_m = value; emit dirty(); }
|
||||
void setHazeKeyLightAltitude_m(const float value) { hazeKeyLightAltitude_m = value; emit dirty(); }
|
||||
|
||||
void setHazeBackgroundBlendValue(const float value) { hazeBackgroundBlendValue = value; ; emit dirty(); }
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class MakeHaze {
|
||||
public:
|
||||
using Config = MakeHazeConfig;
|
||||
using JobModel = render::Job::ModelO<MakeHaze, model::HazePointer, Config>;
|
||||
|
||||
MakeHaze();
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, model::HazePointer& haze);
|
||||
|
||||
private:
|
||||
model::HazePointer _haze;
|
||||
};
|
||||
|
||||
class HazeConfig : public render::Job::Config {
|
||||
public:
|
||||
HazeConfig() : render::Job::Config(true) {}
|
||||
|
||||
// attributes
|
||||
float hazeColorR{ model::initialHazeColor.r };
|
||||
float hazeColorG{ model::initialHazeColor.g };
|
||||
float hazeColorB{ model::initialHazeColor.b };
|
||||
float hazeDirectionalLightAngle_degs{ model::initialDirectionalLightAngle_degs };
|
||||
|
||||
float hazeDirectionalLightColorR{ model::initialDirectionalLightColor.r };
|
||||
float hazeDirectionalLightColorG{ model::initialDirectionalLightColor.g };
|
||||
float hazeDirectionalLightColorB{ model::initialDirectionalLightColor.b };
|
||||
float hazeBaseReference{ model::initialHazeBaseReference };
|
||||
|
||||
bool isHazeActive{ false }; // Setting this to true will set haze to on
|
||||
bool isAltitudeBased{ false };
|
||||
bool isHazeAttenuateKeyLight{ false };
|
||||
bool isModulateColorActive{ false };
|
||||
bool isHazeEnableGlare{ false };
|
||||
|
||||
float hazeRange_m{ model::initialHazeRange_m };
|
||||
float hazeAltitude_m{ model::initialHazeAltitude_m };
|
||||
|
||||
float hazeKeyLightRange_m{ model::initialHazeKeyLightRange_m };
|
||||
float hazeKeyLightAltitude_m{ model::initialHazeKeyLightAltitude_m };
|
||||
|
||||
float hazeBackgroundBlendValue{ model::initialHazeBackgroundBlendValue };
|
||||
|
||||
// methods
|
||||
void setHazeColorR(const float value);
|
||||
void setHazeColorG(const float value);
|
||||
void setHazeColorB(const float value);
|
||||
void setDirectionalLightAngle_degs(const float value);
|
||||
|
||||
void setDirectionalLightColorR(const float value);
|
||||
void setDirectionalLightColorG(const float value);
|
||||
void setDirectionalLightColorB(const float value);
|
||||
void setHazeBaseReference(const float value);
|
||||
|
||||
void setHazeActive(const bool active);
|
||||
void setAltitudeBased(const bool active);
|
||||
void setHazeAttenuateKeyLight(const bool active);
|
||||
void setModulateColorActive(const bool active);
|
||||
void setHazeEnableGlare(const bool active);
|
||||
|
||||
void setHazeRange_m(const float value);
|
||||
void setHazeAltitude_m(const float value);
|
||||
|
||||
void setHazeKeyLightRange_m(const float value);
|
||||
void setHazeKeyLightAltitude_m(const float value);
|
||||
|
||||
void setHazeBackgroundBlendValue(const float value);
|
||||
};
|
||||
|
||||
class DrawHaze {
|
||||
public:
|
||||
using Inputs = render::VaryingSet5<model::HazePointer, gpu::FramebufferPointer, LinearDepthFramebufferPointer, DeferredFrameTransformPointer, gpu::FramebufferPointer>;
|
||||
using Config = HazeConfig;
|
||||
using JobModel = render::Job::ModelI<DrawHaze, Inputs, Config>;
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
|
||||
private:
|
||||
gpu::PipelinePointer _hazePipeline;
|
||||
};
|
||||
|
||||
#endif // hifi_render_utils_DrawHaze_h
|
147
libraries/render-utils/src/Haze.slf
Normal file
|
@ -0,0 +1,147 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// Created by Nissim Hadar on 9/5/2107.
|
||||
// Copyright 2016 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 DeferredTransform.slh@>
|
||||
<$declareDeferredFrameTransform()$>
|
||||
|
||||
<@include model/Light.slh@>
|
||||
|
||||
<@include LightingModel.slh@>
|
||||
<$declareLightBuffer()$>
|
||||
|
||||
<@include LightDirectional.slh@>
|
||||
<$declareLightingDirectional(_SCRIBE_NULL)$>
|
||||
|
||||
<@include Haze.slh@>
|
||||
|
||||
uniform sampler2D colorMap;
|
||||
|
||||
vec4 unpackPositionFromZeye(vec2 texcoord) {
|
||||
float Zeye = -texture(linearDepthMap, texcoord).x;
|
||||
int side = 0;
|
||||
if (isStereo()) {
|
||||
if (texcoord.x > 0.5) {
|
||||
texcoord.x -= 0.5;
|
||||
side = 1;
|
||||
}
|
||||
texcoord.x *= 2.0;
|
||||
}
|
||||
return vec4(evalEyePositionFromZeye(side, Zeye, texcoord), 1.0);
|
||||
}
|
||||
|
||||
in vec2 varTexCoord0;
|
||||
out vec4 outFragColor;
|
||||
|
||||
void main(void) {
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// Distance to fragment
|
||||
vec4 eyeFragPos = unpackPositionFromZeye(varTexCoord0);
|
||||
float distance = length(eyeFragPos.xyz);
|
||||
|
||||
vec4 fragColor = texture(colorMap, varTexCoord0);
|
||||
vec4 hazeColor = vec4(hazeParams.hazeColor, 1.0);
|
||||
|
||||
// Directional light component is a function of the angle from the eye, between the fragment and the sun
|
||||
DeferredFrameTransform deferredTransform = getDeferredFrameTransform();
|
||||
vec4 worldFragPos = getViewInverse() * eyeFragPos;
|
||||
vec3 eyeFragDir = normalize(worldFragPos.xyz);
|
||||
|
||||
Light light = getLight();
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
|
||||
float directionalLightComponent = max(0.0, dot(eyeFragDir, -lightDirection));
|
||||
float power = min(1.0, pow(directionalLightComponent, hazeParams.directionalLightBlend));
|
||||
|
||||
vec4 directionalLightColor = vec4(hazeParams.directionalLightColor, 1.0);
|
||||
|
||||
// Use the haze colour for the belnd-out colour, if blend is not enabled
|
||||
vec4 blendedHazeColor;
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ENABLE_LIGHT_BLEND) == HAZE_MODE_IS_ENABLE_LIGHT_BLEND) {
|
||||
blendedHazeColor = mix(hazeColor, directionalLightColor, power);
|
||||
} else {
|
||||
blendedHazeColor = hazeColor;
|
||||
}
|
||||
|
||||
vec4 potentialFragColor;
|
||||
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_MODULATE_COLOR) == HAZE_MODE_IS_MODULATE_COLOR) {
|
||||
// Compute separately for each colour
|
||||
// Haze is based on both range and altitude
|
||||
// Taken from www.crytek.com/download/GDC2007_RealtimeAtmoFxInGamesRev.ppt
|
||||
|
||||
// The eyepoint position is in the last column of the matrix
|
||||
vec3 worldEyePos = getViewInverse()[3].xyz;
|
||||
|
||||
// Note that the haze base reference affects only the haze density as function of altitude
|
||||
vec3 hazeDensityDistribution =
|
||||
hazeParams.colorModulationFactor *
|
||||
exp(-hazeParams.hazeAltitudeFactor * (worldEyePos.y - hazeParams.hazeBaseReference));
|
||||
|
||||
vec3 hazeIntegral = hazeDensityDistribution * distance;
|
||||
|
||||
const float slopeThreshold = 0.01;
|
||||
float deltaHeight = worldFragPos.y - worldEyePos.y;
|
||||
if (abs(deltaHeight) > slopeThreshold) {
|
||||
float t = hazeParams.hazeAltitudeFactor * deltaHeight;
|
||||
hazeIntegral *= (1.0 - exp (-t)) / t;
|
||||
}
|
||||
|
||||
vec3 hazeAmount = 1.0 - exp(-hazeIntegral);
|
||||
|
||||
// Compute color after haze effect
|
||||
potentialFragColor = mix(fragColor, vec4(1.0, 1.0, 1.0, 1.0), vec4(hazeAmount, 1.0));
|
||||
} else if ((hazeParams.hazeMode & HAZE_MODE_IS_ALTITUDE_BASED) != HAZE_MODE_IS_ALTITUDE_BASED) {
|
||||
// Haze is based only on range
|
||||
float hazeAmount = 1.0 - exp(-distance * hazeParams.hazeRangeFactor);
|
||||
|
||||
// Compute color after haze effect
|
||||
potentialFragColor = mix(fragColor, blendedHazeColor, hazeAmount);
|
||||
} else {
|
||||
// Haze is based on both range and altitude
|
||||
// Taken from www.crytek.com/download/GDC2007_RealtimeAtmoFxInGamesRev.ppt
|
||||
|
||||
// The eyepoint position is in the last column of the matrix
|
||||
vec3 worldEyePos = getViewInverse()[3].xyz;
|
||||
|
||||
// Note that the haze base reference affects only the haze density as function of altitude
|
||||
float hazeDensityDistribution =
|
||||
hazeParams.hazeRangeFactor *
|
||||
exp(-hazeParams.hazeAltitudeFactor * (worldEyePos.y - hazeParams.hazeBaseReference));
|
||||
|
||||
float hazeIntegral = hazeDensityDistribution * distance;
|
||||
|
||||
const float slopeThreshold = 0.01;
|
||||
float deltaHeight = worldFragPos.y - worldEyePos.y;
|
||||
if (abs(deltaHeight) > slopeThreshold) {
|
||||
float t = hazeParams.hazeAltitudeFactor * deltaHeight;
|
||||
// Protect from wild values
|
||||
if (abs(t) > 0.0000001) {
|
||||
hazeIntegral *= (1.0 - exp (-t)) / t;
|
||||
}
|
||||
}
|
||||
|
||||
float hazeAmount = 1.0 - exp(-hazeIntegral);
|
||||
|
||||
// Compute color after haze effect
|
||||
potentialFragColor = mix(fragColor, blendedHazeColor, hazeAmount);
|
||||
}
|
||||
|
||||
// Mix with background at far range
|
||||
if (distance > 32000.0) {
|
||||
outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlendValue);
|
||||
} else {
|
||||
outFragColor = potentialFragColor;
|
||||
}
|
||||
}
|
||||
|
46
libraries/render-utils/src/Haze.slh
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!
|
||||
// Haze.slh
|
||||
//
|
||||
// Created by Nissim Hadar on 9/13/2017
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
!>
|
||||
<@if not HAZE_SLH@>
|
||||
<@def HAZE_SLH@>
|
||||
|
||||
const int HAZE_MODE_IS_ACTIVE = 1 << 0;
|
||||
const int HAZE_MODE_IS_ALTITUDE_BASED = 1 << 1;
|
||||
const int HAZE_MODE_IS_DIRECTIONAL_LIGHT_ATTENUATED = 1 << 2;
|
||||
const int HAZE_MODE_IS_MODULATE_COLOR = 1 << 3;
|
||||
const int HAZE_MODE_IS_ENABLE_LIGHT_BLEND = 1 << 4;
|
||||
|
||||
struct HazeParams {
|
||||
vec3 hazeColor;
|
||||
float directionalLightBlend;
|
||||
|
||||
vec3 directionalLightColor;
|
||||
float hazeBaseReference;
|
||||
|
||||
vec3 colorModulationFactor;
|
||||
int hazeMode;
|
||||
|
||||
mat4 zoneTransform;
|
||||
float backgroundBlendValue;
|
||||
|
||||
float hazeRangeFactor;
|
||||
float hazeAltitudeFactor;
|
||||
|
||||
float hazeRangeFactorKeyLight;
|
||||
float hazeAltitudeFactorKeyLight;
|
||||
};
|
||||
|
||||
layout(std140) uniform hazeBuffer {
|
||||
HazeParams hazeParams;
|
||||
};
|
||||
|
||||
uniform sampler2D linearDepthMap;
|
||||
|
||||
<@endif@>
|
||||
|
97
libraries/render-utils/src/HazeStage.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// HazeStage.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 9/26/2017.
|
||||
// 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
|
||||
//
|
||||
#include "HazeStage.h"
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#include <gpu/Context.h>
|
||||
|
||||
std::string HazeStage::_stageName { "HAZE_STAGE"};
|
||||
|
||||
FetchHazeStage::FetchHazeStage() {
|
||||
_haze = std::make_shared<model::Haze>();
|
||||
}
|
||||
|
||||
void FetchHazeStage::configure(const Config& config) {
|
||||
_haze->setHazeColor(glm::vec3(config.hazeColorR, config.hazeColorG, config.hazeColorB));
|
||||
_haze->setDirectionalLightBlend(model::convertDirectionalLightAngleToPower(config.hazeDirectionalLightAngle_degs));
|
||||
|
||||
_haze->setDirectionalLightColor(glm::vec3(config.hazeDirectionalLightColorR, config.hazeDirectionalLightColorG, config.hazeDirectionalLightColorB));
|
||||
_haze->setHazeBaseReference(config.hazeBaseReference);
|
||||
|
||||
_haze->setHazeActive(config.isHazeActive);
|
||||
_haze->setAltitudeBased(config.isAltitudeBased);
|
||||
_haze->setHazeAttenuateKeyLight(config.isHazeAttenuateKeyLight);
|
||||
_haze->setModulateColorActive(config.isModulateColorActive);
|
||||
_haze->setHazeEnableGlare(config.isHazeEnableGlare);
|
||||
|
||||
_haze->setHazeRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeRange_m));
|
||||
_haze->setHazeAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeAltitude_m));
|
||||
|
||||
_haze->setHazeKeyLightRangeFactor(model::convertHazeRangeToHazeRangeFactor(config.hazeKeyLightRange_m));
|
||||
_haze->setHazeKeyLightAltitudeFactor(model::convertHazeAltitudeToHazeAltitudeFactor(config.hazeKeyLightAltitude_m));
|
||||
|
||||
_haze->setHazeBackgroundBlendValue(config.hazeBackgroundBlendValue);
|
||||
}
|
||||
|
||||
HazeStage::Index HazeStage::findHaze(const HazePointer& haze) const {
|
||||
auto found = _hazeMap.find(haze);
|
||||
if (found != _hazeMap.end()) {
|
||||
return INVALID_INDEX;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
HazeStage::Index HazeStage::addHaze(const HazePointer& haze) {
|
||||
auto found = _hazeMap.find(haze);
|
||||
if (found == _hazeMap.end()) {
|
||||
auto hazeId = _hazes.newElement(haze);
|
||||
// Avoid failing to allocate a haze, just pass
|
||||
if (hazeId != INVALID_INDEX) {
|
||||
|
||||
// Insert the haze and its index in the reverse map
|
||||
_hazeMap.insert(HazeMap::value_type(haze, hazeId));
|
||||
}
|
||||
return hazeId;
|
||||
} else {
|
||||
return (*found).second;
|
||||
}
|
||||
}
|
||||
|
||||
HazeStage::HazePointer HazeStage::removeHaze(Index index) {
|
||||
HazePointer removed = _hazes.freeElement(index);
|
||||
|
||||
if (removed) {
|
||||
_hazeMap.erase(removed);
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
HazeStageSetup::HazeStageSetup() {
|
||||
}
|
||||
|
||||
void HazeStageSetup::run(const render::RenderContextPointer& renderContext) {
|
||||
auto stage = renderContext->_scene->getStage(HazeStage::getName());
|
||||
if (!stage) {
|
||||
renderContext->_scene->resetStage(HazeStage::getName(), std::make_shared<HazeStage>());
|
||||
}
|
||||
}
|
||||
|
||||
void FetchHazeStage::run(const render::RenderContextPointer& renderContext, model::HazePointer& haze) {
|
||||
auto hazeStage = renderContext->_scene->getStage<HazeStage>();
|
||||
assert(hazeStage);
|
||||
|
||||
haze = nullptr;
|
||||
if (hazeStage->_currentFrame._hazes.size() != 0) {
|
||||
auto hazeId = hazeStage->_currentFrame._hazes.front();
|
||||
haze = hazeStage->getHaze(hazeId);
|
||||
}
|
||||
}
|
180
libraries/render-utils/src/HazeStage.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// HazeStage.h
|
||||
|
||||
// Created by Nissim Hadar on 9/26/2017.
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_render_utils_HazeStage_h
|
||||
#define hifi_render_utils_HazeStage_h
|
||||
|
||||
#include <model/Stage.h>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <render/IndexedContainer.h>
|
||||
#include <render/Stage.h>
|
||||
|
||||
#include <render/Forward.h>
|
||||
#include <render/DrawTask.h>
|
||||
#include "model/Haze.h"
|
||||
|
||||
// Haze stage to set up haze-related rendering tasks
|
||||
class HazeStage : public render::Stage {
|
||||
public:
|
||||
static std::string _stageName;
|
||||
static const std::string& getName() { return _stageName; }
|
||||
|
||||
using Index = render::indexed_container::Index;
|
||||
static const Index INVALID_INDEX { render::indexed_container::INVALID_INDEX };
|
||||
static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; }
|
||||
|
||||
using HazePointer = model::HazePointer;
|
||||
using Hazes = render::indexed_container::IndexedPointerVector<model::Haze>;
|
||||
using HazeMap = std::unordered_map<HazePointer, Index>;
|
||||
|
||||
using HazeIndices = std::vector<Index>;
|
||||
|
||||
Index findHaze(const HazePointer& haze) const;
|
||||
Index addHaze(const HazePointer& haze);
|
||||
|
||||
HazePointer removeHaze(Index index);
|
||||
|
||||
bool checkHazeId(Index index) const { return _hazes.checkIndex(index); }
|
||||
|
||||
Index getNumHazes() const { return _hazes.getNumElements(); }
|
||||
Index getNumFreeHazes() const { return _hazes.getNumFreeIndices(); }
|
||||
Index getNumAllocatedHazes() const { return _hazes.getNumAllocatedIndices(); }
|
||||
|
||||
HazePointer getHaze(Index hazeId) const {
|
||||
return _hazes.get(hazeId);
|
||||
}
|
||||
|
||||
Hazes _hazes;
|
||||
HazeMap _hazeMap;
|
||||
|
||||
class Frame {
|
||||
public:
|
||||
Frame() {}
|
||||
|
||||
void clear() { _hazes.clear(); }
|
||||
|
||||
void pushHaze(HazeStage::Index index) { _hazes.emplace_back(index); }
|
||||
|
||||
HazeStage::HazeIndices _hazes;
|
||||
};
|
||||
|
||||
Frame _currentFrame;
|
||||
};
|
||||
using HazeStagePointer = std::shared_ptr<HazeStage>;
|
||||
|
||||
class HazeStageSetup {
|
||||
public:
|
||||
using JobModel = render::Job::Model<HazeStageSetup>;
|
||||
|
||||
HazeStageSetup();
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
class FetchHazeConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(float hazeColorR MEMBER hazeColorR WRITE setHazeColorR NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeColorG MEMBER hazeColorG WRITE setHazeColorG NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeColorB MEMBER hazeColorB WRITE setHazeColorB NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeDirectionalLightAngle_degs MEMBER hazeDirectionalLightAngle_degs WRITE setDirectionalLightAngle_degs NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeDirectionalLightColorR MEMBER hazeDirectionalLightColorR WRITE setDirectionalLightColorR NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeDirectionalLightColorG MEMBER hazeDirectionalLightColorG WRITE setDirectionalLightColorG NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeDirectionalLightColorB MEMBER hazeDirectionalLightColorB WRITE setDirectionalLightColorB NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeBaseReference MEMBER hazeBaseReference WRITE setHazeBaseReference NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(bool isHazeActive MEMBER isHazeActive WRITE setHazeActive NOTIFY dirty);
|
||||
Q_PROPERTY(bool isAltitudeBased MEMBER isAltitudeBased WRITE setAltitudeBased NOTIFY dirty);
|
||||
Q_PROPERTY(bool isHazeAttenuateKeyLight MEMBER isHazeAttenuateKeyLight WRITE setHazeAttenuateKeyLight NOTIFY dirty);
|
||||
Q_PROPERTY(bool isModulateColorActive MEMBER isModulateColorActive WRITE setModulateColorActive NOTIFY dirty);
|
||||
Q_PROPERTY(bool isHazeEnableGlare MEMBER isHazeEnableGlare WRITE setHazeEnableGlare NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeRange_m MEMBER hazeRange_m WRITE setHazeRange_m NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeAltitude_m MEMBER hazeAltitude_m WRITE setHazeAltitude_m NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeKeyLightRange_m MEMBER hazeKeyLightRange_m WRITE setHazeKeyLightRange_m NOTIFY dirty);
|
||||
Q_PROPERTY(float hazeKeyLightAltitude_m MEMBER hazeKeyLightAltitude_m WRITE setHazeKeyLightAltitude_m NOTIFY dirty);
|
||||
|
||||
Q_PROPERTY(float hazeBackgroundBlendValue MEMBER hazeBackgroundBlendValue WRITE setHazeBackgroundBlendValue NOTIFY dirty);
|
||||
|
||||
public:
|
||||
FetchHazeConfig() : render::Job::Config() {}
|
||||
|
||||
float hazeColorR{ model::initialHazeColor.r };
|
||||
float hazeColorG{ model::initialHazeColor.g };
|
||||
float hazeColorB{ model::initialHazeColor.b };
|
||||
float hazeDirectionalLightAngle_degs{ model::initialDirectionalLightAngle_degs };
|
||||
|
||||
float hazeDirectionalLightColorR{ model::initialDirectionalLightColor.r };
|
||||
float hazeDirectionalLightColorG{ model::initialDirectionalLightColor.g };
|
||||
float hazeDirectionalLightColorB{ model::initialDirectionalLightColor.b };
|
||||
float hazeBaseReference{ model::initialHazeBaseReference };
|
||||
|
||||
bool isHazeActive{ false };
|
||||
bool isAltitudeBased{ false };
|
||||
bool isHazeAttenuateKeyLight{ false };
|
||||
bool isModulateColorActive{ false };
|
||||
bool isHazeEnableGlare{ false };
|
||||
|
||||
float hazeRange_m{ model::initialHazeRange_m };
|
||||
float hazeAltitude_m{ model::initialHazeAltitude_m };
|
||||
|
||||
float hazeKeyLightRange_m{ model::initialHazeKeyLightRange_m };
|
||||
float hazeKeyLightAltitude_m{ model::initialHazeKeyLightAltitude_m };
|
||||
|
||||
float hazeBackgroundBlendValue{ model::initialHazeBackgroundBlendValue };
|
||||
|
||||
public slots:
|
||||
void setHazeColorR(const float value) { hazeColorR = value; emit dirty(); }
|
||||
void setHazeColorG(const float value) { hazeColorG = value; emit dirty(); }
|
||||
void setHazeColorB(const float value) { hazeColorB = value; emit dirty(); }
|
||||
void setDirectionalLightAngle_degs(const float value) { hazeDirectionalLightAngle_degs = value; emit dirty(); }
|
||||
|
||||
void setDirectionalLightColorR(const float value) { hazeDirectionalLightColorR = value; emit dirty(); }
|
||||
void setDirectionalLightColorG(const float value) { hazeDirectionalLightColorG = value; emit dirty(); }
|
||||
void setDirectionalLightColorB(const float value) { hazeDirectionalLightColorB = value; emit dirty(); }
|
||||
void setHazeBaseReference(const float value) { hazeBaseReference = value; ; emit dirty(); }
|
||||
|
||||
void setHazeActive(const bool active) { isHazeActive = active; emit dirty(); }
|
||||
void setAltitudeBased(const bool active) { isAltitudeBased = active; emit dirty(); }
|
||||
void setHazeAttenuateKeyLight(const bool active) { isHazeAttenuateKeyLight = active; emit dirty(); }
|
||||
void setModulateColorActive(const bool active) { isModulateColorActive = active; emit dirty(); }
|
||||
void setHazeEnableGlare(const bool active) { isHazeEnableGlare = active; emit dirty(); }
|
||||
|
||||
void setHazeRange_m(const float value) { hazeRange_m = value; emit dirty(); }
|
||||
void setHazeAltitude_m(const float value) { hazeAltitude_m = value; emit dirty(); }
|
||||
|
||||
void setHazeKeyLightRange_m(const float value) { hazeKeyLightRange_m = value; emit dirty(); }
|
||||
void setHazeKeyLightAltitude_m(const float value) { hazeKeyLightAltitude_m = value; emit dirty(); }
|
||||
|
||||
void setHazeBackgroundBlendValue(const float value) { hazeBackgroundBlendValue = value; ; emit dirty(); }
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
};
|
||||
|
||||
class FetchHazeStage {
|
||||
public:
|
||||
using Config = FetchHazeConfig;
|
||||
using JobModel = render::Job::ModelO<FetchHazeStage, model::HazePointer, Config>;
|
||||
|
||||
FetchHazeStage();
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, model::HazePointer& haze);
|
||||
|
||||
private:
|
||||
model::HazePointer _haze;
|
||||
gpu::PipelinePointer _hazePipeline;
|
||||
};
|
||||
#endif
|
|
@ -40,6 +40,7 @@
|
|||
#include "AntialiasingEffect.h"
|
||||
#include "ToneMappingEffect.h"
|
||||
#include "SubsurfaceScattering.h"
|
||||
#include "DrawHaze.h"
|
||||
#include "OutlineEffect.h"
|
||||
|
||||
#include <gpu/StandardShaderLib.h>
|
||||
|
@ -149,11 +150,13 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
// Create the cluster grid of lights, cpu job for now
|
||||
const auto lightClusteringPassInputs = LightClusteringPass::Inputs(deferredFrameTransform, lightingModel, linearDepthTarget).asVarying();
|
||||
const auto lightClusters = task.addJob<LightClusteringPass>("LightClustering", lightClusteringPassInputs);
|
||||
|
||||
|
||||
|
||||
// Add haze model
|
||||
const auto hazeModel = task.addJob<FetchHazeStage>("HazeModel");
|
||||
|
||||
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
|
||||
const auto deferredLightingInputs = RenderDeferred::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel,
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters).asVarying();
|
||||
surfaceGeometryFramebuffer, ambientOcclusionFramebuffer, scatteringResource, lightClusters, hazeModel).asVarying();
|
||||
|
||||
task.addJob<RenderDeferred>("RenderDeferred", deferredLightingInputs);
|
||||
|
||||
|
@ -169,7 +172,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto debugLightClustersInputs = DebugLightClusters::Inputs(deferredFrameTransform, deferredFramebuffer, lightingModel, linearDepthTarget, lightClusters).asVarying();
|
||||
task.addJob<DebugLightClusters>("DebugLightClusters", debugLightClustersInputs);
|
||||
}
|
||||
|
||||
|
||||
const auto drawHazeInputs = render::Varying(DrawHaze::Inputs(hazeModel, lightingFramebuffer, linearDepthTarget, deferredFrameTransform, lightingFramebuffer));
|
||||
task.addJob<DrawHaze>("DrawHaze", drawHazeInputs);
|
||||
|
||||
const auto toneAndPostRangeTimer = task.addJob<BeginGPURangeTimer>("BeginToneAndPostRangeTimer", "PostToneOverlaysAntialiasing");
|
||||
|
||||
// Lighting Buffer ready for tone mapping
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
#include <render/SceneTask.h>
|
||||
#include "LightStage.h"
|
||||
#include "BackgroundStage.h"
|
||||
#include "HazeStage.h"
|
||||
#include <render/TransitionStage.h>
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
void UpdateSceneTask::build(JobModel& task, const render::Varying& input, render::Varying& output) {
|
||||
task.addJob<LightStageSetup>("LightStageSetup");
|
||||
task.addJob<BackgroundStageSetup>("BackgroundStageSetup");
|
||||
task.addJob<HazeStageSetup>("HazeStageSetup");
|
||||
task.addJob<render::TransitionStageSetup>("TransitionStageSetup");
|
||||
|
||||
task.addJob<DefaultLightingSetup>("DefaultLightingSetup");
|
||||
|
|
|
@ -56,6 +56,11 @@ void SetupZones::run(const RenderContextPointer& context, const Inputs& inputs)
|
|||
assert(backgroundStage);
|
||||
backgroundStage->_currentFrame.clear();
|
||||
|
||||
// Haze
|
||||
auto hazeStage = context->_scene->getStage<HazeStage>();
|
||||
assert(hazeStage);
|
||||
hazeStage->_currentFrame.clear();
|
||||
|
||||
// call render in the correct order first...
|
||||
render::renderItems(context, inputs);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ void main(void) {
|
|||
frag.scattering,
|
||||
midNormalCurvature,
|
||||
lowNormalCurvature);
|
||||
_fragColor = vec4(color, 1.0);
|
||||
|
||||
_fragColor = vec4(color, 1.0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -325,6 +325,7 @@ protected:
|
|||
template < typename T0, typename T1, typename T2, typename T3, typename T4 > using VaryingSet5 = task::VaryingSet5<T0, T1, T2, T3, T4>; \
|
||||
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5 > using VaryingSet6 = task::VaryingSet6<T0, T1, T2, T3, T4, T5>; \
|
||||
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6 > using VaryingSet7 = task::VaryingSet7<T0, T1, T2, T3, T4, T5, T6>; \
|
||||
template < typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7 > using VaryingSet8 = task::VaryingSet8<T0, T1, T2, T3, T4, T5, T6, T7>; \
|
||||
template < class T, int NUM > using VaryingArray = task::VaryingArray<T, NUM>;
|
||||
|
||||
#endif // hifi_task_Task_h
|
||||
|
|
|
@ -292,7 +292,42 @@ public:
|
|||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
|
||||
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
||||
class VaryingSet8 : public std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying> {
|
||||
public:
|
||||
using Parent = std::tuple<Varying, Varying, Varying, Varying, Varying, Varying, Varying, Varying>;
|
||||
|
||||
VaryingSet8() : Parent(Varying(T0()), Varying(T1()), Varying(T2()), Varying(T3()), Varying(T4()), Varying(T5()), Varying(T6()), Varying(T7())) {}
|
||||
VaryingSet8(const VaryingSet8& src) : Parent(std::get<0>(src), std::get<1>(src), std::get<2>(src), std::get<3>(src), std::get<4>(src), std::get<5>(src), std::get<6>(src), std::get<7>(src)) {}
|
||||
VaryingSet8(const Varying& first, const Varying& second, const Varying& third, const Varying& fourth, const Varying& fifth, const Varying& sixth, const Varying& seventh, const Varying& eighth) : Parent(first, second, third, fourth, fifth, sixth, seventh, eighth) {}
|
||||
|
||||
const T0& get0() const { return std::get<0>((*this)).template get<T0>(); }
|
||||
T0& edit0() { return std::get<0>((*this)).template edit<T0>(); }
|
||||
|
||||
const T1& get1() const { return std::get<1>((*this)).template get<T1>(); }
|
||||
T1& edit1() { return std::get<1>((*this)).template edit<T1>(); }
|
||||
|
||||
const T2& get2() const { return std::get<2>((*this)).template get<T2>(); }
|
||||
T2& edit2() { return std::get<2>((*this)).template edit<T2>(); }
|
||||
|
||||
const T3& get3() const { return std::get<3>((*this)).template get<T3>(); }
|
||||
T3& edit3() { return std::get<3>((*this)).template edit<T3>(); }
|
||||
|
||||
const T4& get4() const { return std::get<4>((*this)).template get<T4>(); }
|
||||
T4& edit4() { return std::get<4>((*this)).template edit<T4>(); }
|
||||
|
||||
const T5& get5() const { return std::get<5>((*this)).template get<T5>(); }
|
||||
T5& edit5() { return std::get<5>((*this)).template edit<T5>(); }
|
||||
|
||||
const T6& get6() const { return std::get<6>((*this)).template get<T6>(); }
|
||||
T6& edit6() { return std::get<6>((*this)).template edit<T6>(); }
|
||||
|
||||
const T7& get7() const { return std::get<7>((*this)).template get<T7>(); }
|
||||
T7& edit7() { return std::get<7>((*this)).template edit<T7>(); }
|
||||
|
||||
Varying asVarying() const { return Varying((*this)); }
|
||||
};
|
||||
|
||||
template < class T, int NUM >
|
||||
class VaryingArray : public std::array<Varying, NUM> {
|
||||
public:
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
/// Scriptable interface a Quaternion helper class object. Used exclusively in the JavaScript API
|
||||
class Quat : public QObject, protected QScriptable {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(glm::quat IDENTITY READ IDENTITY CONSTANT)
|
||||
|
||||
public slots:
|
||||
glm::quat multiply(const glm::quat& q1, const glm::quat& q2);
|
||||
|
@ -63,6 +64,10 @@ public slots:
|
|||
bool equal(const glm::quat& q1, const glm::quat& q2);
|
||||
glm::quat cancelOutRollAndPitch(const glm::quat& q);
|
||||
glm::quat cancelOutRoll(const glm::quat& q);
|
||||
|
||||
private:
|
||||
const glm::quat& IDENTITY() const { return Quaternions::IDENTITY; }
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_Quat_h
|
||||
|
|
|
@ -129,6 +129,101 @@ QString SceneScripting::Stage::getBackgroundMode() const {
|
|||
};
|
||||
}
|
||||
|
||||
void SceneScripting::Stage::setHazeMode(const QString& mode) {
|
||||
if (mode == QString("haze off")) {
|
||||
_skyStage->setHazeMode(model::SunSkyStage::HAZE_OFF);
|
||||
} else if (mode == QString("haze on")) {
|
||||
_skyStage->setHazeMode(model::SunSkyStage::HAZE_ON);
|
||||
}
|
||||
}
|
||||
|
||||
QString SceneScripting::Stage::getHazeMode() const {
|
||||
switch (_skyStage->getHazeMode()) {
|
||||
case model::SunSkyStage::HAZE_OFF:
|
||||
return QString("haze off");
|
||||
case model::SunSkyStage::HAZE_ON:
|
||||
return QString("haze on");
|
||||
default:
|
||||
return QString("inherit");
|
||||
};
|
||||
}
|
||||
|
||||
void SceneScripting::Stage::setHazeRange(const float hazeRange) {
|
||||
_skyStage->setHazeRange(hazeRange);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeRange() const {
|
||||
return _skyStage->getHazeRange();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeColor(const xColor hazeColor) {
|
||||
_skyStage->setHazeColor(hazeColor);
|
||||
}
|
||||
xColor SceneScripting::Stage::getHazeColor() const {
|
||||
return _skyStage->getHazeColor();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeGlareColor(const xColor hazeGlareColor) {
|
||||
_skyStage->setHazeGlareColor(hazeGlareColor);
|
||||
}
|
||||
xColor SceneScripting::Stage::getHazeGlareColor() const {
|
||||
return _skyStage->getHazeGlareColor();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeEnableGlare(const bool hazeEnableGlare) {
|
||||
_skyStage->setHazeEnableGlare(hazeEnableGlare);
|
||||
}
|
||||
bool SceneScripting::Stage::getHazeEnableGlare() const {
|
||||
return _skyStage->getHazeEnableGlare();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeGlareAngle(const float hazeGlareAngle) {
|
||||
_skyStage->setHazeGlareAngle(hazeGlareAngle);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeGlareAngle() const {
|
||||
return _skyStage->getHazeGlareAngle();
|
||||
}
|
||||
|
||||
void SceneScripting::Stage::setHazeAltitudeEffect(const bool hazeAltitudeEffect) {
|
||||
_skyStage->setHazeAltitudeEffect(hazeAltitudeEffect);
|
||||
}
|
||||
bool SceneScripting::Stage::getHazeAltitudeEffect() const {
|
||||
return _skyStage->getHazeAltitudeEffect();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeCeiling(const float hazeCeiling) {
|
||||
_skyStage->setHazeCeiling(hazeCeiling);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeCeiling() const {
|
||||
return _skyStage->getHazeCeiling();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeBaseRef(const float hazeBaseRef) {
|
||||
_skyStage->setHazeBaseRef(hazeBaseRef);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeBaseRef() const {
|
||||
return _skyStage->getHazeBaseRef();
|
||||
}
|
||||
|
||||
void SceneScripting::Stage::setHazeBackgroundBlend(const float hazeBackgroundBlend) {
|
||||
_skyStage->setHazeBackgroundBlend(hazeBackgroundBlend);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeBackgroundBlend() const {
|
||||
return _skyStage->getHazeBackgroundBlend();
|
||||
}
|
||||
|
||||
void SceneScripting::Stage::setHazeAttenuateKeyLight(const bool hazeAttenuateKeyLight) {
|
||||
_skyStage->setHazeAttenuateKeyLight(hazeAttenuateKeyLight);
|
||||
}
|
||||
bool SceneScripting::Stage::getHazeAttenuateKeyLight() const {
|
||||
return _skyStage->getHazeAttenuateKeyLight();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeKeyLightRange(const float hazeKeyLightRange) {
|
||||
_skyStage->setHazeKeyLightRange(hazeKeyLightRange);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeKeyLightRange() const {
|
||||
return _skyStage->getHazeKeyLightRange();
|
||||
}
|
||||
void SceneScripting::Stage::setHazeKeyLightAltitude(const float hazeKeyLightAltitude) {
|
||||
_skyStage->setHazeKeyLightAltitude(hazeKeyLightAltitude);
|
||||
}
|
||||
float SceneScripting::Stage::getHazeKeyLightAltitude() const {
|
||||
return _skyStage->getHazeKeyLightAltitude();
|
||||
}
|
||||
|
||||
SceneScriptingInterface::SceneScriptingInterface() : _stage{ new SceneScripting::Stage{ _skyStage } } {
|
||||
// Let's make sure the sunSkyStage is using a proceduralSkybox
|
||||
_skyStage->setSkybox(model::SkyboxPointer(new ProceduralSkybox()));
|
||||
|
|
|
@ -121,6 +121,58 @@ namespace SceneScripting {
|
|||
void setBackgroundMode(const QString& mode);
|
||||
QString getBackgroundMode() const;
|
||||
|
||||
Q_PROPERTY(QString hazeMode READ getHazeMode WRITE setHazeMode)
|
||||
void setHazeMode(const QString& mode);
|
||||
QString getHazeMode() const;
|
||||
|
||||
Q_PROPERTY(float hazeRange READ getHazeRange WRITE setHazeRange)
|
||||
void setHazeRange(float value);
|
||||
float getHazeRange() const;
|
||||
|
||||
Q_PROPERTY(xColor hazeColor READ getHazeColor WRITE setHazeColor)
|
||||
void setHazeColor(xColor value);
|
||||
xColor getHazeColor() const;
|
||||
|
||||
Q_PROPERTY(xColor hazeGlareColor READ getHazeGlareColor WRITE setHazeGlareColor)
|
||||
void setHazeGlareColor(xColor value);
|
||||
xColor getHazeGlareColor() const;
|
||||
|
||||
Q_PROPERTY(bool hazeEnableGlare READ getHazeEnableGlare WRITE setHazeEnableGlare)
|
||||
void setHazeEnableGlare(bool value);
|
||||
bool getHazeEnableGlare() const;
|
||||
|
||||
Q_PROPERTY(float hazeGlareAngle READ getHazeGlareAngle WRITE setHazeGlareAngle)
|
||||
void setHazeGlareAngle(float value);
|
||||
float getHazeGlareAngle() const;
|
||||
|
||||
Q_PROPERTY(bool hazeAltitudeEffect READ getHazeAltitudeEffect WRITE setHazeAltitudeEffect)
|
||||
void setHazeAltitudeEffect(bool value);
|
||||
bool getHazeAltitudeEffect() const;
|
||||
|
||||
Q_PROPERTY(float hazeCeiling READ getHazeCeiling WRITE setHazeCeiling)
|
||||
void setHazeCeiling(float value);
|
||||
float getHazeCeiling() const;
|
||||
|
||||
Q_PROPERTY(float hazeBaseRef READ getHazeBaseRef WRITE setHazeBaseRef)
|
||||
void setHazeBaseRef(float value);
|
||||
float getHazeBaseRef() const;
|
||||
|
||||
Q_PROPERTY(float hazeBackgroundBlend READ getHazeBackgroundBlend WRITE setHazeBackgroundBlend)
|
||||
void setHazeBackgroundBlend(float value);
|
||||
float getHazeBackgroundBlend() const;
|
||||
|
||||
Q_PROPERTY(bool hazeAttenuateKeyLight READ getHazeAttenuateKeyLight WRITE setHazeAttenuateKeyLight)
|
||||
void setHazeAttenuateKeyLight(bool value);
|
||||
bool getHazeAttenuateKeyLight() const;
|
||||
|
||||
Q_PROPERTY(float hazeKeyLightRange READ getHazeKeyLightRange WRITE setHazeKeyLightRange)
|
||||
void setHazeKeyLightRange(float value);
|
||||
float getHazeKeyLightRange() const;
|
||||
|
||||
Q_PROPERTY(float hazeKeyLightAltitude READ getHazeKeyLightAltitude WRITE setHazeKeyLightAltitude)
|
||||
void setHazeKeyLightAltitude(float value);
|
||||
float getHazeKeyLightAltitude() const;
|
||||
|
||||
protected:
|
||||
model::SunSkyStagePointer _skyStage;
|
||||
LocationPointer _location;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
/// Scriptable interface for a UUID helper class object. Used exclusively in the JavaScript API
|
||||
class ScriptUUID : public QObject, protected QScriptable {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString NULL READ NULL_UUID CONSTANT) // String for use in scripts.
|
||||
|
||||
public slots:
|
||||
QUuid fromString(const QString& string);
|
||||
|
@ -28,6 +29,10 @@ public slots:
|
|||
bool isEqual(const QUuid& idA, const QUuid& idB);
|
||||
bool isNull(const QUuid& id);
|
||||
void print(const QString& label, const QUuid& id);
|
||||
|
||||
private:
|
||||
const QString NULL_UUID() { return NULL_ID; }
|
||||
const QString NULL_ID { "{00000000-0000-0000-0000-000000000000}" };
|
||||
};
|
||||
|
||||
#endif // hifi_ScriptUUID_h
|
||||
|
|
24
libraries/shared/src/ComponentMode.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// ComponentMode.h
|
||||
// libraries/entities/src
|
||||
//
|
||||
// Created by Nissim Hadar on 9/21/17.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ComponentMode_h
|
||||
#define hifi_ComponentMode_h
|
||||
|
||||
enum ComponentMode {
|
||||
COMPONENT_MODE_INHERIT,
|
||||
COMPONENT_MODE_DISABLED,
|
||||
COMPONENT_MODE_ENABLED,
|
||||
|
||||
COMPONENT_MODE_ITEM_COUNT
|
||||
};
|
||||
|
||||
#endif // hifi_ComponentMode_h
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
#include <gl/OffscreenGLCanvas.h>
|
||||
#include <gl/GLHelpers.h>
|
||||
#include <gl/Context.h>
|
||||
#include <shared/ReadWriteLockable.h>
|
||||
|
||||
#include "types/FileTypeProfile.h"
|
||||
#include "types/HFWebEngineProfile.h"
|
||||
|
@ -52,6 +53,53 @@ Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml")
|
|||
Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl")
|
||||
Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus")
|
||||
|
||||
|
||||
class OffscreenQmlWhitelist : public Dependency, private ReadWriteLockable {
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
public:
|
||||
|
||||
void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback) {
|
||||
withWriteLock([&] {
|
||||
for (const auto& url : urls) {
|
||||
_callbacks[url].push_back(callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
QList<QmlContextCallback> getCallbacksForUrl(const QUrl& url) const {
|
||||
return resultWithReadLock<QList<QmlContextCallback>>([&] {
|
||||
QList<QmlContextCallback> result;
|
||||
auto itr = _callbacks.find(url);
|
||||
if (_callbacks.end() != itr) {
|
||||
result = *itr;
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
QHash<QUrl, QList<QmlContextCallback>> _callbacks;
|
||||
};
|
||||
|
||||
QSharedPointer<OffscreenQmlWhitelist> getQmlWhitelist() {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
DependencyManager::set<OffscreenQmlWhitelist>();
|
||||
});
|
||||
|
||||
return DependencyManager::get<OffscreenQmlWhitelist>();
|
||||
}
|
||||
|
||||
|
||||
void OffscreenQmlSurface::addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback) {
|
||||
getQmlWhitelist()->addWhitelistContextHandler(urls, callback);
|
||||
}
|
||||
|
||||
|
||||
QmlContextCallback OffscreenQmlSurface::DEFAULT_CONTEXT_CALLBACK = [](QQmlContext*, QObject*) {};
|
||||
|
||||
struct TextureSet {
|
||||
// The number of surfaces with this size
|
||||
size_t count { 0 };
|
||||
|
@ -640,18 +688,26 @@ void OffscreenQmlSurface::setBaseUrl(const QUrl& baseUrl) {
|
|||
_qmlContext->setBaseUrl(baseUrl);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
|
||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, const QmlContextCallback& onQmlLoadedCallback) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
qCWarning(uiLogging) << "Called load on a non-surface thread";
|
||||
}
|
||||
// Synchronous loading may take a while; restart the deadlock timer
|
||||
QMetaObject::invokeMethod(qApp, "updateHeartbeat", Qt::DirectConnection);
|
||||
|
||||
// Get any whitelist functionality
|
||||
QList<QmlContextCallback> callbacks = getQmlWhitelist()->getCallbacksForUrl(qmlSource);
|
||||
// If we have whitelisted content, we must load a new context
|
||||
createNewContext |= !callbacks.empty();
|
||||
callbacks.push_back(onQmlLoadedCallback);
|
||||
|
||||
QQmlContext* targetContext = _qmlContext;
|
||||
if (_rootItem && createNewContext) {
|
||||
targetContext = new QQmlContext(targetContext);
|
||||
}
|
||||
|
||||
|
||||
// FIXME eliminate loading of relative file paths for QML
|
||||
QUrl finalQmlSource = qmlSource;
|
||||
if ((qmlSource.isRelative() && !qmlSource.isEmpty()) || qmlSource.scheme() == QLatin1String("file")) {
|
||||
finalQmlSource = _qmlContext->resolvedUrl(qmlSource);
|
||||
|
@ -659,29 +715,32 @@ void OffscreenQmlSurface::load(const QUrl& qmlSource, bool createNewContext, std
|
|||
|
||||
auto qmlComponent = new QQmlComponent(_qmlContext->engine(), finalQmlSource, QQmlComponent::PreferSynchronous);
|
||||
if (qmlComponent->isLoading()) {
|
||||
connect(qmlComponent, &QQmlComponent::statusChanged, this,
|
||||
[this, qmlComponent, targetContext, onQmlLoadedCallback](QQmlComponent::Status) {
|
||||
finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
|
||||
connect(qmlComponent, &QQmlComponent::statusChanged, this, [=](QQmlComponent::Status) {
|
||||
finishQmlLoad(qmlComponent, targetContext, callbacks);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
finishQmlLoad(qmlComponent, targetContext, onQmlLoadedCallback);
|
||||
finishQmlLoad(qmlComponent, targetContext, callbacks);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
|
||||
void OffscreenQmlSurface::loadInNewContext(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback) {
|
||||
load(qmlSource, true, onQmlLoadedCallback);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
|
||||
void OffscreenQmlSurface::load(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback) {
|
||||
load(qmlSource, false, onQmlLoadedCallback);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::load(const QString& qmlSourceFile, const QmlContextCallback& onQmlLoadedCallback) {
|
||||
return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::clearCache() {
|
||||
_qmlContext->engine()->clearComponentCache();
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback) {
|
||||
void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QList<QmlContextCallback>& callbacks) {
|
||||
disconnect(qmlComponent, &QQmlComponent::statusChanged, this, 0);
|
||||
if (qmlComponent->isError()) {
|
||||
for (const auto& error : qmlComponent->errors()) {
|
||||
|
@ -716,7 +775,9 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
|||
// Make sure we will call callback for this codepath
|
||||
// Call this before qmlComponent->completeCreate() otherwise ghost window appears
|
||||
if (newItem && _rootItem) {
|
||||
onQmlLoadedCallback(qmlContext, newObject);
|
||||
for (const auto& callback : callbacks) {
|
||||
callback(qmlContext, newObject);
|
||||
}
|
||||
}
|
||||
|
||||
QObject* eventBridge = qmlContext->contextProperty("eventBridge").value<QObject*>();
|
||||
|
@ -751,8 +812,11 @@ void OffscreenQmlSurface::finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext
|
|||
_rootItem = newItem;
|
||||
_rootItem->setParentItem(_quickWindow->contentItem());
|
||||
_rootItem->setSize(_quickWindow->renderTargetSize());
|
||||
|
||||
// Call this callback after rootitem is set, otherwise VrMenu wont work
|
||||
onQmlLoadedCallback(qmlContext, newObject);
|
||||
for (const auto& callback : callbacks) {
|
||||
callback(qmlContext, newObject);
|
||||
}
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::updateQuick() {
|
||||
|
@ -1018,6 +1082,36 @@ void OffscreenQmlSurface::synthesizeKeyPress(QString key, QObject* targetOverrid
|
|||
}
|
||||
}
|
||||
|
||||
static void forEachKeyboard(QQuickItem* parent, std::function<void(QQuickItem*)> function) {
|
||||
if (!function) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto keyboards = parent->findChildren<QObject*>("keyboard");
|
||||
|
||||
for (auto keyboardObject : keyboards) {
|
||||
auto keyboard = qobject_cast<QQuickItem*>(keyboardObject);
|
||||
if (keyboard) {
|
||||
function(keyboard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const int TEXTINPUT_PASSWORD = 2;
|
||||
|
||||
static QQuickItem* getTopmostParent(QQuickItem* item) {
|
||||
QObject* itemObject = item;
|
||||
while (itemObject) {
|
||||
if (itemObject->parent()) {
|
||||
itemObject = itemObject->parent();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return qobject_cast<QQuickItem*> (itemObject);
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool numeric) {
|
||||
#if Q_OS_ANDROID
|
||||
return;
|
||||
|
@ -1030,11 +1124,40 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n
|
|||
// if HMD is being worn, allow keyboard to open. allow it to close, HMD or not.
|
||||
if (!raised || qApp->property(hifi::properties::HMD).toBool()) {
|
||||
QQuickItem* item = dynamic_cast<QQuickItem*>(object);
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto echoMode = item->property("echoMode");
|
||||
bool isPasswordField = echoMode.isValid() && echoMode.toInt() == TEXTINPUT_PASSWORD;
|
||||
|
||||
// we need to somehow pass 'isPasswordField' to visible keyboard so it will change its 'mirror text' to asterixes
|
||||
// the issue in some cases there might be more than one keyboard in object tree and it is hard to understand which one is being used at the moment
|
||||
// unfortunately attempts to check for visibility failed becuase visibility is not updated yet. So... I don't see other way than just update properties for all the keyboards
|
||||
|
||||
auto topmostParent = getTopmostParent(item);
|
||||
if (topmostParent) {
|
||||
forEachKeyboard(topmostParent, [&](QQuickItem* keyboard) {
|
||||
keyboard->setProperty("mirroredText", QVariant::fromValue(QString("")));
|
||||
keyboard->setProperty("password", isPasswordField);
|
||||
});
|
||||
}
|
||||
|
||||
// for future probably makes sense to consider one of the following:
|
||||
// 1. make keyboard a singleton, which will be dynamically re-parented before showing
|
||||
// 2. track currently visible keyboard somewhere, allow to subscribe for this signal
|
||||
// any of above should also eliminate need in duplicated properties and code below
|
||||
|
||||
while (item) {
|
||||
// Numeric value may be set in parameter from HTML UI; for QML UI, detect numeric fields here.
|
||||
numeric = numeric || QString(item->metaObject()->className()).left(7) == "SpinBox";
|
||||
|
||||
if (item->property("keyboardRaised").isValid()) {
|
||||
forEachKeyboard(item, [&](QQuickItem* keyboard) {
|
||||
keyboard->setProperty("mirroredText", QVariant::fromValue(QString("")));
|
||||
keyboard->setProperty("password", isPasswordField);
|
||||
});
|
||||
|
||||
// FIXME - HMD only: Possibly set value of "keyboardEnabled" per isHMDMode() for use in WebView.qml.
|
||||
if (item->property("punctuationMode").isValid()) {
|
||||
item->setProperty("punctuationMode", QVariant(numeric));
|
||||
|
|
|
@ -35,12 +35,18 @@ class QQuickItem;
|
|||
// one copy in flight, and one copy being used by the receiver
|
||||
#define GPU_RESOURCE_BUFFER_SIZE 3
|
||||
|
||||
using QmlContextCallback = std::function<void(QQmlContext*, QObject*)>;
|
||||
|
||||
class OffscreenQmlSurface : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
|
||||
public:
|
||||
static void setSharedContext(QOpenGLContext* context);
|
||||
|
||||
static QmlContextCallback DEFAULT_CONTEXT_CALLBACK;
|
||||
static void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback);
|
||||
static void addWhitelistContextHandler(const QUrl& url, const QmlContextCallback& callback) { addWhitelistContextHandler({ { url } }, callback); };
|
||||
|
||||
OffscreenQmlSurface();
|
||||
virtual ~OffscreenQmlSurface();
|
||||
|
||||
|
@ -50,12 +56,10 @@ public:
|
|||
void resize(const QSize& size, bool forceResize = false);
|
||||
QSize size() const;
|
||||
|
||||
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
|
||||
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
|
||||
Q_INVOKABLE void load(const QUrl& qmlSource, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {});
|
||||
Q_INVOKABLE void load(const QString& qmlSourceFile, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback = [](QQmlContext*, QObject*) {}) {
|
||||
return load(QUrl(qmlSourceFile), onQmlLoadedCallback);
|
||||
}
|
||||
Q_INVOKABLE void load(const QUrl& qmlSource, bool createNewContext, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||
Q_INVOKABLE void loadInNewContext(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||
Q_INVOKABLE void load(const QUrl& qmlSource, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||
Q_INVOKABLE void load(const QString& qmlSourceFile, const QmlContextCallback& onQmlLoadedCallback = DEFAULT_CONTEXT_CALLBACK);
|
||||
void clearCache();
|
||||
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; }
|
||||
// Optional values for event handling
|
||||
|
@ -120,7 +124,7 @@ protected:
|
|||
private:
|
||||
static QOpenGLContext* getSharedContext();
|
||||
|
||||
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, std::function<void(QQmlContext*, QObject*)> onQmlLoadedCallback);
|
||||
void finishQmlLoad(QQmlComponent* qmlComponent, QQmlContext* qmlContext, const QList<QmlContextCallback>& callbacks);
|
||||
QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject);
|
||||
void setupFbo();
|
||||
bool allowNewFrame(uint8_t fps);
|
||||
|
|
185
scripts/developer/debugging/debugHaze.qml
Normal file
|
@ -0,0 +1,185 @@
|
|||
//
|
||||
// haze.qml
|
||||
// developer/utilities/render
|
||||
//
|
||||
// Nissim Hadar, created on 9/8/2017.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import "../utilities/render/configSlider"
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property var hazeModel: Render.getConfig("RenderMainView.HazeModel")
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
|
||||
Row {
|
||||
CheckBox {
|
||||
text: "Haze Active"
|
||||
checked: root.hazeModel["isHazeActive"]
|
||||
onCheckedChanged: {
|
||||
root.hazeModel["isHazeActive"] = checked;
|
||||
}
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Modulated Color"
|
||||
checked: root.hazeModel["isModulateColorActive"]
|
||||
onCheckedChanged: {
|
||||
root.hazeModel["isModulateColorActive"] = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckBox {
|
||||
text: "Altitude Based"
|
||||
checked: root.hazeModel["isAltitudeBased"]
|
||||
onCheckedChanged: {
|
||||
root.hazeModel["isAltitudeBased"] = checked;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Range"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeRange_m"
|
||||
max: 10000
|
||||
min: 5
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Altitude"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeAltitude_m"
|
||||
max: 2000
|
||||
min: 5
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Haze Color R"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeColorR"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Haze Color G"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeColorG"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Haze Color B"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeColorB"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Sun R"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeDirectionalLightColorR"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Sun G"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeDirectionalLightColorG"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Sun B"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeDirectionalLightColorB"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Sun glare angle"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeDirectionalLightAngle_degs"
|
||||
max: 70.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Base"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeBaseReference"
|
||||
max: 500.0
|
||||
min: -500.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "BG Blend"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeBackgroundBlendValue"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Keylight Attenuation"
|
||||
checked: root.hazeModel["isDirectionaLightAttenuationActive"]
|
||||
onCheckedChanged: {
|
||||
root.hazeModel["isDirectionaLightAttenuationActive"] = checked;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Range"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeKeyLightRange_m"
|
||||
max: 10000
|
||||
min: 5
|
||||
width: 280
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
label: "Altitude"
|
||||
integral: false
|
||||
config: root.hazeModel
|
||||
property: "hazeKeyLightAltitude_m"
|
||||
max: 2000
|
||||
min: 5
|
||||
width: 280
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,4 +53,8 @@ ScriptDiscoveryService.clearDebugWindow.connect(function() {
|
|||
window.clearDebugWindow();
|
||||
});
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
window.close();
|
||||
})
|
||||
|
||||
}());
|
||||
|
|
64
scripts/developer/debugging/surfaceGeometryPass.qml
Normal file
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// surfaceGeometryPass.qml
|
||||
//
|
||||
// Created by Sam Gateau on 6/6/2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import "configSlider"
|
||||
|
||||
Column {
|
||||
spacing: 8
|
||||
Column {
|
||||
id: surfaceGeometry
|
||||
spacing: 10
|
||||
|
||||
Column{
|
||||
ConfigSlider {
|
||||
label: qsTr("Depth Threshold [cm]")
|
||||
integral: false
|
||||
config: Render.getConfig("RenderMainView.SurfaceGeometry")
|
||||
property: "depthThreshold"
|
||||
max: 5.0
|
||||
min: 0.0
|
||||
}
|
||||
Repeater {
|
||||
model: [
|
||||
"Basis Scale:basisScale:2.0:false",
|
||||
"Curvature Scale:curvatureScale:100.0:false",
|
||||
]
|
||||
ConfigSlider {
|
||||
label: qsTr(modelData.split(":")[0])
|
||||
integral: (modelData.split(":")[3] == 'true')
|
||||
config: Render.getConfig("RenderMainView.SurfaceGeometry")
|
||||
property: modelData.split(":")[1]
|
||||
max: modelData.split(":")[2]
|
||||
min: 0.0
|
||||
}
|
||||
}
|
||||
CheckBox {
|
||||
text: "Half Resolution"
|
||||
checked: Render.getConfig("RenderMainView.SurfaceGeometry")["resolutionLevel"]
|
||||
onCheckedChanged: { Render.getConfig("RenderMainView.SurfaceGeometry")["resolutionLevel"] = checked }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: [ "Diffusion Scale:RenderMainView.SurfaceGeometry:diffuseFilterScale:2.0",
|
||||
"Diffusion Depth Threshold:RenderMainView.SurfaceGeometry:diffuseDepthThreshold:1.0"
|
||||
]
|
||||
ConfigSlider {
|
||||
label: qsTr(modelData.split(":")[0])
|
||||
integral: false
|
||||
config: Render.getConfig(modelData.split(":")[1])
|
||||
property: modelData.split(":")[2]
|
||||
max: modelData.split(":")[3]
|
||||
min: 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
|
||||
|
||||
var debugSphereBaseProperties = {
|
||||
type: "Sphere",
|
||||
dimensions: { x: 0.2, y: 0.2, z: 0.2 },
|
||||
|
|
5
scripts/developer/tests/hazeTestInitialPose.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
var ORIGIN = {x: -68.7, y: 27.4, z: 487.7};
|
||||
var ROT_IDENT = {x: 0, y: 0.901, z: 0, w: 0.434};
|
||||
|
||||
MyAvatar.position = ORIGIN;
|
||||
MyAvatar.orientation = ROT_IDENT;
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
Script.include("libraries/utils.js");
|
||||
|
||||
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
|
||||
var DEFAULT_WEARABLE_DATA = {
|
||||
joints: {}
|
||||
};
|
||||
|
@ -116,7 +115,7 @@ function AttachedEntitiesManager() {
|
|||
var allowedJoints = getEntityCustomData('wearable', grabbedEntity, DEFAULT_WEARABLE_DATA).joints;
|
||||
|
||||
var props = Entities.getEntityProperties(grabbedEntity, ["position", "parentID", "parentJointIndex"]);
|
||||
if (props.parentID === NULL_UUID || props.parentID === MyAvatar.sessionUUID) {
|
||||
if (props.parentID === Uuid.NULL || props.parentID === MyAvatar.sessionUUID) {
|
||||
var bestJointName = "";
|
||||
var bestJointIndex = -1;
|
||||
var bestJointDistance = 0;
|
||||
|
@ -168,7 +167,7 @@ function AttachedEntitiesManager() {
|
|||
if (updatePresets) {
|
||||
this.updateRelativeOffsets(newEntity);
|
||||
}
|
||||
} else if (props.parentID != NULL_UUID) {
|
||||
} else if (props.parentID != Uuid.NULL) {
|
||||
// drop the entity and set it to have no parent (not on the avatar), unless it's being equipped in a hand.
|
||||
if (props.parentID === MyAvatar.sessionUUID &&
|
||||
(props.parentJointIndex == MyAvatar.getJointIndex("RightHand") ||
|
||||
|
@ -176,7 +175,7 @@ function AttachedEntitiesManager() {
|
|||
// this is equipped on a hand -- don't clear the parent.
|
||||
} else {
|
||||
var wearProps = Entities.getEntityProperties(grabbedEntity);
|
||||
wearProps.parentID = NULL_UUID;
|
||||
wearProps.parentID = Uuid.NULL;
|
||||
wearProps.parentJointIndex = -1;
|
||||
delete wearProps.id;
|
||||
delete wearProps.created;
|
||||
|
|
|
@ -30,7 +30,6 @@ var OVERLAY_DATA = {
|
|||
};
|
||||
var AVATAR_MOVE_FOR_ACTIVE_DISTANCE = 0.8; // meters -- no longer away if avatar moves this far while away
|
||||
|
||||
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
|
||||
var CAMERA_MATRIX = -7;
|
||||
|
||||
var OVERLAY_DATA_HMD = {
|
||||
|
@ -44,7 +43,7 @@ var OVERLAY_DATA_HMD = {
|
|||
scale: 2 * MyAvatar.sensorToWorldScale,
|
||||
emissive: true,
|
||||
drawInFront: true,
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: CAMERA_MATRIX
|
||||
};
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
|||
var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ;
|
||||
|
||||
var PROFILE = false;
|
||||
var DEBUG = true;
|
||||
var DEBUG = false;
|
||||
|
||||
if (typeof Test !== "undefined") {
|
||||
PROFILE = true;
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
|
||||
/* globals createControllerDisplay:true deleteControllerDisplay:true */
|
||||
|
||||
var PARENT_ID = "{00000000-0000-0000-0000-000000000001}";
|
||||
|
||||
function clamp(value, min, max) {
|
||||
if (value < min) {
|
||||
return min;
|
||||
|
@ -178,7 +176,7 @@ createControllerDisplay = function(config) {
|
|||
dimensions: Vec3.multiply(sensorScaleFactor, controller.dimensions),
|
||||
localRotation: controller.rotation,
|
||||
localPosition: Vec3.multiply(sensorScaleFactor, position),
|
||||
parentID: PARENT_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: controller.jointIndex,
|
||||
ignoreRayIntersection: true
|
||||
});
|
||||
|
@ -198,7 +196,7 @@ createControllerDisplay = function(config) {
|
|||
url: part.modelURL,
|
||||
localPosition: partPosition,
|
||||
localRotation: innerRotation,
|
||||
parentID: PARENT_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: controller.jointIndex,
|
||||
ignoreRayIntersection: true
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID,
|
||||
getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||
getControllerJointIndex, enableDispatcherModule, disableDispatcherModule,
|
||||
Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions,
|
||||
Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable,
|
||||
cloneEntity, DISPATCHER_PROPERTIES
|
||||
|
@ -333,7 +333,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
var props = controllerData.nearbyEntityPropertiesByID[hotspot.entityID];
|
||||
|
||||
var hasParent = true;
|
||||
if (props.parentID === NULL_UUID) {
|
||||
if (props.parentID === Uuid.NULL) {
|
||||
hasParent = false;
|
||||
}
|
||||
|
||||
|
@ -491,7 +491,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
}
|
||||
|
||||
var reparentProps = {
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: handJointIndex,
|
||||
localVelocity: {x: 0, y: 0, z: 0},
|
||||
localAngularVelocity: {x: 0, y: 0, z: 0},
|
||||
|
@ -539,7 +539,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
|
||||
this.endEquipEntity = function () {
|
||||
Entities.editEntity(this.targetEntityID, {
|
||||
parentID: NULL_UUID,
|
||||
parentID: Uuid.NULL,
|
||||
parentJointIndex: -1
|
||||
});
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
|
||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities,
|
||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, entityIsGrabbable,
|
||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
|
||||
|
||||
*/
|
||||
|
@ -23,6 +23,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
(function() {
|
||||
var PICK_WITH_HAND_RAY = true;
|
||||
|
||||
var SEARCH_SPHERE_SIZE = 0.0132;
|
||||
var dim = {x: SEARCH_SPHERE_SIZE, y: SEARCH_SPHERE_SIZE, z: SEARCH_SPHERE_SIZE};
|
||||
var halfPath = {
|
||||
type: "line3d",
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
|
@ -33,10 +35,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var halfEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -54,10 +57,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var fullEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -75,7 +79,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
|
||||
var renderStates = [
|
||||
|
@ -135,10 +139,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
100);
|
||||
|
||||
this.updateLaserPointer = function(controllerData) {
|
||||
var SEARCH_SPHERE_SIZE = 0.011;
|
||||
var MIN_SPHERE_SIZE = 0.0005;
|
||||
var radius = Math.max(1.2 * SEARCH_SPHERE_SIZE * this.intersectionDistance, MIN_SPHERE_SIZE) * MyAvatar.sensorToWorldScale;
|
||||
var dim = {x: radius, y: radius, z: radius};
|
||||
var mode = "hold";
|
||||
if (!this.distanceHolding && !this.distanceRotating) {
|
||||
if (controllerData.triggerClicks[this.hand]) {
|
||||
|
@ -150,16 +150,10 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
var laserPointerID = PICK_WITH_HAND_RAY ? this.laserPointer : this.headLaserPointer;
|
||||
if (mode === "full") {
|
||||
var fullEndToEdit = PICK_WITH_HAND_RAY ? this.fullEnd : fullEnd;
|
||||
fullEndToEdit.dimensions = dim;
|
||||
LaserPointers.editRenderState(laserPointerID, mode, { path: fullPath, end: fullEndToEdit });
|
||||
this.contextOverlayTimer = false;
|
||||
this.destroyContextOverlay();
|
||||
} else if (mode === "half") {
|
||||
var halfEndToEdit = PICK_WITH_HAND_RAY ? this.halfEnd : halfEnd;
|
||||
halfEndToEdit.dimensions = dim;
|
||||
LaserPointers.editRenderState(laserPointerID, mode, {path: halfPath, end: halfEndToEdit});
|
||||
}
|
||||
|
||||
LaserPointers.enableLaserPointer(laserPointerID);
|
||||
LaserPointers.setRenderState(laserPointerID, mode);
|
||||
if (this.distanceHolding || this.distanceRotating) {
|
||||
|
@ -238,7 +232,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
tag: "far-grab-" + MyAvatar.sessionUUID,
|
||||
ttl: ACTION_TTL
|
||||
});
|
||||
if (this.actionID === NULL_UUID) {
|
||||
if (this.actionID === Uuid.NULL) {
|
||||
this.actionID = null;
|
||||
}
|
||||
|
||||
|
@ -577,8 +571,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
LaserPointers.removeLaserPointer(this.laserPointer);
|
||||
};
|
||||
|
||||
this.halfEnd = halfEnd;
|
||||
this.fullEnd = fullEnd;
|
||||
this.laserPointer = LaserPointers.createLaserPointer({
|
||||
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
|
||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||
|
@ -586,6 +578,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
posOffset: getGrabPointSphereOffset(this.handToController(), true),
|
||||
renderStates: renderStates,
|
||||
faceAvatar: true,
|
||||
distanceScaleEnd: true,
|
||||
defaultRenderStates: defaultRenderStates
|
||||
});
|
||||
}
|
||||
|
|
|
@ -9,13 +9,15 @@
|
|||
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, MyAvatar, getGrabPointSphereOffset,
|
||||
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, getGrabbableData
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
|
||||
(function() {
|
||||
var SEARCH_SPHERE_SIZE = 0.0132;
|
||||
var dim = {x: SEARCH_SPHERE_SIZE, y: SEARCH_SPHERE_SIZE, z: SEARCH_SPHERE_SIZE};
|
||||
var halfPath = {
|
||||
type: "line3d",
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
|
@ -26,10 +28,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var halfEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -47,10 +50,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var fullEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -68,7 +72,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
|
||||
var renderStates = [
|
||||
|
@ -107,10 +111,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.updateLaserPointer = function(controllerData) {
|
||||
var SEARCH_SPHERE_SIZE = 0.011;
|
||||
var MIN_SPHERE_SIZE = 0.0005;
|
||||
var radius = Math.max(1.2 * SEARCH_SPHERE_SIZE * this.intersectionDistance, MIN_SPHERE_SIZE);
|
||||
var dim = {x: radius, y: radius, z: radius};
|
||||
var mode = "none";
|
||||
if (controllerData.triggerClicks[this.hand]) {
|
||||
mode = "full";
|
||||
|
@ -118,18 +118,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
mode = "half";
|
||||
}
|
||||
|
||||
var laserPointerID = this.laserPointer;
|
||||
if (mode === "full") {
|
||||
var fullEndToEdit = this.fullEnd;
|
||||
fullEndToEdit.dimensions = dim;
|
||||
LaserPointers.editRenderState(laserPointerID, mode, {path: fullPath, end: fullEndToEdit});
|
||||
} else if (mode === "half") {
|
||||
var halfEndToEdit = this.halfEnd;
|
||||
halfEndToEdit.dimensions = dim;
|
||||
LaserPointers.editRenderState(laserPointerID, mode, {path: halfPath, end: halfEndToEdit});
|
||||
}
|
||||
LaserPointers.enableLaserPointer(laserPointerID);
|
||||
LaserPointers.setRenderState(laserPointerID, mode);
|
||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||
LaserPointers.setRenderState(this.laserPointer, mode);
|
||||
};
|
||||
|
||||
this.laserPointerOff = function() {
|
||||
|
@ -192,8 +182,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
return makeRunningValues(true, [this.targetEntityID], []);
|
||||
};
|
||||
|
||||
this.halfEnd = halfEnd;
|
||||
this.fullEnd = fullEnd;
|
||||
this.laserPointer = LaserPointers.createLaserPointer({
|
||||
joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND",
|
||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||
|
@ -201,6 +189,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
posOffset: getGrabPointSphereOffset(this.handToController(), true),
|
||||
renderStates: renderStates,
|
||||
faceAvatar: true,
|
||||
distanceScaleEnd: true,
|
||||
defaultRenderStates: defaultRenderStates
|
||||
});
|
||||
|
||||
|
|
|
@ -11,17 +11,19 @@
|
|||
//
|
||||
|
||||
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat,
|
||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID,
|
||||
getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities,
|
||||
enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable,
|
||||
makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic,
|
||||
getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI
|
||||
|
||||
*/
|
||||
(function() {
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
var ControllerDispatcherUtils = Script.require("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
var END_RADIUS = 0.005;
|
||||
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
|
||||
var halfPath = {
|
||||
type: "line3d",
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
|
@ -32,10 +34,11 @@
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawHUDLayer: true,
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var halfEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -53,10 +56,11 @@
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawHUDLayer: true,
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var fullEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -74,7 +78,7 @@
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawHUDLayer: true,
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
|
||||
var renderStates = [
|
||||
|
@ -126,17 +130,6 @@
|
|||
};
|
||||
|
||||
this.updateLaserPointer = function(controllerData) {
|
||||
var RADIUS = 0.005;
|
||||
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
||||
|
||||
if (this.mode === "full") {
|
||||
this.fullEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
|
||||
} else if (this.mode === "half") {
|
||||
this.halfEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
|
||||
}
|
||||
|
||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||
};
|
||||
|
@ -212,8 +205,6 @@
|
|||
LaserPointers.removeLaserPointer(this.laserPointer);
|
||||
};
|
||||
|
||||
this.halfEnd = halfEnd;
|
||||
this.fullEnd = fullEnd;
|
||||
this.laserPointer = LaserPointers.createLaserPointer({
|
||||
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
||||
filter: RayPick.PICK_HUD,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||
Messages, makeDispatcherModuleParameters, AVATAR_SELF_ID, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
Messages, makeDispatcherModuleParameters, HMD, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE,
|
||||
getEnabledModuleByName, PICK_MAX_DISTANCE, isInEditMode, LaserPointers, RayPick
|
||||
*/
|
||||
|
@ -18,6 +18,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
Script.include("/~/system/libraries/utils.js");
|
||||
|
||||
(function () {
|
||||
var END_RADIUS = 0.005;
|
||||
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
|
||||
var halfPath = {
|
||||
type: "line3d",
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
|
@ -28,10 +30,11 @@ Script.include("/~/system/libraries/utils.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var halfEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -49,10 +52,11 @@ Script.include("/~/system/libraries/utils.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var fullEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -70,7 +74,7 @@ Script.include("/~/system/libraries/utils.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
|
||||
var renderStates = [
|
||||
|
@ -121,17 +125,6 @@ Script.include("/~/system/libraries/utils.js");
|
|||
};
|
||||
|
||||
this.updateLaserPointer = function(controllerData) {
|
||||
var RADIUS = 0.005;
|
||||
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
||||
|
||||
if (this.mode === "full") {
|
||||
this.fullEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
|
||||
} else if (this.mode === "half") {
|
||||
this.halfEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
|
||||
}
|
||||
|
||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||
};
|
||||
|
@ -230,10 +223,6 @@ Script.include("/~/system/libraries/utils.js");
|
|||
LaserPointers.removeLaserPointer(this.laserPointer);
|
||||
};
|
||||
|
||||
|
||||
this.halfEnd = halfEnd;
|
||||
this.fullEnd = fullEnd;
|
||||
|
||||
this.laserPointer = LaserPointers.createLaserPointer({
|
||||
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
||||
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||
getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||
getControllerJointIndex, getGrabbableData, enableDispatcherModule, disableDispatcherModule,
|
||||
propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable,
|
||||
Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues,
|
||||
TRIGGER_OFF_VALUE, NEAR_GRAB_RADIUS, findGroupParent, entityIsCloneable, propsAreCloneDynamic, cloneEntity,
|
||||
|
@ -101,7 +101,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
kinematicSetVelocity: true,
|
||||
ignoreIK: this.ignoreIK
|
||||
});
|
||||
if (this.actionID === NULL_UUID) {
|
||||
if (this.actionID === Uuid.NULL) {
|
||||
this.actionID = null;
|
||||
return;
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
|
||||
if (targetProps) {
|
||||
if ((!propsArePhysical(targetProps) && !propsAreCloneDynamic(targetProps)) ||
|
||||
targetProps.parentID != NULL_UUID) {
|
||||
targetProps.parentID !== Uuid.NULL) {
|
||||
return makeRunningValues(false, [], []); // let nearParentGrabEntity handle it
|
||||
} else {
|
||||
this.targetEntityID = targetProps.id;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID,
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
|
||||
enableDispatcherModule, disableDispatcherModule, propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||
TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues, NEAR_GRAB_RADIUS,
|
||||
findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH,
|
||||
|
@ -50,7 +50,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
return false;
|
||||
}
|
||||
|
||||
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
|
||||
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== MyAvatar.SELF_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
Entities.callEntityMethod(targetProps.id, "startNearGrab", args);
|
||||
|
||||
var reparentProps = {
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: handJointIndex,
|
||||
localVelocity: {x: 0, y: 0, z: 0},
|
||||
localAngularVelocity: {x: 0, y: 0, z: 0}
|
||||
|
@ -120,7 +120,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
this.hapticTargetID = null;
|
||||
var props = controllerData.nearbyEntityPropertiesByID[this.targetEntityID];
|
||||
if (this.thisHandIsParent(props)) {
|
||||
if (this.previousParentID[this.targetEntityID] === NULL_UUID || this.previousParentID === undefined) {
|
||||
if (this.previousParentID[this.targetEntityID] === Uuid.NULL || this.previousParentID === undefined) {
|
||||
Entities.editEntity(this.targetEntityID, {
|
||||
parentID: this.previousParentID[this.targetEntityID],
|
||||
parentJointIndex: this.previousParentJointIndex[this.targetEntityID]
|
||||
|
@ -152,7 +152,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
var now = Date.now();
|
||||
if (now - this.lastUnequipCheckTime > MSECS_PER_SEC * TEAR_AWAY_CHECK_TIME) {
|
||||
this.lastUnequipCheckTime = now;
|
||||
if (props.parentID == AVATAR_SELF_ID) {
|
||||
if (props.parentID === MyAvatar.SELF_ID) {
|
||||
var sensorScaleFactor = MyAvatar.sensorToWorldScale;
|
||||
var handPosition = controllerData.controllerLocations[this.hand].position;
|
||||
var dist = distanceBetweenPointAndEntityBoundingBox(handPosition, props);
|
||||
|
@ -198,7 +198,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
var UNHOOK_LOOP_DETECT_MS = 200;
|
||||
if (_this.previouslyUnhooked[childID]) {
|
||||
if (now - _this.previouslyUnhooked[childID] < UNHOOK_LOOP_DETECT_MS) {
|
||||
previousParentID = NULL_UUID;
|
||||
previousParentID = Uuid.NULL;
|
||||
previousParentJointIndex = -1;
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
parentJointIndex: previousParentJointIndex
|
||||
});
|
||||
} else {
|
||||
Entities.editEntity(childID, { parentID: NULL_UUID });
|
||||
Entities.editEntity(childID, { parentID: Uuid.NULL });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -258,7 +258,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
|
||||
if (targetProps) {
|
||||
if ((propsArePhysical(targetProps) || propsAreCloneDynamic(targetProps)) &&
|
||||
targetProps.parentID == NULL_UUID) {
|
||||
targetProps.parentID === Uuid.NULL) {
|
||||
return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it
|
||||
} else {
|
||||
this.targetEntityID = targetProps.id;
|
||||
|
@ -273,7 +273,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js");
|
|||
this.run = function (controllerData, deltaTime) {
|
||||
if (this.grabbing) {
|
||||
if (controllerData.triggerClicks[this.hand] < TRIGGER_OFF_VALUE &&
|
||||
controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) {
|
||||
controllerData.secondaryValues[this.hand] < TRIGGER_OFF_VALUE) {
|
||||
this.endNearParentingGrabEntity(controllerData);
|
||||
return makeRunningValues(false, [], []);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
|
||||
/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID,
|
||||
/* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
|
||||
enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION,
|
||||
makeDispatcherModuleParameters, Overlays, makeRunningValues, Vec3, resizeTablet, getTabletWidthFromSettings,
|
||||
NEAR_GRAB_RADIUS
|
||||
|
@ -48,7 +48,7 @@ Script.include("/~/system/libraries/utils.js");
|
|||
};
|
||||
|
||||
this.thisHandIsParent = function(props) {
|
||||
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== AVATAR_SELF_ID) {
|
||||
if (props.parentID !== MyAvatar.sessionUUID && props.parentID !== MyAvatar.SELF_ID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ Script.include("/~/system/libraries/utils.js");
|
|||
var grabbedProperties = this.getGrabbedProperties();
|
||||
|
||||
var reparentProps = {
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: handJointIndex,
|
||||
velocity: {x: 0, y: 0, z: 0},
|
||||
angularVelocity: {x: 0, y: 0, z: 0}
|
||||
|
@ -130,9 +130,9 @@ Script.include("/~/system/libraries/utils.js");
|
|||
|
||||
this.endNearParentingGrabOverlay = function () {
|
||||
var previousParentID = this.previousParentID[this.grabbedThingID];
|
||||
if ((previousParentID === NULL_UUID || previousParentID === null) && !this.robbed) {
|
||||
if ((previousParentID === Uuid.NULL || previousParentID === null) && !this.robbed) {
|
||||
Overlays.editOverlay(this.grabbedThingID, {
|
||||
parentID: NULL_UUID,
|
||||
parentID: Uuid.NULL,
|
||||
parentJointIndex: -1
|
||||
});
|
||||
} else if (!this.robbed){
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, NULL_UUID, enableDispatcherModule, disableDispatcherModule,
|
||||
makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, AVATAR_SELF_ID, HMD,
|
||||
/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule,
|
||||
makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD,
|
||||
INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE,
|
||||
TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, LaserPointers, RayPick, ContextOverlay
|
||||
|
@ -17,6 +17,8 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
|
||||
(function() {
|
||||
var TouchEventUtils = Script.require("/~/system/libraries/touchEventUtils.js");
|
||||
var END_RADIUS = 0.005;
|
||||
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
|
||||
var halfPath = {
|
||||
type: "line3d",
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
|
@ -27,10 +29,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var halfEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -48,10 +51,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var fullEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -69,7 +73,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
|
||||
var renderStates = [
|
||||
|
@ -171,17 +175,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.updateLaserPointer = function(controllerData) {
|
||||
var RADIUS = 0.005;
|
||||
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
||||
|
||||
if (this.mode === "full") {
|
||||
this.fullEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd});
|
||||
} else if (this.mode === "half") {
|
||||
this.halfEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd});
|
||||
}
|
||||
|
||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||
};
|
||||
|
@ -235,7 +228,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds
|
||||
if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY ||
|
||||
distance2D(this.laserTarget.position2D,
|
||||
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
|
||||
this.pressEnterLaserTarget.position2D) > this.deadspotRadius) {
|
||||
TouchEventUtils.sendTouchMoveEventToTouchTarget(this.hand, this.laserTarget);
|
||||
this.deadspotExpired = true;
|
||||
}
|
||||
|
@ -366,8 +359,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
LaserPointers.removeLaserPointer(this.laserPointer);
|
||||
};
|
||||
|
||||
this.halfEnd = halfEnd;
|
||||
this.fullEnd = fullEnd;
|
||||
this.laserPointer = LaserPointers.createLaserPointer({
|
||||
joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND",
|
||||
filter: RayPick.PICK_OVERLAYS,
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND,
|
||||
NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||
enableDispatcherModule, disableDispatcherModule, makeRunningValues,
|
||||
Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC,
|
||||
AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
|
||||
HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset,
|
||||
getEnabledModuleByName
|
||||
*/
|
||||
|
||||
|
@ -172,7 +172,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
visible: true,
|
||||
ignoreRayIntersection: true,
|
||||
drawInFront: false,
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ?
|
||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND")
|
||||
|
@ -288,7 +288,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
}
|
||||
|
||||
// add the tabletScreen, if it is valid
|
||||
if (HMD.tabletScreenID && HMD.tabletScreenID !== NULL_UUID &&
|
||||
if (HMD.tabletScreenID && HMD.tabletScreenID !== Uuid.NULL &&
|
||||
Overlays.getProperty(HMD.tabletScreenID, "visible")) {
|
||||
stylusTarget = TouchEventUtils.calculateTouchTargetFromOverlay(this.stylusTip, HMD.tabletScreenID);
|
||||
if (stylusTarget) {
|
||||
|
@ -297,7 +297,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
}
|
||||
|
||||
// add the tablet home button.
|
||||
if (HMD.homeButtonID && HMD.homeButtonID !== NULL_UUID &&
|
||||
if (HMD.homeButtonID && HMD.homeButtonID !== Uuid.NULL &&
|
||||
Overlays.getProperty(HMD.homeButtonID, "visible")) {
|
||||
stylusTarget = TouchEventUtils.calculateTouchTargetFromOverlay(this.stylusTip, HMD.homeButtonID);
|
||||
if (stylusTarget) {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID,
|
||||
/* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex,
|
||||
enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Vec3,
|
||||
LaserPointers, RayPick, HMD, Uuid, AvatarList
|
||||
*/
|
||||
|
|
|
@ -8,15 +8,17 @@
|
|||
/* jslint bitwise: true */
|
||||
|
||||
/* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Vec3, Quat, getGrabPointSphereOffset,
|
||||
makeRunningValues, Entities, NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
|
||||
makeRunningValues, Entities, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters,
|
||||
PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD,
|
||||
AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, ZERO_VEC, Overlays
|
||||
DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, ZERO_VEC, Overlays
|
||||
*/
|
||||
|
||||
Script.include("/~/system/libraries/controllerDispatcherUtils.js");
|
||||
Script.include("/~/system/libraries/controllers.js");
|
||||
|
||||
(function() {
|
||||
var END_RADIUS = 0.005;
|
||||
var dim = { x: END_RADIUS, y: END_RADIUS, z: END_RADIUS };
|
||||
var halfPath = {
|
||||
type: "line3d",
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
|
@ -27,10 +29,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var halfEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -48,10 +51,11 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
var fullEnd = {
|
||||
type: "sphere",
|
||||
dimensions: dim,
|
||||
solid: true,
|
||||
color: COLORS_GRAB_SEARCHING_FULL_SQUEEZE,
|
||||
alpha: 0.9,
|
||||
|
@ -69,7 +73,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
lineWidth: 5,
|
||||
ignoreRayIntersection: true, // always ignore this
|
||||
drawInFront: true, // Even when burried inside of something, show it.
|
||||
parentID: AVATAR_SELF_ID
|
||||
parentID: MyAvatar.SELF_ID
|
||||
};
|
||||
|
||||
var renderStates = [
|
||||
|
@ -90,15 +94,15 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
var HAPTIC_STYLUS_DURATION = 20.0;
|
||||
|
||||
function laserTargetHasKeyboardFocus(laserTarget) {
|
||||
if (laserTarget && laserTarget !== NULL_UUID) {
|
||||
if (laserTarget && laserTarget !== Uuid.NULL) {
|
||||
return Entities.keyboardFocusOverlay === laserTarget;
|
||||
}
|
||||
}
|
||||
|
||||
function setKeyboardFocusOnLaserTarget(laserTarget) {
|
||||
if (laserTarget && laserTarget !== NULL_UUID) {
|
||||
if (laserTarget && laserTarget !== Uuid.NULL) {
|
||||
Entities.wantsHandControllerPointerEvents(laserTarget);
|
||||
Overlays.keyboardFocusOverlay = NULL_UUID;
|
||||
Overlays.keyboardFocusOverlay = Uuid.NULL;
|
||||
Entities.keyboardFocusEntity = laserTarget;
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +121,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
button: "None"
|
||||
};
|
||||
|
||||
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
|
||||
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
|
||||
Entities.sendHoverEnterEntity(laserTarget.entityID, pointerEvent);
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +141,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
button: "None"
|
||||
};
|
||||
|
||||
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
|
||||
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
|
||||
Entities.sendMouseMoveOnEntity(laserTarget.entityID, pointerEvent);
|
||||
Entities.sendHoverOverEntity(laserTarget.entityID, pointerEvent);
|
||||
}
|
||||
|
@ -156,7 +160,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
isPrimaryHeld: true
|
||||
};
|
||||
|
||||
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
|
||||
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
|
||||
Entities.sendMousePressOnEntity(laserTarget.entityID, pointerEvent);
|
||||
Entities.sendClickDownOnEntity(laserTarget.entityID, pointerEvent);
|
||||
}
|
||||
|
@ -173,7 +177,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
button: "Primary"
|
||||
};
|
||||
|
||||
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
|
||||
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
|
||||
Entities.sendMouseReleaseOnEntity(laserTarget.entityID, pointerEvent);
|
||||
Entities.sendClickReleaseOnEntity(laserTarget.entityID, pointerEvent);
|
||||
Entities.sendHoverLeaveEntity(laserTarget.entityID, pointerEvent);
|
||||
|
@ -192,7 +196,7 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
isPrimaryHeld: true
|
||||
};
|
||||
|
||||
if (laserTarget.entityID && laserTarget.entityID !== NULL_UUID) {
|
||||
if (laserTarget.entityID && laserTarget.entityID !== Uuid.NULL) {
|
||||
Entities.sendMouseMoveOnEntity(laserTarget.entityID, pointerEvent);
|
||||
Entities.sendHoldingClickOnEntity(laserTarget.entityID, pointerEvent);
|
||||
}
|
||||
|
@ -366,17 +370,6 @@ Script.include("/~/system/libraries/controllers.js");
|
|||
};
|
||||
|
||||
this.updateLaserPointer = function(controllerData) {
|
||||
var RADIUS = 0.005;
|
||||
var dim = { x: RADIUS, y: RADIUS, z: RADIUS };
|
||||
|
||||
if (this.mode === "full") {
|
||||
fullEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: fullEnd});
|
||||
} else if (this.mode === "half") {
|
||||
halfEnd.dimensions = dim;
|
||||
LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: halfEnd});
|
||||
}
|
||||
|
||||
LaserPointers.enableLaserPointer(this.laserPointer);
|
||||
LaserPointers.setRenderState(this.laserPointer, this.mode);
|
||||
};
|
||||
|
|
|
@ -1360,7 +1360,7 @@ function unparentSelectedEntities() {
|
|||
}
|
||||
selectedEntities.forEach(function (id, index) {
|
||||
var parentId = Entities.getEntityProperties(id, ["parentID"]).parentID;
|
||||
if (parentId !== null && parentId.length > 0 && parentId !== "{00000000-0000-0000-0000-000000000000}") {
|
||||
if (parentId !== null && parentId.length > 0 && parentId !== Uuid.NULL) {
|
||||
parentCheck = true;
|
||||
}
|
||||
Entities.editEntity(id, {parentID: null});
|
||||
|
@ -1476,10 +1476,19 @@ function onFileSaveChanged(filename) {
|
|||
|
||||
function onFileOpenChanged(filename) {
|
||||
// disconnect the event, otherwise the requests will stack up
|
||||
Window.openFileChanged.disconnect(onFileOpenChanged);
|
||||
try {
|
||||
// Not all calls to onFileOpenChanged() connect an event.
|
||||
Window.openFileChanged.disconnect(onFileOpenChanged);
|
||||
} catch (e) {
|
||||
// Ignore.
|
||||
}
|
||||
|
||||
var importURL = null;
|
||||
if (filename !== "") {
|
||||
importURL = "file:///" + filename;
|
||||
importURL = filename;
|
||||
if (!/^(http|https):\/\//.test(filename)) {
|
||||
importURL = "file:///" + importURL;
|
||||
}
|
||||
}
|
||||
if (importURL) {
|
||||
if (!isActive && (Entities.canRez() && Entities.canRezTmp())) {
|
||||
|
|
|
@ -543,6 +543,84 @@
|
|||
<input type="text" id="property-zone-key-ambient-url">
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="minor">
|
||||
<legend class="sub-section-header zone-group zone-section haze-section">
|
||||
Haze
|
||||
</legend>
|
||||
<form>
|
||||
<input type="radio" name="hazeMode" value="inherit" id="property-zone-haze-mode-inherit" checked> Inherit
|
||||
<input type="radio" name="hazeMode" value="disabled" id="property-zone-haze-mode-disabled"> Off
|
||||
<input type="radio" name="hazeMode" value="enabled" id="property-zone-haze-mode-enabled"> On
|
||||
</form>
|
||||
<fieldset class="zone-group zone-section haze-section property gen fstuple">
|
||||
<div class="tuple">
|
||||
<div><label>Range<span class="unit">m</span></label><input type="number" id="property-zone-haze-range" min="5" max="10000" step="5"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="zone-group zone-section haze-section property rgb fstuple">
|
||||
<div class="zone-group zone-section haze-section property checkbox">
|
||||
<input type="checkbox" id="property-zone-haze-altitude-effect">
|
||||
<label for="property-zone-haze-altitude-effect">Use Altitude</label>
|
||||
</div>
|
||||
<fieldset class="zone-group zone-section haze-section property gen fstuple">
|
||||
<div class="tuple">
|
||||
<div><label>Base<span class="unit">m</span></label><input type="number" id="property-zone-haze-base" min="-1000" max="1000" step="10"></div>
|
||||
<div><label>Ceiling<span class="unit">m</span></label><input type="number" id="property-zone-haze-ceiling" min="-1000" max="5000" step="10"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
<fieldset class="zone-group zone-section haze-section property rgb fstuple">
|
||||
<div class="color-picker" id="property-zone-haze-blend-in-color"></div>
|
||||
<legend>Haze Color</legend>
|
||||
<div class="tuple">
|
||||
<div><input type="number" class="red" id="property-zone-haze-blend-in-color-red" min="0" max="255" step="1">
|
||||
<label for="property-zone-haze-blend-in-color-red">Red:</label></div>
|
||||
<div><input type="number" class="green" id="property-zone-haze-blend-in-color-green" min="0" max="255" step="1">
|
||||
<label for="property-zone-haze-blend-in-color-green">Green:</label></div>
|
||||
<div><input type="number" class="blue" id="property-zone-haze-blend-in-color-blue" min="0" max="255" step="1">
|
||||
<label for="property-zone-haze-blend-in-color-blue">Blue:</label></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="zone-group zone-section haze-section property checkbox">
|
||||
<input type="checkbox" id="property-zone-haze-enable-light-blend">
|
||||
<label for="property-zone-haze-enable-light-blend">Enable Glare</label>
|
||||
</div>
|
||||
<fieldset class="zone-group zone-section haze-section property rgb fstuple">
|
||||
<div class="color-picker" id="property-zone-haze-blend-out-color"></div>
|
||||
<legend>Glare Color</legend>
|
||||
<div class="tuple">
|
||||
<div><input type="number" class="red" id="property-zone-haze-blend-out-color-red" min="0" max="255" step="1">
|
||||
<label for="property-zone-haze-blend-out-color-red">Red:</label></div>
|
||||
<div><input type="number" class="green" id="property-zone-haze-blend-out-color-green" min="0" max="255" step="1">
|
||||
<label for="property-zone-haze-blend-out-color-green">Green:</label></div>
|
||||
<div><input type="number" class="blue" id="property-zone-haze-blend-out-color-blue" min="0" max="255" step="1">
|
||||
<label for="property-zone-haze-blend-out-color-blue">Blue:</label></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="zone-group zone-section haze-section property gen fstuple">
|
||||
<div class="tuple">
|
||||
<div><label>Glare Angle<span class="unit">deg</span></label><input type="number" id="property-zone-haze-blend-angle" min="0" max="180" step="1"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="zone-group zone-section haze-section property gen fstuple">
|
||||
<div class="zone-group zone-section haze-section property checkbox">
|
||||
<input type="checkbox" id="property-zone-haze-attenuate-keylight">
|
||||
<label for="property-zone-haze-attenuate-keylight">Attenuate Keylight</label>
|
||||
</div>
|
||||
<div class="tuple">
|
||||
<div><label>Range<span class="unit">m</span></label><input type="number" id="property-zone-haze-keylight-range"
|
||||
min="5" max="1000000" step="5"></div>
|
||||
<div><label>Altitude<span class="unit">m</span></label><input type="number" id="property-zone-haze-keylight-altitude"
|
||||
min="-1000" max="50000" step="10"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="zone-group zone-section haze-section property gen fstuple">
|
||||
<div>
|
||||
<label>Background Blend</label>
|
||||
<input type="number" id="property-zone-haze-background-blend" min="0.0" max="1.0" step="0.01">
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
<fieldset class="minor">
|
||||
<legend class="sub-section-header zone-group zone-section stage-section">
|
||||
Stage
|
||||
|
|
|
@ -146,6 +146,22 @@ function createEmitTextPropertyUpdateFunction(propertyName) {
|
|||
};
|
||||
}
|
||||
|
||||
function createZoneComponentModeChangedFunction(zoneComponent, zoneComponentModeInherit, zoneComponentModeDisabled, zoneComponentModeEnabled) {
|
||||
return function() {
|
||||
var zoneComponentMode;
|
||||
|
||||
if (zoneComponentModeInherit.checked) {
|
||||
zoneComponentMode = 'inherit';
|
||||
} else if (zoneComponentModeDisabled.checked) {
|
||||
zoneComponentMode = 'disabled';
|
||||
} else if (zoneComponentModeEnabled.checked) {
|
||||
zoneComponentMode = 'enabled';
|
||||
}
|
||||
|
||||
updateProperty(zoneComponent, zoneComponentMode);
|
||||
}
|
||||
}
|
||||
|
||||
function createEmitGroupTextPropertyUpdateFunction(group, propertyName) {
|
||||
return function() {
|
||||
var properties = {};
|
||||
|
@ -657,6 +673,32 @@ function loaded() {
|
|||
var elZoneKeyLightDirectionZ = document.getElementById("property-zone-key-light-direction-z");
|
||||
var elZoneKeyLightAmbientURL = document.getElementById("property-zone-key-ambient-url");
|
||||
|
||||
var elZoneHazeModeInherit = document.getElementById("property-zone-haze-mode-inherit");
|
||||
var elZoneHazeModeDisabled = document.getElementById("property-zone-haze-mode-disabled");
|
||||
var elZoneHazeModeEnabled = document.getElementById("property-zone-haze-mode-enabled");
|
||||
|
||||
var elZoneHazeRange = document.getElementById("property-zone-haze-range");
|
||||
var elZoneHazeColor = document.getElementById("property-zone-haze-blend-in-color");
|
||||
var elZoneHazeColorRed = document.getElementById("property-zone-haze-blend-in-color-red");
|
||||
var elZoneHazeColorGreen = document.getElementById("property-zone-haze-blend-in-color-green");
|
||||
var elZoneHazeColorBlue = document.getElementById("property-zone-haze-blend-in-color-blue");
|
||||
var elZoneHazeGlareColor = document.getElementById("property-zone-haze-blend-out-color");
|
||||
var elZoneHazeGlareColorRed = document.getElementById("property-zone-haze-blend-out-color-red");
|
||||
var elZoneHazeGlareColorGreen = document.getElementById("property-zone-haze-blend-out-color-green");
|
||||
var elZoneHazeGlareColorBlue = document.getElementById("property-zone-haze-blend-out-color-blue");
|
||||
var elZoneHazeEnableGlare = document.getElementById("property-zone-haze-enable-light-blend");
|
||||
var elZonehazeGlareAngle = document.getElementById("property-zone-haze-blend-angle");
|
||||
|
||||
var elZoneHazeAltitudeEffect = document.getElementById("property-zone-haze-altitude-effect");
|
||||
var elZoneHazeBaseRef = document.getElementById("property-zone-haze-base");
|
||||
var elZoneHazeCeiling = document.getElementById("property-zone-haze-ceiling");
|
||||
|
||||
var elZoneHazeBackgroundBlend = document.getElementById("property-zone-haze-background-blend");
|
||||
|
||||
var elZoneHazeAttenuateKeyLight = document.getElementById("property-zone-haze-attenuate-keylight");
|
||||
var elZoneHazeKeyLightRange = document.getElementById("property-zone-haze-keylight-range");
|
||||
var elZoneHazeKeyLightAltitude = document.getElementById("property-zone-haze-keylight-altitude");
|
||||
|
||||
var elZoneStageLatitude = document.getElementById("property-zone-stage-latitude");
|
||||
var elZoneStageLongitude = document.getElementById("property-zone-stage-longitude");
|
||||
var elZoneStageAltitude = document.getElementById("property-zone-stage-altitude");
|
||||
|
@ -994,6 +1036,42 @@ function loaded() {
|
|||
elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2);
|
||||
elZoneKeyLightAmbientURL.value = properties.keyLight.ambientURL;
|
||||
|
||||
elZoneHazeModeInherit.checked = (properties.hazeMode == 'inherit');
|
||||
elZoneHazeModeDisabled.checked = (properties.hazeMode == 'disabled');
|
||||
elZoneHazeModeEnabled.checked = (properties.hazeMode == 'enabled');
|
||||
|
||||
elZoneHazeRange.value = properties.haze.hazeRange.toFixed(0);
|
||||
elZoneHazeColor.style.backgroundColor = "rgb(" +
|
||||
properties.haze.hazeColor.red + "," +
|
||||
properties.haze.hazeColor.green + "," +
|
||||
properties.haze.hazeColor.blue + ")";
|
||||
|
||||
elZoneHazeColorRed.value = properties.haze.hazeColor.red;
|
||||
elZoneHazeColorGreen.value = properties.haze.hazeColor.green;
|
||||
elZoneHazeColorBlue.value = properties.haze.hazeColor.blue;
|
||||
elZoneHazeBackgroundBlend.value = properties.haze.hazeBackgroundBlend.toFixed(2);
|
||||
|
||||
elZoneHazeGlareColor.style.backgroundColor = "rgb(" +
|
||||
properties.haze.hazeGlareColor.red + "," +
|
||||
properties.haze.hazeGlareColor.green + "," +
|
||||
properties.haze.hazeGlareColor.blue + ")";
|
||||
|
||||
elZoneHazeGlareColorRed.value = properties.haze.hazeGlareColor.red;
|
||||
elZoneHazeGlareColorGreen.value = properties.haze.hazeGlareColor.green;
|
||||
elZoneHazeGlareColorBlue.value = properties.haze.hazeGlareColor.blue;
|
||||
|
||||
elZoneHazeEnableGlare.checked = properties.haze.hazeEnableGlare;
|
||||
elZonehazeGlareAngle.value = properties.haze.hazeGlareAngle.toFixed(0);
|
||||
|
||||
elZoneHazeAltitudeEffect.checked = properties.haze.hazeAltitudeEffect;
|
||||
elZoneHazeBaseRef.value = properties.haze.hazeBaseRef.toFixed(0);
|
||||
elZoneHazeCeiling.value = properties.haze.hazeCeiling.toFixed(0);
|
||||
|
||||
elZoneHazeBackgroundBlend.value = properties.haze.hazeBackgroundBlend.toFixed(2);
|
||||
|
||||
elZoneHazeAttenuateKeyLight.checked = properties.haze.hazeAttenuateKeyLight;
|
||||
elZoneHazeKeyLightRange.value = properties.haze.hazeKeyLightRange.toFixed(0);
|
||||
elZoneHazeKeyLightAltitude.value = properties.haze.hazeKeyLightAltitude.toFixed(0);
|
||||
|
||||
elZoneStageLatitude.value = properties.stage.latitude.toFixed(2);
|
||||
elZoneStageLongitude.value = properties.stage.longitude.toFixed(2);
|
||||
|
@ -1389,6 +1467,76 @@ function loaded() {
|
|||
elZoneKeyLightDirectionX.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
||||
elZoneKeyLightDirectionY.addEventListener('change', zoneKeyLightDirectionChangeFunction);
|
||||
|
||||
var hazeModeChanged = createZoneComponentModeChangedFunction('hazeMode', elZoneHazeModeInherit, elZoneHazeModeDisabled, elZoneHazeModeEnabled)
|
||||
elZoneHazeModeInherit.addEventListener('change', hazeModeChanged);
|
||||
elZoneHazeModeDisabled.addEventListener('change', hazeModeChanged);
|
||||
elZoneHazeModeEnabled.addEventListener('change', hazeModeChanged);
|
||||
|
||||
elZoneHazeRange.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeRange'));
|
||||
|
||||
colorPickers.push($('#property-zone-haze-blend-in-color').colpick({
|
||||
colorScheme: 'dark',
|
||||
layout: 'hex',
|
||||
color: '000000',
|
||||
onShow: function(colpick) {
|
||||
$('#property-zone-haze-blend-in-color').attr('active', 'true');
|
||||
},
|
||||
onHide: function(colpick) {
|
||||
$('#property-zone-haze-blend-in-color').attr('active', 'false');
|
||||
},
|
||||
onSubmit: function(hsb, hex, rgb, el) {
|
||||
$(el).css('background-color', '#' + hex);
|
||||
$(el).colpickHide();
|
||||
emitColorPropertyUpdate('hazeColor', rgb.r, rgb.g, rgb.b, 'haze');
|
||||
}
|
||||
}));
|
||||
var zoneHazeColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('haze', 'hazeColor',
|
||||
elZoneHazeColorRed,
|
||||
elZoneHazeColorGreen,
|
||||
elZoneHazeColorBlue);
|
||||
|
||||
elZoneHazeColorRed.addEventListener('change', zoneHazeColorChangeFunction);
|
||||
elZoneHazeColorGreen.addEventListener('change', zoneHazeColorChangeFunction);
|
||||
elZoneHazeColorBlue.addEventListener('change', zoneHazeColorChangeFunction);
|
||||
|
||||
colorPickers.push($('#property-zone-haze-blend-out-color').colpick({
|
||||
colorScheme: 'dark',
|
||||
layout: 'hex',
|
||||
color: '000000',
|
||||
onShow: function(colpick) {
|
||||
$('#property-zone-haze-blend-out-color').attr('active', 'true');
|
||||
},
|
||||
onHide: function(colpick) {
|
||||
$('#property-zone-haze-blend-out-color').attr('active', 'false');
|
||||
},
|
||||
onSubmit: function(hsb, hex, rgb, el) {
|
||||
$(el).css('background-color', '#' + hex);
|
||||
$(el).colpickHide();
|
||||
emitColorPropertyUpdate('hazeGlareColor', rgb.r, rgb.g, rgb.b, 'haze');
|
||||
}
|
||||
}));
|
||||
var zoneHazeGlareColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('haze', 'hazeGlareColor',
|
||||
elZoneHazeGlareColorRed,
|
||||
elZoneHazeGlareColorGreen,
|
||||
elZoneHazeGlareColorBlue);
|
||||
|
||||
elZoneHazeGlareColorRed.addEventListener('change', zoneHazeGlareColorChangeFunction);
|
||||
elZoneHazeGlareColorGreen.addEventListener('change', zoneHazeGlareColorChangeFunction);
|
||||
elZoneHazeGlareColorBlue.addEventListener('change', zoneHazeGlareColorChangeFunction);
|
||||
|
||||
elZoneHazeEnableGlare.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('haze', 'hazeEnableGlare'));
|
||||
elZonehazeGlareAngle.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeGlareAngle'));
|
||||
|
||||
elZoneHazeAltitudeEffect.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('haze', 'hazeAltitudeEffect'));
|
||||
elZoneHazeCeiling.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeCeiling'));
|
||||
elZoneHazeBaseRef.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeBaseRef'));
|
||||
|
||||
elZoneHazeBackgroundBlend.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeBackgroundBlend'));
|
||||
|
||||
elZoneHazeAttenuateKeyLight.addEventListener('change', createEmitGroupCheckedPropertyUpdateFunction('haze', 'hazeAttenuateKeyLight'));
|
||||
elZoneHazeKeyLightRange.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeKeyLightRange'));
|
||||
elZoneHazeKeyLightAltitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('haze', 'hazeKeyLightAltitude'));
|
||||
|
||||
elZoneStageLatitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'latitude'));
|
||||
elZoneStageLongitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'longitude'));
|
||||
elZoneStageAltitude.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'altitude'));
|
||||
|
@ -1396,8 +1544,8 @@ function loaded() {
|
|||
elZoneStageDay.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'day'));
|
||||
elZoneStageHour.addEventListener('change', createEmitGroupNumberPropertyUpdateFunction('stage', 'hour'));
|
||||
|
||||
|
||||
elZoneBackgroundMode.addEventListener('change', createEmitTextPropertyUpdateFunction('backgroundMode'));
|
||||
|
||||
var zoneSkyboxColorChangeFunction = createEmitGroupColorPropertyUpdateFunction('skybox', 'color',
|
||||
elZoneSkyboxColorRed, elZoneSkyboxColorGreen, elZoneSkyboxColorBlue);
|
||||
elZoneSkyboxColorRed.addEventListener('change', zoneSkyboxColorChangeFunction);
|
||||
|
|
|
@ -193,6 +193,11 @@
|
|||
var navbarBrandElement = document.getElementsByClassName('navbar-brand')[0];
|
||||
var purchasesElement = document.createElement('a');
|
||||
var dropDownElement = document.getElementById('user-dropdown');
|
||||
|
||||
$('#user-dropdown').find('.username')[0].style = "max-width:80px;white-space:nowrap;overflow:hidden;" +
|
||||
"text-overflow:ellipsis;display:inline-block;position:relative;top:4px;";
|
||||
$('#user-dropdown').find('.caret')[0].style = "position:relative;top:-3px;";
|
||||
|
||||
purchasesElement.id = "purchasesButton";
|
||||
purchasesElement.setAttribute('href', "#");
|
||||
purchasesElement.innerHTML = "My Purchases";
|
||||
|
|
|
@ -25,7 +25,6 @@ var ROT_LANDSCAPE = {x: 1.0, y: 1.0, z: 0, w: 0};
|
|||
var ROT_LANDSCAPE_WINDOW = {x: 0.0, y: 0.0, z: 0.0, w: 0};
|
||||
var TABLET_TEXTURE_RESOLUTION = { x: 480, y: 706 };
|
||||
var INCHES_TO_METERS = 1 / 39.3701;
|
||||
var AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
|
||||
|
||||
var NO_HANDS = -1;
|
||||
var DELAY_FOR_30HZ = 33; // milliseconds
|
||||
|
@ -100,7 +99,7 @@ WebTablet = function (url, width, dpi, hand, clientOnly, location, visible) {
|
|||
"grabbableKey": {"grabbable": true}
|
||||
}),
|
||||
dimensions: { x: tabletWidth, y: tabletHeight, z: tabletDepth },
|
||||
parentID: AVATAR_SELF_ID,
|
||||
parentID: MyAvatar.SELF_ID,
|
||||
visible: visible
|
||||
};
|
||||
|
||||
|
@ -471,7 +470,7 @@ WebTablet.prototype.register = function() {
|
|||
|
||||
WebTablet.prototype.cleanUpOldTabletsOnJoint = function(jointIndex) {
|
||||
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, jointIndex);
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, jointIndex));
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, jointIndex));
|
||||
children.forEach(function(childID) {
|
||||
var props = Entities.getEntityProperties(childID, ["name"]);
|
||||
if (props.name === "WebTablet Tablet") {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
|
||||
/* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform,
|
||||
MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, NULL_UUID:true, AVATAR_SELF_ID:true, FORBIDDEN_GRAB_TYPES:true,
|
||||
MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, FORBIDDEN_GRAB_TYPES:true,
|
||||
HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true,
|
||||
DEFAULT_REGISTRATION_POINT:true, INCHES_TO_METERS:true,
|
||||
TRIGGER_OFF_VALUE:true,
|
||||
|
@ -60,9 +60,6 @@ ONE_VEC = { x: 1, y: 1, z: 1 };
|
|||
LEFT_HAND = 0;
|
||||
RIGHT_HAND = 1;
|
||||
|
||||
NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
|
||||
AVATAR_SELF_ID = "{00000000-0000-0000-0000-000000000001}";
|
||||
|
||||
FORBIDDEN_GRAB_TYPES = ["Unknown", "Light", "PolyLine", "Zone"];
|
||||
|
||||
HAPTIC_PULSE_STRENGTH = 1.0;
|
||||
|
@ -284,7 +281,7 @@ ensureDynamic = function (entityID) {
|
|||
// if we distance hold something and keep it very still before releasing it, it ends up
|
||||
// non-dynamic in bullet. If it's too still, give it a little bounce so it will fall.
|
||||
var props = Entities.getEntityProperties(entityID, ["velocity", "dynamic", "parentID"]);
|
||||
if (props.dynamic && props.parentID === NULL_UUID) {
|
||||
if (props.dynamic && props.parentID === Uuid.NULL) {
|
||||
var velocity = props.velocity;
|
||||
if (Vec3.length(velocity) < 0.05) { // see EntityMotionState.cpp DYNAMIC_LINEAR_VELOCITY_THRESHOLD
|
||||
velocity = { x: 0.0, y: 0.2, z: 0.0 };
|
||||
|
@ -295,7 +292,7 @@ ensureDynamic = function (entityID) {
|
|||
|
||||
findGroupParent = function (controllerData, targetProps) {
|
||||
while (targetProps.parentID &&
|
||||
targetProps.parentID !== NULL_UUID &&
|
||||
targetProps.parentID !== Uuid.NULL &&
|
||||
Entities.getNestableType(targetProps.parentID) == "entity") {
|
||||
var parentProps = Entities.getEntityProperties(targetProps.parentID, DISPATCHER_PROPERTIES);
|
||||
if (!parentProps) {
|
||||
|
@ -314,19 +311,19 @@ findHandChildEntities = function(hand) {
|
|||
// find children of avatar's hand joint
|
||||
var handJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex);
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, handJointIndex));
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, handJointIndex));
|
||||
|
||||
// find children of faux controller joint
|
||||
var controllerJointIndex = getControllerJointIndex(hand);
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, controllerJointIndex));
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, controllerJointIndex));
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, controllerJointIndex));
|
||||
|
||||
// find children of faux camera-relative controller joint
|
||||
var controllerCRJointIndex = MyAvatar.getJointIndex(hand === RIGHT_HAND ?
|
||||
"_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" :
|
||||
"_CAMERA_RELATIVE_CONTROLLER_LEFTHAND");
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, controllerCRJointIndex));
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(AVATAR_SELF_ID, controllerCRJointIndex));
|
||||
children = children.concat(Entities.getChildrenIDsOfJoint(MyAvatar.SELF_ID, controllerCRJointIndex));
|
||||
|
||||
return children.filter(function (childID) {
|
||||
var childType = Entities.getNestableType(childID);
|
||||
|
|
|
@ -118,20 +118,12 @@ CameraManager = function() {
|
|||
that.targetYaw = 0;
|
||||
that.targetPitch = 0;
|
||||
|
||||
that.focalPoint = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
that.targetFocalPoint = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
};
|
||||
that.focalPoint = Vec3.ZERO;
|
||||
that.targetFocalPoint = Vec3.ZERO;
|
||||
|
||||
easing = false;
|
||||
easingTime = 0;
|
||||
startOrientation = Quat.fromPitchYawRollDegrees(0, 0, 0);
|
||||
startOrientation = Quat.IDENTITY;
|
||||
|
||||
that.previousCameraMode = null;
|
||||
|
||||
|
|