Commit 15fd6367 authored by Bergmann89's avatar Bergmann89

* reimplemented matrix unit using type helpers

parent 02d239b2
{$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}
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.
This diff is collapsed.
......@@ -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}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment