123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2023 by Michael Van Canneyt
- member of the Free Pascal development team
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- {
- Tests were made to determine where delphi implementation differs
- from standards and glscene, and adapt the implementation
- The numbers of tests done here can also be found in the unit tests.
-
- run this application with number of test to run only that test.
- }
- {$IFDEF FPC}
- {$mode delphi}
- uses SysUtils, System.Math.Vectors;
- {$ELSE}
- uses System.SysUtils, System.Math.Vectors;
- {$ENDIF}
- {$IFNDEF FPC}
- Function MIdentity : TMatrix;
- begin
- Result:=TMatrix.Identity;
- end;
- Function M3DIdentity : TMatrix3D;
- begin
- Result:=TMatrix3D.Identity;
- end;
- // Delphi does not have ToString, use helper to implement it.
- // We cannot inherit record helpers in Delphi,
- // so we define this after the above functions to have Identity.
- Type
- TVHelper = record Helper for TVector
- Function ToString: String;
- end;
- TPHelper = record Helper for TPoint3D
- Function ToString: String;
- end;
- TMHelper = record Helper {(TMatrixConstants)} for TMatrix
- function ToString(Multiline: Boolean = True): String;
- class function Identity : TMatrix; static;
- end;
- TM3DHelper = record Helper {(TMatrixConstants)} for TMatrix3D
- function ToString(Multiline: Boolean = True): String;
- class function Identity : TMatrix3D; static;
- end;
- TQ3DHelper = record Helper {(TMatrixConstants)} for TQuaternion3D
- function ToString(Multiline: Boolean = True): String;
- end;
- Function TVHelper.ToString: String;
- begin
- Result:=Format('(%7.4f,%7.4f W:%7.4f)',[X,Y,W]);
- end;
- Function TPHelper.ToString: String;
- begin
- Result:=Format('(%7.4f,%7.4f,%7.4f)',[X,Y,Z]);
- end;
- class function TMHelper.Identity : TMatrix;
- begin
- Result:=Midentity;
- end;
- function TMHelper.ToString(Multiline: Boolean): String;
- var
- S,Sep : String;
- begin
- Sep:='';
- if MultiLine then
- Sep:=sLineBreak;
- S:='['+Format('%7.4f,%7.4f,%7.4f',[m11,m12,m13]);
- Result:=S+','+Sep;
- S:=Format('%7.4f,%7.4f,%7.4f',[m21,m22,m23]);
- Result:=Result+S+Sep;
- S:=Format('%7.4f,%7.4f,%7.4f',[m31,m32,m33]);
- Result:=Result+S+']';
- end;
- class function TM3DHelper.Identity : TMatrix3D;
- begin
- Result:=M3Didentity;
- end;
- function TM3DHelper.ToString(Multiline: Boolean): String;
- var
- S,Sep : String;
- begin
- Sep:='';
- if MultiLine then
- Sep:=sLineBreak;
- S:='['+Format('%7.4f,%7.4f,%7.4f,%7.4f',[m11,m12,m13,m14]);
- Result:=S+','+Sep;
- S:=Format('%7.4f,%7.4f,%7.4f,%7.4f',[m21,m22,m23,m24]);
- Result:=Result+S+','+Sep;
- S:=Format('%7.4f,%7.4f,%7.4f,%7.4f',[m31,m32,m33,m34]);
- Result:=Result+S+','+Sep;
- S:=Format('%7.4f,%7.4f,%7.4f,%7.4f',[m41,m42,m43,m44]);
- Result:=Result+S+']';
- end;
-
- function TQ3DHelper.ToString(Multiline: Boolean = True): String;
-
- begin
- Result:=Format('(%7.4f,i: %7.4f,j: %7.4f, k: %7.4f)',[Realpart,ImagPart.X,ImagPart.Y,ImagPart.Z]);
- end;
- {$ENDIF}
- Function DoTest(aId : integer; const aCaption : String) : boolean;
- var
- cID : Integer;
- begin
- cID:=StrToIntDef(Paramstr(1),-1);
- Result:=(aId=cID) or (Cid=-1);
- if Result then
- Writeln('[',aID,'] ',aCaption);
- end;
- Procedure TV;
- var
- V1,V2,V3 : TVector;
- begin
- if DoTest(1,'Vector CrossProduct') then
- begin
- V1:=TVector.Create(1,0,0);
- V2:=TVector.Create(0,1,0);
- V3:=V2.CrossProduct(V1);
- With V3 do
- Writeln('1: V3 ',V3.ToString);
- end;
- end;
- Procedure TP;
- var
- P1,P2,P3 : TPoint3D;
- begin
- P1:=TPoint3D.Create(1,0,0);
- P2:=TPoint3D.Create(0,0,1); // Z-axis
- if DoTest(101,'Rotate Z axis') then
- begin
- P3:=P1.Rotate(P2,Pi/2);
- Writeln('P3 = ',P3.ToString);
- end;
- if DoTest(102,'Rotate Y axis') then
- begin
- P2:=TPoint3D.Create(0,1,0); // Y-axis
- P3:=P1.Rotate(P2,Pi/2);
- Writeln('P3 = ',P3.ToString);
- end;
- end;
- Procedure TM;
- var
- M,M2 : TMatrix;
- begin
- if DoTest(11,'Identity') then
- begin
- M:=TMatrix.Identity;
- Writeln(M.ToString);
- end;
- If DoTest(12,'Rotation (Pi/2)') then
- begin
- M:=TMatrix.CreateRotation(Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(13,'Rotation Pi') then
- begin
- M:=TMatrix.CreateRotation(Pi);
- Writeln(M.ToString);
- end;
- If DoTest(14,'Scaling 2') then
- begin
- M:=TMatrix.CreateScaling(2,3);
- Writeln(M.ToString);
- end;
- If DoTest(15,'Translation (3,4)') then
- begin
- M:=TMatrix.CreateTranslation(3,4);
- Writeln(M.ToString);
- end;
- If DoTest(16,'Adjoint') then
- begin
- M:=TMatrix.CreateRotation(Pi/6);
- M2:=M.Adjoint;
- Writeln(M2.ToString);
- end;
- end;
- Procedure Params(const ASource, ATarget, ACeiling: TPoint3D);
- var
- ZAxis, XAxis, YAxis: TPoint3D;
- begin
- Writeln('aSource: ',aSource.ToString);
- Writeln('aTarget: ',aTarget.ToString);
- Writeln('aCeiling: ',aCeiling.ToString);
-
- ZAxis := (ASource - ATarget).Normalize;
- Writeln('Zaxis: ',ZAxis.ToString);
- XAxis := ACeiling.CrossProduct(ZAxis).Normalize;
- Writeln('Xaxis: ',XAxis.ToString);
- YAxis := ZAxis.CrossProduct(XAxis);
- Writeln('Yaxis: ',YAxis.ToString);
- end;
- Procedure TM3D;
- var
- M,M2,M3 : TMatrix3D;
- begin
- if DoTest(31,'M3D.Identity') then
- begin
- M:=TMatrix3D.Identity;
- Writeln(M.ToString);
- end;
- if DoTest(32,'M3D.Rotation ((1,0,0),Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotation(Point3D(1,0,0),Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(33,'M3D.Rotation ((0,1,0),Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotation(Point3D(0,1,0),Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(34,'M3D.Rotation ((0,0,1),Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotation(Point3D(0,0,1),pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(35,'M3D.Scaling (1,2,3)') then
- begin
- M:=TMatrix3D.CreateScaling(Point3D(1,2,3));
- Writeln(M.ToString);
- end;
- if DoTest(36,'MD3D.Translation (3,4,5)') then
- begin
- M:=TMatrix3d.CreateTranslation(Point3D(3,4,5));
- Writeln(M.ToString);
- end;
- if DoTest(37,'M3D.HeadingPitchBank(Pi/2,0,0)') then
- begin
- M:=TMatrix3D.CreateRotationHeadingPitchBank(Pi/2,0,0);
- Writeln(M.ToString);
- end;
- if DoTest(38,'M3D.HeadingPitchBank(0,Pi/2,0)') then
- begin
- M:=TMatrix3D.CreateRotationHeadingPitchBank(0,Pi/2,0);
- Writeln(M.ToString);
- end;
- if DoTest(39,'M3D.HeadingPitchBank(0,0,Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotationHeadingPitchBank(0,0,Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(40,'M3D.RotationX(Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotationX(Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(41,'M3D.RotationY(Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotationY(Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(42,'M3D.RotationZ(Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotationZ(Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(43,'M3D.YawPitchRoll(Pi/2,0,0)') then
- begin
- M:=TMatrix3D.CreateRotationYawPitchRoll(Pi/2,0,0);
- Writeln(M.ToString);
- end;
- if DoTest(44,'M3D.YawPitchRoll(0,Pi/2,0)') then
- begin
- M:=TMatrix3D.CreateRotationYawPitchRoll(0,Pi/2,0);
- Writeln(M.ToString);
- end;
- if DoTest(45,'M3D.YawPitchRoll(0,0,Pi/2)') then
- begin
- M:=TMatrix3D.CreateRotationYawPitchRoll(0,0,Pi/2);
- Writeln(M.ToString);
- end;
- if DoTest(46,'M3D.LookAtDirLH((0,0,0),(0,0,1),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtDirLH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(47,'M3D.LookAtDirLH((0,0,0),(0,1,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtDirLH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(48,'M3D.LookAtDirLH((0,0,0),(1,0,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtDirLH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(49,'M3D.LookAtDirRH((0,0,0),(0,0,1),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtDirRH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(50,'M3D.LookAtDirRH((0,0,0),(0,1,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtDirRH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(51,'M3D.LookAtDirRH((0,0,0),(1,0,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtDirRH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(52,'M3D.LookAtLH((0,0,0),(0,0,1),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtLH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(53,'M3D.LookAtLH((0,0,0),(0,1,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtLH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(54,'M3D.LookAtLH((0,0,0),(1,0,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtLH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(55,'M3D.LookAtRH((0,0,0),(0,0,1),(0,0,1)') then
- begin
- Params(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
- M:=TMatrix3D.CreateLookAtRH(Point3D(0,0,0),Point3D(0,0,1),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(56,'M3D.LookAtRH((0,0,0),(0,1,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtRH(Point3D(0,0,0),Point3D(0,1,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(57,'M3D.LookAtRH((0,0,0),(1,0,0),(0,0,1)') then
- begin
- M:=TMatrix3D.CreateLookAtRH(Point3D(0,0,0),Point3D(1,0,0),Point3D(0,0,1));
- Writeln(M.ToString);
- end;
- if DoTest(58,'M3D.CreateOrthoLH(1,1,0,1)') then
- begin
- M:=TMatrix3D.CreateOrthoLH(1,1,0,1);
- Writeln(M.ToString);
- end;
- if DoTest(59,'M3D.CreateOrthoLH(1,1,0,2)') then
- begin
- M:=TMatrix3D.CreateOrthoLH(1,1,0,2);
- Writeln(M.ToString);
- end;
- if DoTest(60,'M3D.CreateOrthoRH(1,1,0,1)') then
- begin
- M:=TMatrix3D.CreateOrthoRH(1,1,0,1);
- Writeln(M.ToString);
- end;
- if DoTest(61,'M3D.CreateOrthoRH(1,1,0,2)') then
- begin
- M:=TMatrix3D.CreateOrthoRH(1,1,0,2);
- Writeln(M.ToString);
- end;
- if DoTest(62,'M3D.CreateOrthoOffCenterLH(0,0,1,1,0,1)') then
- begin
- M:=TMatrix3D.CreateOrthoOffCenterLH(0,0,1,1,0,1);
- Writeln(M.ToString);
- end;
- if DoTest(63,'M3D.CreateOrthoOffCenterLH(0,0,1,1,0,2)') then
- begin
- M:=TMatrix3D.CreateOrthoOffCenterLH(0,0,1,1,0,2);
- Writeln(M.ToString);
- end;
- if DoTest(64,'M3D.CreateOrthoOffCenterRH(0,0,1,1,0,1)') then
- begin
- M:=TMatrix3D.CreateOrthoOffCenterRH(0,0,1,1,0,1);
- Writeln(M.ToString);
- end;
- if DoTest(65,'M3D.CreateOrthoOffCenterRH(0,0,1,1,0,2)') then
- begin
- M:=TMatrix3D.CreateOrthoOffCenterRH(0,0,1,1,0,2);
- Writeln(M.ToString);
- end;
- if DoTest(66,'M3D.CreatePerspectiveFovLH(pi/2,1,0,1)') then
- begin
- M:=TMatrix3D.CreatePerspectiveFovLH(pi/2,1,0,1);
- Writeln(M.ToString);
- end;
- if DoTest(67,'M3D.CreatePerspectiveFovLH(pi/21,0,1,True)') then
- begin
- M:=TMatrix3D.CreatePerspectiveFovLH(pi/2,1,0,1,True);
- Writeln(M.ToString);
- end;
- if DoTest(68,'M3D.CreatePerspectiveFovRH(pi/2,1,0,1)') then
- begin
- M:=TMatrix3D.CreatePerspectiveFovRH(pi/2,1,0,1);
- Writeln(M.ToString);
- end;
- if DoTest(69,'M3D.CreatePerspectiveFovRH(pi/2,1,0,1,True)') then
- begin
- M:=TMatrix3D.CreatePerspectiveFovRH(pi/2,1,0,1,True);
- Writeln(M.ToString);
- end;
- if DoTest(70,'M3D.Create(array)') then
- begin
- M:=TMatrix3D.Create([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
- Writeln(M.ToString);
- end;
- if DoTest(71,'M3D.CreateScaling(Point3D(1,2,3))') then
- begin
- M:=TMatrix3D.CreateScaling(Point3D(1,2,3));
- Writeln(M.ToString);
- end;
- if DoTest(72,'M3D.CreateTranslation(Point3D(1,2,3))') then
- begin
- M:=TMatrix3D.CreateTranslation(Point3D(1,2,3));
- Writeln(M.ToString);
- end;
- if DoTest(73,'M3D*M3D') then
- begin
- M:=TMatrix3D.Create( [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
- M2:=TMatrix3D.Create([16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]);
- M3:=M*M2;
- Writeln(M3.ToString);
- end;
- if DoTest(74,'M3D.Adjoint') then
- begin
- M:=TMatrix3D.CreateRotationZ(Pi/3);
- M2:=M.Adjoint;
- Writeln(M2.ToString);
- end;
- if DoTest(75,'M3D.Determinant') then
- begin
- M:=TMatrix3D.CreateRotationZ(Pi/3);
- Writeln(M.Determinant);
- end;
- if DoTest(76,'M3D.Determinant') then
- begin
- M:=TMatrix3D.Create(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
- // M:=TMatrix3D.Create(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);
- Writeln(M.Determinant);
- end;
- if DoTest(77,'M3D.Rotation.EyePosition') then
- begin
- M:=TMatrix3D.CreateRotationZ(Pi/2);
- Writeln(M.EyePosition.ToString);
- end;
- if DoTest(78,'M3D.Translation.EyePosition') then
- begin
- M:=TMatrix3D.CreateRotationZ(Pi/3)*TMatrix3D.CreateTranslation(Point3D(1,0,0));
- Writeln(M.EyePosition.ToString);
- end;
- if DoTest(79,'M3D.Inverse') then
- begin
- M:=TMatrix3D.CreateRotationZ(Pi/3);
- Writeln(M.Inverse.ToString);
- end;
-
-
- end;
- Procedure TQ;
- var
- Q1,Q2 : TQuaternion3D;
- begin
- {$IFDEF FPC}
- If DoTest(201,'TQuaternion3D.Create(Point3D(1,0,0),Point3D(0,1,0))') then
- begin
- Q1:=TQuaternion3D.Create(Point3D(1,0,0),Point3D(0,1,0));
- Writeln('Q = ',Q1.ToString);
- end;
- {$ENDIF}
- If DoTest(202,'TQuaternion3D.Create(Point3D(1,0,0),Pi/2)') then
- begin
- Q1:=TQuaternion3D.Create(Point3D(1,0,0),Pi/2);
- Writeln('Q = ',Q1.ToString);
- end;
- If DoTest(203,'TQuaternion3D.Create(Point3D(0,1,0),Pi/2)') then
- begin
- Q1:=TQuaternion3D.Create(Point3D(0,1,0),Pi/2);
- Writeln('Q = ',Q1.ToString);
- end;
- If DoTest(204,'TQuaternion3D.Create(Point3D(0,0,1),Pi/2)') then
- begin
- Q1:=TQuaternion3D.Create(Point3D(0,0,1),Pi/2);
- Writeln('Q = ',Q1.ToString);
- end;
- If DoTest(205,'TQuaternion3D.Create(Pi/2,0,0)') then
- begin
- Q1:=TQuaternion3D.Create(Pi/2,0,0);
- Writeln('Q = ',Q1.ToString);
- end;
- If DoTest(206,'TQuaternion3D.Create(0,Pi/2,0)') then
- begin
- Q1:=TQuaternion3D.Create(0,Pi/2,0);
- Writeln('Q = ',Q1.ToString);
- end;
- If DoTest(207,'TQuaternion3D.Create(0,0,Pi/2)') then
- begin
- Q1:=TQuaternion3D.Create(0,0,Pi/2);
- Writeln('Q = ',Q1.ToString);
- end;
- If DoTest(208,'TQuaternion3D.Multiply (yawpitchroll)') then
- begin
- Q1:=TQuaternion3D.Create(0,0,Pi/2);
- Q2:=TQuaternion3D.Create(0,Pi/2,0);
- Writeln('Q1*Q2 = ',(Q1*Q2).ToString);
- end;
- If DoTest(209,'TQuaternion3D.Multiply (angle/vector)') then
- begin
- Q1:=TQuaternion3D.Create(Point3D(1,0,0),Pi/2);
- Q2:=TQuaternion3D.Create(Point3D(0,1,0),Pi/2);
- Writeln('Q1*Q2 = ',(Q1*Q2).ToString);
- end;
- end;
- begin
- TV;
- TP;
- TM;
- TM3D;
- TQ;
- end.
|