diff --git a/libraries/render-utils/src/PickItemsJob.cpp b/libraries/render-utils/src/PickItemsJob.cpp new file mode 100644 index 0000000000..4665a45989 --- /dev/null +++ b/libraries/render-utils/src/PickItemsJob.cpp @@ -0,0 +1,51 @@ +// +// PickItemsJob.cpp +// render-utils/src/ +// +// Created by Olivier Prat on 08/08/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 "PickItemsJob.h" + +void PickItemsJob::configure(const Config& config) { + _isEnabled = config.isEnabled; +} + +void PickItemsJob::run(const render::RenderContextPointer& renderContext, const PickItemsJob::Input& input, PickItemsJob::Output& output) { + output.clear(); + + if (_isEnabled) { + float minIsectDistance = std::numeric_limits::max(); + auto& itemBounds = input; + auto itemID = findNearestItem(renderContext, itemBounds, minIsectDistance); + + if (render::Item::isValidID(itemID)) { + output.emplace_back(itemID); + } + } +} + +render::ItemID PickItemsJob::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 + +class PickItemsConfig : public render::Job::Config { + Q_OBJECT + Q_PROPERTY(bool isEnabled MEMBER isEnabled NOTIFY dirty) + +public: + + bool isEnabled{ false }; + +signals: + + void dirty(); +}; + +class PickItemsJob { + +public: + + using Config = PickItemsConfig; + using Input = render::ItemBounds; + using Output = render::ItemBounds; + using JobModel = render::Job::ModelIO; + + PickItemsJob() {} + + void configure(const Config& config); + void run(const render::RenderContextPointer& renderContext, const PickItemsJob::Input& input, PickItemsJob::Output& output); + +private: + + bool _isEnabled{ false }; + + render::ItemID findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const; +}; + +#endif // hifi_render_utils_PickItemsJob_h + +