/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #pragma once /** \file * \ingroup freestyle * \brief Various tools for geometry */ #include #include "Geom.h" #include "../system/FreestyleConfig.h" using namespace std; namespace Freestyle { using namespace Geometry; namespace GeomUtils { // // Templated procedures // ///////////////////////////////////////////////////////////////////////////// /*! Computes the distance from a point P to a segment AB */ template real distPointSegment(const T &P, const T &A, const T &B) { T AB, AP, BP; AB = B - A; AP = P - A; BP = P - B; real c1(AB * AP); if (c1 <= 0) { return AP.norm(); } real c2(AB * AB); if (c2 <= c1) { return BP.norm(); } real b = c1 / c2; T Pb, PPb; Pb = A + b * AB; PPb = P - Pb; return PPb.norm(); } // // Non-templated procedures // ///////////////////////////////////////////////////////////////////////////// typedef enum { DONT_INTERSECT, DO_INTERSECT, COLINEAR, COINCIDENT, } intersection_test; intersection_test intersect2dSeg2dSeg(const Vec2r &p1, const Vec2r &p2, // first segment const Vec2r &p3, const Vec2r &p4, // second segment Vec2r &res); // found intersection point intersection_test intersect2dLine2dLine(const Vec2r &p1, const Vec2r &p2, // first segment const Vec2r &p3, const Vec2r &p4, // second segment Vec2r &res); // found intersection point intersection_test intersect2dSeg2dSegParametric(const Vec2r &p1, const Vec2r &p2, // first segment const Vec2r &p3, const Vec2r &p4, // second segment real &t, // I = P1 + t * P1P2) real &u, // I = P3 + u * P3P4 real epsilon = M_EPSILON); /*! check whether a 2D segment intersect a 2D region or not */ bool intersect2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B); /*! check whether a 2D segment is included in a 2D region or not */ bool include2dSeg2dArea(const Vec2r &min, const Vec2r &max, const Vec2r &A, const Vec2r &B); /*! Box-triangle overlap test, adapted from Tomas Akenine-Möller code */ bool overlapTriangleBox(Vec3r &boxcenter, Vec3r &boxhalfsize, Vec3r triverts[3]); /*! Fast, Minimum Storage Ray-Triangle Intersection, adapted from Tomas Möller and Ben Trumbore * code. */ bool intersectRayTriangle(const Vec3r &orig, const Vec3r &dir, const Vec3r &v0, const Vec3r &v1, const Vec3r &v2, real &t, // I = orig + t * dir real &u, real &v, // I = (1 - u - v) * v0 + u * v1 + v * v2 const real epsilon = M_EPSILON); // the epsilon to use /*! Intersection between plane and ray adapted from Graphics Gems, Didier Badouel */ intersection_test intersectRayPlane(const Vec3r &orig, const Vec3r &dir, // ray origin and direction // plane's normal and offset (plane = { P / P.N + d = 0 }) const Vec3r &norm, const real d, real &t, // I = orig + t * dir const real epsilon = M_EPSILON); // the epsilon to use /*! Intersection Ray-Bounding box (axis aligned). * Adapted from Williams et al, "An Efficient Robust Ray-Box Intersection Algorithm", JGT 10:1 * (2005), pp. 49-54. */ bool intersectRayBBox(const Vec3r &orig, const Vec3r &dir, // ray origin and direction const Vec3r &boxMin, const Vec3r &boxMax, // the bbox // the interval in which at least on of the intersections must happen real t0, real t1, real &tmin, // Imin = orig + tmin * dir is the first intersection real &tmax, // Imax = orig + tmax * dir is the second intersection real epsilon = M_EPSILON); // the epsilon to use /*! Checks whether 3D point P lies inside or outside of the triangle ABC */ bool includePointTriangle(const Vec3r &P, const Vec3r &A, const Vec3r &B, const Vec3r &C); void transformVertex(const Vec3r &vert, const Matrix44r &matrix, Vec3r &res); void transformVertices(const vector &vertices, const Matrix44r &trans, vector &res); Vec3r rotateVector(const Matrix44r &mat, const Vec3r &v); // // Coordinates systems changing procedures // ///////////////////////////////////////////////////////////////////////////// /*! From world to image * p * point's coordinates expressed in world coordinates system * q * vector in which the result will be stored * model_view_matrix * The model view matrix expressed in line major order (OpenGL * matrices are column major ordered) * projection_matrix * The projection matrix expressed in line major order (OpenGL * matrices are column major ordered) * viewport * The viewport: x,y coordinates followed by width and height (OpenGL like viewport) */ void fromWorldToImage(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4], const real projection_matrix[4][4], const int viewport[4]); /*! From world to image * p * point's coordinates expressed in world coordinates system * q * vector in which the result will be stored * transform * The transformation matrix (gathering model view and projection), * expressed in line major order (OpenGL matrices are column major ordered) * viewport * The viewport: x,y coordinates followed by width and height (OpenGL like viewport) */ void fromWorldToImage(const Vec3r &p, Vec3r &q, const real transform[4][4], const int viewport[4]); /*! Projects from world coordinates to camera coordinates * Returns the point's coordinates expressed in the camera's * coordinates system. * p * point's coordinates expressed in world coordinates system * q * vector in which the result will be stored * model_view_matrix * The model view matrix expressed in line major order (OpenGL * matrices are column major ordered) */ void fromWorldToCamera(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4]); /*! Projects from World Coordinates to retina coordinates * Returns the point's coordinates expressed in Retina system. * p * point's coordinates expressed in camera system * q * vector in which the result will be stored * projection_matrix * The projection matrix expressed in line major order (OpenGL * matrices are column major ordered) */ void fromCameraToRetina(const Vec3r &p, Vec3r &q, const real projection_matrix[4][4]); /*! From retina to image. * Returns the coordinates expressed in Image coordinates system. * p * point's coordinates expressed in retina system * q * vector in which the result will be stored * viewport * The viewport: x,y coordinates followed by width and height (OpenGL like viewport). */ void fromRetinaToImage(const Vec3r &p, Vec3r &q, const int viewport[4]); /*! From image to retina * p * point's coordinates expressed in image system * q * vector in which the result will be stored * viewport * The viewport: x,y coordinates followed by width and height (OpenGL like viewport). */ void fromImageToRetina(const Vec3r &p, Vec3r &q, const int viewport[4]); /*! computes the coordinates of q in the camera coordinates system, * using the known z coordinates of the 3D point. * That means that this method does not inverse any matrices, * it only computes X and Y from x,y and Z) * p * point's coordinates expressed in retina system * q * vector in which the result will be stored * projection_matrix * The projection matrix expressed in line major order (OpenGL * matrices are column major ordered) */ void fromRetinaToCamera(const Vec3r &p, Vec3r &q, real z, const real projection_matrix[4][4]); /*! Projects from camera coordinates to world coordinates * Returns the point's coordinates expressed in the world's * coordinates system. * p * point's coordinates expressed in the camera coordinates system * q * vector in which the result will be stored * model_view_matrix * The model view matrix expressed in line major order (OpenGL * matrices are column major ordered) */ void fromCameraToWorld(const Vec3r &p, Vec3r &q, const real model_view_matrix[4][4]); } // end of namespace GeomUtils } /* namespace Freestyle */