Merge branch 'master' into tablet_extended_sounds
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
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <ClientServerUtils.h>
|
#include <ClientServerUtils.h>
|
||||||
#include <FBXBaker.h>
|
#include <FBXBaker.h>
|
||||||
|
#include <JSBaker.h>
|
||||||
#include <NodeType.h>
|
#include <NodeType.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
@ -49,10 +50,12 @@ static const int INTERFACE_RUNNING_CHECK_FREQUENCY_MS = 1000;
|
||||||
|
|
||||||
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
||||||
|
|
||||||
static const QStringList BAKEABLE_MODEL_EXTENSIONS = { "fbx" };
|
static const QStringList BAKEABLE_MODEL_EXTENSIONS = {"fbx"};
|
||||||
static QStringList BAKEABLE_TEXTURE_EXTENSIONS;
|
static QStringList BAKEABLE_TEXTURE_EXTENSIONS;
|
||||||
|
static const QStringList BAKEABLE_SCRIPT_EXTENSIONS = {"js"};
|
||||||
static const QString BAKED_MODEL_SIMPLE_NAME = "asset.fbx";
|
static const QString BAKED_MODEL_SIMPLE_NAME = "asset.fbx";
|
||||||
static const QString BAKED_TEXTURE_SIMPLE_NAME = "texture.ktx";
|
static const QString BAKED_TEXTURE_SIMPLE_NAME = "texture.ktx";
|
||||||
|
static const QString BAKED_SCRIPT_SIMPLE_NAME = "asset.js";
|
||||||
|
|
||||||
void AssetServer::bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) {
|
void AssetServer::bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) {
|
||||||
qDebug() << "Starting bake for: " << assetPath << assetHash;
|
qDebug() << "Starting bake for: " << assetPath << assetHash;
|
||||||
|
@ -99,6 +102,8 @@ std::pair<BakingStatus, QString> AssetServer::getAssetStatus(const AssetPath& pa
|
||||||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
||||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||||
|
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
return { Irrelevant, "" };
|
return { Irrelevant, "" };
|
||||||
}
|
}
|
||||||
|
@ -186,6 +191,8 @@ bool AssetServer::needsToBeBaked(const AssetPath& path, const AssetHash& assetHa
|
||||||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (loaded && BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit())) {
|
} else if (loaded && BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit())) {
|
||||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||||
|
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +235,8 @@ void updateConsumedCores() {
|
||||||
AssetServer::AssetServer(ReceivedMessage& message) :
|
AssetServer::AssetServer(ReceivedMessage& message) :
|
||||||
ThreadedAssignment(message),
|
ThreadedAssignment(message),
|
||||||
_transferTaskPool(this),
|
_transferTaskPool(this),
|
||||||
_bakingTaskPool(this)
|
_bakingTaskPool(this),
|
||||||
|
_filesizeLimit(MAX_UPLOAD_SIZE)
|
||||||
{
|
{
|
||||||
// store the current state of image compression so we can reset it when this assignment is complete
|
// store the current state of image compression so we can reset it when this assignment is complete
|
||||||
_wasColorTextureCompressionEnabled = image::isColorTexturesCompressionEnabled();
|
_wasColorTextureCompressionEnabled = image::isColorTexturesCompressionEnabled();
|
||||||
|
@ -336,8 +344,8 @@ void AssetServer::completeSetup() {
|
||||||
auto maxBandwidthValue = assetServerObject[MAX_BANDWIDTH_OPTION];
|
auto maxBandwidthValue = assetServerObject[MAX_BANDWIDTH_OPTION];
|
||||||
auto maxBandwidthFloat = maxBandwidthValue.toDouble(-1);
|
auto maxBandwidthFloat = maxBandwidthValue.toDouble(-1);
|
||||||
|
|
||||||
|
const int BITS_PER_MEGABITS = 1000 * 1000;
|
||||||
if (maxBandwidthFloat > 0.0) {
|
if (maxBandwidthFloat > 0.0) {
|
||||||
const int BITS_PER_MEGABITS = 1000 * 1000;
|
|
||||||
int maxBandwidth = maxBandwidthFloat * BITS_PER_MEGABITS;
|
int maxBandwidth = maxBandwidthFloat * BITS_PER_MEGABITS;
|
||||||
nodeList->setConnectionMaxBandwidth(maxBandwidth);
|
nodeList->setConnectionMaxBandwidth(maxBandwidth);
|
||||||
qCInfo(asset_server) << "Set maximum bandwith per connection to" << maxBandwidthFloat << "Mb/s."
|
qCInfo(asset_server) << "Set maximum bandwith per connection to" << maxBandwidthFloat << "Mb/s."
|
||||||
|
@ -399,6 +407,15 @@ void AssetServer::completeSetup() {
|
||||||
qCCritical(asset_server) << "Asset Server assignment will not continue because mapping file could not be loaded.";
|
qCCritical(asset_server) << "Asset Server assignment will not continue because mapping file could not be loaded.";
|
||||||
setFinished(true);
|
setFinished(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get file size limit for an asset
|
||||||
|
static const QString ASSETS_FILESIZE_LIMIT_OPTION = "assets_filesize_limit";
|
||||||
|
auto assetsFilesizeLimitJSONValue = assetServerObject[ASSETS_FILESIZE_LIMIT_OPTION];
|
||||||
|
auto assetsFilesizeLimit = (uint64_t)assetsFilesizeLimitJSONValue.toInt(MAX_UPLOAD_SIZE);
|
||||||
|
|
||||||
|
if (assetsFilesizeLimit != 0 && assetsFilesizeLimit < MAX_UPLOAD_SIZE) {
|
||||||
|
_filesizeLimit = assetsFilesizeLimit * BITS_PER_MEGABITS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetServer::cleanupUnmappedFiles() {
|
void AssetServer::cleanupUnmappedFiles() {
|
||||||
|
@ -488,6 +505,8 @@ void AssetServer::handleGetMappingOperation(ReceivedMessage& message, SharedNode
|
||||||
bakedRootFile = BAKED_MODEL_SIMPLE_NAME;
|
bakedRootFile = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(assetPathExtension.toLocal8Bit())) {
|
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(assetPathExtension.toLocal8Bit())) {
|
||||||
bakedRootFile = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedRootFile = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(assetPathExtension)) {
|
||||||
|
bakedRootFile = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto originalAssetHash = it->second;
|
auto originalAssetHash = it->second;
|
||||||
|
@ -721,7 +740,7 @@ void AssetServer::handleAssetUpload(QSharedPointer<ReceivedMessage> message, Sha
|
||||||
if (senderNode->getCanWriteToAssetServer()) {
|
if (senderNode->getCanWriteToAssetServer()) {
|
||||||
qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << uuidStringWithoutCurlyBraces(senderNode->getUUID());
|
qCDebug(asset_server) << "Starting an UploadAssetTask for upload from" << uuidStringWithoutCurlyBraces(senderNode->getUUID());
|
||||||
|
|
||||||
auto task = new UploadAssetTask(message, senderNode, _filesDirectory);
|
auto task = new UploadAssetTask(message, senderNode, _filesDirectory, _filesizeLimit);
|
||||||
_transferTaskPool.start(task);
|
_transferTaskPool.start(task);
|
||||||
} else {
|
} else {
|
||||||
// this is a node the domain told us is not allowed to rez entities
|
// this is a node the domain told us is not allowed to rez entities
|
||||||
|
@ -1141,6 +1160,7 @@ bool AssetServer::renameMapping(AssetPath oldPath, AssetPath newPath) {
|
||||||
|
|
||||||
static const QString BAKED_ASSET_SIMPLE_FBX_NAME = "asset.fbx";
|
static const QString BAKED_ASSET_SIMPLE_FBX_NAME = "asset.fbx";
|
||||||
static const QString BAKED_ASSET_SIMPLE_TEXTURE_NAME = "texture.ktx";
|
static const QString BAKED_ASSET_SIMPLE_TEXTURE_NAME = "texture.ktx";
|
||||||
|
static const QString BAKED_ASSET_SIMPLE_JS_NAME = "asset.js";
|
||||||
|
|
||||||
QString getBakeMapping(const AssetHash& hash, const QString& relativeFilePath) {
|
QString getBakeMapping(const AssetHash& hash, const QString& relativeFilePath) {
|
||||||
return HIDDEN_BAKED_CONTENT_FOLDER + hash + "/" + relativeFilePath;
|
return HIDDEN_BAKED_CONTENT_FOLDER + hash + "/" + relativeFilePath;
|
||||||
|
@ -1204,14 +1224,14 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
|
||||||
// setup the mapping for this bake file
|
// setup the mapping for this bake file
|
||||||
auto relativeFilePath = QUrl(filePath).fileName();
|
auto relativeFilePath = QUrl(filePath).fileName();
|
||||||
qDebug() << "Relative file path is: " << relativeFilePath;
|
qDebug() << "Relative file path is: " << relativeFilePath;
|
||||||
|
|
||||||
if (relativeFilePath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
if (relativeFilePath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
||||||
// for an FBX file, we replace the filename with the simple name
|
// for an FBX file, we replace the filename with the simple name
|
||||||
// (to handle the case where two mapped assets have the same hash but different names)
|
// (to handle the case where two mapped assets have the same hash but different names)
|
||||||
relativeFilePath = BAKED_ASSET_SIMPLE_FBX_NAME;
|
relativeFilePath = BAKED_ASSET_SIMPLE_FBX_NAME;
|
||||||
|
} else if (relativeFilePath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||||
|
relativeFilePath = BAKED_ASSET_SIMPLE_JS_NAME;
|
||||||
} else if (!originalAssetPath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
} else if (!originalAssetPath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
||||||
relativeFilePath = BAKED_ASSET_SIMPLE_TEXTURE_NAME;
|
relativeFilePath = BAKED_ASSET_SIMPLE_TEXTURE_NAME;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString bakeMapping = getBakeMapping(originalAssetHash, relativeFilePath);
|
QString bakeMapping = getBakeMapping(originalAssetHash, relativeFilePath);
|
||||||
|
@ -1364,6 +1384,8 @@ bool AssetServer::setBakingEnabled(const AssetPathList& paths, bool enabled) {
|
||||||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
||||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||||
|
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||||
|
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,8 @@ private:
|
||||||
bool _wasGrayscaleTextureCompressionEnabled { false };
|
bool _wasGrayscaleTextureCompressionEnabled { false };
|
||||||
bool _wasNormalTextureCompressionEnabled { false };
|
bool _wasNormalTextureCompressionEnabled { false };
|
||||||
bool _wasCubeTextureCompressionEnabled { false };
|
bool _wasCubeTextureCompressionEnabled { false };
|
||||||
|
|
||||||
|
uint64_t _filesizeLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <FBXBaker.h>
|
#include <FBXBaker.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
#include <JSBaker.h>
|
||||||
|
|
||||||
BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) :
|
BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) :
|
||||||
_assetHash(assetHash),
|
_assetHash(assetHash),
|
||||||
|
@ -52,6 +53,10 @@ void BakeAssetTask::run() {
|
||||||
_baker = std::unique_ptr<FBXBaker> {
|
_baker = std::unique_ptr<FBXBaker> {
|
||||||
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
||||||
};
|
};
|
||||||
|
} else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||||
|
_baker = std::unique_ptr<JSBaker>{
|
||||||
|
new JSBaker(QUrl("file:///" + _filePath), PathUtils::generateTemporaryDir())
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||||
_baker = std::unique_ptr<TextureBaker> {
|
_baker = std::unique_ptr<TextureBaker> {
|
||||||
|
|
|
@ -22,10 +22,11 @@
|
||||||
|
|
||||||
|
|
||||||
UploadAssetTask::UploadAssetTask(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode,
|
UploadAssetTask::UploadAssetTask(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode,
|
||||||
const QDir& resourcesDir) :
|
const QDir& resourcesDir, uint64_t filesizeLimit) :
|
||||||
_receivedMessage(receivedMessage),
|
_receivedMessage(receivedMessage),
|
||||||
_senderNode(senderNode),
|
_senderNode(senderNode),
|
||||||
_resourcesDir(resourcesDir)
|
_resourcesDir(resourcesDir),
|
||||||
|
_filesizeLimit(filesizeLimit)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,7 @@ void UploadAssetTask::run() {
|
||||||
auto replyPacket = NLPacket::create(PacketType::AssetUploadReply, -1, true);
|
auto replyPacket = NLPacket::create(PacketType::AssetUploadReply, -1, true);
|
||||||
replyPacket->writePrimitive(messageID);
|
replyPacket->writePrimitive(messageID);
|
||||||
|
|
||||||
if (fileSize > MAX_UPLOAD_SIZE) {
|
if (fileSize > _filesizeLimit) {
|
||||||
replyPacket->writePrimitive(AssetServerError::AssetTooLarge);
|
replyPacket->writePrimitive(AssetServerError::AssetTooLarge);
|
||||||
} else {
|
} else {
|
||||||
QByteArray fileData = buffer.read(fileSize);
|
QByteArray fileData = buffer.read(fileSize);
|
||||||
|
|
|
@ -26,7 +26,8 @@ class Node;
|
||||||
|
|
||||||
class UploadAssetTask : public QRunnable {
|
class UploadAssetTask : public QRunnable {
|
||||||
public:
|
public:
|
||||||
UploadAssetTask(QSharedPointer<ReceivedMessage> message, QSharedPointer<Node> senderNode, const QDir& resourcesDir);
|
UploadAssetTask(QSharedPointer<ReceivedMessage> message, QSharedPointer<Node> senderNode,
|
||||||
|
const QDir& resourcesDir, uint64_t filesizeLimit);
|
||||||
|
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ private:
|
||||||
QSharedPointer<ReceivedMessage> _receivedMessage;
|
QSharedPointer<ReceivedMessage> _receivedMessage;
|
||||||
QSharedPointer<Node> _senderNode;
|
QSharedPointer<Node> _senderNode;
|
||||||
QDir _resourcesDir;
|
QDir _resourcesDir;
|
||||||
|
uint64_t _filesizeLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_UploadAssetTask_h
|
#endif // hifi_UploadAssetTask_h
|
||||||
|
|
|
@ -118,6 +118,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
||||||
foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
|
foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
|
||||||
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
|
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
|
||||||
file(TO_CMAKE_PATH "${AUTOSCRIBE_SHADER_RETURN}" AUTOSCRIBE_GENERATED_FILE)
|
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})
|
list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_GENERATED_FILE})
|
||||||
endforeach()
|
endforeach()
|
||||||
#message(${TARGET_NAME} ${AUTOSCRIBE_SHADER_SRC})
|
#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)
|
function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE)
|
||||||
if ("$ENV{${_ENV_VAR_NAME}}" STREQUAL "")
|
if (NOT DEFINED ${_RESULT_NAME})
|
||||||
set (${_RESULT_NAME} ${_DEFAULT_VALUE} PARENT_SCOPE)
|
if ("$ENV{${_ENV_VAR_NAME}}" STREQUAL "")
|
||||||
else()
|
set (${_RESULT_NAME} ${_DEFAULT_VALUE} PARENT_SCOPE)
|
||||||
set (${_RESULT_NAME} $ENV{${_ENV_VAR_NAME}} PARENT_SCOPE)
|
else()
|
||||||
|
set (${_RESULT_NAME} $ENV{${_ENV_VAR_NAME}} PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
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>
|
|
@ -858,6 +858,14 @@
|
||||||
"help": "The path to the directory assets are stored in.<br/>If this path is relative, it will be relative to the application data directory.<br/>If you change this path you will need to manually copy any existing assets from the previous directory.",
|
"help": "The path to the directory assets are stored in.<br/>If this path is relative, it will be relative to the application data directory.<br/>If you change this path you will need to manually copy any existing assets from the previous directory.",
|
||||||
"default": "",
|
"default": "",
|
||||||
"advanced": true
|
"advanced": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "assets_filesize_limit",
|
||||||
|
"type": "int",
|
||||||
|
"label": "File Size Limit",
|
||||||
|
"help": "The file size limit of an asset that can be imported into the asset server in MBytes. 0 (default) means no limit on file size.",
|
||||||
|
"default": 0,
|
||||||
|
"advanced": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
set(TARGET_NAME interface)
|
set(TARGET_NAME interface)
|
||||||
project(${TARGET_NAME})
|
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 a default root dir for each of our optional externals if it was not passed
|
||||||
set(OPTIONAL_EXTERNALS "LeapMotion")
|
set(OPTIONAL_EXTERNALS "LeapMotion")
|
||||||
|
|
||||||
|
@ -66,9 +80,7 @@ qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
||||||
# add them to the interface source files
|
# add them to the interface source files
|
||||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
||||||
|
|
||||||
file(GLOB_RECURSE QML_SRC resources/qml/*.qml resources/qml/*.js)
|
list(APPEND INTERFACE_SRCS ${INTERFACE_QML_QRC})
|
||||||
add_custom_target(qml SOURCES ${QML_SRC})
|
|
||||||
GroupSources("resources/qml")
|
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
install(
|
install(
|
||||||
|
@ -131,10 +143,10 @@ if (APPLE)
|
||||||
|
|
||||||
# append the discovered resources to our list of interface sources
|
# append the discovered resources to our list of interface sources
|
||||||
list(APPEND INTERFACE_SRCS ${DISCOVERED_RESOURCES})
|
list(APPEND INTERFACE_SRCS ${DISCOVERED_RESOURCES})
|
||||||
|
list(APPEND INTERFACE_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME})
|
||||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# create the executable, make it a bundle on OS X
|
# create the executable, make it a bundle on OS X
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${INTERFACE_SRCS} ${QM})
|
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() {
|
function shouldRaiseKeyboard() {
|
||||||
var nodeName = document.activeElement.nodeName;
|
var nodeName = document.activeElement.nodeName;
|
||||||
var nodeType = document.activeElement.type;
|
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") {
|
|| document.activeElement.nodeName === "TEXTAREA") {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,14 +2,14 @@ name = mannequin
|
||||||
type = body+head
|
type = body+head
|
||||||
scale = 1
|
scale = 1
|
||||||
filename = mannequin/mannequin.baked.fbx
|
filename = mannequin/mannequin.baked.fbx
|
||||||
joint = jointEyeLeft = LeftEye
|
|
||||||
joint = jointRightHand = RightHand
|
|
||||||
joint = jointHead = Head
|
|
||||||
joint = jointEyeRight = RightEye
|
|
||||||
joint = jointLean = Spine
|
|
||||||
joint = jointNeck = Neck
|
|
||||||
joint = jointLeftHand = LeftHand
|
|
||||||
joint = jointRoot = Hips
|
joint = jointRoot = Hips
|
||||||
|
joint = jointLean = Spine
|
||||||
|
joint = jointLeftHand = LeftHand
|
||||||
|
joint = jointHead = Head
|
||||||
|
joint = jointEyeLeft = LeftEye
|
||||||
|
joint = jointEyeRight = RightEye
|
||||||
|
joint = jointRightHand = RightHand
|
||||||
|
joint = jointNeck = Neck
|
||||||
freeJoint = LeftArm
|
freeJoint = LeftArm
|
||||||
freeJoint = LeftForeArm
|
freeJoint = LeftForeArm
|
||||||
freeJoint = RightArm
|
freeJoint = RightArm
|
||||||
|
@ -18,72 +18,72 @@ bs = EyeBlink_L = blink = 1
|
||||||
bs = JawOpen = mouth_Open = 1
|
bs = JawOpen = mouth_Open = 1
|
||||||
bs = LipsFunnel = Oo = 1
|
bs = LipsFunnel = Oo = 1
|
||||||
bs = BrowsU_L = brow_Up = 1
|
bs = BrowsU_L = brow_Up = 1
|
||||||
jointIndex = RightHandIndex2 = 27
|
|
||||||
jointIndex = LeftHandIndex2 = 51
|
|
||||||
jointIndex = RightUpLeg = 6
|
|
||||||
jointIndex = RightToe_End = 10
|
|
||||||
jointIndex = RightEye = 65
|
|
||||||
jointIndex = LeftHandPinky1 = 42
|
|
||||||
jointIndex = RightHandRing1 = 22
|
|
||||||
jointIndex = face = 67
|
|
||||||
jointIndex = LeftUpLeg = 1
|
|
||||||
jointIndex = LeftHand = 41
|
|
||||||
jointIndex = LeftHandMiddle1 = 58
|
|
||||||
jointIndex = LeftHandIndex1 = 50
|
|
||||||
jointIndex = LeftEye = 64
|
|
||||||
jointIndex = RightHandIndex1 = 26
|
|
||||||
jointIndex = LeftHandPinky4 = 45
|
|
||||||
jointIndex = RightArm = 15
|
|
||||||
jointIndex = LeftShoulder = 38
|
|
||||||
jointIndex = RightHandPinky2 = 19
|
jointIndex = RightHandPinky2 = 19
|
||||||
jointIndex = RightHandThumb1 = 30
|
|
||||||
jointIndex = RightForeArm = 16
|
|
||||||
jointIndex = LeftHandMiddle3 = 60
|
|
||||||
jointIndex = Neck = 62
|
|
||||||
jointIndex = LeftHandThumb1 = 54
|
|
||||||
jointIndex = RightHandMiddle2 = 35
|
|
||||||
jointIndex = LeftHandMiddle4 = 61
|
jointIndex = LeftHandMiddle4 = 61
|
||||||
jointIndex = mannequin = 68
|
jointIndex = LeftHand = 41
|
||||||
jointIndex = Spine1 = 12
|
jointIndex = LeftHandRing4 = 49
|
||||||
|
jointIndex = RightHandMiddle3 = 36
|
||||||
|
jointIndex = LeftHandThumb4 = 57
|
||||||
|
jointIndex = RightToe_End = 10
|
||||||
|
jointIndex = LeftHandRing1 = 46
|
||||||
|
jointIndex = LeftForeArm = 40
|
||||||
|
jointIndex = RightHandIndex4 = 29
|
||||||
|
jointIndex = LeftShoulder = 38
|
||||||
|
jointIndex = RightHandMiddle4 = 37
|
||||||
|
jointIndex = RightShoulder = 14
|
||||||
|
jointIndex = LeftLeg = 2
|
||||||
|
jointIndex = LeftToe_End = 5
|
||||||
|
jointIndex = Hips = 0
|
||||||
jointIndex = RightFoot = 8
|
jointIndex = RightFoot = 8
|
||||||
|
jointIndex = RightHandThumb2 = 31
|
||||||
|
jointIndex = LeftHandMiddle3 = 60
|
||||||
|
jointIndex = RightHandThumb1 = 30
|
||||||
|
jointIndex = Neck = 62
|
||||||
|
jointIndex = Spine = 11
|
||||||
|
jointIndex = RightHandThumb4 = 33
|
||||||
|
jointIndex = RightHandMiddle1 = 34
|
||||||
|
jointIndex = LeftHandIndex4 = 53
|
||||||
|
jointIndex = face = 68
|
||||||
|
jointIndex = RightHandRing3 = 24
|
||||||
|
jointIndex = LeftHandPinky4 = 45
|
||||||
|
jointIndex = LeftHandMiddle2 = 59
|
||||||
|
jointIndex = RightHandThumb3 = 32
|
||||||
|
jointIndex = LeftHandPinky3 = 44
|
||||||
|
jointIndex = HeadTop_End = 66
|
||||||
|
jointIndex = Spine1 = 12
|
||||||
|
jointIndex = LeftHandRing3 = 48
|
||||||
|
jointIndex = mannequin1 = 67
|
||||||
|
jointIndex = RightEye = 65
|
||||||
|
jointIndex = RightHandRing4 = 25
|
||||||
|
jointIndex = RightHandPinky4 = 21
|
||||||
|
jointIndex = LeftHandRing2 = 47
|
||||||
|
jointIndex = RightHandIndex3 = 28
|
||||||
|
jointIndex = RightUpLeg = 6
|
||||||
|
jointIndex = LeftArm = 39
|
||||||
|
jointIndex = LeftHandThumb3 = 56
|
||||||
|
jointIndex = RightHandIndex2 = 27
|
||||||
|
jointIndex = RightForeArm = 16
|
||||||
|
jointIndex = RightArm = 15
|
||||||
|
jointIndex = RightHandRing2 = 23
|
||||||
|
jointIndex = LeftHandMiddle1 = 58
|
||||||
|
jointIndex = Spine2 = 13
|
||||||
|
jointIndex = LeftHandThumb2 = 55
|
||||||
|
jointIndex = RightHandMiddle2 = 35
|
||||||
|
jointIndex = RightHandPinky1 = 18
|
||||||
|
jointIndex = LeftUpLeg = 1
|
||||||
|
jointIndex = RightLeg = 7
|
||||||
|
jointIndex = LeftHandIndex2 = 51
|
||||||
jointIndex = RightHand = 17
|
jointIndex = RightHand = 17
|
||||||
jointIndex = LeftHandIndex3 = 52
|
jointIndex = LeftHandIndex3 = 52
|
||||||
jointIndex = RightHandIndex3 = 28
|
|
||||||
jointIndex = RightHandMiddle4 = 37
|
|
||||||
jointIndex = LeftLeg = 2
|
|
||||||
jointIndex = RightHandMiddle1 = 34
|
|
||||||
jointIndex = Spine2 = 13
|
|
||||||
jointIndex = LeftHandMiddle2 = 59
|
|
||||||
jointIndex = LeftHandPinky3 = 44
|
|
||||||
jointIndex = LeftHandThumb3 = 56
|
|
||||||
jointIndex = LeftHandRing4 = 49
|
|
||||||
jointIndex = RightHandThumb2 = 31
|
|
||||||
jointIndex = LeftHandRing3 = 48
|
|
||||||
jointIndex = HeadTop_End = 66
|
|
||||||
jointIndex = LeftHandThumb4 = 57
|
|
||||||
jointIndex = RightHandThumb3 = 32
|
|
||||||
jointIndex = RightHandPinky1 = 18
|
|
||||||
jointIndex = RightLeg = 7
|
|
||||||
jointIndex = RightHandMiddle3 = 36
|
|
||||||
jointIndex = RightHandPinky3 = 20
|
|
||||||
jointIndex = LeftToeBase = 4
|
|
||||||
jointIndex = LeftForeArm = 40
|
|
||||||
jointIndex = RightShoulder = 14
|
|
||||||
jointIndex = LeftHandRing2 = 47
|
|
||||||
jointIndex = LeftHandThumb2 = 55
|
|
||||||
jointIndex = Head = 63
|
|
||||||
jointIndex = RightHandRing4 = 25
|
|
||||||
jointIndex = LeftHandRing1 = 46
|
|
||||||
jointIndex = LeftFoot = 3
|
jointIndex = LeftFoot = 3
|
||||||
jointIndex = RightHandRing3 = 24
|
jointIndex = RightHandPinky3 = 20
|
||||||
jointIndex = RightHandThumb4 = 33
|
jointIndex = RightHandIndex1 = 26
|
||||||
jointIndex = LeftArm = 39
|
jointIndex = LeftHandPinky1 = 42
|
||||||
jointIndex = LeftToe_End = 5
|
|
||||||
jointIndex = RightToeBase = 9
|
jointIndex = RightToeBase = 9
|
||||||
jointIndex = RightHandPinky4 = 21
|
jointIndex = LeftHandIndex1 = 50
|
||||||
jointIndex = Spine = 11
|
jointIndex = LeftToeBase = 4
|
||||||
jointIndex = LeftHandIndex4 = 53
|
|
||||||
jointIndex = LeftHandPinky2 = 43
|
jointIndex = LeftHandPinky2 = 43
|
||||||
jointIndex = RightHandIndex4 = 29
|
jointIndex = RightHandRing1 = 22
|
||||||
jointIndex = Hips = 0
|
jointIndex = LeftHandThumb1 = 54
|
||||||
jointIndex = RightHandRing2 = 23
|
jointIndex = LeftEye = 64
|
||||||
|
jointIndex = Head = 63
|
||||||
|
|
BIN
interface/resources/meshes/mannequin/Eyes.ktx
Executable file → Normal file
BIN
interface/resources/meshes/mannequin/lambert1_Base_Color.ktx
Executable file → Normal file
BIN
interface/resources/meshes/mannequin/lambert1_Normal_OpenGL.ktx
Executable file → Normal file
BIN
interface/resources/meshes/mannequin/lambert1_Roughness.ktx
Executable file → Normal file
BIN
interface/resources/meshes/mannequin/mannequin.baked.fbx
Executable file → Normal file
|
@ -17,6 +17,7 @@ import "./hifi/audio" as HifiAudio
|
||||||
Hifi.AvatarInputs {
|
Hifi.AvatarInputs {
|
||||||
id: root;
|
id: root;
|
||||||
objectName: "AvatarInputs"
|
objectName: "AvatarInputs"
|
||||||
|
property int modality: Qt.NonModal
|
||||||
width: audio.width;
|
width: audio.width;
|
||||||
height: audio.height;
|
height: audio.height;
|
||||||
x: 10; y: 5;
|
x: 10; y: 5;
|
||||||
|
|
|
@ -8,6 +8,9 @@ Item {
|
||||||
|
|
||||||
anchors.leftMargin: 300
|
anchors.leftMargin: 300
|
||||||
objectName: "StatsItem"
|
objectName: "StatsItem"
|
||||||
|
property int modality: Qt.NonModal
|
||||||
|
implicitHeight: row.height
|
||||||
|
implicitWidth: row.width
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
stats.parentChanged.connect(fill);
|
stats.parentChanged.connect(fill);
|
||||||
|
@ -18,8 +21,9 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fill() {
|
function fill() {
|
||||||
// Explicitly fill in order to avoid warnings at shutdown
|
// This will cause a warning at shutdown, need to find another way to remove
|
||||||
anchors.fill = parent;
|
// the warning other than filling the anchors to the parent
|
||||||
|
anchors.horizontalCenter = parent.horizontalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
Hifi.Stats {
|
Hifi.Stats {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import "."
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: keyboardBase
|
id: keyboardBase
|
||||||
|
objectName: "keyboard"
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
@ -27,6 +28,8 @@ Rectangle {
|
||||||
|
|
||||||
readonly property int mirrorTextHeight: keyboardRowHeight
|
readonly property int mirrorTextHeight: keyboardRowHeight
|
||||||
|
|
||||||
|
property bool password: false
|
||||||
|
property alias mirroredText: mirrorText.text
|
||||||
property bool showMirrorText: true
|
property bool showMirrorText: true
|
||||||
readonly property int raisedHeight: 200
|
readonly property int raisedHeight: 200
|
||||||
|
|
||||||
|
@ -112,19 +115,23 @@ Rectangle {
|
||||||
color: "#252525"
|
color: "#252525"
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
TextEdit {
|
TextInput {
|
||||||
id: mirrorText
|
id: mirrorText
|
||||||
visible: showMirrorText
|
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
|
horizontalAlignment: Text.AlignHCenter
|
||||||
color: "#FFFFFF";
|
color: "#FFFFFF";
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
wrapMode: Text.WordWrap
|
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
|
selectByMouse: false
|
||||||
|
echoMode: password ? TextInput.Password : TextInput.Normal
|
||||||
|
|
||||||
Keys.onPressed: {
|
Keys.onPressed: {
|
||||||
if (event.key == Qt.Key_Return) {
|
if (event.key == Qt.Key_Return || event.key == Qt.Key_Space) {
|
||||||
mirrorText.text = "";
|
mirrorText.text = "";
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,20 @@ TextField {
|
||||||
|
|
||||||
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
y: textFieldLabel.visible ? textFieldLabel.height + textFieldLabel.anchors.bottomMargin : 0
|
||||||
|
|
||||||
|
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
||||||
|
Keys.onPressed: {
|
||||||
|
switch (event.key) {
|
||||||
|
case Qt.Key_Return:
|
||||||
|
case Qt.Key_Enter:
|
||||||
|
event.accepted = true;
|
||||||
|
|
||||||
|
// emit accepted signal manually
|
||||||
|
if (acceptableInput) {
|
||||||
|
accepted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
style: TextFieldStyle {
|
style: TextFieldStyle {
|
||||||
textColor: {
|
textColor: {
|
||||||
if (isLightColorScheme) {
|
if (isLightColorScheme) {
|
||||||
|
|
|
@ -301,15 +301,19 @@ FocusScope {
|
||||||
function isPointOnWindow(point) {
|
function isPointOnWindow(point) {
|
||||||
for (var i = 0; i < desktop.visibleChildren.length; i++) {
|
for (var i = 0; i < desktop.visibleChildren.length; i++) {
|
||||||
var child = desktop.visibleChildren[i];
|
var child = desktop.visibleChildren[i];
|
||||||
if (child.visible) {
|
if (child.hasOwnProperty("modality")) {
|
||||||
if (child.hasOwnProperty("modality")) {
|
var mappedPoint = mapToItem(child, point.x, point.y);
|
||||||
var mappedPoint = child.mapFromGlobal(point.x, point.y);
|
if (child.hasOwnProperty("frame")) {
|
||||||
var outLine = child.frame.children[2];
|
var outLine = child.frame.children[2];
|
||||||
var framePoint = outLine.mapFromGlobal(point.x, point.y);
|
var framePoint = outLine.mapFromGlobal(point.x, point.y);
|
||||||
if (child.contains(mappedPoint) || outLine.contains(framePoint)) {
|
if (outLine.contains(framePoint)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (child.contains(mappedPoint)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -239,6 +239,25 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiCommerceCommon.FirstUseTutorial {
|
||||||
|
id: firstUseTutorial;
|
||||||
|
z: 999;
|
||||||
|
visible: root.activeView === "firstUseTutorial";
|
||||||
|
anchors.fill: parent;
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
onSendSignalToParent: {
|
||||||
|
switch (message.method) {
|
||||||
|
case 'tutorial_skipClicked':
|
||||||
|
case 'tutorial_finished':
|
||||||
|
Settings.setValue("isFirstUseOfPurchases", false);
|
||||||
|
root.activeView = "checkoutSuccess";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -611,6 +630,28 @@ Rectangle {
|
||||||
lightboxPopup.visible = true;
|
lightboxPopup.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RalewaySemiBold {
|
||||||
|
id: explainRezText;
|
||||||
|
//visible: !root.isWearable;
|
||||||
|
text: '<font color="' + hifi.colors.redAccent + '"><a href="#">What does "Rez" mean?</a></font>'
|
||||||
|
// Text size
|
||||||
|
size: 16;
|
||||||
|
// Anchors
|
||||||
|
anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
|
||||||
|
anchors.topMargin: 6;
|
||||||
|
height: paintedHeight;
|
||||||
|
anchors.left: parent.left;
|
||||||
|
anchors.right: parent.right;
|
||||||
|
// Style
|
||||||
|
color: hifi.colors.redAccent;
|
||||||
|
wrapMode: Text.WordWrap;
|
||||||
|
// Alignment
|
||||||
|
horizontalAlignment: Text.AlignHCenter;
|
||||||
|
verticalAlignment: Text.AlignVCenter;
|
||||||
|
onLinkActivated: {
|
||||||
|
root.activeView = "firstUseTutorial";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RalewaySemiBold {
|
RalewaySemiBold {
|
||||||
id: myPurchasesLink;
|
id: myPurchasesLink;
|
||||||
|
@ -618,7 +659,7 @@ Rectangle {
|
||||||
// Text size
|
// Text size
|
||||||
size: 20;
|
size: 20;
|
||||||
// Anchors
|
// Anchors
|
||||||
anchors.top: noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom;
|
anchors.top: explainRezText.visible ? explainRezText.bottom : (noPermissionText.visible ? noPermissionText.bottom : rezNowButton.bottom);
|
||||||
anchors.topMargin: 40;
|
anchors.topMargin: 40;
|
||||||
height: paintedHeight;
|
height: paintedHeight;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
|
|
|
@ -25,7 +25,13 @@ Rectangle {
|
||||||
HifiConstants { id: hifi; }
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
id: root;
|
id: root;
|
||||||
property int activeView: 1;
|
property int activeView: 1;
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
root.activeView = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
@ -200,12 +200,6 @@ Rectangle {
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.lightGray;
|
color: hifi.colors.lightGray;
|
||||||
}
|
}
|
||||||
FontLoader { id: ralewayRegular; source: "../../../../fonts/Raleway-Regular.ttf"; }
|
|
||||||
TextMetrics {
|
|
||||||
id: textMetrics;
|
|
||||||
font.family: ralewayRegular.name
|
|
||||||
text: root.itemOwner;
|
|
||||||
}
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
id: ownedBy;
|
id: ownedBy;
|
||||||
text: root.itemOwner;
|
text: root.itemOwner;
|
||||||
|
@ -215,8 +209,7 @@ Rectangle {
|
||||||
anchors.top: ownedByHeader.bottom;
|
anchors.top: ownedByHeader.bottom;
|
||||||
anchors.topMargin: 8;
|
anchors.topMargin: 8;
|
||||||
anchors.left: ownedByHeader.left;
|
anchors.left: ownedByHeader.left;
|
||||||
height: textMetrics.height;
|
height: paintedHeight;
|
||||||
width: root.isMyCert ? textMetrics.width + 25 : ownedByHeader.width;
|
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.darkGray;
|
color: hifi.colors.darkGray;
|
||||||
elide: Text.ElideRight;
|
elide: Text.ElideRight;
|
||||||
|
@ -231,7 +224,7 @@ Rectangle {
|
||||||
anchors.topMargin: 4;
|
anchors.topMargin: 4;
|
||||||
anchors.bottom: ownedBy.bottom;
|
anchors.bottom: ownedBy.bottom;
|
||||||
anchors.left: ownedBy.right;
|
anchors.left: ownedBy.right;
|
||||||
anchors.leftMargin: 4;
|
anchors.leftMargin: 6;
|
||||||
anchors.right: ownedByHeader.right;
|
anchors.right: ownedByHeader.right;
|
||||||
// Style
|
// Style
|
||||||
color: hifi.colors.lightGray;
|
color: hifi.colors.lightGray;
|
||||||
|
|
|
@ -241,7 +241,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstUseTutorial {
|
HifiCommerceCommon.FirstUseTutorial {
|
||||||
id: firstUseTutorial;
|
id: firstUseTutorial;
|
||||||
z: 999;
|
z: 999;
|
||||||
visible: root.activeView === "firstUseTutorial";
|
visible: root.activeView === "firstUseTutorial";
|
||||||
|
|
|
@ -25,6 +25,7 @@ Item {
|
||||||
|
|
||||||
id: root;
|
id: root;
|
||||||
property string keyFilePath;
|
property string keyFilePath;
|
||||||
|
property bool showDebugButtons: true;
|
||||||
|
|
||||||
Hifi.QmlCommerce {
|
Hifi.QmlCommerce {
|
||||||
id: commerce;
|
id: commerce;
|
||||||
|
@ -56,6 +57,7 @@ Item {
|
||||||
}
|
}
|
||||||
HifiControlsUit.Button {
|
HifiControlsUit.Button {
|
||||||
id: clearCachedPassphraseButton;
|
id: clearCachedPassphraseButton;
|
||||||
|
visible: root.showDebugButtons;
|
||||||
color: hifi.buttons.black;
|
color: hifi.buttons.black;
|
||||||
colorScheme: hifi.colorSchemes.dark;
|
colorScheme: hifi.colorSchemes.dark;
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
|
@ -71,6 +73,7 @@ Item {
|
||||||
}
|
}
|
||||||
HifiControlsUit.Button {
|
HifiControlsUit.Button {
|
||||||
id: resetButton;
|
id: resetButton;
|
||||||
|
visible: root.showDebugButtons;
|
||||||
color: hifi.buttons.red;
|
color: hifi.buttons.red;
|
||||||
colorScheme: hifi.colorSchemes.dark;
|
colorScheme: hifi.colorSchemes.dark;
|
||||||
anchors.top: clearCachedPassphraseButton.top;
|
anchors.top: clearCachedPassphraseButton.top;
|
||||||
|
@ -90,17 +93,22 @@ Item {
|
||||||
ListElement {
|
ListElement {
|
||||||
isExpanded: false;
|
isExpanded: false;
|
||||||
question: "What are private keys?"
|
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 {
|
ListElement {
|
||||||
isExpanded: false;
|
isExpanded: false;
|
||||||
question: "Where are my private keys stored?"
|
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 folder where your HifiKeys are stored on your main display.</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 folder where your HifiKeys are stored on your main display.</a></font></b>');
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
isExpanded: false;
|
isExpanded: false;
|
||||||
question: "What happens if I lose my passphrase?"
|
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 {
|
ListElement {
|
||||||
isExpanded: false;
|
isExpanded: false;
|
||||||
|
|
|
@ -25,7 +25,7 @@ Item {
|
||||||
HifiConstants { id: hifi; }
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
id: root;
|
id: root;
|
||||||
z: 998;
|
z: 997;
|
||||||
property bool keyboardRaised: false;
|
property bool keyboardRaised: false;
|
||||||
property string titleBarIcon: "";
|
property string titleBarIcon: "";
|
||||||
property string titleBarText: "";
|
property string titleBarText: "";
|
||||||
|
@ -350,7 +350,7 @@ Item {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: keyboardContainer;
|
id: keyboardContainer;
|
||||||
z: 999;
|
z: 998;
|
||||||
visible: keyboard.raised;
|
visible: keyboard.raised;
|
||||||
property bool punctuationMode: false;
|
property bool punctuationMode: false;
|
||||||
anchors {
|
anchors {
|
||||||
|
@ -361,11 +361,13 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: lowerKeyboardButton;
|
id: lowerKeyboardButton;
|
||||||
|
z: 999;
|
||||||
source: "images/lowerKeyboard.png";
|
source: "images/lowerKeyboard.png";
|
||||||
anchors.horizontalCenter: parent.horizontalCenter;
|
anchors.right: keyboard.right;
|
||||||
anchors.bottom: keyboard.top;
|
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
|
||||||
height: 30;
|
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
|
||||||
width: 120;
|
height: 50;
|
||||||
|
width: 60;
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
|
|
@ -290,7 +290,17 @@ Item {
|
||||||
id: removeHmdContainer;
|
id: removeHmdContainer;
|
||||||
z: 998;
|
z: 998;
|
||||||
visible: false;
|
visible: false;
|
||||||
color: hifi.colors.blueHighlight;
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0.2;
|
||||||
|
color: hifi.colors.baseGrayHighlight;
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1.0;
|
||||||
|
color: hifi.colors.baseGrayShadow;
|
||||||
|
}
|
||||||
|
}
|
||||||
anchors.fill: backupInstructionsButton;
|
anchors.fill: backupInstructionsButton;
|
||||||
radius: 5;
|
radius: 5;
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
@ -165,7 +165,7 @@ Rectangle {
|
||||||
WalletSetup {
|
WalletSetup {
|
||||||
id: walletSetup;
|
id: walletSetup;
|
||||||
visible: root.activeView === "walletSetup";
|
visible: root.activeView === "walletSetup";
|
||||||
z: 998;
|
z: 997;
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -192,7 +192,7 @@ Rectangle {
|
||||||
PassphraseChange {
|
PassphraseChange {
|
||||||
id: passphraseChange;
|
id: passphraseChange;
|
||||||
visible: root.activeView === "passphraseChange";
|
visible: root.activeView === "passphraseChange";
|
||||||
z: 998;
|
z: 997;
|
||||||
anchors.top: titleBarContainer.bottom;
|
anchors.top: titleBarContainer.bottom;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
|
@ -217,7 +217,7 @@ Rectangle {
|
||||||
SecurityImageChange {
|
SecurityImageChange {
|
||||||
id: securityImageChange;
|
id: securityImageChange;
|
||||||
visible: root.activeView === "securityImageChange";
|
visible: root.activeView === "securityImageChange";
|
||||||
z: 998;
|
z: 997;
|
||||||
anchors.top: titleBarContainer.bottom;
|
anchors.top: titleBarContainer.bottom;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
|
@ -653,7 +653,7 @@ Rectangle {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: keyboardContainer;
|
id: keyboardContainer;
|
||||||
z: 999;
|
z: 998;
|
||||||
visible: keyboard.raised;
|
visible: keyboard.raised;
|
||||||
property bool punctuationMode: false;
|
property bool punctuationMode: false;
|
||||||
anchors {
|
anchors {
|
||||||
|
@ -664,11 +664,13 @@ Rectangle {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: lowerKeyboardButton;
|
id: lowerKeyboardButton;
|
||||||
|
z: 999;
|
||||||
source: "images/lowerKeyboard.png";
|
source: "images/lowerKeyboard.png";
|
||||||
anchors.horizontalCenter: parent.horizontalCenter;
|
anchors.right: keyboard.right;
|
||||||
anchors.bottom: keyboard.top;
|
anchors.top: keyboard.showMirrorText ? keyboard.top : undefined;
|
||||||
height: 30;
|
anchors.bottom: keyboard.showMirrorText ? undefined : keyboard.bottom;
|
||||||
width: 120;
|
height: 50;
|
||||||
|
width: 60;
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
|
|
|
@ -164,7 +164,7 @@ Item {
|
||||||
anchors.top: parent.top;
|
anchors.top: parent.top;
|
||||||
anchors.topMargin: 26;
|
anchors.topMargin: 26;
|
||||||
anchors.left: parent.left;
|
anchors.left: parent.left;
|
||||||
anchors.leftMargin: 30;
|
anchors.leftMargin: 20;
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 30;
|
anchors.rightMargin: 30;
|
||||||
height: 30;
|
height: 30;
|
||||||
|
|
|
@ -679,7 +679,7 @@ Item {
|
||||||
anchors.right: parent.right;
|
anchors.right: parent.right;
|
||||||
anchors.rightMargin: 30;
|
anchors.rightMargin: 30;
|
||||||
height: 40;
|
height: 40;
|
||||||
text: "Open Instructions for Later";
|
text: "Open Backup Instructions for Later";
|
||||||
onClicked: {
|
onClicked: {
|
||||||
instructions01Container.visible = false;
|
instructions01Container.visible = false;
|
||||||
instructions02Container.visible = true;
|
instructions02Container.visible = true;
|
||||||
|
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 1.2 KiB |
|
@ -19,6 +19,7 @@ Window {
|
||||||
shown: true
|
shown: true
|
||||||
width: content.width
|
width: content.width
|
||||||
height: content.height
|
height: content.height
|
||||||
|
disableFade: true
|
||||||
// Disable this window from being able to call 'desktop.raise() and desktop.showDesktop'
|
// Disable this window from being able to call 'desktop.raise() and desktop.showDesktop'
|
||||||
activator: Item {}
|
activator: Item {}
|
||||||
property bool horizontal: true
|
property bool horizontal: true
|
||||||
|
|
|
@ -26,6 +26,7 @@ FocusScope {
|
||||||
property var completionCallback;
|
property var completionCallback;
|
||||||
// The target property to animate, usually scale or opacity
|
// The target property to animate, usually scale or opacity
|
||||||
property alias fadeTargetProperty: root.opacity
|
property alias fadeTargetProperty: root.opacity
|
||||||
|
property bool disableFade: false
|
||||||
// always start the property at 0 to enable fade in on creation
|
// always start the property at 0 to enable fade in on creation
|
||||||
fadeTargetProperty: 0
|
fadeTargetProperty: 0
|
||||||
// DO NOT set visible to false or when derived types override it it
|
// DO NOT set visible to false or when derived types override it it
|
||||||
|
@ -35,6 +36,9 @@ FocusScope {
|
||||||
// Some dialogs should be destroyed when they become
|
// Some dialogs should be destroyed when they become
|
||||||
// invisible, so handle that
|
// invisible, so handle that
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
|
if (disableFade) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// If someone directly set the visibility to false
|
// If someone directly set the visibility to false
|
||||||
// toggle it back on and use the targetVisible flag to transition
|
// toggle it back on and use the targetVisible flag to transition
|
||||||
// via fading.
|
// via fading.
|
||||||
|
@ -62,7 +66,9 @@ FocusScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
onFadeTargetPropertyChanged: {
|
onFadeTargetPropertyChanged: {
|
||||||
visible = (fadeTargetProperty != 0.0);
|
if (!disableFade) {
|
||||||
|
visible = (fadeTargetProperty != 0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fadeIn(callback) {
|
function fadeIn(callback) {
|
||||||
|
|
|
@ -207,6 +207,17 @@
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include <VersionHelpers.h>
|
#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" {
|
extern "C" {
|
||||||
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||||
}
|
}
|
||||||
|
@ -264,9 +275,7 @@ private:
|
||||||
switch ((int)event->type()) {
|
switch ((int)event->type()) {
|
||||||
case ApplicationEvent::Render:
|
case ApplicationEvent::Render:
|
||||||
render();
|
render();
|
||||||
// Ensure we never back up the render events. Each render should be triggered only in response
|
qApp->_pendingRenderEvent.store(false);
|
||||||
// to the NEXT render event after the last render occured
|
|
||||||
QCoreApplication::removePostedEvents(this, ApplicationEvent::Render);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2249,7 +2258,7 @@ void Application::initializeUi() {
|
||||||
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
offscreenUi->setBaseUrl(QUrl::fromLocalFile(PathUtils::resourcesPath() + "/qml/"));
|
||||||
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
// OffscreenUi is a subclass of OffscreenQmlSurface specifically designed to
|
||||||
// support the window management and scripting proxies for VR use
|
// 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
|
// FIXME either expose so that dialogs can set this themselves or
|
||||||
// do better detection in the offscreen UI of what has focus
|
// do better detection in the offscreen UI of what has focus
|
||||||
|
@ -2717,9 +2726,14 @@ bool Application::importFromZIP(const QString& filePath) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
void Application::onPresent(quint32 frameCount) {
|
void Application::onPresent(quint32 frameCount) {
|
||||||
postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority);
|
bool expected = false;
|
||||||
if (_renderEventHandler && !isAboutToQuit()) {
|
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));
|
postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2786,7 +2800,26 @@ bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) {
|
||||||
return false;
|
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) {
|
bool Application::event(QEvent* event) {
|
||||||
|
|
||||||
if (!Menu::getInstance()) {
|
if (!Menu::getInstance()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2806,8 +2839,18 @@ bool Application::event(QEvent* event) {
|
||||||
// see (windowMinimizedChanged)
|
// see (windowMinimizedChanged)
|
||||||
case ApplicationEvent::Idle:
|
case ApplicationEvent::Idle:
|
||||||
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;
|
return true;
|
||||||
|
|
||||||
case QEvent::MouseMove:
|
case QEvent::MouseMove:
|
||||||
|
@ -3968,9 +4011,14 @@ void Application::calibrateEyeTracker5Points() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs, const glm::vec3* givenOffset) {
|
bool Application::exportEntities(const QString& filename,
|
||||||
|
const QVector<EntityItemID>& entityIDs,
|
||||||
|
const glm::vec3* givenOffset) {
|
||||||
QHash<EntityItemID, EntityItemPointer> entities;
|
QHash<EntityItemID, EntityItemPointer> entities;
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
const QUuid myAvatarID = nodeList->getSessionUUID();
|
||||||
|
|
||||||
auto entityTree = getEntities()->getTree();
|
auto entityTree = getEntities()->getTree();
|
||||||
auto exportTree = std::make_shared<EntityTree>();
|
auto exportTree = std::make_shared<EntityTree>();
|
||||||
exportTree->createRootElement();
|
exportTree->createRootElement();
|
||||||
|
@ -3986,8 +4034,12 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
||||||
|
|
||||||
if (!givenOffset) {
|
if (!givenOffset) {
|
||||||
EntityItemID parentID = entityItem->getParentID();
|
EntityItemID parentID = entityItem->getParentID();
|
||||||
if (parentID.isInvalidID() || !entityIDs.contains(parentID) || !entityTree->findEntityByEntityItemID(parentID)) {
|
bool parentIsAvatar = (parentID == AVATAR_SELF_ID || parentID == myAvatarID);
|
||||||
auto position = entityItem->getPosition(); // If parent wasn't selected, we want absolute position, which isn't in properties.
|
if (!parentIsAvatar && (parentID.isInvalidID() ||
|
||||||
|
!entityIDs.contains(parentID) ||
|
||||||
|
!entityTree->findEntityByEntityItemID(parentID))) {
|
||||||
|
// If parent wasn't selected, we want absolute position, which isn't in properties.
|
||||||
|
auto position = entityItem->getPosition();
|
||||||
root.x = glm::min(root.x, position.x);
|
root.x = glm::min(root.x, position.x);
|
||||||
root.y = glm::min(root.y, position.y);
|
root.y = glm::min(root.y, position.y);
|
||||||
root.z = glm::min(root.z, position.z);
|
root.z = glm::min(root.z, position.z);
|
||||||
|
@ -4007,12 +4059,16 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
||||||
for (EntityItemPointer& entityDatum : entities) {
|
for (EntityItemPointer& entityDatum : entities) {
|
||||||
auto properties = entityDatum->getProperties();
|
auto properties = entityDatum->getProperties();
|
||||||
EntityItemID parentID = properties.getParentID();
|
EntityItemID parentID = properties.getParentID();
|
||||||
if (parentID.isInvalidID()) {
|
bool parentIsAvatar = (parentID == AVATAR_SELF_ID || parentID == myAvatarID);
|
||||||
properties.setPosition(properties.getPosition() - root);
|
if (parentIsAvatar) {
|
||||||
|
properties.setParentID(AVATAR_SELF_ID);
|
||||||
|
} else {
|
||||||
|
if (parentID.isInvalidID()) {
|
||||||
|
properties.setPosition(properties.getPosition() - root);
|
||||||
|
} else if (!entities.contains(parentID)) {
|
||||||
|
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
|
||||||
|
} // else valid parent -- don't offset
|
||||||
}
|
}
|
||||||
else if (!entities.contains(parentID)) {
|
|
||||||
entityDatum->globalizeProperties(properties, "Parent %3 of %2 %1 is not selected for export.", -root);
|
|
||||||
} // else valid parent -- don't offset
|
|
||||||
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
|
exportTree->addEntity(entityDatum->getEntityItemID(), properties);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -7197,7 +7253,7 @@ void Application::updateDisplayMode() {
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
||||||
_displayPlugin = 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();
|
auto desktop = offscreenUi->getDesktop();
|
||||||
if (desktop) {
|
if (desktop) {
|
||||||
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
||||||
|
|
|
@ -717,5 +717,8 @@ private:
|
||||||
LaserPointerManager _laserPointerManager;
|
LaserPointerManager _laserPointerManager;
|
||||||
|
|
||||||
friend class RenderEventHandler;
|
friend class RenderEventHandler;
|
||||||
|
|
||||||
|
std::atomic<bool> _pendingIdleEvent { false };
|
||||||
|
std::atomic<bool> _pendingRenderEvent { false };
|
||||||
};
|
};
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -72,6 +72,12 @@ void Application::paintGL() {
|
||||||
{
|
{
|
||||||
QMutexLocker viewLocker(&_renderArgsMutex);
|
QMutexLocker viewLocker(&_renderArgsMutex);
|
||||||
renderArgs = _appRenderArgs._renderArgs;
|
renderArgs = _appRenderArgs._renderArgs;
|
||||||
|
|
||||||
|
// don't render if there is no context.
|
||||||
|
if (!_appRenderArgs._renderArgs._context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HMDSensorPose = _appRenderArgs._headPose;
|
HMDSensorPose = _appRenderArgs._headPose;
|
||||||
eyeToWorld = _appRenderArgs._eyeToWorld;
|
eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||||
sensorToWorld = _appRenderArgs._sensorToWorld;
|
sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||||
|
|
|
@ -53,7 +53,7 @@ const QUuid MY_AVATAR_KEY; // NULL key
|
||||||
|
|
||||||
AvatarManager::AvatarManager(QObject* parent) :
|
AvatarManager::AvatarManager(QObject* parent) :
|
||||||
_avatarsToFade(),
|
_avatarsToFade(),
|
||||||
_myAvatar(std::make_shared<MyAvatar>(qApp->thread()))
|
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
|
||||||
{
|
{
|
||||||
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
||||||
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
||||||
|
@ -297,7 +297,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
||||||
return std::make_shared<OtherAvatar>(qApp->thread());
|
return AvatarSharedPointer(new OtherAvatar(qApp->thread()), [](OtherAvatar* ptr) { ptr->deleteLater(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
|
||||||
|
|
|
@ -3238,3 +3238,9 @@ void MyAvatar::setModelScale(float scale) {
|
||||||
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
emit sensorToWorldScaleChanged(sensorToWorldScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpatialParentTree* MyAvatar::getParentTree() const {
|
||||||
|
auto entityTreeRenderer = qApp->getEntities();
|
||||||
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
|
return entityTree.get();
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include <Rig.h>
|
#include <Rig.h>
|
||||||
#include <Sound.h>
|
#include <Sound.h>
|
||||||
|
@ -106,6 +108,8 @@ class MyAvatar : public Avatar {
|
||||||
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
|
* "scripts/system/controllers/toggleAdvancedMovementForHandControllers.js".
|
||||||
* @property userHeight {number} The height of the user in sensor space. (meters).
|
* @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 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
|
// 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 userHeight READ getUserHeight WRITE setUserHeight)
|
||||||
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
|
Q_PROPERTY(float userEyeHeight READ getUserEyeHeight)
|
||||||
|
|
||||||
|
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
|
||||||
|
|
||||||
const QString DOMINANT_LEFT_HAND = "left";
|
const QString DOMINANT_LEFT_HAND = "left";
|
||||||
const QString DOMINANT_RIGHT_HAND = "right";
|
const QString DOMINANT_RIGHT_HAND = "right";
|
||||||
|
@ -544,6 +550,10 @@ public:
|
||||||
float getUserHeight() const;
|
float getUserHeight() const;
|
||||||
float getUserEyeHeight() const;
|
float getUserEyeHeight() const;
|
||||||
|
|
||||||
|
virtual SpatialParentTree* getParentTree() const override;
|
||||||
|
|
||||||
|
const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void increaseSize();
|
void increaseSize();
|
||||||
void decreaseSize();
|
void decreaseSize();
|
||||||
|
@ -646,8 +656,6 @@ private:
|
||||||
|
|
||||||
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
|
void setVisibleInSceneIfReady(Model* model, const render::ScenePointer& scene, bool visiblity);
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
virtual void updatePalms() override {}
|
virtual void updatePalms() override {}
|
||||||
void lateUpdatePalms();
|
void lateUpdatePalms();
|
||||||
|
|
||||||
|
|
|
@ -105,19 +105,19 @@ RSA* readKeys(const char* filename) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool writeBackupInstructions() {
|
bool Wallet::writeBackupInstructions() {
|
||||||
QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html");
|
QString inputFilename(PathUtils::resourcesPath() + "html/commerce/backup_instructions.html");
|
||||||
QString filename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
QString outputFilename = PathUtils::getAppDataFilePath(INSTRUCTIONS_FILE);
|
||||||
QFile outputFile(filename);
|
QFile outputFile(outputFilename);
|
||||||
bool retval = false;
|
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();
|
QByteArray fileData = outputFile.readAll();
|
||||||
QString text(fileData);
|
QString text(fileData);
|
||||||
|
@ -132,7 +132,7 @@ bool writeBackupInstructions() {
|
||||||
retval = true;
|
retval = true;
|
||||||
qCDebug(commerce) << "wrote html file successfully";
|
qCDebug(commerce) << "wrote html file successfully";
|
||||||
} else {
|
} else {
|
||||||
qCDebug(commerce) << "failed to open output html file" << filename;
|
qCDebug(commerce) << "failed to open output html file" << outputFilename;
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -154,8 +154,6 @@ bool writeKeys(const char* filename, RSA* keys) {
|
||||||
QFile(QString(filename)).remove();
|
QFile(QString(filename)).remove();
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeBackupInstructions();
|
|
||||||
|
|
||||||
retval = true;
|
retval = true;
|
||||||
qCDebug(commerce) << "wrote keys successfully";
|
qCDebug(commerce) << "wrote keys successfully";
|
||||||
|
@ -359,6 +357,8 @@ bool Wallet::setPassphrase(const QString& passphrase) {
|
||||||
|
|
||||||
_publicKeys.clear();
|
_publicKeys.clear();
|
||||||
|
|
||||||
|
writeBackupInstructions();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,6 +526,8 @@ bool Wallet::generateKeyPair() {
|
||||||
qCInfo(commerce) << "Generating keypair.";
|
qCInfo(commerce) << "Generating keypair.";
|
||||||
auto keyPair = generateRSAKeypair();
|
auto keyPair = generateRSAKeypair();
|
||||||
|
|
||||||
|
writeBackupInstructions();
|
||||||
|
|
||||||
// TODO: redo this soon -- need error checking and so on
|
// TODO: redo this soon -- need error checking and so on
|
||||||
writeSecurityImage(_securityImage, keyFilePath());
|
writeSecurityImage(_securityImage, keyFilePath());
|
||||||
QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last();
|
QString oldKey = _publicKeys.count() == 0 ? "" : _publicKeys.last();
|
||||||
|
|
|
@ -80,6 +80,7 @@ private:
|
||||||
void updateImageProvider();
|
void updateImageProvider();
|
||||||
bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath);
|
bool writeSecurityImage(const QPixmap* pixmap, const QString& outputFilePath);
|
||||||
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
bool readSecurityImage(const QString& inputFilePath, unsigned char** outputBufferPtr, int* outputBufferLen);
|
||||||
|
bool writeBackupInstructions();
|
||||||
|
|
||||||
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);
|
bool verifyOwnerChallenge(const QByteArray& encryptedText, const QString& publicKey, QString& decryptedText);
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
|
|
||||||
LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
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),
|
_renderingEnabled(enabled),
|
||||||
_renderStates(renderStates),
|
_renderStates(renderStates),
|
||||||
_defaultRenderStates(defaultRenderStates),
|
_defaultRenderStates(defaultRenderStates),
|
||||||
_faceAvatar(faceAvatar),
|
_faceAvatar(faceAvatar),
|
||||||
_centerEndY(centerEndY),
|
_centerEndY(centerEndY),
|
||||||
_lockEnd(lockEnd)
|
_lockEnd(lockEnd),
|
||||||
|
_distanceScaleEnd(distanceScaleEnd)
|
||||||
{
|
{
|
||||||
_rayPickUID = DependencyManager::get<RayPickScriptingInterface>()->createRayPick(rayProps);
|
_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].getStartID(), startProps);
|
||||||
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps);
|
||||||
updateRenderStateOverlay(_renderStates[state].getEndID(), endProps);
|
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) {
|
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()) {
|
if (!renderState.getEndID().isNull()) {
|
||||||
QVariantMap endProps;
|
QVariantMap endProps;
|
||||||
glm::quat faceAvatarRotation = DependencyManager::get<AvatarManager>()->getMyAvatar()->getOrientation() * glm::quat(glm::radians(glm::vec3(0.0f, 180.0f, 0.0f)));
|
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) {
|
if (_centerEndY) {
|
||||||
endProps.insert("position", end);
|
endProps.insert("position", end);
|
||||||
} else {
|
} else {
|
||||||
glm::vec3 dim = vec3FromVariant(qApp->getOverlays().getProperty(renderState.getEndID(), "dimensions").value);
|
|
||||||
glm::vec3 currentUpVector = faceAvatarRotation * Vectors::UP;
|
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)));
|
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();
|
_pathIgnoreRays = qApp->getOverlays().getProperty(_pathID, "ignoreRayIntersection").value.toBool();
|
||||||
}
|
}
|
||||||
if (!_endID.isNull()) {
|
if (!_endID.isNull()) {
|
||||||
|
_endDim = vec3FromVariant(qApp->getOverlays().getProperty(_endID, "dimensions").value);
|
||||||
_endIgnoreRays = qApp->getOverlays().getProperty(_endID, "ignoreRayIntersection").value.toBool();
|
_endIgnoreRays = qApp->getOverlays().getProperty(_endID, "ignoreRayIntersection").value.toBool();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ public:
|
||||||
const bool& doesPathIgnoreRays() const { return _pathIgnoreRays; }
|
const bool& doesPathIgnoreRays() const { return _pathIgnoreRays; }
|
||||||
const bool& doesEndIgnoreRays() const { return _endIgnoreRays; }
|
const bool& doesEndIgnoreRays() const { return _endIgnoreRays; }
|
||||||
|
|
||||||
|
void setEndDim(const glm::vec3& endDim) { _endDim = endDim; }
|
||||||
|
const glm::vec3& getEndDim() const { return _endDim; }
|
||||||
|
|
||||||
void deleteOverlays();
|
void deleteOverlays();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -41,6 +44,8 @@ private:
|
||||||
bool _startIgnoreRays;
|
bool _startIgnoreRays;
|
||||||
bool _pathIgnoreRays;
|
bool _pathIgnoreRays;
|
||||||
bool _endIgnoreRays;
|
bool _endIgnoreRays;
|
||||||
|
|
||||||
|
glm::vec3 _endDim;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,7 +57,7 @@ public:
|
||||||
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
|
typedef std::unordered_map<std::string, std::pair<float, RenderState>> DefaultRenderStateMap;
|
||||||
|
|
||||||
LaserPointer(const QVariant& rayProps, const RenderStateMap& renderStates, const DefaultRenderStateMap& defaultRenderStates,
|
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();
|
~LaserPointer();
|
||||||
|
|
||||||
QUuid getRayUID() { return _rayPickUID; }
|
QUuid getRayUID() { return _rayPickUID; }
|
||||||
|
@ -88,6 +93,7 @@ private:
|
||||||
bool _faceAvatar;
|
bool _faceAvatar;
|
||||||
bool _centerEndY;
|
bool _centerEndY;
|
||||||
bool _lockEnd;
|
bool _lockEnd;
|
||||||
|
bool _distanceScaleEnd;
|
||||||
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
std::pair<QUuid, bool> _objectLockEnd { std::pair<QUuid, bool>(QUuid(), false)};
|
||||||
|
|
||||||
QUuid _rayPickUID;
|
QUuid _rayPickUID;
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#include "LaserPointerManager.h"
|
#include "LaserPointerManager.h"
|
||||||
|
|
||||||
QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
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) {
|
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, enabled);
|
std::shared_ptr<LaserPointer> laserPointer = std::make_shared<LaserPointer>(rayProps, renderStates, defaultRenderStates, faceAvatar, centerEndY, lockEnd, distanceScaleEnd, enabled);
|
||||||
if (!laserPointer->getRayUID().isNull()) {
|
if (!laserPointer->getRayUID().isNull()) {
|
||||||
QWriteLocker containsLock(&_containsLock);
|
QWriteLocker containsLock(&_containsLock);
|
||||||
QUuid id = QUuid::createUuid();
|
QUuid id = QUuid::createUuid();
|
||||||
|
|
|
@ -22,7 +22,7 @@ class LaserPointerManager {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QUuid createLaserPointer(const QVariant& rayProps, const LaserPointer::RenderStateMap& renderStates, const LaserPointer::DefaultRenderStateMap& defaultRenderStates,
|
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 removeLaserPointer(const QUuid uid);
|
||||||
void enableLaserPointer(const QUuid uid);
|
void enableLaserPointer(const QUuid uid);
|
||||||
void disableLaserPointer(const QUuid uid);
|
void disableLaserPointer(const QUuid uid);
|
||||||
|
|
|
@ -32,6 +32,11 @@ QUuid LaserPointerScriptingInterface::createLaserPointer(const QVariant& propert
|
||||||
lockEnd = propertyMap["lockEnd"].toBool();
|
lockEnd = propertyMap["lockEnd"].toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool distanceScaleEnd = false;
|
||||||
|
if (propertyMap["distanceScaleEnd"].isValid()) {
|
||||||
|
distanceScaleEnd = propertyMap["distanceScaleEnd"].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
if (propertyMap["enabled"].isValid()) {
|
if (propertyMap["enabled"].isValid()) {
|
||||||
enabled = propertyMap["enabled"].toBool();
|
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) {
|
void LaserPointerScriptingInterface::editRenderState(QUuid uid, const QString& renderState, const QVariant& properties) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen
|
||||||
Q_PROPERTY(bool showTablet READ getShouldShowTablet)
|
Q_PROPERTY(bool showTablet READ getShouldShowTablet)
|
||||||
Q_PROPERTY(QUuid tabletID READ getCurrentTabletFrameID WRITE setCurrentTabletFrameID)
|
Q_PROPERTY(QUuid tabletID READ getCurrentTabletFrameID WRITE setCurrentTabletFrameID)
|
||||||
Q_PROPERTY(QUuid homeButtonID READ getCurrentHomeButtonID WRITE setCurrentHomeButtonID)
|
Q_PROPERTY(QUuid homeButtonID READ getCurrentHomeButtonID WRITE setCurrentHomeButtonID)
|
||||||
|
Q_PROPERTY(QUuid homeButtonHighlightID READ getCurrentHomeButtonHightlightID WRITE setCurrentHomeButtonHightlightID)
|
||||||
Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID)
|
Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -97,6 +98,9 @@ public:
|
||||||
void setCurrentHomeButtonID(QUuid homeButtonID) { _homeButtonID = homeButtonID; }
|
void setCurrentHomeButtonID(QUuid homeButtonID) { _homeButtonID = homeButtonID; }
|
||||||
QUuid getCurrentHomeButtonID() const { return _homeButtonID; }
|
QUuid getCurrentHomeButtonID() const { return _homeButtonID; }
|
||||||
|
|
||||||
|
void setCurrentHomeButtonHightlightID(QUuid homeButtonHightlightID) { _homeButtonHightlightID = homeButtonHightlightID; }
|
||||||
|
QUuid getCurrentHomeButtonHightlightID() const { return _homeButtonHightlightID; }
|
||||||
|
|
||||||
void setCurrentTabletScreenID(QUuid tabletID) { _tabletScreenID = tabletID; }
|
void setCurrentTabletScreenID(QUuid tabletID) { _tabletScreenID = tabletID; }
|
||||||
QUuid getCurrentTabletScreenID() const { return _tabletScreenID; }
|
QUuid getCurrentTabletScreenID() const { return _tabletScreenID; }
|
||||||
|
|
||||||
|
@ -105,6 +109,7 @@ private:
|
||||||
QUuid _tabletUIID; // this is the entityID of the tablet frame
|
QUuid _tabletUIID; // this is the entityID of the tablet frame
|
||||||
QUuid _tabletScreenID; // this is the overlayID which is part of (a child of) the tablet-ui.
|
QUuid _tabletScreenID; // this is the overlayID which is part of (a child of) the tablet-ui.
|
||||||
QUuid _homeButtonID;
|
QUuid _homeButtonID;
|
||||||
|
QUuid _homeButtonHightlightID;
|
||||||
QUuid _tabletEntityID;
|
QUuid _tabletEntityID;
|
||||||
|
|
||||||
// Get the position of the HMD
|
// Get the position of the HMD
|
||||||
|
|
|
@ -106,14 +106,15 @@ extern std::atomic<size_t> DECIMATED_TEXTURE_COUNT;
|
||||||
extern std::atomic<size_t> RECTIFIED_TEXTURE_COUNT;
|
extern std::atomic<size_t> RECTIFIED_TEXTURE_COUNT;
|
||||||
|
|
||||||
void Stats::updateStats(bool force) {
|
void Stats::updateStats(bool force) {
|
||||||
|
QQuickItem* parent = parentItem();
|
||||||
if (!force) {
|
if (!force) {
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||||
if (isVisible()) {
|
if (parent->isVisible()) {
|
||||||
setVisible(false);
|
parent->setVisible(false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (!isVisible()) {
|
} else if (!parent->isVisible()) {
|
||||||
setVisible(true);
|
parent->setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -305,3 +305,9 @@ Transform Base3DOverlay::evalRenderTransform() {
|
||||||
void Base3DOverlay::setRenderTransform(const Transform& transform) {
|
void Base3DOverlay::setRenderTransform(const Transform& transform) {
|
||||||
_renderTransform = transform;
|
_renderTransform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpatialParentTree* Base3DOverlay::getParentTree() const {
|
||||||
|
auto entityTreeRenderer = qApp->getEntities();
|
||||||
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
|
return entityTree.get();
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
virtual AABox getBounds() const override = 0;
|
virtual AABox getBounds() const override = 0;
|
||||||
|
|
||||||
void update(float deltatime) override;
|
void update(float deltatime) override;
|
||||||
|
|
||||||
void notifyRenderTransformChange() const;
|
void notifyRenderTransformChange() const;
|
||||||
|
|
||||||
void setProperties(const QVariantMap& properties) override;
|
void setProperties(const QVariantMap& properties) override;
|
||||||
|
@ -69,6 +69,8 @@ public:
|
||||||
return findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
return findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual SpatialParentTree* getParentTree() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void locationChanged(bool tellPhysics = true) override;
|
virtual void locationChanged(bool tellPhysics = true) override;
|
||||||
virtual void parentDeleted() override;
|
virtual void parentDeleted() override;
|
||||||
|
|
|
@ -161,33 +161,33 @@ OverlayID Overlays::addOverlay(const QString& type, const QVariant& properties)
|
||||||
Overlay::Pointer thisOverlay = nullptr;
|
Overlay::Pointer thisOverlay = nullptr;
|
||||||
|
|
||||||
if (type == ImageOverlay::TYPE) {
|
if (type == ImageOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<ImageOverlay>();
|
thisOverlay = Overlay::Pointer(new ImageOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Image3DOverlay::TYPE || type == "billboard") { // "billboard" for backwards compatibility
|
} else if (type == Image3DOverlay::TYPE || type == "billboard") { // "billboard" for backwards compatibility
|
||||||
thisOverlay = std::make_shared<Image3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Image3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == TextOverlay::TYPE) {
|
} else if (type == TextOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<TextOverlay>();
|
thisOverlay = Overlay::Pointer(new TextOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Text3DOverlay::TYPE) {
|
} else if (type == Text3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Text3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Text3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Shape3DOverlay::TYPE) {
|
} else if (type == Shape3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Shape3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Shape3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Cube3DOverlay::TYPE) {
|
} else if (type == Cube3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Cube3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Cube3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Sphere3DOverlay::TYPE) {
|
} else if (type == Sphere3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Sphere3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Sphere3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Circle3DOverlay::TYPE) {
|
} else if (type == Circle3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Circle3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Circle3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Rectangle3DOverlay::TYPE) {
|
} else if (type == Rectangle3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Rectangle3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Rectangle3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Line3DOverlay::TYPE) {
|
} else if (type == Line3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Line3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Line3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Grid3DOverlay::TYPE) {
|
} else if (type == Grid3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Grid3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Grid3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == ModelOverlay::TYPE) {
|
} else if (type == ModelOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<ModelOverlay>();
|
thisOverlay = Overlay::Pointer(new ModelOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == Web3DOverlay::TYPE) {
|
} else if (type == Web3DOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<Web3DOverlay>();
|
thisOverlay = Overlay::Pointer(new Web3DOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
} else if (type == RectangleOverlay::TYPE) {
|
} else if (type == RectangleOverlay::TYPE) {
|
||||||
thisOverlay = std::make_shared<RectangleOverlay>();
|
thisOverlay = Overlay::Pointer(new RectangleOverlay(), [](Overlay* ptr) { ptr->deleteLater(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thisOverlay) {
|
if (thisOverlay) {
|
||||||
|
@ -230,7 +230,7 @@ OverlayID Overlays::cloneOverlay(OverlayID id) {
|
||||||
Overlay::Pointer thisOverlay = getOverlay(id);
|
Overlay::Pointer thisOverlay = getOverlay(id);
|
||||||
|
|
||||||
if (thisOverlay) {
|
if (thisOverlay) {
|
||||||
OverlayID cloneId = addOverlay(Overlay::Pointer(thisOverlay->createClone()));
|
OverlayID cloneId = addOverlay(Overlay::Pointer(thisOverlay->createClone(), [](Overlay* ptr) { ptr->deleteLater(); }));
|
||||||
#if OVERLAY_PANELS
|
#if OVERLAY_PANELS
|
||||||
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(thisOverlay);
|
auto attachable = std::dynamic_pointer_cast<PanelAttachable>(thisOverlay);
|
||||||
if (attachable && attachable->getParentPanel()) {
|
if (attachable && attachable->getParentPanel()) {
|
||||||
|
|
|
@ -135,6 +135,7 @@ static const int32_t exp2Table[1 << EXP2_TABBITS][3] = {
|
||||||
|
|
||||||
static const int IEEE754_FABS_MASK = 0x7fffffff;
|
static const int IEEE754_FABS_MASK = 0x7fffffff;
|
||||||
static const int IEEE754_MANT_BITS = 23;
|
static const int IEEE754_MANT_BITS = 23;
|
||||||
|
static const int IEEE754_EXPN_BITS = 8;
|
||||||
static const int IEEE754_EXPN_BIAS = 127;
|
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
|
// split into e and x - 1.0
|
||||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
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
|
// saturate
|
||||||
if (e > 31) {
|
if (e > 31) {
|
||||||
|
@ -191,7 +192,7 @@ static inline int32_t peaklog2(float* input0, float* input1) {
|
||||||
|
|
||||||
// split into e and x - 1.0
|
// split into e and x - 1.0
|
||||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
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
|
// saturate
|
||||||
if (e > 31) {
|
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
|
// split into e and x - 1.0
|
||||||
int32_t e = IEEE754_EXPN_BIAS - (peak >> IEEE754_MANT_BITS) + LOG2_HEADROOM;
|
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
|
// saturate
|
||||||
if (e > 31) {
|
if (e > 31) {
|
||||||
|
@ -259,30 +260,30 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
|
||||||
// Count Leading Zeros
|
// Count Leading Zeros
|
||||||
// Emulates the CLZ (ARM) and LZCNT (x86) instruction
|
// 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;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
int e = 0;
|
int e = 0;
|
||||||
if (x < 0x00010000) {
|
if (u < 0x00010000) {
|
||||||
x <<= 16;
|
u <<= 16;
|
||||||
e += 16;
|
e += 16;
|
||||||
}
|
}
|
||||||
if (x < 0x01000000) {
|
if (u < 0x01000000) {
|
||||||
x <<= 8;
|
u <<= 8;
|
||||||
e += 8;
|
e += 8;
|
||||||
}
|
}
|
||||||
if (x < 0x10000000) {
|
if (u < 0x10000000) {
|
||||||
x <<= 4;
|
u <<= 4;
|
||||||
e += 4;
|
e += 4;
|
||||||
}
|
}
|
||||||
if (x < 0x40000000) {
|
if (u < 0x40000000) {
|
||||||
x <<= 2;
|
u <<= 2;
|
||||||
e += 2;
|
e += 2;
|
||||||
}
|
}
|
||||||
if (x < 0x80000000) {
|
if (u < 0x80000000) {
|
||||||
e += 1;
|
e += 1;
|
||||||
}
|
}
|
||||||
return e;
|
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
|
// Compute -log2(x) for x=[0,1] in Q31, result in Q26
|
||||||
// x = 0 returns 0x7fffffff
|
// x <= 0 returns 0x7fffffff
|
||||||
// x < 0 undefined
|
|
||||||
//
|
//
|
||||||
static inline int32_t fixlog2(int32_t x) {
|
static inline int32_t fixlog2(int32_t x) {
|
||||||
|
|
||||||
if (x == 0) {
|
if (x <= 0) {
|
||||||
return 0x7fffffff;
|
return 0x7fffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
// split into e and x - 1.0
|
// split into e and x - 1.0
|
||||||
int e = CLZ((uint32_t)x);
|
uint32_t u = (uint32_t)x;
|
||||||
x <<= e; // normalize to [0x80000000, 0xffffffff]
|
int e = CLZ(u);
|
||||||
x &= 0x7fffffff; // x - 1.0
|
u <<= e; // normalize to [0x80000000, 0xffffffff]
|
||||||
|
x = u & 0x7fffffff; // x - 1.0
|
||||||
|
|
||||||
int k = x >> (31 - LOG2_TABBITS);
|
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
|
// 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) {
|
static inline int32_t fixexp2(int32_t x) {
|
||||||
|
|
||||||
|
if (x <= 0) {
|
||||||
|
return 0x7fffffff;
|
||||||
|
}
|
||||||
|
|
||||||
// split into e and 1.0 - x
|
// split into e and 1.0 - x
|
||||||
int e = x >> LOG2_FRACBITS;
|
uint32_t u = (uint32_t)x;
|
||||||
x = ~(x << LOG2_INTBITS) & 0x7fffffff;
|
int e = u >> LOG2_FRACBITS;
|
||||||
|
x = ~(u << LOG2_INTBITS) & 0x7fffffff;
|
||||||
|
|
||||||
int k = x >> (31 - EXP2_TABBITS);
|
int k = x >> (31 - EXP2_TABBITS);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class MonoDCBlock {
|
||||||
public:
|
public:
|
||||||
void process(int32_t& x) {
|
void process(int32_t& x) {
|
||||||
|
|
||||||
x <<= 15; // scale to Q30
|
x *= (1 << 15); // scale to Q30
|
||||||
x -= _dcOffset; // remove DC
|
x -= _dcOffset; // remove DC
|
||||||
_dcOffset += x >> 13; // pole = (1.0 - 2^-13) = 0.9999
|
_dcOffset += x >> 13; // pole = (1.0 - 2^-13) = 0.9999
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ class StereoDCBlock {
|
||||||
public:
|
public:
|
||||||
void process(int32_t& x0, int32_t& x1) {
|
void process(int32_t& x0, int32_t& x1) {
|
||||||
|
|
||||||
x0 <<= 15;
|
x0 *= (1 << 15);
|
||||||
x1 <<= 15;
|
x1 *= (1 << 15);
|
||||||
|
|
||||||
x0 -= _dcOffset[0];
|
x0 -= _dcOffset[0];
|
||||||
x1 -= _dcOffset[1];
|
x1 -= _dcOffset[1];
|
||||||
|
@ -71,10 +71,10 @@ class QuadDCBlock {
|
||||||
public:
|
public:
|
||||||
void process(int32_t& x0, int32_t& x1, int32_t& x2, int32_t& x3) {
|
void process(int32_t& x0, int32_t& x1, int32_t& x2, int32_t& x3) {
|
||||||
|
|
||||||
x0 <<= 15;
|
x0 *= (1 << 15);
|
||||||
x1 <<= 15;
|
x1 *= (1 << 15);
|
||||||
x2 <<= 15;
|
x2 *= (1 << 15);
|
||||||
x3 <<= 15;
|
x3 *= (1 << 15);
|
||||||
|
|
||||||
x0 -= _dcOffset[0];
|
x0 -= _dcOffset[0];
|
||||||
x1 -= _dcOffset[1];
|
x1 -= _dcOffset[1];
|
||||||
|
@ -100,10 +100,10 @@ protected:
|
||||||
int _histogram[NHIST] = {};
|
int _histogram[NHIST] = {};
|
||||||
|
|
||||||
// peakhold
|
// peakhold
|
||||||
int32_t _holdMin = 0x7fffffff;
|
uint32_t _holdMin = 0x7fffffff;
|
||||||
int32_t _holdInc = 0x7fffffff;
|
uint32_t _holdInc = 0x7fffffff;
|
||||||
uint32_t _holdMax = 0x7fffffff;
|
uint32_t _holdMax = 0x7fffffff;
|
||||||
int32_t _holdRel = 0x7fffffff;
|
uint32_t _holdRel = 0x7fffffff;
|
||||||
int32_t _holdPeak = 0x7fffffff;
|
int32_t _holdPeak = 0x7fffffff;
|
||||||
|
|
||||||
// hysteresis
|
// hysteresis
|
||||||
|
@ -177,18 +177,23 @@ void GateImpl::setThreshold(float threshold) {
|
||||||
void GateImpl::setHold(float hold) {
|
void GateImpl::setHold(float hold) {
|
||||||
|
|
||||||
const double RELEASE = 100.0; // release = 100ms
|
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
|
// pure hold = 1 to 1000ms
|
||||||
hold = MAX(hold, 1.0f);
|
hold = MAX(hold, 1.0f);
|
||||||
hold = MIN(hold, 1000.0f);
|
hold = MIN(hold, 1000.0f);
|
||||||
|
|
||||||
|
// compute final tc
|
||||||
_holdMin = msToTc(RELEASE, _sampleRate);
|
_holdMin = msToTc(RELEASE, _sampleRate);
|
||||||
|
|
||||||
_holdInc = (int32_t)((_holdMin - 0x7fffffff) / (PROGHOLD * _sampleRate));
|
// compute tc increment, to progress from 0x7fffffff to _holdMin in PROGHOLD ms
|
||||||
_holdInc = MIN(_holdInc, -1); // prevent 0 on long releases
|
double progSamples = PROGHOLD/1000.0 * _sampleRate;
|
||||||
|
_holdInc = (uint32_t)((0x7fffffff - _holdMin) / progSamples);
|
||||||
_holdMax = 0x7fffffff - (uint32_t)(_holdInc * (double)hold/1000.0 * _sampleRate);
|
_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
|
// smooth threshold update
|
||||||
_threshAdapt = threshold + MULQ31((_threshAdapt - threshold), tcThreshold);
|
_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) progressive hold
|
||||||
// (_holdRel = _holdMin) release
|
// (_holdRel = _holdMin) release
|
||||||
|
|
||||||
_holdRel += _holdInc; // update progressive hold
|
_holdRel -= _holdInc; // update progressive hold
|
||||||
_holdRel = MAX((uint32_t)_holdRel, (uint32_t)_holdMin); // saturate at final value
|
int32_t tc = MIN(MAX(_holdRel, _holdMin), 0x7fffffff); // saturate to [_holdMin, 0x7fffffff]
|
||||||
|
|
||||||
int32_t tc = MIN((uint32_t)_holdRel, 0x7fffffff);
|
|
||||||
peak += MULQ31((_holdPeak - peak), tc); // apply release
|
peak += MULQ31((_holdPeak - peak), tc); // apply release
|
||||||
|
|
||||||
} else {
|
} 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.
|
// _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;
|
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) :
|
InboundAudioStream::InboundAudioStream(int numChannels, int numFrames, int numBlocks, int numStaticJitterBlocks) :
|
||||||
_ringBuffer(numChannels * numFrames, numBlocks),
|
_ringBuffer(numChannels * numFrames, numBlocks),
|
||||||
_numChannels(numChannels),
|
_numChannels(numChannels),
|
||||||
|
@ -153,6 +157,7 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
||||||
// If we recieved a SilentAudioFrame from our sender, we might want to drop
|
// 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.
|
// some of the samples in order to catch up to our desired jitter buffer size.
|
||||||
writeDroppableSilentFrames(networkFrames);
|
writeDroppableSilentFrames(networkFrames);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// note: PCM and no codec are identical
|
// note: PCM and no codec are identical
|
||||||
bool selectedPCM = _selectedCodecName == "pcm" || _selectedCodecName == "";
|
bool selectedPCM = _selectedCodecName == "pcm" || _selectedCodecName == "";
|
||||||
|
@ -160,20 +165,33 @@ int InboundAudioStream::parseData(ReceivedMessage& message) {
|
||||||
if (codecInPacket == _selectedCodecName || (packetPCM && selectedPCM)) {
|
if (codecInPacket == _selectedCodecName || (packetPCM && selectedPCM)) {
|
||||||
auto afterProperties = message.readWithoutCopy(message.getBytesLeftToRead());
|
auto afterProperties = message.readWithoutCopy(message.getBytesLeftToRead());
|
||||||
parseAudioData(message.getType(), afterProperties);
|
parseAudioData(message.getType(), afterProperties);
|
||||||
|
_mismatchedAudioCodecCount = 0;
|
||||||
|
|
||||||
} else {
|
} 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,
|
if (packetPCM) {
|
||||||
// we need to let the codec know that we don't have data for it, this will
|
// If there are PCM packets in-flight after the codec is changed, use them.
|
||||||
// allow the codec to interpolate missing data and produce a fade to silence.
|
auto afterProperties = message.readWithoutCopy(message.getBytesLeftToRead());
|
||||||
lostAudioData(1);
|
_ringBuffer.writeData(afterProperties.data(), afterProperties.size());
|
||||||
|
} else {
|
||||||
// inform others of the mismatch
|
// Since the data in the stream is using a codec that we aren't prepared for,
|
||||||
auto sendingNode = DependencyManager::get<NodeList>()->nodeWithUUID(message.getSourceID());
|
// we need to let the codec know that we don't have data for it, this will
|
||||||
if (sendingNode) {
|
// allow the codec to interpolate missing data and produce a fade to silence.
|
||||||
emit mismatchedAudioCodec(sendingNode, _selectedCodecName, codecInPacket);
|
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;
|
break;
|
||||||
|
|
|
@ -186,6 +186,7 @@ protected:
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
Decoder* _decoder { nullptr };
|
Decoder* _decoder { nullptr };
|
||||||
|
int _mismatchedAudioCodecCount { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
float calculateRepeatedFrameFadeFactor(int indexOfRepeat);
|
float calculateRepeatedFrameFadeFactor(int indexOfRepeat);
|
||||||
|
|
|
@ -994,10 +994,12 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
|
||||||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||||
return glmExtractRotation(finalMat);
|
return glmExtractRotation(finalMat);
|
||||||
}
|
}
|
||||||
|
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
|
||||||
case CONTROLLER_LEFTHAND_INDEX: {
|
case CONTROLLER_LEFTHAND_INDEX: {
|
||||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||||
return controllerLeftHandTransform.getRotation();
|
return controllerLeftHandTransform.getRotation();
|
||||||
}
|
}
|
||||||
|
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
|
||||||
case CONTROLLER_RIGHTHAND_INDEX: {
|
case CONTROLLER_RIGHTHAND_INDEX: {
|
||||||
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
||||||
return controllerRightHandTransform.getRotation();
|
return controllerRightHandTransform.getRotation();
|
||||||
|
@ -1032,10 +1034,12 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
||||||
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix;
|
||||||
return extractTranslation(finalMat);
|
return extractTranslation(finalMat);
|
||||||
}
|
}
|
||||||
|
case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX:
|
||||||
case CONTROLLER_LEFTHAND_INDEX: {
|
case CONTROLLER_LEFTHAND_INDEX: {
|
||||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||||
return controllerLeftHandTransform.getTranslation();
|
return controllerLeftHandTransform.getTranslation();
|
||||||
}
|
}
|
||||||
|
case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX:
|
||||||
case CONTROLLER_RIGHTHAND_INDEX: {
|
case CONTROLLER_RIGHTHAND_INDEX: {
|
||||||
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix());
|
||||||
return controllerRightHandTransform.getTranslation();
|
return controllerRightHandTransform.getTranslation();
|
||||||
|
|
|
@ -594,6 +594,10 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
|
||||||
QString fbxTextureFileName { textureChild.properties.at(0).toByteArray() };
|
QString fbxTextureFileName { textureChild.properties.at(0).toByteArray() };
|
||||||
QFileInfo textureFileInfo { fbxTextureFileName.replace("\\", "/") };
|
QFileInfo textureFileInfo { fbxTextureFileName.replace("\\", "/") };
|
||||||
|
|
||||||
|
if (hasErrors()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (textureFileInfo.suffix() == BAKED_TEXTURE_EXT.mid(1)) {
|
if (textureFileInfo.suffix() == BAKED_TEXTURE_EXT.mid(1)) {
|
||||||
// re-baking an FBX that already references baked textures is a fail
|
// re-baking an FBX that already references baked textures is a fail
|
||||||
// so we add an error and return from here
|
// so we add an error and return from here
|
||||||
|
@ -602,6 +606,11 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!TextureBaker::getSupportedFormats().contains(textureFileInfo.suffix())) {
|
||||||
|
// this is a texture format we don't bake, skip it
|
||||||
|
handleWarning(fbxTextureFileName + " is not a bakeable texture format");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure this texture points to something and isn't one we've already re-mapped
|
// make sure this texture points to something and isn't one we've already re-mapped
|
||||||
if (!textureFileInfo.filePath().isEmpty()) {
|
if (!textureFileInfo.filePath().isEmpty()) {
|
||||||
|
|
247
libraries/baking/src/JSBaker.cpp
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
//
|
||||||
|
// JSBaker.cpp
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 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 <PathUtils.h>
|
||||||
|
|
||||||
|
#include "JSBaker.h"
|
||||||
|
#include "Baker.h"
|
||||||
|
|
||||||
|
const int ASCII_CHARACTERS_UPPER_LIMIT = 126;
|
||||||
|
|
||||||
|
JSBaker::JSBaker(const QUrl& jsURL, const QString& bakedOutputDir) :
|
||||||
|
_jsURL(jsURL),
|
||||||
|
_bakedOutputDir(bakedOutputDir)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSBaker::bake() {
|
||||||
|
qCDebug(js_baking) << "JS Baker " << _jsURL << "bake starting";
|
||||||
|
|
||||||
|
// Import file to start baking
|
||||||
|
QFile jsFile(_jsURL.toLocalFile());
|
||||||
|
if (!jsFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
handleError("Error opening " + _jsURL.fileName() + " for reading");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file into an array
|
||||||
|
QByteArray inputJS = jsFile.readAll();
|
||||||
|
QByteArray outputJS;
|
||||||
|
|
||||||
|
// Call baking on inputJS and store result in outputJS
|
||||||
|
bool success = bakeJS(inputJS, outputJS);
|
||||||
|
if (!success) {
|
||||||
|
qCDebug(js_baking) << "Bake Failed";
|
||||||
|
handleError("Unterminated multi-line comment");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bake Successful. Export the file
|
||||||
|
auto fileName = _jsURL.fileName();
|
||||||
|
auto baseName = fileName.left(fileName.lastIndexOf('.'));
|
||||||
|
auto bakedFilename = baseName + BAKED_JS_EXTENSION;
|
||||||
|
|
||||||
|
_bakedJSFilePath = _bakedOutputDir + "/" + bakedFilename;
|
||||||
|
|
||||||
|
QFile bakedFile;
|
||||||
|
bakedFile.setFileName(_bakedJSFilePath);
|
||||||
|
if (!bakedFile.open(QIODevice::WriteOnly)) {
|
||||||
|
handleError("Error opening " + _bakedJSFilePath + " for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bakedFile.write(outputJS);
|
||||||
|
|
||||||
|
// Export successful
|
||||||
|
_outputFiles.push_back(_bakedJSFilePath);
|
||||||
|
qCDebug(js_baking) << "Exported" << _jsURL << "minified to" << _bakedJSFilePath;
|
||||||
|
|
||||||
|
// emit signal to indicate the JS baking is finished
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::bakeJS(const QByteArray& inputFile, QByteArray& outputFile) {
|
||||||
|
// Read from inputFile and write to outputFile per character
|
||||||
|
QTextStream in(inputFile, QIODevice::ReadOnly);
|
||||||
|
QTextStream out(outputFile, QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
// Algorithm requires the knowledge of previous and next character for each character read
|
||||||
|
QChar currentCharacter;
|
||||||
|
QChar nextCharacter;
|
||||||
|
// Initialize previousCharacter with new line
|
||||||
|
QChar previousCharacter = '\n';
|
||||||
|
|
||||||
|
in >> currentCharacter;
|
||||||
|
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
|
||||||
|
if (currentCharacter == '\r') {
|
||||||
|
out << '\n';
|
||||||
|
} else if (currentCharacter == '/') {
|
||||||
|
// Check if single line comment i.e. //
|
||||||
|
if (nextCharacter == '/') {
|
||||||
|
handleSingleLineComments(in);
|
||||||
|
|
||||||
|
//Start fresh after handling comments
|
||||||
|
previousCharacter = '\n';
|
||||||
|
in >> currentCharacter;
|
||||||
|
continue;
|
||||||
|
} else if (nextCharacter == '*') {
|
||||||
|
// Check if multi line comment i.e. /*
|
||||||
|
bool success = handleMultiLineComments(in);
|
||||||
|
if (!success) {
|
||||||
|
// Errors present return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//Start fresh after handling comments
|
||||||
|
previousCharacter = '\n';
|
||||||
|
in >> currentCharacter;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// If '/' is not followed by '/' or '*' print '/'
|
||||||
|
out << currentCharacter;
|
||||||
|
}
|
||||||
|
} else if (isSpaceOrTab(currentCharacter)) {
|
||||||
|
// Check if white space or tab
|
||||||
|
|
||||||
|
// Skip multiple spaces or tabs
|
||||||
|
while (isSpaceOrTab(nextCharacter)) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
if (nextCharacter == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if space can be omitted
|
||||||
|
if (!canOmitSpace(previousCharacter, nextCharacter)) {
|
||||||
|
out << ' ';
|
||||||
|
}
|
||||||
|
} else if (currentCharacter == '\n') {
|
||||||
|
// Check if new line
|
||||||
|
|
||||||
|
//Skip multiple new lines
|
||||||
|
//Skip new line followed by space or tab
|
||||||
|
while (nextCharacter == '\n' || isSpaceOrTab(nextCharacter)) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if new line can be omitted
|
||||||
|
if (!canOmitNewLine(previousCharacter, nextCharacter)) {
|
||||||
|
out << '\n';
|
||||||
|
}
|
||||||
|
} else if (isQuote(currentCharacter)) {
|
||||||
|
// Print the current quote and nextCharacter as is
|
||||||
|
out << currentCharacter;
|
||||||
|
out << nextCharacter;
|
||||||
|
|
||||||
|
// Store the type of quote we are processing
|
||||||
|
QChar quote = currentCharacter;
|
||||||
|
|
||||||
|
// Don't modify the quoted strings
|
||||||
|
while (nextCharacter != quote) {
|
||||||
|
in >> nextCharacter;
|
||||||
|
out << nextCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start fresh after handling quoted strings
|
||||||
|
previousCharacter = nextCharacter;
|
||||||
|
in >> currentCharacter;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// In all other cases write the currentCharacter to outputFile
|
||||||
|
out << currentCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousCharacter = currentCharacter;
|
||||||
|
currentCharacter = nextCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//write currentCharacter to output file when nextCharacter reaches EOF
|
||||||
|
if (currentCharacter != '\n') {
|
||||||
|
out << currentCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successful bake. Return true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JSBaker::handleSingleLineComments(QTextStream& in) {
|
||||||
|
QChar character;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
in >> character;
|
||||||
|
if (character == '\n') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::handleMultiLineComments(QTextStream& in) {
|
||||||
|
QChar character;
|
||||||
|
while (!in.atEnd()) {
|
||||||
|
in >> character;
|
||||||
|
if (character == '*') {
|
||||||
|
if (in.read(1) == '/') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::canOmitSpace(QChar previousCharacter, QChar nextCharacter) {
|
||||||
|
return(!((isAlphanum(previousCharacter) || isNonAscii(previousCharacter) || isSpecialCharacter(previousCharacter)) &&
|
||||||
|
(isAlphanum(nextCharacter) || isNonAscii(nextCharacter) || isSpecialCharacter(nextCharacter)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::canOmitNewLine(QChar previousCharacter, QChar nextCharacter) {
|
||||||
|
return (!((isAlphanum(previousCharacter) || isNonAscii(previousCharacter) || isSpecialCharacterPrevious(previousCharacter)) &&
|
||||||
|
(isAlphanum(nextCharacter) || isNonAscii(nextCharacter) || isSpecialCharacterNext(nextCharacter)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if character is alphabet, number or one of the following: '_', '$', '\\' or a non-ASCII character
|
||||||
|
bool JSBaker::isAlphanum(QChar c) {
|
||||||
|
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
|
||||||
|
|| c == '_' || c == '$' || c == '\\' || c > ASCII_CHARACTERS_UPPER_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSBaker::isNonAscii(QChar c) {
|
||||||
|
return ((int)c.toLatin1() > ASCII_CHARACTERS_UPPER_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous and next characters are special characters, don't omit space
|
||||||
|
bool JSBaker::isSpecialCharacter(QChar c) {
|
||||||
|
return (c == '\'' || c == '$' || c == '_' || c == '/' || c== '+' || c == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If previous character is a special character, maybe don't omit new line (depends on next character as well)
|
||||||
|
bool JSBaker::isSpecialCharacterPrevious(QChar c) {
|
||||||
|
return (c == '\'' || c == '$' || c == '_' || c == '}' || c == ']' || c == ')' || c == '+' || c == '-'
|
||||||
|
|| c == '"' || c == "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If next character is a special character, maybe don't omit new line (depends on previous character as well)
|
||||||
|
bool JSBaker::isSpecialCharacterNext(QChar c) {
|
||||||
|
return (c == '\'' || c == '$' || c == '_' || c == '{' || c == '[' || c == '(' || c == '+' || c == '-');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if white space or tab
|
||||||
|
bool JSBaker::isSpaceOrTab(QChar c) {
|
||||||
|
return (c == ' ' || c == '\t');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check If the currentCharacter is " or ' or `
|
||||||
|
bool JSBaker::isQuote(QChar c) {
|
||||||
|
return (c == '"' || c == "'" || c == '`');
|
||||||
|
}
|
49
libraries/baking/src/JSBaker.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// JSBaker.h
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 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_JSBaker_h
|
||||||
|
#define hifi_JSBaker_h
|
||||||
|
|
||||||
|
#include "Baker.h"
|
||||||
|
#include "JSBakingLoggingCategory.h"
|
||||||
|
|
||||||
|
static const QString BAKED_JS_EXTENSION = ".baked.js";
|
||||||
|
|
||||||
|
class JSBaker : public Baker {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
JSBaker(const QUrl& jsURL, const QString& bakedOutputDir);
|
||||||
|
static bool bakeJS(const QByteArray& inputFile, QByteArray& outputFile);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void bake() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl _jsURL;
|
||||||
|
QString _bakedOutputDir;
|
||||||
|
QString _bakedJSFilePath;
|
||||||
|
|
||||||
|
static void handleSingleLineComments(QTextStream& in);
|
||||||
|
static bool handleMultiLineComments(QTextStream& in);
|
||||||
|
|
||||||
|
static bool canOmitSpace(QChar previousCharacter, QChar nextCharacter);
|
||||||
|
static bool canOmitNewLine(QChar previousCharacter, QChar nextCharacter);
|
||||||
|
|
||||||
|
static bool isAlphanum(QChar c);
|
||||||
|
static bool isNonAscii(QChar c);
|
||||||
|
static bool isSpecialCharacter(QChar c);
|
||||||
|
static bool isSpecialCharacterPrevious(QChar c);
|
||||||
|
static bool isSpecialCharacterNext(QChar c);
|
||||||
|
static bool isSpaceOrTab(QChar c);
|
||||||
|
static bool isQuote(QChar c);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !hifi_JSBaker_h
|
14
libraries/baking/src/JSBakingLoggingCategory.cpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
//
|
||||||
|
// JSBakingLoggingCategory.cpp
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 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 "JSBakingLoggingCategory.h"
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(js_baking, "hifi.JS-baking");
|
19
libraries/baking/src/JSBakingLoggingCategory.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// JSBakingLoggingCategory.h
|
||||||
|
// libraries/baking/src
|
||||||
|
//
|
||||||
|
// Created by Utkarsh Gautam on 9/18/17.
|
||||||
|
// Copyright 2017 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_JSBakingLoggingCategory_h
|
||||||
|
#define hifi_JSBakingLoggingCategory_h
|
||||||
|
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(js_baking)
|
||||||
|
|
||||||
|
#endif // hifi_ModelBakingLoggingCategory_h
|
|
@ -237,19 +237,7 @@ void EntityTreeRenderer::update(bool simulate) {
|
||||||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
tree->update(simulate);
|
tree->update(simulate);
|
||||||
|
|
||||||
if (simulate) {
|
// Update the rendereable entities as needed
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer sceneTimer("scene");
|
PerformanceTimer sceneTimer("scene");
|
||||||
auto scene = _viewState->getMain3DScene();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,8 @@ bool ModelEntityWrapper::isModelLoaded() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity{ new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()) };
|
EntityItemPointer entity(new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()),
|
||||||
|
[](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity)
|
||||||
polylineFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, position));
|
polylineFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, position));
|
||||||
polylineFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, normal));
|
polylineFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), offsetof(Vertex, normal));
|
||||||
polylineFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), offsetof(Vertex, uv));
|
polylineFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV), offsetof(Vertex, uv));
|
||||||
|
polylineFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB), offsetof(Vertex, color));
|
||||||
});
|
});
|
||||||
|
|
||||||
PolyLineUniforms uniforms;
|
PolyLineUniforms uniforms;
|
||||||
|
@ -116,7 +117,8 @@ bool PolyLineEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP
|
||||||
entity->pointsChanged() ||
|
entity->pointsChanged() ||
|
||||||
entity->strokeWidthsChanged() ||
|
entity->strokeWidthsChanged() ||
|
||||||
entity->normalsChanged() ||
|
entity->normalsChanged() ||
|
||||||
entity->texturesChanged()
|
entity->texturesChanged() ||
|
||||||
|
entity->strokeColorsChanged()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,9 +131,11 @@ void PolyLineEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer&
|
||||||
if (!textures.isEmpty()) {
|
if (!textures.isEmpty()) {
|
||||||
entityTextures = QUrl(textures);
|
entityTextures = QUrl(textures);
|
||||||
}
|
}
|
||||||
|
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_texture || _texture->getURL() != entityTextures) {
|
|
||||||
|
if (!_texture) {
|
||||||
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
|
_texture = DependencyManager::get<TextureCache>()->getTexture(entityTextures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,6 +147,10 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
auto pointsChanged = entity->pointsChanged();
|
auto pointsChanged = entity->pointsChanged();
|
||||||
auto strokeWidthsChanged = entity->strokeWidthsChanged();
|
auto strokeWidthsChanged = entity->strokeWidthsChanged();
|
||||||
auto normalsChanged = entity->normalsChanged();
|
auto normalsChanged = entity->normalsChanged();
|
||||||
|
auto strokeColorsChanged = entity->strokeColorsChanged();
|
||||||
|
|
||||||
|
|
||||||
|
bool isUVModeStretch = entity->getIsUVModeStretch();
|
||||||
entity->resetPolyLineChanged();
|
entity->resetPolyLineChanged();
|
||||||
|
|
||||||
_polylineTransform = Transform();
|
_polylineTransform = Transform();
|
||||||
|
@ -158,10 +166,14 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo
|
||||||
if (normalsChanged) {
|
if (normalsChanged) {
|
||||||
_lastNormals = entity->getNormals();
|
_lastNormals = entity->getNormals();
|
||||||
}
|
}
|
||||||
if (pointsChanged || strokeWidthsChanged || normalsChanged) {
|
if (strokeColorsChanged) {
|
||||||
|
_lastStrokeColors = entity->getStrokeColors();
|
||||||
|
_lastStrokeColors = _lastNormals.size() == _lastStrokeColors.size() ? _lastStrokeColors : QVector<glm::vec3>({ toGlm(entity->getXColor()) });
|
||||||
|
}
|
||||||
|
if (pointsChanged || strokeWidthsChanged || normalsChanged || strokeColorsChanged) {
|
||||||
_empty = std::min(_lastPoints.size(), std::min(_lastNormals.size(), _lastStrokeWidths.size())) < 2;
|
_empty = std::min(_lastPoints.size(), std::min(_lastNormals.size(), _lastStrokeWidths.size())) < 2;
|
||||||
if (!_empty) {
|
if (!_empty) {
|
||||||
updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths));
|
updateGeometry(updateVertices(_lastPoints, _lastNormals, _lastStrokeWidths, _lastStrokeColors, isUVModeStretch, _textureAspectRatio));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,7 +187,12 @@ void PolyLineEntityRenderer::updateGeometry(const std::vector<Vertex>& vertices)
|
||||||
_verticesBuffer->setSubData(0, vertices);
|
_verticesBuffer->setSubData(0, vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths) {
|
std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertices(const QVector<glm::vec3>& points,
|
||||||
|
const QVector<glm::vec3>& normals,
|
||||||
|
const QVector<float>& strokeWidths,
|
||||||
|
const QVector<glm::vec3>& strokeColors,
|
||||||
|
const bool isUVModeStretch,
|
||||||
|
const float textureAspectRatio) {
|
||||||
// Calculate the minimum vector size out of normals, points, and stroke widths
|
// Calculate the minimum vector size out of normals, points, and stroke widths
|
||||||
int size = std::min(points.size(), std::min(normals.size(), strokeWidths.size()));
|
int size = std::min(points.size(), std::min(normals.size(), strokeWidths.size()));
|
||||||
|
|
||||||
|
@ -190,10 +207,52 @@ std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertic
|
||||||
float uCoord = 0.0f;
|
float uCoord = 0.0f;
|
||||||
int finalIndex = size - 1;
|
int finalIndex = size - 1;
|
||||||
glm::vec3 binormal;
|
glm::vec3 binormal;
|
||||||
|
float accumulatedDistance = 0.0f;
|
||||||
|
float distanceToLastPoint = 0.0f;
|
||||||
|
float accumulatedStrokeWidth = 0.0f;
|
||||||
|
float strokeWidth = 0.0f;
|
||||||
|
bool doesStrokeWidthVary = false;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 1; i < strokeWidths.size(); i++) {
|
||||||
|
if (strokeWidths[i] != strokeWidths[i - 1]) {
|
||||||
|
doesStrokeWidthVary = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i <= finalIndex; i++) {
|
for (int i = 0; i <= finalIndex; i++) {
|
||||||
const float& width = strokeWidths.at(i);
|
const float& width = strokeWidths.at(i);
|
||||||
const auto& point = points.at(i);
|
const auto& point = points.at(i);
|
||||||
const auto& normal = normals.at(i);
|
const auto& normal = normals.at(i);
|
||||||
|
const auto& color = strokeColors.size() == normals.size() ? strokeColors.at(i) : strokeColors.at(0);
|
||||||
|
int vertexIndex = i * 2;
|
||||||
|
|
||||||
|
|
||||||
|
if (!isUVModeStretch && i >= 1) {
|
||||||
|
distanceToLastPoint = glm::distance(points.at(i), points.at(i - 1));
|
||||||
|
accumulatedDistance += distanceToLastPoint;
|
||||||
|
strokeWidth = 2 * strokeWidths[i];
|
||||||
|
|
||||||
|
if (doesStrokeWidthVary) {
|
||||||
|
//If the stroke varies along the line the texture will stretch more or less depending on the speed
|
||||||
|
//because it looks better than using the same method as below
|
||||||
|
accumulatedStrokeWidth += strokeWidth;
|
||||||
|
float increaseValue = 1;
|
||||||
|
if (accumulatedStrokeWidth != 0) {
|
||||||
|
float newUcoord = glm::ceil(((1.0f / textureAspectRatio) * accumulatedDistance) / (accumulatedStrokeWidth / i));
|
||||||
|
increaseValue = newUcoord - uCoord;
|
||||||
|
}
|
||||||
|
|
||||||
|
increaseValue = increaseValue > 0 ? increaseValue : 1;
|
||||||
|
uCoord += increaseValue;
|
||||||
|
} else {
|
||||||
|
//If the stroke width is constant then the textures should keep the aspect ratio along the line
|
||||||
|
uCoord = ((1.0f / textureAspectRatio) * accumulatedDistance) / strokeWidth;
|
||||||
|
}
|
||||||
|
} else if (vertexIndex >= 2) {
|
||||||
|
uCoord += uCoordInc;
|
||||||
|
}
|
||||||
|
|
||||||
// For last point we can assume binormals are the same since it represents the last two vertices of quad
|
// For last point we can assume binormals are the same since it represents the last two vertices of quad
|
||||||
if (i < finalIndex) {
|
if (i < finalIndex) {
|
||||||
|
@ -206,11 +265,10 @@ std::vector<PolyLineEntityRenderer::Vertex> PolyLineEntityRenderer::updateVertic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto v1 = point + binormal;
|
const auto v1 = points.at(i) + binormal;
|
||||||
const auto v2 = point - binormal;
|
const auto v2 = points.at(i) - binormal;
|
||||||
vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f));
|
vertices.emplace_back(v1, normal, vec2(uCoord, 0.0f), color);
|
||||||
vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f));
|
vertices.emplace_back(v2, normal, vec2(uCoord, 1.0f), color);
|
||||||
uCoord += uCoordInc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return vertices;
|
return vertices;
|
||||||
|
@ -235,6 +293,12 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
batch.setResourceTexture(PAINTSTROKE_TEXTURE_SLOT, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float textureWidth = (float)_texture->getOriginalWidth();
|
||||||
|
float textureHeight = (float)_texture->getOriginalHeight();
|
||||||
|
if (textureWidth != 0 && textureHeight != 0) {
|
||||||
|
_textureAspectRatio = textureWidth / textureHeight;
|
||||||
|
}
|
||||||
|
|
||||||
batch.setInputFormat(polylineFormat);
|
batch.setInputFormat(polylineFormat);
|
||||||
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
|
batch.setInputBuffer(0, _verticesBuffer, 0, sizeof(Vertex));
|
||||||
|
|
||||||
|
@ -247,4 +311,4 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
batch.draw(gpu::TRIANGLE_STRIP, _numVertices, 0);
|
||||||
}
|
}
|
|
@ -27,7 +27,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
|
||||||
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
|
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene,
|
||||||
|
Transaction& transaction,
|
||||||
|
const TypedEntityPointer& entity) override;
|
||||||
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
|
||||||
|
|
||||||
virtual ItemKey getKey() override;
|
virtual ItemKey getKey() override;
|
||||||
|
@ -38,24 +40,37 @@ protected:
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
Vertex() {}
|
Vertex() {}
|
||||||
Vertex(const vec3& position, const vec3& normal, const vec2& uv) : position(position), normal(normal), uv(uv) {}
|
Vertex(const vec3& position, const vec3& normal, const vec2& uv, const vec3& color) : position(position),
|
||||||
|
normal(normal),
|
||||||
|
uv(uv),
|
||||||
|
color(color) {}
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec2 uv;
|
vec2 uv;
|
||||||
|
vec3 color;
|
||||||
};
|
};
|
||||||
|
|
||||||
void updateGeometry(const std::vector<Vertex>& vertices);
|
void updateGeometry(const std::vector<Vertex>& vertices);
|
||||||
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points, const QVector<glm::vec3>& normals, const QVector<float>& strokeWidths);
|
static std::vector<Vertex> updateVertices(const QVector<glm::vec3>& points,
|
||||||
|
const QVector<glm::vec3>& normals,
|
||||||
|
const QVector<float>& strokeWidths,
|
||||||
|
const QVector<glm::vec3>& strokeColors,
|
||||||
|
const bool isUVModeStretch,
|
||||||
|
const float textureAspectRatio);
|
||||||
|
|
||||||
Transform _polylineTransform;
|
Transform _polylineTransform;
|
||||||
QVector<glm::vec3> _lastPoints;
|
QVector<glm::vec3> _lastPoints;
|
||||||
QVector<glm::vec3> _lastNormals;
|
QVector<glm::vec3> _lastNormals;
|
||||||
|
QVector<glm::vec3> _lastStrokeColors;
|
||||||
QVector<float> _lastStrokeWidths;
|
QVector<float> _lastStrokeWidths;
|
||||||
gpu::BufferPointer _verticesBuffer;
|
gpu::BufferPointer _verticesBuffer;
|
||||||
gpu::BufferView _uniformBuffer;
|
gpu::BufferView _uniformBuffer;
|
||||||
|
|
||||||
uint32_t _numVertices { 0 };
|
uint32_t _numVertices { 0 };
|
||||||
bool _empty{ true };
|
bool _empty{ true };
|
||||||
NetworkTexturePointer _texture;
|
NetworkTexturePointer _texture;
|
||||||
|
float _textureAspectRatio { 1.0f };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // namespace
|
} } // namespace
|
||||||
|
|
|
@ -138,7 +138,7 @@ void loop3(const T& start, const T& end, F f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderablePolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
std::shared_ptr<RenderablePolyVoxEntityItem> entity{ new RenderablePolyVoxEntityItem(entityID) };
|
std::shared_ptr<RenderablePolyVoxEntityItem> entity(new RenderablePolyVoxEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
entity->initializePolyVox();
|
entity->initializePolyVox();
|
||||||
return entity;
|
return entity;
|
||||||
|
|
|
@ -52,6 +52,12 @@ void ZoneEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity
|
||||||
_backgroundStage->removeBackground(_backgroundIndex);
|
_backgroundStage->removeBackground(_backgroundIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_hazeStage) {
|
||||||
|
if (!HazeStage::isIndexInvalid(_hazeIndex)) {
|
||||||
|
_hazeStage->removeHaze(_hazeIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
||||||
|
@ -95,6 +101,11 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
||||||
assert(_backgroundStage);
|
assert(_backgroundStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_hazeStage) {
|
||||||
|
_hazeStage = args->_scene->getStage<HazeStage>();
|
||||||
|
assert(_hazeStage);
|
||||||
|
}
|
||||||
|
|
||||||
{ // Sun
|
{ // Sun
|
||||||
// Need an update ?
|
// Need an update ?
|
||||||
if (_needSunUpdate) {
|
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) {
|
if (_visible) {
|
||||||
// FInally, push the light visible in the frame
|
// FInally, push the light visible in the frame
|
||||||
// THe directional key light for sure
|
// THe directional key light for sure
|
||||||
|
@ -150,6 +170,11 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
|
||||||
if (_backgroundMode != BACKGROUND_MODE_INHERIT) {
|
if (_backgroundMode != BACKGROUND_MODE_INHERIT) {
|
||||||
_backgroundStage->_currentFrame.pushBackground(_backgroundIndex);
|
_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 sunChanged = entity->keyLightPropertiesChanged();
|
||||||
bool backgroundChanged = entity->backgroundPropertiesChanged();
|
bool backgroundChanged = entity->backgroundPropertiesChanged();
|
||||||
bool skyboxChanged = entity->skyboxPropertiesChanged();
|
bool skyboxChanged = entity->skyboxPropertiesChanged();
|
||||||
|
bool hazeChanged = entity->hazePropertiesChanged();
|
||||||
|
|
||||||
entity->resetRenderingPropertiesChanged();
|
entity->resetRenderingPropertiesChanged();
|
||||||
_lastPosition = entity->getPosition();
|
_lastPosition = entity->getPosition();
|
||||||
_lastRotation = entity->getRotation();
|
_lastRotation = entity->getRotation();
|
||||||
_lastDimensions = entity->getDimensions();
|
_lastDimensions = entity->getDimensions();
|
||||||
|
|
||||||
_keyLightProperties = entity->getKeyLightProperties();
|
_keyLightProperties = entity->getKeyLightProperties();
|
||||||
_stageProperties = entity->getStageProperties();
|
|
||||||
_skyboxProperties = entity->getSkyboxProperties();
|
_skyboxProperties = entity->getSkyboxProperties();
|
||||||
|
_hazeProperties = entity->getHazeProperties();
|
||||||
|
_stageProperties = entity->getStageProperties();
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) {
|
if (_lastShapeURL != _typedEntity->getCompoundShapeURL()) {
|
||||||
|
@ -209,9 +236,14 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
||||||
if (sunChanged || skyboxChanged) {
|
if (sunChanged || skyboxChanged) {
|
||||||
updateKeyAmbientFromEntity();
|
updateKeyAmbientFromEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backgroundChanged || skyboxChanged) {
|
if (backgroundChanged || skyboxChanged) {
|
||||||
updateKeyBackgroundFromEntity(entity);
|
updateKeyBackgroundFromEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hazeChanged) {
|
||||||
|
updateHazeFromEntity(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||||
|
@ -228,6 +260,7 @@ ItemKey ZoneEntityRenderer::getKey() {
|
||||||
bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
|
||||||
if (entity->keyLightPropertiesChanged() ||
|
if (entity->keyLightPropertiesChanged() ||
|
||||||
entity->backgroundPropertiesChanged() ||
|
entity->backgroundPropertiesChanged() ||
|
||||||
|
entity->hazePropertiesChanged() ||
|
||||||
entity->skyboxPropertiesChanged()) {
|
entity->skyboxPropertiesChanged()) {
|
||||||
return true;
|
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) {
|
void ZoneEntityRenderer::updateKeyBackgroundFromEntity(const TypedEntityPointer& entity) {
|
||||||
editBackground();
|
editBackground();
|
||||||
setBackgroundMode(entity->getBackgroundMode());
|
setBackgroundMode(entity->getBackgroundMode());
|
||||||
|
@ -408,6 +471,10 @@ void ZoneEntityRenderer::setBackgroundMode(BackgroundMode mode) {
|
||||||
_backgroundMode = mode;
|
_backgroundMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneEntityRenderer::setHazeMode(ComponentMode mode) {
|
||||||
|
_hazeMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
void ZoneEntityRenderer::setSkyboxColor(const glm::vec3& color) {
|
void ZoneEntityRenderer::setSkyboxColor(const glm::vec3& color) {
|
||||||
editSkybox()->setColor(color);
|
editSkybox()->setColor(color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,15 @@
|
||||||
|
|
||||||
#include <ZoneEntityItem.h>
|
#include <ZoneEntityItem.h>
|
||||||
#include <model/Skybox.h>
|
#include <model/Skybox.h>
|
||||||
|
#include <model/Haze.h>
|
||||||
#include <model/Stage.h>
|
#include <model/Stage.h>
|
||||||
#include <LightStage.h>
|
#include <LightStage.h>
|
||||||
#include <BackgroundStage.h>
|
#include <BackgroundStage.h>
|
||||||
|
#include <HazeStage.h>
|
||||||
#include <TextureCache.h>
|
#include <TextureCache.h>
|
||||||
#include "RenderableEntityItem.h"
|
#include "RenderableEntityItem.h"
|
||||||
|
#include <ComponentMode.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#include <Model.h>
|
#include <Model.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,12 +48,14 @@ private:
|
||||||
void updateKeyZoneItemFromEntity();
|
void updateKeyZoneItemFromEntity();
|
||||||
void updateKeySunFromEntity();
|
void updateKeySunFromEntity();
|
||||||
void updateKeyAmbientFromEntity();
|
void updateKeyAmbientFromEntity();
|
||||||
|
void updateHazeFromEntity(const TypedEntityPointer& entity);
|
||||||
void updateKeyBackgroundFromEntity(const TypedEntityPointer& entity);
|
void updateKeyBackgroundFromEntity(const TypedEntityPointer& entity);
|
||||||
void updateAmbientMap();
|
void updateAmbientMap();
|
||||||
void updateSkyboxMap();
|
void updateSkyboxMap();
|
||||||
void setAmbientURL(const QString& ambientUrl);
|
void setAmbientURL(const QString& ambientUrl);
|
||||||
void setSkyboxURL(const QString& skyboxUrl);
|
void setSkyboxURL(const QString& skyboxUrl);
|
||||||
void setBackgroundMode(BackgroundMode mode);
|
void setBackgroundMode(BackgroundMode mode);
|
||||||
|
void setHazeMode(ComponentMode mode);
|
||||||
void setSkyboxColor(const glm::vec3& color);
|
void setSkyboxColor(const glm::vec3& color);
|
||||||
void setProceduralUserData(const QString& userData);
|
void setProceduralUserData(const QString& userData);
|
||||||
|
|
||||||
|
@ -57,7 +63,7 @@ private:
|
||||||
model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; }
|
model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; }
|
||||||
model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; }
|
model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; }
|
||||||
model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
|
model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
|
||||||
|
model::HazePointer editHaze() { _needHazeUpdate = true; return _haze; }
|
||||||
|
|
||||||
bool _needsInitialSimulation{ true };
|
bool _needsInitialSimulation{ true };
|
||||||
glm::vec3 _lastPosition;
|
glm::vec3 _lastPosition;
|
||||||
|
@ -76,7 +82,10 @@ private:
|
||||||
const model::LightPointer _sunLight{ std::make_shared<model::Light>() };
|
const model::LightPointer _sunLight{ std::make_shared<model::Light>() };
|
||||||
const model::LightPointer _ambientLight{ 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::SunSkyStagePointer _background{ std::make_shared<model::SunSkyStage>() };
|
||||||
|
const model::HazePointer _haze{ std::make_shared<model::Haze>() };
|
||||||
|
|
||||||
BackgroundMode _backgroundMode{ BACKGROUND_MODE_INHERIT };
|
BackgroundMode _backgroundMode{ BACKGROUND_MODE_INHERIT };
|
||||||
|
ComponentMode _hazeMode{ COMPONENT_MODE_INHERIT };
|
||||||
|
|
||||||
indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX };
|
indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX };
|
||||||
indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX };
|
indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX };
|
||||||
|
@ -84,12 +93,17 @@ private:
|
||||||
BackgroundStagePointer _backgroundStage;
|
BackgroundStagePointer _backgroundStage;
|
||||||
BackgroundStage::Index _backgroundIndex{ BackgroundStage::INVALID_INDEX };
|
BackgroundStage::Index _backgroundIndex{ BackgroundStage::INVALID_INDEX };
|
||||||
|
|
||||||
|
HazeStagePointer _hazeStage;
|
||||||
|
HazeStage::Index _hazeIndex{ HazeStage::INVALID_INDEX };
|
||||||
|
|
||||||
bool _needUpdate{ true };
|
bool _needUpdate{ true };
|
||||||
bool _needSunUpdate{ true };
|
bool _needSunUpdate{ true };
|
||||||
bool _needAmbientUpdate{ true };
|
bool _needAmbientUpdate{ true };
|
||||||
bool _needBackgroundUpdate{ true };
|
bool _needBackgroundUpdate{ true };
|
||||||
|
bool _needHazeUpdate{ true };
|
||||||
|
|
||||||
KeyLightPropertyGroup _keyLightProperties;
|
KeyLightPropertyGroup _keyLightProperties;
|
||||||
|
HazePropertyGroup _hazeProperties;
|
||||||
StagePropertyGroup _stageProperties;
|
StagePropertyGroup _stageProperties;
|
||||||
SkyboxPropertyGroup _skyboxProperties;
|
SkyboxPropertyGroup _skyboxProperties;
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ void main(void) {
|
||||||
packDeferredFragmentTranslucent(
|
packDeferredFragmentTranslucent(
|
||||||
float(frontCondition) * interpolatedNormal,
|
float(frontCondition) * interpolatedNormal,
|
||||||
texel.a * varColor.a,
|
texel.a * varColor.a,
|
||||||
polyline.color * texel.rgb,
|
color * texel.rgb,
|
||||||
vec3(0.01, 0.01, 0.01),
|
vec3(0.01, 0.01, 0.01),
|
||||||
10.0);
|
10.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ void EntityEditPacketSender::queueEditAvatarEntityMessage(PacketType type,
|
||||||
}
|
}
|
||||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(entityItemID);
|
EntityItemPointer entity = entityTree->findEntityByEntityItemID(entityItemID);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "EntityEditPacketSender::queueEditEntityMessage can't find entity.";
|
qCDebug(entities) << "EntityEditPacketSender::queueEditAvatarEntityMessage can't find entity: " << entityItemID;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
AnimationPropertyGroup EntityItemProperties::_staticAnimation;
|
AnimationPropertyGroup EntityItemProperties::_staticAnimation;
|
||||||
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
SkyboxPropertyGroup EntityItemProperties::_staticSkybox;
|
||||||
|
HazePropertyGroup EntityItemProperties::_staticHaze;
|
||||||
StagePropertyGroup EntityItemProperties::_staticStage;
|
StagePropertyGroup EntityItemProperties::_staticStage;
|
||||||
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
KeyLightPropertyGroup EntityItemProperties::_staticKeyLight;
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ void EntityItemProperties::debugDump() const {
|
||||||
|
|
||||||
getAnimation().debugDump();
|
getAnimation().debugDump();
|
||||||
getSkybox().debugDump();
|
getSkybox().debugDump();
|
||||||
|
getHaze().debugDump();
|
||||||
getKeyLight().debugDump();
|
getKeyLight().debugDump();
|
||||||
|
|
||||||
qCDebug(entities) << " changed properties...";
|
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 EntityItemProperties::getChangedProperties() const {
|
||||||
EntityPropertyFlags changedProperties;
|
EntityPropertyFlags changedProperties;
|
||||||
|
|
||||||
|
@ -303,6 +331,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
CHECK_PROPERTY_CHANGE(PROP_NAME, name);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_BACKGROUND_MODE, backgroundMode);
|
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_SOURCE_URL, sourceUrl);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
CHECK_PROPERTY_CHANGE(PROP_VOXEL_VOLUME_SIZE, voxelVolumeSize);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_VOXEL_DATA, voxelData);
|
CHECK_PROPERTY_CHANGE(PROP_VOXEL_DATA, voxelData);
|
||||||
|
@ -314,7 +345,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
|
CHECK_PROPERTY_CHANGE(PROP_FACE_CAMERA, faceCamera);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
CHECK_PROPERTY_CHANGE(PROP_ACTION_DATA, actionData);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
|
CHECK_PROPERTY_CHANGE(PROP_NORMALS, normals);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_STROKE_COLORS, strokeColors);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
|
CHECK_PROPERTY_CHANGE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
CHECK_PROPERTY_CHANGE(PROP_X_TEXTURE_URL, xTextureURL);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
CHECK_PROPERTY_CHANGE(PROP_Y_TEXTURE_URL, yTextureURL);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
CHECK_PROPERTY_CHANGE(PROP_Z_TEXTURE_URL, zTextureURL);
|
||||||
|
@ -350,6 +383,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
changedProperties += _keyLight.getChangedProperties();
|
changedProperties += _keyLight.getChangedProperties();
|
||||||
changedProperties += _skybox.getChangedProperties();
|
changedProperties += _skybox.getChangedProperties();
|
||||||
changedProperties += _stage.getChangedProperties();
|
changedProperties += _stage.getChangedProperties();
|
||||||
|
changedProperties += _haze.getChangedProperties();
|
||||||
|
|
||||||
return changedProperties;
|
return changedProperties;
|
||||||
}
|
}
|
||||||
|
@ -529,6 +563,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FILTER_URL, filterURL);
|
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
|
// Web only
|
||||||
|
@ -560,8 +597,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_WIDTH, lineWidth);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LINE_POINTS, linePoints);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_NORMALS, normals);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_COLORS, strokeColors);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_STROKE_WIDTHS, strokeWidths);
|
||||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_TEXTURES, textures);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_IS_UV_MODE_STRETCH, isUVModeStretch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipDefaults && !strictSemantics) {
|
if (!skipDefaults && !strictSemantics) {
|
||||||
|
@ -712,6 +751,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
|
||||||
|
|
||||||
COPY_PROPERTY_FROM_QSCRITPTVALUE_ENUM(backgroundMode, BackgroundMode);
|
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(sourceUrl, QString, setSourceUrl);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, glmVec3, setVoxelVolumeSize);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelVolumeSize, glmVec3, setVoxelVolumeSize);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelData, QByteArray, setVoxelData);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(voxelData, QByteArray, setVoxelData);
|
||||||
|
@ -723,7 +765,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(faceCamera, bool, setFaceCamera);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(actionData, QByteArray, setActionData);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(normals, qVectorVec3, setNormals);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeColors, qVectorVec3, setStrokeColors);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(strokeWidths,qVectorFloat, setStrokeWidths);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(isUVModeStretch, bool, setIsUVModeStretch);
|
||||||
|
|
||||||
|
|
||||||
if (!honorReadOnly) {
|
if (!honorReadOnly) {
|
||||||
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
// this is used by the json reader to set things that we don't want javascript to able to affect.
|
||||||
|
@ -739,6 +784,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
_keyLight.copyFromScriptValue(object, _defaultSettings);
|
_keyLight.copyFromScriptValue(object, _defaultSettings);
|
||||||
_skybox.copyFromScriptValue(object, _defaultSettings);
|
_skybox.copyFromScriptValue(object, _defaultSettings);
|
||||||
_stage.copyFromScriptValue(object, _defaultSettings);
|
_stage.copyFromScriptValue(object, _defaultSettings);
|
||||||
|
_haze.copyFromScriptValue(object, _defaultSettings);
|
||||||
|
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(xTextureURL, QString, setXTextureURL);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(yTextureURL, QString, setYTextureURL);
|
||||||
|
@ -862,6 +908,9 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
||||||
COPY_PROPERTY_IF_CHANGED(collisionSoundURL);
|
COPY_PROPERTY_IF_CHANGED(collisionSoundURL);
|
||||||
|
|
||||||
COPY_PROPERTY_IF_CHANGED(backgroundMode);
|
COPY_PROPERTY_IF_CHANGED(backgroundMode);
|
||||||
|
|
||||||
|
COPY_PROPERTY_IF_CHANGED(hazeMode);
|
||||||
|
|
||||||
COPY_PROPERTY_IF_CHANGED(sourceUrl);
|
COPY_PROPERTY_IF_CHANGED(sourceUrl);
|
||||||
COPY_PROPERTY_IF_CHANGED(voxelVolumeSize);
|
COPY_PROPERTY_IF_CHANGED(voxelVolumeSize);
|
||||||
COPY_PROPERTY_IF_CHANGED(voxelData);
|
COPY_PROPERTY_IF_CHANGED(voxelData);
|
||||||
|
@ -873,13 +922,16 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
|
||||||
COPY_PROPERTY_IF_CHANGED(faceCamera);
|
COPY_PROPERTY_IF_CHANGED(faceCamera);
|
||||||
COPY_PROPERTY_IF_CHANGED(actionData);
|
COPY_PROPERTY_IF_CHANGED(actionData);
|
||||||
COPY_PROPERTY_IF_CHANGED(normals);
|
COPY_PROPERTY_IF_CHANGED(normals);
|
||||||
|
COPY_PROPERTY_IF_CHANGED(strokeColors);
|
||||||
COPY_PROPERTY_IF_CHANGED(strokeWidths);
|
COPY_PROPERTY_IF_CHANGED(strokeWidths);
|
||||||
|
COPY_PROPERTY_IF_CHANGED(isUVModeStretch);
|
||||||
COPY_PROPERTY_IF_CHANGED(created);
|
COPY_PROPERTY_IF_CHANGED(created);
|
||||||
|
|
||||||
_animation.merge(other._animation);
|
_animation.merge(other._animation);
|
||||||
_keyLight.merge(other._keyLight);
|
_keyLight.merge(other._keyLight);
|
||||||
_skybox.merge(other._skybox);
|
_skybox.merge(other._skybox);
|
||||||
_stage.merge(other._stage);
|
_stage.merge(other._stage);
|
||||||
|
_haze.merge(other._haze);
|
||||||
|
|
||||||
COPY_PROPERTY_IF_CHANGED(xTextureURL);
|
COPY_PROPERTY_IF_CHANGED(xTextureURL);
|
||||||
COPY_PROPERTY_IF_CHANGED(yTextureURL);
|
COPY_PROPERTY_IF_CHANGED(yTextureURL);
|
||||||
|
@ -1059,7 +1111,9 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
||||||
ADD_PROPERTY_TO_MAP(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
ADD_PROPERTY_TO_MAP(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
ADD_PROPERTY_TO_MAP(PROP_ACTION_DATA, ActionData, actionData, QByteArray);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
ADD_PROPERTY_TO_MAP(PROP_NORMALS, Normals, normals, QVector<glm::vec3>);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
ADD_PROPERTY_TO_MAP(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, QVector<float>);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
ADD_PROPERTY_TO_MAP(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
ADD_PROPERTY_TO_MAP(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString);
|
||||||
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
ADD_PROPERTY_TO_MAP(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString);
|
||||||
|
@ -1110,6 +1164,24 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
||||||
ADD_PROPERTY_TO_MAP(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool);
|
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_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);
|
ADD_PROPERTY_TO_MAP(PROP_DPI, DPI, dpi, uint16_t);
|
||||||
|
|
||||||
// FIXME - these are not yet handled
|
// FIXME - these are not yet handled
|
||||||
|
@ -1358,6 +1430,10 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, properties.getFilterURL());
|
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) {
|
if (properties.getType() == EntityTypes::PolyVox) {
|
||||||
|
@ -1383,9 +1459,11 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
if (properties.getType() == EntityTypes::PolyLine) {
|
if (properties.getType() == EntityTypes::PolyLine) {
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, properties.getLineWidth());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, properties.getLinePoints());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getNormals());
|
APPEND_ENTITY_PROPERTY(PROP_NORMALS, properties.getPackedNormals());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, properties.getPackedStrokeColors());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, properties.getStrokeWidths());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, properties.getTextures());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, properties.getIsUVModeStretch());
|
||||||
}
|
}
|
||||||
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
||||||
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
|
// when encoding/decoding edits because otherwise they can't polymorph to other shape types
|
||||||
|
@ -1472,6 +1550,44 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray EntityItemProperties::getPackedNormals() const {
|
||||||
|
return packNormals(getNormals());
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray EntityItemProperties::packNormals(const QVector<glm::vec3>& normals) const {
|
||||||
|
int normalsSize = normals.size();
|
||||||
|
QByteArray packedNormals = QByteArray(normalsSize * 6 + 1, '0');
|
||||||
|
// add size of the array
|
||||||
|
packedNormals[0] = ((uint8_t)normalsSize);
|
||||||
|
|
||||||
|
int index = 1;
|
||||||
|
for (int i = 0; i < normalsSize; i++) {
|
||||||
|
int numBytes = packFloatVec3ToSignedTwoByteFixed((unsigned char*)packedNormals.data() + index, normals[i], 15);
|
||||||
|
index += numBytes;
|
||||||
|
}
|
||||||
|
return packedNormals;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray EntityItemProperties::getPackedStrokeColors() const {
|
||||||
|
return packStrokeColors(getStrokeColors());
|
||||||
|
}
|
||||||
|
QByteArray EntityItemProperties::packStrokeColors(const QVector<glm::vec3>& strokeColors) const {
|
||||||
|
int strokeColorsSize = strokeColors.size();
|
||||||
|
QByteArray packedStrokeColors = QByteArray(strokeColorsSize * 3 + 1, '0');
|
||||||
|
|
||||||
|
// add size of the array
|
||||||
|
packedStrokeColors[0] = ((uint8_t)strokeColorsSize);
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < strokeColorsSize; i++) {
|
||||||
|
// add the color to the QByteArray
|
||||||
|
packedStrokeColors[i * 3 + 1] = strokeColors[i].r * 255;
|
||||||
|
packedStrokeColors[i * 3 + 2] = strokeColors[i].g * 255;
|
||||||
|
packedStrokeColors[i * 3 + 3] = strokeColors[i].b * 255;
|
||||||
|
}
|
||||||
|
return packedStrokeColors;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// how to handle lastEdited?
|
// how to handle lastEdited?
|
||||||
// how to handle lastUpdated?
|
// how to handle lastUpdated?
|
||||||
|
@ -1664,7 +1780,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_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
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_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) {
|
if (properties.getType() == EntityTypes::PolyVox) {
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VOXEL_VOLUME_SIZE, glm::vec3, setVoxelVolumeSize);
|
||||||
|
@ -1690,9 +1809,11 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
if (properties.getType() == EntityTypes::PolyLine) {
|
if (properties.getType() == EntityTypes::PolyLine) {
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_WIDTH, float, setLineWidth);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_NORMALS, QByteArray, setPackedNormals);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_COLORS, QByteArray, setPackedStrokeColors);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_TEXTURES, QString, setTextures);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
// NOTE: Spheres and Boxes are just special cases of Shape, and they need to include their PROP_SHAPE
|
||||||
|
@ -1723,6 +1844,53 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityItemProperties::setPackedNormals(const QByteArray& value) {
|
||||||
|
setNormals(unpackNormals(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<glm::vec3> EntityItemProperties::unpackNormals(const QByteArray& normals) {
|
||||||
|
// the size of the vector is packed first
|
||||||
|
QVector<glm::vec3> unpackedNormals = QVector<glm::vec3>((int)normals[0]);
|
||||||
|
|
||||||
|
if ((int)normals[0] == normals.size() / 6) {
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 1; i < normals.size();) {
|
||||||
|
glm::vec3 aux = glm::vec3();
|
||||||
|
i += unpackFloatVec3FromSignedTwoByteFixed((unsigned char*)normals.data() + i, aux, 15);
|
||||||
|
unpackedNormals[j] = aux;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCDebug(entities) << "WARNING - Expected received size for normals does not match. Expected: " << (int)normals[0]
|
||||||
|
<< " Received: " << (normals.size() / 6);
|
||||||
|
}
|
||||||
|
return unpackedNormals;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityItemProperties::setPackedStrokeColors(const QByteArray& value) {
|
||||||
|
setStrokeColors(unpackStrokeColors(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<glm::vec3> EntityItemProperties::unpackStrokeColors(const QByteArray& strokeColors) {
|
||||||
|
// the size of the vector is packed first
|
||||||
|
QVector<glm::vec3> unpackedStrokeColors = QVector<glm::vec3>((int)strokeColors[0]);
|
||||||
|
|
||||||
|
if ((int)strokeColors[0] == strokeColors.size() / 3) {
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 1; i < strokeColors.size();) {
|
||||||
|
|
||||||
|
float r = (uint8_t)strokeColors[i++] / 255.0f;
|
||||||
|
float g = (uint8_t)strokeColors[i++] / 255.0f;
|
||||||
|
float b = (uint8_t)strokeColors[i++] / 255.0f;
|
||||||
|
unpackedStrokeColors[j++] = glmVec3(r, g, b);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qCDebug(entities) << "WARNING - Expected received size for stroke colors does not match. Expected: "
|
||||||
|
<< (int)strokeColors[0] << " Received: " << (strokeColors.size() / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return unpackedStrokeColors;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: This version will only encode the portion of the edit message immediately following the
|
// NOTE: This version will only encode the portion of the edit message immediately following the
|
||||||
// header it does not include the send times and sequence number because that is handled by the
|
// header it does not include the send times and sequence number because that is handled by the
|
||||||
|
@ -1843,10 +2011,12 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_keyLight.markAllChanged();
|
_keyLight.markAllChanged();
|
||||||
|
|
||||||
_backgroundModeChanged = true;
|
_backgroundModeChanged = true;
|
||||||
|
_hazeModeChanged = true;
|
||||||
|
|
||||||
_animation.markAllChanged();
|
_animation.markAllChanged();
|
||||||
_skybox.markAllChanged();
|
_skybox.markAllChanged();
|
||||||
_stage.markAllChanged();
|
_stage.markAllChanged();
|
||||||
|
_haze.markAllChanged();
|
||||||
|
|
||||||
_sourceUrlChanged = true;
|
_sourceUrlChanged = true;
|
||||||
_voxelVolumeSizeChanged = true;
|
_voxelVolumeSizeChanged = true;
|
||||||
|
@ -1862,7 +2032,9 @@ void EntityItemProperties::markAllChanged() {
|
||||||
_actionDataChanged = true;
|
_actionDataChanged = true;
|
||||||
|
|
||||||
_normalsChanged = true;
|
_normalsChanged = true;
|
||||||
|
_strokeColorsChanged = true;
|
||||||
_strokeWidthsChanged = true;
|
_strokeWidthsChanged = true;
|
||||||
|
_isUVModeStretchChanged = true;
|
||||||
|
|
||||||
_xTextureURLChanged = true;
|
_xTextureURLChanged = true;
|
||||||
_yTextureURLChanged = true;
|
_yTextureURLChanged = true;
|
||||||
|
@ -2181,6 +2353,11 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
||||||
if (backgroundModeChanged()) {
|
if (backgroundModeChanged()) {
|
||||||
out += "backgroundMode";
|
out += "backgroundMode";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hazeModeChanged()) {
|
||||||
|
out += "hazeMode";
|
||||||
|
}
|
||||||
|
|
||||||
if (voxelVolumeSizeChanged()) {
|
if (voxelVolumeSizeChanged()) {
|
||||||
out += "voxelVolumeSize";
|
out += "voxelVolumeSize";
|
||||||
}
|
}
|
||||||
|
@ -2272,10 +2449,19 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
||||||
out += "shape";
|
out += "shape";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strokeColorsChanged()) {
|
||||||
|
out += "strokeColors";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUVModeStretchChanged()) {
|
||||||
|
out += "isUVModeStretch";
|
||||||
|
}
|
||||||
|
|
||||||
getAnimation().listChangedProperties(out);
|
getAnimation().listChangedProperties(out);
|
||||||
getKeyLight().listChangedProperties(out);
|
getKeyLight().listChangedProperties(out);
|
||||||
getSkybox().listChangedProperties(out);
|
getSkybox().listChangedProperties(out);
|
||||||
getStage().listChangedProperties(out);
|
getStage().listChangedProperties(out);
|
||||||
|
getHaze().listChangedProperties(out);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "PolyVoxEntityItem.h"
|
#include "PolyVoxEntityItem.h"
|
||||||
#include "SimulationOwner.h"
|
#include "SimulationOwner.h"
|
||||||
#include "SkyboxPropertyGroup.h"
|
#include "SkyboxPropertyGroup.h"
|
||||||
|
#include "HazePropertyGroup.h"
|
||||||
#include "StagePropertyGroup.h"
|
#include "StagePropertyGroup.h"
|
||||||
#include "TextEntityItem.h"
|
#include "TextEntityItem.h"
|
||||||
#include "ZoneEntityItem.h"
|
#include "ZoneEntityItem.h"
|
||||||
|
@ -177,7 +178,11 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_NAME, Name, name, QString, ENTITY_ITEM_DEFAULT_NAME);
|
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_REF_ENUM(PROP_BACKGROUND_MODE, BackgroundMode, backgroundMode, BackgroundMode, BACKGROUND_MODE_INHERIT);
|
||||||
DEFINE_PROPERTY_GROUP(Stage, stage, StagePropertyGroup);
|
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(Skybox, skybox, SkyboxPropertyGroup);
|
||||||
|
DEFINE_PROPERTY_GROUP(Haze, haze, HazePropertyGroup);
|
||||||
DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup);
|
DEFINE_PROPERTY_GROUP(Animation, animation, AnimationPropertyGroup);
|
||||||
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, "");
|
DEFINE_PROPERTY_REF(PROP_SOURCE_URL, SourceUrl, sourceUrl, QString, "");
|
||||||
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH);
|
DEFINE_PROPERTY(PROP_LINE_WIDTH, LineWidth, lineWidth, float, LineEntityItem::DEFAULT_LINE_WIDTH);
|
||||||
|
@ -186,8 +191,10 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString, "");
|
DEFINE_PROPERTY_REF(PROP_DESCRIPTION, Description, description, QString, "");
|
||||||
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool, TextEntityItem::DEFAULT_FACE_CAMERA);
|
DEFINE_PROPERTY(PROP_FACE_CAMERA, FaceCamera, faceCamera, bool, TextEntityItem::DEFAULT_FACE_CAMERA);
|
||||||
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray, QByteArray());
|
DEFINE_PROPERTY_REF(PROP_ACTION_DATA, ActionData, actionData, QByteArray, QByteArray());
|
||||||
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, QVector<glm::vec3>());
|
DEFINE_PROPERTY(PROP_NORMALS, Normals, normals, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
|
||||||
|
DEFINE_PROPERTY(PROP_STROKE_COLORS, StrokeColors, strokeColors, QVector<glm::vec3>, ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC);
|
||||||
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>, QVector<float>());
|
DEFINE_PROPERTY(PROP_STROKE_WIDTHS, StrokeWidths, strokeWidths, QVector<float>, QVector<float>());
|
||||||
|
DEFINE_PROPERTY(PROP_IS_UV_MODE_STRETCH, IsUVModeStretch, isUVModeStretch, bool, true);
|
||||||
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString, "");
|
DEFINE_PROPERTY_REF(PROP_X_TEXTURE_URL, XTextureURL, xTextureURL, QString, "");
|
||||||
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString, "");
|
DEFINE_PROPERTY_REF(PROP_Y_TEXTURE_URL, YTextureURL, yTextureURL, QString, "");
|
||||||
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString, "");
|
DEFINE_PROPERTY_REF(PROP_Z_TEXTURE_URL, ZTextureURL, zTextureURL, QString, "");
|
||||||
|
@ -239,6 +246,7 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
|
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
|
||||||
|
|
||||||
static QString getBackgroundModeString(BackgroundMode mode);
|
static QString getBackgroundModeString(BackgroundMode mode);
|
||||||
|
static QString getHazeModeString(uint32_t mode);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -316,6 +324,17 @@ public:
|
||||||
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; }
|
||||||
void setRenderInfoHasTransparent(bool value) { _renderInfoHasTransparent = value; }
|
void setRenderInfoHasTransparent(bool value) { _renderInfoHasTransparent = value; }
|
||||||
|
|
||||||
|
void setPackedNormals(const QByteArray& value);
|
||||||
|
QVector<glm::vec3> unpackNormals(const QByteArray& normals);
|
||||||
|
|
||||||
|
void setPackedStrokeColors(const QByteArray& value);
|
||||||
|
QVector<glm::vec3> unpackStrokeColors(const QByteArray& strokeColors);
|
||||||
|
|
||||||
|
QByteArray getPackedNormals() const;
|
||||||
|
QByteArray packNormals(const QVector<glm::vec3>& normals) const;
|
||||||
|
|
||||||
|
QByteArray getPackedStrokeColors() const;
|
||||||
|
QByteArray packStrokeColors(const QVector<glm::vec3>& strokeColors) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString getCollisionMaskAsString() const;
|
QString getCollisionMaskAsString() const;
|
||||||
|
@ -451,6 +470,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CertificateID, certificateID, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, CertificateID, certificateID, "");
|
||||||
|
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
|
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, VoxelVolumeSize, voxelVolumeSize, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelData, voxelData, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelData, voxelData, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelSurfaceStyle, voxelSurfaceStyle, "");
|
||||||
|
|
|
@ -24,6 +24,8 @@ const glm::vec3 ENTITY_ITEM_ZERO_VEC3 = glm::vec3(0.0f);
|
||||||
const glm::vec3 ENTITY_ITEM_ONE_VEC3 = glm::vec3(1.0f);
|
const glm::vec3 ENTITY_ITEM_ONE_VEC3 = glm::vec3(1.0f);
|
||||||
const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f);
|
const glm::vec3 ENTITY_ITEM_HALF_VEC3 = glm::vec3(0.5f);
|
||||||
|
|
||||||
|
const QVector<glm::vec3> ENTITY_ITEM_DEFAULT_EMPTY_VEC3_QVEC = QVector<glm::vec3>();
|
||||||
|
|
||||||
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
|
const bool ENTITY_ITEM_DEFAULT_LOCKED = false;
|
||||||
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
|
const QString ENTITY_ITEM_DEFAULT_USER_DATA = QString("");
|
||||||
const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid();
|
const QUuid ENTITY_ITEM_DEFAULT_SIMULATOR_ID = QUuid();
|
||||||
|
|
|
@ -109,7 +109,9 @@ enum EntityPropertyList {
|
||||||
|
|
||||||
// Used by PolyLine entity
|
// Used by PolyLine entity
|
||||||
PROP_NORMALS,
|
PROP_NORMALS,
|
||||||
|
PROP_STROKE_COLORS,
|
||||||
PROP_STROKE_WIDTHS,
|
PROP_STROKE_WIDTHS,
|
||||||
|
PROP_IS_UV_MODE_STRETCH,
|
||||||
|
|
||||||
// used by particles
|
// used by particles
|
||||||
PROP_SPEED_SPREAD,
|
PROP_SPEED_SPREAD,
|
||||||
|
@ -231,6 +233,25 @@ enum EntityPropertyList {
|
||||||
PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
PROP_STAGE_HOUR = PROP_QUADRATIC_ATTENUATION_UNUSED,
|
||||||
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
PROP_STAGE_AUTOMATIC_HOURDAY = PROP_ANIMATION_FRAME_INDEX,
|
||||||
PROP_BACKGROUND_MODE = PROP_MODEL_URL,
|
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_COLOR = PROP_ANIMATION_URL,
|
||||||
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
PROP_SKYBOX_URL = PROP_ANIMATION_FPS,
|
||||||
PROP_KEYLIGHT_AMBIENT_URL = PROP_ANIMATION_PLAYING,
|
PROP_KEYLIGHT_AMBIENT_URL = PROP_ANIMATION_PLAYING,
|
||||||
|
|
|
@ -1848,7 +1848,13 @@ bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void
|
||||||
|
|
||||||
QHash<EntityItemID, EntityItemID>::iterator iter = args->map->find(oldID);
|
QHash<EntityItemID, EntityItemID>::iterator iter = args->map->find(oldID);
|
||||||
if (iter == args->map->end()) {
|
if (iter == args->map->end()) {
|
||||||
EntityItemID newID = QUuid::createUuid();
|
EntityItemID newID;
|
||||||
|
if (oldID == AVATAR_SELF_ID) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
newID = EntityItemID(nodeList->getSessionUUID());
|
||||||
|
} else {
|
||||||
|
newID = QUuid::createUuid();
|
||||||
|
}
|
||||||
args->map->insert(oldID, newID);
|
args->map->insert(oldID, newID);
|
||||||
return newID;
|
return newID;
|
||||||
}
|
}
|
||||||
|
@ -1865,8 +1871,8 @@ bool EntityTree::sendEntitiesOperation(const OctreeElementPointer& element, void
|
||||||
properties.setPosition(properties.getPosition() + args->root);
|
properties.setPosition(properties.getPosition() + args->root);
|
||||||
} else {
|
} else {
|
||||||
EntityItemPointer parentEntity = args->ourTree->findEntityByEntityItemID(oldParentID);
|
EntityItemPointer parentEntity = args->ourTree->findEntityByEntityItemID(oldParentID);
|
||||||
if (parentEntity) { // map the parent
|
if (parentEntity || oldParentID == AVATAR_SELF_ID) { // map the parent
|
||||||
properties.setParentID(getMapped(parentEntity->getID()));
|
properties.setParentID(getMapped(oldParentID));
|
||||||
// But do not add root offset in this case.
|
// But do not add root offset in this case.
|
||||||
} else { // Should not happen, but let's try to be helpful...
|
} else { // Should not happen, but let's try to be helpful...
|
||||||
item->globalizeProperties(properties, "Cannot find %3 parent of %2 %1", args->root);
|
item->globalizeProperties(properties, "Cannot find %3 parent of %2 %1", args->root);
|
||||||
|
@ -1941,6 +1947,12 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
||||||
entityItemID = EntityItemID(QUuid::createUuid());
|
entityItemID = EntityItemID(QUuid::createUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.getClientOnly()) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
const QUuid myNodeID = nodeList->getSessionUUID();
|
||||||
|
properties.setOwningAvatarID(myNodeID);
|
||||||
|
}
|
||||||
|
|
||||||
EntityItemPointer entity = addEntity(entityItemID, properties);
|
EntityItemPointer entity = addEntity(entityItemID, properties);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
||||||
|
|
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
|
// libraries/entities/src
|
||||||
//
|
//
|
||||||
// Created by Sam Gateau on 2015/10/23.
|
// Created by Sam Gateau on 2015/10/23.
|
||||||
|
|
|
@ -30,7 +30,7 @@ const float LightEntityItem::DEFAULT_CUTOFF = PI / 2.0f;
|
||||||
bool LightEntityItem::_lightsArePickable = false;
|
bool LightEntityItem::_lightsArePickable = false;
|
||||||
|
|
||||||
EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new LightEntityItem(entityID) };
|
EntityItemPointer entity(new LightEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const int LineEntityItem::MAX_POINTS_PER_LINE = 70;
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new LineEntityItem(entityID) };
|
EntityItemPointer entity(new LineEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -214,4 +214,4 @@ void LineEntityItem::resetPointsChanged() {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_pointsChanged = false;
|
_pointsChanged = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ const QString ModelEntityItem::DEFAULT_MODEL_URL = QString("");
|
||||||
const QString ModelEntityItem::DEFAULT_COMPOUND_SHAPE_URL = QString("");
|
const QString ModelEntityItem::DEFAULT_COMPOUND_SHAPE_URL = QString("");
|
||||||
|
|
||||||
EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ModelEntityItem(entityID) };
|
EntityItemPointer entity(new ModelEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ uint64_t Properties::emitIntervalUsecs() const {
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ParticleEffectEntityItem(entityID) };
|
EntityItemPointer entity(new ParticleEffectEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,15 +22,16 @@
|
||||||
#include "PolyLineEntityItem.h"
|
#include "PolyLineEntityItem.h"
|
||||||
|
|
||||||
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
|
const float PolyLineEntityItem::DEFAULT_LINE_WIDTH = 0.1f;
|
||||||
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 70;
|
const int PolyLineEntityItem::MAX_POINTS_PER_LINE = 60;
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer PolyLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity{ new PolyLineEntityItem(entityID) };
|
EntityItemPointer entity(new PolyLineEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
|
PolyLineEntityItem::PolyLineEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID) {
|
||||||
_type = EntityTypes::PolyLine;
|
_type = EntityTypes::PolyLine;
|
||||||
}
|
}
|
||||||
|
@ -42,12 +43,15 @@ EntityItemProperties PolyLineEntityItem::getProperties(EntityPropertyFlags desir
|
||||||
|
|
||||||
properties._color = getXColor();
|
properties._color = getXColor();
|
||||||
properties._colorChanged = false;
|
properties._colorChanged = false;
|
||||||
|
|
||||||
|
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lineWidth, getLineWidth);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(linePoints, getLinePoints);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(normals, getNormals);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeColors, getStrokeColors);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(strokeWidths, getStrokeWidths);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(isUVModeStretch, getIsUVModeStretch);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +64,10 @@ bool PolyLineEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lineWidth, setLineWidth);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(linePoints, setLinePoints);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(normals, setNormals);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeColors, setStrokeColors);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(strokeWidths, setStrokeWidths);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(isUVModeStretch, setIsUVModeStretch);
|
||||||
|
|
||||||
if (somethingChanged) {
|
if (somethingChanged) {
|
||||||
bool wantDebug = false;
|
bool wantDebug = false;
|
||||||
|
@ -108,6 +114,15 @@ bool PolyLineEntityItem::setNormals(const QVector<glm::vec3>& normals) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PolyLineEntityItem::setStrokeColors(const QVector<glm::vec3>& strokeColors) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
_strokeColors = strokeColors;
|
||||||
|
_strokeColorsChanged = true;
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
bool PolyLineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
|
||||||
if (points.size() > MAX_POINTS_PER_LINE) {
|
if (points.size() > MAX_POINTS_PER_LINE) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -193,8 +208,10 @@ int PolyLineEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* da
|
||||||
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
|
READ_ENTITY_PROPERTY(PROP_LINE_WIDTH, float, setLineWidth);
|
||||||
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
READ_ENTITY_PROPERTY(PROP_LINE_POINTS, QVector<glm::vec3>, setLinePoints);
|
||||||
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
READ_ENTITY_PROPERTY(PROP_NORMALS, QVector<glm::vec3>, setNormals);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_STROKE_COLORS, QVector<glm::vec3>, setStrokeColors);
|
||||||
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
READ_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, QVector<float>, setStrokeWidths);
|
||||||
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, bool, setIsUVModeStretch);
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
@ -207,8 +224,10 @@ EntityPropertyFlags PolyLineEntityItem::getEntityProperties(EncodeBitstreamParam
|
||||||
requestedProperties += PROP_LINE_WIDTH;
|
requestedProperties += PROP_LINE_WIDTH;
|
||||||
requestedProperties += PROP_LINE_POINTS;
|
requestedProperties += PROP_LINE_POINTS;
|
||||||
requestedProperties += PROP_NORMALS;
|
requestedProperties += PROP_NORMALS;
|
||||||
|
requestedProperties += PROP_STROKE_COLORS;
|
||||||
requestedProperties += PROP_STROKE_WIDTHS;
|
requestedProperties += PROP_STROKE_WIDTHS;
|
||||||
requestedProperties += PROP_TEXTURES;
|
requestedProperties += PROP_TEXTURES;
|
||||||
|
requestedProperties += PROP_IS_UV_MODE_STRETCH;
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,8 +246,10 @@ void PolyLineEntityItem::appendSubclassData(OctreePacketData* packetData, Encode
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_WIDTH, getLineWidth());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
APPEND_ENTITY_PROPERTY(PROP_LINE_POINTS, getLinePoints());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
APPEND_ENTITY_PROPERTY(PROP_NORMALS, getNormals());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_COLORS, getStrokeColors());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
APPEND_ENTITY_PROPERTY(PROP_STROKE_WIDTHS, getStrokeWidths());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
|
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_IS_UV_MODE_STRETCH, getIsUVModeStretch());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyLineEntityItem::debugDump() const {
|
void PolyLineEntityItem::debugDump() const {
|
||||||
|
@ -258,6 +279,14 @@ QVector<glm::vec3> PolyLineEntityItem::getNormals() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<glm::vec3> PolyLineEntityItem::getStrokeColors() const {
|
||||||
|
QVector<glm::vec3> result;
|
||||||
|
withReadLock([&] {
|
||||||
|
result = _strokeColors;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<float> PolyLineEntityItem::getStrokeWidths() const {
|
QVector<float> PolyLineEntityItem::getStrokeWidths() const {
|
||||||
QVector<float> result;
|
QVector<float> result;
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
|
|
|
@ -46,9 +46,11 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
|
||||||
|
|
||||||
void setColor(const rgbColor& value) {
|
void setColor(const rgbColor& value) {
|
||||||
|
_strokeColorsChanged = true;
|
||||||
memcpy(_color, value, sizeof(_color));
|
memcpy(_color, value, sizeof(_color));
|
||||||
}
|
}
|
||||||
void setColor(const xColor& value) {
|
void setColor(const xColor& value) {
|
||||||
|
_strokeColorsChanged = true;
|
||||||
_color[RED_INDEX] = value.red;
|
_color[RED_INDEX] = value.red;
|
||||||
_color[GREEN_INDEX] = value.green;
|
_color[GREEN_INDEX] = value.green;
|
||||||
_color[BLUE_INDEX] = value.blue;
|
_color[BLUE_INDEX] = value.blue;
|
||||||
|
@ -64,9 +66,15 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
bool setNormals(const QVector<glm::vec3>& normals);
|
bool setNormals(const QVector<glm::vec3>& normals);
|
||||||
QVector<glm::vec3> getNormals() const;
|
QVector<glm::vec3> getNormals() const;
|
||||||
|
|
||||||
|
bool setStrokeColors(const QVector<glm::vec3>& strokeColors);
|
||||||
|
QVector<glm::vec3> getStrokeColors() const;
|
||||||
|
|
||||||
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
bool setStrokeWidths(const QVector<float>& strokeWidths);
|
||||||
QVector<float> getStrokeWidths() const;
|
QVector<float> getStrokeWidths() const;
|
||||||
|
|
||||||
|
void setIsUVModeStretch(bool isUVModeStretch){ _isUVModeStretch = isUVModeStretch; }
|
||||||
|
bool getIsUVModeStretch() const{ return _isUVModeStretch; }
|
||||||
|
|
||||||
QString getTextures() const;
|
QString getTextures() const;
|
||||||
void setTextures(const QString& textures);
|
void setTextures(const QString& textures);
|
||||||
|
|
||||||
|
@ -76,10 +84,11 @@ class PolyLineEntityItem : public EntityItem {
|
||||||
|
|
||||||
bool pointsChanged() const { return _pointsChanged; }
|
bool pointsChanged() const { return _pointsChanged; }
|
||||||
bool normalsChanged() const { return _normalsChanged; }
|
bool normalsChanged() const { return _normalsChanged; }
|
||||||
|
bool strokeColorsChanged() const { return _strokeColorsChanged; }
|
||||||
bool strokeWidthsChanged() const { return _strokeWidthsChanged; }
|
bool strokeWidthsChanged() const { return _strokeWidthsChanged; }
|
||||||
bool texturesChanged() const { return _texturesChangedFlag; }
|
bool texturesChanged() const { return _texturesChangedFlag; }
|
||||||
void resetTexturesChanged() { _texturesChangedFlag = false; }
|
void resetTexturesChanged() { _texturesChangedFlag = false; }
|
||||||
void resetPolyLineChanged() { _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
|
void resetPolyLineChanged() { _strokeColorsChanged = _strokeWidthsChanged = _normalsChanged = _pointsChanged = false; }
|
||||||
|
|
||||||
|
|
||||||
// never have a ray intersection pick a PolyLineEntityItem.
|
// never have a ray intersection pick a PolyLineEntityItem.
|
||||||
|
@ -103,11 +112,14 @@ private:
|
||||||
float _lineWidth { DEFAULT_LINE_WIDTH };
|
float _lineWidth { DEFAULT_LINE_WIDTH };
|
||||||
bool _pointsChanged { true };
|
bool _pointsChanged { true };
|
||||||
bool _normalsChanged { true };
|
bool _normalsChanged { true };
|
||||||
|
bool _strokeColorsChanged { true };
|
||||||
bool _strokeWidthsChanged { true };
|
bool _strokeWidthsChanged { true };
|
||||||
QVector<glm::vec3> _points;
|
QVector<glm::vec3> _points;
|
||||||
QVector<glm::vec3> _normals;
|
QVector<glm::vec3> _normals;
|
||||||
|
QVector<glm::vec3> _strokeColors;
|
||||||
QVector<float> _strokeWidths;
|
QVector<float> _strokeWidths;
|
||||||
QString _textures;
|
QString _textures;
|
||||||
|
bool _isUVModeStretch;
|
||||||
bool _texturesChangedFlag { false };
|
bool _texturesChangedFlag { false };
|
||||||
mutable QReadWriteLock _quadReadWriteLock;
|
mutable QReadWriteLock _quadReadWriteLock;
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,7 +47,7 @@ const QString PolyVoxEntityItem::DEFAULT_Y_TEXTURE_URL = QString("");
|
||||||
const QString PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL = QString("");
|
const QString PolyVoxEntityItem::DEFAULT_Z_TEXTURE_URL = QString("");
|
||||||
|
|
||||||
EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new PolyVoxEntityItem(entityID) };
|
EntityItemPointer entity(new PolyVoxEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
Pointer entity { new ShapeEntityItem(entityID) };
|
Pointer entity(new ShapeEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0};
|
||||||
const bool TextEntityItem::DEFAULT_FACE_CAMERA = false;
|
const bool TextEntityItem::DEFAULT_FACE_CAMERA = false;
|
||||||
|
|
||||||
EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new TextEntityItem(entityID) };
|
EntityItemPointer entity(new TextEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
const QString WebEntityItem::DEFAULT_SOURCE_URL("http://www.google.com");
|
const QString WebEntityItem::DEFAULT_SOURCE_URL("http://www.google.com");
|
||||||
|
|
||||||
EntityItemPointer WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new WebEntityItem(entityID) };
|
EntityItemPointer entity(new WebEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ const bool ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED = true;
|
||||||
const QString ZoneEntityItem::DEFAULT_FILTER_URL = "";
|
const QString ZoneEntityItem::DEFAULT_FILTER_URL = "";
|
||||||
|
|
||||||
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ZoneEntityItem(entityID) };
|
EntityItemPointer entity(new ZoneEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,9 @@ EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredPr
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
|
||||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(filterURL, getFilterURL);
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(filterURL, getFilterURL);
|
||||||
|
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(hazeMode, getHazeMode);
|
||||||
|
_hazeProperties.getProperties(properties);
|
||||||
|
|
||||||
return 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(compoundShapeURL, setCompoundShapeURL);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
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
|
// Contains a QString property, must be synchronized
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_skyboxPropertiesChanged = _skyboxProperties.setProperties(properties);
|
_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;
|
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_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||||
READ_ENTITY_PROPERTY(PROP_FILTER_URL, QString, setFilterURL);
|
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;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,10 +185,11 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
||||||
requestedProperties += _keyLightProperties.getEntityProperties(params);
|
requestedProperties += _keyLightProperties.getEntityProperties(params);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||||
|
|
||||||
requestedProperties += PROP_SHAPE_TYPE;
|
requestedProperties += PROP_SHAPE_TYPE;
|
||||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||||
requestedProperties += PROP_BACKGROUND_MODE;
|
requestedProperties += PROP_BACKGROUND_MODE;
|
||||||
requestedProperties += _stageProperties.getEntityProperties(params);
|
|
||||||
|
|
||||||
withReadLock([&] {
|
withReadLock([&] {
|
||||||
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
||||||
|
@ -183,6 +199,9 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
||||||
requestedProperties += PROP_GHOSTING_ALLOWED;
|
requestedProperties += PROP_GHOSTING_ALLOWED;
|
||||||
requestedProperties += PROP_FILTER_URL;
|
requestedProperties += PROP_FILTER_URL;
|
||||||
|
|
||||||
|
requestedProperties += PROP_HAZE_MODE;
|
||||||
|
requestedProperties += _hazeProperties.getEntityProperties(params);
|
||||||
|
|
||||||
return requestedProperties;
|
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??
|
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
||||||
|
|
||||||
_skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
_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_FLYING_ALLOWED, getFlyingAllowed());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
|
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_FILTER_URL, getFilterURL());
|
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 {
|
void ZoneEntityItem::debugDump() const {
|
||||||
|
@ -222,10 +245,12 @@ void ZoneEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions());
|
||||||
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
|
||||||
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
|
||||||
|
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode);
|
||||||
|
|
||||||
_keyLightProperties.debugDump();
|
_keyLightProperties.debugDump();
|
||||||
_stageProperties.debugDump();
|
|
||||||
_skyboxProperties.debugDump();
|
_skyboxProperties.debugDump();
|
||||||
|
_hazeProperties.debugDump();
|
||||||
|
_stageProperties.debugDump();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeType ZoneEntityItem::getShapeType() const {
|
ShapeType ZoneEntityItem::getShapeType() const {
|
||||||
|
@ -289,7 +314,117 @@ void ZoneEntityItem::resetRenderingPropertiesChanged() {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_keyLightPropertiesChanged = false;
|
_keyLightPropertiesChanged = false;
|
||||||
_backgroundPropertiesChanged = false;
|
_backgroundPropertiesChanged = false;
|
||||||
_stagePropertiesChanged = false;
|
|
||||||
_skyboxPropertiesChanged = 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|