UCollisionProcessing.pas
上传用户:zkjn0718
上传日期:2021-01-01
资源大小:776k
文件大小:6k
源码类别:
Delphi/CppBuilder
开发平台:
Delphi
- unit UCollisionProcessing;
- interface
- {$I ......SourcePhysics2D.inc}
- uses
- UMain, UPhysics2DTypes, UPhysics2D, SysUtils, Math;
- type
- TCollisionProcessing = class(TTester)
- public
- constructor Create; override;
- procedure Step(var settings: TSettings; timeStep: Float); override;
- end;
- implementation
- { TCollisionProcessing }
- constructor TCollisionProcessing.Create;
- const
- xLo = -5;
- xHi = 5;
- yLo = 2;
- yHi = 35;
- var
- sd: Tb2PolygonDef;
- bd: Tb2BodyDef;
- ground: Tb2Body;
- triangleShapeDef, boxShapeDef: Tb2PolygonDef;
- circleShapeDef: Tb2CircleDef;
- triangleBodyDef, boxBodyDef, circleBodyDef: Tb2BodyDef;
- body1, body2, body3, body4, body5, body6: Tb2Body;
- begin
- inherited;
- // Ground body
- begin
- sd := Tb2PolygonDef.Create;
- sd.SetAsBox(50.0, 10.0);
- sd.friction := 0.3;
- bd := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- bd.position.SetValue(0.0, -10.0);
- {$ELSE}
- SetValue(bd.position, 0.0, -10.0);
- {$ENDIF}
- ground := m_world.CreateBody(bd);
- ground.CreateShape(sd);
- end;
- // Small triangle
- triangleShapeDef := Tb2PolygonDef.Create;
- triangleShapeDef.vertexCount := 3;
- {$IFDEF OP_OVERLOAD}
- triangleShapeDef.vertices[0].SetValue(-1.0, 0.0);
- triangleShapeDef.vertices[1].SetValue(1.0, 0.0);
- triangleShapeDef.vertices[2].SetValue(0.0, 2.0);
- {$ELSE}
- SetValue(triangleShapeDef.vertices[0], -1.0, 0.0);
- SetValue(triangleShapeDef.vertices[1], 1.0, 0.0);
- SetValue(triangleShapeDef.vertices[2], 0.0, 2.0);
- {$ENDIF}
- triangleShapeDef.density := 1.0;
- triangleBodyDef := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- triangleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ELSE}
- SetValue(triangleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ENDIF}
- body1 := m_world.CreateBody(triangleBodyDef, False);
- body1.CreateShape(triangleShapeDef, False);
- body1.SetMassFromShapes;
- // Large triangle (recycle definitions)
- {$IFDEF OP_OVERLOAD}
- triangleShapeDef.vertices[0] := triangleShapeDef.vertices[0] * 2.0;
- triangleShapeDef.vertices[1] := triangleShapeDef.vertices[1] * 2.0;
- triangleShapeDef.vertices[2] := triangleShapeDef.vertices[2] * 2.0;
- triangleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ELSE}
- triangleShapeDef.vertices[0] := Multiply(triangleShapeDef.vertices[0], 2.0);
- triangleShapeDef.vertices[1] := Multiply(triangleShapeDef.vertices[1], 2.0);
- triangleShapeDef.vertices[2] := Multiply(triangleShapeDef.vertices[2], 2.0);
- SetValue(triangleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ENDIF}
- body2 := m_world.CreateBody(triangleBodyDef);
- body2.CreateShape(triangleShapeDef);
- body2.SetMassFromShapes;
- // Small box
- boxShapeDef := Tb2PolygonDef.Create;
- boxShapeDef.SetAsBox(1.0, 0.5);
- boxShapeDef.density := 1.0;
- boxBodyDef := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- boxBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ELSE}
- SetValue(boxBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ENDIF}
- body3 := m_world.CreateBody(boxBodyDef, False);
- body3.CreateShape(boxShapeDef, False);
- body3.SetMassFromShapes;
- // Large box (recycle definitions)
- boxShapeDef.SetAsBox(2.0, 1.0);
- {$IFDEF OP_OVERLOAD}
- boxBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ELSE}
- SetValue(boxBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ENDIF}
- body4 := m_world.CreateBody(boxBodyDef);
- body4.CreateShape(boxShapeDef);
- body4.SetMassFromShapes;
- // Small circle
- circleShapeDef := Tb2CircleDef.Create;
- circleShapeDef.radius := 1.0;
- circleShapeDef.density := 1.0;
- circleBodyDef := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- circleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ELSE}
- SetValue(circleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ENDIF}
- body5 := m_world.CreateBody(circleBodyDef, False);
- body5.CreateShape(circleShapeDef, False);
- body5.SetMassFromShapes;
- // Large circle
- circleShapeDef.radius := circleShapeDef.radius * 2.0;
- {$IFDEF OP_OVERLOAD}
- circleBodyDef.position.SetValue(RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ELSE}
- SetValue(circleBodyDef.position, RandomRange(xLo, xHi), RandomRange(yLo, yHi));
- {$ENDIF}
- body6 := m_world.CreateBody(circleBodyDef);
- body6.CreateShape(circleShapeDef);
- body6.SetMassFromShapes;
- end;
- procedure TCollisionProcessing.Step(var settings: TSettings; timeStep: Float);
- const
- k_maxNuke = 6;
- var
- i, j: Integer;
- // We are going to destroy some bodies according to contact
- // points. We must buffer the bodies that should be destroyed
- nuke: array[0..k_maxNuke - 1] of Tb2Body;
- nukeCount: Int32;
- b: Tb2Body;
- begin
- inherited;
- nukeCount := 0;
- // Traverse the contact results. Destroy bodies that are touching heavier bodies.
- for i := 0 to m_pointCount - 1 do
- with m_points[i] do
- if (shape1.GetBody.GetMass > 0.0) and (shape2.GetBody.GetMass > 0.0) then
- begin
- if shape2.GetBody.GetMass > shape1.GetBody.GetMass then
- nuke[nukeCount] := shape1.GetBody
- else
- nuke[nukeCount] := shape2.GetBody;
- Inc(nukeCount);
- if nukeCount = k_maxNuke then
- Break;
- end;
- // Sort the nuke array to group duplicates.
- for i := 0 to nukeCount - 2 do
- for j := nukeCount - 1 downto i + 1 do
- if Integer(nuke[i]) > Integer(nuke[j]) then
- begin
- b := nuke[i];
- nuke[i] := nuke[j];
- nuke[j] := b;
- end;
- // Destroy the bodies, skipping duplicates.
- i := 0;
- while (i < nukeCount) do
- begin
- b := nuke[i];
- Inc(i);
- while (i < nukeCount) and (nuke[i] = b) do
- Inc(i);
- m_world.DestroyBody(b);
- end;
- end;
- initialization
- RegisterTestEntry('Collision Processing', TCollisionProcessing);
- end.