Matrices4.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:25k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit Matrices4;
  2. //---------------------------------------------------------------------------
  3. // Matrices4.pas                                        Modified: 02-Apr-2007
  4. // Definitions and functions working with 3D 4x4 matrices         Version 1.0
  5. //---------------------------------------------------------------------------
  6. // Important Notice:
  7. //
  8. // If you modify/use this code or one of its parts either in original or
  9. // modified form, you must comply with Mozilla Public License v1.1,
  10. // specifically section 3, "Distribution Obligations". Failure to do so will
  11. // result in the license breach, which will be resolved in the court.
  12. // Remember that violating author's rights is considered a serious crime in
  13. // many countries. Thank you!
  14. //
  15. // !! Please *read* Mozilla Public License 1.1 document located at:
  16. //  http://www.mozilla.org/MPL/
  17. //
  18. // If you require any clarifications about the license, feel free to contact
  19. // us or post your question on our forums at: http://www.afterwarp.net
  20. //---------------------------------------------------------------------------
  21. // The contents of this file are subject to the Mozilla Public License
  22. // Version 1.1 (the "License"); you may not use this file except in
  23. // compliance with the License. You may obtain a copy of the License at
  24. // http://www.mozilla.org/MPL/
  25. //
  26. // Software distributed under the License is distributed on an "AS IS"
  27. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  28. // License for the specific language governing rights and limitations
  29. // under the License.
  30. //
  31. // The Original Code is Matrices4.pas.
  32. //
  33. // The Initial Developer of the Original Code is M. Sc. Yuriy Kotsarenko.
  34. // Portions created by M. Sc. Yuriy Kotsarenko are Copyright (C) 2007,
  35. // M. Sc. Yuriy Kotsarenko. All Rights Reserved.
  36. //---------------------------------------------------------------------------
  37. interface
  38. //---------------------------------------------------------------------------
  39. // Enable the following option to take advantage of mathematical routines
  40. // from D3DX interface.
  41. //---------------------------------------------------------------------------
  42. {$define SupportD3DX}
  43. //---------------------------------------------------------------------------
  44. uses
  45.  {$ifdef SupportD3DX}d3dx9,{$endif} SysUtils, Math, Vectors3;
  46. //---------------------------------------------------------------------------
  47. type
  48.  PMatrix4 = ^TMatrix4;
  49.  TMatrix4 = record
  50.   Data: array[0..3, 0..3] of Single;
  51.   class operator Add(const a, b: TMatrix4): TMatrix4;
  52.   class operator Subtract(const a, b: TMatrix4): TMatrix4;
  53.   class operator Multiply(const a, b: TMatrix4): TMatrix4;
  54.   class operator Multiply(const Mtx: TMatrix4; Theta: Single): TMatrix4;
  55.   class operator Multiply(const v: TVector3; const m: TMatrix4): TVector3;
  56.   class operator Divide(const Mtx: TMatrix4; Theta: Single): TMatrix4;
  57.   function GetPos(): TVector3;
  58.  end;
  59. //---------------------------------------------------------------------------
  60. const
  61.  IdentityMtx4: TMatrix4 = (Data: ((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0),
  62.   (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0)));
  63.  ZeroMtx4: TMatrix4 = (Data: ((0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0),
  64.   (0.0, 0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 0.0)));
  65. //---------------------------------------------------------------------------
  66. // Matrix Transposition
  67. //---------------------------------------------------------------------------
  68. function TransposeMtx4(const Mtx: TMatrix4): TMatrix4;
  69. //---------------------------------------------------------------------------
  70. // Inverse of the Matrix
  71. //---------------------------------------------------------------------------
  72. function InvertMtx4(const m: TMatrix4): TMatrix4;
  73. //---------------------------------------------------------------------------
  74. // Translation Matrix
  75. //---------------------------------------------------------------------------
  76. function TranslateMtx4(const Offset: TVector3): TMatrix4;
  77. //---------------------------------------------------------------------------
  78. // Scaling Matrix
  79. //---------------------------------------------------------------------------
  80. function ScaleMtx4(const Coef: TVector3): TMatrix4;
  81. //---------------------------------------------------------------------------
  82. // String Representation of Matrix
  83. //---------------------------------------------------------------------------
  84. function StringMtx4(const m: TMatrix4): string;
  85. //---------------------------------------------------------------------------
  86. // Rotation Matrix around X-axis
  87. //---------------------------------------------------------------------------
  88. function RotateXMtx4(Angle: Single): TMatrix4;
  89. //---------------------------------------------------------------------------
  90. // Rotation Matrix around Y-axis
  91. //---------------------------------------------------------------------------
  92. function RotateYMtx4(Angle: Single): TMatrix4;
  93. //---------------------------------------------------------------------------
  94. // Rotation Matrix around Z-axis
  95. //---------------------------------------------------------------------------
  96. function RotateZMtx4(Angle: Single): TMatrix4;
  97. //---------------------------------------------------------------------------
  98. // Rotation Matrix around an arbitrary axis
  99. //---------------------------------------------------------------------------
  100. function RotateMtx4(const Axis: TVector3; Angle: Single): TMatrix4;
  101. //---------------------------------------------------------------------------
  102. // Reflection Matrix
  103. //---------------------------------------------------------------------------
  104. function ReflectMtx4(const Axis: TVector3): TMatrix4;
  105. //---------------------------------------------------------------------------
  106. // Look at given point Matrix (left-handed coordinates)
  107. //---------------------------------------------------------------------------
  108. function LookAtMtx4(const Origin, Target, Roof: TVector3): TMatrix4;
  109. //---------------------------------------------------------------------------
  110. // Perspective Projection with Field of View in Y-axis
  111. //---------------------------------------------------------------------------
  112. function PerspectiveFOVYMtx4(FieldOfView, AspectRatio, MinRange,
  113.  MaxRange: Single): TMatrix4;
  114. //---------------------------------------------------------------------------
  115. // Perspective Projection with Field of View in X-axis
  116. //---------------------------------------------------------------------------
  117. function PerspectiveFOVXMtx4(FieldOfView, AspectRatio, MinRange,
  118.  MaxRange: Single): TMatrix4;
  119. //---------------------------------------------------------------------------
  120. // Perspective Projection with View Volume
  121. //---------------------------------------------------------------------------
  122. function PerspectiveVOLMtx4(Width, Height, MinRange, MaxRange: Single): TMatrix4;
  123. //---------------------------------------------------------------------------
  124. // Perspective Projection with Axis Boundaries
  125. //---------------------------------------------------------------------------
  126. function PerspectiveBDSMtx4(Left, Right, Top, Bottom, MinRange,
  127.  MaxRange: Single): TMatrix4;
  128. //---------------------------------------------------------------------------
  129. // Orthogonal Projection with View Volume
  130. //---------------------------------------------------------------------------
  131. function OrthogonalVOLMtx4(Width, Height, MinRange, MaxRange: Single): TMatrix4;
  132. //---------------------------------------------------------------------------
  133. // Orthogonal Projection with Axis Boundaries
  134. //---------------------------------------------------------------------------
  135. function OrthogonalBDSMtx4(Left, Right, Top, Bottom, MinRange,
  136.  MaxRange: Single): TMatrix4;
  137. //---------------------------------------------------------------------------
  138. // Euler rotation matrix with respective heading, pitch and bank.
  139. //---------------------------------------------------------------------------
  140. function HeadingPitchBankMtx4(Heading, Pitch,
  141.  Bank: Single): TMatrix4; overload;
  142. function HeadingPitchBankMtx4(const v: TVector3): TMatrix4; overload;
  143. //---------------------------------------------------------------------------
  144. {$ifdef SupportD3DX}
  145. function YawPitchRollMtx4(Yaw, Pitch, Roll: Single): TMatrix4; overload;
  146. function YawPitchRollMtx4(const v: TVector3): TMatrix4; overload;
  147. {$endif}
  148. //---------------------------------------------------------------------------
  149. implementation
  150. //--------------------------------------------------------------------------
  151. type
  152.  PLMatrix4 = ^TLMatrix4;
  153.  TLMatrix4 = array[0..15] of Single;
  154. //---------------------------------------------------------------------------
  155. function TMatrix4.GetPos(): TVector3;
  156. var
  157.  View: PLMatrix4;
  158. begin
  159.  View:= @Data[0, 0];
  160.  Result.x:= -View[0] * View[12] - View[1] * View[13] - View[2] * View[14];
  161.  Result.y:= -View[4] * View[12] - View[5] * View[13] - View[6] * View[14];
  162.  Result.z:= -View[8] * View[12] - View[9] * View[13] - View[10] * View[14];
  163. end;
  164. //---------------------------------------------------------------------------
  165. class operator TMatrix4.Add(const a, b: TMatrix4): TMatrix4;
  166. var
  167.  i, j: Integer;
  168. begin
  169.  for j:= 0 to 3 do
  170.   for i:= 0 to 3 do
  171.    Result.Data[j, i]:= a.Data[j, i] + b.Data[j, i];
  172. end;
  173. //---------------------------------------------------------------------------
  174. class operator TMatrix4.Subtract(const a, b: TMatrix4): TMatrix4;
  175. var
  176.  i, j: Integer;
  177. begin
  178.  for j:= 0 to 3 do
  179.   for i:= 0 to 3 do
  180.    Result.Data[j, i]:= a.Data[j, i] - b.Data[j, i];
  181. end;
  182. //---------------------------------------------------------------------------
  183. class operator TMatrix4.Multiply(const a, b: TMatrix4): TMatrix4;
  184. {$ifndef SupportD3DX}
  185. var
  186.  i, j: Integer;
  187. {$endif}
  188. begin
  189.  {$ifdef SupportD3DX}
  190.  D3DXMatrixMultiply(TD3DXMatrix(Result), TD3DXMatrix(a), TD3DXMatrix(b));
  191.  {$else}
  192.  for j:= 0 to 3 do
  193.   for i:= 0 to 3 do
  194.    Result.Data[j, i]:= (a.Data[j, 0] * b.Data[0, i]) +
  195.     (a.Data[j, 1] * b.Data[1, i]) +
  196.     (a.Data[j, 2] * b.Data[2, i]) +
  197.     (a.Data[j, 3] * b.Data[3, i]);
  198.  {$endif}   
  199. end;
  200. //---------------------------------------------------------------------------
  201. class operator TMatrix4.Multiply(const Mtx: TMatrix4; Theta: Single): TMatrix4;
  202. var
  203.  i, j: Integer;
  204. begin
  205.  for j:= 0 to 3 do
  206.   for i:= 0 to 3 do
  207.    Result.Data[j, i]:= Mtx.Data[j, i] * Theta;
  208. end;
  209. //---------------------------------------------------------------------------
  210. class operator TMatrix4.Divide(const Mtx: TMatrix4; Theta: Single): TMatrix4;
  211. var
  212.  i, j: Integer;
  213. begin
  214.  for j:= 0 to 3 do
  215.   for i:= 0 to 3 do
  216.    Result.Data[j, i]:= Mtx.Data[j, i] / Theta;
  217. end;
  218. //---------------------------------------------------------------------------
  219. class operator TMatrix4.Multiply(const v: TVector3;
  220.  const m: TMatrix4): TVector3;
  221. begin
  222.  Result.x:= (v.x * m.Data[0, 0]) + (v.y * m.Data[1, 0]) +
  223.   (v.z * m.Data[2, 0]) + (1.0 * m.Data[3, 0]);
  224.  Result.y:= (v.x * m.Data[0, 1]) + (v.y * m.Data[1, 1]) +
  225.   (v.z * m.Data[2, 1]) + (1.0 * m.Data[3, 1]);
  226.  Result.z:= (v.x * m.Data[0, 2]) + (v.y * m.Data[1, 2]) +
  227.  (v.z * m.Data[2, 2]) + (1.0 * m.Data[3, 2]);
  228. end;
  229. //---------------------------------------------------------------------------
  230. function StringMtx4(const m: TMatrix4): string;
  231. var
  232.  s: string;
  233.  i, j: Integer;
  234. begin
  235.  s:= '{';
  236.  for i:= 0 to 3 do
  237.   begin
  238.    s:= s + '(';
  239.    for j:= 0 to 3 do
  240.     begin
  241.      s:= s + Format('%1.2f', [m.Data[i, j]]);
  242.      if (j < 3) then s:= s + ', ';
  243.     end;
  244.    s:= s + ')';
  245.    if (i < 3) then s:= s + #13#10;
  246.   end;
  247.  Result:= s + '}';
  248. end;
  249. //--------------------------------------------------------------------------
  250. function TransposeMtx4(const Mtx: TMatrix4): TMatrix4;
  251. var
  252.  i, j: Integer;
  253. begin
  254.  for i:= 0 to 3 do
  255.   for j:= 0 to 3 do
  256.    Result.Data[i, j]:= Mtx.Data[j, i];
  257. end;
  258. //---------------------------------------------------------------------------
  259. function TranslateMtx4(const Offset: TVector3): TMatrix4;
  260. begin
  261.  Result:= IdentityMtx4;
  262.  Result.Data[3, 0]:= Offset.x;
  263.  Result.Data[3, 1]:= Offset.y;
  264.  Result.Data[3, 2]:= Offset.z;
  265. end;
  266. //--------------------------------------------------------------------------
  267. function ScaleMtx4(const Coef: TVector3): TMatrix4;
  268. begin
  269.  Result:= IdentityMtx4;
  270.  Result.Data[0, 0]:= Coef.x;
  271.  Result.Data[1, 1]:= Coef.y;
  272.  Result.Data[2, 2]:= Coef.z;
  273. end;
  274. //---------------------------------------------------------------------------
  275. function DetMtx3(a1, a2, a3, b1, b2, b3, c1, c2, c3: Single): Single;
  276. begin
  277.  Result:= a1 * (b2 * c3 - b3 * c2) - b1 * (a2 * c3 - a3 * c2) +
  278.   c1 * (a2 * b3 - a3 * b2);
  279. end;
  280. //---------------------------------------------------------------------------
  281. function AdjointMtx4(const m: TMatrix4): TMatrix4;
  282. begin
  283.  Result.Data[0, 0]:=  DetMtx3(m.Data[1, 1], m.Data[2, 1], m.Data[3, 1],
  284.   m.Data[1, 2], m.Data[2, 2], m.Data[3, 2], m.Data[1, 3], m.Data[2, 3],
  285.   m.Data[3, 3]);
  286.  Result.Data[1, 0]:= -DetMtx3(m.Data[1, 0], m.Data[2, 0], m.Data[3, 0],
  287.   m.Data[1, 2], m.Data[2, 2], m.Data[3, 2], m.Data[1, 3], m.Data[2, 3],
  288.   m.Data[3, 3]);
  289.  Result.Data[2, 0]:=  DetMtx3(m.Data[1, 0], m.Data[2, 0], m.Data[3, 0],
  290.   m.Data[1, 1], m.Data[2, 1], m.Data[3, 1], m.Data[1, 3], m.Data[2, 3],
  291.   m.Data[3, 3]);
  292.  Result.Data[3, 0]:= -DetMtx3(m.Data[1, 0], m.Data[2, 0], m.Data[3, 0],
  293.   m.Data[1, 1], m.Data[2, 1], m.Data[3, 1], m.Data[1, 2], m.Data[2, 2],
  294.   m.Data[3, 2]);
  295.  Result.Data[0, 1]:= -DetMtx3(m.Data[0, 1], m.Data[2, 1], m.Data[3, 1],
  296.   m.Data[0, 2], m.Data[2, 2], m.Data[3, 2], m.Data[0, 3], m.Data[2, 3],
  297.   m.Data[3, 3]);
  298.  Result.Data[1, 1]:=  DetMtx3(m.Data[0, 0], m.Data[2, 0], m.Data[3, 0],
  299.   m.Data[0, 2], m.Data[2, 2], m.Data[3, 2], m.Data[0, 3], m.Data[2, 3],
  300.   m.Data[3, 3]);
  301.  Result.Data[2, 1]:= -DetMtx3(m.Data[0, 0], m.Data[2, 0], m.Data[3, 0],
  302.   m.Data[0, 1], m.Data[2, 1], m.Data[3, 1], m.Data[0, 3], m.Data[2, 3],
  303.   m.Data[3, 3]);
  304.  Result.Data[3, 1]:=  DetMtx3(m.Data[0, 0], m.Data[2, 0], m.Data[3, 0],
  305.   m.Data[0, 1], m.Data[2, 1], m.Data[3, 1], m.Data[0, 2], m.Data[2, 2],
  306.   m.Data[3, 2]);
  307.  Result.Data[0, 2]:=  DetMtx3(m.Data[0, 1], m.Data[1, 1], m.Data[3, 1],
  308.   m.Data[0, 2], m.Data[1, 2], m.Data[3, 2], m.Data[0, 3], m.Data[1, 3],
  309.   m.Data[3, 3]);
  310.  Result.Data[1, 2]:= -DetMtx3(m.Data[0, 0], m.Data[1, 0], m.Data[3, 0],
  311.   m.Data[0, 2], m.Data[1, 2], m.Data[3, 2], m.Data[0, 3], m.Data[1, 3],
  312.   m.Data[3, 3]);
  313.  Result.Data[2, 2]:=  DetMtx3(m.Data[0, 0], m.Data[1, 0], m.Data[3, 0],
  314.   m.Data[0, 1], m.Data[1, 1], m.Data[3, 1], m.Data[0, 3], m.Data[1, 3],
  315.   m.Data[3, 3]);
  316.  Result.Data[3, 2]:= -DetMtx3(m.Data[0, 0], m.Data[1, 0], m.Data[3, 0],
  317.   m.Data[0, 1], m.Data[1, 1], m.Data[3, 1], m.Data[0, 2], m.Data[1, 2],
  318.   m.Data[3, 2]);
  319.  Result.Data[0, 3]:= -DetMtx3(m.Data[0, 1], m.Data[1, 1], m.Data[2, 1],
  320.   m.Data[0, 2], m.Data[1, 2], m.Data[2, 2], m.Data[0, 3], m.Data[1, 3],
  321.   m.Data[2, 3]);
  322.  Result.Data[1, 3]:=  DetMtx3(m.Data[0, 0], m.Data[1, 0], m.Data[2, 0],
  323.   m.Data[0, 2], m.Data[1, 2], m.Data[2, 2], m.Data[0, 3], m.Data[1, 3],
  324.   m.Data[2, 3]);
  325.  Result.Data[2, 3]:= -DetMtx3(m.Data[0, 0], m.Data[1, 0], m.Data[2, 0],
  326.   m.Data[0, 1], m.Data[1, 1], m.Data[2, 1], m.Data[0, 3], m.Data[1, 3],
  327.   m.Data[2, 3]);
  328.  Result.Data[3, 3]:=  DetMtx3(m.Data[0, 0], m.Data[1, 0], m.Data[2, 0],
  329.   m.Data[0, 1], m.Data[1, 1], m.Data[2, 1], m.Data[0, 2], m.Data[1, 2],
  330.   m.Data[2, 2]);
  331. end;
  332. //---------------------------------------------------------------------------
  333. function DetMtx4(const m: TMatrix4): Single;
  334. begin
  335.  {$ifdef SupportD3DX}
  336.  Result:= D3DXMatrixDeterminant(TD3DXMatrix(m));
  337.  {$else}
  338.  Result:= m.Data[0, 0] * DetMtx3(m.Data[1, 1], m.Data[2, 1], m.Data[3, 1],
  339.   m.Data[1, 2], m.Data[2, 2], m.Data[3, 2], m.Data[1, 3], m.Data[2, 3],
  340.   m.Data[3, 3]) - m.Data[0, 1] * DetMtx3(m.Data[1, 0], m.Data[2, 0],
  341.   m.Data[3, 0], m.Data[1, 2], m.Data[2, 2], m.Data[3, 2], m.Data[1, 3],
  342.   m.Data[2, 3], m.Data[3, 3]) + m.Data[0, 2] * DetMtx3(m.Data[1, 0],
  343.   m.Data[2, 0], m.Data[3, 0], m.Data[1, 1], m.Data[2, 1], m.Data[3, 1],
  344.   m.Data[1, 3], m.Data[2, 3], m.Data[3, 3]) - m.Data[0, 3] *
  345.   DetMtx3(m.Data[1, 0], m.Data[2, 0], m.Data[3, 0], m.Data[1, 1],
  346.   m.Data[2, 1], m.Data[3, 1], m.Data[1, 2], m.Data[2, 2], m.Data[3, 2]);
  347.  {$endif}
  348. end;
  349. //---------------------------------------------------------------------------
  350. function InvertMtx4(const m: TMatrix4): TMatrix4;
  351. {$ifndef SupportD3DX}
  352. var
  353.  Det: Single;
  354. {$endif}
  355. begin
  356.  {$ifdef SupportD3DX}
  357.  D3DXMatrixInverse(TD3DXMatrix(Result), nil, TD3DXMatrix(m));
  358.  {$else}
  359.  Det:= DetMtx4(m);
  360.  if (Det <> 0.0) then
  361.   begin
  362.    Result:= AdjointMtx4(m) / Det;
  363.   end else Result:= IdentityMtx4
  364.  {$endif} 
  365. end;
  366. //--------------------------------------------------------------------------
  367. function RotateXMtx4(Angle: Single): TMatrix4;
  368. begin
  369.  {$ifdef SupportD3DX}
  370.  D3DXMatrixRotationX(TD3DXMatrix(Result), Angle);
  371.  {$else}
  372.  Result:= IdentityMtx4;
  373.  Result.Data[1, 1]:=  Cos(Angle);
  374.  Result.Data[1, 2]:=  Sin(Angle);
  375.  Result.Data[2, 1]:= -Result.Data[1, 2];
  376.  Result.Data[2, 2]:=  Result.Data[1, 1];
  377.  {$endif}
  378. end;
  379. //--------------------------------------------------------------------------
  380. function RotateYMtx4(Angle: Single): TMatrix4;
  381. begin
  382.  {$ifdef SupportD3DX}
  383.  D3DXMatrixRotationY(TD3DXMatrix(Result), Angle);
  384.  {$else}
  385.  Result:= IdentityMtx4;
  386.  Result.Data[0, 0]:=  Cos(Angle);
  387.  Result.Data[0, 2]:= -Sin(Angle);
  388.  Result.Data[2, 0]:= -Result.Data[0, 2];
  389.  Result.Data[2, 2]:=  Result.Data[0, 0];
  390.  {$endif}
  391. end;
  392. //--------------------------------------------------------------------------
  393. function RotateZMtx4(Angle: Single): TMatrix4;
  394. begin
  395.  {$ifdef SupportD3DX}
  396.  D3DXMatrixRotationZ(TD3DXMatrix(Result), Angle);
  397.  {$else}
  398.  Result:= IdentityMtx4;
  399.  Result.Data[0, 0]:=  Cos(Angle);
  400.  Result.Data[0, 1]:=  Sin(Angle);
  401.  Result.Data[1, 0]:= -Result.Data[0, 1];
  402.  Result.Data[1, 1]:=  Result.Data[0, 0];
  403.  {$endif}
  404. end;
  405. //--------------------------------------------------------------------------
  406. function RotateMtx4(const Axis: TVector3; Angle: Single): TMatrix4;
  407. {$ifndef SupportD3DX}
  408. var
  409.  CosTh, iCosTh, SinTh: Single;
  410.  xy, xz, yz, xSin, ySin, zSin: Single;
  411. {$endif}
  412. begin
  413.  {$ifdef SupportD3DX}
  414.  D3DXMatrixRotationAxis(TD3DXMatrix(Result), TD3DXVector3(Axis), Angle);
  415.  {$else}
  416.  CosTh := Cos(Angle);
  417.  iCosTh:= 1.0 - CosTh;
  418.  SinTh := Sin(Angle);
  419.  xy    := Axis.x * Axis.y * iCosTh;
  420.  xz    := Axis.x * Axis.z * iCosTh;
  421.  yz    := Axis.y * Axis.z * iCosTh;
  422.  xSin  := Axis.x * SinTh;
  423.  ySin  := Axis.y * SinTh;
  424.  zSin  := Axis.z * SinTh;
  425.  Result:= IdentityMtx4;
  426.  Result.Data[0, 0]:= (Sqr(Axis.x) * iCosTh) + CosTh;
  427.  Result.Data[0, 1]:= xy + zSin;
  428.  Result.Data[0, 2]:= xz - ySin;
  429.  Result.Data[1, 0]:= xy - zSin;
  430.  Result.Data[1, 1]:= (Sqr(Axis.y) * iCosTh) + CosTh;
  431.  Result.Data[1, 2]:= yz + xSin;
  432.  Result.Data[2, 0]:= xz + ySin;
  433.  Result.Data[2, 1]:= yz - xSin;
  434.  Result.Data[2, 2]:= (Sqr(Axis.z) * iCosTh) + CosTh;
  435.  {$endif}
  436. end;
  437. //---------------------------------------------------------------------------
  438. function ReflectMtx4(const Axis: TVector3): TMatrix4;
  439. var
  440.  xy, yz, xz: Single;
  441. begin
  442.  xy:= -2.0 * Axis.x * Axis.y;
  443.  xz:= -2.0 * Axis.x * Axis.z;
  444.  yz:= -2.0 * Axis.y * Axis.z;
  445.  Result:= IdentityMtx4;
  446.  Result.Data[0, 0]:= 1.0 - (2.0 * Sqr(Axis.x));
  447.  Result.Data[0, 1]:= xy;
  448.  Result.Data[0, 2]:= xz;
  449.  Result.Data[1, 0]:= xy;
  450.  Result.Data[1, 1]:= 1.0 - (2.0 * Sqr(Axis.y));
  451.  Result.Data[1, 2]:= yz;
  452.  Result.Data[2, 0]:= xz;
  453.  Result.Data[2, 1]:= yz;
  454.  Result.Data[2, 2]:= 1.0 - (2.0 * Sqr(Axis.z));
  455. end;
  456. //---------------------------------------------------------------------------
  457. function LookAtMtx4(const Origin, Target, Roof: TVector3): TMatrix4;
  458. {$ifndef SupportD3DX}
  459. var
  460.  xAxis, yAxis, zAxis: TVector3;
  461. {$endif}
  462. begin
  463.  {$ifdef SupportD3DX}
  464.  D3DXMatrixLookAtLH(TD3DXMatrix(Result), TD3DXVector3(Origin),
  465.   TD3DXVector3(Target), TD3DXVector3(Roof));
  466.  {$else}
  467.  zAxis:= Norm3(Target - Origin);
  468.  xAxis:= Norm3(Cross3(Roof, zAxis));
  469.  yAxis:= Cross3(zAxis, xAxis);
  470.  Result.Data[0, 0]:= xAxis.x;
  471.  Result.Data[0, 1]:= yAxis.x;
  472.  Result.Data[0, 2]:= zAxis.x;
  473.  Result.Data[0, 3]:= 0.0;
  474.  Result.Data[1, 0]:= xAxis.y;
  475.  Result.Data[1, 1]:= yAxis.y;
  476.  Result.Data[1, 2]:= zAxis.y;
  477.  Result.Data[1, 3]:= 0.0;
  478.  Result.Data[2, 0]:= xAxis.z;
  479.  Result.Data[2, 1]:= yAxis.z;
  480.  Result.Data[2, 2]:= zAxis.z;
  481.  Result.Data[2, 3]:= 0.0;
  482.  Result.Data[3, 0]:= -Dot3(xAxis, Origin);
  483.  Result.Data[3, 1]:= -Dot3(yAxis, Origin);
  484.  Result.Data[3, 2]:= -Dot3(zAxis, Origin);
  485.  Result.Data[3, 3]:= 1.0;
  486.  {$endif}
  487. end;
  488. //---------------------------------------------------------------------------
  489. function PerspectiveFOVYMtx4(FieldOfView, AspectRatio, MinRange,
  490.  MaxRange: Single): TMatrix4;
  491. var
  492.  xScale, yScale, zCoef: Single;
  493. begin
  494.  yScale:= Cot(FieldOfView * 0.5);
  495.  xScale:= yScale / AspectRatio;
  496.  zCoef := MaxRange / (MaxRange - MinRange);
  497.  Result:= ZeroMtx4;
  498.  Result.Data[0, 0]:= xScale;
  499.  Result.Data[1, 1]:= yScale;
  500.  Result.Data[2, 2]:= zCoef;
  501.  Result.Data[2, 3]:= 1.0;
  502.  Result.Data[3, 2]:= -MinRange * zCoef;
  503. end;
  504. //---------------------------------------------------------------------------
  505. function PerspectiveFOVXMtx4(FieldOfView, AspectRatio, MinRange,
  506.  MaxRange: Single): TMatrix4;
  507. var
  508.  xScale, yScale, zCoef: Single;
  509. begin
  510.  xScale:= Cot(FieldOfView * 0.5);
  511.  yScale:= xScale / AspectRatio;
  512.  zCoef := MaxRange / (MaxRange - MinRange);
  513.  Result:= ZeroMtx4;
  514.  Result.Data[0, 0]:= xScale;
  515.  Result.Data[1, 1]:= yScale;
  516.  Result.Data[2, 2]:= zCoef;
  517.  Result.Data[2, 3]:= 1.0;
  518.  Result.Data[3, 2]:= -MinRange * zCoef;
  519. end;
  520. //---------------------------------------------------------------------------
  521. function PerspectiveVOLMtx4(Width, Height, MinRange, MaxRange: Single): TMatrix4;
  522. begin
  523.  Result:= ZeroMtx4;
  524.  Result.Data[0, 0]:= (2.0 * MinRange) / Width;
  525.  Result.Data[1, 1]:= (2.0 * MinRange) / Height;
  526.  Result.Data[2, 2]:= MaxRange / (MaxRange - MinRange);
  527.  Result.Data[2, 3]:= 1.0;
  528.  Result.Data[3, 2]:= MinRange * MaxRange / (MinRange - MaxRange);
  529. end;
  530. //---------------------------------------------------------------------------
  531. function PerspectiveBDSMtx4(Left, Right, Top, Bottom, MinRange,
  532.  MaxRange: Single): TMatrix4;
  533. begin
  534.  Result:= ZeroMtx4;
  535.  Result.Data[0, 0]:= (2.0 * MinRange) / (Right - Left);
  536.  Result.Data[1, 1]:= (2.0 * MinRange) / (Top - Bottom);
  537.  Result.Data[2, 0]:= (Left + Right) / (Left - Right);
  538.  Result.Data[2, 1]:= (Top + Bottom) / (Bottom - Top);
  539.  Result.Data[2, 2]:= MaxRange / (MaxRange - MinRange);
  540.  Result.Data[2, 3]:= 1.0;
  541.  Result.Data[3, 2]:= MinRange * MaxRange / (MinRange - MaxRange);
  542. end;
  543. //---------------------------------------------------------------------------
  544. function OrthogonalVOLMtx4(Width, Height, MinRange, MaxRange: Single): TMatrix4;
  545. begin
  546.  Result:= ZeroMtx4;
  547.  Result.Data[0, 0]:= 2.0 / Width;
  548.  Result.Data[1, 1]:= 2.0 / Height;
  549.  Result.Data[2, 2]:= 1.0 / (MaxRange - MinRange);
  550.  Result.Data[2, 3]:= MinRange / (MinRange - MaxRange);
  551.  Result.Data[3, 3]:= 1.0;
  552. end;
  553. //---------------------------------------------------------------------------
  554. function OrthogonalBDSMtx4(Left, Right, Top, Bottom, MinRange,
  555.  MaxRange: Single): TMatrix4;
  556. begin
  557.  Result:= ZeroMtx4;
  558.  Result.Data[0, 0]:= 2.0 / (Right - Left);
  559.  Result.Data[1, 1]:= 2.0 / (Top - Bottom);
  560.  Result.Data[2, 2]:= 1.0 / (MaxRange - MinRange);
  561.  Result.Data[2, 3]:= MinRange / (MinRange - MaxRange);
  562.  Result.Data[3, 0]:= (Left + Right) / (Left - Right);
  563.  Result.Data[3, 1]:= (Top + Bottom) / (Bottom - Top);
  564.  Result.Data[3, 2]:= MinRange / (MinRange - MaxRange);
  565.  Result.Data[3, 3]:= 1.0;
  566. end;
  567. //--------------------------------------------------------------------------
  568. function HeadingPitchBankMtx4(Heading, Pitch, Bank: Single): TMatrix4;
  569. var
  570.  CosH, SinH: Single;
  571.  CosP, SinP: Single;
  572.  CosB, SinB: Single;
  573. begin
  574.  Result:= IdentityMtx4;
  575.  CosH:= Cos(Heading);
  576.  SinH:= Sin(Heading);
  577.  CosP:= Cos(Pitch);
  578.  SinP:= Sin(Pitch);
  579.  CosB:= Cos(Bank);
  580.  SinB:= Sin(Bank);
  581.  Result.Data[0, 0]:= (CosH * CosB) + (SinH * SinP * SinB);
  582.  Result.Data[0, 1]:= (-CosH * SinB) + (SinH * SinP * CosB);
  583.  Result.Data[0, 2]:= SinH * CosP;
  584.  Result.Data[1, 0]:= SinB * CosP;
  585.  Result.Data[1, 1]:= CosB * CosP;
  586.  Result.Data[1, 2]:= -SinP;
  587.  Result.Data[2, 0]:= (-SinH * CosB) + (CosH * SinP * SinB);
  588.  Result.Data[2, 1]:= (SinB * SinH) + (CosH * SinP * CosB);
  589.  Result.Data[2, 2]:= CosH * CosP;
  590. end;
  591. //---------------------------------------------------------------------------
  592. function HeadingPitchBankMtx4(const v: TVector3): TMatrix4; overload;
  593. begin
  594.  Result:= HeadingPitchBankMtx4(v.y, v.x, v.z);
  595. end;
  596. //---------------------------------------------------------------------------
  597. {$ifdef SupportD3DX}
  598. function YawPitchRollMtx4(Yaw, Pitch, Roll: Single): TMatrix4; overload;
  599. begin
  600.  D3DXMatrixRotationYawPitchRoll(TD3DXMatrix(Result), Yaw, Pitch, Roll);
  601. end;
  602. //---------------------------------------------------------------------------
  603. function YawPitchRollMtx4(const v: TVector3): TMatrix4; overload;
  604. begin
  605.  D3DXMatrixRotationYawPitchRoll(TD3DXMatrix(Result), v.y, v.x, v.z);
  606. end;
  607. {$endif}
  608. //---------------------------------------------------------------------------
  609. end.