b2_collision.cpp
Go to the documentation of this file.
1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #include "box2d/b2_collision.h"
24 #include "box2d/b2_distance.h"
25 
27  const b2Transform& xfA, float radiusA,
28  const b2Transform& xfB, float radiusB)
29 {
30  if (manifold->pointCount == 0)
31  {
32  return;
33  }
34 
35  switch (manifold->type)
36  {
38  {
39  normal.Set(1.0f, 0.0f);
40  b2Vec2 pointA = b2Mul(xfA, manifold->localPoint);
41  b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint);
42  if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon)
43  {
44  normal = pointB - pointA;
45  normal.Normalize();
46  }
47 
48  b2Vec2 cA = pointA + radiusA * normal;
49  b2Vec2 cB = pointB - radiusB * normal;
50  points[0] = 0.5f * (cA + cB);
51  separations[0] = b2Dot(cB - cA, normal);
52  }
53  break;
54 
56  {
57  normal = b2Mul(xfA.q, manifold->localNormal);
58  b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint);
59 
60  for (int32 i = 0; i < manifold->pointCount; ++i)
61  {
62  b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);
63  b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal;
64  b2Vec2 cB = clipPoint - radiusB * normal;
65  points[i] = 0.5f * (cA + cB);
66  separations[i] = b2Dot(cB - cA, normal);
67  }
68  }
69  break;
70 
72  {
73  normal = b2Mul(xfB.q, manifold->localNormal);
74  b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint);
75 
76  for (int32 i = 0; i < manifold->pointCount; ++i)
77  {
78  b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);
79  b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;
80  b2Vec2 cA = clipPoint - radiusA * normal;
81  points[i] = 0.5f * (cA + cB);
82  separations[i] = b2Dot(cA - cB, normal);
83  }
84 
85  // Ensure normal points from A to B.
86  normal = -normal;
87  }
88  break;
89  }
90 }
91 
92 void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
93  const b2Manifold* manifold1, const b2Manifold* manifold2)
94 {
95  for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
96  {
97  state1[i] = b2_nullState;
98  state2[i] = b2_nullState;
99  }
100 
101  // Detect persists and removes.
102  for (int32 i = 0; i < manifold1->pointCount; ++i)
103  {
104  b2ContactID id = manifold1->points[i].id;
105 
106  state1[i] = b2_removeState;
107 
108  for (int32 j = 0; j < manifold2->pointCount; ++j)
109  {
110  if (manifold2->points[j].id.key == id.key)
111  {
112  state1[i] = b2_persistState;
113  break;
114  }
115  }
116  }
117 
118  // Detect persists and adds.
119  for (int32 i = 0; i < manifold2->pointCount; ++i)
120  {
121  b2ContactID id = manifold2->points[i].id;
122 
123  state2[i] = b2_addState;
124 
125  for (int32 j = 0; j < manifold1->pointCount; ++j)
126  {
127  if (manifold1->points[j].id.key == id.key)
128  {
129  state2[i] = b2_persistState;
130  break;
131  }
132  }
133  }
134 }
135 
136 // From Real-time Collision Detection, p179.
137 bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const
138 {
139  float tmin = -b2_maxFloat;
140  float tmax = b2_maxFloat;
141 
142  b2Vec2 p = input.p1;
143  b2Vec2 d = input.p2 - input.p1;
144  b2Vec2 absD = b2Abs(d);
145 
146  b2Vec2 normal;
147 
148  for (int32 i = 0; i < 2; ++i)
149  {
150  if (absD(i) < b2_epsilon)
151  {
152  // Parallel.
153  if (p(i) < lowerBound(i) || upperBound(i) < p(i))
154  {
155  return false;
156  }
157  }
158  else
159  {
160  float inv_d = 1.0f / d(i);
161  float t1 = (lowerBound(i) - p(i)) * inv_d;
162  float t2 = (upperBound(i) - p(i)) * inv_d;
163 
164  // Sign of the normal vector.
165  float s = -1.0f;
166 
167  if (t1 > t2)
168  {
169  b2Swap(t1, t2);
170  s = 1.0f;
171  }
172 
173  // Push the min up
174  if (t1 > tmin)
175  {
176  normal.SetZero();
177  normal(i) = s;
178  tmin = t1;
179  }
180 
181  // Pull the max down
182  tmax = b2Min(tmax, t2);
183 
184  if (tmin > tmax)
185  {
186  return false;
187  }
188  }
189  }
190 
191  // Does the ray start inside the box?
192  // Does the ray intersect beyond the max fraction?
193  if (tmin < 0.0f || input.maxFraction < tmin)
194  {
195  return false;
196  }
197 
198  // Intersection.
199  output->fraction = tmin;
200  output->normal = normal;
201  return true;
202 }
203 
204 // Sutherland-Hodgman clipping.
206  const b2Vec2& normal, float offset, int32 vertexIndexA)
207 {
208  // Start with no output points
209  int32 count = 0;
210 
211  // Calculate the distance of end points to the line
212  float distance0 = b2Dot(normal, vIn[0].v) - offset;
213  float distance1 = b2Dot(normal, vIn[1].v) - offset;
214 
215  // If the points are behind the plane
216  if (distance0 <= 0.0f) vOut[count++] = vIn[0];
217  if (distance1 <= 0.0f) vOut[count++] = vIn[1];
218 
219  // If the points are on different sides of the plane
220  if (distance0 * distance1 < 0.0f)
221  {
222  // Find intersection point of edge and plane
223  float interp = distance0 / (distance0 - distance1);
224  vOut[count].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
225 
226  // VertexA is hitting edgeB.
227  vOut[count].id.cf.indexA = static_cast<uint8>(vertexIndexA);
228  vOut[count].id.cf.indexB = vIn[0].id.cf.indexB;
229  vOut[count].id.cf.typeA = b2ContactFeature::e_vertex;
230  vOut[count].id.cf.typeB = b2ContactFeature::e_face;
231  ++count;
232 
233  b2Assert(count == 2);
234  }
235 
236  return count;
237 }
238 
239 bool b2TestOverlap( const b2Shape* shapeA, int32 indexA,
240  const b2Shape* shapeB, int32 indexB,
241  const b2Transform& xfA, const b2Transform& xfB)
242 {
243  b2DistanceInput input;
244  input.proxyA.Set(shapeA, indexA);
245  input.proxyB.Set(shapeB, indexB);
246  input.transformA = xfA;
247  input.transformB = xfB;
248  input.useRadii = true;
249 
250  b2SimplexCache cache;
251  cache.count = 0;
252 
253  b2DistanceOutput output;
254 
255  b2Distance(&output, &cache, &input);
256 
257  return output.distance < 10.0f * b2_epsilon;
258 }
d
uint8 indexB
Feature index on shapeB.
Definition: b2_collision.h:53
uint8 typeA
The feature type on shapeA.
Definition: b2_collision.h:54
void Initialize(const b2Manifold *manifold, const b2Transform &xfA, float radiusA, const b2Transform &xfB, float radiusB)
T b2Min(T a, T b)
Definition: b2_math.h:626
void Set(const b2Shape *shape, int32 index)
Definition: b2_distance.cpp:32
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2_math.h:422
Contact ids to facilitate warm starting.
Definition: b2_collision.h:59
Used for computing contact manifolds.
Definition: b2_collision.h:146
float b2Dot(const b2Vec2 &a, const b2Vec2 &b)
Perform the dot product on two vectors.
Definition: b2_math.h:395
b2Vec2 localNormal
not use for Type::e_points
Definition: b2_collision.h:109
b2Rot q
Definition: b2_math.h:361
b2Vec2 points[b2_maxManifoldPoints]
world contact point (point of intersection)
Definition: b2_collision.h:127
f
XmlRpcServer s
Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
Definition: b2_collision.h:153
b2Vec2 normal
world vector pointing from A to B
Definition: b2_collision.h:126
b2ContactID id
uniquely identifies a contact point between two shapes
Definition: b2_collision.h:80
uint8 typeB
The feature type on shapeB.
Definition: b2_collision.h:55
void b2Swap(T &a, T &b)
Definition: b2_math.h:658
b2ContactFeature cf
Definition: b2_collision.h:61
#define b2_maxManifoldPoints
Definition: b2_common.h:51
b2DistanceProxy proxyA
Definition: b2_distance.h:78
uint32 key
Used to quickly compare contact ids.
Definition: b2_collision.h:62
bool RayCast(b2RayCastOutput *output, const b2RayCastInput &input) const
void SetZero()
Set this vector to all zeros.
Definition: b2_math.h:50
A 2D column vector.
Definition: b2_math.h:41
b2ContactID id
Definition: b2_collision.h:149
signed int int32
Definition: b2_types.h:28
float b2DistanceSquared(const b2Vec2 &a, const b2Vec2 &b)
Definition: b2_math.h:467
void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], const b2Manifold *manifold1, const b2Manifold *manifold2)
int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], const b2Vec2 &normal, float offset, int32 vertexIndexA)
Clipping for contact manifolds.
b2Transform transformA
Definition: b2_distance.h:80
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2Transform transformB
Definition: b2_distance.h:81
int32 pointCount
the number of manifold points
Definition: b2_collision.h:112
b2Vec2 localPoint
usage depends on manifold type
Definition: b2_collision.h:77
point was removed in the update
Definition: b2_collision.h:137
B2_API void b2Distance(b2DistanceOutput *output, b2SimplexCache *cache, const b2DistanceInput *input)
uint8 indexA
Feature index on shapeA.
Definition: b2_collision.h:52
point was added in the update
Definition: b2_collision.h:135
b2PointState
This is used for determining the state of contact points.
Definition: b2_collision.h:132
float separations[b2_maxManifoldPoints]
a negative value indicates overlap, in meters
Definition: b2_collision.h:128
b2Vec2 localPoint
usage depends on manifold type
Definition: b2_collision.h:110
b2ManifoldPoint points[b2_maxManifoldPoints]
the points of contact
Definition: b2_collision.h:108
unsigned char uint8
Definition: b2_types.h:29
bool b2TestOverlap(const b2Shape *shapeA, int32 indexA, const b2Shape *shapeB, int32 indexB, const b2Transform &xfA, const b2Transform &xfB)
Determine if two generic shapes overlap.
Output for b2Distance.
Definition: b2_distance.h:86
float Normalize()
Convert this vector into a unit vector. Returns the length.
Definition: b2_math.h:102
T b2Abs(T a)
Definition: b2_math.h:610
#define b2_maxFloat
Definition: b2_common.h:39
#define b2_epsilon
Definition: b2_common.h:40
point does not exist
Definition: b2_collision.h:134
#define b2Assert(A)
Definition: b2_common.h:37
b2DistanceProxy proxyB
Definition: b2_distance.h:79
point persisted across the update
Definition: b2_collision.h:136


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:19