This file is indexed.

/usr/include/SurgSim/Collision/SegmentSegmentCcdMovingContact.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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// 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_COLLISION_SEGMENTSEGMENTCCDMOVINGCONTACT_H
#define SURGSIM_COLLISION_SEGMENTSEGMENTCCDMOVINGCONTACT_H

#include <array>

#include "SurgSim/Collision/SegmentSegmentCcdIntervalCheck.h"
#include "SurgSim/Collision/SegmentSegmentCcdStaticContact.h"
#include "SurgSim/Framework/Logger.h"

namespace SurgSim
{
namespace Math
{
class SegmentMeshShape;
};

namespace Collision
{

class CollisionPair;

/// SegmentSegmentCcdMovingContact computes the self collisions among a SegmentMesh under motion at two
/// time points parametrized over the time interval [0,1]. An initial phase uses the AABB tree to
/// select a set of potentially colliding segments from the SegmentMesh. For each of these
/// candidate segment pairs, the goal is to determine the point of earliest contact should any exist.
///
/// At the highest level the actual collision detection of candidate segment pairs is a two phase
/// algorithm. First determine if there is contact at the start of an interval and report the contact if
/// found. If no contact is found at the start, subdivide the interval, determine which of the resulting
/// candidate subintervals may have collisions, and then recursively check those promising subintervals.
/// Note that a simple algorithm based on interval arithmetic (including the Interval, LinearMotion and
/// Polynomial interval classes) allows for a quick determination of promising subintervals allowing many
/// of the subintervals to be pruned during the subdivision step without forcing the recursion to bottom out.
///
/// \sa Interval, LinearMotion, Polynomial, SegmentSegmentCcdIntervalCheck
///
class SegmentSegmentCcdMovingContact
{
public:
	static const int SUB_POINTS_PARALLEL_CASE = 5;
	static const int SUB_POINTS_COPLANAR_CASE = 10;

	/// Constructor.
	SegmentSegmentCcdMovingContact();

	/// Calculate if, where, and when the segments p and q collide in the interval from t = 0 to t = 1
	/// for "zero" thickness segments.
	/// \param pt0Positions are the segment endpoints for the first segment at time t=0.
	/// \param pt1Positions are the segment endpoints for the first segment at time t=1.
	/// \param qt0Positions are the segment endpoints for the second segment at time t=0.
	/// \param qt1Positions are the segment endpoints for the second segment at time t=1.
	/// \param thicknessEpsilon spatial nearness criteria for declaring a contact.
	/// \param timePrecisionEpsilon time nearness criteria for declaring a contact.
	/// \param t [out] parametric location of the collision along the time axes in the interval [0, 1]
	/// \param r [out] parametric location of the collision along p in the interval [0, 1]
	/// \param s [out] parametric location of the collision along q in the interval [0, 1]
	/// \param pToQDir [out] direction from the contact point on p to the contact point on q
	/// \return true if p and q collide in interval [0, 1]
	bool collideMovingSegmentSegment(
		const std::array<Math::Vector3d, 2>& pt0Positions,
		const std::array<Math::Vector3d, 2>& pt1Positions,
		const std::array<Math::Vector3d, 2>& qt0Positions,
		const std::array<Math::Vector3d, 2>& qt1Positions,
		double thicknessEpsilon,
		double timePrecisionEpsilon,
		double* t, double* r, double* s, Math::Vector3d* pToQDir);

	/// Calculate if, where, and when the segments p and q collide in the interval from t = 0 to t = 1
	/// for thick segments.
	/// \param pt0Positions are the segment endpoints for the first segment at time t=0.
	/// \param pt1Positions are the segment endpoints for the first segment at time t=1.
	/// \param qt0Positions are the segment endpoints for the second segment at time t=0.
	/// \param qt1Positions are the segment endpoints for the second segment at time t=1.
	/// \param thicknessP radius of segment p.
	/// \param thicknessQ radius of segment q.
	/// \param timePrecisionEpsilon time nearness criteria for declaring a contact.
	/// \param t [out] parametric location of the collision along the time axes in the interval [0, 1]
	/// \param r [out] parametric location of the collision along p in the interval [0, 1]
	/// \param s [out] parametric location of the collision along q in the interval [0, 1]
	/// \param pToQDir [out] direction from the contact point on p to the contact point on q at time t
	/// \return true if p and q collide in interval [0, 1]
	bool collideMovingSegmentSegment(
		const std::array<Math::Vector3d, 2>& pt0Positions,
		const std::array<Math::Vector3d, 2>& pt1Positions,
		const std::array<Math::Vector3d, 2>& qt0Positions,
		const std::array<Math::Vector3d, 2>& qt1Positions,
		double thicknessP,
		double thicknessQ,
		double timePrecisionEpsilon,
		double* t, double* r, double* s, Math::Vector3d* pToQDir);

protected:
	/// Manage the collision of moving segments as a series of cases based on the segment
	/// relationships over the moving interval.
	/// \param pT0 are the segment endpoints for the first segment at time t=0.
	/// \param pT1 are the segment endpoints for the first segment at time t=1.
	/// \param qT0 are the segment endpoints for the second segment at time t=0.
	/// \param qT1 are the segment endpoints for the second segment at time t=1.
	/// \param thicknessP radius of segment p.
	/// \param thicknessQ radius of segment q.
	/// \param timePrecisionEpsilon time nearness criteria for declaring a contact.
	/// \param t [out] parametric location of the collision along the time axes in the interval [0, 1]
	/// \param r [out] parametric location of the collision along p in the interval [0, 1]
	/// \param s [out] parametric location of the collision along q in the interval [0, 1]
	/// \return true if p and q collide in interval [0, 1]
	bool collideSegmentSegmentBaseCase(
		const std::array<Math::Vector3d, 2>& pT0,
		const std::array<Math::Vector3d, 2>& pT1,
		const std::array<Math::Vector3d, 2>& qT0,
		const std::array<Math::Vector3d, 2>& qT1,
		double thicknessP,
		double thicknessQ,
		double timePrecisionEpsilon,
		double* t, double* r, double* s);

	/// Manage the specific case of detecting collisions between segments p and q which are parallel throughout
	/// the parametric time interval of interest [a, b].
	/// \param pT0 are the segment endpoints for the first segment at time t=0.
	/// \param pT1 are the segment endpoints for the first segment at time t=1.
	/// \param qT0 are the segment endpoints for the second segment at time t=0.
	/// \param qT1 are the segment endpoints for the second segment at time t=1.
	/// \param a parametric starting point of the interval of interest.
	/// \param b parametric ending point of the interval of interest.
	/// \param thicknessP radius of segment p.
	/// \param thicknessQ radius of segment q.
	/// \param timePrecisionEpsilon time nearness criteria for declaring a contact.
	/// \param t [out] parametric location of the collision along the time axes in the interval [0, 1]
	/// \param r [in/out] parametric location of the collision along p in the interval [0, 1]
	/// \param s [in/out] parametric location of the collision along q in the interval [0, 1]
	/// \param depth recursion depth.
	/// \return true if p and q collide in interval [a, b]
	bool collideSegmentSegmentParallelCase(
		const std::array<Math::Vector3d, 2>& pT0,
		const std::array<Math::Vector3d, 2>& pT1,
		const std::array<Math::Vector3d, 2>& qT0,
		const std::array<Math::Vector3d, 2>& qT1,
		double a, double b,
		double thicknessP, double thicknessQ,
		double timePrecisionEpsilon,
		double* t, double* r, double* s, int depth = 0);

	/// Manage the specific case of detecting collisions between segments p and q which are coplanar throughout
	/// the parametric time interval of interest [a, b].
	/// \param pT0 are the segment endpoints for the first segment at time t=0.
	/// \param pT1 are the segment endpoints for the first segment at time t=1.
	/// \param qT0 are the segment endpoints for the second segment at time t=0.
	/// \param qT1 are the segment endpoints for the second segment at time t=1.
	/// \param a parametric starting point of the interval of interest.
	/// \param b parametric ending point of the interval of interest.
	/// \param thicknessP radius of segment p.
	/// \param thicknessQ radius of segment q.
	/// \param timePrecisionEpsilon time nearness criteria for declaring a contact.
	/// \param t [out] parametric location of the collision along the time axes in the interval [0, 1]
	/// \param r [in/out] parametric location of the collision along p in the interval [0, 1]
	/// \param s [in/out] parametric location of the collision along q in the interval [0, 1]
	/// \param depth recursion depth.
	/// \return true if p and q collide in interval [a, b]
	bool collideSegmentSegmentCoplanarCase(
		const std::array<Math::Vector3d, 2>& pT0, /* Segment 1 at t=0 */
		const std::array<Math::Vector3d, 2>& pT1, /* Segment 1 at t=1 */
		const std::array<Math::Vector3d, 2>& qT0, /* Segment 2 at t=0 */
		const std::array<Math::Vector3d, 2>& qT1, /* Segment 2 at t=1 */
		double a, double b, /* Interval boundaries */
		double timePrecisionEpsilon,
		double thicknessP, double thicknessQ,
		double* t, double* r, double* s,
		int depth = 0);

	/// Manage the general case of detecting collisions between segments p and q over the parametric time
	/// interval [a, b] when no special spatial relationships can be observed that improve performance.
	/// \param state an encapsulation of the segment locations, movements, and detection parameters.
	/// \param a parametric starting point of the interval of interest.
	/// \param b parametric ending point of the interval of interest.
	/// \param t [out] parametric location of the collision along the time axes in the interval [0, 1]
	/// \param r [out] parametric location of the collision along p in the interval [0, 1]
	/// \param s [out] parametric location of the collision along q in the interval [0, 1]
	/// \param depth recursion depth.
	/// \return true if p and q collide in interval [a, b]
	bool collideSegmentSegmentGeneralCase(
		const SegmentSegmentCcdIntervalCheck& state,
		double a, double b, // Interval boundaries
		double* t, double* r, double* s,
		int depth = 0);

	/// Safely normalize segments t0 and t1 consistently with each other. Under the assumption that they
	/// both represent the same segment at two different time points. Ensure that for cases where the segment
	/// is too small at one or both time points (i.e. they essentially degenerate to a point) that we make
	/// an intelligent choice.
	/// \param t0 segment at time 0
	/// \param t1 segment at time 1
	/// \param epsilon threshold for valid normalization value.
	void normalizeSegmentsConsistently(Math::Vector3d* t0, Math::Vector3d* t1, double epsilon) const;

private:
	/// Utility routine to perform a series of checks to determine if a collision is likely within an interval. The
	/// checks seek to determine if two coplanar segments could have been out of contact at the start of an interval,
	/// and then moved through a contact and back away. Among the values checked are the normals because a change in
	/// normal direction of p X q indicates that p is now on the other side of q. Other checks are made for flipping
	/// segments, etc.
	/// \param rCurrent is the parametric location on segment p at the start of the current time interval
	/// \param rNext is the parametric location on segment p at the end of the current time interval
	/// \param sCurrent is the parametric location on segment q at the start of the current time interval
	/// \param sNext is the parametric location on segment q at the end of the current time interval
	/// \param nCurrent is the normal of p x q at the start of the current time interval
	/// \param nNext is the normal of p x q at the current time point
	/// \return true if the check indicates a collision may be possible for coplanar segments p and
	/// q at the current time interval.
	bool checkForCoplanarContactWithinInterval(double rCurrent, double rNext, double sCurrent, double sNext,
			const Math::Vector3d& nCurrent, const Math::Vector3d& nNext) const;

	/// Minimum distance precision epsilon used in continuous collision detection.
	const double m_distanceEpsilon;

	/// Utility class for testing interval boundary collisions.
	Collision::SegmentSegmentCcdStaticContact m_staticTest;

	/// Logger
	std::shared_ptr<SurgSim::Framework::Logger> m_logger;
};

}; // namespace Collision
}; // namespace SurgSim

#endif // SURGSIM_COLLISION_SEGMENTSEGMENTCCDMOVINGCONTACT_H