00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <Box2D/Dynamics/b2Fixture.h>
00020 #include <Box2D/Dynamics/Contacts/b2Contact.h>
00021 #include <Box2D/Dynamics/b2World.h>
00022 #include <Box2D/Collision/Shapes/b2CircleShape.h>
00023 #include <Box2D/Collision/Shapes/b2EdgeShape.h>
00024 #include <Box2D/Collision/Shapes/b2PolygonShape.h>
00025 #include <Box2D/Collision/Shapes/b2ChainShape.h>
00026 #include <Box2D/Collision/b2BroadPhase.h>
00027 #include <Box2D/Collision/b2Collision.h>
00028 #include <Box2D/Common/b2BlockAllocator.h>
00029
00030 b2Fixture::b2Fixture()
00031 {
00032 m_userData = NULL;
00033 m_body = NULL;
00034 m_next = NULL;
00035 m_proxies = NULL;
00036 m_proxyCount = 0;
00037 m_shape = NULL;
00038 m_density = 0.0f;
00039 }
00040
00041 void b2Fixture::Create(b2BlockAllocator* allocator, b2Body* body, const b2FixtureDef* def)
00042 {
00043 m_userData = def->userData;
00044 m_friction = def->friction;
00045 m_restitution = def->restitution;
00046
00047 m_body = body;
00048 m_next = NULL;
00049
00050 m_filter = def->filter;
00051
00052 m_isSensor = def->isSensor;
00053
00054 m_shape = def->shape->Clone(allocator);
00055
00056
00057 int32 childCount = m_shape->GetChildCount();
00058 m_proxies = (b2FixtureProxy*)allocator->Allocate(childCount * sizeof(b2FixtureProxy));
00059 for (int32 i = 0; i < childCount; ++i)
00060 {
00061 m_proxies[i].fixture = NULL;
00062 m_proxies[i].proxyId = b2BroadPhase::e_nullProxy;
00063 }
00064 m_proxyCount = 0;
00065
00066 m_density = def->density;
00067 }
00068
00069 void b2Fixture::Destroy(b2BlockAllocator* allocator)
00070 {
00071
00072 b2Assert(m_proxyCount == 0);
00073
00074
00075 int32 childCount = m_shape->GetChildCount();
00076 allocator->Free(m_proxies, childCount * sizeof(b2FixtureProxy));
00077 m_proxies = NULL;
00078
00079
00080 switch (m_shape->m_type)
00081 {
00082 case b2Shape::e_circle:
00083 {
00084 b2CircleShape* s = (b2CircleShape*)m_shape;
00085 s->~b2CircleShape();
00086 allocator->Free(s, sizeof(b2CircleShape));
00087 }
00088 break;
00089
00090 case b2Shape::e_edge:
00091 {
00092 b2EdgeShape* s = (b2EdgeShape*)m_shape;
00093 s->~b2EdgeShape();
00094 allocator->Free(s, sizeof(b2EdgeShape));
00095 }
00096 break;
00097
00098 case b2Shape::e_polygon:
00099 {
00100 b2PolygonShape* s = (b2PolygonShape*)m_shape;
00101 s->~b2PolygonShape();
00102 allocator->Free(s, sizeof(b2PolygonShape));
00103 }
00104 break;
00105
00106 case b2Shape::e_chain:
00107 {
00108 b2ChainShape* s = (b2ChainShape*)m_shape;
00109 s->~b2ChainShape();
00110 allocator->Free(s, sizeof(b2ChainShape));
00111 }
00112 break;
00113
00114 default:
00115 b2Assert(false);
00116 break;
00117 }
00118
00119 m_shape = NULL;
00120 }
00121
00122 void b2Fixture::CreateProxies(b2BroadPhase* broadPhase, const b2Transform& xf)
00123 {
00124 b2Assert(m_proxyCount == 0);
00125
00126
00127 m_proxyCount = m_shape->GetChildCount();
00128
00129 for (int32 i = 0; i < m_proxyCount; ++i)
00130 {
00131 b2FixtureProxy* proxy = m_proxies + i;
00132 m_shape->ComputeAABB(&proxy->aabb, xf, i);
00133 proxy->proxyId = broadPhase->CreateProxy(proxy->aabb, proxy);
00134 proxy->fixture = this;
00135 proxy->childIndex = i;
00136 }
00137 }
00138
00139 void b2Fixture::DestroyProxies(b2BroadPhase* broadPhase)
00140 {
00141
00142 for (int32 i = 0; i < m_proxyCount; ++i)
00143 {
00144 b2FixtureProxy* proxy = m_proxies + i;
00145 broadPhase->DestroyProxy(proxy->proxyId);
00146 proxy->proxyId = b2BroadPhase::e_nullProxy;
00147 }
00148
00149 m_proxyCount = 0;
00150 }
00151
00152 void b2Fixture::Synchronize(b2BroadPhase* broadPhase, const b2Transform& transform1, const b2Transform& transform2)
00153 {
00154 if (m_proxyCount == 0)
00155 {
00156 return;
00157 }
00158
00159 for (int32 i = 0; i < m_proxyCount; ++i)
00160 {
00161 b2FixtureProxy* proxy = m_proxies + i;
00162
00163
00164 b2AABB aabb1, aabb2;
00165 m_shape->ComputeAABB(&aabb1, transform1, proxy->childIndex);
00166 m_shape->ComputeAABB(&aabb2, transform2, proxy->childIndex);
00167
00168 proxy->aabb.Combine(aabb1, aabb2);
00169
00170 b2Vec2 displacement = transform2.p - transform1.p;
00171
00172 broadPhase->MoveProxy(proxy->proxyId, proxy->aabb, displacement);
00173 }
00174 }
00175
00176 void b2Fixture::SetFilterData(const b2Filter& filter)
00177 {
00178 m_filter = filter;
00179
00180 Refilter();
00181 }
00182
00183 void b2Fixture::Refilter()
00184 {
00185 if (m_body == NULL)
00186 {
00187 return;
00188 }
00189
00190
00191 b2ContactEdge* edge = m_body->GetContactList();
00192 while (edge)
00193 {
00194 b2Contact* contact = edge->contact;
00195 b2Fixture* fixtureA = contact->GetFixtureA();
00196 b2Fixture* fixtureB = contact->GetFixtureB();
00197 if (fixtureA == this || fixtureB == this)
00198 {
00199 contact->FlagForFiltering();
00200 }
00201
00202 edge = edge->next;
00203 }
00204
00205 b2World* world = m_body->GetWorld();
00206
00207 if (world == NULL)
00208 {
00209 return;
00210 }
00211
00212
00213 b2BroadPhase* broadPhase = &world->m_contactManager.m_broadPhase;
00214 for (int32 i = 0; i < m_proxyCount; ++i)
00215 {
00216 broadPhase->TouchProxy(m_proxies[i].proxyId);
00217 }
00218 }
00219
00220 void b2Fixture::SetSensor(bool sensor)
00221 {
00222 if (sensor != m_isSensor)
00223 {
00224 m_body->SetAwake(true);
00225 m_isSensor = sensor;
00226 }
00227 }
00228
00229 void b2Fixture::Dump(int32 bodyIndex)
00230 {
00231 b2Log(" b2FixtureDef fd;\n");
00232 b2Log(" fd.friction = %.15lef;\n", m_friction);
00233 b2Log(" fd.restitution = %.15lef;\n", m_restitution);
00234 b2Log(" fd.density = %.15lef;\n", m_density);
00235 b2Log(" fd.isSensor = bool(%d);\n", m_isSensor);
00236 b2Log(" fd.filter.categoryBits = uint16(%d);\n", m_filter.categoryBits);
00237 b2Log(" fd.filter.maskBits = uint16(%d);\n", m_filter.maskBits);
00238 b2Log(" fd.filter.groupIndex = int16(%d);\n", m_filter.groupIndex);
00239
00240 switch (m_shape->m_type)
00241 {
00242 case b2Shape::e_circle:
00243 {
00244 b2CircleShape* s = (b2CircleShape*)m_shape;
00245 b2Log(" b2CircleShape shape;\n");
00246 b2Log(" shape.m_radius = %.15lef;\n", s->m_radius);
00247 b2Log(" shape.m_p.Set(%.15lef, %.15lef);\n", s->m_p.x, s->m_p.y);
00248 }
00249 break;
00250
00251 case b2Shape::e_edge:
00252 {
00253 b2EdgeShape* s = (b2EdgeShape*)m_shape;
00254 b2Log(" b2EdgeShape shape;\n");
00255 b2Log(" shape.m_radius = %.15lef;\n", s->m_radius);
00256 b2Log(" shape.m_vertex0.Set(%.15lef, %.15lef);\n", s->m_vertex0.x, s->m_vertex0.y);
00257 b2Log(" shape.m_vertex1.Set(%.15lef, %.15lef);\n", s->m_vertex1.x, s->m_vertex1.y);
00258 b2Log(" shape.m_vertex2.Set(%.15lef, %.15lef);\n", s->m_vertex2.x, s->m_vertex2.y);
00259 b2Log(" shape.m_vertex3.Set(%.15lef, %.15lef);\n", s->m_vertex3.x, s->m_vertex3.y);
00260 b2Log(" shape.m_hasVertex0 = bool(%d);\n", s->m_hasVertex0);
00261 b2Log(" shape.m_hasVertex3 = bool(%d);\n", s->m_hasVertex3);
00262 }
00263 break;
00264
00265 case b2Shape::e_polygon:
00266 {
00267 b2PolygonShape* s = (b2PolygonShape*)m_shape;
00268 b2Log(" b2PolygonShape shape;\n");
00269 b2Log(" b2Vec2 vs[%d];\n", b2_maxPolygonVertices);
00270 for (int32 i = 0; i < s->m_count; ++i)
00271 {
00272 b2Log(" vs[%d].Set(%.15lef, %.15lef);\n", i, s->m_vertices[i].x, s->m_vertices[i].y);
00273 }
00274 b2Log(" shape.Set(vs, %d);\n", s->m_count);
00275 }
00276 break;
00277
00278 case b2Shape::e_chain:
00279 {
00280 b2ChainShape* s = (b2ChainShape*)m_shape;
00281 b2Log(" b2ChainShape shape;\n");
00282 b2Log(" b2Vec2 vs[%d];\n", s->m_count);
00283 for (int32 i = 0; i < s->m_count; ++i)
00284 {
00285 b2Log(" vs[%d].Set(%.15lef, %.15lef);\n", i, s->m_vertices[i].x, s->m_vertices[i].y);
00286 }
00287 b2Log(" shape.CreateChain(vs, %d);\n", s->m_count);
00288 b2Log(" shape.m_prevVertex.Set(%.15lef, %.15lef);\n", s->m_prevVertex.x, s->m_prevVertex.y);
00289 b2Log(" shape.m_nextVertex.Set(%.15lef, %.15lef);\n", s->m_nextVertex.x, s->m_nextVertex.y);
00290 b2Log(" shape.m_hasPrevVertex = bool(%d);\n", s->m_hasPrevVertex);
00291 b2Log(" shape.m_hasNextVertex = bool(%d);\n", s->m_hasNextVertex);
00292 }
00293 break;
00294
00295 default:
00296 return;
00297 }
00298
00299 b2Log("\n");
00300 b2Log(" fd.shape = &shape;\n");
00301 b2Log("\n");
00302 b2Log(" bodies[%d]->CreateFixture(&fd);\n", bodyIndex);
00303 }