unit dmatrix4f;

interface

uses
  dvector3f;

type
  TMat4f = array[0..15] of Single;

function Identity4f: TMat4f;
function Translate4f(const V: TVec3f): TMat4f;
function Transpose4f(const M: TMat4f): TMat4f;

function Apply4f(const V: TVec3f; const M: TMat4f): TVec3f;

implementation

procedure Exchangef(var A, B, Temp: Single); inline;
begin
  Temp := A;
  A := B;
  B := Temp;
end;

function Identity4f: TMat4f;
var
  I: LongInt;
begin
  for I := 0 to 15 do begin
    Result[I] := Ord((I mod 5) = 0);
  end;
end;

function Translate4f(const V: TVec3f): TMat4f;
var
  I: LongInt;
begin
  for I := 0 to 15 do begin
    Result[I] := Ord((I mod 5) = 0);
  end;
  Result[12] := V.X;
  Result[13] := V.Y;
  Result[14] := V.Z;
end;

function Transpose4f(const M: TMat4f): TMat4f;
var
  I, J: LongInt;
  Temp: Single;
begin
  J := 0;
  for I := 0 to 15 do begin
    Result[J] := M[I];
    Inc(J, 4);
    if J > 15 then
      Dec(J, 15);
  end;
end;

function Apply4f(const V: TVec3f; const M: TMat4f): TVec3f;
begin
  // Result.X := V.X * M[ 0] + V.Y * M[ 1] + V.Z * M[ 2] + M[ 3];
  // Result.Y := V.X * M[ 4] + V.Y * M[ 5] + V.Z * M[ 6] + M[ 7];
  // Result.Z := V.X * M[ 8] + V.Y * M[ 9] + V.Z * M[10] + M[11];
  Result.X := V.X * M[ 0] + V.Y * M[ 4] + V.Z * M[ 8] + M[12];
  Result.Y := V.X * M[ 1] + V.Y * M[ 5] + V.Z * M[ 9] + M[13];
  Result.Z := V.X * M[ 2] + V.Y * M[ 6] + V.Z * M[10] + M[14];
end;

end.
