Skip to content
Snippets Groups Projects
splat_render.cpp 8.25 KiB
Newer Older
#include <ftl/render/splat_render.hpp>
Nicolas Pope's avatar
Nicolas Pope committed
#include <ftl/utility/matrix_conversion.hpp>
#include "splatter_cuda.hpp"
Nicolas Pope's avatar
Nicolas Pope committed
#include <ftl/cuda/points.hpp>

#include <opencv2/core/cuda_stream_accessor.hpp>
Nicolas Pope's avatar
Nicolas Pope committed

using ftl::render::Splatter;
using ftl::rgbd::Channel;
using ftl::rgbd::Channels;
using ftl::rgbd::Format;
Nicolas Pope's avatar
Nicolas Pope committed
using cv::cuda::GpuMat;
Nicolas Pope's avatar
Nicolas Pope committed
Splatter::Splatter(nlohmann::json &config, ftl::rgbd::FrameSet *fs) : ftl::render::Renderer(config), scene_(fs) {
Nicolas Pope's avatar
Nicolas Pope committed

}

Splatter::~Splatter() {

}

Nicolas Pope's avatar
Nicolas Pope committed
bool Splatter::render(ftl::rgbd::VirtualSource *src, ftl::rgbd::Frame &out, cudaStream_t stream) {
	SHARED_LOCK(scene_->mtx, lk);
Nicolas Pope's avatar
Nicolas Pope committed
	if (!src->isReady()) return false;
	if (scene_->frames.size() > 0) LOG(INFO) << "Render ready2 " << (unsigned int)scene_->frames[0].getChannels();
Nicolas Pope's avatar
Nicolas Pope committed
	const auto &camera = src->parameters();

	//cudaSafeCall(cudaSetDevice(scene_->getCUDADevice()));
Nicolas Pope's avatar
Nicolas Pope committed
	// Create all the required channels
	out.create<GpuMat>(Channel::Depth, Format<float>(camera.width, camera.height));
	out.create<GpuMat>(Channel::Colour, Format<uchar4>(camera.width, camera.height));
	temp_.create<GpuMat>(Channel::Colour, Format<float4>(camera.width, camera.height));
	temp_.create<GpuMat>(Channel::Colour2, Format<uchar4>(camera.width, camera.height));
	temp_.create<GpuMat>(Channel::Confidence, Format<float>(camera.width, camera.height));
	temp_.create<GpuMat>(Channel::Depth, Format<int>(camera.width, camera.height));
	temp_.create<GpuMat>(Channel::Depth2, Format<int>(camera.width, camera.height));
	temp_.create<GpuMat>(Channel::Normals, Format<float4>(camera.width, camera.height));

	cv::cuda::Stream cvstream = cv::cuda::StreamAccessor::wrapStream(stream);
	LOG(INFO) << "Render ready1";

	// Create buffers if they don't exist
	/*if ((unsigned int)depth1_.width() != camera.width || (unsigned int)depth1_.height() != camera.height) {
		depth1_ = ftl::cuda::TextureObject<int>(camera.width, camera.height);
	if ((unsigned int)depth3_.width() != camera.width || (unsigned int)depth3_.height() != camera.height) {
		depth3_ = ftl::cuda::TextureObject<int>(camera.width, camera.height);
	}
Nicolas Pope's avatar
Nicolas Pope committed
	if ((unsigned int)colour1_.width() != camera.width || (unsigned int)colour1_.height() != camera.height) {
Nicolas Pope's avatar
Nicolas Pope committed
		colour1_ = ftl::cuda::TextureObject<uchar4>(camera.width, camera.height);
	}
	if ((unsigned int)colour_tmp_.width() != camera.width || (unsigned int)colour_tmp_.height() != camera.height) {
		colour_tmp_ = ftl::cuda::TextureObject<float4>(camera.width, camera.height);
	}
	if ((unsigned int)normal1_.width() != camera.width || (unsigned int)normal1_.height() != camera.height) {
		normal1_ = ftl::cuda::TextureObject<float4>(camera.width, camera.height);
	}
Nicolas Pope's avatar
Nicolas Pope committed
	if ((unsigned int)depth2_.width() != camera.width || (unsigned int)depth2_.height() != camera.height) {
Nicolas Pope's avatar
Nicolas Pope committed
		depth2_ = ftl::cuda::TextureObject<float>(camera.width, camera.height);
	}
Nicolas Pope's avatar
Nicolas Pope committed
	if ((unsigned int)colour2_.width() != camera.width || (unsigned int)colour2_.height() != camera.height) {
Nicolas Pope's avatar
Nicolas Pope committed
		colour2_ = ftl::cuda::TextureObject<uchar4>(camera.width, camera.height);
Nicolas Pope's avatar
Nicolas Pope committed
	// Parameters object to pass to CUDA describing the camera
Nicolas Pope's avatar
Nicolas Pope committed
	SplatParams params;
	params.m_flags = 0;
	if (src->value("splatting", true) == false) params.m_flags |= ftl::render::kNoSplatting;
	if (src->value("upsampling", true) == false) params.m_flags |= ftl::render::kNoUpsampling;
	if (src->value("texturing", true) == false) params.m_flags |= ftl::render::kNoTexturing;
Nicolas Pope's avatar
Nicolas Pope committed
	params.m_viewMatrix = MatrixConversion::toCUDA(src->getPose().cast<float>().inverse());
	params.m_viewMatrixInverse = MatrixConversion::toCUDA(src->getPose().cast<float>());
	params.camera = camera;
Nicolas Pope's avatar
Nicolas Pope committed

	LOG(INFO) << "VPOSE = " << src->getPose();

Nicolas Pope's avatar
Nicolas Pope committed
	// Clear all channels to 0 or max depth
	temp_.get<GpuMat>(Channel::Depth).setTo(cv::Scalar(0x7FFFFFFF), cvstream);
	temp_.get<GpuMat>(Channel::Depth2).setTo(cv::Scalar(0x7FFFFFFF), cvstream);
	out.get<GpuMat>(Channel::Depth).setTo(cv::Scalar(1000.0f), cvstream);
	out.get<GpuMat>(Channel::Colour).setTo(cv::Scalar(76,76,76), cvstream);
Nicolas Pope's avatar
Nicolas Pope committed

	LOG(INFO) << "Render ready: " << camera.width << "," << camera.height;
Nicolas Pope's avatar
Nicolas Pope committed
	// Render each camera into virtual view
	for (size_t i=0; i<scene_->frames.size(); ++i) {
		auto &f = scene_->frames[i];
		auto *s = scene_->sources[i];

		if (f.empty(Channel::Depth + Channel::Colour)) {
			LOG(ERROR) << "Missing required channel";
			continue;
		} else {
			LOG(INFO) << "Channels found";
Nicolas Pope's avatar
Nicolas Pope committed
		// Needs to create points channel first?
		if (!f.hasChannel(Channel::Points)) {
			LOG(INFO) << "Creating points... " << s->parameters().width;
Nicolas Pope's avatar
Nicolas Pope committed
			auto &t = f.createTexture<float4>(Channel::Points, Format<float4>(f.get<GpuMat>(Channel::Colour).size()));
			auto pose = MatrixConversion::toCUDA(s->getPose().cast<float>().inverse());
			ftl::cuda::point_cloud(t, f.createTexture<float>(Channel::Depth), s->parameters(), pose, stream);

			LOG(INFO) << "POINTS Added";
Nicolas Pope's avatar
Nicolas Pope committed
		}

		ftl::cuda::dibr_merge(
			f.createTexture<float4>(Channel::Points),
			temp_.createTexture<int>(Channel::Depth),
			params, stream
		);

		LOG(INFO) << "DIBR DONE";
Nicolas Pope's avatar
Nicolas Pope committed
	}

		//ftl::cuda::dibr(depth1_, colour1_, normal1_, depth2_, colour_tmp_, depth3_, scene_->cameraCount(), params, stream);
		// Step 1: Put all points into virtual view to gather them
		//ftl::cuda::dibr_raw(depth1_, scene_->cameraCount(), params, stream);
Nicolas Pope's avatar
Nicolas Pope committed

		// Step 2: For each point, use a warp to do MLS and up sample
		//ftl::cuda::mls_render_depth(depth1_, depth3_, params, scene_->cameraCount(), stream);
		if (src->getChannel() == Channel::Depth) {
			LOG(INFO) << "Rendering depth";
			//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);
			if (value("splatting",  false)) {
				//ftl::cuda::splat_points(depth1_, colour1_, normal1_, depth2_, colour2_, params, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);

Nicolas Pope's avatar
Nicolas Pope committed
				temp_.get<GpuMat>(Channel::Depth).convertTo(out.get<GpuMat>(Channel::Depth), CV_32F, 1.0f / 1000.0f, cvstream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->writeFrames(ts, colour1_, depth2_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->write(scene_.timestamp, output_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				temp_.get<GpuMat>(Channel::Depth).convertTo(out.get<GpuMat>(Channel::Depth), CV_32F, 1.0f / 1000.0f, cvstream);
Nicolas Pope's avatar
Nicolas Pope committed
				//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);
				//src->writeFrames(ts, colour1_, depth2_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->write(scene_.timestamp, output_, stream);
		} else if (src->getChannel() == Channel::Energy) {
			//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);
			//if (src->value("splatting",  false)) {
				//ftl::cuda::splat_points(depth1_, colour1_, normal1_, depth2_, colour2_, params, stream);
				//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->writeFrames(ts, colour1_, depth2_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->write(scene_.timestamp, output_, stream);
			//} else {
				//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);
			//	src->writeFrames(colour1_, depth2_, stream);
			//}
		} else if (src->getChannel() == Channel::Right) {
			LOG(INFO) << "Rendering right";
Nicolas Pope's avatar
Nicolas Pope committed
			// Adjust pose to right eye position
			Eigen::Affine3f transform(Eigen::Translation3f(camera.baseline,0.0f,0.0f));
			Eigen::Matrix4f matrix =  src->getPose().cast<float>() * transform.matrix();
			params.m_viewMatrix = MatrixConversion::toCUDA(matrix.inverse());
			params.m_viewMatrixInverse = MatrixConversion::toCUDA(matrix);

Nicolas Pope's avatar
Nicolas Pope committed
			//ftl::cuda::clear_depth(depth1_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
			//ftl::cuda::dibr(depth1_, colour1_, normal1_, depth2_, colour_tmp_, depth3_, scene_->cameraCount(), params, stream);
Nicolas Pope's avatar
Nicolas Pope committed
			//src->writeFrames(ts, colour1_, colour2_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
			//src->write(scene_.timestamp, output_, stream);
			LOG(INFO) << "No second rendering";
			//if (value("splatting",  false)) {
				//ftl::cuda::splat_points(depth1_, colour1_, normal1_, depth2_, colour2_, params, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->writeFrames(ts, colour1_, depth2_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->write(scene_.timestamp, out, stream);
			//} else {
Nicolas Pope's avatar
Nicolas Pope committed
				//ftl::cuda::int_to_float(depth1_, depth2_, 1.0f / 1000.0f, stream);
				temp_.get<GpuMat>(Channel::Depth).convertTo(out.get<GpuMat>(Channel::Depth), CV_32F, 1.0f / 1000.0f, cvstream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->writeFrames(ts, colour1_, depth2_, stream);
Nicolas Pope's avatar
Nicolas Pope committed
				//src->write(scene_.timestamp, output_, stream);

	//ftl::cuda::median_filter(depth1_, depth2_, stream);
	//ftl::cuda::splat_points(depth1_, depth2_, params, stream);
Nicolas Pope's avatar
Nicolas Pope committed

	// TODO: Second pass
Nicolas Pope's avatar
Nicolas Pope committed
//void Splatter::setOutputDevice(int device) {
//	device_ = device;
//}