MathgeomGLS
1999 строк · 52.1 Кб
1{ Angle and Trigonometry Functions }
2
3function Radians(const ADegrees: Single): Single;
4begin
5Result := ADegrees * (Pi / 180);
6end;
7
8function Radians(const ADegrees: TVector2): TVector2;
9begin
10Result.Init(Radians(ADegrees.X), Radians(ADegrees.Y));
11end;
12
13function Radians(const ADegrees: TVector3): TVector3;
14begin
15Result.Init(Radians(ADegrees.X), Radians(ADegrees.Y), Radians(ADegrees.Z));
16end;
17
18function Radians(const ADegrees: TVector4): TVector4;
19begin
20Result.Init(Radians(ADegrees.X), Radians(ADegrees.Y), Radians(ADegrees.Z), Radians(ADegrees.W));
21end;
22
23function Degrees(const ARadians: Single): Single;
24begin
25Result := ARadians * (180 / Pi);
26end;
27
28function Degrees(const ARadians: TVector2): TVector2;
29begin
30Result.Init(Degrees(ARadians.X), Degrees(ARadians.Y));
31end;
32
33function Degrees(const ARadians: TVector3): TVector3;
34begin
35Result.Init(Degrees(ARadians.X), Degrees(ARadians.Y), Degrees(ARadians.Z));
36end;
37
38function Degrees(const ARadians: TVector4): TVector4;
39begin
40Result.Init(Degrees(ARadians.X), Degrees(ARadians.Y), Degrees(ARadians.Z), Degrees(ARadians.W));
41end;
42
43{ Exponential Functions }
44
45function Sqrt(const A: Single): Single;
46begin
47Result := System.Sqrt(A);
48end;
49
50function Sqrt(const A: TVector2): TVector2;
51begin
52Result.Init(System.Sqrt(A.X), System.Sqrt(A.Y));
53end;
54
55function Sqrt(const A: TVector3): TVector3;
56begin
57Result.Init(System.Sqrt(A.X), System.Sqrt(A.Y), System.Sqrt(A.Z));
58end;
59
60function Sqrt(const A: TVector4): TVector4;
61begin
62Result.Init(System.Sqrt(A.X), System.Sqrt(A.Y), System.Sqrt(A.Z), System.Sqrt(A.W));
63end;
64
65function InverseSqrt(const A: Single): Single;
66begin
67Result := 1 / Sqrt(A)
68end;
69
70function InverseSqrt(const A: TVector2): TVector2;
71begin
72Result.Init(InverseSqrt(A.X), InverseSqrt(A.Y));
73end;
74
75function InverseSqrt(const A: TVector3): TVector3;
76begin
77Result.Init(InverseSqrt(A.X), InverseSqrt(A.Y), InverseSqrt(A.Z));
78end;
79
80function InverseSqrt(const A: TVector4): TVector4;
81begin
82Result.Init(InverseSqrt(A.X), InverseSqrt(A.Y), InverseSqrt(A.Z), InverseSqrt(A.W));
83end;
84
85{ Fast approximate Functions }
86
87function FastSin(const ARadians: Single): Single;
88const
89FOPI = 1.27323954473516;
90SINCOF_P0 = -1.9515295891E-4;
91SINCOF_P1 = 8.3321608736E-3;
92SINCOF_P2 = -1.6666654611E-1;
93COSCOF_P0 = 2.443315711809948E-005;
94COSCOF_P1 = -1.388731625493765E-003;
95COSCOF_P2 = 4.166664568298827E-002;
96var
97X, Y, Z: Single;
98XBits: Cardinal absolute X;
99YBits: Cardinal absolute Y;
100SignBit: Cardinal;
101J: Integer;
102begin
103X := ARadians;
104SignBit := XBits and $80000000;
105XBits := XBits and $7FFFFFFF;
106
107J := Trunc(FOPI * X);
108J := (J + 1) and (not 1);
109Y := J;
110
111J := J and 7;
112if (J > 3) then
113begin
114SignBit := SignBit xor $80000000;
115Dec(J, 4);
116end;
117
118X := X - Y * (0.25 * Pi);
119Z := X * X;
120if (J = 1) or (J = 2) then
121begin
122Y := COSCOF_P0 * Z + COSCOF_P1;
123Y := Y * Z + COSCOF_P2;
124Y := Y * (Z * Z);
125Y := Y - 0.5 * Z + 1;
126end
127else
128begin
129Y := SINCOF_P0 * Z + SINCOF_P1;
130Y := Y * Z + SINCOF_P2;
131Y := Y * (Z * X);
132Y := Y + X;
133end;
134
135YBits := YBits xor SignBit;
136Result := Y;
137end;
138
139function FastSin(const ARadians: TVector2): TVector2;
140begin
141Result.Init(FastSin(ARadians.X), FastSin(ARadians.Y));
142end;
143
144function FastSin(const ARadians: TVector3): TVector3;
145begin
146Result.Init(FastSin(ARadians.X), FastSin(ARadians.Y), FastSin(ARadians.Z));
147end;
148
149function FastSin(const ARadians: TVector4): TVector4;
150begin
151Result.Init(FastSin(ARadians.X), FastSin(ARadians.Y), FastSin(ARadians.Z), FastSin(ARadians.W));
152end;
153
154function FastCos(const ARadians: Single): Single;
155const
156FOPI = 1.27323954473516;
157SINCOF_P0 = -1.9515295891E-4;
158SINCOF_P1 = 8.3321608736E-3;
159SINCOF_P2 = -1.6666654611E-1;
160COSCOF_P0 = 2.443315711809948E-005;
161COSCOF_P1 = -1.388731625493765E-003;
162COSCOF_P2 = 4.166664568298827E-002;
163var
164X, Y, Z: Single;
165XBits: Cardinal absolute X;
166YBits: Cardinal absolute Y;
167SignBit: Cardinal;
168J: Integer;
169begin
170X := ARadians;
171SignBit := 0;
172XBits := XBits and $7FFFFFFF;
173
174J := Trunc(FOPI * X);
175J := (J + 1) and (not 1);
176Y := J;
177
178J := J and 7;
179if (J > 3) then
180begin
181SignBit := $80000000;
182Dec(J, 4);
183end;
184
185if (J > 1) then
186SignBit := SignBit xor $80000000;
187
188X := X - Y * (0.25 * Pi);
189Z := X * X;
190if (J = 1) or (J = 2) then
191begin
192Y := SINCOF_P0 * Z + SINCOF_P1;
193Y := Y * Z + SINCOF_P2;
194Y := Y * (Z * X);
195Y := Y + X;
196end
197else
198begin
199Y := COSCOF_P0 * Z + COSCOF_P1;
200Y := Y * Z + COSCOF_P2;
201Y := Y * (Z * Z);
202Y := Y - 0.5 * Z + 1;
203end;
204
205YBits := YBits xor SignBit;
206Result := Y;
207end;
208
209function FastCos(const ARadians: TVector2): TVector2;
210begin
211Result.Init(FastCos(ARadians.X), FastCos(ARadians.Y));
212end;
213
214function FastCos(const ARadians: TVector3): TVector3;
215begin
216Result.Init(FastCos(ARadians.X), FastCos(ARadians.Y), FastCos(ARadians.Z));
217end;
218
219function FastCos(const ARadians: TVector4): TVector4;
220begin
221Result.Init(FastCos(ARadians.X), FastCos(ARadians.Y), FastCos(ARadians.Z), FastCos(ARadians.W));
222end;
223
224procedure FastSinCos(const ARadians: Single; out ASin, ACos: Single);
225const
226FOPI = 1.27323954473516;
227SINCOF_P0 = -1.9515295891E-4;
228SINCOF_P1 = 8.3321608736E-3;
229SINCOF_P2 = -1.6666654611E-1;
230COSCOF_P0 = 2.443315711809948E-005;
231COSCOF_P1 = -1.388731625493765E-003;
232COSCOF_P2 = 4.166664568298827E-002;
233var
234ASinBits: Cardinal absolute ASin;
235ACosBits: Cardinal absolute ACos;
236SignBitSin, SwapSignBitSin, SignBitCos: Cardinal;
237X, Y, Y2, Z: Single;
238XBits: Cardinal absolute X;
239J: Integer;
240begin
241X := ARadians;
242SignBitSin := (XBits and $80000000);
243XBits := XBits and $7FFFFFFF;
244J := (Trunc(FOPI * X) + 1) and (not 1);
245Y := J;
246SwapSignBitSin := (J and 4) shl 29;
247
248X := X - Y * (0.25 * Pi);
249
250SignBitCos := (4 and (not (J - 2))) shl 29;
251SignBitSin := SignBitSin xor SwapSignBitSin;
252
253Z := X * X;
254
255Y := COSCOF_P0 * Z + COSCOF_P1;
256Y := Y * Z + COSCOF_P2;
257Y := Y * (Z * Z) - (0.5 * Z) + 1;
258
259Y2 := SINCOF_P0 * Z + SINCOF_P1;
260Y2 := Y2 * Z + SINCOF_P2;
261Y2 := Y2 * (Z * X) + X;
262
263if ((J and 2) = 0) then
264begin
265ASin := Y2;
266ACos := Y;
267end
268else
269begin
270ASin := Y;
271ACos := Y2;
272end;
273
274ASinBits := ASinBits xor SignBitSin;
275ACosBits := ACosBits xor SignBitCos;
276end;
277
278procedure FastSinCos(const ARadians: TVector2; out ASin, ACos: TVector2);
279begin
280FastSinCos(ARadians.X, ASin.X, ACos.X);
281FastSinCos(ARadians.Y, ASin.Y, ACos.Y);
282end;
283
284procedure FastSinCos(const ARadians: TVector3; out ASin, ACos: TVector3);
285begin
286FastSinCos(ARadians.X, ASin.X, ACos.X);
287FastSinCos(ARadians.Y, ASin.Y, ACos.Y);
288FastSinCos(ARadians.Z, ASin.Z, ACos.Z);
289end;
290
291procedure FastSinCos(const ARadians: TVector4; out ASin, ACos: TVector4);
292begin
293FastSinCos(ARadians.X, ASin.X, ACos.X);
294FastSinCos(ARadians.Y, ASin.Y, ACos.Y);
295FastSinCos(ARadians.Z, ASin.Z, ACos.Z);
296FastSinCos(ARadians.W, ASin.W, ACos.W);
297end;
298
299function FastExp(const A: Single): Single;
300const
301EXP_CST = 2139095040.0;
302var
303Val, B: Single;
304IVal: Integer;
305XU, XU2: record
306case Byte of
3070: (I: Integer);
3081: (S: Single);
309end;
310begin
311Val := 12102203.1615614 * A + 1065353216.0;
312
313if (Val >= EXP_CST) then
314Val := EXP_CST;
315
316if (Val > 0) then
317IVal := Trunc(Val)
318else
319IVal := 0;
320
321XU.I := IVal and $7F800000;
322XU2.I := (IVal and $007FFFFF) or $3F800000;
323B := XU2.S;
324
325Result := XU.S *
326( 0.509964287281036376953125 + B *
327( 0.3120158612728118896484375 + B *
328( 0.1666135489940643310546875 + B *
329(-2.12528370320796966552734375e-3 + B *
3301.3534179888665676116943359375e-2))));
331end;
332
333function FastExp(const A: TVector2): TVector2;
334begin
335Result.Init(FastExp(A.X), FastExp(A.Y));
336end;
337
338function FastExp(const A: TVector3): TVector3;
339begin
340Result.Init(FastExp(A.X), FastExp(A.Y), FastExp(A.Z));
341end;
342
343function FastExp(const A: TVector4): TVector4;
344begin
345Result.Init(FastExp(A.X), FastExp(A.Y), FastExp(A.Z), FastExp(A.W));
346end;
347
348function FastLn(const A: Single): Single;
349var
350Exp, AddCst, X, X2: Single;
351Val: record
352case Byte of
3530: (S: Single);
3541: (I: Integer);
355end;
356begin
357Val.S := A;
358Exp := Val.I shr 23;
359if (A > 0) then
360AddCst := -89.93423858
361else
362AddCst := NegInfinity;
363
364Val.I := (Val.I and $007FFFFF) or $3F800000;
365X := Val.S;
366X2 := X * X;
367
368Result :=
369(3.3977745 * X + AddCst) +
370X2 * ((X - 2.2744832) +
371X2 * (0.024982445 * X - 0.24371102)) +
3720.69314718055995 * Exp;
373end;
374
375function FastLn(const A: TVector2): TVector2;
376begin
377Result.Init(FastLn(A.X), FastLn(A.Y));
378end;
379
380function FastLn(const A: TVector3): TVector3;
381begin
382Result.Init(FastLn(A.X), FastLn(A.Y), FastLn(A.Z));
383end;
384
385function FastLn(const A: TVector4): TVector4;
386begin
387Result.Init(FastLn(A.X), FastLn(A.Y), FastLn(A.Z), FastLn(A.W));
388end;
389
390function FastLog2(const A: Single): Single;
391var
392MX, VX: record
393case Byte of
3940: (S: Single);
3951: (I: UInt32);
396end;
397begin
398VX.S := A;
399MX.I := (VX.I and $007FFFFF) or $3F000000;
400Result := VX.I * 1.1920928955078125e-7;
401Result := Result
402- 124.22551499
403- 1.498030302 * MX.S
404- 1.72587999 / (0.3520887068 + MX.S);
405end;
406
407function FastLog2(const A: TVector2): TVector2;
408begin
409Result.Init(FastLog2(A.X), FastLog2(A.Y));
410end;
411
412function FastLog2(const A: TVector3): TVector3;
413begin
414Result.Init(FastLog2(A.X), FastLog2(A.Y), FastLog2(A.Z));
415end;
416
417function FastLog2(const A: TVector4): TVector4;
418begin
419Result.Init(FastLog2(A.X), FastLog2(A.Y), FastLog2(A.Z), FastLog2(A.W));
420end;
421
422function FastExp2(const A: Single): Single;
423var
424Offset, Z: Single;
425V: record
426case Byte of
4270: (S: Single);
4281: (I: UInt32);
429end;
430begin
431if (A < 0) then
432Offset := 1
433else
434Offset := 0;
435Z := A - Trunc(A) + Offset;
436V.I := Trunc((1 shl 23) * (A + 121.2740575 + 27.7280233 / (4.84252568 - Z) - 1.49012907 * Z));
437Result := V.S;
438end;
439
440function FastExp2(const A: TVector2): TVector2;
441begin
442Result.Init(FastExp2(A.X), FastExp2(A.Y));
443end;
444
445function FastExp2(const A: TVector3): TVector3;
446begin
447Result.Init(FastExp2(A.X), FastExp2(A.Y), FastExp2(A.Z));
448end;
449
450function FastExp2(const A: TVector4): TVector4;
451begin
452Result.Init(FastExp2(A.X), FastExp2(A.Y), FastExp2(A.Z), FastExp2(A.W));
453end;
454
455{ Common Functions }
456
457function Abs(const A: Single): Single;
458begin
459Result := System.Abs(A);
460end;
461
462function Abs(const A: TVector2): TVector2;
463begin
464Result.Init(System.Abs(A.X), System.Abs(A.Y));
465end;
466
467function Abs(const A: TVector3): TVector3;
468begin
469Result.Init(System.Abs(A.X), System.Abs(A.Y), System.Abs(A.Z));
470end;
471
472function Abs(const A: TVector4): TVector4;
473begin
474Result.Init(System.Abs(A.X), System.Abs(A.Y), System.Abs(A.Z), System.Abs(A.W));
475end;
476
477function Sign(const A: Single): Single;
478begin
479Result := System.Math.Sign(A);
480end;
481
482function Sign(const A: TVector2): TVector2;
483begin
484Result.Init(System.Math.Sign(A.X), System.Math.Sign(A.Y));
485end;
486
487function Sign(const A: TVector3): TVector3;
488begin
489Result.Init(System.Math.Sign(A.X), System.Math.Sign(A.Y), System.Math.Sign(A.Z));
490end;
491
492function Sign(const A: TVector4): TVector4;
493begin
494Result.Init(System.Math.Sign(A.X), System.Math.Sign(A.Y), System.Math.Sign(A.Z), System.Math.Sign(A.W));
495end;
496
497function Floor(const A: Single): Integer;
498begin
499Result := System.Math.Floor(A);
500end;
501
502function Floor(const A: TVector2): TIVector2;
503begin
504Result.Init(System.Math.Floor(A.X), System.Math.Floor(A.Y));
505end;
506
507function Floor(const A: TVector3): TIVector3;
508begin
509Result.Init(System.Math.Floor(A.X), System.Math.Floor(A.Y), System.Math.Floor(A.Z));
510end;
511
512function Floor(const A: TVector4): TIVector4;
513begin
514Result.Init(System.Math.Floor(A.X), System.Math.Floor(A.Y), System.Math.Floor(A.Z), System.Math.Floor(A.W));
515end;
516
517function Trunc(const A: Single): Integer;
518begin
519Result := System.Trunc(A);
520end;
521
522function Trunc(const A: TVector2): TIVector2;
523begin
524Result.Init(System.Trunc(A.X), System.Trunc(A.Y));
525end;
526
527function Trunc(const A: TVector3): TIVector3;
528begin
529Result.Init(System.Trunc(A.X), System.Trunc(A.Y), System.Trunc(A.Z));
530end;
531
532function Trunc(const A: TVector4): TIVector4;
533begin
534Result.Init(System.Trunc(A.X), System.Trunc(A.Y), System.Trunc(A.Z), System.Trunc(A.W));
535end;
536
537function Round(const A: Single): Integer;
538begin
539Result := System.Round(A);
540end;
541
542function Round(const A: TVector2): TIVector2;
543begin
544Result.Init(System.Round(A.X), System.Round(A.Y));
545end;
546
547function Round(const A: TVector3): TIVector3;
548begin
549Result.Init(System.Round(A.X), System.Round(A.Y), System.Round(A.Z));
550end;
551
552function Round(const A: TVector4): TIVector4;
553begin
554Result.Init(System.Round(A.X), System.Round(A.Y), System.Round(A.Z), System.Round(A.W));
555end;
556
557function Ceil(const A: Single): Integer;
558begin
559Result := System.Math.Ceil(A);
560end;
561
562function Ceil(const A: TVector2): TIVector2;
563begin
564Result.Init(System.Math.Ceil(A.X), System.Math.Ceil(A.Y));
565end;
566
567function Ceil(const A: TVector3): TIVector3;
568begin
569Result.Init(System.Math.Ceil(A.X), System.Math.Ceil(A.Y), System.Math.Ceil(A.Z));
570end;
571
572function Ceil(const A: TVector4): TIVector4;
573begin
574Result.Init(System.Math.Ceil(A.X), System.Math.Ceil(A.Y), System.Math.Ceil(A.Z), System.Math.Ceil(A.W));
575end;
576
577function Frac(const A: Single): Single;
578begin
579Result := System.Frac(A);
580end;
581
582function Frac(const A: TVector2): TVector2;
583begin
584Result.Init(System.Frac(A.X), System.Frac(A.Y));
585end;
586
587function Frac(const A: TVector3): TVector3;
588begin
589Result.Init(System.Frac(A.X), System.Frac(A.Y), System.Frac(A.Z));
590end;
591
592function Frac(const A: TVector4): TVector4;
593begin
594Result.Init(System.Frac(A.X), System.Frac(A.Y), System.Frac(A.Z), System.Frac(A.W));
595end;
596
597function FMod(const A, B: Single): Single;
598begin
599Result := A - (B * Trunc(A / B));
600end;
601
602function FMod(const A: TVector2; const B: Single): TVector2;
603begin
604Result.Init(Neslib.FastMath.FMod(A.X, B), Neslib.FastMath.FMod(A.Y, B));
605end;
606
607function FMod(const A, B: TVector2): TVector2;
608begin
609Result.Init(Neslib.FastMath.FMod(A.X, B.X), Neslib.FastMath.FMod(A.Y, B.Y));
610end;
611
612function FMod(const A: TVector3; const B: Single): TVector3;
613begin
614Result.Init(Neslib.FastMath.FMod(A.X, B), Neslib.FastMath.FMod(A.Y, B), Neslib.FastMath.FMod(A.Z, B));
615end;
616
617function FMod(const A, B: TVector3): TVector3;
618begin
619Result.Init(Neslib.FastMath.FMod(A.X, B.X), Neslib.FastMath.FMod(A.Y, B.Y), Neslib.FastMath.FMod(A.Z, B.Z));
620end;
621
622function FMod(const A: TVector4; const B: Single): TVector4;
623begin
624Result.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));
625end;
626
627function FMod(const A, B: TVector4): TVector4;
628begin
629Result.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));
630end;
631
632function ModF(const A: Single; out B: Integer): Single;
633begin
634B := Trunc(A);
635Result := Frac(A);
636end;
637
638function ModF(const A: TVector2; out B: TIVector2): TVector2;
639begin
640Result.Init(ModF(A.X, B.X), ModF(A.Y, B.Y));
641end;
642
643function ModF(const A: TVector3; out B: TIVector3): TVector3;
644begin
645Result.Init(ModF(A.X, B.X), ModF(A.Y, B.Y), ModF(A.Z, B.Z));
646end;
647
648function ModF(const A: TVector4; out B: TIVector4): TVector4;
649begin
650Result.Init(ModF(A.X, B.X), ModF(A.Y, B.Y), ModF(A.Z, B.Z), ModF(A.W, B.W));
651end;
652
653function Min(const A: TVector2; const B: Single): TVector2;
654begin
655Result.Init(System.Math.Min(A.X, B), System.Math.Min(A.Y, B));
656end;
657
658function Min(const A, B: TVector2): TVector2;
659begin
660Result.Init(System.Math.Min(A.X, B.X), System.Math.Min(A.Y, B.Y));
661end;
662
663function Min(const A: TVector3; const B: Single): TVector3;
664begin
665Result.Init(System.Math.Min(A.X, B), System.Math.Min(A.Y, B), System.Math.Min(A.Z, B));
666end;
667
668function Min(const A, B: TVector3): TVector3;
669begin
670Result.Init(System.Math.Min(A.X, B.X), System.Math.Min(A.Y, B.Y), System.Math.Min(A.Z, B.Z));
671end;
672
673function Min(const A: TVector4; const B: Single): TVector4;
674begin
675Result.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));
676end;
677
678function Min(const A, B: TVector4): TVector4;
679begin
680Result.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));
681end;
682
683function Max(const A: TVector2; const B: Single): TVector2;
684begin
685Result.Init(System.Math.Max(A.X, B), System.Math.Max(A.Y, B));
686end;
687
688function Max(const A, B: TVector2): TVector2;
689begin
690Result.Init(System.Math.Max(A.X, B.X), System.Math.Max(A.Y, B.Y));
691end;
692
693function Max(const A: TVector3; const B: Single): TVector3;
694begin
695Result.Init(System.Math.Max(A.X, B), System.Math.Max(A.Y, B), System.Math.Max(A.Z, B));
696end;
697
698function Max(const A, B: TVector3): TVector3;
699begin
700Result.Init(System.Math.Max(A.X, B.X), System.Math.Max(A.Y, B.Y), System.Math.Max(A.Z, B.Z));
701end;
702
703function Max(const A: TVector4; const B: Single): TVector4;
704begin
705Result.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));
706end;
707
708function Max(const A, B: TVector4): TVector4;
709begin
710Result.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));
711end;
712
713function EnsureRange(const A, AMin, AMax: Single): Single;
714begin
715Result := System.Math.EnsureRange(A, AMin, AMax);
716end;
717
718function EnsureRange(const A: TVector2; const AMin, AMax: Single): TVector2;
719begin
720Result.Init(System.Math.EnsureRange(A.X, AMin, AMax), System.Math.EnsureRange(A.Y, AMin, AMax));
721end;
722
723function EnsureRange(const A, AMin, AMax: TVector2): TVector2;
724begin
725Result.Init(System.Math.EnsureRange(A.X, AMin.X, AMax.X), System.Math.EnsureRange(A.Y, AMin.Y, AMax.Y));
726end;
727
728function EnsureRange(const A: TVector3; const AMin, AMax: Single): TVector3;
729begin
730Result.Init(System.Math.EnsureRange(A.X, AMin, AMax), System.Math.EnsureRange(A.Y, AMin, AMax), System.Math.EnsureRange(A.Z, AMin, AMax));
731end;
732
733function EnsureRange(const A, AMin, AMax: TVector3): TVector3;
734begin
735Result.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));
736end;
737
738function EnsureRange(const A: TVector4; const AMin, AMax: Single): TVector4;
739begin
740Result.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));
741end;
742
743function EnsureRange(const A, AMin, AMax: TVector4): TVector4;
744begin
745Result.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));
746end;
747
748function Mix(const A, B: TVector2; const T: Single): TVector2;
749begin
750Result.Init(Mix(A.X, B.X, T), Mix(A.Y, B.Y, T));
751end;
752
753function Mix(const A, B, T: TVector2): TVector2;
754begin
755Result.Init(Mix(A.X, B.X, T.X), Mix(A.Y, B.Y, T.Y));
756end;
757
758function Mix(const A, B: TVector3; const T: Single): TVector3;
759begin
760Result.Init(Mix(A.X, B.X, T), Mix(A.Y, B.Y, T), Mix(A.Z, B.Z, T));
761end;
762
763function Mix(const A, B, T: TVector3): TVector3;
764begin
765Result.Init(Mix(A.X, B.X, T.X), Mix(A.Y, B.Y, T.Y), Mix(A.Z, B.Z, T.Z));
766end;
767
768function Mix(const A, B: TVector4; const T: Single): TVector4;
769begin
770Result.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));
771end;
772
773function Mix(const A, B, T: TVector4): TVector4;
774begin
775Result.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));
776end;
777
778function Step(const AEdge: Single; const A: TVector2): TVector2;
779begin
780Result.Init(Step(AEdge, A.X), Step(AEdge, A.Y));
781end;
782
783function Step(const AEdge, A: TVector2): TVector2;
784begin
785Result.Init(Step(AEdge.X, A.X), Step(AEdge.Y, A.Y));
786end;
787
788function Step(const AEdge: Single; const A: TVector3): TVector3;
789begin
790Result.Init(Step(AEdge, A.X), Step(AEdge, A.Y), Step(AEdge, A.Z));
791end;
792
793function Step(const AEdge, A: TVector3): TVector3;
794begin
795Result.Init(Step(AEdge.X, A.X), Step(AEdge.Y, A.Y), Step(AEdge.Z, A.Z));
796end;
797
798function Step(const AEdge: Single; const A: TVector4): TVector4;
799begin
800Result.Init(Step(AEdge, A.X), Step(AEdge, A.Y), Step(AEdge, A.Z), Step(AEdge, A.W));
801end;
802
803function Step(const AEdge, A: TVector4): TVector4;
804begin
805Result.Init(Step(AEdge.X, A.X), Step(AEdge.Y, A.Y), Step(AEdge.Z, A.Z), Step(AEdge.W, A.W));
806end;
807
808function SmoothStep(const AEdge0, AEdge1: Single; const A: TVector2): TVector2;
809begin
810Result.Init(SmoothStep(AEdge0, AEdge1, A.X), SmoothStep(AEdge0, AEdge1, A.Y));
811end;
812
813function SmoothStep(const AEdge0, AEdge1, A: TVector2): TVector2;
814begin
815Result.Init(SmoothStep(AEdge0.X, AEdge1.X, A.X), SmoothStep(AEdge0.Y, AEdge1.Y, A.Y));
816end;
817
818function SmoothStep(const AEdge0, AEdge1: Single; const A: TVector3): TVector3;
819begin
820Result.Init(SmoothStep(AEdge0, AEdge1, A.X), SmoothStep(AEdge0, AEdge1, A.Y), SmoothStep(AEdge0, AEdge1, A.Z));
821end;
822
823function SmoothStep(const AEdge0, AEdge1, A: TVector3): TVector3;
824begin
825Result.Init(SmoothStep(AEdge0.X, AEdge1.X, A.X), SmoothStep(AEdge0.Y, AEdge1.Y, A.Y), SmoothStep(AEdge0.Z, AEdge1.Z, A.Z));
826end;
827
828function SmoothStep(const AEdge0, AEdge1: Single; const A: TVector4): TVector4;
829begin
830Result.Init(SmoothStep(AEdge0, AEdge1, A.X), SmoothStep(AEdge0, AEdge1, A.Y), SmoothStep(AEdge0, AEdge1, A.Z), SmoothStep(AEdge0, AEdge1, A.W));
831end;
832
833function SmoothStep(const AEdge0, AEdge1, A: TVector4): TVector4;
834begin
835Result.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));
836end;
837
838function FMA(const A, B, C: TVector2): TVector2;
839begin
840Result.Init(FMA(A.X, B.X, C.X), FMA(A.Y, B.Y, C.Y));
841end;
842
843function FMA(const A, B, C: TVector3): TVector3;
844begin
845Result.Init(FMA(A.X, B.X, C.X), FMA(A.Y, B.Y, C.Y), FMA(A.Z, B.Z, C.Z));
846end;
847
848function FMA(const A, B, C: TVector4): TVector4;
849begin
850Result.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));
851end;
852
853{ Matrix functions }
854
855{$IFDEF FM_COLUMN_MAJOR}
856function OuterProduct(const C, R: TVector2): TMatrix2;
857var
858I: Integer;
859begin
860for I := 0 to 1 do
861Result.C[I] := C * R.C[I];
862end;
863
864function OuterProduct(const C, R: TVector3): TMatrix3;
865var
866I: Integer;
867begin
868for I := 0 to 2 do
869Result.C[I] := C * R.C[I];
870end;
871
872function OuterProduct(const C, R: TVector4): TMatrix4;
873var
874I: Integer;
875begin
876for I := 0 to 3 do
877Result.C[I] := C * R.C[I];
878end;
879{$ELSE}
880function OuterProduct(const C, R: TVector2): TMatrix2;
881var
882I: Integer;
883begin
884for I := 0 to 1 do
885Result.R[I] := R * C.C[I];
886end;
887
888function OuterProduct(const C, R: TVector3): TMatrix3;
889var
890I: Integer;
891begin
892for I := 0 to 2 do
893Result.R[I] := R * C.C[I];
894end;
895
896function OuterProduct(const C, R: TVector4): TMatrix4;
897var
898I: Integer;
899begin
900for I := 0 to 3 do
901Result.R[I] := R * C.C[I];
902end;
903{$ENDIF}
904
905{ TVector2 }
906
907class operator TVector2.Add(const A: TVector2; const B: Single): TVector2;
908begin
909Result.X := A.X + B;
910Result.Y := A.Y + B;
911end;
912
913class operator TVector2.Add(const A: Single; const B: TVector2): TVector2;
914begin
915Result.X := A + B.X;
916Result.Y := A + B.Y;
917end;
918
919class operator TVector2.Add(const A, B: TVector2): TVector2;
920begin
921Result.X := A.X + B.X;
922Result.Y := A.Y + B.Y;
923end;
924
925function TVector2.Distance(const AOther: TVector2): Single;
926begin
927Result := (Self - AOther).Length;
928end;
929
930function TVector2.DistanceSquared(const AOther: TVector2): Single;
931begin
932Result := (Self - AOther).LengthSquared;
933end;
934
935class operator TVector2.Divide(const A: TVector2; const B: Single): TVector2;
936var
937InvB: Single;
938begin
939InvB := 1 / B;
940Result.X := A.X * InvB;
941Result.Y := A.Y * InvB;
942end;
943
944class operator TVector2.Divide(const A: Single; const B: TVector2): TVector2;
945begin
946Result.X := A / B.X;
947Result.Y := A / B.Y;
948end;
949
950class operator TVector2.Divide(const A, B: TVector2): TVector2;
951begin
952Result.X := A.X / B.X;
953Result.Y := A.Y / B.Y;
954end;
955
956function TVector2.Dot(const AOther: TVector2): Single;
957begin
958Result := (X * AOther.X) + (Y * AOther.Y);
959end;
960
961function TVector2.FaceForward(const I, NRef: TVector2): TVector2;
962begin
963if (NRef.Dot(I) < 0) then
964Result := Self
965else
966Result := -Self;
967end;
968
969function TVector2.GetLength: Single;
970begin
971Result := Sqrt((X * X) + (Y * Y));
972end;
973
974function TVector2.GetLengthSquared: Single;
975begin
976Result := (X * X) + (Y * Y);
977end;
978
979class operator TVector2.Multiply(const A: TVector2; const B: Single): TVector2;
980begin
981Result.X := A.X * B;
982Result.Y := A.Y * B;
983end;
984
985class operator TVector2.Multiply(const A: Single; const B: TVector2): TVector2;
986begin
987Result.X := A * B.X;
988Result.Y := A * B.Y;
989end;
990
991class operator TVector2.Multiply(const A, B: TVector2): TVector2;
992begin
993Result.X := A.X * B.X;
994Result.Y := A.Y * B.Y;
995end;
996
997function TVector2.NormalizeFast: TVector2;
998begin
999Result := Self * InverseSqrt(Self.LengthSquared);
1000end;
1001
1002function TVector2.Reflect(const N: TVector2): TVector2;
1003begin
1004Result := Self - ((2 * N.Dot(Self)) * N);
1005end;
1006
1007function TVector2.Refract(const N: TVector2; const Eta: Single): TVector2;
1008var
1009D, K: Single;
1010begin
1011D := N.Dot(Self);
1012K := 1 - Eta * Eta * (1 - D * D);
1013if (K < 0) then
1014Result.Init
1015else
1016Result := (Eta * Self) - ((Eta * D + Sqrt(K)) * N);
1017end;
1018
1019procedure TVector2.SetNormalizedFast;
1020begin
1021Self := Self * InverseSqrt(Self.LengthSquared);
1022end;
1023
1024class operator TVector2.Subtract(const A: TVector2; const B: Single): TVector2;
1025begin
1026Result.X := A.X - B;
1027Result.Y := A.Y - B;
1028end;
1029
1030class operator TVector2.Subtract(const A: Single; const B: TVector2): TVector2;
1031begin
1032Result.X := A - B.X;
1033Result.Y := A - B.Y;
1034end;
1035
1036class operator TVector2.Subtract(const A, B: TVector2): TVector2;
1037begin
1038Result.X := A.X - B.X;
1039Result.Y := A.Y - B.Y;
1040end;
1041
1042{ TVector3 }
1043
1044class operator TVector3.Add(const A: TVector3; const B: Single): TVector3;
1045begin
1046Result.X := A.X + B;
1047Result.Y := A.Y + B;
1048Result.Z := A.Z + B;
1049end;
1050
1051class operator TVector3.Add(const A: Single; const B: TVector3): TVector3;
1052begin
1053Result.X := A + B.X;
1054Result.Y := A + B.Y;
1055Result.Z := A + B.Z;
1056end;
1057
1058class operator TVector3.Add(const A, B: TVector3): TVector3;
1059begin
1060Result.X := A.X + B.X;
1061Result.Y := A.Y + B.Y;
1062Result.Z := A.Z + B.Z;
1063end;
1064
1065function TVector3.Distance(const AOther: TVector3): Single;
1066begin
1067Result := (Self - AOther).Length;
1068end;
1069
1070function TVector3.DistanceSquared(const AOther: TVector3): Single;
1071begin
1072Result := (Self - AOther).LengthSquared;
1073end;
1074
1075class operator TVector3.Divide(const A: TVector3; const B: Single): TVector3;
1076var
1077InvB: Single;
1078begin
1079InvB := 1 / B;
1080Result.X := A.X * InvB;
1081Result.Y := A.Y * InvB;
1082Result.Z := A.Z * InvB;
1083end;
1084
1085class operator TVector3.Divide(const A: Single; const B: TVector3): TVector3;
1086begin
1087Result.X := A / B.X;
1088Result.Y := A / B.Y;
1089Result.Z := A / B.Z;
1090end;
1091
1092class operator TVector3.Divide(const A, B: TVector3): TVector3;
1093begin
1094Result.X := A.X / B.X;
1095Result.Y := A.Y / B.Y;
1096Result.Z := A.Z / B.Z;
1097end;
1098
1099function TVector3.Cross(const AOther: TVector3): TVector3;
1100begin
1101Result.X := (Y * AOther.Z) - (AOther.Y * Z);
1102Result.Y := (Z * AOther.X) - (AOther.Z * X);
1103Result.Z := (X * AOther.Y) - (AOther.X * Y);
1104end;
1105
1106function TVector3.Dot(const AOther: TVector3): Single;
1107begin
1108Result := (X * AOther.X) + (Y * AOther.Y) + (Z * AOther.Z);
1109end;
1110
1111function TVector3.FaceForward(const I, NRef: TVector3): TVector3;
1112begin
1113if (NRef.Dot(I) < 0) then
1114Result := Self
1115else
1116Result := -Self;
1117end;
1118
1119function TVector3.GetLength: Single;
1120begin
1121Result := Sqrt((X * X) + (Y * Y) + (Z * Z));
1122end;
1123
1124function TVector3.GetLengthSquared: Single;
1125begin
1126Result := (X * X) + (Y * Y) + (Z * Z);
1127end;
1128
1129class operator TVector3.Multiply(const A: TVector3; const B: Single): TVector3;
1130begin
1131Result.X := A.X * B;
1132Result.Y := A.Y * B;
1133Result.Z := A.Z * B;
1134end;
1135
1136class operator TVector3.Multiply(const A: Single; const B: TVector3): TVector3;
1137begin
1138Result.X := A * B.X;
1139Result.Y := A * B.Y;
1140Result.Z := A * B.Z;
1141end;
1142
1143class operator TVector3.Multiply(const A, B: TVector3): TVector3;
1144begin
1145Result.X := A.X * B.X;
1146Result.Y := A.Y * B.Y;
1147Result.Z := A.Z * B.Z;
1148end;
1149
1150class operator TVector3.Negative(const A: TVector3): TVector3;
1151begin
1152Result.X := -A.X;
1153Result.Y := -A.Y;
1154Result.Z := -A.Z;
1155end;
1156
1157function TVector3.NormalizeFast: TVector3;
1158begin
1159Result := Self * InverseSqrt(Self.LengthSquared);
1160end;
1161
1162function TVector3.Reflect(const N: TVector3): TVector3;
1163begin
1164Result := Self - ((2 * N.Dot(Self)) * N);
1165end;
1166
1167function TVector3.Refract(const N: TVector3; const Eta: Single): TVector3;
1168var
1169D, K: Single;
1170begin
1171D := N.Dot(Self);
1172K := 1 - Eta * Eta * (1 - D * D);
1173if (K < 0) then
1174Result.Init
1175else
1176Result := (Eta * Self) - ((Eta * D + Sqrt(K)) * N);
1177end;
1178
1179procedure TVector3.SetNormalizedFast;
1180begin
1181Self := Self * InverseSqrt(Self.LengthSquared);
1182end;
1183
1184class operator TVector3.Subtract(const A: TVector3; const B: Single): TVector3;
1185begin
1186Result.X := A.X - B;
1187Result.Y := A.Y - B;
1188Result.Z := A.Z - B;
1189end;
1190
1191class operator TVector3.Subtract(const A: Single; const B: TVector3): TVector3;
1192begin
1193Result.X := A - B.X;
1194Result.Y := A - B.Y;
1195Result.Z := A - B.Z;
1196end;
1197
1198class operator TVector3.Subtract(const A, B: TVector3): TVector3;
1199begin
1200Result.X := A.X - B.X;
1201Result.Y := A.Y - B.Y;
1202Result.Z := A.Z - B.Z;
1203end;
1204
1205{ TVector4 }
1206
1207class operator TVector4.Add(const A: TVector4; const B: Single): TVector4;
1208begin
1209Result.X := A.X + B;
1210Result.Y := A.Y + B;
1211Result.Z := A.Z + B;
1212Result.W := A.W + B;
1213end;
1214
1215class operator TVector4.Add(const A: Single; const B: TVector4): TVector4;
1216begin
1217Result.X := A + B.X;
1218Result.Y := A + B.Y;
1219Result.Z := A + B.Z;
1220Result.W := A + B.W;
1221end;
1222
1223class operator TVector4.Add(const A, B: TVector4): TVector4;
1224begin
1225Result.X := A.X + B.X;
1226Result.Y := A.Y + B.Y;
1227Result.Z := A.Z + B.Z;
1228Result.W := A.W + B.W;
1229end;
1230
1231function TVector4.Distance(const AOther: TVector4): Single;
1232begin
1233Result := (Self - AOther).Length;
1234end;
1235
1236function TVector4.DistanceSquared(const AOther: TVector4): Single;
1237begin
1238Result := (Self - AOther).LengthSquared;
1239end;
1240
1241class operator TVector4.Divide(const A: TVector4; const B: Single): TVector4;
1242begin
1243Result.X := A.X / B;
1244Result.Y := A.Y / B;
1245Result.Z := A.Z / B;
1246Result.W := A.W / B;
1247end;
1248
1249class operator TVector4.Divide(const A: Single; const B: TVector4): TVector4;
1250begin
1251Result.X := A / B.X;
1252Result.Y := A / B.Y;
1253Result.Z := A / B.Z;
1254Result.W := A / B.W;
1255end;
1256
1257class operator TVector4.Divide(const A, B: TVector4): TVector4;
1258begin
1259Result.X := A.X / B.X;
1260Result.Y := A.Y / B.Y;
1261Result.Z := A.Z / B.Z;
1262Result.W := A.W / B.W;
1263end;
1264
1265function TVector4.Dot(const AOther: TVector4): Single;
1266begin
1267Result := (X * AOther.X) + (Y * AOther.Y) + (Z * AOther.Z) + (W * AOther.W);
1268end;
1269
1270function TVector4.FaceForward(const I, NRef: TVector4): TVector4;
1271begin
1272if (NRef.Dot(I) < 0) then
1273Result := Self
1274else
1275Result := -Self;
1276end;
1277
1278function TVector4.GetLength: Single;
1279begin
1280Result := Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W));
1281end;
1282
1283function TVector4.GetLengthSquared: Single;
1284begin
1285Result := (X * X) + (Y * Y) + (Z * Z) + (W * W);
1286end;
1287
1288class operator TVector4.Multiply(const A: TVector4; const B: Single): TVector4;
1289begin
1290Result.X := A.X * B;
1291Result.Y := A.Y * B;
1292Result.Z := A.Z * B;
1293Result.W := A.W * B;
1294end;
1295
1296class operator TVector4.Multiply(const A: Single; const B: TVector4): TVector4;
1297begin
1298Result.X := A * B.X;
1299Result.Y := A * B.Y;
1300Result.Z := A * B.Z;
1301Result.W := A * B.W;
1302end;
1303
1304class operator TVector4.Multiply(const A, B: TVector4): TVector4;
1305begin
1306Result.X := A.X * B.X;
1307Result.Y := A.Y * B.Y;
1308Result.Z := A.Z * B.Z;
1309Result.W := A.W * B.W;
1310end;
1311
1312class operator TVector4.Negative(const A: TVector4): TVector4;
1313begin
1314Result.X := -A.X;
1315Result.Y := -A.Y;
1316Result.Z := -A.Z;
1317Result.W := -A.W;
1318end;
1319
1320function TVector4.NormalizeFast: TVector4;
1321begin
1322Result := Self * InverseSqrt(Self.LengthSquared);
1323end;
1324
1325function TVector4.Reflect(const N: TVector4): TVector4;
1326begin
1327Result := Self - ((2 * N.Dot(Self)) * N);
1328end;
1329
1330function TVector4.Refract(const N: TVector4; const Eta: Single): TVector4;
1331var
1332D, K: Single;
1333begin
1334D := N.Dot(Self);
1335K := 1 - Eta * Eta * (1 - D * D);
1336if (K < 0) then
1337Result.Init
1338else
1339Result := (Eta * Self) - ((Eta * D + Sqrt(K)) * N);
1340end;
1341
1342procedure TVector4.SetNormalizedFast;
1343begin
1344Self := Self * InverseSqrt(Self.LengthSquared);
1345end;
1346
1347class operator TVector4.Subtract(const A: TVector4; const B: Single): TVector4;
1348begin
1349Result.X := A.X - B;
1350Result.Y := A.Y - B;
1351Result.Z := A.Z - B;
1352Result.W := A.W - B;
1353end;
1354
1355class operator TVector4.Subtract(const A: Single; const B: TVector4): TVector4;
1356begin
1357Result.X := A - B.X;
1358Result.Y := A - B.Y;
1359Result.Z := A - B.Z;
1360Result.W := A - B.W;
1361end;
1362
1363class operator TVector4.Subtract(const A, B: TVector4): TVector4;
1364begin
1365Result.X := A.X - B.X;
1366Result.Y := A.Y - B.Y;
1367Result.Z := A.Z - B.Z;
1368Result.W := A.W - B.W;
1369end;
1370
1371{ TQuaternion }
1372
1373class operator TQuaternion.Add(const A, B: TQuaternion): TQuaternion;
1374begin
1375Result.X := A.X + B.X;
1376Result.Y := A.Y + B.Y;
1377Result.Z := A.Z + B.Z;
1378Result.W := A.W + B.W;
1379end;
1380
1381function TQuaternion.GetLength: Single;
1382begin
1383Result := Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W));
1384end;
1385
1386function TQuaternion.GetLengthSquared: Single;
1387begin
1388Result := (X * X) + (Y * Y) + (Z * Z) + (W * W);
1389end;
1390
1391class operator TQuaternion.Multiply(const A: TQuaternion; const B: Single): TQuaternion;
1392begin
1393Result.X := A.X * B;
1394Result.Y := A.Y * B;
1395Result.Z := A.Z * B;
1396Result.W := A.W * B;
1397end;
1398
1399class operator TQuaternion.Multiply(const A: Single; const B: TQuaternion): TQuaternion;
1400begin
1401Result.X := A * B.X;
1402Result.Y := A * B.Y;
1403Result.Z := A * B.Z;
1404Result.W := A * B.W;
1405end;
1406
1407class operator TQuaternion.Multiply(const A, B: TQuaternion): TQuaternion;
1408begin
1409Result.X := (A.W * B.X) + (A.X * B.W) + (A.Y * B.Z) - (A.Z * B.Y);
1410Result.Y := (A.W * B.Y) + (A.Y * B.W) + (A.Z * B.X) - (A.X * B.Z);
1411Result.Z := (A.W * B.Z) + (A.Z * B.W) + (A.X * B.Y) - (A.Y * B.X);
1412Result.W := (A.W * B.W) - (A.X * B.X) - (A.Y * B.Y) - (A.Z * B.Z);
1413end;
1414
1415function TQuaternion.NormalizeFast: TQuaternion;
1416begin
1417Result := Self * InverseSqrt(Self.LengthSquared);
1418end;
1419
1420procedure TQuaternion.SetNormalizedFast;
1421begin
1422Self := Self * InverseSqrt(Self.LengthSquared);
1423end;
1424
1425{ TMatrix 2 }
1426
1427class operator TMatrix2.Add(const A: TMatrix2; const B: Single): TMatrix2;
1428begin
1429Result.V[0] := A.V[0] + B;
1430Result.V[1] := A.V[1] + B;
1431end;
1432
1433class operator TMatrix2.Add(const A: Single; const B: TMatrix2): TMatrix2;
1434begin
1435Result.V[0] := A + B.V[0];
1436Result.V[1] := A + B.V[1];
1437end;
1438
1439class operator TMatrix2.Add(const A, B: TMatrix2): TMatrix2;
1440begin
1441Result.V[0] := A.V[0] + B.V[0];
1442Result.V[1] := A.V[1] + B.V[1];
1443end;
1444
1445function TMatrix2.CompMult(const AOther: TMatrix2): TMatrix2;
1446var
1447I: Integer;
1448begin
1449for I := 0 to 1 do
1450Result.V[I] := V[I] * AOther.V[I];
1451end;
1452
1453class operator TMatrix2.Divide(const A: Single; const B: TMatrix2): TMatrix2;
1454begin
1455Result.V[0] := A / B.V[0];
1456Result.V[1] := A / B.V[1];
1457end;
1458
1459class operator TMatrix2.Divide(const A: TMatrix2; const B: Single): TMatrix2;
1460var
1461InvB: Single;
1462begin
1463InvB := 1 / B;
1464Result.V[0] := A.V[0] * InvB;
1465Result.V[1] := A.V[1] * InvB;
1466end;
1467
1468class operator TMatrix2.Multiply(const A: Single; const B: TMatrix2): TMatrix2;
1469begin
1470Result.V[0] := A * B.V[0];
1471Result.V[1] := A * B.V[1];
1472end;
1473
1474class operator TMatrix2.Multiply(const A: TMatrix2; const B: Single): TMatrix2;
1475begin
1476Result.V[0] := A.V[0] * B;
1477Result.V[1] := A.V[1] * B;
1478end;
1479
1480class operator TMatrix2.Multiply(const A: TVector2; const B: TMatrix2): TVector2;
1481begin
1482Result.X := (A.X * B.M[0,0]) + (A.Y * B.M[0,1]);
1483Result.Y := (A.X * B.M[1,0]) + (A.Y * B.M[1,1]);
1484end;
1485
1486class operator TMatrix2.Multiply(const A: TMatrix2; const B: TVector2): TVector2;
1487begin
1488Result.X := (A.M[0,0] * B.X) + (A.M[1,0] * B.Y);
1489Result.Y := (A.M[0,1] * B.X) + (A.M[1,1] * B.Y);
1490end;
1491
1492class operator TMatrix2.Multiply(const A, B: TMatrix2): TMatrix2;
1493begin
1494Result.M[0,0] := (A.M[0,0] * B.M[0,0]) + (A.M[1,0] * B.M[0,1]);
1495Result.M[0,1] := (A.M[0,1] * B.M[0,0]) + (A.M[1,1] * B.M[0,1]);
1496Result.M[1,0] := (A.M[0,0] * B.M[1,0]) + (A.M[1,0] * B.M[1,1]);
1497Result.M[1,1] := (A.M[0,1] * B.M[1,0]) + (A.M[1,1] * B.M[1,1]);
1498end;
1499
1500class operator TMatrix2.Negative(const A: TMatrix2): TMatrix2;
1501begin
1502Result.V[0] := -A.V[0];
1503Result.V[1] := -A.V[1];
1504end;
1505
1506procedure TMatrix2.SetTransposed;
1507begin
1508Self := Transpose;
1509end;
1510
1511class operator TMatrix2.Subtract(const A: TMatrix2; const B: Single): TMatrix2;
1512begin
1513Result.V[0] := A.V[0] - B;
1514Result.V[1] := A.V[1] - B;
1515end;
1516
1517class operator TMatrix2.Subtract(const A, B: TMatrix2): TMatrix2;
1518begin
1519Result.V[0] := A.V[0] - B.V[0];
1520Result.V[1] := A.V[1] - B.V[1];
1521end;
1522
1523class operator TMatrix2.Subtract(const A: Single; const B: TMatrix2): TMatrix2;
1524begin
1525Result.V[0] := A - B.V[0];
1526Result.V[1] := A - B.V[1];
1527end;
1528
1529function TMatrix2.Transpose: TMatrix2;
1530begin
1531Result.M[0,0] := M[0,0];
1532Result.M[0,1] := M[1,0];
1533
1534Result.M[1,0] := M[0,1];
1535Result.M[1,1] := M[1,1];
1536end;
1537
1538{ TMatrix3 }
1539
1540class operator TMatrix3.Add(const A: TMatrix3; const B: Single): TMatrix3;
1541begin
1542Result.V[0] := A.V[0] + B;
1543Result.V[1] := A.V[1] + B;
1544Result.V[2] := A.V[2] + B;
1545end;
1546
1547class operator TMatrix3.Add(const A: Single; const B: TMatrix3): TMatrix3;
1548begin
1549Result.V[0] := A + B.V[0];
1550Result.V[1] := A + B.V[1];
1551Result.V[2] := A + B.V[2];
1552end;
1553
1554class operator TMatrix3.Add(const A, B: TMatrix3): TMatrix3;
1555begin
1556Result.V[0] := A.V[0] + B.V[0];
1557Result.V[1] := A.V[1] + B.V[1];
1558Result.V[2] := A.V[2] + B.V[2];
1559end;
1560
1561function TMatrix3.CompMult(const AOther: TMatrix3): TMatrix3;
1562var
1563I: Integer;
1564begin
1565for I := 0 to 2 do
1566Result.V[I] := V[I] * AOther.V[I];
1567end;
1568
1569class operator TMatrix3.Divide(const A: Single; const B: TMatrix3): TMatrix3;
1570begin
1571Result.V[0] := A / B.V[0];
1572Result.V[1] := A / B.V[1];
1573Result.V[2] := A / B.V[2];
1574end;
1575
1576class operator TMatrix3.Divide(const A: TMatrix3; const B: Single): TMatrix3;
1577var
1578InvB: Single;
1579begin
1580InvB := 1 / B;
1581Result.V[0] := A.V[0] * InvB;
1582Result.V[1] := A.V[1] * InvB;
1583Result.V[2] := A.V[2] * InvB;
1584end;
1585
1586class operator TMatrix3.Multiply(const A: Single; const B: TMatrix3): TMatrix3;
1587begin
1588Result.V[0] := A * B.V[0];
1589Result.V[1] := A * B.V[1];
1590Result.V[2] := A * B.V[2];
1591end;
1592
1593class operator TMatrix3.Multiply(const A: TMatrix3; const B: Single): TMatrix3;
1594begin
1595Result.V[0] := A.V[0] * B;
1596Result.V[1] := A.V[1] * B;
1597Result.V[2] := A.V[2] * B;
1598end;
1599
1600{$IFDEF FM_COLUMN_MAJOR}
1601class operator TMatrix3.Multiply(const A: TMatrix3; const B: TVector3): TVector3;
1602begin
1603Result.X := (B.X * A.M[0,0]) + (B.Y * A.M[1,0]) + (B.Z * A.M[2,0]);
1604Result.Y := (B.X * A.M[0,1]) + (B.Y * A.M[1,1]) + (B.Z * A.M[2,1]);
1605Result.Z := (B.X * A.M[0,2]) + (B.Y * A.M[1,2]) + (B.Z * A.M[2,2]);
1606end;
1607
1608class operator TMatrix3.Multiply(const A: TVector3; const B: TMatrix3): TVector3;
1609begin
1610Result.X := (B.M[0,0] * A.X) + (B.M[0,1] * A.Y) + (B.M[0,2] * A.Z);
1611Result.Y := (B.M[1,0] * A.X) + (B.M[1,1] * A.Y) + (B.M[1,2] * A.Z);
1612Result.Z := (B.M[2,0] * A.X) + (B.M[2,1] * A.Y) + (B.M[2,2] * A.Z);
1613end;
1614{$ELSE}
1615class operator TMatrix3.Multiply(const A: TMatrix3; const B: TVector3): TVector3;
1616begin
1617Result.X := (B.X * A.M[0,0]) + (B.Y * A.M[0,1]) + (B.Z * A.M[0,2]);
1618Result.Y := (B.X * A.M[1,0]) + (B.Y * A.M[1,1]) + (B.Z * A.M[1,2]);
1619Result.Z := (B.X * A.M[2,0]) + (B.Y * A.M[2,1]) + (B.Z * A.M[2,2]);
1620end;
1621
1622class operator TMatrix3.Multiply(const A: TVector3; const B: TMatrix3): TVector3;
1623begin
1624Result.X := (B.M[0,0] * A.X) + (B.M[1,0] * A.Y) + (B.M[2,0] * A.Z);
1625Result.Y := (B.M[0,1] * A.X) + (B.M[1,1] * A.Y) + (B.M[2,1] * A.Z);
1626Result.Z := (B.M[0,2] * A.X) + (B.M[1,2] * A.Y) + (B.M[2,2] * A.Z);
1627end;
1628{$ENDIF}
1629
1630class operator TMatrix3.Multiply(const A, B: TMatrix3): TMatrix3;
1631var
1632A00, A01, A02, A10, A11, A12, A20, A21, A22: Single;
1633B00, B01, B02, B10, B11, B12, B20, B21, B22: Single;
1634begin
1635A00 := A.M[0,0];
1636A01 := A.M[0,1];
1637A02 := A.M[0,2];
1638A10 := A.M[1,0];
1639A11 := A.M[1,1];
1640A12 := A.M[1,2];
1641A20 := A.M[2,0];
1642A21 := A.M[2,1];
1643A22 := A.M[2,2];
1644
1645B00 := B.M[0,0];
1646B01 := B.M[0,1];
1647B02 := B.M[0,2];
1648B10 := B.M[1,0];
1649B11 := B.M[1,1];
1650B12 := B.M[1,2];
1651B20 := B.M[2,0];
1652B21 := B.M[2,1];
1653B22 := B.M[2,2];
1654
1655{$IFDEF FM_COLUMN_MAJOR}
1656Result.M[0,0] := (A00 * B00) + (A10 * B01) + (A20 * B02);
1657Result.M[0,1] := (A01 * B00) + (A11 * B01) + (A21 * B02);
1658Result.M[0,2] := (A02 * B00) + (A12 * B01) + (A22 * B02);
1659Result.M[1,0] := (A00 * B10) + (A10 * B11) + (A20 * B12);
1660Result.M[1,1] := (A01 * B10) + (A11 * B11) + (A21 * B12);
1661Result.M[1,2] := (A02 * B10) + (A12 * B11) + (A22 * B12);
1662Result.M[2,0] := (A00 * B20) + (A10 * B21) + (A20 * B22);
1663Result.M[2,1] := (A01 * B20) + (A11 * B21) + (A21 * B22);
1664Result.M[2,2] := (A02 * B20) + (A12 * B21) + (A22 * B22);
1665{$ELSE}
1666Result.M[0,0] := (A00 * B00) + (A01 * B10) + (A02 * B20);
1667Result.M[0,1] := (A00 * B01) + (A01 * B11) + (A02 * B21);
1668Result.M[0,2] := (A00 * B02) + (A01 * B12) + (A02 * B22);
1669Result.M[1,0] := (A10 * B00) + (A11 * B10) + (A12 * B20);
1670Result.M[1,1] := (A10 * B01) + (A11 * B11) + (A12 * B21);
1671Result.M[1,2] := (A10 * B02) + (A11 * B12) + (A12 * B22);
1672Result.M[2,0] := (A20 * B00) + (A21 * B10) + (A22 * B20);
1673Result.M[2,1] := (A20 * B01) + (A21 * B11) + (A22 * B21);
1674Result.M[2,2] := (A20 * B02) + (A21 * B12) + (A22 * B22);
1675{$ENDIF}
1676end;
1677
1678class operator TMatrix3.Negative(const A: TMatrix3): TMatrix3;
1679begin
1680Result.V[0] := -A.V[0];
1681Result.V[1] := -A.V[1];
1682Result.V[2] := -A.V[2];
1683end;
1684
1685procedure TMatrix3.SetTransposed;
1686begin
1687Self := Transpose;
1688end;
1689
1690class operator TMatrix3.Subtract(const A: TMatrix3; const B: Single): TMatrix3;
1691begin
1692Result.V[0] := A.V[0] - B;
1693Result.V[1] := A.V[1] - B;
1694Result.V[2] := A.V[2] - B;
1695end;
1696
1697class operator TMatrix3.Subtract(const A, B: TMatrix3): TMatrix3;
1698begin
1699Result.V[0] := A.V[0] - B.V[0];
1700Result.V[1] := A.V[1] - B.V[1];
1701Result.V[2] := A.V[2] - B.V[2];
1702end;
1703
1704class operator TMatrix3.Subtract(const A: Single; const B: TMatrix3): TMatrix3;
1705begin
1706Result.V[0] := A - B.V[0];
1707Result.V[1] := A - B.V[1];
1708Result.V[2] := A - B.V[2];
1709end;
1710
1711function TMatrix3.Transpose: TMatrix3;
1712begin
1713Result.M[0,0] := M[0,0];
1714Result.M[0,1] := M[1,0];
1715Result.M[0,2] := M[2,0];
1716
1717Result.M[1,0] := M[0,1];
1718Result.M[1,1] := M[1,1];
1719Result.M[1,2] := M[2,1];
1720
1721Result.M[2,0] := M[0,2];
1722Result.M[2,1] := M[1,2];
1723Result.M[2,2] := M[2,2];
1724end;
1725
1726{ TMatrix 4 }
1727
1728class operator TMatrix4.Add(const A: TMatrix4; const B: Single): TMatrix4;
1729begin
1730Result.V[0] := A.V[0] + B;
1731Result.V[1] := A.V[1] + B;
1732Result.V[2] := A.V[2] + B;
1733Result.V[3] := A.V[3] + B;
1734end;
1735
1736class operator TMatrix4.Add(const A: Single; const B: TMatrix4): TMatrix4;
1737begin
1738Result.V[0] := A + B.V[0];
1739Result.V[1] := A + B.V[1];
1740Result.V[2] := A + B.V[2];
1741Result.V[3] := A + B.V[3];
1742end;
1743
1744class operator TMatrix4.Add(const A, B: TMatrix4): TMatrix4;
1745begin
1746Result.V[0] := A.V[0] + B.V[0];
1747Result.V[1] := A.V[1] + B.V[1];
1748Result.V[2] := A.V[2] + B.V[2];
1749Result.V[3] := A.V[3] + B.V[3];
1750end;
1751
1752function TMatrix4.CompMult(const AOther: TMatrix4): TMatrix4;
1753var
1754I: Integer;
1755begin
1756for I := 0 to 3 do
1757Result.V[I] := V[I] * AOther.V[I];
1758end;
1759
1760class operator TMatrix4.Divide(const A: Single; const B: TMatrix4): TMatrix4;
1761begin
1762Result.V[0] := A / B.V[0];
1763Result.V[1] := A / B.V[1];
1764Result.V[2] := A / B.V[2];
1765Result.V[3] := A / B.V[3];
1766end;
1767
1768class operator TMatrix4.Divide(const A: TMatrix4; const B: Single): TMatrix4;
1769var
1770InvB: Single;
1771begin
1772InvB := 1 / B;
1773Result.V[0] := A.V[0] * InvB;
1774Result.V[1] := A.V[1] * InvB;
1775Result.V[2] := A.V[2] * InvB;
1776Result.V[3] := A.V[3] * InvB;
1777end;
1778
1779function TMatrix4.Inverse: TMatrix4;
1780var
1781C00, C02, C03, C04, C06, C07, C08, C10, C11: Single;
1782C12, C14, C15, C16, C18, C19, C20, C22, C23: Single;
1783F0, F1, F2, F3, F4, F5, V0, V1, V2, V3, I0, I1, I2, I3, SA, SB, Row, Dot: TVector4;
1784Inv: TMatrix4;
1785OneOverDeterminant: Single;
1786begin
1787C00 := (M[2,2] * M[3,3]) - (M[3,2] * M[2,3]);
1788C02 := (M[1,2] * M[3,3]) - (M[3,2] * M[1,3]);
1789C03 := (M[1,2] * M[2,3]) - (M[2,2] * M[1,3]);
1790
1791C04 := (M[2,1] * M[3,3]) - (M[3,1] * M[2,3]);
1792C06 := (M[1,1] * M[3,3]) - (M[3,1] * M[1,3]);
1793C07 := (M[1,1] * M[2,3]) - (M[2,1] * M[1,3]);
1794
1795C08 := (M[2,1] * M[3,2]) - (M[3,1] * M[2,2]);
1796C10 := (M[1,1] * M[3,2]) - (M[3,1] * M[1,2]);
1797C11 := (M[1,1] * M[2,2]) - (M[2,1] * M[1,2]);
1798
1799C12 := (M[2,0] * M[3,3]) - (M[3,0] * M[2,3]);
1800C14 := (M[1,0] * M[3,3]) - (M[3,0] * M[1,3]);
1801C15 := (M[1,0] * M[2,3]) - (M[2,0] * M[1,3]);
1802
1803C16 := (M[2,0] * M[3,2]) - (M[3,0] * M[2,2]);
1804C18 := (M[1,0] * M[3,2]) - (M[3,0] * M[1,2]);
1805C19 := (M[1,0] * M[2,2]) - (M[2,0] * M[1,2]);
1806
1807C20 := (M[2,0] * M[3,1]) - (M[3,0] * M[2,1]);
1808C22 := (M[1,0] * M[3,1]) - (M[3,0] * M[1,1]);
1809C23 := (M[1,0] * M[2,1]) - (M[2,0] * M[1,1]);
1810
1811F0 := Vector4(C00, C00, C02, C03);
1812F1 := Vector4(C04, C04, C06, C07);
1813F2 := Vector4(C08, C08, C10, C11);
1814F3 := Vector4(C12, C12, C14, C15);
1815F4 := Vector4(C16, C16, C18, C19);
1816F5 := Vector4(C20, C20, C22, C23);
1817
1818V0 := Vector4(M[1,0], M[0,0], M[0,0], M[0,0]);
1819V1 := Vector4(M[1,1], M[0,1], M[0,1], M[0,1]);
1820V2 := Vector4(M[1,2], M[0,2], M[0,2], M[0,2]);
1821V3 := Vector4(M[1,3], M[0,3], M[0,3], M[0,3]);
1822
1823I0 := (V1 * F0) - (V2 * F1) + (V3 * F2);
1824I1 := (V0 * F0) - (V2 * F3) + (V3 * F4);
1825I2 := (V0 * F1) - (V1 * F3) + (V3 * F5);
1826I3 := (V0 * F2) - (V1 * F4) + (V2 * F5);
1827
1828SA := Vector4(+1, -1, +1, -1);
1829SB := Vector4(-1, +1, -1, +1);
1830
1831Inv := Matrix4(I0 * SA, I1 * SB, I2 * SA, I3 * SB);
1832
1833Row := Vector4(Inv[0,0], Inv[1,0], Inv[2,0], Inv[3,0]);
1834Dot := V[0] * Row;
1835
1836OneOverDeterminant := 1 / ((Dot.X + Dot.Y) + (Dot.Z + Dot.W));
1837Result := Inv * OneOverDeterminant;
1838end;
1839
1840class operator TMatrix4.Multiply(const A: Single; const B: TMatrix4): TMatrix4;
1841begin
1842Result.V[0] := A * B.V[0];
1843Result.V[1] := A * B.V[1];
1844Result.V[2] := A * B.V[2];
1845Result.V[3] := A * B.V[3];
1846end;
1847
1848class operator TMatrix4.Multiply(const A: TMatrix4; const B: Single): TMatrix4;
1849begin
1850Result.V[0] := A.V[0] * B;
1851Result.V[1] := A.V[1] * B;
1852Result.V[2] := A.V[2] * B;
1853Result.V[3] := A.V[3] * B;
1854end;
1855
1856{$IFDEF FM_COLUMN_MAJOR}
1857class operator TMatrix4.Multiply(const A: TVector4; const B: TMatrix4): TVector4;
1858begin
1859Result.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]);
1860Result.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]);
1861Result.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]);
1862Result.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]);
1863end;
1864
1865class operator TMatrix4.Multiply(const A: TMatrix4; const B: TVector4): TVector4;
1866begin
1867Result.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]);
1868Result.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]);
1869Result.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]);
1870Result.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]);
1871end;
1872
1873class operator TMatrix4.Multiply(const A, B: TMatrix4): TMatrix4;
1874begin
1875Result.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]);
1876Result.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]);
1877Result.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]);
1878Result.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
1880Result.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]);
1881Result.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]);
1882Result.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]);
1883Result.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
1885Result.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]);
1886Result.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]);
1887Result.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]);
1888Result.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
1890Result.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]);
1891Result.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]);
1892Result.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]);
1893Result.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]);
1894end;
1895{$ELSE}
1896class operator TMatrix4.Multiply(const A: TVector4; const B: TMatrix4): TVector4;
1897begin
1898Result.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);
1899Result.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);
1900Result.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);
1901Result.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);
1902end;
1903
1904class operator TMatrix4.Multiply(const A: TMatrix4; const B: TVector4): TVector4;
1905begin
1906Result.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]);
1907Result.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]);
1908Result.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]);
1909Result.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]);
1910end;
1911
1912class operator TMatrix4.Multiply(const A, B: TMatrix4): TMatrix4;
1913begin
1914Result.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]);
1915Result.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]);
1916Result.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]);
1917Result.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
1919Result.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]);
1920Result.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]);
1921Result.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]);
1922Result.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
1924Result.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]);
1925Result.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]);
1926Result.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]);
1927Result.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
1929Result.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]);
1930Result.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]);
1931Result.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]);
1932Result.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]);
1933end;
1934{$ENDIF}
1935
1936class operator TMatrix4.Negative(const A: TMatrix4): TMatrix4;
1937begin
1938Result.V[0] := -A.V[0];
1939Result.V[1] := -A.V[1];
1940Result.V[2] := -A.V[2];
1941Result.V[3] := -A.V[3];
1942end;
1943
1944procedure TMatrix4.SetInversed;
1945begin
1946Self := Inverse;
1947end;
1948
1949procedure TMatrix4.SetTransposed;
1950begin
1951Self := Transpose;
1952end;
1953
1954class operator TMatrix4.Subtract(const A: TMatrix4; const B: Single): TMatrix4;
1955begin
1956Result.V[0] := A.V[0] - B;
1957Result.V[1] := A.V[1] - B;
1958Result.V[2] := A.V[2] - B;
1959Result.V[3] := A.V[3] - B;
1960end;
1961
1962class operator TMatrix4.Subtract(const A, B: TMatrix4): TMatrix4;
1963begin
1964Result.V[0] := A.V[0] - B.V[0];
1965Result.V[1] := A.V[1] - B.V[1];
1966Result.V[2] := A.V[2] - B.V[2];
1967Result.V[3] := A.V[3] - B.V[3];
1968end;
1969
1970class operator TMatrix4.Subtract(const A: Single; const B: TMatrix4): TMatrix4;
1971begin
1972Result.V[0] := A - B.V[0];
1973Result.V[1] := A - B.V[1];
1974Result.V[2] := A - B.V[2];
1975Result.V[3] := A - B.V[3];
1976end;
1977
1978function TMatrix4.Transpose: TMatrix4;
1979begin
1980Result.M[0,0] := M[0,0];
1981Result.M[0,1] := M[1,0];
1982Result.M[0,2] := M[2,0];
1983Result.M[0,3] := M[3,0];
1984
1985Result.M[1,0] := M[0,1];
1986Result.M[1,1] := M[1,1];
1987Result.M[1,2] := M[2,1];
1988Result.M[1,3] := M[3,1];
1989
1990Result.M[2,0] := M[0,2];
1991Result.M[2,1] := M[1,2];
1992Result.M[2,2] := M[2,2];
1993Result.M[2,3] := M[3,2];
1994
1995Result.M[3,0] := M[0,3];
1996Result.M[3,1] := M[1,3];
1997Result.M[3,2] := M[2,3];
1998Result.M[3,3] := M[3,3];
1999end;
2000