Sfoglia il codice sorgente

* reimplemented matrix unit using type helpers

master
Bergmann89 10 anni fa
parent
commit
15fd6367b9
5 ha cambiato i file con 990 aggiunte e 9 eliminazioni
  1. +281
    -0
      ugluMatrixEx.inc
  2. +129
    -0
      ugluMatrixEx.pas
  3. +540
    -0
      ugluMatrixExHelper.pas
  4. +32
    -0
      ugluVectorEx.pas
  5. +8
    -9
      ugluVectorExHelper.pas

+ 281
- 0
ugluMatrixEx.inc Vedi File

@@ -0,0 +1,281 @@
{$IF DEFINED(__MATRIX_HELPER_INTERFACE)}
type __HELPER = type helper for __MAT
public const
{$IF __SIZE = 2}
Identity: __MAT = ((1, 0), (0, 1));
{$ELSEIF __SIZE = 3}
Identity: __MAT = ((1, 0, 0), (0, 1, 0), (0, 0, 1));
{$ELSEIF __SIZE = 4}
Identity: __MAT = ((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1));
{$ELSE}
{$ERROR only vectors of size 2, 3 or 4 are supported}
{$ENDIF}
public
function ToString(const aRound: Integer = -3): String; inline;
function Transpose: __MAT; inline;
function Determinant: Double; inline;
function Invert: __MAT; inline;

class function TryFromString(const s: String; out m: __MAT): Boolean; inline; static;
class function FromString(const s: String): __MAT; inline; static;

{$IF __SIZE = 3}
function Sub(const aCol, aRow: Integer): __IMPL.TMat2; inline;
function Adjoint: __MAT; inline;
function Translate(const v: __IMPL.TVectorHelper.TVector2): __MAT; inline;
function Translate(const x, y: __IMPL.TBaseType): __MAT; inline;
function Scale(const v: __IMPL.TVectorHelper.TVector2): __MAT; inline;
function Scale(const v: __IMPL.TBaseType): __MAT; inline;
function Shear(const v: __IMPL.TVectorHelper.TVector2): __MAT; inline;
function Shear(const x, y: __IMPL.TBaseType): __MAT; inline;
function Rotate(const a: Double): __MAT; inline;

class function CreateTranslate(const v: __IMPL.TVectorHelper.TVector2): __MAT; inline; static;
class function CreateTranslate(const x, y: __IMPL.TBaseType): __MAT; inline; static;
class function CreateScale(const v: __IMPL.TVectorHelper.TVector2): __MAT; inline; static;
class function CreateScale(const v: __IMPL.TBaseType): __MAT; inline; static;
class function CreateShear(const v: __IMPL.TVectorHelper.TVector2): __MAT; inline; static;
class function CreateShear(const x, y: __IMPL.TBaseType): __MAT; inline; static;
class function CreateRotate(const a: Double): __MAT; inline; static;
{$ELSEIF __SIZE = 4}
function Sub(const aCol, aRow: Integer): __IMPL.TMat3; inline;
function Adjoint: __MAT; inline;
function Translate(const v: __IMPL.TVectorHelper.TVector3): __MAT; inline;
function Translate(const x, y, z: __IMPL.TBaseType): __MAT; inline;
function Scale(const v: __IMPL.TVectorHelper.TVector3): __MAT; inline;
function Scale(const v: __IMPL.TBaseType): __MAT; inline;
function Rotate(const axis: __IMPL.TVectorHelper.TVector3; const a: Double): __MAT; inline;

class function CreateTranslate(const v: __IMPL.TVectorHelper.TVector3): __MAT; inline; static;
class function CreateTranslate(const x, y, z: __IMPL.TBaseType): __MAT; inline; static;
class function CreateScale(const v: __IMPL.TVectorHelper.TVector3): __MAT; inline; static;
class function CreateScale(const v: __IMPL.TBaseType): __MAT; inline; static;
class function CreateShear(const x, y, z: __IMPL.TVectorHelper.TVector2): __MAT; inline; static;
class function CreateShear(const xy, xz, yx, yz, zx, zy: __IMPL.TBaseType): __MAT; inline; static;
class function CreateRotate(const axis: __IMPL.TVectorHelper.TVector3; const a: Double): __MAT; inline; static;
{$ENDIF}
end;

operator = (const m1, m2: __MAT): Boolean; inline;
operator * (const m1, m2: __MAT): __MAT; inline;
operator * (const m: __MAT; const v: __VEC): __VEC; inline;
operator * (const s: __IMPL.TBaseType; const m: __MAT): __MAT; inline;
operator * (const m: __MAT; const s: __IMPL.TBaseType): __MAT; inline;
{$ELSEIF DEFINED (__MATRIX_HELPER_IMPL)}
operator = (const m1, m2: __MAT): Boolean;
begin
result := __IMPL.Equals(m1, m2);
end;

operator * (const m1, m2: __MAT): __MAT;
begin
result := __IMPL.Multiply(m1, m2);
end;

operator * (const m: __MAT; const v: __VEC): __VEC;
begin
result := __IMPL.Multiply(m, v);
end;

operator * (const s: __IMPL.TBaseType; const m: __MAT): __MAT;
begin
result := __IMPL.Multiply(m, s);
end;

operator * (const m: __MAT; const s: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.Multiply(m, s);
end;

function __HELPER.ToString(const aRound: Integer = -3): String;
begin
result := __IMPL.ToString(self, aRound);
end;

function __HELPER.Transpose: __MAT;
begin
result := __IMPL.Transpose(self);
end;

function __HELPER.Determinant: Double;
begin
result := __IMPL.Determinant(self);
end;

function __HELPER.Invert: __MAT;
begin
result := __IMPL.Invert(self);
end;

class function __HELPER.TryFromString(const s: String; out m: __MAT): Boolean;
begin
result := __IMPL.TryFromString(s, m);
end;

class function __HELPER.FromString(const s: String): __MAT;
begin
if not __IMPL.TryFromString(s, result) then
result := Identity;
end;

{$IF __SIZE = 3}
function __HELPER.Sub(const aCol, aRow: Integer): __IMPL.TMat2;
begin
result := __IMPL.Sub(self, aCol, aRow);
end;

function __HELPER.Adjoint: __MAT;
begin
result := __IMPL.Adjoint(self);
end;

function __HELPER.Translate(const v: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateTranslate(v));
end;

function __HELPER.Translate(const x, y: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateTranslate(__IMPL.TVectorHelper.Vector2(x, y)));
end;

function __HELPER.Scale(const v: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateScale(v));
end;

function __HELPER.Scale(const v: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateScale(__IMPL.TVectorHelper.Vector2(v, v)));
end;

function __HELPER.Shear(const v: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateShear(v));
end;

function __HELPER.Shear(const x, y: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateShear(__IMPL.TVectorHelper.Vector2(x, y)));
end;

function __HELPER.Rotate(const a: Double): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateRotate(a));
end;

class function __HELPER.CreateTranslate(const v: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.CreateTranslate(v);
end;

class function __HELPER.CreateTranslate(const x, y: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.CreateTranslate(__IMPL.TVectorHelper.Vector2(x, y));
end;

class function __HELPER.CreateScale(const v: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.CreateScale(v);
end;

class function __HELPER.CreateScale(const v: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.CreateScale(__IMPL.TVectorHelper.Vector2(v, v));
end;

class function __HELPER.CreateShear(const v: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.CreateShear(v);
end;

class function __HELPER.CreateShear(const x, y: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.CreateShear(__IMPL.TVectorHelper.Vector2(x, y));
end;

class function __HELPER.CreateRotate(const a: Double): __MAT;
begin
result := __IMPL.CreateRotate(a);
end;
{$ELSEIF __SIZE = 4}
function __HELPER.Sub(const aCol, aRow: Integer): __IMPL.TMat3;
begin
result := __IMPL.Sub(self, aRow, aCol);
end;

function __HELPER.Adjoint: __MAT;
begin
result := __IMPL.Adjoint(self);
end;

function __HELPER.Translate(const v: __IMPL.TVectorHelper.TVector3): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateTranslate(v));
end;

function __HELPER.Translate(const x, y, z: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateTranslate(__IMPL.TVectorHelper.Vector3(x, y, z)));
end;

function __HELPER.Scale(const v: __IMPL.TVectorHelper.TVector3): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateScale(v));
end;

function __HELPER.Scale(const v: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateScale(__IMPL.TVectorHelper.Vector3(v, v, v)));
end;

function __HELPER.Rotate(const axis: __IMPL.TVectorHelper.TVector3; const a: Double): __MAT;
begin
result := __IMPL.Multiply(self, __IMPL.CreateRotate(axis, a));
end;

class function __HELPER.CreateTranslate(const v: __IMPL.TVectorHelper.TVector3): __MAT;
begin
result := __IMPL.CreateTranslate(v);
end;

class function __HELPER.CreateTranslate(const x, y, z: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.CreateTranslate(__IMPL.TVectorHelper.Vector3(x, y, z));
end;

class function __HELPER.CreateScale(const v: __IMPL.TVectorHelper.TVector3): __MAT;
begin
result := __IMPL.CreateScale(v);
end;

class function __HELPER.CreateScale(const v: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.CreateScale(__IMPL.TVectorHelper.Vector3(v, v, v));
end;

class function __HELPER.CreateShear(const x, y, z: __IMPL.TVectorHelper.TVector2): __MAT;
begin
result := __IMPL.CreateShear(x, y, z);
end;

class function __HELPER.CreateShear(const xy, xz, yx, yz, zx, zy: __IMPL.TBaseType): __MAT;
begin
result := __IMPL.CreateShear(
__IMPL.TVectorHelper.Vector2(xy, xz),
__IMPL.TVectorHelper.Vector2(yx, yz),
__IMPL.TVectorHelper.Vector2(zx, zy));
end;

class function __HELPER.CreateRotate(const axis: __IMPL.TVectorHelper.TVector3; const a: Double): __MAT;
begin
result := __IMPL.CreateRotate(axis, a);
end;
{$ENDIF}
{$ENDIF}

{$UNDEF __IMPL}
{$UNDEF __SIZE}
{$UNDEF __VEC}
{$UNDEF __MAT}
{$UNDEF __HELPER}

+ 129
- 0
ugluMatrixEx.pas Vedi File

@@ -0,0 +1,129 @@
unit ugluMatrixEx;

{$mode objfpc}{$H+}
{$macro on}
{$modeswitch typehelpers}

interface

uses
Classes, SysUtils,
ugluVectorEx, ugluMatrixExHelper;

type
TgluMatrix2f = TgluMatrixF.TMat2;
TgluMatrix3f = TgluMatrixF.TMat3;
TgluMatrix4f = TgluMatrixF.TMat4;

TgluMatrix2d = TgluMatrixD.TMat2;
TgluMatrix3d = TgluMatrixD.TMat3;
TgluMatrix4d = TgluMatrixD.TMat4;



PgluMatrix2f = ^TgluMatrix2f;
PgluMatrix3f = ^TgluMatrix3f;
PgluMatrix4f = ^TgluMatrix4f;

PgluMatrix2d = ^TgluMatrix2d;
PgluMatrix3d = ^TgluMatrix3d;
PgluMatrix4d = ^TgluMatrix4d;



{$DEFINE __MATRIX_HELPER_INTERFACE}
{$DEFINE __IMPL := TgluMatrixF}
{$DEFINE __SIZE := 2}
{$DEFINE __VEC := TgluVector2f}
{$DEFINE __MAT := TgluMatrix2f}
{$DEFINE __HELPER := TgluTypeHelperMatrix2f}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixF}
{$DEFINE __SIZE := 3}
{$DEFINE __VEC := TgluVector3f}
{$DEFINE __MAT := TgluMatrix3f}
{$DEFINE __HELPER := TgluTypeHelperMatrix3f}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixF}
{$DEFINE __SIZE := 4}
{$DEFINE __VEC := TgluVector4f}
{$DEFINE __MAT := TgluMatrix4f}
{$DEFINE __HELPER := TgluTypeHelperMatrix4f}
{$I ugluMatrixEx.inc}



{$DEFINE __IMPL := TgluMatrixD}
{$DEFINE __SIZE := 2}
{$DEFINE __VEC := TgluVector2d}
{$DEFINE __MAT := TgluMatrix2d}
{$DEFINE __HELPER := TgluTypeHelperMatrix2d}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixD}
{$DEFINE __SIZE := 3}
{$DEFINE __VEC := TgluVector3d}
{$DEFINE __MAT := TgluMatrix3d}
{$DEFINE __HELPER := TgluTypeHelperMatrix3d}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixD}
{$DEFINE __SIZE := 4}
{$DEFINE __VEC := TgluVector4d}
{$DEFINE __MAT := TgluMatrix4d}
{$DEFINE __HELPER := TgluTypeHelperMatrix4d}
{$I ugluMatrixEx.inc}
{$UNDEF __MATRIX_HELPER_INTERFACE}

implementation

{$DEFINE __MATRIX_HELPER_IMPL}
{$DEFINE __IMPL := TgluMatrixF}
{$DEFINE __SIZE := 2}
{$DEFINE __VEC := TgluVector2f}
{$DEFINE __MAT := TgluMatrix2f}
{$DEFINE __HELPER := TgluTypeHelperMatrix2f}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixF}
{$DEFINE __SIZE := 3}
{$DEFINE __VEC := TgluVector3f}
{$DEFINE __MAT := TgluMatrix3f}
{$DEFINE __HELPER := TgluTypeHelperMatrix3f}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixF}
{$DEFINE __SIZE := 4}
{$DEFINE __VEC := TgluVector4f}
{$DEFINE __MAT := TgluMatrix4f}
{$DEFINE __HELPER := TgluTypeHelperMatrix4f}
{$I ugluMatrixEx.inc}



{$DEFINE __IMPL := TgluMatrixD}
{$DEFINE __SIZE := 2}
{$DEFINE __VEC := TgluVector2d}
{$DEFINE __MAT := TgluMatrix2d}
{$DEFINE __HELPER := TgluTypeHelperMatrix2d}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixD}
{$DEFINE __SIZE := 3}
{$DEFINE __VEC := TgluVector3d}
{$DEFINE __MAT := TgluMatrix3d}
{$DEFINE __HELPER := TgluTypeHelperMatrix3d}
{$I ugluMatrixEx.inc}

{$DEFINE __IMPL := TgluMatrixD}
{$DEFINE __SIZE := 4}
{$DEFINE __VEC := TgluVector4d}
{$DEFINE __MAT := TgluMatrix4d}
{$DEFINE __HELPER := TgluTypeHelperMatrix4d}
{$I ugluMatrixEx.inc}
{$UNDEF __MATRIX_HELPER_IMPL}

end.


+ 540
- 0
ugluMatrixExHelper.pas Vedi File

@@ -0,0 +1,540 @@
unit ugluMatrixExHelper;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils,
ugluVectorExHelper;

type
generic TgluMatrixHelper<T> = class
public type
TVectorHelper = specialize TgluVectorHelper<T>;
TVectorHelperF = specialize TgluVectorHelperF<T>;
TBaseType = T;
PBaseType = ^T;

TMat2 = array[0..1] of TVectorHelper.TVector2;
TMat3 = array[0..2] of TVectorHelper.TVector3;
TMat4 = array[0..3] of TVectorHelper.TVector4;

PMat2 = ^TMat2;
PMat3 = ^TMat3;
PMat4 = ^TMat4;

public
class function Equals(const m1, m2: TMat2): Boolean; overload; inline;
class function Equals(const m1, m2: TMat3): Boolean; overload; inline;
class function Equals(const m1, m2: TMat4): Boolean; overload; inline;

class function ToString(const m: TMat2; const aRound: Integer = -3): String; overload; inline;
class function ToString(const m: TMat3; const aRound: Integer = -3): String; overload; inline;
class function ToString(const m: TMat4; const aRound: Integer = -3): String; overload; inline;

class function TryFromString(const s: String; out m: TMat2): Boolean; overload; inline;
class function TryFromString(const s: String; out m: TMat3): Boolean; overload; inline;
class function TryFromString(const s: String; out m: TMat4): Boolean; overload; inline;

class function Transpose(const m: TMat2): TMat2; overload; inline;
class function Transpose(const m: TMat3): TMat3; overload; inline;
class function Transpose(const m: TMat4): TMat4; overload; inline;

class function Sub(const m: TMat2; const c, r: Integer): TBaseType; overload; inline;
class function Sub(const m: TMat3; const c, r: Integer): TMat2; overload; inline;
class function Sub(const m: TMat4; const c, r: Integer): TMat3; overload; inline;

class function Determinant(const m: TMat2): Double; overload; inline;
class function Determinant(const m: TMat3): Double; overload; inline;
class function Determinant(const m: TMat4): Double; overload;

class function Adjoint(const m: TMat3): TMat3; overload;
class function Adjoint(const m: TMat4): TMat4; overload;

class function Multiply(const m1, m2: TMat2): TMat2; overload; inline;
class function Multiply(const m1, m2: TMat3): TMat3; overload; inline;
class function Multiply(const m1, m2: TMat4): TMat4; overload; inline;

class function Multiply(const m: TMat2; const v: TVectorHelper.TVector2): TVectorHelper.TVector2; overload; inline;
class function Multiply(const m: TMat3; const v: TVectorHelper.TVector3): TVectorHelper.TVector3; overload; inline;
class function Multiply(const m: TMat4; const v: TVectorHelper.TVector4): TVectorHelper.TVector4; overload; inline;

class function Multiply(const m: TMat2; const v: TBaseType): TMat2; overload; inline;
class function Multiply(const m: TMat3; const v: TBaseType): TMat3; overload; inline;
class function Multiply(const m: TMat4; const v: TBaseType): TMat4; overload; inline;

class function Invert(const m: TMat2): TMat2; overload; inline;
class function Invert(const m: TMat3): TMat3; overload; inline;
class function Invert(const m: TMat4): TMat4; overload; inline;

class function CreateTranslate(const v: TVectorHelper.TVector2): TMat3;
class function CreateTranslate(const v: TVectorHelper.TVector3): TMat4;

class function CreateScale(const v: TVectorHelper.TVector2): TMat3;
class function CreateScale(const v: TVectorHelper.TVector3): TMat4;

class function CreateRotate(a: Double): TMat3;
class function CreateRotate(axis: TVectorHelper.TVector3; a: Double): TMat4;

class function CreateShear(const v: TVectorHelper.TVector2): TMat3;
class function CreateShear(const x, y, z: TVectorHelper.TVector2): TMat4;
private
class function GetElement(p: PBaseType; x, y, sz: Integer): TBaseType; // TODO inline;
class procedure SetElement(p: PBaseType; x, y, sz: Integer; v: TBaseType); // TODO inline;

class procedure Transpose(src, dst: PBaseType; sz: Integer);
class procedure Sub(src, dst: PBaseType; sz, c, r: Integer);
class procedure Mult(p1, p2, r: PBaseType; c1r2, r1, c2: Integer);
class procedure Mult(src, dst: PBaseType; c, r: Integer; v: TBaseType);

class function TryFromString(const s: String; p: PBaseType; r, c: Integer): Boolean;
end;

TgluMatrixF = specialize TgluMatrixHelper<Single>;
TgluMatrixD = specialize TgluMatrixHelper<Double>;

implementation

uses
Math;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TgluMatrixHelper//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TgluMatrixHelper.Equals(const m1, m2: TMat2): Boolean;
begin
result :=
TVectorHelper.Equals(m1[0], m2[0]) and
TVectorHelper.Equals(m1[1], m2[1]);
end;

class function TgluMatrixHelper.Equals(const m1, m2: TMat3): Boolean;
begin
result :=
TVectorHelper.Equals(m1[0], m2[0]) and
TVectorHelper.Equals(m1[1], m2[1]) and
TVectorHelper.Equals(m1[2], m2[2]);
end;

class function TgluMatrixHelper.Equals(const m1, m2: TMat4): Boolean;
begin
result :=
TVectorHelper.Equals(m1[0], m2[0]) and
TVectorHelper.Equals(m1[1], m2[1]) and
TVectorHelper.Equals(m1[2], m2[2]) and
TVectorHelper.Equals(m1[3], m2[3]);
end;

class function TgluMatrixHelper.ToString(const m: TMat2; const aRound: Integer): String;
begin
result := format('(%s); (%s)', [
TVectorHelper.ToString(m[0], aRound),
TVectorHelper.ToString(m[1], aRound)]);
end;

class function TgluMatrixHelper.ToString(const m: TMat3; const aRound: Integer): String;
begin
result := format('(%s); (%s); (%s)', [
TVectorHelper.ToString(m[0], aRound),
TVectorHelper.ToString(m[1], aRound),
TVectorHelper.ToString(m[2], aRound)]);
end;

class function TgluMatrixHelper.ToString(const m: TMat4; const aRound: Integer): String;
begin
result := format('(%s); (%s); (%s); (%s)', [
TVectorHelper.ToString(m[0], aRound),
TVectorHelper.ToString(m[1], aRound),
TVectorHelper.ToString(m[2], aRound),
TVectorHelper.ToString(m[3], aRound)]);
end;

class function TgluMatrixHelper.TryFromString(const s: String; out m: TMat2): Boolean;
begin
result := TryFromString(s, @m[0,0], 2, 2);
end;

class function TgluMatrixHelper.TryFromString(const s: String; out m: TMat3): Boolean;
begin
result := TryFromString(s, @m[0,0], 3, 3);
end;

class function TgluMatrixHelper.TryFromString(const s: String; out m: TMat4): Boolean;
begin
result := TryFromString(s, @m[0,0], 4, 4);
end;

class function TgluMatrixHelper.Transpose(const m: TMat2): TMat2;
begin
Transpose(@m[0,0], @result[0,0], Length(m));
end;

class function TgluMatrixHelper.Transpose(const m: TMat3): TMat3;
begin
Transpose(@m[0,0], @result[0,0], Length(m));
end;

class function TgluMatrixHelper.Transpose(const m: TMat4): TMat4;
begin
Transpose(@m[0,0], @result[0,0], Length(m));
end;

class function TgluMatrixHelper.Sub(const m: TMat2; const c, r: Integer): TBaseType;
begin
Sub(@m[0,0], @result, 2, c, r);
end;

class function TgluMatrixHelper.Sub(const m: TMat3; const c, r: Integer): TMat2;
begin
Sub(@m[0,0], @result[0,0], 3, c, r);
end;

class function TgluMatrixHelper.Sub(const m: TMat4; const c, r: Integer): TMat3;
begin
Sub(@m[0,0], @result[0,0], 4, c, r);
end;

class function TgluMatrixHelper.Determinant(const m: TMat2): Double;
begin
result := m[0,0] * m[1,1] - m[1,0] * m[0,1];
end;

class function TgluMatrixHelper.Determinant(const m: TMat3): Double;
begin
result :=
m[0,0] * m[1,1] * m[2,2] +
m[1,0] * m[2,1] * m[0,2] +
m[2,0] * m[0,1] * m[1,2] -
m[2,0] * m[1,1] * m[0,2] -
m[1,0] * m[0,1] * m[2,2] -
m[0,0] * m[2,1] * m[1,2];
end;

class function TgluMatrixHelper.Determinant(const m: TMat4): Double;
var
i: Integer;
begin
result := 0.0;
for i := 0 to 3 do
result := result + power(-1, i) * m[i,0] * Determinant(Sub(m, i, 0));
end;

class function TgluMatrixHelper.Adjoint(const m: TMat3): TMat3;
var
i, j: Integer;
begin
for i := 0 to 2 do
for j := 0 to 2 do
result[i,j] := power(-1, i+j) * Determinant(Sub(m, i, j));
result := Transpose(result{%H-});
end;

class function TgluMatrixHelper.Adjoint(const m: TMat4): TMat4;
var
i, j: Integer;
begin
for i := 0 to 3 do
for j := 0 to 3 do
result[i,j] := power(-1, i+j) * Determinant(Sub(m, i, j));
result := Transpose(result{%H-});
end;

class function TgluMatrixHelper.Multiply(const m1, m2: TMat2): TMat2;
begin
Mult(@m1[0,0], @m2[0,0], @result[0,0], 2, 2, 2);
end;

class function TgluMatrixHelper.Multiply(const m1, m2: TMat3): TMat3;
begin
Mult(@m1[0,0], @m2[0,0], @result[0,0], 3, 3, 3);
end;

class function TgluMatrixHelper.Multiply(const m1, m2: TMat4): TMat4;
begin
Mult(@m1[0,0], @m2[0,0], @result[0,0], 4, 4, 4);
end;

class function TgluMatrixHelper.Multiply(const m: TMat2; const v: TVectorHelper.TVector2): TVectorHelper.TVector2;
begin
Mult(@m[0,0], @v[0], @result[0], 2, 2, 1);
end;

class function TgluMatrixHelper.Multiply(const m: TMat3; const v: TVectorHelper.TVector3): TVectorHelper.TVector3;
begin
Mult(@m[0,0], @v[0], @result[0], 3, 3, 1);
end;

class function TgluMatrixHelper.Multiply(const m: TMat4; const v: TVectorHelper.TVector4): TVectorHelper.TVector4;
begin
Mult(@m[0,0], @v[0], @result[0], 4, 4, 1);
end;

class function TgluMatrixHelper.Multiply(const m: TMat2; const v: TBaseType): TMat2;
begin
Mult(@m[0,0], @result[0,0], 2, 2, v);
end;

class function TgluMatrixHelper.Multiply(const m: TMat3; const v: TBaseType): TMat3;
begin
Mult(@m[0,0], @result[0,0], 3, 3, v);
end;

class function TgluMatrixHelper.Multiply(const m: TMat4; const v: TBaseType): TMat4;
begin
Mult(@m[0,0], @result[0,0], 4, 4, v);
end;

class function TgluMatrixHelper.Invert(const m: TMat2): TMat2;
begin
result[0,0] := m[1,1];
result[0,1] := -m[0,1];
result[1,0] := -m[1,0];
result[1,1] := m[0,0];
Mult(@result[0,0], @result[0,0], 2, 2, 1 / Determinant(m));
end;

class function TgluMatrixHelper.Invert(const m: TMat3): TMat3;
begin
result := Adjoint(m);
Mult(@result[0,0], @result[0,0], 2, 2, 1 / Determinant(m));
end;

class function TgluMatrixHelper.Invert(const m: TMat4): TMat4;
begin
result := Adjoint(m);
Mult(@result[0,0], @result[0,0], 3, 3, 1 / Determinant(m));
end;

class function TgluMatrixHelper.CreateTranslate(const v: TVectorHelper.TVector2): TMat3;
begin
result[0, 0] := 1.0;
result[0, 1] := 0.0;
result[0, 2] := 0.0;
result[1, 0] := 0.0;
result[1, 1] := 1.0;
result[1, 2] := 0.0;
result[2, 0] := v[0];
result[2, 1] := v[1];
result[2, 2] := 1.0;
end;

class function TgluMatrixHelper.CreateTranslate(const v: TVectorHelper.TVector3): TMat4;
begin
result[0, 0] := 1.0;
result[0, 1] := 0.0;
result[0, 2] := 0.0;
result[0, 3] := 0.0;
result[1, 0] := 0.0;
result[1, 1] := 1.0;
result[1, 2] := 0.0;
result[1, 3] := 0.0;
result[2, 0] := 0.0;
result[2, 1] := 0.0;
result[2, 2] := 1.0;
result[2, 3] := 0.0;
result[3, 0] := v[0];
result[3, 1] := v[1];
result[3, 2] := v[2];
result[3, 3] := 1.0;
end;

class function TgluMatrixHelper.CreateScale(const v: TVectorHelper.TVector2): TMat3;
begin
result[0, 0] := v[0];
result[0, 1] := 0.0;
result[0, 2] := 0.0;
result[1, 0] := 0.0;
result[1, 1] := v[1];
result[1, 2] := 0.0;
result[2, 0] := 0.0;
result[2, 1] := 0.0;
result[2, 2] := 1.0;
end;

class function TgluMatrixHelper.CreateScale(const v: TVectorHelper.TVector3): TMat4;
begin
result[0, 0] := v[0];
result[0, 1] := 0.0;
result[0, 2] := 0.0;
result[0, 3] := 0.0;
result[1, 0] := 0.0;
result[1, 1] := v[1];
result[1, 2] := 0.0;
result[1, 3] := 0.0;
result[2, 0] := 0.0;
result[2, 1] := 0.0;
result[2, 2] := v[2];
result[2, 3] := 0.0;
result[3, 0] := 0.0;
result[3, 1] := 0.0;
result[3, 2] := 0.0;
result[3, 3] := 1.0;
end;

class function TgluMatrixHelper.CreateRotate(a: Double): TMat3;
begin
a := DegToRad(a);
result[0, 0] := cos(a);
result[0, 1] := -sin(a);
result[0, 2] := 0.0;
result[1, 0] := sin(a);
result[1, 1] := cos(a);
result[1, 2] := 0.0;
result[2, 0] := 0.0;
result[2, 1] := 0.0;
result[2, 2] := 1.0;
end;

class function TgluMatrixHelper.CreateRotate(axis: TVectorHelper.TVector3; a: Double): TMat4;
var
X, Y, Z, s, c: Single;
begin
a := DegToRad(a);
axis := TVectorHelperF.Normalize(axis);
X := axis[0];
Y := axis[1];
Z := axis[2];
s := sin(a);
c := cos(a);
result[0,0] := SQR(X) + (1-SQR(X))*c;
result[0,1] := X*Y*(1-c) + Z*s;
result[0,2] := X*Z*(1-c) - Y*s;
result[0,3] := 0.0;
result[1,0] := X*Y*(1-c) - Z*s;
result[1,1] := SQR(Y) + (1-SQR(Y))*c;
result[1,2] := Y*Z*(1-c) + X*s;
result[1,3] := 0.0;
result[2,0] := X*Z*(1-c) + Y*s;
result[2,1] := Y*Z*(1-c) - X*s;
result[2,2] := SQR(Z) + (1-SQR(Z))*c;
result[2,3] := 0.0;
result[3,0] := 0.0;
result[3,1] := 0.0;
result[3,2] := 0.0;
result[3,3] := 1.0;
end;

class function TgluMatrixHelper.CreateShear(const v: TVectorHelper.TVector2): TMat3;
begin
result[0, 0] := 1.0;
result[0, 1] := v[1];
result[0, 2] := 0.0;
result[1, 0] := v[0];
result[1, 1] := 1.0;
result[1, 2] := 0.0;
result[2, 0] := 0.0;
result[2, 1] := 0.0;
result[2, 2] := 1.0;
end;

class function TgluMatrixHelper.CreateShear(const x, y, z: TVectorHelper.TVector2): TMat4;
begin
result[0,0] := 1.0;
result[0,1] := y[0];
result[0,2] := z[0];
result[0,3] := 0.0;
result[1,0] := x[0];
result[1,1] := 1.0;
result[1,2] := z[1];
result[1,3] := 0.0;
result[2,0] := x[1];
result[2,1] := y[1];
result[2,2] := 1.0;
result[2,3] := 0.0;
result[3,0] := 0.0;
result[3,1] := 0.0;
result[3,2] := 0.0;
result[3,3] := 1.0;
end;

class function TgluMatrixHelper.GetElement(p: PBaseType; x, y, sz: Integer): TBaseType;
begin
result := (p + (x * sz) + y)^;
end;

class procedure TgluMatrixHelper.SetElement(p: PBaseType; x, y, sz: Integer; v: TBaseType);
begin
(p + (x * sz) + y)^ := v;
end;

class procedure TgluMatrixHelper.Transpose(src, dst: PBaseType; sz: Integer);
var
i, j: Integer;
begin
for i := 0 to sz-1 do
for j := 0 to sz-1 do
SetElement(dst, i, j, sz, GetElement(src, j, i, sz));
end;

class procedure TgluMatrixHelper.Sub(src, dst: PBaseType; sz, c, r: Integer);
var
x, y, i, j: Integer;
begin
for i := 0 to sz-1 do begin
for j := 0 to sz-1 do begin
x := i;
y := j;
if (i >= c) then inc(x);
if (j >= r) then inc(y);
SetElement(dst, i, j, sz-1, GetElement(src, x, y, sz));
end;
end;
end;

class procedure TgluMatrixHelper.Mult(p1, p2, r: PBaseType; c1r2, r1, c2: Integer);
var
x, y, i: Integer;
sum: TBaseType;
begin
for x := 0 to c2-1 do begin
for y := 0 to r1-1 do begin
sum := 0;
for i := 0 to c1r2-1 do
sum := sum + GetElement(p1, i, y, c1r2) * GetElement(p2, x, i, c2);
SetElement(r, x, y, c2, sum);
end;
end;
end;

class procedure TgluMatrixHelper.Mult(src, dst: PBaseType; c, r: Integer; v: TBaseType);
var
i, j: Integer;
begin
for i := 0 to c-1 do
for j := 0 to r-1 do
SetElement(dst, i, j, c, v * GetElement(src, i, j, c));
end;

class function TgluMatrixHelper.TryFromString(const s: String; p: PBaseType; r, c: Integer): Boolean;
var
i, j, l: Integer;
begin
result := true;
l := Length(s);
i := 1;
j := l;
while (i <= l) and (c > 0) and result do begin
if (s[i] = '(') then begin
j := i+1;
end else if (s[i] = ')') then begin
result := TVectorHelper.TryFromString(trim(copy(s, j, i-j)), p, r);
j := l;
inc(p, r);
dec(c);
end;
inc(i);
end;

result := (c = 0);
while (c > 0) do begin
for i := 0 to r-1 do begin
p^ := 0;
inc(p);
end;
dec(c);
end;
end;

end.


+ 32
- 0
ugluVectorEx.pas Vedi File

@@ -39,6 +39,38 @@ type
TgluVector3d = TgluVectorD.TVector3;
TgluVector4d = TgluVectorD.TVector4;



PgluVector2p = ^TgluVector2p;
PgluVector3p = ^TgluVector3p;
PgluVector4p = ^TgluVector4p;

PgluVector2e = ^TgluVector2e;
PgluVector3e = ^TgluVector3e;
PgluVector4e = ^TgluVector4e;

PgluVector2i = ^TgluVector2i;
PgluVector3i = ^TgluVector3i;
PgluVector4i = ^TgluVector4i;

PgluVector2us = ^TgluVector2us;
PgluVector3us = ^TgluVector3us;
PgluVector4us = ^TgluVector4us;

PgluVector2ub = ^TgluVector2ub;
PgluVector3ub = ^TgluVector3ub;
PgluVector4ub = ^TgluVector4ub;

PgluVector2f = ^TgluVector2f;
PgluVector3f = ^TgluVector3f;
PgluVector4f = ^TgluVector4f;

PgluVector2d = ^TgluVector2d;
PgluVector3d = ^TgluVector3d;
PgluVector4d = ^TgluVector4d;



{$DEFINE __VECTOR_HELPER_INTERFACE}
{ TgluVector2p }
{$DEFINE __IMPL := TgluVectorP}


+ 8
- 9
ugluVectorExHelper.pas Vedi File

@@ -38,8 +38,6 @@ type
class function TryFromString(const s: String; out v: TVector2): Boolean; overload; inline;
class function TryFromString(const s: String; out v: TVector3): Boolean; overload; inline;
class function TryFromString(const s: String; out v: TVector4): Boolean; overload; inline;

private
class function TryFromString(const s: String; p: PBaseType; aCount: Integer): Boolean;
end;

@@ -99,12 +97,6 @@ type
TgluVectorF = specialize TgluVectorHelperF<Single>;
TgluVectorD = specialize TgluVectorHelperF<Double>;

implementation

uses
Math;

type
TPointerTypeHelper = type helper for Pointer
function ToString(const aRound: Integer = -3): String;
class function TryFromString(s: String; out v: Pointer): Boolean; static;
@@ -140,6 +132,11 @@ type
class function TryFromString(s: String; out v: Double): Boolean; static;
end;

implementation

uses
Math;

function IntToStrRounded(i: Int64; const aRound: Integer): String;
var p: Cardinal;
begin
@@ -353,7 +350,8 @@ begin
j := 1;
l := Length(s);
while ({%H-}i <= {%H-}l) and (aCount > 0) and result {%H-}do begin
if (s[i] = ';') then begin
if (s[i] = ';') or (i = l) then begin
if (i = l) then inc(i);
result := TBaseType.TryFromString(Trim(copy(s, j, i-{%H-}j)), p^);
j := i+1;
inc(p);
@@ -362,6 +360,7 @@ begin
inc(i);
end;

result := (aCount = 0);
while (aCount > 0) do begin
p^ := TBaseType(0);
inc(p);


Caricamento…
Annulla
Salva