| @@ -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} | |||||
| @@ -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. | |||||
| @@ -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. | |||||
| @@ -39,6 +39,38 @@ type | |||||
| TgluVector3d = TgluVectorD.TVector3; | TgluVector3d = TgluVectorD.TVector3; | ||||
| TgluVector4d = TgluVectorD.TVector4; | 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} | {$DEFINE __VECTOR_HELPER_INTERFACE} | ||||
| { TgluVector2p } | { TgluVector2p } | ||||
| {$DEFINE __IMPL := TgluVectorP} | {$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: TVector2): Boolean; overload; inline; | ||||
| class function TryFromString(const s: String; out v: TVector3): 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; | class function TryFromString(const s: String; out v: TVector4): Boolean; overload; inline; | ||||
| private | |||||
| class function TryFromString(const s: String; p: PBaseType; aCount: Integer): Boolean; | class function TryFromString(const s: String; p: PBaseType; aCount: Integer): Boolean; | ||||
| end; | end; | ||||
| @@ -99,12 +97,6 @@ type | |||||
| TgluVectorF = specialize TgluVectorHelperF<Single>; | TgluVectorF = specialize TgluVectorHelperF<Single>; | ||||
| TgluVectorD = specialize TgluVectorHelperF<Double>; | TgluVectorD = specialize TgluVectorHelperF<Double>; | ||||
| implementation | |||||
| uses | |||||
| Math; | |||||
| type | |||||
| TPointerTypeHelper = type helper for Pointer | TPointerTypeHelper = type helper for Pointer | ||||
| function ToString(const aRound: Integer = -3): String; | function ToString(const aRound: Integer = -3): String; | ||||
| class function TryFromString(s: String; out v: Pointer): Boolean; static; | 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; | class function TryFromString(s: String; out v: Double): Boolean; static; | ||||
| end; | end; | ||||
| implementation | |||||
| uses | |||||
| Math; | |||||
| function IntToStrRounded(i: Int64; const aRound: Integer): String; | function IntToStrRounded(i: Int64; const aRound: Integer): String; | ||||
| var p: Cardinal; | var p: Cardinal; | ||||
| begin | begin | ||||
| @@ -353,7 +350,8 @@ begin | |||||
| j := 1; | j := 1; | ||||
| l := Length(s); | l := Length(s); | ||||
| while ({%H-}i <= {%H-}l) and (aCount > 0) and result {%H-}do begin | 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^); | result := TBaseType.TryFromString(Trim(copy(s, j, i-{%H-}j)), p^); | ||||
| j := i+1; | j := i+1; | ||||
| inc(p); | inc(p); | ||||
| @@ -362,6 +360,7 @@ begin | |||||
| inc(i); | inc(i); | ||||
| end; | end; | ||||
| result := (aCount = 0); | |||||
| while (aCount > 0) do begin | while (aCount > 0) do begin | ||||
| p^ := TBaseType(0); | p^ := TBaseType(0); | ||||
| inc(p); | inc(p); | ||||