eos 1.4.0
Loading...
Searching...
No Matches
ray_triangle_intersect.hpp
1/*
2 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
3 *
4 * File: include/eos/render/ray_triangle_intersect.hpp
5 *
6 * Copyright 2016-2019 Patrik Huber
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20#pragma once
21
22#ifndef EOS_RAY_TRIANGLE_INTERSECT_HPP
23#define EOS_RAY_TRIANGLE_INTERSECT_HPP
24
25#include "eos/cpp17/optional.hpp"
26
27#include "Eigen/Core"
28
29#include <utility>
30
31namespace eos {
32namespace render {
33
56inline std::pair<bool, cpp17::optional<float>>
57ray_triangle_intersect(const Eigen::Vector3f& ray_origin, const Eigen::Vector3f& ray_direction,
58 const Eigen::Vector3f& v0, const Eigen::Vector3f& v1, const Eigen::Vector3f& v2,
59 bool enable_backculling)
60{
61 using Eigen::Vector3f;
62 const float epsilon = 1e-6f;
63
64 const Vector3f v0v1 = v1 - v0;
65 const Vector3f v0v2 = v2 - v0;
66
67 const Vector3f pvec = ray_direction.cross(v0v2);
68
69 const float det = v0v1.dot(pvec);
70
71 if (enable_backculling)
72 {
73 // If det is negative, the triangle is back-facing.
74 // If det is close to 0, the ray misses the triangle.
75 if (det < epsilon)
76 return {false, cpp17::nullopt};
77 } else
78 {
79 // If det is close to 0, the ray and triangle are parallel.
80 if (std::abs(det) < epsilon)
81 return {false, cpp17::nullopt};
82 }
83 const float inv_det = 1 / det;
84
85 const Vector3f tvec = ray_origin - v0;
86 const auto u = tvec.dot(pvec) * inv_det;
87 if (u < 0 || u > 1)
88 return {false, cpp17::nullopt};
89
90 const Vector3f qvec = tvec.cross(v0v1);
91 const auto v = ray_direction.dot(qvec) * inv_det;
92 if (v < 0 || u + v > 1)
93 return {false, cpp17::nullopt};
94
95 const auto t = v0v2.dot(qvec) * inv_det;
96
97 return {true, t};
98};
99
100} /* namespace render */
101} /* namespace eos */
102
103#endif /* EOS_RAY_TRIANGLE_INTERSECT_HPP */
std::pair< bool, cpp17::optional< float > > ray_triangle_intersect(const Eigen::Vector3f &ray_origin, const Eigen::Vector3f &ray_direction, const Eigen::Vector3f &v0, const Eigen::Vector3f &v1, const Eigen::Vector3f &v2, bool enable_backculling)
Computes the intersection of the given ray with the given triangle.
Definition: ray_triangle_intersect.hpp:57
core::Image4u render(const core::Mesh &mesh, const Eigen::Matrix4f &model_view_matrix, const Eigen::Matrix4f &projection_matrix, int viewport_width, int viewport_height, bool enable_backface_culling=false, bool enable_near_clipping=true, bool enable_far_clipping=true)
Definition: render.hpp:52
Namespace containing all of eos's 3D model fitting functionality.