Luxophia

Форк
0
/
LUX.M4.pas 
3415 строк · 76.5 Кб
1
unit LUX.M4;
2

3
interface
4

5
uses
6
  System.SysUtils,
7
  System.Math,
8
  System.Math.Vectors,
9
  LUX,
10
  LUX.D1,
11
  LUX.D2,
12
  LUX.D3,
13
  LUX.D4,
14
  LUX.M2,
15
  LUX.M3;
16

17
type
18

19
  TIntegerM4 = record
20
  private
21
    function GetM(const Y_, X_: Integer): Integer;
22
    procedure SetM(const Y_, X_: Integer; const M_: Integer);
23
  public
24
    property M[const Y_, X_: Integer]: Integer read GetM write SetM; default;
25
    case Integer of
26
      0:
27
        (_: array [1 .. 4, 1 .. 4] of Integer;);
28
      1:
29
        (_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42,
30
          _43, _44: Integer;
31
        );
32
  end;
33

34
  TSingleM4 = record
35
  public
36
    function GetM(const Y_, X_: Integer): Single;
37
    procedure SetM(const Y_, X_: Integer; const M_: Single);
38
    function GetAxisX: TSingle3D;
39
    procedure SetAxisX(const AxisX_: TSingle3D);
40
    function GetAxisY: TSingle3D;
41
    procedure SetAxisY(const AxisY_: TSingle3D);
42
    function GetAxisZ: TSingle3D;
43
    procedure SetAxisZ(const AxisZ_: TSingle3D);
44
    function GetAxisP: TSingle3D;
45
    procedure SetAxisP(const AxisP_: TSingle3D);
46
  public
47
    constructor Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_, _24_,
48
      _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: Single); overload;
49
    constructor Create(const X_, Y_, Z_, P_: TSingle3D); overload;
50
    property M[const Y_, X_: Integer]: Single read GetM write SetM; default;
51
    property AxisX: TSingle3D read GetAxisX write SetAxisX;
52
    property AxisY: TSingle3D read GetAxisY write SetAxisY;
53
    property AxisZ: TSingle3D read GetAxisZ write SetAxisZ;
54
    property AxisP: TSingle3D read GetAxisP write SetAxisP;
55
    class operator Multiply(const A_, B_: TSingleM4): TSingleM4;
56
    class operator Multiply(const A_: Single; const B_: TSingleM4): TSingleM4;
57
    class operator Multiply(const A_: TSingleM4; const B_: Single): TSingleM4;
58
    class operator Multiply(const A_: TSingleM4; const B_: TSingleRay3D)
59
      : TSingleRay3D;
60
    class operator Multiply(const A_: TSingleM4; const B_: TSingle4D)
61
      : TSingle4D;
62
    class operator Multiply(const A_: TSingle4D; const B_: TSingleM4)
63
      : TSingle4D;
64
    class operator Divide(const A_: TSingleM4; const B_: Single): TSingleM4;
65
    class operator Implicit(const V_: Single): TSingleM4;
66
    class operator Implicit(const V_: TMatrix3D): TSingleM4;
67
    class operator Explicit(const V_: TSingleM4): TMatrix3D;
68
    class operator Implicit(const V_: TSingleM3): TSingleM4;
69
    class operator Explicit(const V_: TSingleM4): TSingleM3;
70
    function MultPos(const B_: TSingle3D): TSingle3D;
71
    function MultVec(const B_: TSingle3D): TSingle3D;
72
    function Adjugate: TSingleM4;
73
    function Transpose: TSingleM4;
74
    function Inverse: TSingleM4;
75
    class function Translate(const X_, Y_, Z_: Single): TSingleM4;
76
      overload; static;
77
    class function Translate(const T_: TSingle3D): TSingleM4; overload; static;
78
    class function Scale(const X_, Y_, Z_: Single): TSingleM4; overload; static;
79
    class function Scale(const S_: TSingle3D): TSingleM4; overload; static;
80
    class function RotateX(const T_: Single): TSingleM4; static;
81
    class function RotateY(const T_: Single): TSingleM4; static;
82
    class function RotateZ(const T_: Single): TSingleM4; static;
83
    class function Identity: TSingleM4; static;
84
    class function ProjOrth(const L_, R_, B_, T_, N_, F_: Single)
85
      : TSingleM4; static;
86
    class function ProjPers(const L_, R_, B_, T_, N_, F_: Single)
87
      : TSingleM4; static;
88

89
    case Integer of
90
      0:
91
        (_: array [1 .. 4, 1 .. 4] of Single;);
92
      1:
93
        (_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42,
94
          _43, _44: Single;
95
        );
96
  end;
97

98
  TDoubleM4 = record
99
  public
100
    function GetM(const Y_, X_: Integer): Double;
101
    procedure SetM(const Y_, X_: Integer; const M_: Double);
102
    function GetAxisX: TDouble3D;
103
    procedure SetAxisX(const AxisX_: TDouble3D);
104
    function GetAxisY: TDouble3D;
105
    procedure SetAxisY(const AxisY_: TDouble3D);
106
    function GetAxisZ: TDouble3D;
107
    procedure SetAxisZ(const AxisZ_: TDouble3D);
108
    function GetAxisP: TDouble3D;
109
    procedure SetAxisP(const AxisP_: TDouble3D);
110
  public
111
    constructor Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_, _24_,
112
      _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: Double); overload;
113
    constructor Create(const X_, Y_, Z_, P_: TDouble3D); overload;
114
    property M[const Y_, X_: Integer]: Double read GetM write SetM; default;
115
    property AxisX: TDouble3D read GetAxisX write SetAxisX;
116
    property AxisY: TDouble3D read GetAxisY write SetAxisY;
117
    property AxisZ: TDouble3D read GetAxisZ write SetAxisZ;
118
    property AxisP: TDouble3D read GetAxisP write SetAxisP;
119
    class operator Multiply(const A_, B_: TDoubleM4): TDoubleM4;
120
    class operator Multiply(const A_: Double; const B_: TDoubleM4): TDoubleM4;
121
    class operator Multiply(const A_: TDoubleM4; const B_: Double): TDoubleM4;
122
    class operator Multiply(const A_: TDoubleM4; const B_: TDoubleRay3D)
123
      : TDoubleRay3D;
124
    class operator Multiply(const A_: TDoubleM4; const B_: TDouble4D)
125
      : TDouble4D;
126
    class operator Multiply(const A_: TDouble4D; const B_: TDoubleM4)
127
      : TDouble4D;
128
    class operator Divide(const A_: TDoubleM4; const B_: Double): TDoubleM4;
129
    class operator Implicit(const V_: Double): TDoubleM4;
130
    class operator Implicit(const V_: TMatrix3D): TDoubleM4;
131
    class operator Explicit(const V_: TDoubleM4): TMatrix3D;
132
    class operator Implicit(const V_: TSingleM4): TDoubleM4;
133
    class operator Explicit(const V_: TDoubleM4): TSingleM4;
134
    class operator Implicit(const V_: TDoubleM3): TDoubleM4;
135
    class operator Explicit(const V_: TDoubleM4): TDoubleM3;
136
    function MultPos(const B_: TDouble3D): TDouble3D;
137
    function MultVec(const B_: TDouble3D): TDouble3D;
138
    function Adjugate: TDoubleM4;
139
    function Transpose: TDoubleM4;
140
    function Inverse: TDoubleM4;
141
    class function Translate(const X_, Y_, Z_: Double): TDoubleM4;
142
      overload; static;
143
    class function Translate(const T_: TDouble3D): TDoubleM4; overload; static;
144
    class function Scale(const X_, Y_, Z_: Double): TDoubleM4; overload; static;
145
    class function Scale(const S_: TDouble3D): TDoubleM4; overload; static;
146
    class function RotateX(const T_: Double): TDoubleM4; static;
147
    class function RotateY(const T_: Double): TDoubleM4; static;
148
    class function RotateZ(const T_: Double): TDoubleM4; static;
149
    class function Identity: TDoubleM4; static;
150
    class function ProjOrth(const L_, R_, B_, T_, N_, F_: Double)
151
      : TDoubleM4; static;
152
    class function ProjPers(const L_, R_, B_, T_, N_, F_: Double)
153
      : TDoubleM4; static;
154

155
    case Integer of
156
      0:
157
        (_: array [1 .. 4, 1 .. 4] of Double;);
158
      1:
159
        (_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42,
160
          _43, _44: Double;
161
        );
162
  end;
163

164
  TdSingleM4 = record
165
  public
166
    function GetM(const Y_, X_: Integer): TdSingle;
167
    procedure SetM(const Y_, X_: Integer; const M_: TdSingle);
168
    function GetAxisX: TdSingle3D;
169
    procedure SetAxisX(const AxisX_: TdSingle3D);
170
    function GetAxisY: TdSingle3D;
171
    procedure SetAxisY(const AxisY_: TdSingle3D);
172
    function GetAxisZ: TdSingle3D;
173
    procedure SetAxisZ(const AxisZ_: TdSingle3D);
174
    function GetAxisP: TdSingle3D;
175
    procedure SetAxisP(const AxisP_: TdSingle3D);
176
  public
177
    constructor Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_, _24_,
178
      _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: TdSingle); overload;
179
    constructor Create(const X_, Y_, Z_, P_: TdSingle3D); overload;
180
    property M[const Y_, X_: Integer]: TdSingle read GetM write SetM; default;
181
    property AxisX: TdSingle3D read GetAxisX write SetAxisX;
182
    property AxisY: TdSingle3D read GetAxisY write SetAxisY;
183
    property AxisZ: TdSingle3D read GetAxisZ write SetAxisZ;
184
    property AxisP: TdSingle3D read GetAxisP write SetAxisP;
185
    class operator Multiply(const A_, B_: TdSingleM4): TdSingleM4;
186
    class operator Multiply(const A_: TdSingle; const B_: TdSingleM4)
187
      : TdSingleM4;
188
    class operator Multiply(const A_: TdSingleM4; const B_: TdSingle)
189
      : TdSingleM4;
190
    class operator Multiply(const A_: TdSingleM4; const B_: TdSingle4D)
191
      : TdSingle4D;
192
    class operator Multiply(const A_: TdSingle4D; const B_: TdSingleM4)
193
      : TdSingle4D;
194
    class operator Divide(const A_: TdSingleM4; const B_: TdSingle): TdSingleM4;
195
    class operator Implicit(const V_: TdSingle): TdSingleM4;
196
    class operator Implicit(const V_: TMatrix3D): TdSingleM4;
197
    class operator Explicit(const V_: TdSingleM4): TMatrix3D;
198
    class operator Implicit(const V_: TdSingleM3): TdSingleM4;
199
    class operator Explicit(const V_: TdSingleM4): TdSingleM3;
200
    function MultPos(const B_: TdSingle3D): TdSingle3D;
201
    function MultVec(const B_: TdSingle3D): TdSingle3D;
202
    function Adjugate: TdSingleM4;
203
    function Transpose: TdSingleM4;
204
    function Inverse: TdSingleM4;
205
    class function Translate(const X_, Y_, Z_: TdSingle): TdSingleM4;
206
      overload; static;
207
    class function Translate(const T_: TdSingle3D): TdSingleM4;
208
      overload; static;
209
    class function Scale(const X_, Y_, Z_: TdSingle): TdSingleM4;
210
      overload; static;
211
    class function Scale(const S_: TdSingle3D): TdSingleM4; overload; static;
212
    class function RotateX(const T_: TdSingle): TdSingleM4; static;
213
    class function RotateY(const T_: TdSingle): TdSingleM4; static;
214
    class function RotateZ(const T_: TdSingle): TdSingleM4; static;
215
    class function Identity: TdSingleM4; static;
216

217
    case Integer of
218
      0:
219
        (_: array [1 .. 4, 1 .. 4] of TdSingle;);
220
      1:
221
        (_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42,
222
          _43, _44: TdSingle;
223
        );
224
  end;
225

226
  TdDoubleM4 = record
227
  public
228
    function GetM(const Y_, X_: Integer): TdDouble;
229
    procedure SetM(const Y_, X_: Integer; const M_: TdDouble);
230
    function GetAxisX: TdDouble3D;
231
    procedure SetAxisX(const AxisX_: TdDouble3D);
232
    function GetAxisY: TdDouble3D;
233
    procedure SetAxisY(const AxisY_: TdDouble3D);
234
    function GetAxisZ: TdDouble3D;
235
    procedure SetAxisZ(const AxisZ_: TdDouble3D);
236
    function GetAxisP: TdDouble3D;
237
    procedure SetAxisP(const AxisP_: TdDouble3D);
238
  public
239
    constructor Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_, _24_,
240
      _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: TdDouble); overload;
241
    constructor Create(const X_, Y_, Z_, P_: TdDouble3D); overload;
242
    property M[const Y_, X_: Integer]: TdDouble read GetM write SetM; default;
243
    property AxisX: TdDouble3D read GetAxisX write SetAxisX;
244
    property AxisY: TdDouble3D read GetAxisY write SetAxisY;
245
    property AxisZ: TdDouble3D read GetAxisZ write SetAxisZ;
246
    property AxisP: TdDouble3D read GetAxisP write SetAxisP;
247
    class operator Multiply(const A_, B_: TdDoubleM4): TdDoubleM4;
248
    class operator Multiply(const A_: TdDouble; const B_: TdDoubleM4)
249
      : TdDoubleM4;
250
    class operator Multiply(const A_: TdDoubleM4; const B_: TdDouble)
251
      : TdDoubleM4;
252
    class operator Multiply(const A_: TdDoubleM4; const B_: TdDouble4D)
253
      : TdDouble4D;
254
    class operator Multiply(const A_: TdDouble4D; const B_: TdDoubleM4)
255
      : TdDouble4D;
256
    class operator Divide(const A_: TdDoubleM4; const B_: TdDouble): TdDoubleM4;
257
    class operator Implicit(const V_: TdDouble): TdDoubleM4;
258
    class operator Implicit(const V_: TMatrix3D): TdDoubleM4;
259
    class operator Explicit(const V_: TdDoubleM4): TMatrix3D;
260
    class operator Implicit(const V_: TdSingleM4): TdDoubleM4;
261
    class operator Explicit(const V_: TdDoubleM4): TdSingleM4;
262
    class operator Implicit(const V_: TdDoubleM3): TdDoubleM4;
263
    class operator Explicit(const V_: TdDoubleM4): TdDoubleM3;
264
    function MultPos(const B_: TdDouble3D): TdDouble3D;
265
    function MultVec(const B_: TdDouble3D): TdDouble3D;
266
    function Adjugate: TdDoubleM4;
267
    function Transpose: TdDoubleM4;
268
    function Inverse: TdDoubleM4;
269
    class function Translate(const X_, Y_, Z_: TdDouble): TdDoubleM4;
270
      overload; static;
271
    class function Translate(const T_: TdDouble3D): TdDoubleM4;
272
      overload; static;
273
    class function Scale(const X_, Y_, Z_: TdDouble): TdDoubleM4;
274
      overload; static;
275
    class function Scale(const S_: TdDouble3D): TdDoubleM4; overload; static;
276
    class function RotateX(const T_: TdDouble): TdDoubleM4; static;
277
    class function RotateY(const T_: TdDouble): TdDoubleM4; static;
278
    class function RotateZ(const T_: TdDouble): TdDoubleM4; static;
279
    class function Identity: TdDoubleM4; static;
280

281
    case Integer of
282
      0:
283
        (_: array [1 .. 4, 1 .. 4] of TdDouble;);
284
      1:
285
        (_11, _12, _13, _14, _21, _22, _23, _24, _31, _32, _33, _34, _41, _42,
286
          _43, _44: TdDouble;
287
        );
288
  end;
289

290
  TSingleDualM4 = record
291
  private
292
    _o: TSingleM4;
293
    _i: TSingleM4;
294
    procedure Seto(const o_: TSingleM4);
295
    procedure Seti(const i_: TSingleM4);
296
  public
297
    property o: TSingleM4 read _o write Seto;
298
    property i: TSingleM4 read _i write Seti;
299
    class operator Multiply(const A_, B_: TSingleDualM4): TSingleDualM4;
300
    class operator Multiply(const A_: Single; B_: TSingleDualM4): TSingleDualM4;
301
    class operator Multiply(const A_: TSingleDualM4; B_: Single): TSingleDualM4;
302
    class operator Divide(const A_: TSingleDualM4; const B_: Single)
303
      : TSingleDualM4;
304
    class function Translate(const X_, Y_, Z_: Single): TSingleDualM4; static;
305
    class function Scale(const X_, Y_, Z_: Single): TSingleDualM4; static;
306
    class function RotateX(const T_: Single): TSingleDualM4; static;
307
    class function RotateY(const T_: Single): TSingleDualM4; static;
308
    class function RotateZ(const T_: Single): TSingleDualM4; static;
309
    class function Identity: TSingleDualM4; static;
310
  end;
311

312
function Tensor(const T_: TSingle2D;
313
  const Func_: TConstFunc<TdSingle2D, TdSingle3D>): TSingleM4; overload;
314
function Tensor(const T_: TDouble2D;
315
  const Func_: TConstFunc<TdDouble2D, TdDouble3D>): TDoubleM4; overload;
316

317
function ArrowPose(const P0_, P1_: TSingle3D): TSingleM4; overload;
318
function ArrowPose(const P0_, P1_: TDouble3D): TDoubleM4; overload;
319

320
implementation // --------------------------------------------------------------
321

322
function TIntegerM4.GetM(const Y_, X_: Integer): Integer;
323
begin
324
  Result := _[Y_, X_];
325
end;
326

327
procedure TIntegerM4.SetM(const Y_, X_: Integer; const M_: Integer);
328
begin
329
  _[Y_, X_] := M_;
330
end;
331

332
function TSingleM4.GetM(const Y_, X_: Integer): Single;
333
begin
334
  Result := _[Y_, X_];
335
end;
336

337
procedure TSingleM4.SetM(const Y_, X_: Integer; const M_: Single);
338
begin
339
  _[Y_, X_] := M_;
340
end;
341

342
// ------------------------------------------------------------------------------
343

344
function TSingleM4.GetAxisX: TSingle3D;
345
begin
346
  with Result do
347
  begin
348
    X := _11;
349
    Y := _21;
350
    Z := _31;
351
  end
352
end;
353

354
procedure TSingleM4.SetAxisX(const AxisX_: TSingle3D);
355
begin
356
  with AxisX_ do
357
  begin
358
    _11 := X;
359
    _21 := Y;
360
    _31 := Z;
361
  end
362
end;
363

364
function TSingleM4.GetAxisY: TSingle3D;
365
begin
366
  with Result do
367
  begin
368
    X := _12;
369
    Y := _22;
370
    Z := _32;
371
  end
372
end;
373

374
procedure TSingleM4.SetAxisY(const AxisY_: TSingle3D);
375
begin
376
  with AxisY_ do
377
  begin
378
    _12 := X;
379
    _22 := Y;
380
    _32 := Z;
381
  end
382
end;
383

384
function TSingleM4.GetAxisZ: TSingle3D;
385
begin
386
  with Result do
387
  begin
388
    X := _13;
389
    Y := _23;
390
    Z := _33;
391
  end
392
end;
393

394
procedure TSingleM4.SetAxisZ(const AxisZ_: TSingle3D);
395
begin
396
  with AxisZ_ do
397
  begin
398
    _13 := X;
399
    _23 := Y;
400
    _33 := Z;
401
  end
402
end;
403

404
function TSingleM4.GetAxisP: TSingle3D;
405
begin
406
  with Result do
407
  begin
408
    X := _14;
409
    Y := _24;
410
    Z := _34;
411
  end
412
end;
413

414
procedure TSingleM4.SetAxisP(const AxisP_: TSingle3D);
415
begin
416
  with AxisP_ do
417
  begin
418
    _14 := X;
419
    _24 := Y;
420
    _34 := Z;
421
  end
422
end;
423

424
constructor TSingleM4.Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_,
425
  _24_, _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: Single);
426
begin
427
  _11 := _11_;
428
  _12 := _12_;
429
  _13 := _13_;
430
  _14 := _14_;
431
  _21 := _21_;
432
  _22 := _22_;
433
  _23 := _23_;
434
  _24 := _24_;
435
  _31 := _31_;
436
  _32 := _32_;
437
  _33 := _33_;
438
  _34 := _34_;
439
  _41 := _41_;
440
  _42 := _42_;
441
  _43 := _43_;
442
  _44 := _44_;
443
end;
444

445
constructor TSingleM4.Create(const X_, Y_, Z_: TSingle3D; const P_: TSingle3D);
446
begin
447
  _11 := X_.X;
448
  _12 := Y_.X;
449
  _13 := Z_.X;
450
  _14 := P_.X;
451
  _21 := X_.Y;
452
  _22 := Y_.Y;
453
  _23 := Z_.Y;
454
  _24 := P_.Y;
455
  _31 := X_.Z;
456
  _32 := Y_.Z;
457
  _33 := Z_.Z;
458
  _34 := P_.Z;
459
  _41 := 0;
460
  _42 := 0;
461
  _43 := 0;
462
  _44 := 1;
463
end;
464

465
class operator TSingleM4.Multiply(const A_, B_: TSingleM4): TSingleM4;
466
begin
467
  with Result do
468
  begin
469
    _11 := A_._11 * B_._11 + A_._12 * B_._21 + A_._13 * B_._31 + A_._14
470
      * B_._41;
471
    _12 := A_._11 * B_._12 + A_._12 * B_._22 + A_._13 * B_._32 + A_._14
472
      * B_._42;
473
    _13 := A_._11 * B_._13 + A_._12 * B_._23 + A_._13 * B_._33 + A_._14
474
      * B_._43;
475
    _14 := A_._11 * B_._14 + A_._12 * B_._24 + A_._13 * B_._34 + A_._14
476
      * B_._44;
477

478
    _21 := A_._21 * B_._11 + A_._22 * B_._21 + A_._23 * B_._31 + A_._24
479
      * B_._41;
480
    _22 := A_._21 * B_._12 + A_._22 * B_._22 + A_._23 * B_._32 + A_._24
481
      * B_._42;
482
    _23 := A_._21 * B_._13 + A_._22 * B_._23 + A_._23 * B_._33 + A_._24
483
      * B_._43;
484
    _24 := A_._21 * B_._14 + A_._22 * B_._24 + A_._23 * B_._34 + A_._24
485
      * B_._44;
486

487
    _31 := A_._31 * B_._11 + A_._32 * B_._21 + A_._33 * B_._31 + A_._34
488
      * B_._41;
489
    _32 := A_._31 * B_._12 + A_._32 * B_._22 + A_._33 * B_._32 + A_._34
490
      * B_._42;
491
    _33 := A_._31 * B_._13 + A_._32 * B_._23 + A_._33 * B_._33 + A_._34
492
      * B_._43;
493
    _34 := A_._31 * B_._14 + A_._32 * B_._24 + A_._33 * B_._34 + A_._34
494
      * B_._44;
495

496
    _41 := A_._41 * B_._11 + A_._42 * B_._21 + A_._43 * B_._31 + A_._44
497
      * B_._41;
498
    _42 := A_._41 * B_._12 + A_._42 * B_._22 + A_._43 * B_._32 + A_._44
499
      * B_._42;
500
    _43 := A_._41 * B_._13 + A_._42 * B_._23 + A_._43 * B_._33 + A_._44
501
      * B_._43;
502
    _44 := A_._41 * B_._14 + A_._42 * B_._24 + A_._43 * B_._34 + A_._44
503
      * B_._44;
504
  end
505
end;
506

507
class operator TSingleM4.Multiply(const A_: Single; const B_: TSingleM4)
508
  : TSingleM4;
509
begin
510
  with Result do
511
  begin
512
    _11 := A_ * B_._11;
513
    _12 := A_ * B_._12;
514
    _13 := A_ * B_._13;
515
    _14 := A_ * B_._14;
516
    _21 := A_ * B_._21;
517
    _22 := A_ * B_._22;
518
    _23 := A_ * B_._23;
519
    _24 := A_ * B_._24;
520
    _31 := A_ * B_._31;
521
    _32 := A_ * B_._32;
522
    _33 := A_ * B_._33;
523
    _34 := A_ * B_._34;
524
    _41 := A_ * B_._41;
525
    _42 := A_ * B_._42;
526
    _43 := A_ * B_._43;
527
    _44 := A_ * B_._44;
528
  end
529
end;
530

531
class operator TSingleM4.Multiply(const A_: TSingleM4; const B_: Single)
532
  : TSingleM4;
533
begin
534
  with Result do
535
  begin
536
    _11 := A_._11 * B_;
537
    _12 := A_._12 * B_;
538
    _13 := A_._13 * B_;
539
    _14 := A_._14 * B_;
540
    _21 := A_._21 * B_;
541
    _22 := A_._22 * B_;
542
    _23 := A_._23 * B_;
543
    _24 := A_._24 * B_;
544
    _31 := A_._31 * B_;
545
    _32 := A_._32 * B_;
546
    _33 := A_._33 * B_;
547
    _34 := A_._34 * B_;
548
    _41 := A_._41 * B_;
549
    _42 := A_._42 * B_;
550
    _43 := A_._43 * B_;
551
    _44 := A_._44 * B_;
552
  end
553
end;
554

555
class operator TSingleM4.Multiply(const A_: TSingleM4; const B_: TSingleRay3D)
556
  : TSingleRay3D;
557
begin
558
  with Result do
559
  begin
560
    Pos := A_.MultPos(B_.Pos);
561
    Vec := A_.MultVec(B_.Vec);
562
  end
563
end;
564

565
class operator TSingleM4.Multiply(const A_: TSingleM4; const B_: TSingle4D)
566
  : TSingle4D;
567
begin
568
  with Result do
569
  begin
570
    _1 := A_._11 * B_._1 + A_._12 * B_._2 + A_._13 * B_._3 + A_._14 * B_._4;
571
    _2 := A_._21 * B_._1 + A_._22 * B_._2 + A_._23 * B_._3 + A_._24 * B_._4;
572
    _3 := A_._31 * B_._1 + A_._32 * B_._2 + A_._33 * B_._3 + A_._34 * B_._4;
573
    _4 := A_._41 * B_._1 + A_._42 * B_._2 + A_._43 * B_._3 + A_._44 * B_._4;
574
  end;
575
end;
576

577
class operator TSingleM4.Multiply(const A_: TSingle4D; const B_: TSingleM4)
578
  : TSingle4D;
579
begin
580
  with Result do
581
  begin
582
    _1 := A_._1 * B_._11 + A_._2 * B_._21 + A_._3 * B_._31 + A_._4 * B_._41;
583
    _2 := A_._1 * B_._12 + A_._2 * B_._22 + A_._3 * B_._32 + A_._4 * B_._42;
584
    _3 := A_._1 * B_._13 + A_._2 * B_._23 + A_._3 * B_._33 + A_._4 * B_._43;
585
    _4 := A_._1 * B_._14 + A_._2 * B_._24 + A_._3 * B_._34 + A_._4 * B_._44;
586
  end;
587
end;
588

589
// ------------------------------------------------------------------------------
590

591
class operator TSingleM4.Divide(const A_: TSingleM4; const B_: Single)
592
  : TSingleM4;
593
begin
594
  with A_ do
595
  begin
596
    Result._11 := _11 / B_;
597
    Result._12 := _12 / B_;
598
    Result._13 := _13 / B_;
599
    Result._14 := _14 / B_;
600
    Result._21 := _21 / B_;
601
    Result._22 := _22 / B_;
602
    Result._23 := _23 / B_;
603
    Result._24 := _24 / B_;
604
    Result._31 := _31 / B_;
605
    Result._32 := _32 / B_;
606
    Result._33 := _33 / B_;
607
    Result._34 := _34 / B_;
608
    Result._41 := _41 / B_;
609
    Result._42 := _42 / B_;
610
    Result._43 := _43 / B_;
611
    Result._44 := _44 / B_;
612
  end
613
end;
614

615
class operator TSingleM4.Implicit(const V_: Single): TSingleM4;
616
begin
617
  with Result do
618
  begin
619
    _11 := V_;
620
    _12 := 0;
621
    _13 := 0;
622
    _14 := 0;
623
    _21 := 0;
624
    _22 := V_;
625
    _23 := 0;
626
    _24 := 0;
627
    _31 := 0;
628
    _32 := 0;
629
    _33 := V_;
630
    _34 := 0;
631
    _41 := 0;
632
    _42 := 0;
633
    _43 := 0;
634
    _44 := V_;
635
  end
636
end;
637

638
class operator TSingleM4.Implicit(const V_: TMatrix3D): TSingleM4;
639
begin
640
  with Result do
641
  begin
642
    _11 := +V_.m11;
643
    _12 := +V_.m21;
644
    _13 := +V_.m31;
645
    _14 := +V_.m41;
646
    _21 := -V_.m12;
647
    _22 := -V_.m22;
648
    _23 := -V_.m32;
649
    _24 := -V_.m42;
650
    _31 := -V_.m13;
651
    _32 := -V_.m23;
652
    _33 := -V_.m33;
653
    _34 := -V_.m43;
654
    _41 := +V_.m14;
655
    _42 := +V_.m24;
656
    _43 := +V_.m34;
657
    _44 := +V_.m44;
658
  end
659
end;
660

661
class operator TSingleM4.Explicit(const V_: TSingleM4): TMatrix3D;
662
begin
663
  with Result do
664
  begin
665
    m11 := +V_._11;
666
    m21 := +V_._12;
667
    m31 := +V_._13;
668
    m41 := +V_._14;
669
    m12 := -V_._21;
670
    m22 := -V_._22;
671
    m32 := -V_._23;
672
    m42 := -V_._24;
673
    m13 := -V_._31;
674
    m23 := -V_._32;
675
    m33 := -V_._33;
676
    m43 := -V_._34;
677
    m14 := +V_._41;
678
    m24 := +V_._42;
679
    m34 := +V_._43;
680
    m44 := +V_._44;
681
  end
682
end;
683

684
class operator TSingleM4.Implicit(const V_: TSingleM3): TSingleM4;
685
begin
686
  with Result do
687
  begin
688
    _11 := V_._11;
689
    _12 := V_._12;
690
    _13 := V_._13;
691
    _14 := 0;
692
    _21 := V_._21;
693
    _22 := V_._22;
694
    _23 := V_._23;
695
    _24 := 0;
696
    _31 := V_._31;
697
    _32 := V_._32;
698
    _33 := V_._33;
699
    _34 := 0;
700
    _41 := 0;
701
    _42 := 0;
702
    _43 := 0;
703
    _44 := 1;
704
  end
705
end;
706

707
class operator TSingleM4.Explicit(const V_: TSingleM4): TSingleM3;
708
begin
709
  with Result do
710
  begin
711
    _11 := V_._11;
712
    _12 := V_._12;
713
    _13 := V_._13;
714
    _21 := V_._21;
715
    _22 := V_._22;
716
    _23 := V_._23;
717
    _31 := V_._31;
718
    _32 := V_._32;
719
    _33 := V_._33;
720
  end
721
end;
722

723
function TSingleM4.MultPos(const B_: TSingle3D): TSingle3D;
724
begin
725
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z + _14;
726
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z + _24;
727
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z + _34;
728
end;
729

730
function TSingleM4.MultVec(const B_: TSingle3D): TSingle3D;
731
begin
732
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z;
733
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z;
734
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z;
735
end;
736

737
function TSingleM4.Adjugate: TSingleM4;
738
begin
739
  Result._11 := +TSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
740
    { 21 } _22, _23, _24,
741
    { 31 } _32, _33, _34,
742
    { 41 } _42, _43, _44).Det;
743

744
  Result._21 := -TSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
745
    _21, { 22 } _23, _24, _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
746

747
  Result._31 := +TSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
748
    _21, _22, { 23 } _24, _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
749

750
  Result._41 := -TSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
751
    _21, _22, _23, { 24 }
752
    _31, _32, _33, { 34 }
753
    _41, _42, _43 { 44 } ).Det;
754

755
  Result._12 := -TSingleM3.Create( { 11 } _12, _13, _14,
756
    { 21 } { 22 } { 23 } { 24 }
757
    { 31 } _32, _33, _34,
758
    { 41 } _42, _43, _44).Det;
759

760
  Result._22 := +TSingleM3.Create(_11, { 12 } _13, _14,
761
    { 21 } { 22 } { 23 } { 24 }
762
    _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
763

764
  Result._32 := -TSingleM3.Create(_11, _12, { 13 } _14,
765
    { 21 } { 22 } { 23 } { 24 }
766
    _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
767

768
  Result._42 := +TSingleM3.Create(_11, _12, _13, { 14 }
769
    { 21 } { 22 } { 23 } { 24 }
770
    _31, _32, _33, { 34 }
771
    _41, _42, _43 { 44 } ).Det;
772

773
  Result._13 := +TSingleM3.Create( { 11 } _12, _13, _14,
774
    { 21 } _22, _23, _24,
775
    { 31 } { 32 } { 33 } { 34 }
776
    { 41 } _42, _43, _44).Det;
777

778
  Result._23 := -TSingleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
779
    { 31 } { 32 } { 33 } { 34 }
780
    _41, { 42 } _43, _44).Det;
781

782
  Result._33 := +TSingleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
783
    { 31 } { 32 } { 33 } { 34 }
784
    _41, _42, { 43 } _44).Det;
785

786
  Result._43 := -TSingleM3.Create(_11, _12, _13, { 14 }
787
    _21, _22, _23, { 24 }
788
    { 31 } { 32 } { 33 } { 34 }
789
    _41, _42, _43 { 44 } ).Det;
790

791
  Result._14 := -TSingleM3.Create( { 11 } _12, _13, _14,
792
    { 21 } _22, _23, _24,
793
    { 31 } _32, _33, _34
794
    { 41 } { 42 } { 43 } { 44 } ).Det;
795

796
  Result._24 := +TSingleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
797
    _31, { 32 } _33, _34
798
    { 41 } { 42 } { 43 } { 44 } ).Det;
799

800
  Result._34 := -TSingleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
801
    _31, _32, { 33 } _34
802
    { 41 } { 42 } { 43 } { 44 } ).Det;
803

804
  Result._44 := +TSingleM3.Create(_11, _12, _13, { 14 }
805
    _21, _22, _23, { 24 }
806
    _31, _32, _33 { 34 }
807
    { 41 } { 42 } { 43 } { 44 } ).Det;
808
end;
809

810
// ------------------------------------------------------------------------------
811

812
function TSingleM4.Transpose: TSingleM4;
813
begin
814
  Result._11 := _11;
815
  Result._12 := _21;
816
  Result._13 := _31;
817
  Result._14 := _41;
818
  Result._21 := _12;
819
  Result._22 := _22;
820
  Result._23 := _32;
821
  Result._24 := _42;
822
  Result._31 := _13;
823
  Result._32 := _23;
824
  Result._33 := _33;
825
  Result._34 := _43;
826
  Result._41 := _14;
827
  Result._42 := _24;
828
  Result._43 := _34;
829
  Result._44 := _44;
830
end;
831

832
// ------------------------------------------------------------------------------
833

834
function TSingleM4.Inverse: TSingleM4;
835
var
836
  A: TSingleM4;
837
begin
838
  A := Adjugate;
839

840
  Result := A / (_11 * A._11 + _12 * A._21 + _13 * A._31 + _14 * A._41)
841
end;
842

843
class function TSingleM4.Translate(const X_, Y_, Z_: Single): TSingleM4;
844
begin
845
  with Result do
846
  begin
847
    _11 := 1;
848
    _12 := 0;
849
    _13 := 0;
850
    _14 := X_;
851
    _21 := 0;
852
    _22 := 1;
853
    _23 := 0;
854
    _24 := Y_;
855
    _31 := 0;
856
    _32 := 0;
857
    _33 := 1;
858
    _34 := Z_;
859
    _41 := 0;
860
    _42 := 0;
861
    _43 := 0;
862
    _44 := 1;
863
  end
864
end;
865

866
class function TSingleM4.Translate(const T_: TSingle3D): TSingleM4;
867
begin
868
  with T_ do
869
    Result := Translate(X, Y, Z);
870
end;
871

872
// ------------------------------------------------------------------------------
873

874
class function TSingleM4.Scale(const X_, Y_, Z_: Single): TSingleM4;
875
begin
876
  with Result do
877
  begin
878
    _11 := X_;
879
    _12 := 0;
880
    _13 := 0;
881
    _14 := 0;
882
    _21 := 0;
883
    _22 := Y_;
884
    _23 := 0;
885
    _24 := 0;
886
    _31 := 0;
887
    _32 := 0;
888
    _33 := Z_;
889
    _34 := 0;
890
    _41 := 0;
891
    _42 := 0;
892
    _43 := 0;
893
    _44 := 1;
894
  end
895
end;
896

897
class function TSingleM4.Scale(const S_: TSingle3D): TSingleM4;
898
begin
899
  with S_ do
900
    Result := Scale(X, Y, Z);
901
end;
902

903
// ------------------------------------------------------------------------------
904

905
class function TSingleM4.RotateX(const T_: Single): TSingleM4;
906
var
907
  C, S: Single;
908
begin
909
  SinCos(T_, S, C);
910

911
  with Result do
912
  begin
913
    _11 := 1;
914
    _12 := 0;
915
    _13 := 0;
916
    _14 := 0;
917
    _21 := 0;
918
    _22 := C;
919
    _23 := -S;
920
    _24 := 0;
921
    _31 := 0;
922
    _32 := +S;
923
    _33 := C;
924
    _34 := 0;
925
    _41 := 0;
926
    _42 := 0;
927
    _43 := 0;
928
    _44 := 1;
929
  end
930
end;
931

932
class function TSingleM4.RotateY(const T_: Single): TSingleM4;
933
var
934
  C, S: Single;
935
begin
936
  SinCos(T_, S, C);
937

938
  with Result do
939
  begin
940
    _11 := C;
941
    _12 := 0;
942
    _13 := +S;
943
    _14 := 0;
944
    _21 := 0;
945
    _22 := 1;
946
    _23 := 0;
947
    _24 := 0;
948
    _31 := -S;
949
    _32 := 0;
950
    _33 := C;
951
    _34 := 0;
952
    _41 := 0;
953
    _42 := 0;
954
    _43 := 0;
955
    _44 := 1;
956
  end
957
end;
958

959
class function TSingleM4.RotateZ(const T_: Single): TSingleM4;
960
var
961
  C, S: Single;
962
begin
963
  SinCos(T_, S, C);
964

965
  with Result do
966
  begin
967
    _11 := C;
968
    _12 := -S;
969
    _13 := 0;
970
    _14 := 0;
971
    _21 := +S;
972
    _22 := C;
973
    _23 := 0;
974
    _24 := 0;
975
    _31 := 0;
976
    _32 := 0;
977
    _33 := 1;
978
    _34 := 0;
979
    _41 := 0;
980
    _42 := 0;
981
    _43 := 0;
982
    _44 := 1;
983
  end
984
end;
985

986
// ------------------------------------------------------------------------------
987

988
class function TSingleM4.Identity: TSingleM4;
989
begin
990
  with Result do
991
  begin
992
    _11 := 1;
993
    _12 := 0;
994
    _13 := 0;
995
    _14 := 0;
996
    _21 := 0;
997
    _22 := 1;
998
    _23 := 0;
999
    _24 := 0;
1000
    _31 := 0;
1001
    _32 := 0;
1002
    _33 := 1;
1003
    _34 := 0;
1004
    _41 := 0;
1005
    _42 := 0;
1006
    _43 := 0;
1007
    _44 := 1;
1008
  end
1009
end;
1010

1011
// ------------------------------------------------------------------------------
1012

1013
class function TSingleM4.ProjOrth(const L_, R_, B_, T_, N_, F_: Single)
1014
  : TSingleM4;
1015
var
1016
  RL, TB, FN: Single;
1017
begin
1018
  RL := R_ - L_;
1019
  TB := T_ - B_;
1020
  FN := F_ - N_;
1021

1022
  with Result do
1023
  begin
1024
    _11 := +2 / RL;
1025
    _12 := 0;
1026
    _13 := 0;
1027
    _14 := -(R_ + L_) / RL;
1028
    _21 := 0;
1029
    _22 := +2 / TB;
1030
    _23 := 0;
1031
    _24 := -(T_ + B_) / TB;
1032
    _31 := 0;
1033
    _32 := 0;
1034
    _33 := -2 / FN;
1035
    _34 := -(F_ + N_) / FN;
1036
    _41 := 0;
1037
    _42 := 0;
1038
    _43 := 0;
1039
    _44 := +1;
1040
  end;
1041
end;
1042

1043
class function TSingleM4.ProjPers(const L_, R_, B_, T_, N_, F_: Single)
1044
  : TSingleM4;
1045
var
1046
  RL, TB, FN: Single;
1047
begin
1048
  RL := R_ - L_;
1049
  TB := T_ - B_;
1050
  FN := F_ - N_;
1051

1052
  with Result do
1053
  begin
1054
    _11 := +2 * N_ / RL;
1055
    _12 := 0;
1056
    _13 := +(R_ + L_) / RL;
1057
    _14 := 0;
1058
    _21 := 0;
1059
    _22 := +2 * N_ / TB;
1060
    _23 := +(T_ + B_) / TB;
1061
    _24 := 0;
1062
    _31 := 0;
1063
    _32 := 0;
1064
    _33 := -(F_ + N_) / FN;
1065
    _34 := -2 * F_ * N_ / FN;
1066
    _41 := 0;
1067
    _42 := 0;
1068
    _43 := -1;
1069
    _44 := 0;
1070
  end;
1071
end;
1072

1073
function TDoubleM4.GetM(const Y_, X_: Integer): Double;
1074
begin
1075
  Result := _[Y_, X_];
1076
end;
1077

1078
procedure TDoubleM4.SetM(const Y_, X_: Integer; const M_: Double);
1079
begin
1080
  _[Y_, X_] := M_;
1081
end;
1082

1083
// ------------------------------------------------------------------------------
1084

1085
function TDoubleM4.GetAxisX: TDouble3D;
1086
begin
1087
  with Result do
1088
  begin
1089
    X := _11;
1090
    Y := _21;
1091
    Z := _31;
1092
  end
1093
end;
1094

1095
procedure TDoubleM4.SetAxisX(const AxisX_: TDouble3D);
1096
begin
1097
  with AxisX_ do
1098
  begin
1099
    _11 := X;
1100
    _21 := Y;
1101
    _31 := Z;
1102
  end
1103
end;
1104

1105
function TDoubleM4.GetAxisY: TDouble3D;
1106
begin
1107
  with Result do
1108
  begin
1109
    X := _12;
1110
    Y := _22;
1111
    Z := _32;
1112
  end
1113
end;
1114

1115
procedure TDoubleM4.SetAxisY(const AxisY_: TDouble3D);
1116
begin
1117
  with AxisY_ do
1118
  begin
1119
    _12 := X;
1120
    _22 := Y;
1121
    _32 := Z;
1122
  end
1123
end;
1124

1125
function TDoubleM4.GetAxisZ: TDouble3D;
1126
begin
1127
  with Result do
1128
  begin
1129
    X := _13;
1130
    Y := _23;
1131
    Z := _33;
1132
  end
1133
end;
1134

1135
procedure TDoubleM4.SetAxisZ(const AxisZ_: TDouble3D);
1136
begin
1137
  with AxisZ_ do
1138
  begin
1139
    _13 := X;
1140
    _23 := Y;
1141
    _33 := Z;
1142
  end
1143
end;
1144

1145
function TDoubleM4.GetAxisP: TDouble3D;
1146
begin
1147
  with Result do
1148
  begin
1149
    X := _14;
1150
    Y := _24;
1151
    Z := _34;
1152
  end
1153
end;
1154

1155
procedure TDoubleM4.SetAxisP(const AxisP_: TDouble3D);
1156
begin
1157
  with AxisP_ do
1158
  begin
1159
    _14 := X;
1160
    _24 := Y;
1161
    _34 := Z;
1162
  end
1163
end;
1164

1165
constructor TDoubleM4.Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_,
1166
  _24_, _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: Double);
1167
begin
1168
  _11 := _11_;
1169
  _12 := _12_;
1170
  _13 := _13_;
1171
  _14 := _14_;
1172
  _21 := _21_;
1173
  _22 := _22_;
1174
  _23 := _23_;
1175
  _24 := _24_;
1176
  _31 := _31_;
1177
  _32 := _32_;
1178
  _33 := _33_;
1179
  _34 := _34_;
1180
  _41 := _41_;
1181
  _42 := _42_;
1182
  _43 := _43_;
1183
  _44 := _44_;
1184
end;
1185

1186
constructor TDoubleM4.Create(const X_, Y_, Z_, P_: TDouble3D);
1187
begin
1188
  _11 := X_.X;
1189
  _12 := Y_.X;
1190
  _13 := Z_.X;
1191
  _14 := P_.X;
1192
  _21 := X_.Y;
1193
  _22 := Y_.Y;
1194
  _23 := Z_.Y;
1195
  _24 := P_.Y;
1196
  _31 := X_.Z;
1197
  _32 := Y_.Z;
1198
  _33 := Z_.Z;
1199
  _34 := P_.Z;
1200
  _41 := 0;
1201
  _42 := 0;
1202
  _43 := 0;
1203
  _44 := 1;
1204
end;
1205

1206
class operator TDoubleM4.Multiply(const A_, B_: TDoubleM4): TDoubleM4;
1207
begin
1208
  with Result do
1209
  begin
1210
    _11 := A_._11 * B_._11 + A_._12 * B_._21 + A_._13 * B_._31 + A_._14
1211
      * B_._41;
1212
    _12 := A_._11 * B_._12 + A_._12 * B_._22 + A_._13 * B_._32 + A_._14
1213
      * B_._42;
1214
    _13 := A_._11 * B_._13 + A_._12 * B_._23 + A_._13 * B_._33 + A_._14
1215
      * B_._43;
1216
    _14 := A_._11 * B_._14 + A_._12 * B_._24 + A_._13 * B_._34 + A_._14
1217
      * B_._44;
1218

1219
    _21 := A_._21 * B_._11 + A_._22 * B_._21 + A_._23 * B_._31 + A_._24
1220
      * B_._41;
1221
    _22 := A_._21 * B_._12 + A_._22 * B_._22 + A_._23 * B_._32 + A_._24
1222
      * B_._42;
1223
    _23 := A_._21 * B_._13 + A_._22 * B_._23 + A_._23 * B_._33 + A_._24
1224
      * B_._43;
1225
    _24 := A_._21 * B_._14 + A_._22 * B_._24 + A_._23 * B_._34 + A_._24
1226
      * B_._44;
1227

1228
    _31 := A_._31 * B_._11 + A_._32 * B_._21 + A_._33 * B_._31 + A_._34
1229
      * B_._41;
1230
    _32 := A_._31 * B_._12 + A_._32 * B_._22 + A_._33 * B_._32 + A_._34
1231
      * B_._42;
1232
    _33 := A_._31 * B_._13 + A_._32 * B_._23 + A_._33 * B_._33 + A_._34
1233
      * B_._43;
1234
    _34 := A_._31 * B_._14 + A_._32 * B_._24 + A_._33 * B_._34 + A_._34
1235
      * B_._44;
1236

1237
    _41 := A_._41 * B_._11 + A_._42 * B_._21 + A_._43 * B_._31 + A_._44
1238
      * B_._41;
1239
    _42 := A_._41 * B_._12 + A_._42 * B_._22 + A_._43 * B_._32 + A_._44
1240
      * B_._42;
1241
    _43 := A_._41 * B_._13 + A_._42 * B_._23 + A_._43 * B_._33 + A_._44
1242
      * B_._43;
1243
    _44 := A_._41 * B_._14 + A_._42 * B_._24 + A_._43 * B_._34 + A_._44
1244
      * B_._44;
1245
  end
1246
end;
1247

1248
class operator TDoubleM4.Multiply(const A_: Double; const B_: TDoubleM4)
1249
  : TDoubleM4;
1250
begin
1251
  with Result do
1252
  begin
1253
    _11 := A_ * B_._11;
1254
    _12 := A_ * B_._12;
1255
    _13 := A_ * B_._13;
1256
    _14 := A_ * B_._14;
1257
    _21 := A_ * B_._21;
1258
    _22 := A_ * B_._22;
1259
    _23 := A_ * B_._23;
1260
    _24 := A_ * B_._24;
1261
    _31 := A_ * B_._31;
1262
    _32 := A_ * B_._32;
1263
    _33 := A_ * B_._33;
1264
    _34 := A_ * B_._34;
1265
    _41 := A_ * B_._41;
1266
    _42 := A_ * B_._42;
1267
    _43 := A_ * B_._43;
1268
    _44 := A_ * B_._44;
1269
  end
1270
end;
1271

1272
class operator TDoubleM4.Multiply(const A_: TDoubleM4; const B_: Double)
1273
  : TDoubleM4;
1274
begin
1275
  with Result do
1276
  begin
1277
    _11 := A_._11 * B_;
1278
    _12 := A_._12 * B_;
1279
    _13 := A_._13 * B_;
1280
    _14 := A_._14 * B_;
1281
    _21 := A_._21 * B_;
1282
    _22 := A_._22 * B_;
1283
    _23 := A_._23 * B_;
1284
    _24 := A_._24 * B_;
1285
    _31 := A_._31 * B_;
1286
    _32 := A_._32 * B_;
1287
    _33 := A_._33 * B_;
1288
    _34 := A_._34 * B_;
1289
    _41 := A_._41 * B_;
1290
    _42 := A_._42 * B_;
1291
    _43 := A_._43 * B_;
1292
    _44 := A_._44 * B_;
1293
  end
1294
end;
1295

1296
class operator TDoubleM4.Multiply(const A_: TDoubleM4; const B_: TDoubleRay3D)
1297
  : TDoubleRay3D;
1298
begin
1299
  with Result do
1300
  begin
1301
    Pos := A_.MultPos(B_.Pos);
1302
    Vec := A_.MultVec(B_.Vec);
1303
  end
1304
end;
1305

1306
class operator TDoubleM4.Multiply(const A_: TDoubleM4; const B_: TDouble4D)
1307
  : TDouble4D;
1308
begin
1309
  with Result do
1310
  begin
1311
    _1 := A_._11 * B_._1 + A_._12 * B_._2 + A_._13 * B_._3 + A_._14 * B_._4;
1312
    _2 := A_._21 * B_._1 + A_._22 * B_._2 + A_._23 * B_._3 + A_._24 * B_._4;
1313
    _3 := A_._31 * B_._1 + A_._32 * B_._2 + A_._33 * B_._3 + A_._34 * B_._4;
1314
    _4 := A_._41 * B_._1 + A_._42 * B_._2 + A_._43 * B_._3 + A_._44 * B_._4;
1315
  end;
1316
end;
1317

1318
class operator TDoubleM4.Multiply(const A_: TDouble4D; const B_: TDoubleM4)
1319
  : TDouble4D;
1320
begin
1321
  with Result do
1322
  begin
1323
    _1 := A_._1 * B_._11 + A_._2 * B_._21 + A_._3 * B_._31 + A_._4 * B_._41;
1324
    _2 := A_._1 * B_._12 + A_._2 * B_._22 + A_._3 * B_._32 + A_._4 * B_._42;
1325
    _3 := A_._1 * B_._13 + A_._2 * B_._23 + A_._3 * B_._33 + A_._4 * B_._43;
1326
    _4 := A_._1 * B_._14 + A_._2 * B_._24 + A_._3 * B_._34 + A_._4 * B_._44;
1327
  end;
1328
end;
1329

1330
class operator TDoubleM4.Divide(const A_: TDoubleM4; const B_: Double)
1331
  : TDoubleM4;
1332
begin
1333
  with A_ do
1334
  begin
1335
    Result._11 := _11 / B_;
1336
    Result._12 := _12 / B_;
1337
    Result._13 := _13 / B_;
1338
    Result._14 := _14 / B_;
1339
    Result._21 := _21 / B_;
1340
    Result._22 := _22 / B_;
1341
    Result._23 := _23 / B_;
1342
    Result._24 := _24 / B_;
1343
    Result._31 := _31 / B_;
1344
    Result._32 := _32 / B_;
1345
    Result._33 := _33 / B_;
1346
    Result._34 := _34 / B_;
1347
    Result._41 := _41 / B_;
1348
    Result._42 := _42 / B_;
1349
    Result._43 := _43 / B_;
1350
    Result._44 := _44 / B_;
1351
  end
1352
end;
1353

1354
class operator TDoubleM4.Implicit(const V_: Double): TDoubleM4;
1355
begin
1356
  with Result do
1357
  begin
1358
    _11 := V_;
1359
    _12 := 0;
1360
    _13 := 0;
1361
    _14 := 0;
1362
    _21 := 0;
1363
    _22 := V_;
1364
    _23 := 0;
1365
    _24 := 0;
1366
    _31 := 0;
1367
    _32 := 0;
1368
    _33 := V_;
1369
    _34 := 0;
1370
    _41 := 0;
1371
    _42 := 0;
1372
    _43 := 0;
1373
    _44 := V_;
1374
  end
1375
end;
1376

1377
class operator TDoubleM4.Implicit(const V_: TMatrix3D): TDoubleM4;
1378
begin
1379
  with Result do
1380
  begin
1381
    _11 := +V_.m11;
1382
    _12 := +V_.m21;
1383
    _13 := +V_.m31;
1384
    _14 := +V_.m41;
1385
    _21 := -V_.m12;
1386
    _22 := -V_.m22;
1387
    _23 := -V_.m32;
1388
    _24 := -V_.m42;
1389
    _31 := -V_.m13;
1390
    _32 := -V_.m23;
1391
    _33 := -V_.m33;
1392
    _34 := -V_.m43;
1393
    _41 := +V_.m14;
1394
    _42 := +V_.m24;
1395
    _43 := +V_.m34;
1396
    _44 := +V_.m44;
1397
  end
1398
end;
1399

1400
class operator TDoubleM4.Explicit(const V_: TDoubleM4): TMatrix3D;
1401
begin
1402
  with Result do
1403
  begin
1404
    m11 := +V_._11;
1405
    m21 := +V_._12;
1406
    m31 := +V_._13;
1407
    m41 := +V_._14;
1408
    m12 := -V_._21;
1409
    m22 := -V_._22;
1410
    m32 := -V_._23;
1411
    m42 := -V_._24;
1412
    m13 := -V_._31;
1413
    m23 := -V_._32;
1414
    m33 := -V_._33;
1415
    m43 := -V_._34;
1416
    m14 := +V_._41;
1417
    m24 := +V_._42;
1418
    m34 := +V_._43;
1419
    m44 := +V_._44;
1420
  end
1421
end;
1422

1423
class operator TDoubleM4.Implicit(const V_: TSingleM4): TDoubleM4;
1424
begin
1425
  with Result do
1426
  begin
1427
    _11 := V_._11;
1428
    _12 := V_._12;
1429
    _13 := V_._13;
1430
    _14 := V_._14;
1431
    _21 := V_._21;
1432
    _22 := V_._22;
1433
    _23 := V_._23;
1434
    _24 := V_._24;
1435
    _31 := V_._31;
1436
    _32 := V_._32;
1437
    _33 := V_._33;
1438
    _34 := V_._34;
1439
    _41 := V_._41;
1440
    _42 := V_._42;
1441
    _43 := V_._43;
1442
    _44 := V_._44;
1443
  end
1444
end;
1445

1446
class operator TDoubleM4.Explicit(const V_: TDoubleM4): TSingleM4;
1447
begin
1448
  with Result do
1449
  begin
1450
    _11 := V_._11;
1451
    _12 := V_._12;
1452
    _13 := V_._13;
1453
    _14 := V_._14;
1454
    _21 := V_._21;
1455
    _22 := V_._22;
1456
    _23 := V_._23;
1457
    _24 := V_._24;
1458
    _31 := V_._31;
1459
    _32 := V_._32;
1460
    _33 := V_._33;
1461
    _34 := V_._34;
1462
    _41 := V_._41;
1463
    _42 := V_._42;
1464
    _43 := V_._43;
1465
    _44 := V_._44;
1466
  end
1467
end;
1468

1469
class operator TDoubleM4.Implicit(const V_: TDoubleM3): TDoubleM4;
1470
begin
1471
  with Result do
1472
  begin
1473
    _11 := V_._11;
1474
    _12 := V_._12;
1475
    _13 := V_._13;
1476
    _14 := 0;
1477
    _21 := V_._21;
1478
    _22 := V_._22;
1479
    _23 := V_._23;
1480
    _24 := 0;
1481
    _31 := V_._31;
1482
    _32 := V_._32;
1483
    _33 := V_._33;
1484
    _34 := 0;
1485
    _41 := 0;
1486
    _42 := 0;
1487
    _43 := 0;
1488
    _44 := 1;
1489
  end
1490
end;
1491

1492
class operator TDoubleM4.Explicit(const V_: TDoubleM4): TDoubleM3;
1493
begin
1494
  with Result do
1495
  begin
1496
    _11 := V_._11;
1497
    _12 := V_._12;
1498
    _13 := V_._13;
1499
    _21 := V_._21;
1500
    _22 := V_._22;
1501
    _23 := V_._23;
1502
    _31 := V_._31;
1503
    _32 := V_._32;
1504
    _33 := V_._33;
1505
  end
1506
end;
1507

1508
function TDoubleM4.MultPos(const B_: TDouble3D): TDouble3D;
1509
begin
1510
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z + _14;
1511
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z + _24;
1512
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z + _34;
1513
end;
1514

1515
function TDoubleM4.MultVec(const B_: TDouble3D): TDouble3D;
1516
begin
1517
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z;
1518
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z;
1519
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z;
1520
end;
1521

1522
function TDoubleM4.Adjugate: TDoubleM4;
1523
begin
1524
  Result._11 := +TDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
1525
    { 21 } _22, _23, _24,
1526
    { 31 } _32, _33, _34,
1527
    { 41 } _42, _43, _44).Det;
1528

1529
  Result._21 := -TDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
1530
    _21, { 22 } _23, _24, _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
1531

1532
  Result._31 := +TDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
1533
    _21, _22, { 23 } _24, _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
1534

1535
  Result._41 := -TDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
1536
    _21, _22, _23, { 24 }
1537
    _31, _32, _33, { 34 }
1538
    _41, _42, _43 { 44 } ).Det;
1539

1540
  Result._12 := -TDoubleM3.Create( { 11 } _12, _13, _14,
1541
    { 21 } { 22 } { 23 } { 24 }
1542
    { 31 } _32, _33, _34,
1543
    { 41 } _42, _43, _44).Det;
1544

1545
  Result._22 := +TDoubleM3.Create(_11, { 12 } _13, _14,
1546
    { 21 } { 22 } { 23 } { 24 }
1547
    _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
1548

1549
  Result._32 := -TDoubleM3.Create(_11, _12, { 13 } _14,
1550
    { 21 } { 22 } { 23 } { 24 }
1551
    _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
1552

1553
  Result._42 := +TDoubleM3.Create(_11, _12, _13, { 14 }
1554
    { 21 } { 22 } { 23 } { 24 }
1555
    _31, _32, _33, { 34 }
1556
    _41, _42, _43 { 44 } ).Det;
1557

1558
  Result._13 := +TDoubleM3.Create( { 11 } _12, _13, _14,
1559
    { 21 } _22, _23, _24,
1560
    { 31 } { 32 } { 33 } { 34 }
1561
    { 41 } _42, _43, _44).Det;
1562

1563
  Result._23 := -TDoubleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
1564
    { 31 } { 32 } { 33 } { 34 }
1565
    _41, { 42 } _43, _44).Det;
1566

1567
  Result._33 := +TDoubleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
1568
    { 31 } { 32 } { 33 } { 34 }
1569
    _41, _42, { 43 } _44).Det;
1570

1571
  Result._43 := -TDoubleM3.Create(_11, _12, _13, { 14 }
1572
    _21, _22, _23, { 24 }
1573
    { 31 } { 32 } { 33 } { 34 }
1574
    _41, _42, _43 { 44 } ).Det;
1575

1576
  Result._14 := -TDoubleM3.Create( { 11 } _12, _13, _14,
1577
    { 21 } _22, _23, _24,
1578
    { 31 } _32, _33, _34
1579
    { 41 } { 42 } { 43 } { 44 } ).Det;
1580

1581
  Result._24 := +TDoubleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
1582
    _31, { 32 } _33, _34
1583
    { 41 } { 42 } { 43 } { 44 } ).Det;
1584

1585
  Result._34 := -TDoubleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
1586
    _31, _32, { 33 } _34
1587
    { 41 } { 42 } { 43 } { 44 } ).Det;
1588

1589
  Result._44 := +TDoubleM3.Create(_11, _12, _13, { 14 }
1590
    _21, _22, _23, { 24 }
1591
    _31, _32, _33 { 34 }
1592
    { 41 } { 42 } { 43 } { 44 } ).Det;
1593
end;
1594

1595
function TDoubleM4.Transpose: TDoubleM4;
1596
begin
1597
  Result._11 := _11;
1598
  Result._12 := _21;
1599
  Result._13 := _31;
1600
  Result._14 := _41;
1601
  Result._21 := _12;
1602
  Result._22 := _22;
1603
  Result._23 := _32;
1604
  Result._24 := _42;
1605
  Result._31 := _13;
1606
  Result._32 := _23;
1607
  Result._33 := _33;
1608
  Result._34 := _43;
1609
  Result._41 := _14;
1610
  Result._42 := _24;
1611
  Result._43 := _34;
1612
  Result._44 := _44;
1613
end;
1614

1615
function TDoubleM4.Inverse: TDoubleM4;
1616
var
1617
  A: TDoubleM4;
1618
begin
1619
  A := Adjugate;
1620

1621
  Result := A / (_11 * A._11 + _12 * A._21 + _13 * A._31 + _14 * A._41)
1622
end;
1623

1624
class function TDoubleM4.Translate(const X_, Y_, Z_: Double): TDoubleM4;
1625
begin
1626
  with Result do
1627
  begin
1628
    _11 := 1;
1629
    _12 := 0;
1630
    _13 := 0;
1631
    _14 := X_;
1632
    _21 := 0;
1633
    _22 := 1;
1634
    _23 := 0;
1635
    _24 := Y_;
1636
    _31 := 0;
1637
    _32 := 0;
1638
    _33 := 1;
1639
    _34 := Z_;
1640
    _41 := 0;
1641
    _42 := 0;
1642
    _43 := 0;
1643
    _44 := 1;
1644
  end
1645
end;
1646

1647
class function TDoubleM4.Translate(const T_: TDouble3D): TDoubleM4;
1648
begin
1649
  with T_ do
1650
    Result := Translate(X, Y, Z);
1651
end;
1652

1653
// ------------------------------------------------------------------------------
1654

1655
class function TDoubleM4.Scale(const X_, Y_, Z_: Double): TDoubleM4;
1656
begin
1657
  with Result do
1658
  begin
1659
    _11 := X_;
1660
    _12 := 0;
1661
    _13 := 0;
1662
    _14 := 0;
1663
    _21 := 0;
1664
    _22 := Y_;
1665
    _23 := 0;
1666
    _24 := 0;
1667
    _31 := 0;
1668
    _32 := 0;
1669
    _33 := Z_;
1670
    _34 := 0;
1671
    _41 := 0;
1672
    _42 := 0;
1673
    _43 := 0;
1674
    _44 := 1;
1675
  end
1676
end;
1677

1678
class function TDoubleM4.Scale(const S_: TDouble3D): TDoubleM4;
1679
begin
1680
  with S_ do
1681
    Result := Scale(X, Y, Z);
1682
end;
1683

1684
// ------------------------------------------------------------------------------
1685

1686
class function TDoubleM4.RotateX(const T_: Double): TDoubleM4;
1687
var
1688
  C, S: Double;
1689
begin
1690
  SinCos(T_, S, C);
1691

1692
  with Result do
1693
  begin
1694
    _11 := 1;
1695
    _12 := 0;
1696
    _13 := 0;
1697
    _14 := 0;
1698
    _21 := 0;
1699
    _22 := C;
1700
    _23 := -S;
1701
    _24 := 0;
1702
    _31 := 0;
1703
    _32 := +S;
1704
    _33 := C;
1705
    _34 := 0;
1706
    _41 := 0;
1707
    _42 := 0;
1708
    _43 := 0;
1709
    _44 := 1;
1710
  end
1711
end;
1712

1713
class function TDoubleM4.RotateY(const T_: Double): TDoubleM4;
1714
var
1715
  C, S: Double;
1716
begin
1717
  SinCos(T_, S, C);
1718

1719
  with Result do
1720
  begin
1721
    _11 := C;
1722
    _12 := 0;
1723
    _13 := +S;
1724
    _14 := 0;
1725
    _21 := 0;
1726
    _22 := 1;
1727
    _23 := 0;
1728
    _24 := 0;
1729
    _31 := -S;
1730
    _32 := 0;
1731
    _33 := C;
1732
    _34 := 0;
1733
    _41 := 0;
1734
    _42 := 0;
1735
    _43 := 0;
1736
    _44 := 1;
1737
  end
1738
end;
1739

1740
class function TDoubleM4.RotateZ(const T_: Double): TDoubleM4;
1741
var
1742
  C, S: Double;
1743
begin
1744
  SinCos(T_, S, C);
1745

1746
  with Result do
1747
  begin
1748
    _11 := C;
1749
    _12 := -S;
1750
    _13 := 0;
1751
    _14 := 0;
1752
    _21 := +S;
1753
    _22 := C;
1754
    _23 := 0;
1755
    _24 := 0;
1756
    _31 := 0;
1757
    _32 := 0;
1758
    _33 := 1;
1759
    _34 := 0;
1760
    _41 := 0;
1761
    _42 := 0;
1762
    _43 := 0;
1763
    _44 := 1;
1764
  end
1765
end;
1766

1767
// ------------------------------------------------------------------------------
1768

1769
class function TDoubleM4.Identity: TDoubleM4;
1770
begin
1771
  with Result do
1772
  begin
1773
    _11 := 1;
1774
    _12 := 0;
1775
    _13 := 0;
1776
    _14 := 0;
1777
    _21 := 0;
1778
    _22 := 1;
1779
    _23 := 0;
1780
    _24 := 0;
1781
    _31 := 0;
1782
    _32 := 0;
1783
    _33 := 1;
1784
    _34 := 0;
1785
    _41 := 0;
1786
    _42 := 0;
1787
    _43 := 0;
1788
    _44 := 1;
1789
  end
1790
end;
1791

1792
// ------------------------------------------------------------------------------
1793

1794
class function TDoubleM4.ProjOrth(const L_, R_, B_, T_, N_, F_: Double)
1795
  : TDoubleM4;
1796
var
1797
  RL, TB, FN: Double;
1798
begin
1799
  RL := R_ - L_;
1800
  TB := T_ - B_;
1801
  FN := F_ - N_;
1802

1803
  with Result do
1804
  begin
1805
    _11 := +2 / RL;
1806
    _12 := 0;
1807
    _13 := 0;
1808
    _14 := -(R_ + L_) / RL;
1809
    _21 := 0;
1810
    _22 := +2 / TB;
1811
    _23 := 0;
1812
    _24 := -(T_ + B_) / TB;
1813
    _31 := 0;
1814
    _32 := 0;
1815
    _33 := -2 / FN;
1816
    _34 := -(F_ + N_) / FN;
1817
    _41 := 0;
1818
    _42 := 0;
1819
    _43 := 0;
1820
    _44 := +1;
1821
  end;
1822
end;
1823

1824
class function TDoubleM4.ProjPers(const L_, R_, B_, T_, N_, F_: Double)
1825
  : TDoubleM4;
1826
var
1827
  RL, TB, FN: Double;
1828
begin
1829
  RL := R_ - L_;
1830
  TB := T_ - B_;
1831
  FN := F_ - N_;
1832

1833
  with Result do
1834
  begin
1835
    _11 := +2 * N_ / RL;
1836
    _12 := 0;
1837
    _13 := +(R_ + L_) / RL;
1838
    _14 := 0;
1839
    _21 := 0;
1840
    _22 := +2 * N_ / TB;
1841
    _23 := +(T_ + B_) / TB;
1842
    _24 := 0;
1843
    _31 := 0;
1844
    _32 := 0;
1845
    _33 := -(F_ + N_) / FN;
1846
    _34 := -2 * F_ * N_ / FN;
1847
    _41 := 0;
1848
    _42 := 0;
1849
    _43 := -1;
1850
    _44 := 0;
1851
  end;
1852
end;
1853

1854
function TdSingleM4.GetM(const Y_, X_: Integer): TdSingle;
1855
begin
1856
  Result := _[Y_, X_];
1857
end;
1858

1859
procedure TdSingleM4.SetM(const Y_, X_: Integer; const M_: TdSingle);
1860
begin
1861
  _[Y_, X_] := M_;
1862
end;
1863

1864
// ------------------------------------------------------------------------------
1865

1866
function TdSingleM4.GetAxisX: TdSingle3D;
1867
begin
1868
  with Result do
1869
  begin
1870
    X := _11;
1871
    Y := _21;
1872
    Z := _31;
1873
  end
1874
end;
1875

1876
procedure TdSingleM4.SetAxisX(const AxisX_: TdSingle3D);
1877
begin
1878
  with AxisX_ do
1879
  begin
1880
    _11 := X;
1881
    _21 := Y;
1882
    _31 := Z;
1883
  end
1884
end;
1885

1886
function TdSingleM4.GetAxisY: TdSingle3D;
1887
begin
1888
  with Result do
1889
  begin
1890
    X := _12;
1891
    Y := _22;
1892
    Z := _32;
1893
  end
1894
end;
1895

1896
procedure TdSingleM4.SetAxisY(const AxisY_: TdSingle3D);
1897
begin
1898
  with AxisY_ do
1899
  begin
1900
    _12 := X;
1901
    _22 := Y;
1902
    _32 := Z;
1903
  end
1904
end;
1905

1906
function TdSingleM4.GetAxisZ: TdSingle3D;
1907
begin
1908
  with Result do
1909
  begin
1910
    X := _13;
1911
    Y := _23;
1912
    Z := _33;
1913
  end
1914
end;
1915

1916
procedure TdSingleM4.SetAxisZ(const AxisZ_: TdSingle3D);
1917
begin
1918
  with AxisZ_ do
1919
  begin
1920
    _13 := X;
1921
    _23 := Y;
1922
    _33 := Z;
1923
  end
1924
end;
1925

1926
function TdSingleM4.GetAxisP: TdSingle3D;
1927
begin
1928
  with Result do
1929
  begin
1930
    X := _14;
1931
    Y := _24;
1932
    Z := _34;
1933
  end
1934
end;
1935

1936
procedure TdSingleM4.SetAxisP(const AxisP_: TdSingle3D);
1937
begin
1938
  with AxisP_ do
1939
  begin
1940
    _14 := X;
1941
    _24 := Y;
1942
    _34 := Z;
1943
  end
1944
end;
1945

1946
constructor TdSingleM4.Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_,
1947
  _24_, _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: TdSingle);
1948
begin
1949
  _11 := _11_;
1950
  _12 := _12_;
1951
  _13 := _13_;
1952
  _14 := _14_;
1953
  _21 := _21_;
1954
  _22 := _22_;
1955
  _23 := _23_;
1956
  _24 := _24_;
1957
  _31 := _31_;
1958
  _32 := _32_;
1959
  _33 := _33_;
1960
  _34 := _34_;
1961
  _41 := _41_;
1962
  _42 := _42_;
1963
  _43 := _43_;
1964
  _44 := _44_;
1965
end;
1966

1967
constructor TdSingleM4.Create(const X_, Y_, Z_: TdSingle3D;
1968
  const P_: TdSingle3D);
1969
begin
1970
  _11 := X_.X;
1971
  _12 := Y_.X;
1972
  _13 := Z_.X;
1973
  _14 := P_.X;
1974
  _21 := X_.Y;
1975
  _22 := Y_.Y;
1976
  _23 := Z_.Y;
1977
  _24 := P_.Y;
1978
  _31 := X_.Z;
1979
  _32 := Y_.Z;
1980
  _33 := Z_.Z;
1981
  _34 := P_.Z;
1982
  _41 := 0;
1983
  _42 := 0;
1984
  _43 := 0;
1985
  _44 := 1;
1986
end;
1987

1988
class operator TdSingleM4.Multiply(const A_, B_: TdSingleM4): TdSingleM4;
1989
begin
1990
  with Result do
1991
  begin
1992
    _11 := A_._11 * B_._11 + A_._12 * B_._21 + A_._13 * B_._31 + A_._14
1993
      * B_._41;
1994
    _12 := A_._11 * B_._12 + A_._12 * B_._22 + A_._13 * B_._32 + A_._14
1995
      * B_._42;
1996
    _13 := A_._11 * B_._13 + A_._12 * B_._23 + A_._13 * B_._33 + A_._14
1997
      * B_._43;
1998
    _14 := A_._11 * B_._14 + A_._12 * B_._24 + A_._13 * B_._34 + A_._14
1999
      * B_._44;
2000

2001
    _21 := A_._21 * B_._11 + A_._22 * B_._21 + A_._23 * B_._31 + A_._24
2002
      * B_._41;
2003
    _22 := A_._21 * B_._12 + A_._22 * B_._22 + A_._23 * B_._32 + A_._24
2004
      * B_._42;
2005
    _23 := A_._21 * B_._13 + A_._22 * B_._23 + A_._23 * B_._33 + A_._24
2006
      * B_._43;
2007
    _24 := A_._21 * B_._14 + A_._22 * B_._24 + A_._23 * B_._34 + A_._24
2008
      * B_._44;
2009

2010
    _31 := A_._31 * B_._11 + A_._32 * B_._21 + A_._33 * B_._31 + A_._34
2011
      * B_._41;
2012
    _32 := A_._31 * B_._12 + A_._32 * B_._22 + A_._33 * B_._32 + A_._34
2013
      * B_._42;
2014
    _33 := A_._31 * B_._13 + A_._32 * B_._23 + A_._33 * B_._33 + A_._34
2015
      * B_._43;
2016
    _34 := A_._31 * B_._14 + A_._32 * B_._24 + A_._33 * B_._34 + A_._34
2017
      * B_._44;
2018

2019
    _41 := A_._41 * B_._11 + A_._42 * B_._21 + A_._43 * B_._31 + A_._44
2020
      * B_._41;
2021
    _42 := A_._41 * B_._12 + A_._42 * B_._22 + A_._43 * B_._32 + A_._44
2022
      * B_._42;
2023
    _43 := A_._41 * B_._13 + A_._42 * B_._23 + A_._43 * B_._33 + A_._44
2024
      * B_._43;
2025
    _44 := A_._41 * B_._14 + A_._42 * B_._24 + A_._43 * B_._34 + A_._44
2026
      * B_._44;
2027
  end
2028
end;
2029

2030
class operator TdSingleM4.Multiply(const A_: TdSingle; const B_: TdSingleM4)
2031
  : TdSingleM4;
2032
begin
2033
  with Result do
2034
  begin
2035
    _11 := A_ * B_._11;
2036
    _12 := A_ * B_._12;
2037
    _13 := A_ * B_._13;
2038
    _14 := A_ * B_._14;
2039
    _21 := A_ * B_._21;
2040
    _22 := A_ * B_._22;
2041
    _23 := A_ * B_._23;
2042
    _24 := A_ * B_._24;
2043
    _31 := A_ * B_._31;
2044
    _32 := A_ * B_._32;
2045
    _33 := A_ * B_._33;
2046
    _34 := A_ * B_._34;
2047
    _41 := A_ * B_._41;
2048
    _42 := A_ * B_._42;
2049
    _43 := A_ * B_._43;
2050
    _44 := A_ * B_._44;
2051
  end
2052
end;
2053

2054
class operator TdSingleM4.Multiply(const A_: TdSingleM4; const B_: TdSingle)
2055
  : TdSingleM4;
2056
begin
2057
  with Result do
2058
  begin
2059
    _11 := A_._11 * B_;
2060
    _12 := A_._12 * B_;
2061
    _13 := A_._13 * B_;
2062
    _14 := A_._14 * B_;
2063
    _21 := A_._21 * B_;
2064
    _22 := A_._22 * B_;
2065
    _23 := A_._23 * B_;
2066
    _24 := A_._24 * B_;
2067
    _31 := A_._31 * B_;
2068
    _32 := A_._32 * B_;
2069
    _33 := A_._33 * B_;
2070
    _34 := A_._34 * B_;
2071
    _41 := A_._41 * B_;
2072
    _42 := A_._42 * B_;
2073
    _43 := A_._43 * B_;
2074
    _44 := A_._44 * B_;
2075
  end
2076
end;
2077

2078
class operator TdSingleM4.Multiply(const A_: TdSingleM4; const B_: TdSingle4D)
2079
  : TdSingle4D;
2080
begin
2081
  with Result do
2082
  begin
2083
    _1 := A_._11 * B_._1 + A_._12 * B_._2 + A_._13 * B_._3 + A_._14 * B_._4;
2084
    _2 := A_._21 * B_._1 + A_._22 * B_._2 + A_._23 * B_._3 + A_._24 * B_._4;
2085
    _3 := A_._31 * B_._1 + A_._32 * B_._2 + A_._33 * B_._3 + A_._34 * B_._4;
2086
    _4 := A_._41 * B_._1 + A_._42 * B_._2 + A_._43 * B_._3 + A_._44 * B_._4;
2087
  end;
2088
end;
2089

2090
class operator TdSingleM4.Multiply(const A_: TdSingle4D; const B_: TdSingleM4)
2091
  : TdSingle4D;
2092
begin
2093
  with Result do
2094
  begin
2095
    _1 := A_._1 * B_._11 + A_._2 * B_._21 + A_._3 * B_._31 + A_._4 * B_._41;
2096
    _2 := A_._1 * B_._12 + A_._2 * B_._22 + A_._3 * B_._32 + A_._4 * B_._42;
2097
    _3 := A_._1 * B_._13 + A_._2 * B_._23 + A_._3 * B_._33 + A_._4 * B_._43;
2098
    _4 := A_._1 * B_._14 + A_._2 * B_._24 + A_._3 * B_._34 + A_._4 * B_._44;
2099
  end;
2100
end;
2101

2102
class operator TdSingleM4.Divide(const A_: TdSingleM4; const B_: TdSingle)
2103
  : TdSingleM4;
2104
begin
2105
  with A_ do
2106
  begin
2107
    Result._11 := _11 / B_;
2108
    Result._12 := _12 / B_;
2109
    Result._13 := _13 / B_;
2110
    Result._14 := _14 / B_;
2111
    Result._21 := _21 / B_;
2112
    Result._22 := _22 / B_;
2113
    Result._23 := _23 / B_;
2114
    Result._24 := _24 / B_;
2115
    Result._31 := _31 / B_;
2116
    Result._32 := _32 / B_;
2117
    Result._33 := _33 / B_;
2118
    Result._34 := _34 / B_;
2119
    Result._41 := _41 / B_;
2120
    Result._42 := _42 / B_;
2121
    Result._43 := _43 / B_;
2122
    Result._44 := _44 / B_;
2123
  end
2124
end;
2125

2126
class operator TdSingleM4.Implicit(const V_: TdSingle): TdSingleM4;
2127
begin
2128
  with Result do
2129
  begin
2130
    _11 := V_;
2131
    _12 := 0;
2132
    _13 := 0;
2133
    _14 := 0;
2134
    _21 := 0;
2135
    _22 := V_;
2136
    _23 := 0;
2137
    _24 := 0;
2138
    _31 := 0;
2139
    _32 := 0;
2140
    _33 := V_;
2141
    _34 := 0;
2142
    _41 := 0;
2143
    _42 := 0;
2144
    _43 := 0;
2145
    _44 := V_;
2146
  end
2147
end;
2148

2149
class operator TdSingleM4.Implicit(const V_: TMatrix3D): TdSingleM4;
2150
begin
2151
  with Result do
2152
  begin
2153
    _11 := +V_.m11;
2154
    _12 := +V_.m21;
2155
    _13 := +V_.m31;
2156
    _14 := +V_.m41;
2157
    _21 := -V_.m12;
2158
    _22 := -V_.m22;
2159
    _23 := -V_.m32;
2160
    _24 := -V_.m42;
2161
    _31 := -V_.m13;
2162
    _32 := -V_.m23;
2163
    _33 := -V_.m33;
2164
    _34 := -V_.m43;
2165
    _41 := +V_.m14;
2166
    _42 := +V_.m24;
2167
    _43 := +V_.m34;
2168
    _44 := +V_.m44;
2169
  end
2170
end;
2171

2172
class operator TdSingleM4.Explicit(const V_: TdSingleM4): TMatrix3D;
2173
begin
2174
  with Result do
2175
  begin
2176
    m11 := +V_._11.o;
2177
    m21 := +V_._12.o;
2178
    m31 := +V_._13.o;
2179
    m41 := +V_._14.o;
2180
    m12 := -V_._21.o;
2181
    m22 := -V_._22.o;
2182
    m32 := -V_._23.o;
2183
    m42 := -V_._24.o;
2184
    m13 := -V_._31.o;
2185
    m23 := -V_._32.o;
2186
    m33 := -V_._33.o;
2187
    m43 := -V_._34.o;
2188
    m14 := +V_._41.o;
2189
    m24 := +V_._42.o;
2190
    m34 := +V_._43.o;
2191
    m44 := +V_._44.o;
2192
  end
2193
end;
2194

2195
class operator TdSingleM4.Implicit(const V_: TdSingleM3): TdSingleM4;
2196
begin
2197
  with Result do
2198
  begin
2199
    _11 := V_._11;
2200
    _12 := V_._12;
2201
    _13 := V_._13;
2202
    _14 := 0;
2203
    _21 := V_._21;
2204
    _22 := V_._22;
2205
    _23 := V_._23;
2206
    _24 := 0;
2207
    _31 := V_._31;
2208
    _32 := V_._32;
2209
    _33 := V_._33;
2210
    _34 := 0;
2211
    _41 := 0;
2212
    _42 := 0;
2213
    _43 := 0;
2214
    _44 := 1;
2215
  end
2216
end;
2217

2218
class operator TdSingleM4.Explicit(const V_: TdSingleM4): TdSingleM3;
2219
begin
2220
  with Result do
2221
  begin
2222
    _11 := V_._11;
2223
    _12 := V_._12;
2224
    _13 := V_._13;
2225
    _21 := V_._21;
2226
    _22 := V_._22;
2227
    _23 := V_._23;
2228
    _31 := V_._31;
2229
    _32 := V_._32;
2230
    _33 := V_._33;
2231
  end
2232
end;
2233

2234
function TdSingleM4.MultPos(const B_: TdSingle3D): TdSingle3D;
2235
begin
2236
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z + _14;
2237
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z + _24;
2238
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z + _34;
2239
end;
2240

2241
function TdSingleM4.MultVec(const B_: TdSingle3D): TdSingle3D;
2242
begin
2243
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z;
2244
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z;
2245
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z;
2246
end;
2247

2248
function TdSingleM4.Adjugate: TdSingleM4;
2249
begin
2250
  Result._11 := +TdSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
2251
    { 21 } _22, _23, _24,
2252
    { 31 } _32, _33, _34,
2253
    { 41 } _42, _43, _44).Det;
2254

2255
  Result._21 := -TdSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
2256
    _21, { 22 } _23, _24, _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
2257

2258
  Result._31 := +TdSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
2259
    _21, _22, { 23 } _24, _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
2260

2261
  Result._41 := -TdSingleM3.Create( { 11 } { 12 } { 13 } { 14 }
2262
    _21, _22, _23, { 24 }
2263
    _31, _32, _33, { 34 }
2264
    _41, _42, _43 { 44 } ).Det;
2265

2266
  Result._12 := -TdSingleM3.Create( { 11 } _12, _13, _14,
2267
    { 21 } { 22 } { 23 } { 24 }
2268
    { 31 } _32, _33, _34,
2269
    { 41 } _42, _43, _44).Det;
2270

2271
  Result._22 := +TdSingleM3.Create(_11, { 12 } _13, _14,
2272
    { 21 } { 22 } { 23 } { 24 }
2273
    _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
2274

2275
  Result._32 := -TdSingleM3.Create(_11, _12, { 13 } _14,
2276
    { 21 } { 22 } { 23 } { 24 }
2277
    _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
2278

2279
  Result._42 := +TdSingleM3.Create(_11, _12, _13, { 14 }
2280
    { 21 } { 22 } { 23 } { 24 }
2281
    _31, _32, _33, { 34 }
2282
    _41, _42, _43 { 44 } ).Det;
2283

2284
  Result._13 := +TdSingleM3.Create( { 11 } _12, _13, _14,
2285
    { 21 } _22, _23, _24,
2286
    { 31 } { 32 } { 33 } { 34 }
2287
    { 41 } _42, _43, _44).Det;
2288

2289
  Result._23 := -TdSingleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
2290
    { 31 } { 32 } { 33 } { 34 }
2291
    _41, { 42 } _43, _44).Det;
2292

2293
  Result._33 := +TdSingleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
2294
    { 31 } { 32 } { 33 } { 34 }
2295
    _41, _42, { 43 } _44).Det;
2296

2297
  Result._43 := -TdSingleM3.Create(_11, _12, _13, { 14 }
2298
    _21, _22, _23, { 24 }
2299
    { 31 } { 32 } { 33 } { 34 }
2300
    _41, _42, _43 { 44 } ).Det;
2301

2302
  Result._14 := -TdSingleM3.Create( { 11 } _12, _13, _14,
2303
    { 21 } _22, _23, _24,
2304
    { 31 } _32, _33, _34
2305
    { 41 } { 42 } { 43 } { 44 } ).Det;
2306

2307
  Result._24 := +TdSingleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
2308
    _31, { 32 } _33, _34
2309
    { 41 } { 42 } { 43 } { 44 } ).Det;
2310

2311
  Result._34 := -TdSingleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
2312
    _31, _32, { 33 } _34
2313
    { 41 } { 42 } { 43 } { 44 } ).Det;
2314

2315
  Result._44 := +TdSingleM3.Create(_11, _12, _13, { 14 }
2316
    _21, _22, _23, { 24 }
2317
    _31, _32, _33 { 34 }
2318
    { 41 } { 42 } { 43 } { 44 } ).Det;
2319
end;
2320

2321
function TdSingleM4.Transpose: TdSingleM4;
2322
begin
2323
  Result._11 := _11;
2324
  Result._12 := _21;
2325
  Result._13 := _31;
2326
  Result._14 := _41;
2327
  Result._21 := _12;
2328
  Result._22 := _22;
2329
  Result._23 := _32;
2330
  Result._24 := _42;
2331
  Result._31 := _13;
2332
  Result._32 := _23;
2333
  Result._33 := _33;
2334
  Result._34 := _43;
2335
  Result._41 := _14;
2336
  Result._42 := _24;
2337
  Result._43 := _34;
2338
  Result._44 := _44;
2339
end;
2340

2341
function TdSingleM4.Inverse: TdSingleM4;
2342
var
2343
  A: TdSingleM4;
2344
begin
2345
  A := Adjugate;
2346

2347
  Result := A / (_11 * A._11 + _12 * A._21 + _13 * A._31 + _14 * A._41)
2348
end;
2349

2350
class function TdSingleM4.Translate(const X_, Y_, Z_: TdSingle): TdSingleM4;
2351
begin
2352
  with Result do
2353
  begin
2354
    _11 := 1;
2355
    _12 := 0;
2356
    _13 := 0;
2357
    _14 := X_;
2358
    _21 := 0;
2359
    _22 := 1;
2360
    _23 := 0;
2361
    _24 := Y_;
2362
    _31 := 0;
2363
    _32 := 0;
2364
    _33 := 1;
2365
    _34 := Z_;
2366
    _41 := 0;
2367
    _42 := 0;
2368
    _43 := 0;
2369
    _44 := 1;
2370
  end
2371
end;
2372

2373
class function TdSingleM4.Translate(const T_: TdSingle3D): TdSingleM4;
2374
begin
2375
  with T_ do
2376
    Result := Translate(X, Y, Z);
2377
end;
2378

2379
// ------------------------------------------------------------------------------
2380

2381
class function TdSingleM4.Scale(const X_, Y_, Z_: TdSingle): TdSingleM4;
2382
begin
2383
  with Result do
2384
  begin
2385
    _11 := X_;
2386
    _12 := 0;
2387
    _13 := 0;
2388
    _14 := 0;
2389
    _21 := 0;
2390
    _22 := Y_;
2391
    _23 := 0;
2392
    _24 := 0;
2393
    _31 := 0;
2394
    _32 := 0;
2395
    _33 := Z_;
2396
    _34 := 0;
2397
    _41 := 0;
2398
    _42 := 0;
2399
    _43 := 0;
2400
    _44 := 1;
2401
  end
2402
end;
2403

2404
class function TdSingleM4.Scale(const S_: TdSingle3D): TdSingleM4;
2405
begin
2406
  with S_ do
2407
    Result := Scale(X, Y, Z);
2408
end;
2409

2410
// ------------------------------------------------------------------------------
2411

2412
class function TdSingleM4.RotateX(const T_: TdSingle): TdSingleM4;
2413
var
2414
  C, S: TdSingle;
2415
begin
2416
  SinCos(T_, S, C);
2417

2418
  with Result do
2419
  begin
2420
    _11 := 1;
2421
    _12 := 0;
2422
    _13 := 0;
2423
    _14 := 0;
2424
    _21 := 0;
2425
    _22 := C;
2426
    _23 := -S;
2427
    _24 := 0;
2428
    _31 := 0;
2429
    _32 := +S;
2430
    _33 := C;
2431
    _34 := 0;
2432
    _41 := 0;
2433
    _42 := 0;
2434
    _43 := 0;
2435
    _44 := 1;
2436
  end
2437
end;
2438

2439
class function TdSingleM4.RotateY(const T_: TdSingle): TdSingleM4;
2440
var
2441
  C, S: TdSingle;
2442
begin
2443
  SinCos(T_, S, C);
2444

2445
  with Result do
2446
  begin
2447
    _11 := C;
2448
    _12 := 0;
2449
    _13 := +S;
2450
    _14 := 0;
2451
    _21 := 0;
2452
    _22 := 1;
2453
    _23 := 0;
2454
    _24 := 0;
2455
    _31 := -S;
2456
    _32 := 0;
2457
    _33 := C;
2458
    _34 := 0;
2459
    _41 := 0;
2460
    _42 := 0;
2461
    _43 := 0;
2462
    _44 := 1;
2463
  end
2464
end;
2465

2466
class function TdSingleM4.RotateZ(const T_: TdSingle): TdSingleM4;
2467
var
2468
  C, S: TdSingle;
2469
begin
2470
  SinCos(T_, S, C);
2471

2472
  with Result do
2473
  begin
2474
    _11 := C;
2475
    _12 := -S;
2476
    _13 := 0;
2477
    _14 := 0;
2478
    _21 := +S;
2479
    _22 := C;
2480
    _23 := 0;
2481
    _24 := 0;
2482
    _31 := 0;
2483
    _32 := 0;
2484
    _33 := 1;
2485
    _34 := 0;
2486
    _41 := 0;
2487
    _42 := 0;
2488
    _43 := 0;
2489
    _44 := 1;
2490
  end
2491
end;
2492

2493
// ------------------------------------------------------------------------------
2494

2495
class function TdSingleM4.Identity: TdSingleM4;
2496
begin
2497
  with Result do
2498
  begin
2499
    _11 := 1;
2500
    _12 := 0;
2501
    _13 := 0;
2502
    _14 := 0;
2503
    _21 := 0;
2504
    _22 := 1;
2505
    _23 := 0;
2506
    _24 := 0;
2507
    _31 := 0;
2508
    _32 := 0;
2509
    _33 := 1;
2510
    _34 := 0;
2511
    _41 := 0;
2512
    _42 := 0;
2513
    _43 := 0;
2514
    _44 := 1;
2515
  end
2516
end;
2517

2518
function TdDoubleM4.GetM(const Y_, X_: Integer): TdDouble;
2519
begin
2520
  Result := _[Y_, X_];
2521
end;
2522

2523
procedure TdDoubleM4.SetM(const Y_, X_: Integer; const M_: TdDouble);
2524
begin
2525
  _[Y_, X_] := M_;
2526
end;
2527

2528
// ------------------------------------------------------------------------------
2529

2530
function TdDoubleM4.GetAxisX: TdDouble3D;
2531
begin
2532
  with Result do
2533
  begin
2534
    X := _11;
2535
    Y := _21;
2536
    Z := _31;
2537
  end
2538
end;
2539

2540
procedure TdDoubleM4.SetAxisX(const AxisX_: TdDouble3D);
2541
begin
2542
  with AxisX_ do
2543
  begin
2544
    _11 := X;
2545
    _21 := Y;
2546
    _31 := Z;
2547
  end
2548
end;
2549

2550
function TdDoubleM4.GetAxisY: TdDouble3D;
2551
begin
2552
  with Result do
2553
  begin
2554
    X := _12;
2555
    Y := _22;
2556
    Z := _32;
2557
  end
2558
end;
2559

2560
procedure TdDoubleM4.SetAxisY(const AxisY_: TdDouble3D);
2561
begin
2562
  with AxisY_ do
2563
  begin
2564
    _12 := X;
2565
    _22 := Y;
2566
    _32 := Z;
2567
  end
2568
end;
2569

2570
function TdDoubleM4.GetAxisZ: TdDouble3D;
2571
begin
2572
  with Result do
2573
  begin
2574
    X := _13;
2575
    Y := _23;
2576
    Z := _33;
2577
  end
2578
end;
2579

2580
procedure TdDoubleM4.SetAxisZ(const AxisZ_: TdDouble3D);
2581
begin
2582
  with AxisZ_ do
2583
  begin
2584
    _13 := X;
2585
    _23 := Y;
2586
    _33 := Z;
2587
  end
2588
end;
2589

2590
function TdDoubleM4.GetAxisP: TdDouble3D;
2591
begin
2592
  with Result do
2593
  begin
2594
    X := _14;
2595
    Y := _24;
2596
    Z := _34;
2597
  end
2598
end;
2599

2600
procedure TdDoubleM4.SetAxisP(const AxisP_: TdDouble3D);
2601
begin
2602
  with AxisP_ do
2603
  begin
2604
    _14 := X;
2605
    _24 := Y;
2606
    _34 := Z;
2607
  end
2608
end;
2609

2610
constructor TdDoubleM4.Create(const _11_, _12_, _13_, _14_, _21_, _22_, _23_,
2611
  _24_, _31_, _32_, _33_, _34_, _41_, _42_, _43_, _44_: TdDouble);
2612
begin
2613
  _11 := _11_;
2614
  _12 := _12_;
2615
  _13 := _13_;
2616
  _14 := _14_;
2617
  _21 := _21_;
2618
  _22 := _22_;
2619
  _23 := _23_;
2620
  _24 := _24_;
2621
  _31 := _31_;
2622
  _32 := _32_;
2623
  _33 := _33_;
2624
  _34 := _34_;
2625
  _41 := _41_;
2626
  _42 := _42_;
2627
  _43 := _43_;
2628
  _44 := _44_;
2629
end;
2630

2631
constructor TdDoubleM4.Create(const X_, Y_, Z_, P_: TdDouble3D);
2632
begin
2633
  _11 := X_.X;
2634
  _12 := Y_.X;
2635
  _13 := Z_.X;
2636
  _14 := P_.X;
2637
  _21 := X_.Y;
2638
  _22 := Y_.Y;
2639
  _23 := Z_.Y;
2640
  _24 := P_.Y;
2641
  _31 := X_.Z;
2642
  _32 := Y_.Z;
2643
  _33 := Z_.Z;
2644
  _34 := P_.Z;
2645
  _41 := 0;
2646
  _42 := 0;
2647
  _43 := 0;
2648
  _44 := 1;
2649
end;
2650

2651
class operator TdDoubleM4.Multiply(const A_, B_: TdDoubleM4): TdDoubleM4;
2652
begin
2653
  with Result do
2654
  begin
2655
    _11 := A_._11 * B_._11 + A_._12 * B_._21 + A_._13 * B_._31 + A_._14
2656
      * B_._41;
2657
    _12 := A_._11 * B_._12 + A_._12 * B_._22 + A_._13 * B_._32 + A_._14
2658
      * B_._42;
2659
    _13 := A_._11 * B_._13 + A_._12 * B_._23 + A_._13 * B_._33 + A_._14
2660
      * B_._43;
2661
    _14 := A_._11 * B_._14 + A_._12 * B_._24 + A_._13 * B_._34 + A_._14
2662
      * B_._44;
2663

2664
    _21 := A_._21 * B_._11 + A_._22 * B_._21 + A_._23 * B_._31 + A_._24
2665
      * B_._41;
2666
    _22 := A_._21 * B_._12 + A_._22 * B_._22 + A_._23 * B_._32 + A_._24
2667
      * B_._42;
2668
    _23 := A_._21 * B_._13 + A_._22 * B_._23 + A_._23 * B_._33 + A_._24
2669
      * B_._43;
2670
    _24 := A_._21 * B_._14 + A_._22 * B_._24 + A_._23 * B_._34 + A_._24
2671
      * B_._44;
2672

2673
    _31 := A_._31 * B_._11 + A_._32 * B_._21 + A_._33 * B_._31 + A_._34
2674
      * B_._41;
2675
    _32 := A_._31 * B_._12 + A_._32 * B_._22 + A_._33 * B_._32 + A_._34
2676
      * B_._42;
2677
    _33 := A_._31 * B_._13 + A_._32 * B_._23 + A_._33 * B_._33 + A_._34
2678
      * B_._43;
2679
    _34 := A_._31 * B_._14 + A_._32 * B_._24 + A_._33 * B_._34 + A_._34
2680
      * B_._44;
2681

2682
    _41 := A_._41 * B_._11 + A_._42 * B_._21 + A_._43 * B_._31 + A_._44
2683
      * B_._41;
2684
    _42 := A_._41 * B_._12 + A_._42 * B_._22 + A_._43 * B_._32 + A_._44
2685
      * B_._42;
2686
    _43 := A_._41 * B_._13 + A_._42 * B_._23 + A_._43 * B_._33 + A_._44
2687
      * B_._43;
2688
    _44 := A_._41 * B_._14 + A_._42 * B_._24 + A_._43 * B_._34 + A_._44
2689
      * B_._44;
2690
  end
2691
end;
2692

2693
class operator TdDoubleM4.Multiply(const A_: TdDouble; const B_: TdDoubleM4)
2694
  : TdDoubleM4;
2695
begin
2696
  with Result do
2697
  begin
2698
    _11 := A_ * B_._11;
2699
    _12 := A_ * B_._12;
2700
    _13 := A_ * B_._13;
2701
    _14 := A_ * B_._14;
2702
    _21 := A_ * B_._21;
2703
    _22 := A_ * B_._22;
2704
    _23 := A_ * B_._23;
2705
    _24 := A_ * B_._24;
2706
    _31 := A_ * B_._31;
2707
    _32 := A_ * B_._32;
2708
    _33 := A_ * B_._33;
2709
    _34 := A_ * B_._34;
2710
    _41 := A_ * B_._41;
2711
    _42 := A_ * B_._42;
2712
    _43 := A_ * B_._43;
2713
    _44 := A_ * B_._44;
2714
  end
2715
end;
2716

2717
class operator TdDoubleM4.Multiply(const A_: TdDoubleM4; const B_: TdDouble)
2718
  : TdDoubleM4;
2719
begin
2720
  with Result do
2721
  begin
2722
    _11 := A_._11 * B_;
2723
    _12 := A_._12 * B_;
2724
    _13 := A_._13 * B_;
2725
    _14 := A_._14 * B_;
2726
    _21 := A_._21 * B_;
2727
    _22 := A_._22 * B_;
2728
    _23 := A_._23 * B_;
2729
    _24 := A_._24 * B_;
2730
    _31 := A_._31 * B_;
2731
    _32 := A_._32 * B_;
2732
    _33 := A_._33 * B_;
2733
    _34 := A_._34 * B_;
2734
    _41 := A_._41 * B_;
2735
    _42 := A_._42 * B_;
2736
    _43 := A_._43 * B_;
2737
    _44 := A_._44 * B_;
2738
  end
2739
end;
2740

2741
class operator TdDoubleM4.Multiply(const A_: TdDoubleM4; const B_: TdDouble4D)
2742
  : TdDouble4D;
2743
begin
2744
  with Result do
2745
  begin
2746
    _1 := A_._11 * B_._1 + A_._12 * B_._2 + A_._13 * B_._3 + A_._14 * B_._4;
2747
    _2 := A_._21 * B_._1 + A_._22 * B_._2 + A_._23 * B_._3 + A_._24 * B_._4;
2748
    _3 := A_._31 * B_._1 + A_._32 * B_._2 + A_._33 * B_._3 + A_._34 * B_._4;
2749
    _4 := A_._41 * B_._1 + A_._42 * B_._2 + A_._43 * B_._3 + A_._44 * B_._4;
2750
  end;
2751
end;
2752

2753
class operator TdDoubleM4.Multiply(const A_: TdDouble4D; const B_: TdDoubleM4)
2754
  : TdDouble4D;
2755
begin
2756
  with Result do
2757
  begin
2758
    _1 := A_._1 * B_._11 + A_._2 * B_._21 + A_._3 * B_._31 + A_._4 * B_._41;
2759
    _2 := A_._1 * B_._12 + A_._2 * B_._22 + A_._3 * B_._32 + A_._4 * B_._42;
2760
    _3 := A_._1 * B_._13 + A_._2 * B_._23 + A_._3 * B_._33 + A_._4 * B_._43;
2761
    _4 := A_._1 * B_._14 + A_._2 * B_._24 + A_._3 * B_._34 + A_._4 * B_._44;
2762
  end;
2763
end;
2764

2765
class operator TdDoubleM4.Divide(const A_: TdDoubleM4; const B_: TdDouble)
2766
  : TdDoubleM4;
2767
begin
2768
  with A_ do
2769
  begin
2770
    Result._11 := _11 / B_;
2771
    Result._12 := _12 / B_;
2772
    Result._13 := _13 / B_;
2773
    Result._14 := _14 / B_;
2774
    Result._21 := _21 / B_;
2775
    Result._22 := _22 / B_;
2776
    Result._23 := _23 / B_;
2777
    Result._24 := _24 / B_;
2778
    Result._31 := _31 / B_;
2779
    Result._32 := _32 / B_;
2780
    Result._33 := _33 / B_;
2781
    Result._34 := _34 / B_;
2782
    Result._41 := _41 / B_;
2783
    Result._42 := _42 / B_;
2784
    Result._43 := _43 / B_;
2785
    Result._44 := _44 / B_;
2786
  end
2787
end;
2788

2789
class operator TdDoubleM4.Implicit(const V_: TdDouble): TdDoubleM4;
2790
begin
2791
  with Result do
2792
  begin
2793
    _11 := V_;
2794
    _12 := 0;
2795
    _13 := 0;
2796
    _14 := 0;
2797
    _21 := 0;
2798
    _22 := V_;
2799
    _23 := 0;
2800
    _24 := 0;
2801
    _31 := 0;
2802
    _32 := 0;
2803
    _33 := V_;
2804
    _34 := 0;
2805
    _41 := 0;
2806
    _42 := 0;
2807
    _43 := 0;
2808
    _44 := V_;
2809
  end
2810
end;
2811

2812
class operator TdDoubleM4.Implicit(const V_: TMatrix3D): TdDoubleM4;
2813
begin
2814
  with Result do
2815
  begin
2816
    _11 := +V_.m11;
2817
    _12 := +V_.m21;
2818
    _13 := +V_.m31;
2819
    _14 := +V_.m41;
2820
    _21 := -V_.m12;
2821
    _22 := -V_.m22;
2822
    _23 := -V_.m32;
2823
    _24 := -V_.m42;
2824
    _31 := -V_.m13;
2825
    _32 := -V_.m23;
2826
    _33 := -V_.m33;
2827
    _34 := -V_.m43;
2828
    _41 := +V_.m14;
2829
    _42 := +V_.m24;
2830
    _43 := +V_.m34;
2831
    _44 := +V_.m44;
2832
  end
2833
end;
2834

2835
class operator TdDoubleM4.Explicit(const V_: TdDoubleM4): TMatrix3D;
2836
begin
2837
  with Result do
2838
  begin
2839
    m11 := +V_._11.o;
2840
    m21 := +V_._12.o;
2841
    m31 := +V_._13.o;
2842
    m41 := +V_._14.o;
2843
    m12 := -V_._21.o;
2844
    m22 := -V_._22.o;
2845
    m32 := -V_._23.o;
2846
    m42 := -V_._24.o;
2847
    m13 := -V_._31.o;
2848
    m23 := -V_._32.o;
2849
    m33 := -V_._33.o;
2850
    m43 := -V_._34.o;
2851
    m14 := +V_._41.o;
2852
    m24 := +V_._42.o;
2853
    m34 := +V_._43.o;
2854
    m44 := +V_._44.o;
2855
  end
2856
end;
2857

2858
class operator TdDoubleM4.Implicit(const V_: TdSingleM4): TdDoubleM4;
2859
begin
2860
  with Result do
2861
  begin
2862
    _11 := V_._11;
2863
    _12 := V_._12;
2864
    _13 := V_._13;
2865
    _14 := V_._14;
2866
    _21 := V_._21;
2867
    _22 := V_._22;
2868
    _23 := V_._23;
2869
    _24 := V_._24;
2870
    _31 := V_._31;
2871
    _32 := V_._32;
2872
    _33 := V_._33;
2873
    _34 := V_._34;
2874
    _41 := V_._41;
2875
    _42 := V_._42;
2876
    _43 := V_._43;
2877
    _44 := V_._44;
2878
  end
2879
end;
2880

2881
class operator TdDoubleM4.Explicit(const V_: TdDoubleM4): TdSingleM4;
2882
begin
2883
  with Result do
2884
  begin
2885
    _11 := V_._11;
2886
    _12 := V_._12;
2887
    _13 := V_._13;
2888
    _14 := V_._14;
2889
    _21 := V_._21;
2890
    _22 := V_._22;
2891
    _23 := V_._23;
2892
    _24 := V_._24;
2893
    _31 := V_._31;
2894
    _32 := V_._32;
2895
    _33 := V_._33;
2896
    _34 := V_._34;
2897
    _41 := V_._41;
2898
    _42 := V_._42;
2899
    _43 := V_._43;
2900
    _44 := V_._44;
2901
  end
2902
end;
2903

2904
class operator TdDoubleM4.Implicit(const V_: TdDoubleM3): TdDoubleM4;
2905
begin
2906
  with Result do
2907
  begin
2908
    _11 := V_._11;
2909
    _12 := V_._12;
2910
    _13 := V_._13;
2911
    _14 := 0;
2912
    _21 := V_._21;
2913
    _22 := V_._22;
2914
    _23 := V_._23;
2915
    _24 := 0;
2916
    _31 := V_._31;
2917
    _32 := V_._32;
2918
    _33 := V_._33;
2919
    _34 := 0;
2920
    _41 := 0;
2921
    _42 := 0;
2922
    _43 := 0;
2923
    _44 := 1;
2924
  end
2925
end;
2926

2927
class operator TdDoubleM4.Explicit(const V_: TdDoubleM4): TdDoubleM3;
2928
begin
2929
  with Result do
2930
  begin
2931
    _11 := V_._11;
2932
    _12 := V_._12;
2933
    _13 := V_._13;
2934
    _21 := V_._21;
2935
    _22 := V_._22;
2936
    _23 := V_._23;
2937
    _31 := V_._31;
2938
    _32 := V_._32;
2939
    _33 := V_._33;
2940
  end
2941
end;
2942

2943
function TdDoubleM4.MultPos(const B_: TdDouble3D): TdDouble3D;
2944
begin
2945
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z + _14;
2946
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z + _24;
2947
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z + _34;
2948
end;
2949

2950
function TdDoubleM4.MultVec(const B_: TdDouble3D): TdDouble3D;
2951
begin
2952
  Result.X := _11 * B_.X + _12 * B_.Y + _13 * B_.Z;
2953
  Result.Y := _21 * B_.X + _22 * B_.Y + _23 * B_.Z;
2954
  Result.Z := _31 * B_.X + _32 * B_.Y + _33 * B_.Z;
2955
end;
2956

2957
function TdDoubleM4.Adjugate: TdDoubleM4;
2958
begin
2959
  Result._11 := +TdDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
2960
    { 21 } _22, _23, _24,
2961
    { 31 } _32, _33, _34,
2962
    { 41 } _42, _43, _44).Det;
2963

2964
  Result._21 := -TdDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
2965
    _21, { 22 } _23, _24, _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
2966

2967
  Result._31 := +TdDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
2968
    _21, _22, { 23 } _24, _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
2969

2970
  Result._41 := -TdDoubleM3.Create( { 11 } { 12 } { 13 } { 14 }
2971
    _21, _22, _23, { 24 }
2972
    _31, _32, _33, { 34 }
2973
    _41, _42, _43 { 44 } ).Det;
2974

2975
  Result._12 := -TdDoubleM3.Create( { 11 } _12, _13, _14,
2976
    { 21 } { 22 } { 23 } { 24 }
2977
    { 31 } _32, _33, _34,
2978
    { 41 } _42, _43, _44).Det;
2979

2980
  Result._22 := +TdDoubleM3.Create(_11, { 12 } _13, _14,
2981
    { 21 } { 22 } { 23 } { 24 }
2982
    _31, { 32 } _33, _34, _41, { 42 } _43, _44).Det;
2983

2984
  Result._32 := -TdDoubleM3.Create(_11, _12, { 13 } _14,
2985
    { 21 } { 22 } { 23 } { 24 }
2986
    _31, _32, { 33 } _34, _41, _42, { 43 } _44).Det;
2987

2988
  Result._42 := +TdDoubleM3.Create(_11, _12, _13, { 14 }
2989
    { 21 } { 22 } { 23 } { 24 }
2990
    _31, _32, _33, { 34 }
2991
    _41, _42, _43 { 44 } ).Det;
2992

2993
  Result._13 := +TdDoubleM3.Create( { 11 } _12, _13, _14,
2994
    { 21 } _22, _23, _24,
2995
    { 31 } { 32 } { 33 } { 34 }
2996
    { 41 } _42, _43, _44).Det;
2997

2998
  Result._23 := -TdDoubleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
2999
    { 31 } { 32 } { 33 } { 34 }
3000
    _41, { 42 } _43, _44).Det;
3001

3002
  Result._33 := +TdDoubleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
3003
    { 31 } { 32 } { 33 } { 34 }
3004
    _41, _42, { 43 } _44).Det;
3005

3006
  Result._43 := -TdDoubleM3.Create(_11, _12, _13, { 14 }
3007
    _21, _22, _23, { 24 }
3008
    { 31 } { 32 } { 33 } { 34 }
3009
    _41, _42, _43 { 44 } ).Det;
3010

3011
  Result._14 := -TdDoubleM3.Create( { 11 } _12, _13, _14,
3012
    { 21 } _22, _23, _24,
3013
    { 31 } _32, _33, _34
3014
    { 41 } { 42 } { 43 } { 44 } ).Det;
3015

3016
  Result._24 := +TdDoubleM3.Create(_11, { 12 } _13, _14, _21, { 22 } _23, _24,
3017
    _31, { 32 } _33, _34
3018
    { 41 } { 42 } { 43 } { 44 } ).Det;
3019

3020
  Result._34 := -TdDoubleM3.Create(_11, _12, { 13 } _14, _21, _22, { 23 } _24,
3021
    _31, _32, { 33 } _34
3022
    { 41 } { 42 } { 43 } { 44 } ).Det;
3023

3024
  Result._44 := +TdDoubleM3.Create(_11, _12, _13, { 14 }
3025
    _21, _22, _23, { 24 }
3026
    _31, _32, _33 { 34 }
3027
    { 41 } { 42 } { 43 } { 44 } ).Det;
3028
end;
3029

3030
function TdDoubleM4.Transpose: TdDoubleM4;
3031
begin
3032
  Result._11 := _11;
3033
  Result._12 := _21;
3034
  Result._13 := _31;
3035
  Result._14 := _41;
3036
  Result._21 := _12;
3037
  Result._22 := _22;
3038
  Result._23 := _32;
3039
  Result._24 := _42;
3040
  Result._31 := _13;
3041
  Result._32 := _23;
3042
  Result._33 := _33;
3043
  Result._34 := _43;
3044
  Result._41 := _14;
3045
  Result._42 := _24;
3046
  Result._43 := _34;
3047
  Result._44 := _44;
3048
end;
3049

3050
function TdDoubleM4.Inverse: TdDoubleM4;
3051
var
3052
  A: TdDoubleM4;
3053
begin
3054
  A := Adjugate;
3055

3056
  Result := A / (_11 * A._11 + _12 * A._21 + _13 * A._31 + _14 * A._41)
3057
end;
3058

3059
class function TdDoubleM4.Translate(const X_, Y_, Z_: TdDouble): TdDoubleM4;
3060
begin
3061
  with Result do
3062
  begin
3063
    _11 := 1;
3064
    _12 := 0;
3065
    _13 := 0;
3066
    _14 := X_;
3067
    _21 := 0;
3068
    _22 := 1;
3069
    _23 := 0;
3070
    _24 := Y_;
3071
    _31 := 0;
3072
    _32 := 0;
3073
    _33 := 1;
3074
    _34 := Z_;
3075
    _41 := 0;
3076
    _42 := 0;
3077
    _43 := 0;
3078
    _44 := 1;
3079
  end
3080
end;
3081

3082
class function TdDoubleM4.Translate(const T_: TdDouble3D): TdDoubleM4;
3083
begin
3084
  with T_ do
3085
    Result := Translate(X, Y, Z);
3086
end;
3087

3088
// ------------------------------------------------------------------------------
3089

3090
class function TdDoubleM4.Scale(const X_, Y_, Z_: TdDouble): TdDoubleM4;
3091
begin
3092
  with Result do
3093
  begin
3094
    _11 := X_;
3095
    _12 := 0;
3096
    _13 := 0;
3097
    _14 := 0;
3098
    _21 := 0;
3099
    _22 := Y_;
3100
    _23 := 0;
3101
    _24 := 0;
3102
    _31 := 0;
3103
    _32 := 0;
3104
    _33 := Z_;
3105
    _34 := 0;
3106
    _41 := 0;
3107
    _42 := 0;
3108
    _43 := 0;
3109
    _44 := 1;
3110
  end
3111
end;
3112

3113
class function TdDoubleM4.Scale(const S_: TdDouble3D): TdDoubleM4;
3114
begin
3115
  with S_ do
3116
    Result := Scale(X, Y, Z);
3117
end;
3118

3119
// ------------------------------------------------------------------------------
3120

3121
class function TdDoubleM4.RotateX(const T_: TdDouble): TdDoubleM4;
3122
var
3123
  C, S: TdDouble;
3124
begin
3125
  SinCos(T_, S, C);
3126

3127
  with Result do
3128
  begin
3129
    _11 := 1;
3130
    _12 := 0;
3131
    _13 := 0;
3132
    _14 := 0;
3133
    _21 := 0;
3134
    _22 := C;
3135
    _23 := -S;
3136
    _24 := 0;
3137
    _31 := 0;
3138
    _32 := +S;
3139
    _33 := C;
3140
    _34 := 0;
3141
    _41 := 0;
3142
    _42 := 0;
3143
    _43 := 0;
3144
    _44 := 1;
3145
  end
3146
end;
3147

3148
class function TdDoubleM4.RotateY(const T_: TdDouble): TdDoubleM4;
3149
var
3150
  C, S: TdDouble;
3151
begin
3152
  SinCos(T_, S, C);
3153

3154
  with Result do
3155
  begin
3156
    _11 := C;
3157
    _12 := 0;
3158
    _13 := +S;
3159
    _14 := 0;
3160
    _21 := 0;
3161
    _22 := 1;
3162
    _23 := 0;
3163
    _24 := 0;
3164
    _31 := -S;
3165
    _32 := 0;
3166
    _33 := C;
3167
    _34 := 0;
3168
    _41 := 0;
3169
    _42 := 0;
3170
    _43 := 0;
3171
    _44 := 1;
3172
  end
3173
end;
3174

3175
class function TdDoubleM4.RotateZ(const T_: TdDouble): TdDoubleM4;
3176
var
3177
  C, S: TdDouble;
3178
begin
3179
  SinCos(T_, S, C);
3180

3181
  with Result do
3182
  begin
3183
    _11 := C;
3184
    _12 := -S;
3185
    _13 := 0;
3186
    _14 := 0;
3187
    _21 := +S;
3188
    _22 := C;
3189
    _23 := 0;
3190
    _24 := 0;
3191
    _31 := 0;
3192
    _32 := 0;
3193
    _33 := 1;
3194
    _34 := 0;
3195
    _41 := 0;
3196
    _42 := 0;
3197
    _43 := 0;
3198
    _44 := 1;
3199
  end
3200
end;
3201

3202
// ------------------------------------------------------------------------------
3203

3204
class function TdDoubleM4.Identity: TdDoubleM4;
3205
begin
3206
  with Result do
3207
  begin
3208
    _11 := 1;
3209
    _12 := 0;
3210
    _13 := 0;
3211
    _14 := 0;
3212
    _21 := 0;
3213
    _22 := 1;
3214
    _23 := 0;
3215
    _24 := 0;
3216
    _31 := 0;
3217
    _32 := 0;
3218
    _33 := 1;
3219
    _34 := 0;
3220
    _41 := 0;
3221
    _42 := 0;
3222
    _43 := 0;
3223
    _44 := 1;
3224
  end
3225
end;
3226

3227
procedure TSingleDualM4.Seto(const o_: TSingleM4);
3228
begin
3229
  _o := o_;
3230
  _i := o_.Inverse;
3231
end;
3232

3233
procedure TSingleDualM4.Seti(const i_: TSingleM4);
3234
begin
3235
  _o := i_.Inverse;
3236
  _i := i_;
3237
end;
3238

3239
class operator TSingleDualM4.Multiply(const A_, B_: TSingleDualM4)
3240
  : TSingleDualM4;
3241
begin
3242
  with Result do
3243
  begin
3244
    _o := A_.o * B_.o;
3245
    _i := B_.i * A_.i;
3246
  end
3247
end;
3248

3249
class operator TSingleDualM4.Multiply(const A_: Single; B_: TSingleDualM4)
3250
  : TSingleDualM4;
3251
begin
3252
  with Result do
3253
  begin
3254
    _o := A_ * B_.o;
3255
    _i := B_.i * A_;
3256
  end
3257
end;
3258

3259
class operator TSingleDualM4.Multiply(const A_: TSingleDualM4; B_: Single)
3260
  : TSingleDualM4;
3261
begin
3262
  with Result do
3263
  begin
3264
    _o := A_.o * B_;
3265
    _i := B_ * A_.i;
3266
  end
3267
end;
3268

3269
class operator TSingleDualM4.Divide(const A_: TSingleDualM4; const B_: Single)
3270
  : TSingleDualM4;
3271
begin
3272
  with Result do
3273
  begin
3274
    _o := A_.o / B_;
3275
    _i := A_.i / B_;
3276
  end
3277
end;
3278

3279
class function TSingleDualM4.Translate(const X_, Y_, Z_: Single): TSingleDualM4;
3280
begin
3281
  with Result do
3282
  begin
3283
    _o := TSingleM4.Translate(+X_, +Y_, +Z_);
3284
    _i := TSingleM4.Translate(-X_, -Y_, -Z_);
3285
  end;
3286
end;
3287

3288
class function TSingleDualM4.Scale(const X_, Y_, Z_: Single): TSingleDualM4;
3289
begin
3290
  with Result do
3291
  begin
3292
    _o := TSingleM4.Scale(+X_, +Y_, +Z_);
3293
    _i := TSingleM4.Scale(-X_, -Y_, -Z_);
3294
  end;
3295
end;
3296

3297
class function TSingleDualM4.RotateX(const T_: Single): TSingleDualM4;
3298
begin
3299
  with Result do
3300
  begin
3301
    _o := TSingleM4.RotateX(+T_);
3302
    _i := TSingleM4.RotateX(-T_);
3303
  end;
3304
end;
3305

3306
class function TSingleDualM4.RotateY(const T_: Single): TSingleDualM4;
3307
begin
3308
  with Result do
3309
  begin
3310
    _o := TSingleM4.RotateY(+T_);
3311
    _i := TSingleM4.RotateY(-T_);
3312
  end;
3313
end;
3314

3315
class function TSingleDualM4.RotateZ(const T_: Single): TSingleDualM4;
3316
begin
3317
  with Result do
3318
  begin
3319
    _o := TSingleM4.RotateZ(+T_);
3320
    _i := TSingleM4.RotateZ(-T_);
3321
  end;
3322
end;
3323

3324
class function TSingleDualM4.Identity: TSingleDualM4;
3325
begin
3326
  with Result do
3327
  begin
3328
    _o := TSingleM4.Identity;
3329
    _i := TSingleM4.Identity;
3330
  end;
3331
end;
3332

3333
function Tensor(const T_: TSingle2D;
3334
  const Func_: TConstFunc<TdSingle2D, TdSingle3D>): TSingleM4;
3335
var
3336
  T: TdSingle2D;
3337
  FP, FX, FY: TdSingle3D;
3338
begin
3339
  with T do
3340
  begin
3341
    U.o := T_.U;
3342
    V.o := T_.V;
3343

3344
    U.d := 0;
3345
    V.d := 0;
3346
    FP := Func_(T);
3347
    U.d := +1;
3348
    V.d := 0;
3349
    FX := Func_(T);
3350
    U.d := 0;
3351
    V.d := -1;
3352
    FY := Func_(T);
3353
  end;
3354

3355
  with Result do
3356
  begin
3357
    AxisP := FP.o;
3358
    AxisX := FX.d;
3359
    AxisY := FY.d;
3360
    AxisZ := CrossProduct(FX.d, FY.d);
3361
  end;
3362
end;
3363

3364
function Tensor(const T_: TDouble2D;
3365
  const Func_: TConstFunc<TdDouble2D, TdDouble3D>): TDoubleM4;
3366
var
3367
  T: TdDouble2D;
3368
  FP, FX, FY: TdDouble3D;
3369
begin
3370
  with T do
3371
  begin
3372
    U.o := T_.U;
3373
    V.o := T_.V;
3374

3375
    U.d := 0;
3376
    V.d := 0;
3377
    FP := Func_(T);
3378
    U.d := +1;
3379
    V.d := 0;
3380
    FX := Func_(T);
3381
    U.d := 0;
3382
    V.d := -1;
3383
    FY := Func_(T);
3384
  end;
3385

3386
  with Result do
3387
  begin
3388
    AxisP := FP.o;
3389
    AxisX := FX.d;
3390
    AxisY := FY.d;
3391
    AxisZ := CrossProduct(FX.d, FY.d);
3392
  end;
3393
end;
3394

3395
// ------------------------------------------------------------------------------
3396

3397
function ArrowPose(const P0_, P1_: TSingle3D): TSingleM4;
3398
begin
3399
  Result := ArrowRot(P0_, P1_);
3400

3401
  Result.AxisP := (P1_ + P0_) / 2;
3402
end;
3403

3404
function ArrowPose(const P0_, P1_: TDouble3D): TDoubleM4;
3405
begin
3406
  Result := ArrowRot(P0_, P1_);
3407

3408
  Result.AxisP := (P1_ + P0_) / 2;
3409
end;
3410

3411
initialization // ------------------------------------------------------------
3412

3413
finalization
3414

3415
end.
3416

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.