Starting to implement a physics system (basic for now). Here is what I have so far:



PHYSICS
Code:
procedure Physics_Open;
procedure Physics_Close;
function  Physics_Opened: Boolean;
procedure Physics_Reset;
procedure Physics_SetGravity(aX: Single; aY: Single);
procedure Phsycis_GetGravity(aX: PSingle; aY: PSingle);
procedure Physics_Destroy(aBody: TPhysicsBody);
function  Physics_CreateCircleBody(aX: Single; aY: Single; aRadius: Single; aDensity: Single): TPhysicsBody;
function  Physics_CreateRectangleBody(aX: Single; aY: Single; aWidth: Single; aHeight: Single; aDensity: Single): TPhysicsBody;
function  Physics_CreatePolygonBody(aX: Single; aY: Single; aRadius: Single; aSides: Integer; aDensity: Single): TPhysicsBody;
procedure Physics_GetPosition(aBody: TPhysicsBody; aX: PSingle; aY: PSingle);
function  Physics_Enabled(aBody: TPhysicsBody): Boolean;
procedure Physics_SetEnabled(aBody: TPhysicsBody; aValue: Boolean);
procedure Physics_UseGravity(aBody: TPhysicsBody; aValue: Boolean);
procedure Physics_AddForce(aBody: TPhysicsBody; aX: Single; aY: Single);
procedure Physics_AddTorque(aBody: TPhysicsBody; aAmount: Single);
procedure Physics_Rotate(aBody: TPhysicsBody; aAngle: Single);
function  Physics_Orientation(aBody: TPhysicsBody): Single;
function  Physics_BodyCount: Integer;
function  Physics_Body(aIndex: Integer): TPhysicsBody;
function  Physics_Shape(aBody: TPhysicsBody): Integer;
function  Physics_ShapeVertexCount(aIndex: Integer): Integer;
function  Physics_ShapeVertex(aBody: TPhysicsBody; aVertex: Integer): TPointf;
procedure Physics_RenderShapes(aColor: dRez.Engine.TColor);
function  Physics_Visible(aBody: TPhysicsBody): Boolean;
procedure Physics_SetVisible(aBody: TPhysicsBody; aValue: Boolean);
function  Physics_Radius(aBody: TPhysicsBody): Single;
procedure Physics_Size(aBody: TPhysicsBody; aWidth: PSingle; aHeight: PSingle);
EXAMPLE
Code:
program physac_test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  dRez.Engine in '..\..\..\libs\dRez.Engine.pas';

const
  screenWidth = 800;
  screenHeight = 450;

var
  logoX: Integer;
  logoY: Integer;
  needsReset: Boolean;
  floor, circle, body: TPhysicsBody;
  bodiesCount: Integer;
  i, fw: Integer;
  mx,my: Integer;
  bx,by: Single;
  hx,hy: Integer;
begin
  // open app window
  Window_Open('Physics Demo', screenWidth, screenHeight, False, False);

  Font_TextSize(Font, 30, 'dRezPhysics', @fw, nil);

  logoX := screenWidth - fw - 10;
  logoY := 15;
  needsReset := false;

  Physics_Open;

  floor := Physics_CreateRectangleBody(screenWidth/2, screenHeight, 500, 100, 10);
  Physics_SetEnabled(floor, False);
  Physics_SetVisible(floor, True);

  circle := Physics_CreateCircleBody(screenWidth/2, screenHeight/2, 45, 10);
  Physics_SetEnabled(circle, False);
  Physics_SetVisible(circle, True);

  // game loop - until app has terminated
  while not Terminated do
  begin
    // process events (kbd, mouse, window, etc)
    ProcessEvents;

    // check if app window is ready (has focus, not minimized)
    if not Window_Ready then
    begin
      // delay for 1 millisecond (allow background tasks to run)
      Delay(1);

      // continue to process events
      continue;
    end;

    if (needsReset) then
    begin
      floor := Physics_CreateRectangleBody(screenWidth/2, screenHeight, 500, 100, 10);
      Physics_SetEnabled(floor, False);
      Physics_SetVisible(floor, True);

      circle := Physics_CreateCircleBody(screenWidth/2, screenHeight/2, 45, 10);
      Physics_SetEnabled(circle, False);
      Physics_SetVisible(circle, True);

      needsReset := False;
    end;

    if Keyboard_Pressed(KEY_R) = true then
    begin
      Physics_Reset;
      needsReset := True;
    end;

    if (Mouse_Pressed(MOUSE_BUTTON_LEFT) or Keyboard_Pressed(KEY_1)) then
      begin
        Mouse_GetPosition(@mx, @my);
        body := Physics_CreatePolygonBody(mx, my, Random_Rangef(20, 80), Random_Rangei(3, 8), 10);
        Physics_SetVisible(body, True);

      end
    else if (Mouse_Pressed(MOUSE_BUTTON_RIGHT) or Keyboard_Pressed(KEY_2)) then
      begin
        Mouse_GetPosition(@mx, @my);
        body := Physics_CreateCircleBody(mx, my, Random_Rangef(10, 45), 10);
        Physics_SetVisible(body, True);
      end;


    bodiesCount := Physics_BodyCount;
    for i := bodiesCount - 1 downto 0 do
    begin
      body := Physics_Body(i);
      Physics_GetPosition(body, @bx, @by);
      if (body <> nil) and (by > screenHeight * 2) then
        begin
          Physics_Destroy(body);
        end;
    end;

    // clear background to a color
    Renderer_ClearFrame(BLACK);

    Physics_RenderShapes(GREEN);

    Font_DrawFPS(ConsoleFont, 3, 3, WHITE, 12);

    hx := 100;
    hy := 30;
    Font_DrawTextY(ConsoleFont, hx, hy, 15, WHITE, 12, 'Left mouse button to create a polygon');
    Font_DrawTextY(ConsoleFont, hx, hy, 15, WHITE, 12, 'Right mouse button to create a circle');
    Font_DrawTextY(ConsoleFont, hx, hy, 15, WHITE, 12, 'Press "R" to reset example');

    Font_DrawText(Font, logoX, logoY, WHITE, 30, 'dRezPhysics');
    Font_DrawText(ConsoleFont, logoX+45, logoY-13, WHITE, 12, 'Powered by');

    // show frame buffer
    Renderer_ShowFrame;

  end;

  Physics_Close;

  // close app window
  Window_Close;
end.