MathgeomGLS

Форк
0
/
Neslib.FastMath.Pascal.inc 
1999 строк · 52.1 Кб
1
{ Angle and Trigonometry Functions }
2

3
function Radians(const ADegrees: Single): Single;
4
begin
5
  Result := ADegrees * (Pi / 180);
6
end;
7

8
function Radians(const ADegrees: TVector2): TVector2;
9
begin
10
  Result.Init(Radians(ADegrees.X), Radians(ADegrees.Y));
11
end;
12

13
function Radians(const ADegrees: TVector3): TVector3;
14
begin
15
  Result.Init(Radians(ADegrees.X), Radians(ADegrees.Y), Radians(ADegrees.Z));
16
end;
17

18
function Radians(const ADegrees: TVector4): TVector4;
19
begin
20
  Result.Init(Radians(ADegrees.X), Radians(ADegrees.Y), Radians(ADegrees.Z), Radians(ADegrees.W));
21
end;
22

23
function Degrees(const ARadians: Single): Single;
24
begin
25
  Result := ARadians * (180 / Pi);
26
end;
27

28
function Degrees(const ARadians: TVector2): TVector2;
29
begin
30
  Result.Init(Degrees(ARadians.X), Degrees(ARadians.Y));
31
end;
32

33
function Degrees(const ARadians: TVector3): TVector3;
34
begin
35
  Result.Init(Degrees(ARadians.X), Degrees(ARadians.Y), Degrees(ARadians.Z));
36
end;
37

38
function Degrees(const ARadians: TVector4): TVector4;
39
begin
40
  Result.Init(Degrees(ARadians.X), Degrees(ARadians.Y), Degrees(ARadians.Z), Degrees(ARadians.W));
41
end;
42

43
{ Exponential Functions }
44

45
function Sqrt(const A: Single): Single;
46
begin
47
  Result := System.Sqrt(A);
48
end;
49

50
function Sqrt(const A: TVector2): TVector2;
51
begin
52
  Result.Init(System.Sqrt(A.X), System.Sqrt(A.Y));
53
end;
54

55
function Sqrt(const A: TVector3): TVector3;
56
begin
57
  Result.Init(System.Sqrt(A.X), System.Sqrt(A.Y), System.Sqrt(A.Z));
58
end;
59

60
function Sqrt(const A: TVector4): TVector4;
61
begin
62
  Result.Init(System.Sqrt(A.X), System.Sqrt(A.Y), System.Sqrt(A.Z), System.Sqrt(A.W));
63
end;
64

65
function InverseSqrt(const A: Single): Single;
66
begin
67
  Result := 1 / Sqrt(A)
68
end;
69

70
function InverseSqrt(const A: TVector2): TVector2;
71
begin
72
  Result.Init(InverseSqrt(A.X), InverseSqrt(A.Y));
73
end;
74

75
function InverseSqrt(const A: TVector3): TVector3;
76
begin
77
  Result.Init(InverseSqrt(A.X), InverseSqrt(A.Y), InverseSqrt(A.Z));
78
end;
79

80
function InverseSqrt(const A: TVector4): TVector4;
81
begin
82
  Result.Init(InverseSqrt(A.X), InverseSqrt(A.Y), InverseSqrt(A.Z), InverseSqrt(A.W));
83
end;
84

85
{ Fast approximate Functions }
86

87
function FastSin(const ARadians: Single): Single;
88
const
89
  FOPI = 1.27323954473516;
90
  SINCOF_P0 = -1.9515295891E-4;
91
  SINCOF_P1 = 8.3321608736E-3;
92
  SINCOF_P2 = -1.6666654611E-1;
93
  COSCOF_P0 = 2.443315711809948E-005;
94
  COSCOF_P1 = -1.388731625493765E-003;
95
  COSCOF_P2 = 4.166664568298827E-002;
96
var
97
  X, Y, Z: Single;
98
  XBits: Cardinal absolute X;
99
  YBits: Cardinal absolute Y;
100
  SignBit: Cardinal;
101
  J: Integer;
102
begin
103
  X := ARadians;
104
  SignBit := XBits and $80000000;
105
  XBits := XBits and $7FFFFFFF;
106

107
  J := Trunc(FOPI * X);
108
  J := (J + 1) and (not 1);
109
  Y := J;
110

111
  J := J and 7;
112
  if (J > 3) then
113
  begin
114
    SignBit := SignBit xor $80000000;
115
    Dec(J, 4);
116
  end;
117

118
  X := X - Y * (0.25 * Pi);
119
  Z := X * X;
120
  if (J = 1) or (J = 2) then
121
  begin
122
    Y := COSCOF_P0 * Z + COSCOF_P1;
123
    Y := Y * Z + COSCOF_P2;
124
    Y := Y * (Z * Z);
125
    Y := Y - 0.5 * Z + 1;
126
  end
127
  else
128
  begin
129
    Y := SINCOF_P0 * Z + SINCOF_P1;
130
    Y := Y * Z + SINCOF_P2;
131
    Y := Y * (Z * X);
132
    Y := Y + X;
133
  end;
134

135
  YBits := YBits xor SignBit;
136
  Result := Y;
137
end;
138

139
function FastSin(const ARadians: TVector2): TVector2;
140
begin
141
  Result.Init(FastSin(ARadians.X), FastSin(ARadians.Y));
142
end;
143

144
function FastSin(const ARadians: TVector3): TVector3;
145
begin
146
  Result.Init(FastSin(ARadians.X), FastSin(ARadians.Y), FastSin(ARadians.Z));
147
end;
148

149
function FastSin(const ARadians: TVector4): TVector4;
150
begin
151
  Result.Init(FastSin(ARadians.X), FastSin(ARadians.Y), FastSin(ARadians.Z), FastSin(ARadians.W));
152
end;
153

154
function FastCos(const ARadians: Single): Single;
155
const
156
  FOPI = 1.27323954473516;
157
  SINCOF_P0 = -1.9515295891E-4;
158
  SINCOF_P1 = 8.3321608736E-3;
159
  SINCOF_P2 = -1.6666654611E-1;
160
  COSCOF_P0 = 2.443315711809948E-005;
161
  COSCOF_P1 = -1.388731625493765E-003;
162
  COSCOF_P2 = 4.166664568298827E-002;
163
var
164
  X, Y, Z: Single;
165
  XBits: Cardinal absolute X;
166
  YBits: Cardinal absolute Y;
167
  SignBit: Cardinal;
168
  J: Integer;
169
begin
170
  X := ARadians;
171
  SignBit := 0;
172
  XBits := XBits and $7FFFFFFF;
173

174
  J := Trunc(FOPI * X);
175
  J := (J + 1) and (not 1);
176
  Y := J;
177

178
  J := J and 7;
179
  if (J > 3) then
180
  begin
181
    SignBit := $80000000;
182
    Dec(J, 4);
183
  end;
184

185
  if (J > 1) then
186
    SignBit := SignBit xor $80000000;
187

188
  X := X - Y * (0.25 * Pi);
189
  Z := X * X;
190
  if (J = 1) or (J = 2) then
191
  begin
192
    Y := SINCOF_P0 * Z + SINCOF_P1;
193
    Y := Y * Z + SINCOF_P2;
194
    Y := Y * (Z * X);
195
    Y := Y + X;
196
  end
197
  else
198
  begin
199
    Y := COSCOF_P0 * Z + COSCOF_P1;
200
    Y := Y * Z + COSCOF_P2;
201
    Y := Y * (Z * Z);
202
    Y := Y - 0.5 * Z + 1;
203
  end;
204

205
  YBits := YBits xor SignBit;
206
  Result := Y;
207
end;
208

209
function FastCos(const ARadians: TVector2): TVector2;
210
begin
211
  Result.Init(FastCos(ARadians.X), FastCos(ARadians.Y));
212
end;
213

214
function FastCos(const ARadians: TVector3): TVector3;
215
begin
216
  Result.Init(FastCos(ARadians.X), FastCos(ARadians.Y), FastCos(ARadians.Z));
217
end;
218

219
function FastCos(const ARadians: TVector4): TVector4;
220
begin
221
  Result.Init(FastCos(ARadians.X), FastCos(ARadians.Y), FastCos(ARadians.Z), FastCos(ARadians.W));
222
end;
223

224
procedure FastSinCos(const ARadians: Single; out ASin, ACos: Single);
225
const
226
  FOPI = 1.27323954473516;
227
  SINCOF_P0 = -1.9515295891E-4;
228
  SINCOF_P1 = 8.3321608736E-3;
229
  SINCOF_P2 = -1.6666654611E-1;
230
  COSCOF_P0 = 2.443315711809948E-005;
231
  COSCOF_P1 = -1.388731625493765E-003;
232
  COSCOF_P2 = 4.166664568298827E-002;
233
var
234
  ASinBits: Cardinal absolute ASin;
235
  ACosBits: Cardinal absolute ACos;
236
  SignBitSin, SwapSignBitSin, SignBitCos: Cardinal;
237
  X, Y, Y2, Z: Single;
238
  XBits: Cardinal absolute X;
239
  J: Integer;
240
begin
241
  X := ARadians;
242
  SignBitSin := (XBits and $80000000);
243
  XBits := XBits and $7FFFFFFF;
244
  J := (Trunc(FOPI * X) + 1) and (not 1);
245
  Y := J;
246
  SwapSignBitSin := (J and 4) shl 29;
247

248
  X := X - Y * (0.25 * Pi);
249

250
  SignBitCos := (4 and (not (J - 2))) shl 29;
251
  SignBitSin := SignBitSin xor SwapSignBitSin;
252

253
  Z := X * X;
254

255
  Y := COSCOF_P0 * Z + COSCOF_P1;
256
  Y := Y * Z + COSCOF_P2;
257
  Y := Y * (Z * Z) - (0.5 * Z) + 1;
258

259
  Y2 := SINCOF_P0 * Z + SINCOF_P1;
260
  Y2 := Y2 * Z + SINCOF_P2;
261
  Y2 := Y2 * (Z * X) + X;
262

263
  if ((J and 2) = 0) then
264
  begin
265
    ASin := Y2;
266
    ACos := Y;
267
  end
268
  else
269
  begin
270
    ASin := Y;
271
    ACos := Y2;
272
  end;
273

274
  ASinBits := ASinBits xor SignBitSin;
275
  ACosBits := ACosBits xor SignBitCos;
276
end;
277

278
procedure FastSinCos(const ARadians: TVector2; out ASin, ACos: TVector2);
279
begin
280
  FastSinCos(ARadians.X, ASin.X, ACos.X);
281
  FastSinCos(ARadians.Y, ASin.Y, ACos.Y);
282
end;
283

284
procedure FastSinCos(const ARadians: TVector3; out ASin, ACos: TVector3);
285
begin
286
  FastSinCos(ARadians.X, ASin.X, ACos.X);
287
  FastSinCos(ARadians.Y, ASin.Y, ACos.Y);
288
  FastSinCos(ARadians.Z, ASin.Z, ACos.Z);
289
end;
290

291
procedure FastSinCos(const ARadians: TVector4; out ASin, ACos: TVector4);
292
begin
293
  FastSinCos(ARadians.X, ASin.X, ACos.X);
294
  FastSinCos(ARadians.Y, ASin.Y, ACos.Y);
295
  FastSinCos(ARadians.Z, ASin.Z, ACos.Z);
296
  FastSinCos(ARadians.W, ASin.W, ACos.W);
297
end;
298

299
function FastExp(const A: Single): Single;
300
const
301
  EXP_CST = 2139095040.0;
302
var
303
  Val, B: Single;
304
  IVal: Integer;
305
  XU, XU2: record
306
    case Byte of
307
      0: (I: Integer);
308
      1: (S: Single);
309
  end;
310
begin
311
  Val := 12102203.1615614 * A + 1065353216.0;
312

313
  if (Val >= EXP_CST) then
314
    Val := EXP_CST;
315

316
  if (Val > 0) then
317
    IVal := Trunc(Val)
318
  else
319
    IVal := 0;
320

321
  XU.I := IVal and $7F800000;
322
  XU2.I := (IVal and $007FFFFF) or $3F800000;
323
  B := XU2.S;
324

325
  Result := XU.S *
326
    ( 0.509964287281036376953125 + B *
327
    ( 0.3120158612728118896484375 + B *
328
    ( 0.1666135489940643310546875 + B *
329
    (-2.12528370320796966552734375e-3 + B *
330
      1.3534179888665676116943359375e-2))));
331
end;
332

333
function FastExp(const A: TVector2): TVector2;
334
begin
335
  Result.Init(FastExp(A.X), FastExp(A.Y));
336
end;
337

338
function FastExp(const A: TVector3): TVector3;
339
begin
340
  Result.Init(FastExp(A.X), FastExp(A.Y), FastExp(A.Z));
341
end;
342

343
function FastExp(const A: TVector4): TVector4;
344
begin
345
  Result.Init(FastExp(A.X), FastExp(A.Y), FastExp(A.Z), FastExp(A.W));
346
end;
347

348
function FastLn(const A: Single): Single;
349
var
350
  Exp, AddCst, X, X2: Single;
351
  Val: record
352
    case Byte of
353
      0: (S: Single);
354
      1: (I: Integer);
355
  end;
356
begin
357
  Val.S := A;
358
  Exp := Val.I shr 23;
359
  if (A > 0) then
360
    AddCst := -89.93423858
361
  else
362
    AddCst := NegInfinity;
363

364
  Val.I := (Val.I and $007FFFFF) or $3F800000;
365
  X := Val.S;
366
  X2 := X * X;
367

368
  Result :=
369
    (3.3977745 * X + AddCst) +
370
    X2 * ((X - 2.2744832) +
371
    X2 * (0.024982445 * X - 0.24371102)) +
372
    0.69314718055995 * Exp;
373
end;
374

375
function FastLn(const A: TVector2): TVector2;
376
begin
377
  Result.Init(FastLn(A.X), FastLn(A.Y));
378
end;
379

380
function FastLn(const A: TVector3): TVector3;
381
begin
382
  Result.Init(FastLn(A.X), FastLn(A.Y), FastLn(A.Z));
383
end;
384

385
function FastLn(const A: TVector4): TVector4;
386
begin
387
  Result.Init(FastLn(A.X), FastLn(A.Y), FastLn(A.Z), FastLn(A.W));
388
end;
389

390
function FastLog2(const A: Single): Single;
391
var
392
  MX, VX: record
393
  case Byte of
394
    0: (S: Single);
395
    1: (I: UInt32);
396
  end;
397
begin
398
  VX.S := A;
399
  MX.I := (VX.I and $007FFFFF) or $3F000000;
400
  Result := VX.I * 1.1920928955078125e-7;
401
  Result := Result
402
    - 124.22551499
403
    - 1.498030302 * MX.S
404
    - 1.72587999 / (0.3520887068 + MX.S);
405
end;
406

407
function FastLog2(const A: TVector2): TVector2;
408
begin
409
  Result.Init(FastLog2(A.X), FastLog2(A.Y));
410
end;
411

412
function FastLog2(const A: TVector3): TVector3;
413
begin
414
  Result.Init(FastLog2(A.X), FastLog2(A.Y), FastLog2(A.Z));
415
end;
416

417
function FastLog2(const A: TVector4): TVector4;
418
begin
419
  Result.Init(FastLog2(A.X), FastLog2(A.Y), FastLog2(A.Z), FastLog2(A.W));
420
end;
421

422
function FastExp2(const A: Single): Single;
423
var
424
  Offset, Z: Single;
425
  V: record
426
  case Byte of
427
    0: (S: Single);
428
    1: (I: UInt32);
429
  end;
430
begin
431
  if (A < 0) then
432
    Offset := 1
433
  else
434
    Offset := 0;
435
  Z := A - Trunc(A) + Offset;
436
  V.I := Trunc((1 shl 23) * (A + 121.2740575 + 27.7280233 / (4.84252568 - Z) - 1.49012907 * Z));
437
  Result := V.S;
438
end;
439

440
function FastExp2(const A: TVector2): TVector2;
441
begin
442
  Result.Init(FastExp2(A.X), FastExp2(A.Y));
443
end;
444

445
function FastExp2(const A: TVector3): TVector3;
446
begin
447
  Result.Init(FastExp2(A.X), FastExp2(A.Y), FastExp2(A.Z));
448
end;
449

450
function FastExp2(const A: TVector4): TVector4;
451
begin
452
  Result.Init(FastExp2(A.X), FastExp2(A.Y), FastExp2(A.Z), FastExp2(A.W));
453
end;
454

455
{ Common Functions }
456

457
function Abs(const A: Single): Single;
458
begin
459
  Result := System.Abs(A);
460
end;
461

462
function Abs(const A: TVector2): TVector2;
463
begin
464
  Result.Init(System.Abs(A.X), System.Abs(A.Y));
465
end;
466

467
function Abs(const A: TVector3): TVector3;
468
begin
469
  Result.Init(System.Abs(A.X), System.Abs(A.Y), System.Abs(A.Z));
470
end;
471

472
function Abs(const A: TVector4): TVector4;
473
begin
474
  Result.Init(System.Abs(A.X), System.Abs(A.Y), System.Abs(A.Z), System.Abs(A.W));
475
end;
476

477
function Sign(const A: Single): Single;
478
begin
479
  Result := System.Math.Sign(A);
480
end;
481

482
function Sign(const A: TVector2): TVector2;
483
begin
484
  Result.Init(System.Math.Sign(A.X), System.Math.Sign(A.Y));
485
end;
486

487
function Sign(const A: TVector3): TVector3;
488
begin
489
  Result.Init(System.Math.Sign(A.X), System.Math.Sign(A.Y), System.Math.Sign(A.Z));
490
end;
491

492
function Sign(const A: TVector4): TVector4;
493
begin
494
  Result.Init(System.Math.Sign(A.X), System.Math.Sign(A.Y), System.Math.Sign(A.Z), System.Math.Sign(A.W));
495
end;
496

497
function Floor(const A: Single): Integer;
498
begin
499
  Result := System.Math.Floor(A);
500
end;
501

502
function Floor(const A: TVector2): TIVector2;
503
begin
504
  Result.Init(System.Math.Floor(A.X), System.Math.Floor(A.Y));
505
end;
506

507
function Floor(const A: TVector3): TIVector3;
508
begin
509
  Result.Init(System.Math.Floor(A.X), System.Math.Floor(A.Y), System.Math.Floor(A.Z));
510
end;
511

512
function Floor(const A: TVector4): TIVector4;
513
begin
514
  Result.Init(System.Math.Floor(A.X), System.Math.Floor(A.Y), System.Math.Floor(A.Z), System.Math.Floor(A.W));
515
end;
516

517
function Trunc(const A: Single): Integer;
518
begin
519
  Result := System.Trunc(A);
520
end;
521

522
function Trunc(const A: TVector2): TIVector2;
523
begin
524
  Result.Init(System.Trunc(A.X), System.Trunc(A.Y));
525
end;
526

527
function Trunc(const A: TVector3): TIVector3;
528
begin
529
  Result.Init(System.Trunc(A.X), System.Trunc(A.Y), System.Trunc(A.Z));
530
end;
531

532
function Trunc(const A: TVector4): TIVector4;
533
begin
534
  Result.Init(System.Trunc(A.X), System.Trunc(A.Y), System.Trunc(A.Z), System.Trunc(A.W));
535
end;
536

537
function Round(const A: Single): Integer;
538
begin
539
  Result := System.Round(A);
540
end;
541

542
function Round(const A: TVector2): TIVector2;
543
begin
544
  Result.Init(System.Round(A.X), System.Round(A.Y));
545
end;
546

547
function Round(const A: TVector3): TIVector3;
548
begin
549
  Result.Init(System.Round(A.X), System.Round(A.Y), System.Round(A.Z));
550
end;
551

552
function Round(const A: TVector4): TIVector4;
553
begin
554
  Result.Init(System.Round(A.X), System.Round(A.Y), System.Round(A.Z), System.Round(A.W));
555
end;
556

557
function Ceil(const A: Single): Integer;
558
begin
559
  Result := System.Math.Ceil(A);
560
end;
561

562
function Ceil(const A: TVector2): TIVector2;
563
begin
564
  Result.Init(System.Math.Ceil(A.X), System.Math.Ceil(A.Y));
565
end;
566

567
function Ceil(const A: TVector3): TIVector3;
568
begin
569
  Result.Init(System.Math.Ceil(A.X), System.Math.Ceil(A.Y), System.Math.Ceil(A.Z));
570
end;
571

572
function Ceil(const A: TVector4): TIVector4;
573
begin
574
  Result.Init(System.Math.Ceil(A.X), System.Math.Ceil(A.Y), System.Math.Ceil(A.Z), System.Math.Ceil(A.W));
575
end;
576

577
function Frac(const A: Single): Single;
578
begin
579
  Result := System.Frac(A);
580
end;
581

582
function Frac(const A: TVector2): TVector2;
583
begin
584
  Result.Init(System.Frac(A.X), System.Frac(A.Y));
585
end;
586

587
function Frac(const A: TVector3): TVector3;
588
begin
589
  Result.Init(System.Frac(A.X), System.Frac(A.Y), System.Frac(A.Z));
590
end;
591

592
function Frac(const A: TVector4): TVector4;
593
begin
594
  Result.Init(System.Frac(A.X), System.Frac(A.Y), System.Frac(A.Z), System.Frac(A.W));
595
end;
596

597
function FMod(const A, B: Single): Single;
598
begin
599
  Result := A - (B * Trunc(A / B));
600
end;
601

602
function FMod(const A: TVector2; const B: Single): TVector2;
603
begin
604
  Result.Init(Neslib.FastMath.FMod(A.X, B), Neslib.FastMath.FMod(A.Y, B));
605
end;
606

607
function FMod(const A, B: TVector2): TVector2;
608
begin
609
  Result.Init(Neslib.FastMath.FMod(A.X, B.X), Neslib.FastMath.FMod(A.Y, B.Y));
610
end;
611

612
function FMod(const A: TVector3; const B: Single): TVector3;
613
begin
614
  Result.Init(Neslib.FastMath.FMod(A.X, B), Neslib.FastMath.FMod(A.Y, B), Neslib.FastMath.FMod(A.Z, B));
615
end;
616

617
function FMod(const A, B: TVector3): TVector3;
618
begin
619
  Result.Init(Neslib.FastMath.FMod(A.X, B.X), Neslib.FastMath.FMod(A.Y, B.Y), Neslib.FastMath.FMod(A.Z, B.Z));
620
end;
621

622
function FMod(const A: TVector4; const B: Single): TVector4;
623
begin
624
  Result.Init(Neslib.FastMath.FMod(A.X, B), Neslib.FastMath.FMod(A.Y, B), Neslib.FastMath.FMod(A.Z, B), Neslib.FastMath.FMod(A.W, B));
625
end;
626

627
function FMod(const A, B: TVector4): TVector4;
628
begin
629
  Result.Init(Neslib.FastMath.FMod(A.X, B.X), Neslib.FastMath.FMod(A.Y, B.Y), Neslib.FastMath.FMod(A.Z, B.Z), Neslib.FastMath.FMod(A.W, B.W));
630
end;
631

632
function ModF(const A: Single; out B: Integer): Single;
633
begin
634
  B := Trunc(A);
635
  Result := Frac(A);
636
end;
637

638
function ModF(const A: TVector2; out B: TIVector2): TVector2;
639
begin
640
  Result.Init(ModF(A.X, B.X), ModF(A.Y, B.Y));
641
end;
642

643
function ModF(const A: TVector3; out B: TIVector3): TVector3;
644
begin
645
  Result.Init(ModF(A.X, B.X), ModF(A.Y, B.Y), ModF(A.Z, B.Z));
646
end;
647

648
function ModF(const A: TVector4; out B: TIVector4): TVector4;
649
begin
650
  Result.Init(ModF(A.X, B.X), ModF(A.Y, B.Y), ModF(A.Z, B.Z), ModF(A.W, B.W));
651
end;
652

653
function Min(const A: TVector2; const B: Single): TVector2;
654
begin
655
  Result.Init(System.Math.Min(A.X, B), System.Math.Min(A.Y, B));
656
end;
657

658
function Min(const A, B: TVector2): TVector2;
659
begin
660
  Result.Init(System.Math.Min(A.X, B.X), System.Math.Min(A.Y, B.Y));
661
end;
662

663
function Min(const A: TVector3; const B: Single): TVector3;
664
begin
665
  Result.Init(System.Math.Min(A.X, B), System.Math.Min(A.Y, B), System.Math.Min(A.Z, B));
666
end;
667

668
function Min(const A, B: TVector3): TVector3;
669
begin
670
  Result.Init(System.Math.Min(A.X, B.X), System.Math.Min(A.Y, B.Y), System.Math.Min(A.Z, B.Z));
671
end;
672

673
function Min(const A: TVector4; const B: Single): TVector4;
674
begin
675
  Result.Init(System.Math.Min(A.X, B), System.Math.Min(A.Y, B), System.Math.Min(A.Z, B), System.Math.Min(A.W, B));
676
end;
677

678
function Min(const A, B: TVector4): TVector4;
679
begin
680
  Result.Init(System.Math.Min(A.X, B.X), System.Math.Min(A.Y, B.Y), System.Math.Min(A.Z, B.Z), System.Math.Min(A.W, B.W));
681
end;
682

683
function Max(const A: TVector2; const B: Single): TVector2;
684
begin
685
  Result.Init(System.Math.Max(A.X, B), System.Math.Max(A.Y, B));
686
end;
687

688
function Max(const A, B: TVector2): TVector2;
689
begin
690
  Result.Init(System.Math.Max(A.X, B.X), System.Math.Max(A.Y, B.Y));
691
end;
692

693
function Max(const A: TVector3; const B: Single): TVector3;
694
begin
695
  Result.Init(System.Math.Max(A.X, B), System.Math.Max(A.Y, B), System.Math.Max(A.Z, B));
696
end;
697

698
function Max(const A, B: TVector3): TVector3;
699
begin
700
  Result.Init(System.Math.Max(A.X, B.X), System.Math.Max(A.Y, B.Y), System.Math.Max(A.Z, B.Z));
701
end;
702

703
function Max(const A: TVector4; const B: Single): TVector4;
704
begin
705
  Result.Init(System.Math.Max(A.X, B), System.Math.Max(A.Y, B), System.Math.Max(A.Z, B), System.Math.Max(A.W, B));
706
end;
707

708
function Max(const A, B: TVector4): TVector4;
709
begin
710
  Result.Init(System.Math.Max(A.X, B.X), System.Math.Max(A.Y, B.Y), System.Math.Max(A.Z, B.Z), System.Math.Max(A.W, B.W));
711
end;
712

713
function EnsureRange(const A, AMin, AMax: Single): Single;
714
begin
715
  Result := System.Math.EnsureRange(A, AMin, AMax);
716
end;
717

718
function EnsureRange(const A: TVector2; const AMin, AMax: Single): TVector2;
719
begin
720
  Result.Init(System.Math.EnsureRange(A.X, AMin, AMax), System.Math.EnsureRange(A.Y, AMin, AMax));
721
end;
722

723
function EnsureRange(const A, AMin, AMax: TVector2): TVector2;
724
begin
725
  Result.Init(System.Math.EnsureRange(A.X, AMin.X, AMax.X), System.Math.EnsureRange(A.Y, AMin.Y, AMax.Y));
726
end;
727

728
function EnsureRange(const A: TVector3; const AMin, AMax: Single): TVector3;
729
begin
730
  Result.Init(System.Math.EnsureRange(A.X, AMin, AMax), System.Math.EnsureRange(A.Y, AMin, AMax), System.Math.EnsureRange(A.Z, AMin, AMax));
731
end;
732

733
function EnsureRange(const A, AMin, AMax: TVector3): TVector3;
734
begin
735
  Result.Init(System.Math.EnsureRange(A.X, AMin.X, AMax.X), System.Math.EnsureRange(A.Y, AMin.Y, AMax.Y), System.Math.EnsureRange(A.Z, AMin.Z, AMax.Z));
736
end;
737

738
function EnsureRange(const A: TVector4; const AMin, AMax: Single): TVector4;
739
begin
740
  Result.Init(System.Math.EnsureRange(A.X, AMin, AMax), System.Math.EnsureRange(A.Y, AMin, AMax), System.Math.EnsureRange(A.Z, AMin, AMax), System.Math.EnsureRange(A.W, AMin, AMax));
741
end;
742

743
function EnsureRange(const A, AMin, AMax: TVector4): TVector4;
744
begin
745
  Result.Init(System.Math.EnsureRange(A.X, AMin.X, AMax.X), System.Math.EnsureRange(A.Y, AMin.Y, AMax.Y), System.Math.EnsureRange(A.Z, AMin.Z, AMax.Z), System.Math.EnsureRange(A.W, AMin.W, AMax.W));
746
end;
747

748
function Mix(const A, B: TVector2; const T: Single): TVector2;
749
begin
750
  Result.Init(Mix(A.X, B.X, T), Mix(A.Y, B.Y, T));
751
end;
752

753
function Mix(const A, B, T: TVector2): TVector2;
754
begin
755
  Result.Init(Mix(A.X, B.X, T.X), Mix(A.Y, B.Y, T.Y));
756
end;
757

758
function Mix(const A, B: TVector3; const T: Single): TVector3;
759
begin
760
  Result.Init(Mix(A.X, B.X, T), Mix(A.Y, B.Y, T), Mix(A.Z, B.Z, T));
761
end;
762

763
function Mix(const A, B, T: TVector3): TVector3;
764
begin
765
  Result.Init(Mix(A.X, B.X, T.X), Mix(A.Y, B.Y, T.Y), Mix(A.Z, B.Z, T.Z));
766
end;
767

768
function Mix(const A, B: TVector4; const T: Single): TVector4;
769
begin
770
  Result.Init(Mix(A.X, B.X, T), Mix(A.Y, B.Y, T), Mix(A.Z, B.Z, T), Mix(A.W, B.W, T));
771
end;
772

773
function Mix(const A, B, T: TVector4): TVector4;
774
begin
775
  Result.Init(Mix(A.X, B.X, T.X), Mix(A.Y, B.Y, T.Y), Mix(A.Z, B.Z, T.Z), Mix(A.W, B.W, T.W));
776
end;
777

778
function Step(const AEdge: Single; const A: TVector2): TVector2;
779
begin
780
  Result.Init(Step(AEdge, A.X), Step(AEdge, A.Y));
781
end;
782

783
function Step(const AEdge, A: TVector2): TVector2;
784
begin
785
  Result.Init(Step(AEdge.X, A.X), Step(AEdge.Y, A.Y));
786
end;
787

788
function Step(const AEdge: Single; const A: TVector3): TVector3;
789
begin
790
  Result.Init(Step(AEdge, A.X), Step(AEdge, A.Y), Step(AEdge, A.Z));
791
end;
792

793
function Step(const AEdge, A: TVector3): TVector3;
794
begin
795
  Result.Init(Step(AEdge.X, A.X), Step(AEdge.Y, A.Y), Step(AEdge.Z, A.Z));
796
end;
797

798
function Step(const AEdge: Single; const A: TVector4): TVector4;
799
begin
800
  Result.Init(Step(AEdge, A.X), Step(AEdge, A.Y), Step(AEdge, A.Z), Step(AEdge, A.W));
801
end;
802

803
function Step(const AEdge, A: TVector4): TVector4;
804
begin
805
  Result.Init(Step(AEdge.X, A.X), Step(AEdge.Y, A.Y), Step(AEdge.Z, A.Z), Step(AEdge.W, A.W));
806
end;
807

808
function SmoothStep(const AEdge0, AEdge1: Single; const A: TVector2): TVector2;
809
begin
810
  Result.Init(SmoothStep(AEdge0, AEdge1, A.X), SmoothStep(AEdge0, AEdge1, A.Y));
811
end;
812

813
function SmoothStep(const AEdge0, AEdge1, A: TVector2): TVector2;
814
begin
815
  Result.Init(SmoothStep(AEdge0.X, AEdge1.X, A.X), SmoothStep(AEdge0.Y, AEdge1.Y, A.Y));
816
end;
817

818
function SmoothStep(const AEdge0, AEdge1: Single; const A: TVector3): TVector3;
819
begin
820
  Result.Init(SmoothStep(AEdge0, AEdge1, A.X), SmoothStep(AEdge0, AEdge1, A.Y), SmoothStep(AEdge0, AEdge1, A.Z));
821
end;
822

823
function SmoothStep(const AEdge0, AEdge1, A: TVector3): TVector3;
824
begin
825
  Result.Init(SmoothStep(AEdge0.X, AEdge1.X, A.X), SmoothStep(AEdge0.Y, AEdge1.Y, A.Y), SmoothStep(AEdge0.Z, AEdge1.Z, A.Z));
826
end;
827

828
function SmoothStep(const AEdge0, AEdge1: Single; const A: TVector4): TVector4;
829
begin
830
  Result.Init(SmoothStep(AEdge0, AEdge1, A.X), SmoothStep(AEdge0, AEdge1, A.Y), SmoothStep(AEdge0, AEdge1, A.Z), SmoothStep(AEdge0, AEdge1, A.W));
831
end;
832

833
function SmoothStep(const AEdge0, AEdge1, A: TVector4): TVector4;
834
begin
835
  Result.Init(SmoothStep(AEdge0.X, AEdge1.X, A.X), SmoothStep(AEdge0.Y, AEdge1.Y, A.Y), SmoothStep(AEdge0.Z, AEdge1.Z, A.Z), SmoothStep(AEdge0.W, AEdge1.W, A.W));
836
end;
837

838
function FMA(const A, B, C: TVector2): TVector2;
839
begin
840
  Result.Init(FMA(A.X, B.X, C.X), FMA(A.Y, B.Y, C.Y));
841
end;
842

843
function FMA(const A, B, C: TVector3): TVector3;
844
begin
845
  Result.Init(FMA(A.X, B.X, C.X), FMA(A.Y, B.Y, C.Y), FMA(A.Z, B.Z, C.Z));
846
end;
847

848
function FMA(const A, B, C: TVector4): TVector4;
849
begin
850
  Result.Init(FMA(A.X, B.X, C.X), FMA(A.Y, B.Y, C.Y), FMA(A.Z, B.Z, C.Z), FMA(A.W, B.W, C.W));
851
end;
852

853
{ Matrix functions }
854

855
{$IFDEF FM_COLUMN_MAJOR}
856
function OuterProduct(const C, R: TVector2): TMatrix2;
857
var
858
  I: Integer;
859
begin
860
  for I := 0 to 1 do
861
    Result.C[I] := C * R.C[I];
862
end;
863

864
function OuterProduct(const C, R: TVector3): TMatrix3;
865
var
866
  I: Integer;
867
begin
868
  for I := 0 to 2 do
869
    Result.C[I] := C * R.C[I];
870
end;
871

872
function OuterProduct(const C, R: TVector4): TMatrix4;
873
var
874
  I: Integer;
875
begin
876
  for I := 0 to 3 do
877
    Result.C[I] := C * R.C[I];
878
end;
879
{$ELSE}
880
function OuterProduct(const C, R: TVector2): TMatrix2;
881
var
882
  I: Integer;
883
begin
884
  for I := 0 to 1 do
885
    Result.R[I] := R * C.C[I];
886
end;
887

888
function OuterProduct(const C, R: TVector3): TMatrix3;
889
var
890
  I: Integer;
891
begin
892
  for I := 0 to 2 do
893
    Result.R[I] := R * C.C[I];
894
end;
895

896
function OuterProduct(const C, R: TVector4): TMatrix4;
897
var
898
  I: Integer;
899
begin
900
  for I := 0 to 3 do
901
    Result.R[I] := R * C.C[I];
902
end;
903
{$ENDIF}
904

905
{ TVector2 }
906

907
class operator TVector2.Add(const A: TVector2; const B: Single): TVector2;
908
begin
909
  Result.X := A.X + B;
910
  Result.Y := A.Y + B;
911
end;
912

913
class operator TVector2.Add(const A: Single; const B: TVector2): TVector2;
914
begin
915
  Result.X := A + B.X;
916
  Result.Y := A + B.Y;
917
end;
918

919
class operator TVector2.Add(const A, B: TVector2): TVector2;
920
begin
921
  Result.X := A.X + B.X;
922
  Result.Y := A.Y + B.Y;
923
end;
924

925
function TVector2.Distance(const AOther: TVector2): Single;
926
begin
927
  Result := (Self - AOther).Length;
928
end;
929

930
function TVector2.DistanceSquared(const AOther: TVector2): Single;
931
begin
932
  Result := (Self - AOther).LengthSquared;
933
end;
934

935
class operator TVector2.Divide(const A: TVector2; const B: Single): TVector2;
936
var
937
  InvB: Single;
938
begin
939
  InvB := 1 / B;
940
  Result.X := A.X * InvB;
941
  Result.Y := A.Y * InvB;
942
end;
943

944
class operator TVector2.Divide(const A: Single; const B: TVector2): TVector2;
945
begin
946
  Result.X := A / B.X;
947
  Result.Y := A / B.Y;
948
end;
949

950
class operator TVector2.Divide(const A, B: TVector2): TVector2;
951
begin
952
  Result.X := A.X / B.X;
953
  Result.Y := A.Y / B.Y;
954
end;
955

956
function TVector2.Dot(const AOther: TVector2): Single;
957
begin
958
  Result := (X * AOther.X) + (Y * AOther.Y);
959
end;
960

961
function TVector2.FaceForward(const I, NRef: TVector2): TVector2;
962
begin
963
  if (NRef.Dot(I) < 0) then
964
    Result := Self
965
  else
966
    Result := -Self;
967
end;
968

969
function TVector2.GetLength: Single;
970
begin
971
  Result := Sqrt((X * X) + (Y * Y));
972
end;
973

974
function TVector2.GetLengthSquared: Single;
975
begin
976
  Result := (X * X) + (Y * Y);
977
end;
978

979
class operator TVector2.Multiply(const A: TVector2; const B: Single): TVector2;
980
begin
981
  Result.X := A.X * B;
982
  Result.Y := A.Y * B;
983
end;
984

985
class operator TVector2.Multiply(const A: Single; const B: TVector2): TVector2;
986
begin
987
  Result.X := A * B.X;
988
  Result.Y := A * B.Y;
989
end;
990

991
class operator TVector2.Multiply(const A, B: TVector2): TVector2;
992
begin
993
  Result.X := A.X * B.X;
994
  Result.Y := A.Y * B.Y;
995
end;
996

997
function TVector2.NormalizeFast: TVector2;
998
begin
999
  Result := Self * InverseSqrt(Self.LengthSquared);
1000
end;
1001

1002
function TVector2.Reflect(const N: TVector2): TVector2;
1003
begin
1004
  Result := Self - ((2 * N.Dot(Self)) * N);
1005
end;
1006

1007
function TVector2.Refract(const N: TVector2; const Eta: Single): TVector2;
1008
var
1009
  D, K: Single;
1010
begin
1011
  D := N.Dot(Self);
1012
  K := 1 - Eta * Eta * (1 - D * D);
1013
  if (K < 0) then
1014
    Result.Init
1015
  else
1016
    Result := (Eta * Self) - ((Eta * D + Sqrt(K)) * N);
1017
end;
1018

1019
procedure TVector2.SetNormalizedFast;
1020
begin
1021
  Self := Self * InverseSqrt(Self.LengthSquared);
1022
end;
1023

1024
class operator TVector2.Subtract(const A: TVector2; const B: Single): TVector2;
1025
begin
1026
  Result.X := A.X - B;
1027
  Result.Y := A.Y - B;
1028
end;
1029

1030
class operator TVector2.Subtract(const A: Single; const B: TVector2): TVector2;
1031
begin
1032
  Result.X := A - B.X;
1033
  Result.Y := A - B.Y;
1034
end;
1035

1036
class operator TVector2.Subtract(const A, B: TVector2): TVector2;
1037
begin
1038
  Result.X := A.X - B.X;
1039
  Result.Y := A.Y - B.Y;
1040
end;
1041

1042
{ TVector3 }
1043

1044
class operator TVector3.Add(const A: TVector3; const B: Single): TVector3;
1045
begin
1046
  Result.X := A.X + B;
1047
  Result.Y := A.Y + B;
1048
  Result.Z := A.Z + B;
1049
end;
1050

1051
class operator TVector3.Add(const A: Single; const B: TVector3): TVector3;
1052
begin
1053
  Result.X := A + B.X;
1054
  Result.Y := A + B.Y;
1055
  Result.Z := A + B.Z;
1056
end;
1057

1058
class operator TVector3.Add(const A, B: TVector3): TVector3;
1059
begin
1060
  Result.X := A.X + B.X;
1061
  Result.Y := A.Y + B.Y;
1062
  Result.Z := A.Z + B.Z;
1063
end;
1064

1065
function TVector3.Distance(const AOther: TVector3): Single;
1066
begin
1067
  Result := (Self - AOther).Length;
1068
end;
1069

1070
function TVector3.DistanceSquared(const AOther: TVector3): Single;
1071
begin
1072
  Result := (Self - AOther).LengthSquared;
1073
end;
1074

1075
class operator TVector3.Divide(const A: TVector3; const B: Single): TVector3;
1076
var
1077
  InvB: Single;
1078
begin
1079
  InvB := 1 / B;
1080
  Result.X := A.X * InvB;
1081
  Result.Y := A.Y * InvB;
1082
  Result.Z := A.Z * InvB;
1083
end;
1084

1085
class operator TVector3.Divide(const A: Single; const B: TVector3): TVector3;
1086
begin
1087
  Result.X := A / B.X;
1088
  Result.Y := A / B.Y;
1089
  Result.Z := A / B.Z;
1090
end;
1091

1092
class operator TVector3.Divide(const A, B: TVector3): TVector3;
1093
begin
1094
  Result.X := A.X / B.X;
1095
  Result.Y := A.Y / B.Y;
1096
  Result.Z := A.Z / B.Z;
1097
end;
1098

1099
function TVector3.Cross(const AOther: TVector3): TVector3;
1100
begin
1101
  Result.X := (Y * AOther.Z) - (AOther.Y * Z);
1102
  Result.Y := (Z * AOther.X) - (AOther.Z * X);
1103
  Result.Z := (X * AOther.Y) - (AOther.X * Y);
1104
end;
1105

1106
function TVector3.Dot(const AOther: TVector3): Single;
1107
begin
1108
  Result := (X * AOther.X) + (Y * AOther.Y) + (Z * AOther.Z);
1109
end;
1110

1111
function TVector3.FaceForward(const I, NRef: TVector3): TVector3;
1112
begin
1113
  if (NRef.Dot(I) < 0) then
1114
    Result := Self
1115
  else
1116
    Result := -Self;
1117
end;
1118

1119
function TVector3.GetLength: Single;
1120
begin
1121
  Result := Sqrt((X * X) + (Y * Y) + (Z * Z));
1122
end;
1123

1124
function TVector3.GetLengthSquared: Single;
1125
begin
1126
  Result := (X * X) + (Y * Y) + (Z * Z);
1127
end;
1128

1129
class operator TVector3.Multiply(const A: TVector3; const B: Single): TVector3;
1130
begin
1131
  Result.X := A.X * B;
1132
  Result.Y := A.Y * B;
1133
  Result.Z := A.Z * B;
1134
end;
1135

1136
class operator TVector3.Multiply(const A: Single; const B: TVector3): TVector3;
1137
begin
1138
  Result.X := A * B.X;
1139
  Result.Y := A * B.Y;
1140
  Result.Z := A * B.Z;
1141
end;
1142

1143
class operator TVector3.Multiply(const A, B: TVector3): TVector3;
1144
begin
1145
  Result.X := A.X * B.X;
1146
  Result.Y := A.Y * B.Y;
1147
  Result.Z := A.Z * B.Z;
1148
end;
1149

1150
class operator TVector3.Negative(const A: TVector3): TVector3;
1151
begin
1152
  Result.X := -A.X;
1153
  Result.Y := -A.Y;
1154
  Result.Z := -A.Z;
1155
end;
1156

1157
function TVector3.NormalizeFast: TVector3;
1158
begin
1159
  Result := Self * InverseSqrt(Self.LengthSquared);
1160
end;
1161

1162
function TVector3.Reflect(const N: TVector3): TVector3;
1163
begin
1164
  Result := Self - ((2 * N.Dot(Self)) * N);
1165
end;
1166

1167
function TVector3.Refract(const N: TVector3; const Eta: Single): TVector3;
1168
var
1169
  D, K: Single;
1170
begin
1171
  D := N.Dot(Self);
1172
  K := 1 - Eta * Eta * (1 - D * D);
1173
  if (K < 0) then
1174
    Result.Init
1175
  else
1176
    Result := (Eta * Self) - ((Eta * D + Sqrt(K)) * N);
1177
end;
1178

1179
procedure TVector3.SetNormalizedFast;
1180
begin
1181
  Self := Self * InverseSqrt(Self.LengthSquared);
1182
end;
1183

1184
class operator TVector3.Subtract(const A: TVector3; const B: Single): TVector3;
1185
begin
1186
  Result.X := A.X - B;
1187
  Result.Y := A.Y - B;
1188
  Result.Z := A.Z - B;
1189
end;
1190

1191
class operator TVector3.Subtract(const A: Single; const B: TVector3): TVector3;
1192
begin
1193
  Result.X := A - B.X;
1194
  Result.Y := A - B.Y;
1195
  Result.Z := A - B.Z;
1196
end;
1197

1198
class operator TVector3.Subtract(const A, B: TVector3): TVector3;
1199
begin
1200
  Result.X := A.X - B.X;
1201
  Result.Y := A.Y - B.Y;
1202
  Result.Z := A.Z - B.Z;
1203
end;
1204

1205
{ TVector4 }
1206

1207
class operator TVector4.Add(const A: TVector4; const B: Single): TVector4;
1208
begin
1209
  Result.X := A.X + B;
1210
  Result.Y := A.Y + B;
1211
  Result.Z := A.Z + B;
1212
  Result.W := A.W + B;
1213
end;
1214

1215
class operator TVector4.Add(const A: Single; const B: TVector4): TVector4;
1216
begin
1217
  Result.X := A + B.X;
1218
  Result.Y := A + B.Y;
1219
  Result.Z := A + B.Z;
1220
  Result.W := A + B.W;
1221
end;
1222

1223
class operator TVector4.Add(const A, B: TVector4): TVector4;
1224
begin
1225
  Result.X := A.X + B.X;
1226
  Result.Y := A.Y + B.Y;
1227
  Result.Z := A.Z + B.Z;
1228
  Result.W := A.W + B.W;
1229
end;
1230

1231
function TVector4.Distance(const AOther: TVector4): Single;
1232
begin
1233
  Result := (Self - AOther).Length;
1234
end;
1235

1236
function TVector4.DistanceSquared(const AOther: TVector4): Single;
1237
begin
1238
  Result := (Self - AOther).LengthSquared;
1239
end;
1240

1241
class operator TVector4.Divide(const A: TVector4; const B: Single): TVector4;
1242
begin
1243
  Result.X := A.X / B;
1244
  Result.Y := A.Y / B;
1245
  Result.Z := A.Z / B;
1246
  Result.W := A.W / B;
1247
end;
1248

1249
class operator TVector4.Divide(const A: Single; const B: TVector4): TVector4;
1250
begin
1251
  Result.X := A / B.X;
1252
  Result.Y := A / B.Y;
1253
  Result.Z := A / B.Z;
1254
  Result.W := A / B.W;
1255
end;
1256

1257
class operator TVector4.Divide(const A, B: TVector4): TVector4;
1258
begin
1259
  Result.X := A.X / B.X;
1260
  Result.Y := A.Y / B.Y;
1261
  Result.Z := A.Z / B.Z;
1262
  Result.W := A.W / B.W;
1263
end;
1264

1265
function TVector4.Dot(const AOther: TVector4): Single;
1266
begin
1267
  Result := (X * AOther.X) + (Y * AOther.Y) + (Z * AOther.Z) + (W * AOther.W);
1268
end;
1269

1270
function TVector4.FaceForward(const I, NRef: TVector4): TVector4;
1271
begin
1272
  if (NRef.Dot(I) < 0) then
1273
    Result := Self
1274
  else
1275
    Result := -Self;
1276
end;
1277

1278
function TVector4.GetLength: Single;
1279
begin
1280
  Result := Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W));
1281
end;
1282

1283
function TVector4.GetLengthSquared: Single;
1284
begin
1285
  Result := (X * X) + (Y * Y) + (Z * Z) + (W * W);
1286
end;
1287

1288
class operator TVector4.Multiply(const A: TVector4; const B: Single): TVector4;
1289
begin
1290
  Result.X := A.X * B;
1291
  Result.Y := A.Y * B;
1292
  Result.Z := A.Z * B;
1293
  Result.W := A.W * B;
1294
end;
1295

1296
class operator TVector4.Multiply(const A: Single; const B: TVector4): TVector4;
1297
begin
1298
  Result.X := A * B.X;
1299
  Result.Y := A * B.Y;
1300
  Result.Z := A * B.Z;
1301
  Result.W := A * B.W;
1302
end;
1303

1304
class operator TVector4.Multiply(const A, B: TVector4): TVector4;
1305
begin
1306
  Result.X := A.X * B.X;
1307
  Result.Y := A.Y * B.Y;
1308
  Result.Z := A.Z * B.Z;
1309
  Result.W := A.W * B.W;
1310
end;
1311

1312
class operator TVector4.Negative(const A: TVector4): TVector4;
1313
begin
1314
  Result.X := -A.X;
1315
  Result.Y := -A.Y;
1316
  Result.Z := -A.Z;
1317
  Result.W := -A.W;
1318
end;
1319

1320
function TVector4.NormalizeFast: TVector4;
1321
begin
1322
  Result := Self * InverseSqrt(Self.LengthSquared);
1323
end;
1324

1325
function TVector4.Reflect(const N: TVector4): TVector4;
1326
begin
1327
  Result := Self - ((2 * N.Dot(Self)) * N);
1328
end;
1329

1330
function TVector4.Refract(const N: TVector4; const Eta: Single): TVector4;
1331
var
1332
  D, K: Single;
1333
begin
1334
  D := N.Dot(Self);
1335
  K := 1 - Eta * Eta * (1 - D * D);
1336
  if (K < 0) then
1337
    Result.Init
1338
  else
1339
    Result := (Eta * Self) - ((Eta * D + Sqrt(K)) * N);
1340
end;
1341

1342
procedure TVector4.SetNormalizedFast;
1343
begin
1344
  Self := Self * InverseSqrt(Self.LengthSquared);
1345
end;
1346

1347
class operator TVector4.Subtract(const A: TVector4; const B: Single): TVector4;
1348
begin
1349
  Result.X := A.X - B;
1350
  Result.Y := A.Y - B;
1351
  Result.Z := A.Z - B;
1352
  Result.W := A.W - B;
1353
end;
1354

1355
class operator TVector4.Subtract(const A: Single; const B: TVector4): TVector4;
1356
begin
1357
  Result.X := A - B.X;
1358
  Result.Y := A - B.Y;
1359
  Result.Z := A - B.Z;
1360
  Result.W := A - B.W;
1361
end;
1362

1363
class operator TVector4.Subtract(const A, B: TVector4): TVector4;
1364
begin
1365
  Result.X := A.X - B.X;
1366
  Result.Y := A.Y - B.Y;
1367
  Result.Z := A.Z - B.Z;
1368
  Result.W := A.W - B.W;
1369
end;
1370

1371
{ TQuaternion }
1372

1373
class operator TQuaternion.Add(const A, B: TQuaternion): TQuaternion;
1374
begin
1375
  Result.X := A.X + B.X;
1376
  Result.Y := A.Y + B.Y;
1377
  Result.Z := A.Z + B.Z;
1378
  Result.W := A.W + B.W;
1379
end;
1380

1381
function TQuaternion.GetLength: Single;
1382
begin
1383
  Result := Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W));
1384
end;
1385

1386
function TQuaternion.GetLengthSquared: Single;
1387
begin
1388
  Result := (X * X) + (Y * Y) + (Z * Z) + (W * W);
1389
end;
1390

1391
class operator TQuaternion.Multiply(const A: TQuaternion; const B: Single): TQuaternion;
1392
begin
1393
  Result.X := A.X * B;
1394
  Result.Y := A.Y * B;
1395
  Result.Z := A.Z * B;
1396
  Result.W := A.W * B;
1397
end;
1398

1399
class operator TQuaternion.Multiply(const A: Single; const B: TQuaternion): TQuaternion;
1400
begin
1401
  Result.X := A * B.X;
1402
  Result.Y := A * B.Y;
1403
  Result.Z := A * B.Z;
1404
  Result.W := A * B.W;
1405
end;
1406

1407
class operator TQuaternion.Multiply(const A, B: TQuaternion): TQuaternion;
1408
begin
1409
  Result.X := (A.W * B.X) + (A.X * B.W) + (A.Y * B.Z) - (A.Z * B.Y);
1410
  Result.Y := (A.W * B.Y) + (A.Y * B.W) + (A.Z * B.X) - (A.X * B.Z);
1411
  Result.Z := (A.W * B.Z) + (A.Z * B.W) + (A.X * B.Y) - (A.Y * B.X);
1412
  Result.W := (A.W * B.W) - (A.X * B.X) - (A.Y * B.Y) - (A.Z * B.Z);
1413
end;
1414

1415
function TQuaternion.NormalizeFast: TQuaternion;
1416
begin
1417
  Result := Self * InverseSqrt(Self.LengthSquared);
1418
end;
1419

1420
procedure TQuaternion.SetNormalizedFast;
1421
begin
1422
  Self := Self * InverseSqrt(Self.LengthSquared);
1423
end;
1424

1425
{ TMatrix 2 }
1426

1427
class operator TMatrix2.Add(const A: TMatrix2; const B: Single): TMatrix2;
1428
begin
1429
  Result.V[0] := A.V[0] + B;
1430
  Result.V[1] := A.V[1] + B;
1431
end;
1432

1433
class operator TMatrix2.Add(const A: Single; const B: TMatrix2): TMatrix2;
1434
begin
1435
  Result.V[0] := A + B.V[0];
1436
  Result.V[1] := A + B.V[1];
1437
end;
1438

1439
class operator TMatrix2.Add(const A, B: TMatrix2): TMatrix2;
1440
begin
1441
  Result.V[0] := A.V[0] + B.V[0];
1442
  Result.V[1] := A.V[1] + B.V[1];
1443
end;
1444

1445
function TMatrix2.CompMult(const AOther: TMatrix2): TMatrix2;
1446
var
1447
  I: Integer;
1448
begin
1449
  for I := 0 to 1 do
1450
    Result.V[I] := V[I] * AOther.V[I];
1451
end;
1452

1453
class operator TMatrix2.Divide(const A: Single; const B: TMatrix2): TMatrix2;
1454
begin
1455
  Result.V[0] := A / B.V[0];
1456
  Result.V[1] := A / B.V[1];
1457
end;
1458

1459
class operator TMatrix2.Divide(const A: TMatrix2; const B: Single): TMatrix2;
1460
var
1461
  InvB: Single;
1462
begin
1463
  InvB := 1 / B;
1464
  Result.V[0] := A.V[0] * InvB;
1465
  Result.V[1] := A.V[1] * InvB;
1466
end;
1467

1468
class operator TMatrix2.Multiply(const A: Single; const B: TMatrix2): TMatrix2;
1469
begin
1470
  Result.V[0] := A * B.V[0];
1471
  Result.V[1] := A * B.V[1];
1472
end;
1473

1474
class operator TMatrix2.Multiply(const A: TMatrix2; const B: Single): TMatrix2;
1475
begin
1476
  Result.V[0] := A.V[0] * B;
1477
  Result.V[1] := A.V[1] * B;
1478
end;
1479

1480
class operator TMatrix2.Multiply(const A: TVector2; const B: TMatrix2): TVector2;
1481
begin
1482
  Result.X := (A.X * B.M[0,0]) + (A.Y * B.M[0,1]);
1483
  Result.Y := (A.X * B.M[1,0]) + (A.Y * B.M[1,1]);
1484
end;
1485

1486
class operator TMatrix2.Multiply(const A: TMatrix2; const B: TVector2): TVector2;
1487
begin
1488
  Result.X := (A.M[0,0] * B.X) + (A.M[1,0] * B.Y);
1489
  Result.Y := (A.M[0,1] * B.X) + (A.M[1,1] * B.Y);
1490
end;
1491

1492
class operator TMatrix2.Multiply(const A, B: TMatrix2): TMatrix2;
1493
begin
1494
  Result.M[0,0] := (A.M[0,0] * B.M[0,0]) + (A.M[1,0] * B.M[0,1]);
1495
  Result.M[0,1] := (A.M[0,1] * B.M[0,0]) + (A.M[1,1] * B.M[0,1]);
1496
  Result.M[1,0] := (A.M[0,0] * B.M[1,0]) + (A.M[1,0] * B.M[1,1]);
1497
  Result.M[1,1] := (A.M[0,1] * B.M[1,0]) + (A.M[1,1] * B.M[1,1]);
1498
end;
1499

1500
class operator TMatrix2.Negative(const A: TMatrix2): TMatrix2;
1501
begin
1502
  Result.V[0] := -A.V[0];
1503
  Result.V[1] := -A.V[1];
1504
end;
1505

1506
procedure TMatrix2.SetTransposed;
1507
begin
1508
  Self := Transpose;
1509
end;
1510

1511
class operator TMatrix2.Subtract(const A: TMatrix2; const B: Single): TMatrix2;
1512
begin
1513
  Result.V[0] := A.V[0] - B;
1514
  Result.V[1] := A.V[1] - B;
1515
end;
1516

1517
class operator TMatrix2.Subtract(const A, B: TMatrix2): TMatrix2;
1518
begin
1519
  Result.V[0] := A.V[0] - B.V[0];
1520
  Result.V[1] := A.V[1] - B.V[1];
1521
end;
1522

1523
class operator TMatrix2.Subtract(const A: Single; const B: TMatrix2): TMatrix2;
1524
begin
1525
  Result.V[0] := A - B.V[0];
1526
  Result.V[1] := A - B.V[1];
1527
end;
1528

1529
function TMatrix2.Transpose: TMatrix2;
1530
begin
1531
  Result.M[0,0] := M[0,0];
1532
  Result.M[0,1] := M[1,0];
1533

1534
  Result.M[1,0] := M[0,1];
1535
  Result.M[1,1] := M[1,1];
1536
end;
1537

1538
{ TMatrix3 }
1539

1540
class operator TMatrix3.Add(const A: TMatrix3; const B: Single): TMatrix3;
1541
begin
1542
  Result.V[0] := A.V[0] + B;
1543
  Result.V[1] := A.V[1] + B;
1544
  Result.V[2] := A.V[2] + B;
1545
end;
1546

1547
class operator TMatrix3.Add(const A: Single; const B: TMatrix3): TMatrix3;
1548
begin
1549
  Result.V[0] := A + B.V[0];
1550
  Result.V[1] := A + B.V[1];
1551
  Result.V[2] := A + B.V[2];
1552
end;
1553

1554
class operator TMatrix3.Add(const A, B: TMatrix3): TMatrix3;
1555
begin
1556
  Result.V[0] := A.V[0] + B.V[0];
1557
  Result.V[1] := A.V[1] + B.V[1];
1558
  Result.V[2] := A.V[2] + B.V[2];
1559
end;
1560

1561
function TMatrix3.CompMult(const AOther: TMatrix3): TMatrix3;
1562
var
1563
  I: Integer;
1564
begin
1565
  for I := 0 to 2 do
1566
    Result.V[I] := V[I] * AOther.V[I];
1567
end;
1568

1569
class operator TMatrix3.Divide(const A: Single; const B: TMatrix3): TMatrix3;
1570
begin
1571
  Result.V[0] := A / B.V[0];
1572
  Result.V[1] := A / B.V[1];
1573
  Result.V[2] := A / B.V[2];
1574
end;
1575

1576
class operator TMatrix3.Divide(const A: TMatrix3; const B: Single): TMatrix3;
1577
var
1578
  InvB: Single;
1579
begin
1580
  InvB := 1 / B;
1581
  Result.V[0] := A.V[0] * InvB;
1582
  Result.V[1] := A.V[1] * InvB;
1583
  Result.V[2] := A.V[2] * InvB;
1584
end;
1585

1586
class operator TMatrix3.Multiply(const A: Single; const B: TMatrix3): TMatrix3;
1587
begin
1588
  Result.V[0] := A * B.V[0];
1589
  Result.V[1] := A * B.V[1];
1590
  Result.V[2] := A * B.V[2];
1591
end;
1592

1593
class operator TMatrix3.Multiply(const A: TMatrix3; const B: Single): TMatrix3;
1594
begin
1595
  Result.V[0] := A.V[0] * B;
1596
  Result.V[1] := A.V[1] * B;
1597
  Result.V[2] := A.V[2] * B;
1598
end;
1599

1600
{$IFDEF FM_COLUMN_MAJOR}
1601
class operator TMatrix3.Multiply(const A: TMatrix3; const B: TVector3): TVector3;
1602
begin
1603
  Result.X := (B.X * A.M[0,0]) + (B.Y * A.M[1,0]) + (B.Z * A.M[2,0]);
1604
  Result.Y := (B.X * A.M[0,1]) + (B.Y * A.M[1,1]) + (B.Z * A.M[2,1]);
1605
  Result.Z := (B.X * A.M[0,2]) + (B.Y * A.M[1,2]) + (B.Z * A.M[2,2]);
1606
end;
1607

1608
class operator TMatrix3.Multiply(const A: TVector3; const B: TMatrix3): TVector3;
1609
begin
1610
  Result.X := (B.M[0,0] * A.X) + (B.M[0,1] * A.Y) + (B.M[0,2] * A.Z);
1611
  Result.Y := (B.M[1,0] * A.X) + (B.M[1,1] * A.Y) + (B.M[1,2] * A.Z);
1612
  Result.Z := (B.M[2,0] * A.X) + (B.M[2,1] * A.Y) + (B.M[2,2] * A.Z);
1613
end;
1614
{$ELSE}
1615
class operator TMatrix3.Multiply(const A: TMatrix3; const B: TVector3): TVector3;
1616
begin
1617
  Result.X := (B.X * A.M[0,0]) + (B.Y * A.M[0,1]) + (B.Z * A.M[0,2]);
1618
  Result.Y := (B.X * A.M[1,0]) + (B.Y * A.M[1,1]) + (B.Z * A.M[1,2]);
1619
  Result.Z := (B.X * A.M[2,0]) + (B.Y * A.M[2,1]) + (B.Z * A.M[2,2]);
1620
end;
1621

1622
class operator TMatrix3.Multiply(const A: TVector3; const B: TMatrix3): TVector3;
1623
begin
1624
  Result.X := (B.M[0,0] * A.X) + (B.M[1,0] * A.Y) + (B.M[2,0] * A.Z);
1625
  Result.Y := (B.M[0,1] * A.X) + (B.M[1,1] * A.Y) + (B.M[2,1] * A.Z);
1626
  Result.Z := (B.M[0,2] * A.X) + (B.M[1,2] * A.Y) + (B.M[2,2] * A.Z);
1627
end;
1628
{$ENDIF}
1629

1630
class operator TMatrix3.Multiply(const A, B: TMatrix3): TMatrix3;
1631
var
1632
  A00, A01, A02, A10, A11, A12, A20, A21, A22: Single;
1633
  B00, B01, B02, B10, B11, B12, B20, B21, B22: Single;
1634
begin
1635
  A00 := A.M[0,0];
1636
  A01 := A.M[0,1];
1637
  A02 := A.M[0,2];
1638
  A10 := A.M[1,0];
1639
  A11 := A.M[1,1];
1640
  A12 := A.M[1,2];
1641
  A20 := A.M[2,0];
1642
  A21 := A.M[2,1];
1643
  A22 := A.M[2,2];
1644

1645
  B00 := B.M[0,0];
1646
  B01 := B.M[0,1];
1647
  B02 := B.M[0,2];
1648
  B10 := B.M[1,0];
1649
  B11 := B.M[1,1];
1650
  B12 := B.M[1,2];
1651
  B20 := B.M[2,0];
1652
  B21 := B.M[2,1];
1653
  B22 := B.M[2,2];
1654

1655
  {$IFDEF FM_COLUMN_MAJOR}
1656
  Result.M[0,0] := (A00 * B00) + (A10 * B01) + (A20 * B02);
1657
  Result.M[0,1] := (A01 * B00) + (A11 * B01) + (A21 * B02);
1658
  Result.M[0,2] := (A02 * B00) + (A12 * B01) + (A22 * B02);
1659
  Result.M[1,0] := (A00 * B10) + (A10 * B11) + (A20 * B12);
1660
  Result.M[1,1] := (A01 * B10) + (A11 * B11) + (A21 * B12);
1661
  Result.M[1,2] := (A02 * B10) + (A12 * B11) + (A22 * B12);
1662
  Result.M[2,0] := (A00 * B20) + (A10 * B21) + (A20 * B22);
1663
  Result.M[2,1] := (A01 * B20) + (A11 * B21) + (A21 * B22);
1664
  Result.M[2,2] := (A02 * B20) + (A12 * B21) + (A22 * B22);
1665
  {$ELSE}
1666
  Result.M[0,0] := (A00 * B00) + (A01 * B10) + (A02 * B20);
1667
  Result.M[0,1] := (A00 * B01) + (A01 * B11) + (A02 * B21);
1668
  Result.M[0,2] := (A00 * B02) + (A01 * B12) + (A02 * B22);
1669
  Result.M[1,0] := (A10 * B00) + (A11 * B10) + (A12 * B20);
1670
  Result.M[1,1] := (A10 * B01) + (A11 * B11) + (A12 * B21);
1671
  Result.M[1,2] := (A10 * B02) + (A11 * B12) + (A12 * B22);
1672
  Result.M[2,0] := (A20 * B00) + (A21 * B10) + (A22 * B20);
1673
  Result.M[2,1] := (A20 * B01) + (A21 * B11) + (A22 * B21);
1674
  Result.M[2,2] := (A20 * B02) + (A21 * B12) + (A22 * B22);
1675
  {$ENDIF}
1676
end;
1677

1678
class operator TMatrix3.Negative(const A: TMatrix3): TMatrix3;
1679
begin
1680
  Result.V[0] := -A.V[0];
1681
  Result.V[1] := -A.V[1];
1682
  Result.V[2] := -A.V[2];
1683
end;
1684

1685
procedure TMatrix3.SetTransposed;
1686
begin
1687
  Self := Transpose;
1688
end;
1689

1690
class operator TMatrix3.Subtract(const A: TMatrix3; const B: Single): TMatrix3;
1691
begin
1692
  Result.V[0] := A.V[0] - B;
1693
  Result.V[1] := A.V[1] - B;
1694
  Result.V[2] := A.V[2] - B;
1695
end;
1696

1697
class operator TMatrix3.Subtract(const A, B: TMatrix3): TMatrix3;
1698
begin
1699
  Result.V[0] := A.V[0] - B.V[0];
1700
  Result.V[1] := A.V[1] - B.V[1];
1701
  Result.V[2] := A.V[2] - B.V[2];
1702
end;
1703

1704
class operator TMatrix3.Subtract(const A: Single; const B: TMatrix3): TMatrix3;
1705
begin
1706
  Result.V[0] := A - B.V[0];
1707
  Result.V[1] := A - B.V[1];
1708
  Result.V[2] := A - B.V[2];
1709
end;
1710

1711
function TMatrix3.Transpose: TMatrix3;
1712
begin
1713
  Result.M[0,0] := M[0,0];
1714
  Result.M[0,1] := M[1,0];
1715
  Result.M[0,2] := M[2,0];
1716

1717
  Result.M[1,0] := M[0,1];
1718
  Result.M[1,1] := M[1,1];
1719
  Result.M[1,2] := M[2,1];
1720

1721
  Result.M[2,0] := M[0,2];
1722
  Result.M[2,1] := M[1,2];
1723
  Result.M[2,2] := M[2,2];
1724
end;
1725

1726
{ TMatrix 4 }
1727

1728
class operator TMatrix4.Add(const A: TMatrix4; const B: Single): TMatrix4;
1729
begin
1730
  Result.V[0] := A.V[0] + B;
1731
  Result.V[1] := A.V[1] + B;
1732
  Result.V[2] := A.V[2] + B;
1733
  Result.V[3] := A.V[3] + B;
1734
end;
1735

1736
class operator TMatrix4.Add(const A: Single; const B: TMatrix4): TMatrix4;
1737
begin
1738
  Result.V[0] := A + B.V[0];
1739
  Result.V[1] := A + B.V[1];
1740
  Result.V[2] := A + B.V[2];
1741
  Result.V[3] := A + B.V[3];
1742
end;
1743

1744
class operator TMatrix4.Add(const A, B: TMatrix4): TMatrix4;
1745
begin
1746
  Result.V[0] := A.V[0] + B.V[0];
1747
  Result.V[1] := A.V[1] + B.V[1];
1748
  Result.V[2] := A.V[2] + B.V[2];
1749
  Result.V[3] := A.V[3] + B.V[3];
1750
end;
1751

1752
function TMatrix4.CompMult(const AOther: TMatrix4): TMatrix4;
1753
var
1754
  I: Integer;
1755
begin
1756
  for I := 0 to 3 do
1757
    Result.V[I] := V[I] * AOther.V[I];
1758
end;
1759

1760
class operator TMatrix4.Divide(const A: Single; const B: TMatrix4): TMatrix4;
1761
begin
1762
  Result.V[0] := A / B.V[0];
1763
  Result.V[1] := A / B.V[1];
1764
  Result.V[2] := A / B.V[2];
1765
  Result.V[3] := A / B.V[3];
1766
end;
1767

1768
class operator TMatrix4.Divide(const A: TMatrix4; const B: Single): TMatrix4;
1769
var
1770
  InvB: Single;
1771
begin
1772
  InvB := 1 / B;
1773
  Result.V[0] := A.V[0] * InvB;
1774
  Result.V[1] := A.V[1] * InvB;
1775
  Result.V[2] := A.V[2] * InvB;
1776
  Result.V[3] := A.V[3] * InvB;
1777
end;
1778

1779
function TMatrix4.Inverse: TMatrix4;
1780
var
1781
  C00, C02, C03, C04, C06, C07, C08, C10, C11: Single;
1782
  C12, C14, C15, C16, C18, C19, C20, C22, C23: Single;
1783
  F0, F1, F2, F3, F4, F5, V0, V1, V2, V3, I0, I1, I2, I3, SA, SB, Row, Dot: TVector4;
1784
  Inv: TMatrix4;
1785
  OneOverDeterminant: Single;
1786
begin
1787
  C00 := (M[2,2] * M[3,3]) - (M[3,2] * M[2,3]);
1788
  C02 := (M[1,2] * M[3,3]) - (M[3,2] * M[1,3]);
1789
  C03 := (M[1,2] * M[2,3]) - (M[2,2] * M[1,3]);
1790

1791
  C04 := (M[2,1] * M[3,3]) - (M[3,1] * M[2,3]);
1792
  C06 := (M[1,1] * M[3,3]) - (M[3,1] * M[1,3]);
1793
  C07 := (M[1,1] * M[2,3]) - (M[2,1] * M[1,3]);
1794

1795
  C08 := (M[2,1] * M[3,2]) - (M[3,1] * M[2,2]);
1796
  C10 := (M[1,1] * M[3,2]) - (M[3,1] * M[1,2]);
1797
  C11 := (M[1,1] * M[2,2]) - (M[2,1] * M[1,2]);
1798

1799
  C12 := (M[2,0] * M[3,3]) - (M[3,0] * M[2,3]);
1800
  C14 := (M[1,0] * M[3,3]) - (M[3,0] * M[1,3]);
1801
  C15 := (M[1,0] * M[2,3]) - (M[2,0] * M[1,3]);
1802

1803
  C16 := (M[2,0] * M[3,2]) - (M[3,0] * M[2,2]);
1804
  C18 := (M[1,0] * M[3,2]) - (M[3,0] * M[1,2]);
1805
  C19 := (M[1,0] * M[2,2]) - (M[2,0] * M[1,2]);
1806

1807
  C20 := (M[2,0] * M[3,1]) - (M[3,0] * M[2,1]);
1808
  C22 := (M[1,0] * M[3,1]) - (M[3,0] * M[1,1]);
1809
  C23 := (M[1,0] * M[2,1]) - (M[2,0] * M[1,1]);
1810

1811
  F0 := Vector4(C00, C00, C02, C03);
1812
  F1 := Vector4(C04, C04, C06, C07);
1813
  F2 := Vector4(C08, C08, C10, C11);
1814
  F3 := Vector4(C12, C12, C14, C15);
1815
  F4 := Vector4(C16, C16, C18, C19);
1816
  F5 := Vector4(C20, C20, C22, C23);
1817

1818
  V0 := Vector4(M[1,0], M[0,0], M[0,0], M[0,0]);
1819
  V1 := Vector4(M[1,1], M[0,1], M[0,1], M[0,1]);
1820
  V2 := Vector4(M[1,2], M[0,2], M[0,2], M[0,2]);
1821
  V3 := Vector4(M[1,3], M[0,3], M[0,3], M[0,3]);
1822

1823
  I0 := (V1 * F0) - (V2 * F1) + (V3 * F2);
1824
  I1 := (V0 * F0) - (V2 * F3) + (V3 * F4);
1825
  I2 := (V0 * F1) - (V1 * F3) + (V3 * F5);
1826
  I3 := (V0 * F2) - (V1 * F4) + (V2 * F5);
1827

1828
  SA := Vector4(+1, -1, +1, -1);
1829
  SB := Vector4(-1, +1, -1, +1);
1830

1831
  Inv := Matrix4(I0 * SA, I1 * SB, I2 * SA, I3 * SB);
1832

1833
  Row := Vector4(Inv[0,0], Inv[1,0], Inv[2,0], Inv[3,0]);
1834
  Dot := V[0] * Row;
1835

1836
  OneOverDeterminant := 1 / ((Dot.X + Dot.Y) + (Dot.Z + Dot.W));
1837
  Result := Inv * OneOverDeterminant;
1838
end;
1839

1840
class operator TMatrix4.Multiply(const A: Single; const B: TMatrix4): TMatrix4;
1841
begin
1842
  Result.V[0] := A * B.V[0];
1843
  Result.V[1] := A * B.V[1];
1844
  Result.V[2] := A * B.V[2];
1845
  Result.V[3] := A * B.V[3];
1846
end;
1847

1848
class operator TMatrix4.Multiply(const A: TMatrix4; const B: Single): TMatrix4;
1849
begin
1850
  Result.V[0] := A.V[0] * B;
1851
  Result.V[1] := A.V[1] * B;
1852
  Result.V[2] := A.V[2] * B;
1853
  Result.V[3] := A.V[3] * B;
1854
end;
1855

1856
{$IFDEF FM_COLUMN_MAJOR}
1857
class operator TMatrix4.Multiply(const A: TVector4; const B: TMatrix4): TVector4;
1858
begin
1859
  Result.X := (A.X * B.M[0,0]) + (A.Y * B.M[0,1]) + (A.Z * B.M[0,2]) + (A.W * B.M[0,3]);
1860
  Result.Y := (A.X * B.M[1,0]) + (A.Y * B.M[1,1]) + (A.Z * B.M[1,2]) + (A.W * B.M[1,3]);
1861
  Result.Z := (A.X * B.M[2,0]) + (A.Y * B.M[2,1]) + (A.Z * B.M[2,2]) + (A.W * B.M[2,3]);
1862
  Result.W := (A.X * B.M[3,0]) + (A.Y * B.M[3,1]) + (A.Z * B.M[3,2]) + (A.W * B.M[3,3]);
1863
end;
1864

1865
class operator TMatrix4.Multiply(const A: TMatrix4; const B: TVector4): TVector4;
1866
begin
1867
  Result.X := (B.X * A.M[0,0]) + (B.Y * A.M[1,0]) + (B.Z * A.M[2,0]) + (B.W * A.M[3,0]);
1868
  Result.Y := (B.X * A.M[0,1]) + (B.Y * A.M[1,1]) + (B.Z * A.M[2,1]) + (B.W * A.M[3,1]);
1869
  Result.Z := (B.X * A.M[0,2]) + (B.Y * A.M[1,2]) + (B.Z * A.M[2,2]) + (B.W * A.M[3,2]);
1870
  Result.W := (B.X * A.M[0,3]) + (B.Y * A.M[1,3]) + (B.Z * A.M[2,3]) + (B.W * A.M[3,3]);
1871
end;
1872

1873
class operator TMatrix4.Multiply(const A, B: TMatrix4): TMatrix4;
1874
begin
1875
  Result.M[0,0] := (B.M[0,0] * A.M[0,0]) + (B.M[0,1] * A.M[1,0]) + (B.M[0,2] * A.M[2,0]) + (B.M[0,3] * A.M[3,0]);
1876
  Result.M[0,1] := (B.M[0,0] * A.M[0,1]) + (B.M[0,1] * A.M[1,1]) + (B.M[0,2] * A.M[2,1]) + (B.M[0,3] * A.M[3,1]);
1877
  Result.M[0,2] := (B.M[0,0] * A.M[0,2]) + (B.M[0,1] * A.M[1,2]) + (B.M[0,2] * A.M[2,2]) + (B.M[0,3] * A.M[3,2]);
1878
  Result.M[0,3] := (B.M[0,0] * A.M[0,3]) + (B.M[0,1] * A.M[1,3]) + (B.M[0,2] * A.M[2,3]) + (B.M[0,3] * A.M[3,3]);
1879

1880
  Result.M[1,0] := (B.M[1,0] * A.M[0,0]) + (B.M[1,1] * A.M[1,0]) + (B.M[1,2] * A.M[2,0]) + (B.M[1,3] * A.M[3,0]);
1881
  Result.M[1,1] := (B.M[1,0] * A.M[0,1]) + (B.M[1,1] * A.M[1,1]) + (B.M[1,2] * A.M[2,1]) + (B.M[1,3] * A.M[3,1]);
1882
  Result.M[1,2] := (B.M[1,0] * A.M[0,2]) + (B.M[1,1] * A.M[1,2]) + (B.M[1,2] * A.M[2,2]) + (B.M[1,3] * A.M[3,2]);
1883
  Result.M[1,3] := (B.M[1,0] * A.M[0,3]) + (B.M[1,1] * A.M[1,3]) + (B.M[1,2] * A.M[2,3]) + (B.M[1,3] * A.M[3,3]);
1884

1885
  Result.M[2,0] := (B.M[2,0] * A.M[0,0]) + (B.M[2,1] * A.M[1,0]) + (B.M[2,2] * A.M[2,0]) + (B.M[2,3] * A.M[3,0]);
1886
  Result.M[2,1] := (B.M[2,0] * A.M[0,1]) + (B.M[2,1] * A.M[1,1]) + (B.M[2,2] * A.M[2,1]) + (B.M[2,3] * A.M[3,1]);
1887
  Result.M[2,2] := (B.M[2,0] * A.M[0,2]) + (B.M[2,1] * A.M[1,2]) + (B.M[2,2] * A.M[2,2]) + (B.M[2,3] * A.M[3,2]);
1888
  Result.M[2,3] := (B.M[2,0] * A.M[0,3]) + (B.M[2,1] * A.M[1,3]) + (B.M[2,2] * A.M[2,3]) + (B.M[2,3] * A.M[3,3]);
1889

1890
  Result.M[3,0] := (B.M[3,0] * A.M[0,0]) + (B.M[3,1] * A.M[1,0]) + (B.M[3,2] * A.M[2,0]) + (B.M[3,3] * A.M[3,0]);
1891
  Result.M[3,1] := (B.M[3,0] * A.M[0,1]) + (B.M[3,1] * A.M[1,1]) + (B.M[3,2] * A.M[2,1]) + (B.M[3,3] * A.M[3,1]);
1892
  Result.M[3,2] := (B.M[3,0] * A.M[0,2]) + (B.M[3,1] * A.M[1,2]) + (B.M[3,2] * A.M[2,2]) + (B.M[3,3] * A.M[3,2]);
1893
  Result.M[3,3] := (B.M[3,0] * A.M[0,3]) + (B.M[3,1] * A.M[1,3]) + (B.M[3,2] * A.M[2,3]) + (B.M[3,3] * A.M[3,3]);
1894
end;
1895
{$ELSE}
1896
class operator TMatrix4.Multiply(const A: TVector4; const B: TMatrix4): TVector4;
1897
begin
1898
  Result.X := (B.M[0,0] * A.X) + (B.M[1,0] * A.Y) + (B.M[2,0] * A.Z) + (B.M[3,0] * A.W);
1899
  Result.Y := (B.M[0,1] * A.X) + (B.M[1,1] * A.Y) + (B.M[2,1] * A.Z) + (B.M[3,1] * A.W);
1900
  Result.Z := (B.M[0,2] * A.X) + (B.M[1,2] * A.Y) + (B.M[2,2] * A.Z) + (B.M[3,2] * A.W);
1901
  Result.W := (B.M[0,3] * A.X) + (B.M[1,3] * A.Y) + (B.M[2,3] * A.Z) + (B.M[3,3] * A.W);
1902
end;
1903

1904
class operator TMatrix4.Multiply(const A: TMatrix4; const B: TVector4): TVector4;
1905
begin
1906
  Result.X := (B.X * A.M[0,0]) + (B.Y * A.M[0,1]) + (B.Z * A.M[0,2]) + (B.W * A.M[0,3]);
1907
  Result.Y := (B.X * A.M[1,0]) + (B.Y * A.M[1,1]) + (B.Z * A.M[1,2]) + (B.W * A.M[1,3]);
1908
  Result.Z := (B.X * A.M[2,0]) + (B.Y * A.M[2,1]) + (B.Z * A.M[2,2]) + (B.W * A.M[2,3]);
1909
  Result.W := (B.X * A.M[3,0]) + (B.Y * A.M[3,1]) + (B.Z * A.M[3,2]) + (B.W * A.M[3,3]);
1910
end;
1911

1912
class operator TMatrix4.Multiply(const A, B: TMatrix4): TMatrix4;
1913
begin
1914
  Result.M[0,0] := (A.M[0,0] * B.M[0,0]) + (A.M[0,1] * B.M[1,0]) + (A.M[0,2] * B.M[2,0]) + (A.M[0,3] * B.M[3,0]);
1915
  Result.M[0,1] := (A.M[0,0] * B.M[0,1]) + (A.M[0,1] * B.M[1,1]) + (A.M[0,2] * B.M[2,1]) + (A.M[0,3] * B.M[3,1]);
1916
  Result.M[0,2] := (A.M[0,0] * B.M[0,2]) + (A.M[0,1] * B.M[1,2]) + (A.M[0,2] * B.M[2,2]) + (A.M[0,3] * B.M[3,2]);
1917
  Result.M[0,3] := (A.M[0,0] * B.M[0,3]) + (A.M[0,1] * B.M[1,3]) + (A.M[0,2] * B.M[2,3]) + (A.M[0,3] * B.M[3,3]);
1918

1919
  Result.M[1,0] := (A.M[1,0] * B.M[0,0]) + (A.M[1,1] * B.M[1,0]) + (A.M[1,2] * B.M[2,0]) + (A.M[1,3] * B.M[3,0]);
1920
  Result.M[1,1] := (A.M[1,0] * B.M[0,1]) + (A.M[1,1] * B.M[1,1]) + (A.M[1,2] * B.M[2,1]) + (A.M[1,3] * B.M[3,1]);
1921
  Result.M[1,2] := (A.M[1,0] * B.M[0,2]) + (A.M[1,1] * B.M[1,2]) + (A.M[1,2] * B.M[2,2]) + (A.M[1,3] * B.M[3,2]);
1922
  Result.M[1,3] := (A.M[1,0] * B.M[0,3]) + (A.M[1,1] * B.M[1,3]) + (A.M[1,2] * B.M[2,3]) + (A.M[1,3] * B.M[3,3]);
1923

1924
  Result.M[2,0] := (A.M[2,0] * B.M[0,0]) + (A.M[2,1] * B.M[1,0]) + (A.M[2,2] * B.M[2,0]) + (A.M[2,3] * B.M[3,0]);
1925
  Result.M[2,1] := (A.M[2,0] * B.M[0,1]) + (A.M[2,1] * B.M[1,1]) + (A.M[2,2] * B.M[2,1]) + (A.M[2,3] * B.M[3,1]);
1926
  Result.M[2,2] := (A.M[2,0] * B.M[0,2]) + (A.M[2,1] * B.M[1,2]) + (A.M[2,2] * B.M[2,2]) + (A.M[2,3] * B.M[3,2]);
1927
  Result.M[2,3] := (A.M[2,0] * B.M[0,3]) + (A.M[2,1] * B.M[1,3]) + (A.M[2,2] * B.M[2,3]) + (A.M[2,3] * B.M[3,3]);
1928

1929
  Result.M[3,0] := (A.M[3,0] * B.M[0,0]) + (A.M[3,1] * B.M[1,0]) + (A.M[3,2] * B.M[2,0]) + (A.M[3,3] * B.M[3,0]);
1930
  Result.M[3,1] := (A.M[3,0] * B.M[0,1]) + (A.M[3,1] * B.M[1,1]) + (A.M[3,2] * B.M[2,1]) + (A.M[3,3] * B.M[3,1]);
1931
  Result.M[3,2] := (A.M[3,0] * B.M[0,2]) + (A.M[3,1] * B.M[1,2]) + (A.M[3,2] * B.M[2,2]) + (A.M[3,3] * B.M[3,2]);
1932
  Result.M[3,3] := (A.M[3,0] * B.M[0,3]) + (A.M[3,1] * B.M[1,3]) + (A.M[3,2] * B.M[2,3]) + (A.M[3,3] * B.M[3,3]);
1933
end;
1934
{$ENDIF}
1935

1936
class operator TMatrix4.Negative(const A: TMatrix4): TMatrix4;
1937
begin
1938
  Result.V[0] := -A.V[0];
1939
  Result.V[1] := -A.V[1];
1940
  Result.V[2] := -A.V[2];
1941
  Result.V[3] := -A.V[3];
1942
end;
1943

1944
procedure TMatrix4.SetInversed;
1945
begin
1946
  Self := Inverse;
1947
end;
1948

1949
procedure TMatrix4.SetTransposed;
1950
begin
1951
  Self := Transpose;
1952
end;
1953

1954
class operator TMatrix4.Subtract(const A: TMatrix4; const B: Single): TMatrix4;
1955
begin
1956
  Result.V[0] := A.V[0] - B;
1957
  Result.V[1] := A.V[1] - B;
1958
  Result.V[2] := A.V[2] - B;
1959
  Result.V[3] := A.V[3] - B;
1960
end;
1961

1962
class operator TMatrix4.Subtract(const A, B: TMatrix4): TMatrix4;
1963
begin
1964
  Result.V[0] := A.V[0] - B.V[0];
1965
  Result.V[1] := A.V[1] - B.V[1];
1966
  Result.V[2] := A.V[2] - B.V[2];
1967
  Result.V[3] := A.V[3] - B.V[3];
1968
end;
1969

1970
class operator TMatrix4.Subtract(const A: Single; const B: TMatrix4): TMatrix4;
1971
begin
1972
  Result.V[0] := A - B.V[0];
1973
  Result.V[1] := A - B.V[1];
1974
  Result.V[2] := A - B.V[2];
1975
  Result.V[3] := A - B.V[3];
1976
end;
1977

1978
function TMatrix4.Transpose: TMatrix4;
1979
begin
1980
  Result.M[0,0] := M[0,0];
1981
  Result.M[0,1] := M[1,0];
1982
  Result.M[0,2] := M[2,0];
1983
  Result.M[0,3] := M[3,0];
1984

1985
  Result.M[1,0] := M[0,1];
1986
  Result.M[1,1] := M[1,1];
1987
  Result.M[1,2] := M[2,1];
1988
  Result.M[1,3] := M[3,1];
1989

1990
  Result.M[2,0] := M[0,2];
1991
  Result.M[2,1] := M[1,2];
1992
  Result.M[2,2] := M[2,2];
1993
  Result.M[2,3] := M[3,2];
1994

1995
  Result.M[3,0] := M[0,3];
1996
  Result.M[3,1] := M[1,3];
1997
  Result.M[3,2] := M[2,3];
1998
  Result.M[3,3] := M[3,3];
1999
end;
2000

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

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

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

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