6 #include <console_bridge/console.h>
24 double d2 = ab.
dot(ap);
30 double d2_2 = d2*d2 / ab.
length2();
31 return d2_2 <= ab.
length2() * (1 + 1e-9) && d1_2-d2_2 <= radius2 * (1 + 1e-9);
107 for (uint i=0; i<3; ++i) {
114 if (!(std::abs(s2)<1e-16 && std::abs(s3)<1e-16))
118 for (uint i=0; i<3; ++i) {
125 for (uint i=0; i<3; ++i) {
146 return new Shape(*
this);
150 throw std::logic_error(
"intersect(Ray, float, float, double) not implemented");
167 const double radius2 = radius*radius;
172 const Vector3 &v1 = t_points[it->i1_];
173 const Vector3 &v2 = t_points[it->i2_];
174 const Vector3 &v3 = t_points[it->i3_];
177 if ((v1-p).length2() < radius2)
179 if ((v2-p).length2() < radius2)
181 if ((v3-p).length2() < radius2)
198 double projected_distance2 = (v1-p).dot(n);
199 projected_distance2 = projected_distance2 * projected_distance2 / n.
length2();
201 if (projected_distance2 > radius2)
206 Vector3 q = p - sqrt(projected_distance2) * n.normalized();
208 Vector3 cross1 = e1.cross(q-v1);
209 Vector3 cross2 = e2.cross(q-v2);
210 Vector3 cross3 = e3.cross(q-v3);
212 double dot1 = cross1.
dot(cross2);
213 double dot2 = cross2.
dot(cross3);
214 double dot3 = cross3.
dot(cross1);
216 if (dot1 > 0 && dot2 > 0 && dot3 > 0)
235 int intersect_count = 0;
248 for (
auto it = triangles_i.
cbegin(); it != triangles_i.
cend(); ++it) {
249 const Vector3 &v1 = t_points[it->i1_];
250 const Vector3 &v2 = t_points[it->i2_];
251 const Vector3 &v3 = t_points[it->i3_];
262 bool clockwise = s1 >= -1e-16 && s2 >= -1e-16 && s3 >= -1e-16;
263 ushort clockwise_nz = (s1 > 1e-16) + (s2 > 1e-16) + (s3 > 1e-16);
264 bool counterclockwise = s1 <= 1e-16 && s2 <= 1e-16 && s3 <= 1e-16;
265 ushort counterclockwise_nz = (s1 < -1e-16) + (s2 < -1e-16) + (s3 < -1e-16);
268 if (!clockwise && !counterclockwise) {
270 CONSOLE_BRIDGE_logDebug(
"No intersection");
273 else if (clockwise && counterclockwise) {
275 CONSOLE_BRIDGE_logDebug(
"Coplanar");
277 CONSOLE_BRIDGE_logDebug(
"Coplanar in the triangle");
280 CONSOLE_BRIDGE_logDebug(
"Coplanar outside the triangle");
283 else if ((clockwise && clockwise_nz > 0) || (counterclockwise && counterclockwise_nz > 0)) {
296 if (clockwise_nz == 2 || counterclockwise_nz == 2) {
298 CONSOLE_BRIDGE_logDebug(
"Edge intersection");
300 if (std::abs(s1) < 1e-16) {
304 else if (std::abs(s2) < 1e-16) {
312 uint& i_min = i1, i_max = i2;
315 if (std::abs((p-t_points[i_min]).length() + (t_points[i_max]-p).length() - (t_points[i_max]-t_points[i_min]).length()) <= 1e-12) {
316 CONSOLE_BRIDGE_logDebug(
"Point is on an edge of the mesh");
321 auto search = edge_hit_map.
find(i_min);
322 if (search == edge_hit_map.
end()) {
325 auto search2 = edge_hit_map[i_min].
find(i_max-i_min-1);
326 if (search2 == edge_hit_map[i_min].end()) {
327 edge_hit_map[i_min][i_max-i_min-1] = 0;
330 int& hit_entry = edge_hit_map[i_min][i_max-i_min-1];
331 if (hit_entry == clockwise-counterclockwise) {
336 hit_entry += clockwise-counterclockwise;
339 else if (clockwise_nz == 1 || counterclockwise_nz == 1) {
341 CONSOLE_BRIDGE_logDebug(
"Vertex intersection");
344 if (std::abs(s2) > 1e-16)
346 else if (std::abs(s3) > 1e-16)
351 if (t_points[i] == p) {
352 CONSOLE_BRIDGE_logDebug(
"Point is a vertex of the mesh");
357 auto search = vertex_hit_map.
find(i);
358 if (search == vertex_hit_map.
end()) {
359 vertex_hit_map[i] = 0;
362 int& hit_entry = vertex_hit_map[i];
363 if (hit_entry == clockwise-counterclockwise) {
368 hit_entry += clockwise-counterclockwise;
373 CONSOLE_BRIDGE_logDebug(
"Proper intersection");
377 CONSOLE_BRIDGE_logError(
"Triangle has a zero area");
383 if (std::abs(s1 + s2 + s3 - s) < 1e-12) {
384 CONSOLE_BRIDGE_logDebug(
"Point is on a triangle");
389 intersect_count += clockwise-counterclockwise;
394 if (intersect_count < 0 || intersect_count > 1) {
395 CONSOLE_BRIDGE_logError(
"intersect_count is %i, it should be 0 or 1! Is your shape constructed correctly?", intersect_count);
399 return intersect_count > 0;
407 double x_min = 1e9, y_min = 1e9, z_min = 1e9;
408 double x_max = -1e9, y_max = -1e9, z_max = -1e9;
409 for (
auto it = points.
cbegin(); it != points.
cend(); ++it)
411 x_min = std::min<double>(it->x, x_min);
412 x_max = std::max<double>(it->x, x_max);
413 y_min = std::min<double>(it->y, y_min);
414 y_max = std::max<double>(it->y, y_max);
415 z_min = std::min<double>(it->z, z_min);
416 z_max = std::max<double>(it->z, z_max);
445 int p_size = points.
size();
446 output.
write((
char*)&p_size,
sizeof(p_size));
453 output.
write((
char*)&x,
sizeof(x));
454 output.
write((
char*)&y,
sizeof(y));
455 output.
write((
char*)&z,
sizeof(z));
459 int t_size = triangles.
size();
460 output.
write((
char*)&t_size,
sizeof(t_size));
463 output.
write((
char*)&
t.i1_,
sizeof(
t.i1_));
464 output.
write((
char*)&
t.i2_,
sizeof(
t.i2_));
465 output.
write((
char*)&
t.i3_,
sizeof(
t.i3_));
475 input.
read((
char*)&p_size,
sizeof(p_size));
477 for(
int i = 0; i < p_size; ++i) {
479 input.
read((
char*)&x,
sizeof(x));
480 input.
read((
char*)&y,
sizeof(y));
481 input.
read((
char*)&z,
sizeof(z));
482 shape->mesh_.addPoint(x, y, z);
486 input.
read((
char*)&t_size,
sizeof(t_size));
488 for(
int i = 0; i < t_size; ++i) {
490 input.
read((
char*)&i1,
sizeof(i1));
491 input.
read((
char*)&i2,
sizeof(i2));
492 input.
read((
char*)&i3,
sizeof(i3));
493 shape->mesh_.addTriangle(i1, i2, i3);