mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 12:32:12 +02:00
Merge pull request #12747 from Zvork/fade
Update to Transitions debugging / editing script
This commit is contained in:
commit
2e37b4a312
6 changed files with 358 additions and 120 deletions
|
@ -110,7 +110,6 @@ bool SelectionScriptingInterface::enableListHighlight(const QString& listName, c
|
|||
}
|
||||
|
||||
if (!(*highlightStyle).isBoundToList()) {
|
||||
setupHandler(listName);
|
||||
(*highlightStyle).setBoundToList(true);
|
||||
}
|
||||
|
||||
|
@ -172,6 +171,18 @@ render::HighlightStyle SelectionScriptingInterface::getHighlightStyle(const QStr
|
|||
}
|
||||
}
|
||||
|
||||
bool SelectionScriptingInterface::enableListToScene(const QString& listName) {
|
||||
setupHandler(listName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SelectionScriptingInterface::disableListToScene(const QString& listName) {
|
||||
removeHandler(listName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T> bool SelectionScriptingInterface::addToGameplayObjects(const QString& listName, T idToAdd) {
|
||||
{
|
||||
QWriteLocker lock(&_selectionListsLock);
|
||||
|
@ -303,6 +314,15 @@ void SelectionScriptingInterface::setupHandler(const QString& selectionName) {
|
|||
(*handler)->initialize(selectionName);
|
||||
}
|
||||
|
||||
void SelectionScriptingInterface::removeHandler(const QString& selectionName) {
|
||||
QWriteLocker lock(&_selectionHandlersLock);
|
||||
auto handler = _handlerMap.find(selectionName);
|
||||
if (handler != _handlerMap.end()) {
|
||||
delete handler.value();
|
||||
_handlerMap.erase(handler);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionScriptingInterface::onSelectedItemsListChanged(const QString& listName) {
|
||||
{
|
||||
QWriteLocker lock(&_selectionHandlersLock);
|
||||
|
|
|
@ -160,13 +160,14 @@ public:
|
|||
* If the Selection doesn't exist, it will be created.
|
||||
* All objects in the list will be displayed with the highlight effect as specified from the highlightStyle.
|
||||
* The function can be called several times with different values in the style to modify it.
|
||||
*
|
||||
*
|
||||
* @function Selection.enableListHighlight
|
||||
* @param listName {string} name of the selection
|
||||
* @param highlightStyle {jsObject} highlight style fields (see Selection.getListHighlightStyle for a detailed description of the highlightStyle).
|
||||
* @returns {bool} true if the selection was successfully enabled for highlight.
|
||||
*/
|
||||
Q_INVOKABLE bool enableListHighlight(const QString& listName, const QVariantMap& highlightStyle);
|
||||
|
||||
/**jsdoc
|
||||
* Disable highlighting for the named selection.
|
||||
* If the Selection doesn't exist or wasn't enabled for highliting then nothing happens simply returning false.
|
||||
|
@ -175,7 +176,27 @@ public:
|
|||
* @param listName {string} name of the selection
|
||||
* @returns {bool} true if the selection was successfully disabled for highlight, false otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool disableListHighlight(const QString& listName);
|
||||
Q_INVOKABLE bool disableListHighlight(const QString& listName);
|
||||
/**jsdoc
|
||||
* Enable scene selection for the named selection.
|
||||
* If the Selection doesn't exist, it will be created.
|
||||
* All objects in the list will be sent to a scene selection.
|
||||
*
|
||||
* @function Selection.enableListToScene
|
||||
* @param listName {string} name of the selection
|
||||
* @returns {bool} true if the selection was successfully enabled on the scene.
|
||||
*/
|
||||
Q_INVOKABLE bool enableListToScene(const QString& listName);
|
||||
/**jsdoc
|
||||
* Disable scene selection for the named selection.
|
||||
* If the Selection doesn't exist or wasn't enabled on the scene then nothing happens simply returning false.
|
||||
*
|
||||
* @function Selection.disableListToScene
|
||||
* @param listName {string} name of the selection
|
||||
* @returns {bool} true if the selection was successfully disabled on the scene, false otherwise.
|
||||
*/
|
||||
Q_INVOKABLE bool disableListToScene(const QString& listName);
|
||||
|
||||
/**jsdoc
|
||||
* Query the highlight style values for the named selection.
|
||||
* If the Selection doesn't exist or hasn't been highlight enabled yet, it will return an empty object.
|
||||
|
@ -223,7 +244,7 @@ private:
|
|||
template <class T> bool removeFromGameplayObjects(const QString& listName, T idToRemove);
|
||||
|
||||
void setupHandler(const QString& selectionName);
|
||||
|
||||
void removeHandler(const QString& selectionName);
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -39,43 +39,52 @@ void FadeEditJob::run(const render::RenderContextPointer& renderContext, const F
|
|||
auto scene = renderContext->_scene;
|
||||
|
||||
if (_isEditEnabled) {
|
||||
float minIsectDistance = std::numeric_limits<float>::max();
|
||||
auto& itemBounds = inputs.get0();
|
||||
auto editedItem = findNearestItem(renderContext, itemBounds, minIsectDistance);
|
||||
render::Transaction transaction;
|
||||
bool hasTransaction{ false };
|
||||
static const std::string selectionName("TransitionEdit");
|
||||
auto scene = renderContext->_scene;
|
||||
if (!scene->isSelectionEmpty(selectionName)) {
|
||||
auto selection = scene->getSelection(selectionName);
|
||||
auto editedItem = selection.getItems().front();
|
||||
render::Transaction transaction;
|
||||
bool hasTransaction{ false };
|
||||
|
||||
if (editedItem != _editedItem && render::Item::isValidID(_editedItem)) {
|
||||
// Remove transition from previously edited item as we've changed edited item
|
||||
hasTransaction = true;
|
||||
if (editedItem != _editedItem && render::Item::isValidID(_editedItem)) {
|
||||
// Remove transition from previously edited item as we've changed edited item
|
||||
hasTransaction = true;
|
||||
transaction.removeTransitionFromItem(_editedItem);
|
||||
}
|
||||
_editedItem = editedItem;
|
||||
|
||||
if (render::Item::isValidID(_editedItem)) {
|
||||
static const render::Transition::Type categoryToTransition[FADE_CATEGORY_COUNT] = {
|
||||
render::Transition::ELEMENT_ENTER_DOMAIN,
|
||||
render::Transition::BUBBLE_ISECT_OWNER,
|
||||
render::Transition::BUBBLE_ISECT_TRESPASSER,
|
||||
render::Transition::USER_ENTER_DOMAIN,
|
||||
render::Transition::AVATAR_CHANGE
|
||||
};
|
||||
|
||||
auto transitionType = categoryToTransition[inputs.get1()];
|
||||
|
||||
transaction.queryTransitionOnItem(_editedItem, [transitionType, scene](render::ItemID id, const render::Transition* transition) {
|
||||
if (transition == nullptr || transition->isFinished || transition->eventType != transitionType) {
|
||||
// Relaunch transition
|
||||
render::Transaction transaction;
|
||||
transaction.addTransitionToItem(id, transitionType);
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
});
|
||||
hasTransaction = true;
|
||||
}
|
||||
|
||||
if (hasTransaction) {
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
} else if (render::Item::isValidID(_editedItem)) {
|
||||
// Remove transition from previously edited item as we've disabled fade edition
|
||||
render::Transaction transaction;
|
||||
transaction.removeTransitionFromItem(_editedItem);
|
||||
}
|
||||
_editedItem = editedItem;
|
||||
|
||||
if (render::Item::isValidID(_editedItem)) {
|
||||
static const render::Transition::Type categoryToTransition[FADE_CATEGORY_COUNT] = {
|
||||
render::Transition::ELEMENT_ENTER_DOMAIN,
|
||||
render::Transition::BUBBLE_ISECT_OWNER,
|
||||
render::Transition::BUBBLE_ISECT_TRESPASSER,
|
||||
render::Transition::USER_ENTER_DOMAIN,
|
||||
render::Transition::AVATAR_CHANGE
|
||||
};
|
||||
|
||||
auto transitionType = categoryToTransition[inputs.get1()];
|
||||
|
||||
transaction.queryTransitionOnItem(_editedItem, [transitionType, scene](render::ItemID id, const render::Transition* transition) {
|
||||
if (transition == nullptr || transition->isFinished || transition->eventType!=transitionType) {
|
||||
// Relaunch transition
|
||||
render::Transaction transaction;
|
||||
transaction.addTransitionToItem(id, transitionType);
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
});
|
||||
hasTransaction = true;
|
||||
}
|
||||
|
||||
if (hasTransaction) {
|
||||
scene->enqueueTransaction(transaction);
|
||||
_editedItem = render::Item::INVALID_ITEM_ID;
|
||||
}
|
||||
}
|
||||
else if (render::Item::isValidID(_editedItem)) {
|
||||
|
@ -87,28 +96,6 @@ void FadeEditJob::run(const render::RenderContextPointer& renderContext, const F
|
|||
}
|
||||
}
|
||||
|
||||
render::ItemID FadeEditJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const {
|
||||
const glm::vec3 rayOrigin = renderContext->args->getViewFrustum().getPosition();
|
||||
const glm::vec3 rayDirection = renderContext->args->getViewFrustum().getDirection();
|
||||
BoxFace face;
|
||||
glm::vec3 normal;
|
||||
float isectDistance;
|
||||
render::ItemID nearestItem = render::Item::INVALID_ITEM_ID;
|
||||
const float minDistance = 1.f;
|
||||
const float maxDistance = 50.f;
|
||||
|
||||
for (const auto& itemBound : inputs) {
|
||||
if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, isectDistance, face, normal)) {
|
||||
auto& item = renderContext->_scene->getItem(itemBound.id);
|
||||
if (item.getKey().isWorldSpace() && isectDistance>minDistance && isectDistance < minIsectDistance && isectDistance<maxDistance) {
|
||||
nearestItem = itemBound.id;
|
||||
minIsectDistance = isectDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearestItem;
|
||||
}
|
||||
|
||||
FadeConfig::FadeConfig()
|
||||
{
|
||||
events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 0.75f, 0.75f, 0.75f };
|
||||
|
@ -353,11 +340,9 @@ QString FadeConfig::eventNames[FADE_CATEGORY_COUNT] = {
|
|||
"avatar_change",
|
||||
};
|
||||
|
||||
void FadeConfig::save() const {
|
||||
// Save will only work if the HIFI_USE_SOURCE_TREE_RESOURCES environment variable is set
|
||||
void FadeConfig::save(const QString& configFilePath) const {
|
||||
assert(editedCategory < FADE_CATEGORY_COUNT);
|
||||
QJsonObject lProperties;
|
||||
const QString configFilePath = PathUtils::resourcesPath() + "config/" + eventNames[editedCategory] + ".json";
|
||||
QFile file(configFilePath);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
qWarning() << "Fade event configuration file " << configFilePath << " cannot be opened";
|
||||
|
@ -382,8 +367,7 @@ void FadeConfig::save() const {
|
|||
}
|
||||
}
|
||||
|
||||
void FadeConfig::load() {
|
||||
const QString configFilePath = PathUtils::resourcesPath() + "config/" + eventNames[editedCategory] + ".json";
|
||||
void FadeConfig::load(const QString& configFilePath) {
|
||||
QFile file(configFilePath);
|
||||
if (!file.exists()) {
|
||||
qWarning() << "Fade event configuration file " << configFilePath << " does not exist";
|
||||
|
@ -594,7 +578,7 @@ void FadeJob::run(const render::RenderContextPointer& renderContext, FadeJob::Ou
|
|||
if (update(*jobConfig, scene, transaction, state, deltaTime)) {
|
||||
hasTransaction = true;
|
||||
}
|
||||
if (isFirstItem && jobConfig->manualFade && (state.threshold != jobConfig->threshold)) {
|
||||
if (isFirstItem && (state.threshold != jobConfig->threshold)) {
|
||||
jobConfig->setProperty("threshold", state.threshold);
|
||||
isFirstItem = false;
|
||||
}
|
||||
|
|
|
@ -160,8 +160,8 @@ public:
|
|||
float manualThreshold{ 0.f };
|
||||
bool manualFade{ false };
|
||||
|
||||
Q_INVOKABLE void save() const;
|
||||
Q_INVOKABLE void load();
|
||||
Q_INVOKABLE void save(const QString& filePath) const;
|
||||
Q_INVOKABLE void load(const QString& filePath);
|
||||
|
||||
static QString eventNames[FADE_CATEGORY_COUNT];
|
||||
|
||||
|
@ -190,7 +190,6 @@ private:
|
|||
bool _isEditEnabled{ false };
|
||||
render::ItemID _editedItem{ render::Item::INVALID_ITEM_ID };
|
||||
|
||||
render::ItemID findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const;
|
||||
};
|
||||
|
||||
class FadeJob {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
"use strict";
|
||||
|
||||
//
|
||||
// debugTransition.js
|
||||
// developer/utilities/render
|
||||
|
@ -12,12 +10,17 @@
|
|||
//
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var TABLET_BUTTON_NAME = "Transition";
|
||||
var QMLAPP_URL = Script.resolvePath("./transition.qml");
|
||||
var ICON_URL = Script.resolvePath("../../../system/assets/images/transition-i.svg");
|
||||
var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/transition-a.svg");
|
||||
|
||||
|
||||
Script.include([
|
||||
Script.resolvePath("../../../system/libraries/stringHelpers.js"),
|
||||
]);
|
||||
|
||||
var onScreen = false;
|
||||
|
||||
function onClicked() {
|
||||
|
@ -37,6 +40,71 @@
|
|||
|
||||
var hasEventBridge = false;
|
||||
|
||||
function enableSphereVisualization() {
|
||||
if (gradientSphere==undefined) {
|
||||
gradientSphere = Overlays.addOverlay("sphere", {
|
||||
position: MyAvatar.position,
|
||||
rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0),
|
||||
dimensions: { x: 1.0, y: 1.0, z: 1.0 },
|
||||
color: { red: 100, green: 150, blue: 255},
|
||||
alpha: 0.2,
|
||||
solid: false
|
||||
});
|
||||
}
|
||||
if (noiseSphere==undefined) {
|
||||
noiseSphere = Overlays.addOverlay("sphere", {
|
||||
position: MyAvatar.position,
|
||||
rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0),
|
||||
dimensions: { x: 1.0, y: 1.0, z: 1.0 },
|
||||
color: { red: 255, green: 150, blue: 100},
|
||||
alpha: 0.2,
|
||||
solid: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function disableSphereVisualization() {
|
||||
Overlays.deleteOverlay(noiseSphere);
|
||||
Overlays.deleteOverlay(gradientSphere);
|
||||
noiseSphere = undefined
|
||||
gradientSphere = undefined
|
||||
}
|
||||
|
||||
// Create a Laser pointer used to pick and add objects to selections
|
||||
var END_DIMENSIONS = { x: 0.05, y: 0.05, z: 0.05 };
|
||||
var COLOR1 = {red: 255, green: 0, blue: 0};
|
||||
var COLOR2 = {red: 0, green: 255, blue: 0};
|
||||
var end1 = {
|
||||
type: "sphere",
|
||||
dimensions: END_DIMENSIONS,
|
||||
color: COLOR1,
|
||||
ignoreRayIntersection: true
|
||||
}
|
||||
var end2 = {
|
||||
type: "sphere",
|
||||
dimensions: END_DIMENSIONS,
|
||||
color: COLOR2,
|
||||
ignoreRayIntersection: true
|
||||
}
|
||||
var laser
|
||||
|
||||
function enablePointer() {
|
||||
laser = Pointers.createPointer(PickType.Ray, {
|
||||
joint: "Mouse",
|
||||
filter: Picks.PICK_ENTITIES,
|
||||
renderStates: [{name: "one", end: end1}],
|
||||
defaultRenderStates: [{name: "one", end: end2, distance: 2.0}],
|
||||
enabled: true
|
||||
});
|
||||
Pointers.setRenderState(laser, "one");
|
||||
Pointers.enablePointer(laser)
|
||||
}
|
||||
|
||||
function disablePointer() {
|
||||
Pointers.disablePointer(laser)
|
||||
Pointers.removePointer(laser);
|
||||
}
|
||||
|
||||
function wireEventBridge(on) {
|
||||
if (!tablet) {
|
||||
print("Warning in wireEventBridge(): 'tablet' undefined!");
|
||||
|
@ -46,11 +114,15 @@
|
|||
if (!hasEventBridge) {
|
||||
tablet.fromQml.connect(fromQml);
|
||||
hasEventBridge = true;
|
||||
enablePointer();
|
||||
Render.getConfig("RenderMainView.FadeEdit")["editFade"] = true
|
||||
}
|
||||
} else {
|
||||
if (hasEventBridge) {
|
||||
tablet.fromQml.disconnect(fromQml);
|
||||
hasEventBridge = false;
|
||||
disablePointer();
|
||||
Render.getConfig("RenderMainView.FadeEdit")["editFade"] = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,12 +138,87 @@
|
|||
wireEventBridge(onScreen);
|
||||
}
|
||||
|
||||
var isEditEnabled = false
|
||||
var noiseSphere
|
||||
var gradientSphere
|
||||
var selectedEntity
|
||||
var editedCategory
|
||||
|
||||
var FADE_MIN_SCALE = 0.001
|
||||
var FADE_MAX_SCALE = 10000.0
|
||||
|
||||
function parameterToValuePow(parameter, minValue, maxOverMinValue) {
|
||||
return minValue * Math.pow(maxOverMinValue, parameter);
|
||||
//return parameter
|
||||
}
|
||||
|
||||
function update(dt) {
|
||||
var gradientProperties = Entities.getEntityProperties(selectedEntity, ["position", "dimensions"]);
|
||||
if (gradientProperties!=undefined) {
|
||||
var pos = gradientProperties.position
|
||||
if (pos!=undefined) {
|
||||
var config = Render.getConfig("RenderMainView.Fade")
|
||||
//print("Center at "+pos.x+" "+pos.y+" "+pos.z)
|
||||
var dim = {x:config.baseSizeX, y:config.baseSizeY, z:config.baseSizeZ}
|
||||
dim.x = parameterToValuePow(dim.x, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE)
|
||||
dim.y = parameterToValuePow(dim.y, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE)
|
||||
dim.z = parameterToValuePow(dim.z, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE)
|
||||
if (editedCategory==4 || editedCategory==5) {
|
||||
dim.y = gradientProperties.dimensions.y
|
||||
pos.y = pos.y - gradientProperties.dimensions.y/2
|
||||
}
|
||||
Overlays.editOverlay(gradientSphere, { position: pos, dimensions: dim, alpha: config.baseLevel })
|
||||
dim.x = parameterToValuePow(config.noiseSizeX, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE)
|
||||
dim.y = parameterToValuePow(config.noiseSizeY, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE)
|
||||
dim.z = parameterToValuePow(config.noiseSizeZ, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE)
|
||||
Overlays.editOverlay(noiseSphere, { position: pos, dimensions: dim, alpha: config.noiseLevel })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Script.update.connect(update);
|
||||
|
||||
function loadConfiguration(fileUrl) {
|
||||
var config = Render.getConfig("RenderMainView.Fade")
|
||||
config.load(fileUrl)
|
||||
}
|
||||
|
||||
function saveConfiguration(fileUrl) {
|
||||
var config = Render.getConfig("RenderMainView.Fade")
|
||||
config.save(fileUrl)
|
||||
}
|
||||
|
||||
function fromQml(message) {
|
||||
tokens = message.split('*')
|
||||
//print("Received '"+message+"' from transition.qml")
|
||||
command = tokens[0].toLowerCase()
|
||||
if (command=="category") {
|
||||
editedCategory = parseInt(tokens[1])
|
||||
} else if (command=="save") {
|
||||
var filePath = tokens[1]
|
||||
print("Raw token = "+filePath)
|
||||
if (filePath.startsWith("file:///")) {
|
||||
filePath = filePath.substr(8)
|
||||
print("Saving configuration to "+filePath)
|
||||
saveConfiguration(filePath)
|
||||
} else {
|
||||
print("Configurations can only be saved to local files")
|
||||
}
|
||||
} else if (command=="load") {
|
||||
var filePath = tokens[1]
|
||||
if (filePath.startsWith("file:///")) {
|
||||
filePath = filePath.substr(8)
|
||||
print("Loading configuration from "+filePath)
|
||||
loadConfiguration(filePath)
|
||||
} else {
|
||||
print("Configurations can only be loaded from local files")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button.clicked.connect(onClicked);
|
||||
tablet.screenChanged.connect(onScreenChanged);
|
||||
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
|
@ -81,4 +228,28 @@
|
|||
tablet.removeButton(button);
|
||||
});
|
||||
|
||||
|
||||
var currentSelectionName = ""
|
||||
var SelectionList = "TransitionEdit"
|
||||
|
||||
Selection.enableListToScene(SelectionList)
|
||||
Selection.clearSelectedItemsList(SelectionList)
|
||||
|
||||
Entities.clickDownOnEntity.connect(function (id, event) {
|
||||
if (selectedEntity) {
|
||||
Selection.removeFromSelectedItemsList(SelectionList, "entity", selectedEntity)
|
||||
}
|
||||
selectedEntity = id
|
||||
Selection.addToSelectedItemsList(SelectionList, "entity", selectedEntity)
|
||||
update()
|
||||
})
|
||||
|
||||
function cleanup() {
|
||||
disablePointer();
|
||||
Selection.removeListFromMap(SelectionList)
|
||||
Selection.disableListToScene(SelectionList);
|
||||
Overlays.deleteOverlay(noiseSphere);
|
||||
Overlays.deleteOverlay(gradientSphere);
|
||||
}
|
||||
Script.scriptEnding.connect(cleanup);
|
||||
}());
|
|
@ -11,6 +11,7 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Dialogs 1.0
|
||||
|
||||
import "qrc:///qml/styles-uit"
|
||||
import "qrc:///qml/controls-uit" as HifiControls
|
||||
|
@ -22,11 +23,31 @@ Rectangle {
|
|||
id: root
|
||||
anchors.margins: hifi.dimensions.contentMargin.x
|
||||
|
||||
signal sendToScript(var message);
|
||||
|
||||
color: hifi.colors.baseGray;
|
||||
|
||||
property var config: Render.getConfig("RenderMainView.Fade");
|
||||
property var configEdit: Render.getConfig("RenderMainView.FadeEdit");
|
||||
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
title: "Please choose a file"
|
||||
folder: shortcuts.documents
|
||||
nameFilters: [ "JSON files (*.json)", "All files (*)" ]
|
||||
onAccepted: {
|
||||
root.sendToScript(title.split(" ")[0]+"*"+fileUrl.toString())
|
||||
// This is a hack to be sure the widgets below properly reflect the change of category: delete the Component
|
||||
// by setting the loader source to Null and then recreate it 500ms later
|
||||
paramWidgetLoader.sourceComponent = undefined;
|
||||
postpone.interval = 500
|
||||
postpone.start()
|
||||
}
|
||||
onRejected: {
|
||||
}
|
||||
Component.onCompleted: visible = false
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 3
|
||||
anchors.left: parent.left
|
||||
|
@ -37,23 +58,14 @@ Rectangle {
|
|||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
spacing: 8
|
||||
Layout.fillWidth: true
|
||||
id: root_col
|
||||
|
||||
HifiControls.CheckBox {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
boxSize: 20
|
||||
text: "Edit"
|
||||
checked: root.configEdit["editFade"]
|
||||
onCheckedChanged: {
|
||||
root.configEdit["editFade"] = checked;
|
||||
Render.getConfig("RenderMainView.DrawFadedOpaqueBounds").enabled = checked;
|
||||
}
|
||||
}
|
||||
HifiControls.ComboBox {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
Layout.fillWidth: true
|
||||
anchors.left : parent.left
|
||||
width: 300
|
||||
id: categoryBox
|
||||
model: ["Elements enter/leave domain", "Bubble isect. - Owner POV", "Bubble isect. - Trespasser POV", "Another user leaves/arrives", "Changing an avatar"]
|
||||
Timer {
|
||||
|
@ -61,17 +73,48 @@ Rectangle {
|
|||
interval: 100; running: false; repeat: false
|
||||
onTriggered: {
|
||||
paramWidgetLoader.sourceComponent = paramWidgets
|
||||
var isTimeBased = categoryBox.currentIndex==0 || categoryBox.currentIndex==3
|
||||
paramWidgetLoader.item.isTimeBased = isTimeBased
|
||||
}
|
||||
}
|
||||
onCurrentIndexChanged: {
|
||||
var descriptions = [
|
||||
"Time based threshold, gradients centered on object",
|
||||
"Fixed threshold, gradients centered on owner avatar",
|
||||
"Position based threshold (increases when trespasser moves closer to avatar), gradients centered on trespasser avatar",
|
||||
"Time based threshold, gradients centered on bottom of object",
|
||||
"UNSUPPORTED"
|
||||
]
|
||||
|
||||
description.text = descriptions[currentIndex]
|
||||
root.config["editedCategory"] = currentIndex;
|
||||
// This is a hack to be sure the widgets below properly reflect the change of category: delete the Component
|
||||
// by setting the loader source to Null and then recreate it 100ms later
|
||||
paramWidgetLoader.sourceComponent = undefined;
|
||||
postpone.interval = 100
|
||||
postpone.start()
|
||||
root.sendToScript("category*"+currentIndex)
|
||||
}
|
||||
}
|
||||
HifiControls.Button {
|
||||
action: saveAction
|
||||
Layout.fillWidth: true
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
HifiControls.Button {
|
||||
action: loadAction
|
||||
Layout.fillWidth: true
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
HifiControls.Label {
|
||||
id: description
|
||||
text: "..."
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
|
@ -104,19 +147,18 @@ Rectangle {
|
|||
id: saveAction
|
||||
text: "Save"
|
||||
onTriggered: {
|
||||
root.config.save()
|
||||
fileDialog.title = "Save configuration..."
|
||||
fileDialog.selectExisting = false
|
||||
fileDialog.open()
|
||||
}
|
||||
}
|
||||
Action {
|
||||
id: loadAction
|
||||
text: "Load"
|
||||
onTriggered: {
|
||||
root.config.load()
|
||||
// This is a hack to be sure the widgets below properly reflect the change of category: delete the Component
|
||||
// by setting the loader source to Null and then recreate it 500ms later
|
||||
paramWidgetLoader.sourceComponent = undefined;
|
||||
postpone.interval = 500
|
||||
postpone.start()
|
||||
fileDialog.title = "Load configuration..."
|
||||
fileDialog.selectExisting = true
|
||||
fileDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,13 +170,8 @@ Rectangle {
|
|||
ColumnLayout {
|
||||
spacing: 3
|
||||
width: root_col.width
|
||||
property bool isTimeBased
|
||||
|
||||
HifiControls.CheckBox {
|
||||
text: "Invert"
|
||||
boxSize: 20
|
||||
checked: root.config["isInverted"]
|
||||
onCheckedChanged: { root.config["isInverted"] = checked }
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
@ -196,16 +233,32 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ConfigSlider {
|
||||
RowLayout {
|
||||
spacing: 20
|
||||
height: 36
|
||||
label: "Edge Width"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeWidth"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
|
||||
HifiControls.CheckBox {
|
||||
text: "Invert gradient"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
boxSize: 20
|
||||
checked: root.config["isInverted"]
|
||||
onCheckedChanged: { root.config["isInverted"] = checked }
|
||||
}
|
||||
ConfigSlider {
|
||||
anchors.left: undefined
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
height: 36
|
||||
width: 300
|
||||
label: "Edge Width"
|
||||
integral: false
|
||||
config: root.config
|
||||
property: "edgeWidth"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
|
@ -278,6 +331,8 @@ Rectangle {
|
|||
Layout.fillWidth: true
|
||||
|
||||
ConfigSlider {
|
||||
enabled: isTimeBased
|
||||
opacity: isTimeBased ? 1.0 : 0.0
|
||||
anchors.left: undefined
|
||||
anchors.right: undefined
|
||||
Layout.fillWidth: true
|
||||
|
@ -290,6 +345,8 @@ Rectangle {
|
|||
min: 0.1
|
||||
}
|
||||
HifiControls.ComboBox {
|
||||
enabled: isTimeBased
|
||||
opacity: isTimeBased ? 1.0 : 0.0
|
||||
Layout.fillWidth: true
|
||||
model: ["Linear", "Ease In", "Ease Out", "Ease In / Out"]
|
||||
currentIndex: root.config["timing"]
|
||||
|
@ -364,20 +421,6 @@ Rectangle {
|
|||
id: paramWidgetLoader
|
||||
sourceComponent: paramWidgets
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Button {
|
||||
action: saveAction
|
||||
}
|
||||
Button {
|
||||
action: loadAction
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue