@@ -107,6 +107,7 @@ class ChainShape : public Sample
107107 b2ChainDef chainDef = b2DefaultChainDef ();
108108 chainDef.points = points;
109109 chainDef.count = count;
110+ chainDef.customColor = b2_colorSteelBlue;
110111 chainDef.isLoop = true ;
111112 chainDef.friction = 0 .2f ;
112113
@@ -1302,3 +1303,118 @@ class OffsetShapes : public Sample
13021303};
13031304
13041305static int sampleOffsetShapes = RegisterSample( " Shapes" , " Offset" , OffsetShapes::Create );
1306+
1307+ // This shows how to use explosions and demonstrates the projected perimeter
1308+ class Explosion : public Sample
1309+ {
1310+ public:
1311+
1312+ explicit Explosion ( Settings& settings )
1313+ : Sample( settings )
1314+ {
1315+ if ( settings.restart == false )
1316+ {
1317+ g_camera.m_center = { 0 .0f , 0 .0f };
1318+ g_camera.m_zoom = 14 .0f ;
1319+ }
1320+
1321+ b2BodyDef bodyDef = b2DefaultBodyDef ();
1322+ b2BodyId groundId = b2CreateBody ( m_worldId, &bodyDef );
1323+
1324+ bodyDef.type = b2_dynamicBody;
1325+ bodyDef.gravityScale = 0 .0f ;
1326+ b2ShapeDef shapeDef = b2DefaultShapeDef ();
1327+
1328+ m_referenceAngle = 0 .0f ;
1329+
1330+ b2WeldJointDef weldDef = b2DefaultWeldJointDef ();
1331+ weldDef.referenceAngle = m_referenceAngle;
1332+ weldDef.angularHertz = 0 .5f ;
1333+ weldDef.angularDampingRatio = 0 .7f ;
1334+ weldDef.linearHertz = 0 .5f ;
1335+ weldDef.linearDampingRatio = 0 .7f ;
1336+ weldDef.bodyIdA = groundId;
1337+ weldDef.localAnchorB = b2Vec2_zero;
1338+
1339+ float r = 8 .0f ;
1340+ for (float angle = 0 .0f ; angle < 360 .0f ; angle += 30 .0f )
1341+ {
1342+ b2CosSin cosSin = b2ComputeCosSin ( angle * b2_pi / 180 .0f );
1343+ bodyDef.position = { r * cosSin.cosine , r * cosSin.sine };
1344+ b2BodyId bodyId = b2CreateBody ( m_worldId, &bodyDef );
1345+
1346+ b2Polygon box = b2MakeBox ( 1 .0f , 0 .1f );
1347+ b2CreatePolygonShape ( bodyId, &shapeDef, &box );
1348+
1349+ weldDef.localAnchorA = bodyDef.position ;
1350+ weldDef.bodyIdB = bodyId;
1351+ b2JointId jointId = b2CreateWeldJoint ( m_worldId, &weldDef );
1352+ m_jointIds.push_back ( jointId );
1353+ }
1354+
1355+ m_radius = 7 .0f ;
1356+ m_falloff = 3 .0f ;
1357+ m_impulse = 10 .0f ;
1358+ }
1359+
1360+ void UpdateUI () override
1361+ {
1362+ float height = 160 .0f ;
1363+ ImGui::SetNextWindowPos ( ImVec2 ( 10 .0f , g_camera.m_height - height - 50 .0f ), ImGuiCond_Once );
1364+ ImGui::SetNextWindowSize ( ImVec2 ( 240 .0f , height ) );
1365+
1366+ ImGui::Begin ( " Explosion" , nullptr , ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize );
1367+
1368+ if ( ImGui::Button ( " Explode" ) )
1369+ {
1370+ b2ExplosionDef def = b2DefaultExplosionDef ();
1371+ def.position = b2Vec2_zero;
1372+ def.radius = m_radius;
1373+ def.falloff = m_falloff;
1374+ def.impulsePerLength = m_impulse;
1375+ b2World_Explode ( m_worldId, &def );
1376+ }
1377+
1378+ ImGui::SliderFloat ( " radius" , &m_radius, 0 .0f , 20 .0f , " %.1f" );
1379+ ImGui::SliderFloat ( " falloff" , &m_falloff, 0 .0f , 20 .0f , " %.1f" );
1380+ ImGui::SliderFloat ( " impulse" , &m_impulse, -20 .0f , 20 .0f , " %.1f" );
1381+
1382+ ImGui::End ();
1383+ }
1384+
1385+ void Step ( Settings& settings ) override
1386+ {
1387+ if (settings.pause == false || settings.singleStep == true )
1388+ {
1389+ m_referenceAngle += settings.hertz > 0 .0f ? 60 .0f * b2_pi / 180 .0f / settings.hertz : 0 .0f ;
1390+ m_referenceAngle = b2UnwindAngle ( m_referenceAngle );
1391+
1392+ int count = m_jointIds.size ();
1393+ for (int i = 0 ; i < count; ++i)
1394+ {
1395+ b2WeldJoint_SetReferenceAngle ( m_jointIds[i], m_referenceAngle );
1396+ }
1397+ }
1398+
1399+ Sample::Step ( settings );
1400+
1401+ g_draw.DrawString ( 5 , m_textLine, " reference angle = %g" , m_referenceAngle );
1402+ m_textLine += m_textIncrement;
1403+
1404+ g_draw.DrawCircle ( b2Vec2_zero, m_radius + m_falloff, b2_colorBox2DBlue );
1405+ g_draw.DrawCircle ( b2Vec2_zero, m_radius, b2_colorBox2DYellow );
1406+ }
1407+
1408+ static Sample* Create ( Settings& settings )
1409+ {
1410+ return new Explosion ( settings );
1411+ }
1412+
1413+ std::vector<b2JointId> m_jointIds;
1414+ float m_radius;
1415+ float m_falloff;
1416+ float m_impulse;
1417+ float m_referenceAngle;
1418+ };
1419+
1420+ static int sampleBodyMove = RegisterSample( " Shapes" , " Explosion" , Explosion::Create );
0 commit comments