This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/freestyle/intern/geometry/GeomUtils.h

268 lines
9.8 KiB
C++

/*
* 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 <vector>
#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<class T> 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<Vec3r> &vertices, const Matrix44r &trans, vector<Vec3r> &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 focal, 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 */