Skip to content
Snippets Groups Projects
Commit e3e408d7 authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Refactor collision touch

parent ffe15263
No related branches found
No related tags found
1 merge request!316Resolves #343 GUI and Frame Refactor
Pipeline #28343 passed
......@@ -18,6 +18,7 @@ set(STREAMSRC
src/renderer.cpp
src/renderers/screen_render.cpp
src/renderers/openvr_render.cpp
src/renderers/collisions.cpp
)
add_library(ftlstreams ${STREAMSRC})
......
#include "collisions.hpp"
#include <ftl/codecs/touch.hpp>
#include <ftl/utility/matrix_conversion.hpp>
#include <ftl/rgbd/capabilities.hpp>
#include <ftl/algorithms/dbscan.hpp>
using ftl::codecs::Channel;
using ftl::rgbd::Capability;
void ftl::render::collision2touch(const ftl::rgbd::Frame &rgbdframe, const std::vector<float4> &collisions, const std::list<ftl::data::FrameSetPtr> &sets, uint32_t myid) {
std::vector<float4> clusters;
std::vector<short> labels;
ftl::dbscan<float4>(collisions, [](const std::vector<float4> &pts, size_t idx, float radius) {
std::vector<size_t> neighbors;
for (auto i = 0u; i < pts.size(); i++) {
if (i == idx) {
continue;
}
float dx = pts[idx].x - pts[i].x;
float dy = pts[idx].y - pts[i].y;
if (dx*dx+dy*dy < radius*radius) {
neighbors.push_back(i);
}
}
return neighbors;
}, 5, 16.0f, labels, clusters);
// TODO: Support multi-touch
if (clusters.size() == 1) {
//LOG(INFO) << "Found " << clusters.size() << " collisions";
//LOG(INFO) << " -- " << clusters[0].x << "," << clusters[0].y << " " << clusters[0].z;
// Find all frames that support touch
for (auto &s : sets) {
if (s->frameset() == myid) continue;
for (const auto &f : s->frames) {
if (f.has(Channel::Capabilities)) {
const auto &cap = f.get<std::unordered_set<Capability>>(Channel::Capabilities);
// If it supports touch, calculate the touch points in screen coordinates
if (cap.count(Capability::TOUCH)){
const auto &rgbdf = f.cast<ftl::rgbd::Frame>();
auto pose = MatrixConversion::toCUDA((rgbdf.getPose().inverse() * rgbdframe.getPose()).cast<float>());
float3 campos = pose * rgbdframe.getLeft().screenToCam(clusters[0].x, clusters[0].y, clusters[0].z);
int2 pt = rgbdf.getLeft().camToScreen<int2>(campos);
//LOG(INFO) << "TOUCH AT " << pt.x << "," << pt.y << " - " << campos.z;
{
// Send the touch data
auto response = f.response();
auto &touches = response.create<std::vector<ftl::codecs::Touch>>(Channel::Touch);
auto &touch = touches.emplace_back();
touch.id = 0;
touch.x = pt.x;
touch.y = pt.y;
touch.type = ftl::codecs::TouchType::COLLISION;
touch.strength = 255;
touch.d = campos.z;
}
}
}
}
}
}
}
\ No newline at end of file
#ifndef _FTL_RENDER_COLLISIONS_HPP_
#define _FTL_RENDER_COLLISIONS_HPP_
#include <ftl/data/new_frameset.hpp>
#include <ftl/rgbd/frame.hpp>
namespace ftl {
namespace render {
void collision2touch(const ftl::rgbd::Frame &rgbdframe, const std::vector<float4> &collisions, const std::list<ftl::data::FrameSetPtr> &sets, uint32_t myid);
}
}
#endif
\ No newline at end of file
......@@ -4,13 +4,12 @@
#include <ftl/rgbd/capabilities.hpp>
#include <ftl/operators/antialiasing.hpp>
#include <ftl/operators/gt_analysis.hpp>
#include <ftl/algorithms/dbscan.hpp>
#include <ftl/utility/matrix_conversion.hpp>
#include <ftl/codecs/touch.hpp>
#include <loguru.hpp>
#include "screen_render.hpp"
#include "collisions.hpp"
using ftl::render::Source;
using ftl::render::ScreenRender;
......@@ -139,65 +138,9 @@ bool ScreenRender::retrieve(ftl::data::Frame &frame_out) {
post_pipe_->apply(rgbdframe, rgbdframe, 0);
const auto &collisions = renderer_->getCollisions();
std::vector<float4> clusters;
std::vector<short> labels;
ftl::dbscan<float4>(collisions, [](const std::vector<float4> &pts, size_t idx, float radius) {
std::vector<size_t> neighbors;
for (auto i = 0u; i < pts.size(); i++) {
if (i == idx) {
continue;
}
float dx = pts[idx].x - pts[i].x;
float dy = pts[idx].y - pts[i].y;
if (dx*dx+dy*dy < radius*radius) {
neighbors.push_back(i);
}
}
return neighbors;
}, 5, 16.0f, labels, clusters);
// TODO: Support multi-touch
if (clusters.size() == 1) {
//LOG(INFO) << "Found " << clusters.size() << " collisions";
//LOG(INFO) << " -- " << clusters[0].x << "," << clusters[0].y << " " << clusters[0].z;
// Find all frames that support touch
for (auto &s : sets) {
if (s->frameset() == my_id_) continue;
for (const auto &f : s->frames) {
if (f.has(Channel::Capabilities)) {
const auto &cap = f.get<std::unordered_set<Capability>>(Channel::Capabilities);
// If it supports touch, calculate the touch points
if (cap.count(Capability::TOUCH)){
const auto &rgbdf = f.cast<ftl::rgbd::Frame>();
auto pose = MatrixConversion::toCUDA((rgbdf.getPose().inverse() * rgbdframe.getPose()).cast<float>());
float3 campos = pose * rgbdframe.getLeft().screenToCam(clusters[0].x, clusters[0].y, clusters[0].z);
int2 pt = rgbdf.getLeft().camToScreen<int2>(campos);
//LOG(INFO) << "TOUCH AT " << pt.x << "," << pt.y << " - " << campos.z;
{
// Send the touch data
auto response = f.response();
auto &touches = response.create<std::vector<ftl::codecs::Touch>>(Channel::Touch);
auto &touch = touches.emplace_back();
touch.id = 0;
touch.x = pt.x;
touch.y = pt.y;
touch.type = ftl::codecs::TouchType::COLLISION;
touch.strength = 255;
touch.d = campos.z;
}
}
}
if (host_->value("enable_touch", false)) {
ftl::render::collision2touch(rgbdframe, renderer_->getCollisions(), sets, my_id_);
}
}
}
return true;
} else {
//LOG(INFO) << "Render fail";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment