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

WIP add some OpenVR support code

parent 34d4143a
Branches
No related tags found
1 merge request!316Resolves #343 GUI and Frame Refactor
Pipeline #28211 failed
......@@ -17,6 +17,7 @@ set(STREAMSRC
src/builder.cpp
src/renderer.cpp
src/renderers/screen_render.cpp
src/renderers/openvr_render.cpp
)
add_library(ftlstreams ${STREAMSRC})
......
......@@ -5,6 +5,7 @@
#include <loguru.hpp>
#include "./renderers/screen_render.hpp"
#include "./renderers/openvr_render.hpp"
using ftl::render::Source;
using ftl::codecs::Channel;
......@@ -31,6 +32,7 @@ bool Source::supports(const std::string &puri) {
if (!uri.isValid() || uri.getScheme() != ftl::URI::SCHEME_DEVICE) return false;
if (uri.getPathSegment(0) == "render") return true;
if (uri.getPathSegment(0) == "openvr") return ftl::render::OpenVRRender::supported();
return false;
}
......@@ -55,7 +57,7 @@ void Source::reset() {
if (uri.getPathSegment(0) == "render") {
impl_ = new ftl::render::ScreenRender(this, feed_);
} else if (uri.getPathSegment(0) == "openvr") {
// TODO: Implement VR
impl_ = new ftl::render::OpenVRRender(this, feed_);
} else {
throw FTL_Error("Invalid render device: " << *uristr);
}
......
#include <ftl/streams/renderer.hpp>
#include <ftl/rgbd/frame.hpp>
#include <ftl/rgbd/frameset.hpp>
#include <ftl/rgbd/capabilities.hpp>
#include <loguru.hpp>
#include "openvr_render.hpp"
#include <ftl/config.h>
#ifdef HAVE_OPENVR
#include <openvr/openvr.h>
#endif
using ftl::render::Source;
using ftl::render::OpenVRRender;
using ftl::codecs::Channel;
using ftl::rgbd::Capability;
OpenVRRender::OpenVRRender(ftl::render::Source *host, ftl::stream::Feed *feed)
: ftl::render::BaseSourceImpl(host), feed_(feed), my_id_(0) {
/*host->restore("device:render", {
"renderer",
"source",
"intrinsics",
"name"
});*/
renderer_ = std::unique_ptr<ftl::render::CUDARender>(
ftl::create<ftl::render::CUDARender>(host_, "renderer")
);
intrinsics_ = ftl::create<ftl::Configurable>(host_, "intrinsics");
filter_ = nullptr;
std::string source = host_->value("source", std::string(""));
if (source.size() > 0) {
filter_ = feed_->filter({source},{Channel::Colour, Channel::Depth});
} else {
filter_ = feed_->filter({Channel::Colour, Channel::Depth});
}
host_->on("source", [this](const ftl::config::Event &e) {
std::string source = host_->value("source", std::string(""));
if (source.size() > 0) {
if (filter_) filter_->remove();
filter_ = feed_->filter({source},{Channel::Colour, Channel::Depth});
} else {
if (filter_) filter_->remove();
filter_ = feed_->filter({Channel::Colour, Channel::Depth});
}
});
}
OpenVRRender::~OpenVRRender() {
if (filter_) filter_->remove();
delete intrinsics_;
}
bool OpenVRRender::supported() {
#ifdef HAVR_OPENVR
return vr::VR_IsHmdPresent();
#else
return false;
#endif
}
bool OpenVRRender::isReady() {
return true;
}
bool OpenVRRender::capture(int64_t ts) {
return true;
}
bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
//auto input = std::atomic_load(&input_);
my_id_ = frame_out.frameset();
auto sets = filter_->getLatestFrameSets();
if (sets.size() > 0) {
ftl::rgbd::Frame &rgbdframe = frame_out.cast<ftl::rgbd::Frame>();
if (!frame_out.has(Channel::Calibration)) {
rgbdframe.setLeft() = ftl::rgbd::Camera::from(intrinsics_);
if (!frame_out.has(Channel::Capabilities)) {
auto &cap = frame_out.create<std::unordered_set<Capability>>(Channel::Capabilities);
cap.emplace(Capability::VIDEO);
cap.emplace(Capability::MOVABLE);
cap.emplace(Capability::ADJUSTABLE);
cap.emplace(Capability::VIRTUAL);
cap.emplace(Capability::LIVE);
cap.emplace(Capability::VR);
}
auto &meta = frame_out.create<std::map<std::string,std::string>>(Channel::MetaData);
meta["name"] = host_->value("name", host_->getID());
meta["uri"] = std::string("device:openvr");
}
if (!frame_out.has(Channel::Pose)) {
rgbdframe.setPose() = Eigen::Matrix4d::Identity();
}
int width = rgbdframe.getLeft().width;
int height = rgbdframe.getLeft().height;
// FIXME: Create opengl buffers here and map to cuda?
rgbdframe.create<cv::cuda::GpuMat>(Channel::Colour).create(height, width, CV_8UC4);
rgbdframe.create<cv::cuda::GpuMat>(Channel::Depth).create(height, width, CV_32F);
rgbdframe.createTexture<float>(Channel::Depth);
try {
renderer_->begin(rgbdframe, ftl::codecs::Channel::Left);
for (auto &s : sets) {
if (s->frameset() == my_id_) continue; // Skip self
renderer_->submit(
s.get(),
ftl::codecs::Channels<0>(ftl::codecs::Channel::Colour),
Eigen::Matrix4d::Identity());
// TODO: Render audio also...
// Use another thread to merge all audio channels along with
// some degree of volume adjustment. Later, do 3D audio.
}
renderer_->render();
renderer_->end();
} catch (const ftl::exception &e) {
LOG(ERROR) << "Render exception: " << e.what();
}
return true;
} else {
//LOG(INFO) << "Render fail";
return true;
}
}
#ifndef _FTL_RENDER_OPENVR_SOURCE_HPP_
#define _FTL_RENDER_OPENVR_SOURCE_HPP_
#include <ftl/data/creators.hpp>
#include <ftl/data/new_frameset.hpp>
#include <ftl/render/renderer.hpp>
#include <ftl/render/CUDARender.hpp>
#include <ftl/streams/feed.hpp>
#include "../baserender.hpp"
namespace ftl {
namespace render {
class OpenVRRender : public ftl::render::BaseSourceImpl {
public:
OpenVRRender(ftl::render::Source *host, ftl::stream::Feed *feed);
~OpenVRRender();
bool capture(int64_t ts) override;
bool retrieve(ftl::data::Frame &) override;
bool isReady() override;
static bool supported();
private:
ftl::stream::Feed *feed_;
ftl::stream::Feed::Filter *filter_;
ftl::data::FrameSetPtr input_;
std::unique_ptr<ftl::render::CUDARender> renderer_;
ftl::Configurable *intrinsics_;
uint32_t my_id_;
};
}
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment