extend the set of interface for multi highlight

This commit is contained in:
samcake 2017-11-21 17:59:45 -08:00
parent aa163db4e6
commit 1514cdfb2f
11 changed files with 729 additions and 163 deletions

View file

@ -72,28 +72,29 @@ bool SelectionScriptingInterface::removeFromSelectedItemsList(const QString& lis
}
bool SelectionScriptingInterface::clearSelectedItemsList(const QString& listName) {
// QWriteLocker lock(&_selectionListsLock);
_selectedItemsListMap.insert(listName, GameplayObjects());
{
QWriteLocker lock(&_selectionListsLock);
_selectedItemsListMap.insert(listName, GameplayObjects());
}
onSelectedItemsListChanged(listName);
return true;
}
bool SelectionScriptingInterface::enableListHighlight(const QString& listName, const QVariantMap& highlightStyleValues) {
// QWriteLocker lock(&_selectionListsLock);
QWriteLocker lock(&_highlightStylesLock);
auto highlightStyle = _highlightedListMap.find(listName);
if (highlightStyle == _highlightedListMap.end()) {
highlightStyle = _highlightedListMap.insert(listName, SelectionHighlightStyle());
auto highlightStyle = _highlightStyleMap.find(listName);
if (highlightStyle == _highlightStyleMap.end()) {
highlightStyle = _highlightStyleMap.insert(listName, SelectionHighlightStyle());
}
if (!(*highlightStyle).isBoundToList()) {
auto currentList = _selectedItemsListMap.find(listName);
/* auto currentList = _selectedItemsListMap.find(listName);
if (currentList == _selectedItemsListMap.end()) {
_selectedItemsListMap.insert(listName, GameplayObjects());
}
}*/
setupHandler(listName);
(*highlightStyle).setBoundToList(true);
}
@ -113,33 +114,32 @@ bool SelectionScriptingInterface::enableListHighlight(const QString& listName, c
}
bool SelectionScriptingInterface::disableListHighlight(const QString& listName) {
// QWriteLocker lock(&_selectionListsLock);
auto highlightStyle = _highlightedListMap.find(listName);
if (highlightStyle != _highlightedListMap.end()) {
// if ((*highlightStyle).isBoundToList()) {
_highlightedListMap.erase(highlightStyle);
QWriteLocker lock(&_highlightStylesLock);
auto highlightStyle = _highlightStyleMap.find(listName);
if (highlightStyle != _highlightStyleMap.end()) {
if ((*highlightStyle).isBoundToList()) {
}
auto mainScene = qApp->getMain3DScene();
if (mainScene) {
render::Transaction transaction;
transaction.removeHighlightFromSelection(listName.toStdString());
mainScene->enqueueTransaction(transaction);
}
else {
qWarning() << "SelectionToSceneHandler::highlightStyleChanged(), Unexpected null scene, possibly during application shutdown";
}
// emit highlightStyleRemoved(listName);
_highlightStyleMap.erase(highlightStyle);
// }
auto mainScene = qApp->getMain3DScene();
if (mainScene) {
render::Transaction transaction;
transaction.removeHighlightFromSelection(listName.toStdString());
mainScene->enqueueTransaction(transaction);
}
else {
qWarning() << "SelectionToSceneHandler::highlightStyleChanged(), Unexpected null scene, possibly during application shutdown";
}
}
return true;
}
QVariantMap SelectionScriptingInterface::getListHighlightStyle(const QString& listName) const {
// QReadLocker lock(&_selectionListsLock);
auto highlightStyle = _highlightedListMap.find(listName);
if (highlightStyle == _highlightedListMap.end()) {
QReadLocker lock(&_highlightStylesLock);
auto highlightStyle = _highlightStyleMap.find(listName);
if (highlightStyle == _highlightStyleMap.end()) {
return QVariantMap();
} else {
return (*highlightStyle).toVariantMap();
@ -147,9 +147,9 @@ QVariantMap SelectionScriptingInterface::getListHighlightStyle(const QString& li
}
render::HighlightStyle SelectionScriptingInterface::getHighlightStyle(const QString& listName) const {
// QReadLocker lock(&_selectionListsLock);
auto highlightStyle = _highlightedListMap.find(listName);
if (highlightStyle == _highlightedListMap.end()) {
QReadLocker lock(&_highlightStylesLock);
auto highlightStyle = _highlightStyleMap.find(listName);
if (highlightStyle == _highlightStyleMap.end()) {
return render::HighlightStyle();
} else {
return (*highlightStyle).getStyle();
@ -157,25 +157,30 @@ render::HighlightStyle SelectionScriptingInterface::getHighlightStyle(const QStr
}
template <class T> bool SelectionScriptingInterface::addToGameplayObjects(const QString& listName, T idToAdd) {
// QWriteLocker lock(&_selectionListsLock);
GameplayObjects currentList = _selectedItemsListMap.value(listName);
currentList.addToGameplayObjects(idToAdd);
_selectedItemsListMap.insert(listName, currentList);
{
QWriteLocker lock(&_selectionListsLock);
GameplayObjects currentList = _selectedItemsListMap.value(listName);
currentList.addToGameplayObjects(idToAdd);
_selectedItemsListMap.insert(listName, currentList);
}
onSelectedItemsListChanged(listName);
return true;
}
template <class T> bool SelectionScriptingInterface::removeFromGameplayObjects(const QString& listName, T idToRemove) {
// QWriteLocker lock(&_selectionListsLock);
GameplayObjects currentList = _selectedItemsListMap.value(listName);
if (currentList.getContainsData()) {
currentList.removeFromGameplayObjects(idToRemove);
_selectedItemsListMap.insert(listName, currentList);
bool listExist = false;
{
QWriteLocker lock(&_selectionListsLock);
auto currentList = _selectedItemsListMap.find(listName);
if (currentList != _selectedItemsListMap.end()) {
listExist = true;
(*currentList).removeFromGameplayObjects(idToRemove);
}
}
if (listExist) {
onSelectedItemsListChanged(listName);
return true;
} else {
}
else {
return false;
}
}
@ -184,12 +189,12 @@ template <class T> bool SelectionScriptingInterface::removeFromGameplayObjects(c
//
GameplayObjects SelectionScriptingInterface::getList(const QString& listName) {
// QReadLocker lock(&_selectionListsLock);
QReadLocker lock(&_selectionListsLock);
return _selectedItemsListMap.value(listName);
}
void SelectionScriptingInterface::printList(const QString& listName) {
// QReadLocker lock(&_selectionListsLock);
QReadLocker lock(&_selectionListsLock);
auto currentList = _selectedItemsListMap.find(listName);
if (currentList != _selectedItemsListMap.end()) {
if ((*currentList).getContainsData()) {
@ -222,8 +227,12 @@ void SelectionScriptingInterface::printList(const QString& listName) {
}
bool SelectionScriptingInterface::removeListFromMap(const QString& listName) {
// QWriteLocker lock(&_selectionListsLock);
if (_selectedItemsListMap.remove(listName)) {
bool removed = false;
{
QWriteLocker lock(&_selectionListsLock);
bool removed = _selectedItemsListMap.remove(listName);
}
if (removed) {
onSelectedItemsListChanged(listName);
return true;
} else {
@ -232,24 +241,25 @@ bool SelectionScriptingInterface::removeListFromMap(const QString& listName) {
}
void SelectionScriptingInterface::setupHandler(const QString& selectionName) {
// QWriteLocker lock(&_selectionListsLock);
QWriteLocker lock(&_selectionHandlersLock);
auto handler = _handlerMap.find(selectionName);
if (handler == _handlerMap.end()) {
handler = _handlerMap.insert(selectionName, new SelectionToSceneHandler());
}
(*handler)->initialize(selectionName);
// connect(this, &SelectionScriptingInterface::selectedItemsListChanged, handler.value(), &SelectionToSceneHandler::selectedItemsListChanged);
}
void SelectionScriptingInterface::onSelectedItemsListChanged(const QString& listName) {
// QWriteLocker lock(&_selectionListsLock);
auto handler = _handlerMap.find(listName);
if (handler != _handlerMap.end()) {
(*handler)->updateSceneFromSelectedList();
{
QWriteLocker lock(&_selectionHandlersLock);
auto handler = _handlerMap.find(listName);
if (handler != _handlerMap.end()) {
(*handler)->updateSceneFromSelectedList();
}
}
emit selectedItemsListChanged(listName);
}
@ -312,66 +322,65 @@ void SelectionToSceneHandler::updateSceneFromSelectedList() {
qWarning() << "SelectionToSceneHandler::updateRendererSelectedList(), Unexpected null scene, possibly during application shutdown";
}
}
/*
void SelectionToSceneHandler::highlightStyleChanged(const QString& listName) {
if (listName == _listName) {
auto mainScene = qApp->getMain3DScene();
if (mainScene) {
auto thisStyle = DependencyManager::get<SelectionScriptingInterface>()->getHighlightStyle(listName);
render::Transaction transaction;
transaction.resetSelectionHighlight(listName.toStdString(), thisStyle);
mainScene->enqueueTransaction(transaction);
}
else {
qWarning() << "SelectionToSceneHandler::highlightStyleChanged(), Unexpected null scene, possibly during application shutdown";
}
}
}
void SelectionToSceneHandler::highlightStyleRemoved(const QString& listName) {
if (listName == _listName) {
auto mainScene = qApp->getMain3DScene();
if (mainScene) {
render::Transaction transaction;
transaction.removeHighlightFromSelection(listName.toStdString());
mainScene->enqueueTransaction(transaction);
}
else {
qWarning() << "SelectionToSceneHandler::highlightStyleRemoved(), Unexpected null scene, possibly during application shutdown";
}
}
}
*/
bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
auto outlineColor = properties["outlineColor"];
if (outlineColor.isValid()) {
auto colorVariant = properties["outlineUnoccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(properties["outlineColor"], isValid);
auto color = xColorFromVariant(colorVariant, isValid);
if (isValid) {
_style.color = toGlm(color);
_style._outlineUnoccluded.color = toGlm(color);
}
}
colorVariant = properties["outlineOccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
if (isValid) {
_style._outlineOccluded.color = toGlm(color);
}
}
colorVariant = properties["fillUnoccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
if (isValid) {
_style._fillUnoccluded.color = toGlm(color);
}
}
colorVariant = properties["fillOccludedColor"];
if (colorVariant.isValid()) {
bool isValid;
auto color = xColorFromVariant(colorVariant, isValid);
if (isValid) {
_style._fillOccluded.color = toGlm(color);
}
}
auto intensityVariant = properties["outlineUnoccludedIntensity"];
if (intensityVariant.isValid()) {
_style._outlineUnoccluded.alpha = intensityVariant.toFloat();
}
intensityVariant = properties["outlineOccludedIntensity"];
if (intensityVariant.isValid()) {
_style._outlineOccluded.alpha = intensityVariant.toFloat();
}
intensityVariant = properties["fillUnoccludedIntensity"];
if (intensityVariant.isValid()) {
_style._fillUnoccluded.alpha = intensityVariant.toFloat();
}
intensityVariant = properties["fillOccludedIntensity"];
if (intensityVariant.isValid()) {
_style._fillOccluded.alpha = intensityVariant.toFloat();
}
auto outlineWidth = properties["outlineWidth"];
if (outlineWidth.isValid()) {
_style.outlineWidth = outlineWidth.toFloat();
_style._outlineWidth = outlineWidth.toFloat();
}
auto isOutlineSmooth = properties["isOutlineSmooth"];
if (isOutlineSmooth.isValid()) {
_style.isOutlineSmooth = isOutlineSmooth.toBool();
}
auto outlineIntensity = properties["outlineIntensity"];
if (outlineIntensity.isValid()) {
_style.outlineIntensity = outlineIntensity.toFloat();
}
auto unoccludedFillOpacity = properties["unoccludedFillOpacity"];
if (unoccludedFillOpacity.isValid()) {
_style.unoccludedFillOpacity = unoccludedFillOpacity.toFloat();
}
auto occludedFillOpacity = properties["occludedFillOpacity"];
if (occludedFillOpacity.isValid()) {
_style.occludedFillOpacity = occludedFillOpacity.toFloat();
_style._isOutlineSmooth = isOutlineSmooth.toBool();
}
return true;
@ -380,12 +389,18 @@ bool SelectionHighlightStyle::fromVariantMap(const QVariantMap& properties) {
QVariantMap SelectionHighlightStyle::toVariantMap() const {
QVariantMap properties;
properties["outlineColor"] = xColorToVariant(xColorFromGlm(_style.color));
properties["outlineWidth"] = _style.outlineWidth;
properties["isOutlineSmooth"] = _style.isOutlineSmooth;
properties["outlineIntensity"] = _style.outlineIntensity;
properties["unoccludedFillOpacity"] = _style.unoccludedFillOpacity;
properties["occludedFillOpacity"] = _style.occludedFillOpacity;
properties["outlineUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineUnoccluded.color));
properties["outlineOccludedColor"] = xColorToVariant(xColorFromGlm(_style._outlineOccluded.color));
properties["fillUnoccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillUnoccluded.color));
properties["fillOccludedColor"] = xColorToVariant(xColorFromGlm(_style._fillOccluded.color));
properties["outlineUnoccludedIntensity"] = _style._outlineUnoccluded.alpha;
properties["outlineOccludedIntensity"] = _style._outlineOccluded.alpha;
properties["fillUnoccludedIntensity"] = _style._fillUnoccluded.alpha;
properties["fillOccludedIntensity"] = _style._fillOccluded.alpha;
properties["outlineWidth"] = _style._outlineWidth;
properties["isOutlineSmooth"] = _style._isOutlineSmooth;
return properties;
}

View file

@ -147,9 +147,12 @@ private:
mutable QReadWriteLock _selectionListsLock;
QMap<QString, GameplayObjects> _selectedItemsListMap;
QMap<QString, SelectionHighlightStyle> _highlightedListMap;
mutable QReadWriteLock _selectionHandlersLock;
QMap<QString, SelectionToSceneHandler*> _handlerMap;
mutable QReadWriteLock _highlightStylesLock;
QMap<QString, SelectionHighlightStyle> _highlightStyleMap;
template <class T> bool addToGameplayObjects(const QString& listName, T idToAdd);
template <class T> bool removeFromGameplayObjects(const QString& listName, T idToRemove);

View file

@ -36,8 +36,6 @@ void main(void) {
// the blur will have a different width between the left / right sides and top / bottom
// sides of the silhouette
float highlightedDepth = texture(highlightedDepthMap, varTexCoord0).x;
float intensity = 0.0;
float isOccluded = 0.0;
if (highlightedDepth < FAR_Z) {
// We're not on the far plane so we are on the highlighted object, thus no outline to do!
@ -48,7 +46,11 @@ void main(void) {
highlightedDepth = -evalZeyeFromZdb(highlightedDepth);
sceneDepth = -evalZeyeFromZdb(sceneDepth);
intensity = sceneDepth < (highlightedDepth-LINEAR_DEPTH_BIAS) ? params._occludedFillOpacity : params._unoccludedFillOpacity;
if (sceneDepth < (highlightedDepth-LINEAR_DEPTH_BIAS)) {
outFragColor = vec4(params._fillOccludedColor, params._fillOccludedAlpha);
} else {
outFragColor = vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha);
}
<@else@>
discard;
<@endif@>
@ -62,8 +64,9 @@ void main(void) {
int x;
int y;
float outlinedDepth = 0;
float sumOutlineDepth = 0;
float intensity = 0.0;
float outlinedDepth = 0.0;
float sumOutlineDepth = 0.0;
for (y=0 ; y<params._blurKernelSize ; y++) {
uv = lineStartUv;
@ -96,21 +99,22 @@ void main(void) {
if (intensity < OPACITY_EPSILON) {
discard;
}
intensity = min(1.0, intensity / params._threshold) * params._intensity;
intensity = min(1.0, intensity / params._threshold);
// But we need to check the scene depth aginst the depth of the outline
// But we need to check the scene depth against the depth of the outline
float sceneDepth = texture(sceneDepthMap, texCoord0).x;
// Transform to linear depth for better precision
outlinedDepth = -evalZeyeFromZdb(sumOutlineDepth);
sceneDepth = -evalZeyeFromZdb(sceneDepth);
// Are we occluded?
if (sceneDepth < (outlinedDepth/*-LINEAR_DEPTH_BIAS*/)) {
isOccluded = 1.0;
outFragColor = vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha);
} else {
outFragColor = vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha);
}
}
outFragColor = vec4(mix(params._color.rgb, vec3(0.1,1,0.1), isOccluded), intensity);
}
<@endfunc@>

View file

@ -88,7 +88,7 @@ HighlightSharedParameters::HighlightSharedParameters() {
}
float HighlightSharedParameters::getBlurPixelWidth(const render::HighlightStyle& style, int frameBufferHeight) {
return ceilf(style.outlineWidth * frameBufferHeight / 400.0f);
return ceilf(style._outlineWidth * frameBufferHeight / 400.0f);
}
PrepareDrawHighlight::PrepareDrawHighlight() {
@ -267,14 +267,19 @@ void DrawHighlight::run(const render::RenderContextPointer& renderContext, const
{
auto& shaderParameters = _configuration.edit();
shaderParameters._color = highlight._style.color;
shaderParameters._intensity = highlight._style.outlineIntensity * (highlight._style.isOutlineSmooth ? 2.0f : 1.0f);
shaderParameters._unoccludedFillOpacity = highlight._style.unoccludedFillOpacity;
shaderParameters._occludedFillOpacity = highlight._style.occludedFillOpacity;
shaderParameters._threshold = highlight._style.isOutlineSmooth ? 1.0f : 1e-3f;
shaderParameters._blurKernelSize = std::min(7, std::max(2, (int)floorf(highlight._style.outlineWidth * 3 + 0.5f)));
shaderParameters._outlineUnoccludedColor = highlight._style._outlineUnoccluded.color;
shaderParameters._outlineUnoccludedAlpha = highlight._style._outlineUnoccluded.alpha * (highlight._style._isOutlineSmooth ? 2.0f : 1.0f);
shaderParameters._outlineOccludedColor = highlight._style._outlineOccluded.color;
shaderParameters._outlineOccludedAlpha = highlight._style._outlineOccluded.alpha * (highlight._style._isOutlineSmooth ? 2.0f : 1.0f);
shaderParameters._fillUnoccludedColor = highlight._style._fillUnoccluded.color;
shaderParameters._fillUnoccludedAlpha = highlight._style._fillUnoccluded.alpha;
shaderParameters._fillOccludedColor = highlight._style._fillOccluded.color;
shaderParameters._fillOccludedAlpha = highlight._style._fillOccluded.alpha;
shaderParameters._threshold = highlight._style._isOutlineSmooth ? 1.0f : 1e-3f;
shaderParameters._blurKernelSize = std::min(7, std::max(2, (int)floorf(highlight._style._outlineWidth * 3 + 0.5f)));
// Size is in normalized screen height. We decide that for highlight width = 1, this is equal to 1/400.
auto size = highlight._style.outlineWidth / 400.0f;
auto size = highlight._style._outlineWidth / 400.0f;
shaderParameters._size.x = (size * framebufferSize.y) / framebufferSize.x;
shaderParameters._size.y = size;
}

View file

@ -11,17 +11,18 @@
struct HighlightParameters
{
TVEC3 _color;
float _intensity;
TVEC3 _outlineUnoccludedColor;
float _outlineUnoccludedAlpha;
TVEC3 _outlineOccludedColor;
float _outlineOccludedAlpha;
TVEC3 _fillUnoccludedColor;
float _fillUnoccludedAlpha;
TVEC3 _fillOccludedColor;
float _fillOccludedAlpha;
TVEC2 _size;
float _unoccludedFillOpacity;
float _occludedFillOpacity;
float _threshold;
int _blurKernelSize;
float padding2;
float padding3;
float _threshold;
TVEC2 _size;
};
// <@if 1@>

View file

@ -61,42 +61,42 @@ void HighlightStageConfig::setSelectionName(const QString& name) {
}
void HighlightStageConfig::setOutlineSmooth(bool isSmooth) {
editStyle().isOutlineSmooth = isSmooth;
editStyle()._isOutlineSmooth = isSmooth;
emit dirty();
}
void HighlightStageConfig::setColorRed(float value) {
editStyle().color.r = value;
editStyle()._outlineUnoccluded.color.r = value;
emit dirty();
}
void HighlightStageConfig::setColorGreen(float value) {
editStyle().color.g = value;
editStyle()._outlineUnoccluded.color.g = value;
emit dirty();
}
void HighlightStageConfig::setColorBlue(float value) {
editStyle().color.b = value;
editStyle()._outlineUnoccluded.color.b = value;
emit dirty();
}
void HighlightStageConfig::setOutlineWidth(float value) {
editStyle().outlineWidth = value;
editStyle()._outlineWidth = value;
emit dirty();
}
void HighlightStageConfig::setOutlineIntensity(float value) {
editStyle().outlineIntensity = value;
editStyle()._outlineUnoccluded.alpha = value;
emit dirty();
}
void HighlightStageConfig::setUnoccludedFillOpacity(float value) {
editStyle().unoccludedFillOpacity = value;
editStyle()._fillUnoccluded.alpha = value;
emit dirty();
}
void HighlightStageConfig::setOccludedFillOpacity(float value) {
editStyle().occludedFillOpacity = value;
editStyle()._fillOccluded.alpha = value;
emit dirty();
}

View file

@ -83,28 +83,28 @@ namespace render {
QString getSelectionName() const { return QString(_selectionName.c_str()); }
void setSelectionName(const QString& name);
bool isOutlineSmooth() const { return getStyle().isOutlineSmooth; }
bool isOutlineSmooth() const { return getStyle()._isOutlineSmooth; }
void setOutlineSmooth(bool isSmooth);
float getColorRed() const { return getStyle().color.r; }
float getColorRed() const { return getStyle()._outlineUnoccluded.color.r; }
void setColorRed(float value);
float getColorGreen() const { return getStyle().color.g; }
float getColorGreen() const { return getStyle()._outlineUnoccluded.color.g; }
void setColorGreen(float value);
float getColorBlue() const { return getStyle().color.b; }
float getColorBlue() const { return getStyle()._outlineUnoccluded.color.b; }
void setColorBlue(float value);
float getOutlineWidth() const { return getStyle().outlineWidth; }
float getOutlineWidth() const { return getStyle()._outlineWidth; }
void setOutlineWidth(float value);
float getOutlineIntensity() const { return getStyle().outlineIntensity; }
float getOutlineIntensity() const { return getStyle()._outlineUnoccluded.alpha; }
void setOutlineIntensity(float value);
float getUnoccludedFillOpacity() const { return getStyle().unoccludedFillOpacity; }
float getUnoccludedFillOpacity() const { return getStyle()._fillUnoccluded.alpha; }
void setUnoccludedFillOpacity(float value);
float getOccludedFillOpacity() const { return getStyle().occludedFillOpacity; }
float getOccludedFillOpacity() const { return getStyle()._fillOccluded.alpha; }
void setOccludedFillOpacity(float value);
std::string _selectionName{ "contextOverlayHighlightList" };

View file

@ -20,17 +20,22 @@ namespace render {
// This holds the configuration for a particular outline style
class HighlightStyle {
public:
struct RGBA {
glm::vec3 color{ 1.f, 0.7f, 0.2f };
float alpha{ 0.9f };
};
RGBA _outlineUnoccluded{ { 1.f, 0.7f, 0.2f }, 0.9f };
RGBA _outlineOccluded{ { 0.2f, 0.7f, 1.0f }, 0.9f };
RGBA _fillUnoccluded{ { 1.f, 0.2f, 0.7f }, 0.0f };
RGBA _fillOccluded{ { 0.7f, 1.f, 0.2f }, 0.0f };
float _outlineWidth{ 2.0f };
bool _isOutlineSmooth{ false };
bool isFilled() const {
return unoccludedFillOpacity > 5e-3f || occludedFillOpacity > 5e-3f;
return _fillUnoccluded.alpha > 5e-3f || _fillOccluded.alpha > 5e-3f;
}
glm::vec3 color{ 1.f, 0.7f, 0.2f };
float outlineWidth{ 2.0f };
float outlineIntensity{ 0.9f };
float unoccludedFillOpacity{ 0.0f };
float occludedFillOpacity{ 0.0f };
bool isOutlineSmooth{ false };
};
}

View file

@ -9,6 +9,111 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
"use strict";
//
// Luci.js
// tablet-engine app
//
// 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
//
(function() {
var TABLET_BUTTON_NAME = "Highlight";
var QMLAPP_URL = Script.resolvePath("./highlight.qml");
var ICON_URL = Script.resolvePath("../../../system/assets/images/luci-i.svg");
var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/luci-a.svg");
var onLuciScreen = false;
function onClicked() {
if (onLuciScreen) {
tablet.gotoHomeScreen();
} else {
tablet.loadQMLSource(QMLAPP_URL);
}
}
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var button = tablet.addButton({
text: TABLET_BUTTON_NAME,
icon: ICON_URL,
activeIcon: ACTIVE_ICON_URL,
sortOrder: 1
});
var hasEventBridge = false;
function wireEventBridge(on) {
if (!tablet) {
print("Warning in wireEventBridge(): 'tablet' undefined!");
return;
}
if (on) {
if (!hasEventBridge) {
tablet.fromQml.connect(fromQml);
hasEventBridge = true;
}
} else {
if (hasEventBridge) {
tablet.fromQml.disconnect(fromQml);
hasEventBridge = false;
}
}
}
function onScreenChanged(type, url) {
if (url === QMLAPP_URL) {
onLuciScreen = true;
} else {
onLuciScreen = false;
}
button.editProperties({isActive: onLuciScreen});
wireEventBridge(onLuciScreen);
}
function fromQml(message) {
}
button.clicked.connect(onClicked);
tablet.screenChanged.connect(onScreenChanged);
var moveDebugCursor = false;
Controller.mousePressEvent.connect(function (e) {
if (e.isMiddleButton) {
moveDebugCursor = true;
setDebugCursor(e.x, e.y);
}
});
Controller.mouseReleaseEvent.connect(function() { moveDebugCursor = false; });
Controller.mouseMoveEvent.connect(function (e) { if (moveDebugCursor) setDebugCursor(e.x, e.y); });
Script.scriptEnding.connect(function () {
if (onLuciScreen) {
tablet.gotoHomeScreen();
}
button.clicked.disconnect(onClicked);
tablet.screenChanged.disconnect(onScreenChanged);
tablet.removeButton(button);
});
function setDebugCursor(x, y) {
nx = (x / Window.innerWidth);
ny = 1.0 - ((y) / (Window.innerHeight - 32));
Render.getConfig("RenderMainView").getConfig("Antialiasing").debugCursorTexcoord = { x: nx, y: ny };
}
}());
// Set up the qml ui
var qml = Script.resolvePath('highlight.qml');
var window = new OverlayWindow({

View file

@ -0,0 +1,251 @@
//
// debugHighlight.js
// developer/utilities/render
//
// Olivier Prat, created on 08/08/2017.
// 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
//
"use strict";
//
// Luci.js
// tablet-engine app
//
// 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
//
(function() {
var TABLET_BUTTON_NAME = "Highlight";
var QMLAPP_URL = Script.resolvePath("./highlight2.qml");
var ICON_URL = Script.resolvePath("../../../system/assets/images/luci-i.svg");
var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/luci-a.svg");
var onLuciScreen = false;
function onClicked() {
if (onLuciScreen) {
tablet.gotoHomeScreen();
} else {
tablet.loadQMLSource(QMLAPP_URL);
}
}
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
var button = tablet.addButton({
text: TABLET_BUTTON_NAME,
icon: ICON_URL,
activeIcon: ACTIVE_ICON_URL,
sortOrder: 1
});
var hasEventBridge = false;
function wireEventBridge(on) {
if (!tablet) {
print("Warning in wireEventBridge(): 'tablet' undefined!");
return;
}
if (on) {
if (!hasEventBridge) {
tablet.fromQml.connect(fromQml);
hasEventBridge = true;
}
} else {
if (hasEventBridge) {
tablet.fromQml.disconnect(fromQml);
hasEventBridge = false;
}
}
}
function onScreenChanged(type, url) {
if (url === QMLAPP_URL) {
onLuciScreen = true;
} else {
onLuciScreen = false;
}
button.editProperties({isActive: onLuciScreen});
wireEventBridge(onLuciScreen);
}
function fromQml(message) {
}
button.clicked.connect(onClicked);
tablet.screenChanged.connect(onScreenChanged);
var moveDebugCursor = false;
Controller.mousePressEvent.connect(function (e) {
if (e.isMiddleButton) {
moveDebugCursor = true;
setDebugCursor(e.x, e.y);
}
});
Controller.mouseReleaseEvent.connect(function() { moveDebugCursor = false; });
Controller.mouseMoveEvent.connect(function (e) { if (moveDebugCursor) setDebugCursor(e.x, e.y); });
Script.scriptEnding.connect(function () {
if (onLuciScreen) {
tablet.gotoHomeScreen();
}
button.clicked.disconnect(onClicked);
tablet.screenChanged.disconnect(onScreenChanged);
tablet.removeButton(button);
});
function setDebugCursor(x, y) {
}
}());
// Set up the qml ui
// Created by Sam Gondelman on 9/7/2017
// 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
/*
(function() { // BEGIN LOCAL_SCOPE
var END_DIMENSIONS = {
x: 0.15,
y: 0.15,
z: 0.15
};
var COLOR = {red: 97, green: 247, blue: 255};
var end = {
type: "sphere",
dimensions: END_DIMENSIONS,
color: COLOR,
ignoreRayIntersection: true,
alpha: 1.0,
visible: true
}
var COLOR2 = {red: 247, green: 97, blue: 255};
var end2 = {
type: "sphere",
dimensions: END_DIMENSIONS,
color: COLOR2,
ignoreRayIntersection: true,
alpha: 1.0,
visible: true
}
var highlightGroupIndex = 0
var isSelectionAddEnabled = false
var isSelectionEnabled = false
var renderStates = [{name: "test", end: end}];
var defaultRenderStates = [{name: "test", distance: 20.0, end: end2}];
var time = 0
var ray = LaserPointers.createLaserPointer({
joint: "Mouse",
filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS | RayPick.PICK_AVATARS | RayPick.PICK_INVISIBLE | RayPick.PICK_NONCOLLIDABLE,
renderStates: renderStates,
defaultRenderStates: defaultRenderStates,
enabled: false
});
function getSelectionName() {
var selectionName = "contextOverlayHighlightList"
if (highlightGroupIndex>0) {
selectionName += highlightGroupIndex
}
return selectionName
}
function fromQml(message) {
tokens = message.split(' ')
print("Received '"+message+"' from hightlight.qml")
if (tokens[0]=="highlight") {
highlightGroupIndex = parseInt(tokens[1])
print("Switching to highlight group "+highlightGroupIndex)
} else if (tokens[0]=="pick") {
isSelectionEnabled = tokens[1]=='true'
print("Ray picking set to "+isSelectionEnabled.toString())
if (isSelectionEnabled) {
LaserPointers.enableLaserPointer(ray)
} else {
LaserPointers.disableLaserPointer(ray)
}
time = 0
} else if (tokens[0]=="add") {
isSelectionAddEnabled = tokens[1]=='true'
print("Add to selection set to "+isSelectionAddEnabled.toString())
if (!isSelectionAddEnabled) {
Selection.clearSelectedItemsList(getSelectionName())
}
}
}
window.fromQml.connect(fromQml);
function cleanup() {
LaserPointers.removeLaserPointer(ray);
}
Script.scriptEnding.connect(cleanup);
var prevID = 0
var prevType = ""
var selectedID = 0
var selectedType = ""
function update(deltaTime) {
// you have to do this repeatedly because there's a bug but I'll fix it
LaserPointers.setRenderState(ray, "test");
var result = LaserPointers.getPrevRayPickResult(ray);
var selectionName = getSelectionName()
if (isSelectionEnabled && result.type != RayPick.INTERSECTED_NONE) {
time += deltaTime
if (result.objectID != prevID) {
var typeName = ""
if (result.type == RayPick.INTERSECTED_ENTITY) {
typeName = "entity"
} else if (result.type == RayPick.INTERSECTED_OVERLAY) {
typeName = "overlay"
} else if (result.type == RayPick.INTERSECTED_AVATAR) {
typeName = "avatar"
}
prevID = result.objectID;
prevType = typeName;
time = 0
} else if (time>1.0 && prevID!=selectedID) {
if (prevID != 0 && !isSelectionAddEnabled) {
Selection.removeFromSelectedItemsList(selectionName, selectedType, selectedID)
}
selectedID = prevID
selectedType = prevType
Selection.addToSelectedItemsList(selectionName, selectedType, selectedID)
print("HIGHLIGHT " + highlightGroupIndex + " picked type: " + result.type + ", id: " + result.objectID);
}
} else {
if (prevID != 0 && !isSelectionAddEnabled) {
Selection.removeFromSelectedItemsList(selectionName, prevType, prevID)
}
prevID = 0
selectedID = 0
time = 0
}
}
Script.update.connect(update);
}()); // END LOCAL_SCOPE*/

View file

@ -0,0 +1,177 @@
//
// highlight.qml
// developer/utilities/render
//
// Olivier Prat, created on 08/08/2017.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import "qrc:///qml/styles-uit"
import "qrc:///qml/controls-uit" as HifiControls
import "configSlider"
Rectangle {
id: root
HifiConstants { id: hifi;}
color: hifi.colors.baseGray;
anchors.margins: hifi.dimensions.contentMargin.x
property var debugConfig: Render.getConfig("RenderMainView.HighlightDebug")
property var highlightConfig: Render.getConfig("UpdateScene.HighlightStageSetup")
signal sendToScript(var message);
Column {
id: col
spacing: 10
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: hifi.dimensions.contentMargin.x
Row {
spacing: 10
anchors.left: parent.left
anchors.right: parent.right
HifiControls.CheckBox {
id: debug
text: "View Mask"
checked: root.debugConfig["viewMask"]
onCheckedChanged: {
root.debugConfig["viewMask"] = checked;
}
}
HifiControls.CheckBox {
text: "Hover select"
checked: false
onCheckedChanged: {
sendToScript("pick "+checked.toString())
}
}
HifiControls.CheckBox {
text: "Add to selection"
checked: false
onCheckedChanged: {
sendToScript("add "+checked.toString())
}
}
}
HifiControls.ComboBox {
id: box
width: 350
z: 999
editable: true
colorScheme: hifi.colorSchemes.dark
model: [
"contextOverlayHighlightList",
"highlightList1",
"highlightList2",
"highlightList3",
"highlightList4"]
label: ""
Timer {
id: postpone
interval: 100; running: false; repeat: false
onTriggered: { paramWidgetLoader.sourceComponent = paramWidgets }
}
onCurrentIndexChanged: {
root.highlightConfig["selectionName"] = model[currentIndex];
sendToScript("highlight "+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()
}
}
Loader {
id: paramWidgetLoader
sourceComponent: paramWidgets
width: 350
}
Component {
id: paramWidgets
Column {
spacing: 10
anchors.margins: hifi.dimensions.contentMargin.x
HifiControls.Label {
text: "Outline"
}
Column {
spacing: 10
anchors.left: parent.left
anchors.right: parent.right
HifiControls.CheckBox {
text: "Smooth"
checked: root.highlightConfig["isOutlineSmooth"]
onCheckedChanged: {
root.highlightConfig["isOutlineSmooth"] = checked;
}
}
Repeater {
model: ["Width:outlineWidth:5.0:0.0",
"Intensity:outlineIntensity:1.0:0.0"
]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: false
config: root.highlightConfig
property: modelData.split(":")[1]
max: modelData.split(":")[2]
min: modelData.split(":")[3]
}
}
}
Separator {}
HifiControls.Label {
text: "Color"
}
Repeater {
model: ["Red:colorR:1.0:0.0",
"Green:colorG:1.0:0.0",
"Blue:colorB:1.0:0.0"
]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: false
config: root.highlightConfig
property: modelData.split(":")[1]
max: modelData.split(":")[2]
min: modelData.split(":")[3]
}
}
Separator {}
HifiControls.Label {
text: "Fill Opacity"
}
Repeater {
model: ["Unoccluded:unoccludedFillOpacity:1.0:0.0",
"Occluded:occludedFillOpacity:1.0:0.0"
]
ConfigSlider {
label: qsTr(modelData.split(":")[0])
integral: false
config: root.highlightConfig
property: modelData.split(":")[1]
max: modelData.split(":")[2]
min: modelData.split(":")[3]
}
}
}
}
}
}