Cogs.Core
RayTriangleIntersection.h
1#pragma once
2
3#include <glm/geometric.hpp>
4#include <glm/vec3.hpp>
5
6namespace Cogs
7{
8 namespace Geometry
9 {
13 inline bool intersect(
14 const glm::vec3 & v0,
15 const glm::vec3 & v1,
16 const glm::vec3 & v2,
17 const glm::vec3 & orig,
18 const glm::vec3 & dir,
19 glm::vec3 & intersection,
20 glm::vec3 & barycentric,
21 bool & front)
22 {
23
24 glm::vec3 edge1 = v1 - v0;
25 glm::vec3 edge2 = v2 - v0;
26
27 glm::vec3 pvec = glm::cross(dir, edge2);
28
29 // If determinant is near zero, ray lies in plane of triangle
30 float det = glm::dot(edge1, pvec);
31
32 if (std::fabs(det) < std::numeric_limits<float>::epsilon()) return false;
33
34 // Does ray hit front or back of triangle
35 if (det > 0.0) front = true;
36 else front = false;
37
38 // Create some more intuitive barycentric coordinate names
39 float u, v, w;
40 float inv_det = 1.0f / det;
41
42 // Calculate distance from v0 to ray origin
43 glm::vec3 tvec = orig - v0;
44
45 // Calculate U parameter and test bounds
46 u = glm::dot(tvec, pvec) * inv_det;
47
48 if (u < 0.0f || u > 1.0f)
49 return false;
50
51 // Prepare to test V parameter
52 glm::vec3 qvec = glm::cross(tvec, edge1);
53
54 // Calculate V parameter and test bounds
55 v = glm::dot(dir, qvec) * inv_det;
56
57 if (v < 0.0f || u + v > 1.0f)
58 return false;
59
60 // Third barycentric coordinate
61 w = 1.0f - u - v;
62
63 // Calculate t and intersection point
64 float t = glm::dot(edge2, qvec) * inv_det;
65
66 glm::vec3 itmp = orig + t * dir;
67
68 intersection = itmp;
69
70 // Set the barycentric coordinates before returning
71 barycentric[0] = static_cast<float>(w);
72 barycentric[1] = static_cast<float>(u);
73 barycentric[2] = static_cast<float>(v);
74
75 return true;
76 }
77
78 static double distanceToQuad(
79 const double xmin, const double ymin,
80 const double xmax, const double ymax,
81 const double x, const double y,
82 double & cx, double & cy)
83 {
84 if (x < xmin) {
85 if (y < ymin) {
86 cx = xmin;
87 cy = ymin;
88 return (x - xmin)*(x - xmin) + (y - ymin)*(y - ymin);
89 } else if (y > ymax) {
90 cx = xmin;
91 cy = ymax;
92 return (x - xmin)*(x - xmin) + (y - ymax)*(y - ymax);
93 } else {
94 cx = xmin;
95 cy = y;
96 return (x - xmin)*(x - xmin);
97 }
98 } else if (x > xmax) {
99 if (y < ymin) {
100 cx = xmax;
101 cy = ymin;
102 return (x - xmax)*(x - xmax) + (y - ymin) * (y - ymin);
103 } else if (y > ymax) {
104 cx = xmax;
105 cy = ymax;
106 return (x - xmax)*(x - xmax) + (y - ymax)*(y - ymax);
107 } else {
108 cx = xmax;
109 cy = y;
110 return (x - xmax)*(x - xmax);
111 }
112 } else {
113 if (y < ymin) {
114 cx = x;
115 cy = ymin;
116 return (y - ymin)*(y - ymin);
117 } else if (y > ymax) {
118 cx = x;
119 cy = ymax;
120 return (y - ymax)*(y - ymax);
121 } else {
122 // inside rectangle
123 cx = x;
124 cy = y;
125 return -1.0;
126 }
127 }
128 }
129 }
130}
@ Geometry
Store entity vector fields (vector<vec3>, vector<vec2>, vector<int>, vector<float>).
Contains all Cogs related functionality.
Definition: FieldSetter.h:23