You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

262 lines
7.9 KiB

// This file is part of libigl, a simple c++ geometry processing library.
//
//
// Copyright (C) 2020 Vladimir Fonov <vladimir.fonov@gmail.com>
// 2013 Alec Jacobson <alecjacobson@gmail.com>
// 2014 Christian Schüller <schuellchr@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public License
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.
//
#ifndef IGL_EMBREE_EMBREE_RENDERER_H
#define IGL_EMBREE_EMBREE_RENDERER_H
#include "../colormap.h"
#include <Eigen/Geometry>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <embree3/rtcore.h>
#include <embree3/rtcore_ray.h>
#include <iostream>
#include <vector>
#include "EmbreeDevice.h"
namespace igl
{
namespace embree
{
/// @private
/// embree-based mesh renderer
class EmbreeRenderer
{
public:
typedef Eigen::RowVector3f Vec3f;
struct Hit
{
int id; // primitive id
int gid; // geometry id
float u,v; // barycentric coordinates
float t; // distance = direction*t to intersection
Vec3f N; // element normal
};
public:
typedef Eigen::Matrix<float,Eigen::Dynamic,3> PointMatrixType;
typedef Eigen::Matrix<float,Eigen::Dynamic,3> ColorMatrixType;
typedef Eigen::Matrix<int, Eigen::Dynamic,3> FaceMatrixType;
typedef Eigen::Matrix<unsigned char,Eigen::Dynamic,Eigen::Dynamic> PixelMatrixType;
public:
EmbreeRenderer();
private:
// Copying and assignment are not allowed.
EmbreeRenderer(const EmbreeRenderer & that);
EmbreeRenderer & operator=(const EmbreeRenderer &);
public:
virtual ~EmbreeRenderer();
// Specify mesh, this call reinitializes embree structures
// Inputs:
// V #V x dim matrix of vertex coordinates
// F #F x simplex_size matrix of indices of simplex corners into V
// is_static - optimize for static thene (HQ rendering)
template <typename DerivedV, typename DerivedF>
void set_mesh(const Eigen::MatrixBase<DerivedV> & V,
const Eigen::MatrixBase<DerivedF> & F,
bool is_static=true);
// Specify per-vertex or per-face color
// Inputs:
// C #V x 3 matrix of vertex colors
// or #F x 3 matrix of face colors
// or 1 x 3 matrix of uniform color
template <typename DerivedC>
void set_colors(const Eigen::MatrixBase<DerivedC> & C);
// Use min(D) and max(D) to set caxis.
template <typename DerivedD>
void set_data(const Eigen::MatrixBase<DerivedD> & D,
igl::ColorMapType cmap = igl::COLOR_MAP_TYPE_VIRIDIS);
// Specify per-vertex or per-face scalar field
// that will be converted to color using jet color map
// Inputs:
// caxis_min caxis minimum bound
// caxis_max caxis maximum bound
// D #V by 1 list of scalar values
// cmap colormap type
// num_steps number of intervals to discretize the colormap
template <typename DerivedD, typename T>
void set_data(
const Eigen::MatrixBase<DerivedD> & D,
T caxis_min,
T caxis_max,
igl::ColorMapType cmap = igl::COLOR_MAP_TYPE_VIRIDIS);
// Specify mesh rotation
// Inputs:
// r 3 x 3 rotaton matrix
template <typename Derivedr>
void set_rot(const Eigen::MatrixBase<Derivedr> &r);
// Specify mesh magnification
// Inputs:
// z magnification ratio
template <typename T>
void set_zoom(T z);
// Specify mesh translation
// Inputs:
// tr translation vector
template <typename Derivedtr>
void set_translation(const Eigen::MatrixBase<Derivedtr> &tr);
// Specify that color is face based
// Inputs:
// f - face or vertex colours
void set_face_based(bool f);
// Use orthographic projection
// Inputs:
// f - orthographic or perspective projection
void set_orthographic(bool f );
// Render both sides of triangles
// Inputs:
// f - double sided
void set_double_sided(bool f);
// render full buffer
// Outputs:
// all outputs should have the same size (size of the output picture)
// area outside of the visible object will have zero alpha component (transparant)
// R - red channel
// G - green channel
// B - blue channel
// A - alpha channel
void render_buffer(PixelMatrixType &R,
PixelMatrixType &G,
PixelMatrixType &B,
PixelMatrixType &A);
// Given a ray find the first hit
//
// Inputs:
// origin 3d origin point of ray
// direction 3d (not necessarily normalized) direction vector of ray
// tnear start of ray segment
// tfar end of ray segment
// mask a 32 bit mask to identify active geometries.
// Output:
// hit information about hit
// Returns true if and only if there was a hit
bool intersect_ray(
const Eigen::RowVector3f& origin,
const Eigen::RowVector3f& direction,
Hit& hit,
float tnear = 0,
float tfar = std::numeric_limits<float>::infinity(),
int mask = 0xFFFFFFFF) const;
private:
// Initialize with a given mesh.
//
// Inputs:
// V #V by 3 list of vertex positions
// F #F by 3 list of Oriented triangles
// isStatic scene is optimized for static geometry
// Side effects:
// The first time this is ever called the embree engine is initialized.
void init(
const PointMatrixType& V,
const FaceMatrixType& F,
bool isStatic = false);
// Initialize embree with a given mesh.
//
// Inputs:
// V vector of #V by 3 list of vertex positions for each geometry
// F vector of #F by 3 list of Oriented triangles for each geometry
// masks a 32 bit mask to identify active geometries.
// isStatic scene is optimized for static geometry
// Side effects:
// The first time this is ever called the embree engine is initialized.
void init(
const std::vector<const PointMatrixType*>& V,
const std::vector<const FaceMatrixType*>& F,
const std::vector<int>& masks,
bool isStatic = false);
// Deinitialize embree datasctructures for current mesh. Also called on
// destruction: no need to call if you just want to init() once and
// destroy.
void deinit();
// initialize view parameters
void init_view();
// scene data
PointMatrixType V; // vertices
FaceMatrixType F; // faces
ColorMatrixType C; // colours
Eigen::RowVector3f uC; // uniform color
bool face_based;
bool uniform_color;
bool double_sided ;
// Camera parameters
float camera_base_zoom;
float camera_zoom;
Eigen::Vector3f camera_base_translation;
Eigen::Vector3f camera_translation;
Eigen::Vector3f camera_eye;
Eigen::Vector3f camera_up;
Eigen::Vector3f camera_center;
float camera_view_angle;
float camera_dnear;
float camera_dfar;
// projection matrixes
Eigen::Matrix4f view;
Eigen::Matrix4f proj;
Eigen::Matrix4f norm;
Eigen::Matrix3f rot_matrix;
bool orthographic;
// embree data
RTCScene scene;
unsigned geomID;
bool initialized;
RTCDevice device;
void create_ray(
RTCRayHit& ray,
const Eigen::RowVector3f& origin,
const Eigen::RowVector3f& direction,
float tnear,
float tfar,
int mask) const;
};
}
}
#ifndef IGL_STATIC_LIBRARY
# include "EmbreeRenderer.cpp"
#endif
#endif //IGL_EMBREE_EMBREE_RENDERER_H