mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 15:53:35 +02:00
Fade edited objects are now selected with ray picking
This commit is contained in:
parent
47437c9564
commit
143a315f1d
5 changed files with 137 additions and 62 deletions
interface/src/scripting
libraries/render-utils/src
scripts/developer/utilities/render
|
@ -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 };
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
|
||||
button.clicked.connect(onClicked);
|
||||
tablet.screenChanged.connect(onScreenChanged);
|
||||
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
if (onScreen) {
|
||||
tablet.gotoHomeScreen();
|
||||
|
@ -81,4 +81,52 @@
|
|||
tablet.removeButton(button);
|
||||
});
|
||||
|
||||
|
||||
// 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 = 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");
|
||||
|
||||
var currentSelectionName = ""
|
||||
var SelectionList = "TransitionEdit"
|
||||
var selectedEntity = null
|
||||
Pointers.enablePointer(laser)
|
||||
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)
|
||||
})
|
||||
|
||||
function cleanup() {
|
||||
Pointers.disablePointer(laser)
|
||||
Pointers.removePointer(ray);
|
||||
Selection.removeListFromMap(SelectionList)
|
||||
Selection.disableListToScene(SelectionList);
|
||||
}
|
||||
|
||||
}());
|
Loading…
Reference in a new issue