collision_filtering.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 "test.h"
24 
25 // This is a test of collision filtering.
26 // There is a triangle, a box, and a circle.
27 // There are 6 shapes. 3 large and 3 small.
28 // The 3 small ones always collide.
29 // The 3 large ones never collide.
30 // The boxes don't collide with triangles (except if both are small).
31 const int16 k_smallGroup = 1;
32 const int16 k_largeGroup = -1;
33 
34 const uint16 k_triangleCategory = 0x0002;
35 const uint16 k_boxCategory = 0x0004;
36 const uint16 k_circleCategory = 0x0008;
37 
38 const uint16 k_triangleMask = 0xFFFF;
40 const uint16 k_circleMask = 0xFFFF;
41 
42 class CollisionFiltering : public Test
43 {
44 public:
46  {
47  // Ground body
48  {
49  b2EdgeShape shape;
50  shape.SetTwoSided(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
51 
52  b2FixtureDef sd;
53  sd.shape = &shape;
54  sd.friction = 0.3f;
55 
56  b2BodyDef bd;
57  b2Body* ground = m_world->CreateBody(&bd);
58  ground->CreateFixture(&sd);
59  }
60 
61  // Small triangle
62  b2Vec2 vertices[3];
63  vertices[0].Set(-1.0f, 0.0f);
64  vertices[1].Set(1.0f, 0.0f);
65  vertices[2].Set(0.0f, 2.0f);
66  b2PolygonShape polygon;
67  polygon.Set(vertices, 3);
68 
69  b2FixtureDef triangleShapeDef;
70  triangleShapeDef.shape = &polygon;
71  triangleShapeDef.density = 1.0f;
72 
73  triangleShapeDef.filter.groupIndex = k_smallGroup;
74  triangleShapeDef.filter.categoryBits = k_triangleCategory;
75  triangleShapeDef.filter.maskBits = k_triangleMask;
76 
77  b2BodyDef triangleBodyDef;
78  triangleBodyDef.type = b2_dynamicBody;
79  triangleBodyDef.position.Set(-5.0f, 2.0f);
80 
81  b2Body* body1 = m_world->CreateBody(&triangleBodyDef);
82  body1->CreateFixture(&triangleShapeDef);
83 
84  // Large triangle (recycle definitions)
85  vertices[0] *= 2.0f;
86  vertices[1] *= 2.0f;
87  vertices[2] *= 2.0f;
88  polygon.Set(vertices, 3);
89  triangleShapeDef.filter.groupIndex = k_largeGroup;
90  triangleBodyDef.position.Set(-5.0f, 6.0f);
91  triangleBodyDef.fixedRotation = true; // look at me!
92 
93  b2Body* body2 = m_world->CreateBody(&triangleBodyDef);
94  body2->CreateFixture(&triangleShapeDef);
95 
96  {
97  b2BodyDef bd;
98  bd.type = b2_dynamicBody;
99  bd.position.Set(-5.0f, 10.0f);
100  b2Body* body = m_world->CreateBody(&bd);
101 
102  b2PolygonShape p;
103  p.SetAsBox(0.5f, 1.0f);
104  body->CreateFixture(&p, 1.0f);
105 
107  jd.bodyA = body2;
108  jd.bodyB = body;
109  jd.enableLimit = true;
110  jd.localAnchorA.Set(0.0f, 4.0f);
111  jd.localAnchorB.SetZero();
112  jd.localAxisA.Set(0.0f, 1.0f);
113  jd.lowerTranslation = -1.0f;
114  jd.upperTranslation = 1.0f;
115 
116  m_world->CreateJoint(&jd);
117  }
118 
119  // Small box
120  polygon.SetAsBox(1.0f, 0.5f);
121  b2FixtureDef boxShapeDef;
122  boxShapeDef.shape = &polygon;
123  boxShapeDef.density = 1.0f;
124  boxShapeDef.restitution = 0.1f;
125 
126  boxShapeDef.filter.groupIndex = k_smallGroup;
127  boxShapeDef.filter.categoryBits = k_boxCategory;
128  boxShapeDef.filter.maskBits = k_boxMask;
129 
130  b2BodyDef boxBodyDef;
131  boxBodyDef.type = b2_dynamicBody;
132  boxBodyDef.position.Set(0.0f, 2.0f);
133 
134  b2Body* body3 = m_world->CreateBody(&boxBodyDef);
135  body3->CreateFixture(&boxShapeDef);
136 
137  // Large box (recycle definitions)
138  polygon.SetAsBox(2.0f, 1.0f);
139  boxShapeDef.filter.groupIndex = k_largeGroup;
140  boxBodyDef.position.Set(0.0f, 6.0f);
141 
142  b2Body* body4 = m_world->CreateBody(&boxBodyDef);
143  body4->CreateFixture(&boxShapeDef);
144 
145  // Small circle
146  b2CircleShape circle;
147  circle.m_radius = 1.0f;
148 
149  b2FixtureDef circleShapeDef;
150  circleShapeDef.shape = &circle;
151  circleShapeDef.density = 1.0f;
152 
153  circleShapeDef.filter.groupIndex = k_smallGroup;
154  circleShapeDef.filter.categoryBits = k_circleCategory;
155  circleShapeDef.filter.maskBits = k_circleMask;
156 
157  b2BodyDef circleBodyDef;
158  circleBodyDef.type = b2_dynamicBody;
159  circleBodyDef.position.Set(5.0f, 2.0f);
160 
161  b2Body* body5 = m_world->CreateBody(&circleBodyDef);
162  body5->CreateFixture(&circleShapeDef);
163 
164  // Large circle
165  circle.m_radius *= 2.0f;
166  circleShapeDef.filter.groupIndex = k_largeGroup;
167  circleBodyDef.position.Set(5.0f, 6.0f);
168 
169  b2Body* body6 = m_world->CreateBody(&circleBodyDef);
170  body6->CreateFixture(&circleShapeDef);
171  }
172 
173  static Test* Create()
174  {
175  return new CollisionFiltering;
176  }
177 };
178 
179 static int testIndex = RegisterTest("Examples", "Collision Filtering", CollisionFiltering::Create);
b2EdgeShape
Definition: b2_edge_shape.h:32
b2Filter::maskBits
uint16 maskBits
Definition: b2_fixture.h:51
b2PrismaticJointDef::localAnchorA
b2Vec2 localAnchorA
The local anchor point relative to bodyA's origin.
Definition: b2_prismatic_joint.h:57
b2PrismaticJointDef::lowerTranslation
float lowerTranslation
The lower translation limit, usually in meters.
Definition: b2_prismatic_joint.h:72
k_smallGroup
const int16 k_smallGroup
Definition: collision_filtering.cpp:31
CollisionFiltering::Create
static Test * Create()
Definition: collision_filtering.cpp:173
b2PrismaticJointDef::localAnchorB
b2Vec2 localAnchorB
The local anchor point relative to bodyB's origin.
Definition: b2_prismatic_joint.h:60
b2Body
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2CircleShape
A solid circle shape.
Definition: b2_circle_shape.h:30
b2Vec2::SetZero
void SetZero()
Set this vector to all zeros.
Definition: b2_math.h:50
b2FixtureDef
Definition: b2_fixture.h:61
k_boxCategory
const uint16 k_boxCategory
Definition: collision_filtering.cpp:35
b2Vec2::Set
void Set(float x_, float y_)
Set this vector to some specified coordinates.
Definition: b2_math.h:53
b2Vec2
A 2D column vector.
Definition: b2_math.h:41
k_boxMask
const uint16 k_boxMask
Definition: collision_filtering.cpp:39
b2EdgeShape::SetTwoSided
void SetTwoSided(const b2Vec2 &v1, const b2Vec2 &v2)
Set this as an isolated edge. Collision is two-sided.
Definition: b2_edge_shape.cpp:36
b2PolygonShape::Set
void Set(const b2Vec2 *points, int32 count)
Definition: b2_polygon_shape.cpp:118
f
f
b2BodyDef::type
b2BodyType type
Definition: b2_body.h:74
b2World::CreateJoint
b2Joint * CreateJoint(const b2JointDef *def)
Definition: b2_world.cpp:220
k_triangleCategory
const uint16 k_triangleCategory
Definition: collision_filtering.cpp:34
b2FixtureDef::restitution
float restitution
The restitution (elasticity) usually in the range [0,1].
Definition: b2_fixture.h:85
b2FixtureDef::friction
float friction
The friction coefficient, usually in the range [0,1].
Definition: b2_fixture.h:82
b2_dynamicBody
@ b2_dynamicBody
Definition: b2_body.h:47
b2FixtureDef::filter
b2Filter filter
Contact filtering data.
Definition: b2_fixture.h:99
b2Shape::m_radius
float m_radius
Definition: b2_shape.h:102
k_circleMask
const uint16 k_circleMask
Definition: collision_filtering.cpp:40
b2PrismaticJointDef::enableLimit
bool enableLimit
Enable/disable the joint limit.
Definition: b2_prismatic_joint.h:69
b2PrismaticJointDef
Definition: b2_prismatic_joint.h:35
b2PolygonShape::SetAsBox
void SetAsBox(float hx, float hy)
Definition: b2_polygon_shape.cpp:36
b2FixtureDef::density
float density
The density, usually in kg/m^2.
Definition: b2_fixture.h:92
k_circleCategory
const uint16 k_circleCategory
Definition: collision_filtering.cpp:36
CollisionFiltering
Definition: collision_filtering.cpp:42
b2BodyDef
Definition: b2_body.h:52
testIndex
static int testIndex
Definition: collision_filtering.cpp:179
k_triangleMask
const uint16 k_triangleMask
Definition: collision_filtering.cpp:38
b2FixtureDef::shape
const b2Shape * shape
Definition: b2_fixture.h:76
uint16
unsigned short uint16
Definition: b2_types.h:30
b2World::CreateBody
b2Body * CreateBody(const b2BodyDef *def)
Definition: b2_world.cpp:115
b2PolygonShape
Definition: b2_polygon_shape.h:32
RegisterTest
int RegisterTest(const char *category, const char *name, TestCreateFcn *fcn)
Definition: test.cpp:458
CollisionFiltering::CollisionFiltering
CollisionFiltering()
Definition: collision_filtering.cpp:45
b2PrismaticJointDef::upperTranslation
float upperTranslation
The upper translation limit, usually in meters.
Definition: b2_prismatic_joint.h:75
int16
signed short int16
Definition: b2_types.h:27
b2Filter::groupIndex
int16 groupIndex
Definition: b2_fixture.h:56
b2BodyDef::fixedRotation
bool fixedRotation
Should this body be prevented from rotating? Useful for characters.
Definition: b2_body.h:109
Test
Definition: test.h:80
b2BodyDef::position
b2Vec2 position
Definition: b2_body.h:78
b2Filter::categoryBits
uint16 categoryBits
The collision category bits. Normally you would just set one bit.
Definition: b2_fixture.h:47
b2PrismaticJointDef::localAxisA
b2Vec2 localAxisA
The local translation unit axis in bodyA.
Definition: b2_prismatic_joint.h:63
k_largeGroup
const int16 k_largeGroup
Definition: collision_filtering.cpp:32
b2JointDef::bodyA
b2Body * bodyA
The first attached body.
Definition: b2_joint.h:89
Test::m_world
b2World * m_world
Definition: test.h:128
b2Body::CreateFixture
b2Fixture * CreateFixture(const b2FixtureDef *def)
Definition: b2_body.cpp:165
b2JointDef::bodyB
b2Body * bodyB
The second attached body.
Definition: b2_joint.h:92


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:07