UCollisionProcessing.pas
上传用户:zkjn0718
上传日期:2021-01-01
资源大小:776k
文件大小:6k
源码类别:

Delphi/CppBuilder

开发平台:

Delphi

  1. unit UCollisionProcessing;
  2. interface
  3. {$I ......SourcePhysics2D.inc}
  4. uses
  5.    UMain, UPhysics2DTypes, UPhysics2D, SysUtils, Math;
  6. type
  7.    TCollisionProcessing = class(TTester)
  8.    public
  9.       constructor Create; override;
  10.       procedure Step(var settings: TSettings; timeStep: Float); override;
  11.    end;
  12. implementation
  13. { TCollisionProcessing }
  14. constructor TCollisionProcessing.Create;
  15. const
  16.    xLo = -5;
  17.    xHi = 5;
  18.    yLo = 2;
  19.    yHi = 35;
  20. var
  21.    sd: Tb2PolygonDef;
  22.    bd: Tb2BodyDef;
  23.    ground: Tb2Body;
  24.    triangleShapeDef, boxShapeDef: Tb2PolygonDef;
  25.    circleShapeDef: Tb2CircleDef;
  26.    triangleBodyDef, boxBodyDef, circleBodyDef: Tb2BodyDef;
  27.    body1, body2, body3, body4, body5, body6: Tb2Body;
  28. begin
  29.    inherited;
  30.    // Ground body
  31.    begin
  32.       sd := Tb2PolygonDef.Create;
  33.       sd.SetAsBox(50.0, 10.0);
  34.       sd.friction := 0.3;
  35.       bd := Tb2BodyDef.Create;
  36.       {$IFDEF OP_OVERLOAD}
  37.       bd.position.SetValue(0.0, -10.0);
  38.       {$ELSE}
  39.       SetValue(bd.position, 0.0, -10.0);
  40.       {$ENDIF}
  41.       ground := m_world.CreateBody(bd);
  42.       ground.CreateShape(sd);
  43.    end;
  44.    // Small triangle
  45.    triangleShapeDef := Tb2PolygonDef.Create;
  46.    triangleShapeDef.vertexCount := 3;
  47.    {$IFDEF OP_OVERLOAD}
  48.    triangleShapeDef.vertices[0].SetValue(-1.0, 0.0);
  49.    triangleShapeDef.vertices[1].SetValue(1.0, 0.0);
  50.    triangleShapeDef.vertices[2].SetValue(0.0, 2.0);
  51.    {$ELSE}
  52.    SetValue(triangleShapeDef.vertices[0], -1.0, 0.0);
  53.    SetValue(triangleShapeDef.vertices[1], 1.0, 0.0);
  54.    SetValue(triangleShapeDef.vertices[2], 0.0, 2.0);
  55.    {$ENDIF}
  56.    triangleShapeDef.density := 1.0;
  57.    triangleBodyDef := Tb2BodyDef.Create;
  58.    {$IFDEF OP_OVERLOAD}
  59.    triangleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  60.    {$ELSE}
  61.    SetValue(triangleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  62.    {$ENDIF}
  63.    body1 := m_world.CreateBody(triangleBodyDef, False);
  64.    body1.CreateShape(triangleShapeDef, False);
  65.    body1.SetMassFromShapes;
  66.    // Large triangle (recycle definitions)
  67.    {$IFDEF OP_OVERLOAD}
  68.    triangleShapeDef.vertices[0] := triangleShapeDef.vertices[0] * 2.0;
  69.    triangleShapeDef.vertices[1] := triangleShapeDef.vertices[1] * 2.0;
  70.    triangleShapeDef.vertices[2] := triangleShapeDef.vertices[2] * 2.0;
  71.    triangleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  72.    {$ELSE}
  73.    triangleShapeDef.vertices[0] := Multiply(triangleShapeDef.vertices[0], 2.0);
  74.    triangleShapeDef.vertices[1] := Multiply(triangleShapeDef.vertices[1], 2.0);
  75.    triangleShapeDef.vertices[2] := Multiply(triangleShapeDef.vertices[2], 2.0);
  76.    SetValue(triangleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  77.    {$ENDIF}
  78.    body2 := m_world.CreateBody(triangleBodyDef);
  79.    body2.CreateShape(triangleShapeDef);
  80.    body2.SetMassFromShapes;
  81.    // Small box
  82.    boxShapeDef := Tb2PolygonDef.Create;
  83.    boxShapeDef.SetAsBox(1.0, 0.5);
  84.    boxShapeDef.density := 1.0;
  85.    boxBodyDef := Tb2BodyDef.Create;
  86.    {$IFDEF OP_OVERLOAD}
  87.    boxBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  88.    {$ELSE}
  89.    SetValue(boxBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  90.    {$ENDIF}
  91.    body3 := m_world.CreateBody(boxBodyDef, False);
  92.    body3.CreateShape(boxShapeDef, False);
  93.    body3.SetMassFromShapes;
  94.    // Large box (recycle definitions)
  95.    boxShapeDef.SetAsBox(2.0, 1.0);
  96.    {$IFDEF OP_OVERLOAD}
  97.    boxBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  98.    {$ELSE}
  99.    SetValue(boxBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  100.    {$ENDIF}
  101.    body4 := m_world.CreateBody(boxBodyDef);
  102.    body4.CreateShape(boxShapeDef);
  103.    body4.SetMassFromShapes;
  104.    // Small circle
  105.    circleShapeDef := Tb2CircleDef.Create;
  106.    circleShapeDef.radius := 1.0;
  107.    circleShapeDef.density := 1.0;
  108.    circleBodyDef := Tb2BodyDef.Create;
  109.    {$IFDEF OP_OVERLOAD}
  110.    circleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  111.    {$ELSE}
  112.    SetValue(circleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  113.    {$ENDIF}
  114.    body5 := m_world.CreateBody(circleBodyDef, False);
  115.    body5.CreateShape(circleShapeDef, False);
  116.    body5.SetMassFromShapes;
  117.    // Large circle
  118.    circleShapeDef.radius := circleShapeDef.radius * 2.0;
  119.    {$IFDEF OP_OVERLOAD}
  120.    circleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  121.    {$ELSE}
  122.    SetValue(circleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
  123.    {$ENDIF}
  124.    body6 := m_world.CreateBody(circleBodyDef);
  125.    body6.CreateShape(circleShapeDef);
  126.    body6.SetMassFromShapes;
  127. end;
  128. procedure TCollisionProcessing.Step(var settings: TSettings; timeStep: Float);
  129. const
  130.    k_maxNuke = 6;
  131. var
  132.    i, j: Integer;
  133.    // We are going to destroy some bodies according to contact
  134.    // points. We must buffer the bodies that should be destroyed
  135.    nuke: array[0..k_maxNuke - 1] of Tb2Body;
  136.    nukeCount: Int32;
  137.    b: Tb2Body;
  138. begin
  139.    inherited;
  140.    nukeCount := 0;
  141.    // Traverse the contact results. Destroy bodies that are touching heavier bodies.
  142.    for i := 0 to m_pointCount - 1 do
  143.       with m_points[i] do
  144.          if (shape1.GetBody.GetMass > 0.0) and (shape2.GetBody.GetMass > 0.0) then
  145.          begin
  146.             if shape2.GetBody.GetMass > shape1.GetBody.GetMass then
  147.                nuke[nukeCount] := shape1.GetBody
  148.             else
  149.                nuke[nukeCount] := shape2.GetBody;
  150.             Inc(nukeCount);
  151.             if nukeCount = k_maxNuke then
  152.                Break;
  153.          end;
  154.    // Sort the nuke array to group duplicates.
  155.    for i := 0 to nukeCount - 2 do
  156.       for j := nukeCount - 1 downto i + 1 do
  157.          if Integer(nuke[i]) > Integer(nuke[j]) then
  158.          begin
  159.             b := nuke[i];
  160.             nuke[i] := nuke[j];
  161.             nuke[j] := b;
  162.          end;
  163.    // Destroy the bodies, skipping duplicates.
  164.    i := 0;
  165.    while (i < nukeCount) do
  166.    begin
  167.       b := nuke[i];
  168.       Inc(i);
  169.       while (i < nukeCount) and (nuke[i] = b) do
  170.          Inc(i);
  171.       m_world.DestroyBody(b);
  172.    end;
  173. end;
  174. initialization
  175.    RegisterTestEntry('Collision Processing', TCollisionProcessing);
  176. end.