2
* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
4
* This software is provided 'as-is', without any express or implied
5
* warranty. In no event will the authors be held liable for any damages
6
* arising from the use of this software.
7
* Permission is granted to anyone to use this software for any purpose,
8
* including commercial applications, and to alter it and redistribute it
9
* freely, subject to the following restrictions:
10
* 1. The origin of this software must not be misrepresented; you must not
11
* claim that you wrote the original software. If you use this software
12
* in a product, an acknowledgment in the product documentation would be
13
* appreciated but is not required.
14
* 2. Altered source versions must be plainly marked as such, and must not be
15
* misrepresented as being the original software.
16
* 3. This notice may not be removed or altered from any source distribution.
19
#include <Box2D/Collision/b2Collision.h>
20
#include <Box2D/Collision/Shapes/b2CircleShape.h>
21
#include <Box2D/Collision/Shapes/b2PolygonShape.h>
23
void b2CollideCircles(
25
const b2CircleShape* circleA, const b2Transform& xfA,
26
const b2CircleShape* circleB, const b2Transform& xfB)
28
manifold->pointCount = 0;
30
b2Vec2 pA = b2Mul(xfA, circleA->m_p);
31
b2Vec2 pB = b2Mul(xfB, circleB->m_p);
34
float32 distSqr = b2Dot(d, d);
35
float32 rA = circleA->m_radius, rB = circleB->m_radius;
36
float32 radius = rA + rB;
37
if (distSqr > radius * radius)
42
manifold->type = b2Manifold::e_circles;
43
manifold->localPoint = circleA->m_p;
44
manifold->localNormal.SetZero();
45
manifold->pointCount = 1;
47
manifold->points[0].localPoint = circleB->m_p;
48
manifold->points[0].id.key = 0;
51
void b2CollidePolygonAndCircle(
53
const b2PolygonShape* polygonA, const b2Transform& xfA,
54
const b2CircleShape* circleB, const b2Transform& xfB)
56
manifold->pointCount = 0;
58
// Compute circle position in the frame of the polygon.
59
b2Vec2 c = b2Mul(xfB, circleB->m_p);
60
b2Vec2 cLocal = b2MulT(xfA, c);
62
// Find the min separating edge.
63
int32 normalIndex = 0;
64
float32 separation = -b2_maxFloat;
65
float32 radius = polygonA->m_radius + circleB->m_radius;
66
int32 vertexCount = polygonA->m_vertexCount;
67
const b2Vec2* vertices = polygonA->m_vertices;
68
const b2Vec2* normals = polygonA->m_normals;
70
for (int32 i = 0; i < vertexCount; ++i)
72
float32 s = b2Dot(normals[i], cLocal - vertices[i]);
87
// Vertices that subtend the incident face.
88
int32 vertIndex1 = normalIndex;
89
int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
90
b2Vec2 v1 = vertices[vertIndex1];
91
b2Vec2 v2 = vertices[vertIndex2];
93
// If the center is inside the polygon ...
94
if (separation < b2_epsilon)
96
manifold->pointCount = 1;
97
manifold->type = b2Manifold::e_faceA;
98
manifold->localNormal = normals[normalIndex];
99
manifold->localPoint = 0.5f * (v1 + v2);
100
manifold->points[0].localPoint = circleB->m_p;
101
manifold->points[0].id.key = 0;
105
// Compute barycentric coordinates
106
float32 u1 = b2Dot(cLocal - v1, v2 - v1);
107
float32 u2 = b2Dot(cLocal - v2, v1 - v2);
110
if (b2DistanceSquared(cLocal, v1) > radius * radius)
115
manifold->pointCount = 1;
116
manifold->type = b2Manifold::e_faceA;
117
manifold->localNormal = cLocal - v1;
118
manifold->localNormal.Normalize();
119
manifold->localPoint = v1;
120
manifold->points[0].localPoint = circleB->m_p;
121
manifold->points[0].id.key = 0;
125
if (b2DistanceSquared(cLocal, v2) > radius * radius)
130
manifold->pointCount = 1;
131
manifold->type = b2Manifold::e_faceA;
132
manifold->localNormal = cLocal - v2;
133
manifold->localNormal.Normalize();
134
manifold->localPoint = v2;
135
manifold->points[0].localPoint = circleB->m_p;
136
manifold->points[0].id.key = 0;
140
b2Vec2 faceCenter = 0.5f * (v1 + v2);
141
float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]);
142
if (separation > radius)
147
manifold->pointCount = 1;
148
manifold->type = b2Manifold::e_faceA;
149
manifold->localNormal = normals[vertIndex1];
150
manifold->localPoint = faceCenter;
151
manifold->points[0].localPoint = circleB->m_p;
152
manifold->points[0].id.key = 0;