This file is indexed.

/usr/include/SurgSim/Math/TriangleTriangleIntersection-inl.h is in libopensurgsim-dev 0.7.0-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SURGSIM_MATH_TRIANGLETRIANGLEINTERSECTION_INL_H
#define SURGSIM_MATH_TRIANGLETRIANGLEINTERSECTION_INL_H

namespace
{
static const double EPSILOND = 1e-12;
}

namespace SurgSim
{

namespace Math
{


/// Two ends of the triangle edge are given in terms of the following vertex properties.
///		- Signed distance from the colliding triangle.
///		- Projection on the separating axis.
/// Get the intersection of this edge and the plane in terms of the projection on the separating axis.
/// \tparam T Accuracy of the calculation, can usually be inferred.
/// \param dStart Signed distance of the start of edge from the plane of the colliding triangle.
/// \param dEnd Signed distance of the end of edge from the plane of the colliding triangle.
/// \param pvStart Projection of the start of edge from the plane of the colliding triangle.
/// \param pvEnd Projection of the end of edge from the plane of the colliding triangle.
/// \param parametricIntersection Parametric representation of the intersection between the triangle edge
///		   and the plane in terms of the projection on the separating axis.
/// \param parametricIntersectionIndex The array index of parametricIntersection.
template<class T>
void edgeIntersection(T dStart, T dEnd, T pvStart, T pvEnd, T* parametricIntersection,
					  size_t* parametricIntersectionIndex)
{
	// Epsilon used in this function.
	static const T EPSILON = static_cast<T>(EPSILOND);

	bool edgeFromUnderToAbove = dStart < 0.0 && dEnd >= 0.0;
	bool edgeFromAboveToUnder = dStart > 0.0 && dEnd <= 0.0;

	if (edgeFromUnderToAbove || edgeFromAboveToUnder)
	{
		if (std::abs(dStart - dEnd) < EPSILON)
		{
			// Start and End are really close. Pick start.
			parametricIntersection[(*parametricIntersectionIndex)++] = pvStart;
		}
		else
		{
			// Clip to the point in the intersection of Start->End and plane of the colliding triangle.
			parametricIntersection[(*parametricIntersectionIndex)++] =
				pvStart + (pvEnd - pvStart) * (dStart / (dStart - dEnd));
		}
	}
}

template <class T, int MOpt> inline
bool doesIntersectTriangleTriangle(
	const Eigen::Matrix<T, 3, 1, MOpt>& t0v0,
	const Eigen::Matrix<T, 3, 1, MOpt>& t0v1,
	const Eigen::Matrix<T, 3, 1, MOpt>& t0v2,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1v0,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1v1,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1v2,
	const Eigen::Matrix<T, 3, 1, MOpt>& t0n,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1n)
{
	typedef Eigen::Matrix<T, 3, 1, MOpt> Vector3;
	using SurgSim::Math::Geometry::DistanceEpsilon;

	if (t0n.isZero() || t1n.isZero())
	{
		// Degenerate triangle(s) passed to checkTriangleTriangleIntersection.
		return false;
	}

	// Variable names mentioned here are the notations used in the paper:
	// T1		- Triangle with vertices (t0v0, t0v1, t0v2).
	// T2		- Triangle with vertices (t1v0, t1v1, t1v2).
	// d1[3]	- Signed distances of the vertices of T1 from the plane of T2.
	// d2[3]	- Signed distances of the vertices of T2 from the plane of T1.
	// D		- Separating axis used for the test. This is calculated as the cross products of the triangle normals.
	// pv1[3]	- Projection of the vertices of T1 onto the separating axis (D).
	// pv2[3]	- Projection of the vertices of T2 onto the separating axis (D).
	// s1[2]	- The intersection between T1 and D is a line segment.
	//			  s1[0] and s1[1] are the parametric representation of the ends of this line segment.
	// s2[2]	- The intersection between T2 and D is a line segment.
	//			  s2[0] and s2[1] are the parametric representation of the ends of this line segment.

	// Early Rejection test:
	// If all the vertices of one triangle are on one side of the plane of the other triangle,
	// there is no intersection.

	// Check if all the vertices of T2 are on one side of p1.
	// Plane eqn of T1: DotProduct(t0n, X) + distanceFromOrigin = 0
	// where distanceFromOrigin = -DotProduct(t0n, t0v0)
	// So, plane eqn of T1: DotProduct(t0n, X - t0v0) = 0
	// Distance of first vertex of T2 from the plane of T1 is: DotProduct(t0n, t1v0 - t0v0)
	Vector3 d2(t0n.dot(t1v0 - t0v0), t0n.dot(t1v1 - t0v0), t0n.dot(t1v2 - t0v0));

	if ((d2.array() < DistanceEpsilon).all() || (d2.array() > -DistanceEpsilon).all())
	{
		return false;
	}

	// Check if all the vertices of T1 are on one side of p2.
	Vector3 d1(t1n.dot(t0v0 - t1v0), t1n.dot(t0v1 - t1v0), t1n.dot(t0v2 - t1v0));

	if ((d1.array() < DistanceEpsilon).all() || (d1.array() > -DistanceEpsilon).all())
	{
		return false;
	}

	// The separating axis.
	Vector3 D = t0n.cross(t1n).normalized();

	// Projection of the triangle vertices on the separating axis.
	Vector3 pv1(D.dot(t0v0), D.dot(t0v1), D.dot(t0v2));
	Vector3 pv2(D.dot(t1v0), D.dot(t1v1), D.dot(t1v2));

	// The intersection of the triangles with the separating axis (D).
	T s1[3];
	T s2[3];
	size_t s1Index = 0;
	size_t s2Index = 0;

	// Loop through the edges of each triangle and find the intersection of these edges onto
	// the plane of the other triangle.
	for (int i = 0; i < 3; ++i)
	{
		int j = (i + 1) % 3;

		edgeIntersection(d1[i], d1[j], pv1[i], pv1[j], s1, &s1Index);
		edgeIntersection(d2[i], d2[j], pv2[i], pv2[j], s2, &s2Index);
	}

	SURGSIM_ASSERT(s1Index == 2 && s2Index == 2)
			<< "The intersection between the triangle and the separating axis is not a line segment."
			<< " This scenario cannot happen, at this point in the algorithm.";

	// s1[0], s1[1] are the (unordered) extents of the projection of T1 on D.
	// s2[0], s2[1] are the (unordered) extents of the projection of T2 on D.
	// If both these are line segments (i.e. the distance between them is > epsilon),
	// and if they overlap, then the two triangles intersect.

	return !(std::abs(s1[0] - s1[1]) <= DistanceEpsilon || std::abs(s2[0] - s2[1]) <= DistanceEpsilon) &&
		   !(s1[0] <= (s2[0] + DistanceEpsilon) && s1[0] <= (s2[1] + DistanceEpsilon) &&
			 s1[1] <= (s2[0] + DistanceEpsilon) && s1[1] <= (s2[1] + DistanceEpsilon)) &&
		   !(s1[0] >= (s2[0] - DistanceEpsilon) && s1[0] >= (s2[1] - DistanceEpsilon) &&
			 s1[1] >= (s2[0] - DistanceEpsilon) && s1[1] >= (s2[1] - DistanceEpsilon));
}


template <class T, int MOpt> inline
bool doesIntersectTriangleTriangle(
	const Eigen::Matrix<T, 3, 1, MOpt>& t0v0,
	const Eigen::Matrix<T, 3, 1, MOpt>& t0v1,
	const Eigen::Matrix<T, 3, 1, MOpt>& t0v2,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1v0,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1v1,
	const Eigen::Matrix<T, 3, 1, MOpt>& t1v2)
{
	Eigen::Matrix<T, 3, 1, MOpt> t0n = (t0v1 - t0v0).cross(t0v2 - t0v0);
	Eigen::Matrix<T, 3, 1, MOpt> t1n = (t1v1 - t1v0).cross(t1v2 - t1v0);
	if (t0n.isZero() || t1n.isZero())
	{
		// Degenerate triangle(s) passed to checkTriangleTriangleIntersection.
		return false;
	}
	t0n.normalize();
	t1n.normalize();
	return doesIntersectTriangleTriangle(t0v0, t0v1, t0v2, t1v0, t1v1, t1v2, t0n, t1n);
}


} // namespace Math

} // namespace SurgSim


#endif // SURGSIM_MATH_TRIANGLETRIANGLEINTERSECTION_INL_H