// This file is part of libigl, a simple c++ geometry processing library. // // // Copyright (C) 2020 Vladimir Fonov // 2013 Alec Jacobson // 2014 Christian Schüller // // 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 #include #include #include #include #include #include #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 PointMatrixType; typedef Eigen::Matrix ColorMatrixType; typedef Eigen::Matrix FaceMatrixType; typedef Eigen::Matrix 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 void set_mesh(const Eigen::MatrixBase & V, const Eigen::MatrixBase & 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 void set_colors(const Eigen::MatrixBase & C); // Use min(D) and max(D) to set caxis. template void set_data(const Eigen::MatrixBase & 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 void set_data( const Eigen::MatrixBase & 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 void set_rot(const Eigen::MatrixBase &r); // Specify mesh magnification // Inputs: // z magnification ratio template void set_zoom(T z); // Specify mesh translation // Inputs: // tr translation vector template void set_translation(const Eigen::MatrixBase &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::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& V, const std::vector& F, const std::vector& 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