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

2D图形编程

开发平台:

Delphi

  1. unit AsphyreMatrices;
  2. //---------------------------------------------------------------------------
  3. // AsphyreMatrices.pas                                  Modified: 02-Apr-2007
  4. // High-level implementation of 4x4 matrix w/32-byte alignment    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 AsphyreMatrices.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} Vectors3, Matrices4;
  46. //---------------------------------------------------------------------------
  47. type
  48.  TAsphyreMatrix = class
  49.  private
  50.   MemAddr: Pointer;
  51.   FRawMtx: PMatrix4;
  52.   function GetPosition(): TVector3;
  53.  public
  54.   property RawMtx: PMatrix4 read FRawMtx;
  55.   property Position: TVector3 read GetPosition;
  56.   procedure LoadMtx(Source: PMatrix4);
  57.   procedure LoadIdentity();
  58.   procedure LoadZero();
  59.   procedure Translate(dx, dy, dz: Single); overload;
  60.   procedure Translate(const v: TVector3); overload;
  61.   procedure Scale(const v: TVector3); overload;
  62.   procedure Scale(dx, dy, dz: Single); overload;
  63.   procedure Scale(Delta: Single); overload;
  64.   procedure RotateX(Phi: Single);
  65.   procedure RotateY(Phi: Single);
  66.   procedure RotateZ(Phi: Single);
  67.   procedure RotateXLocal(Phi: Single);
  68.   procedure RotateYLocal(Phi: Single);
  69.   procedure RotateZLocal(Phi: Single);
  70.   procedure Multiply(SrcMtx: PMatrix4); overload;
  71.   procedure Multiply(const SrcMtx: TMatrix4); overload;
  72.   procedure Multiply(Source: TAsphyreMatrix); overload;
  73.   procedure LoadRotation(SrcMtx: PMatrix4);
  74.   procedure LookAt(const Origin, Target, Roof: TVector3);
  75.   procedure PerspectiveFovY(FieldOfView, AspectRatio, MinRange, MaxRange: Single);
  76.   procedure PerspectiveFovX(FieldOfView, AspectRatio, MinRange, MaxRange: Single);
  77.   procedure PerspectiveVOL(Width, Height, MinRange, MaxRange: Single);
  78.   procedure PerspectiveBDS(Left, Right, Top, Bottom, MinRange, MaxRange: Single);
  79.   procedure OrthogonalVOL(Width, Height, MinRange, MaxRange: Single);
  80.   procedure OrthogonalBDS(Left, Right, Top, Bottom, MinRange, MaxRange: Single);
  81.   procedure HeadingPitchBank(const v: TVector3); overload;
  82.   procedure HeadingPitchBank(Heading, Pitch, Bank: Single); overload;
  83.   {$ifdef SupportD3DX}
  84.   procedure YawPitchRoll(Yaw, Pitch, Roll: Single); overload;
  85.   procedure YawPitchRoll(const v: TVector3); overload;
  86.   {$endif}
  87.   constructor Create();
  88.   destructor Destroy(); override;
  89.  end;
  90. //---------------------------------------------------------------------------
  91. implementation
  92. //---------------------------------------------------------------------------
  93. const
  94.  Grad2Rad = Pi / 180.0;
  95. //---------------------------------------------------------------------------
  96. constructor TAsphyreMatrix.Create();
  97. begin
  98.  inherited;
  99.  MemAddr:= AllocMem(SizeOf(TMatrix4) + 16);
  100.  FRawMtx:= Pointer(Integer(MemAddr) + ($10 - (Integer(MemAddr) and $0F)));
  101.  LoadIdentity();
  102. end;
  103. //---------------------------------------------------------------------------
  104. destructor TAsphyreMatrix.Destroy();
  105. begin
  106.  FreeMem(MemAddr);
  107.  inherited;
  108. end;
  109. //---------------------------------------------------------------------------
  110. function TAsphyreMatrix.GetPosition(): TVector3;
  111. begin
  112.  Result.x:= FRawMtx.Data[3, 0];
  113.  Result.y:= FRawMtx.Data[3, 1];
  114.  Result.z:= FRawMtx.Data[3, 2];
  115. end;
  116. //---------------------------------------------------------------------------
  117. procedure TAsphyreMatrix.LoadIdentity();
  118. begin
  119.  Move(IdentityMtx4, FRawMtx^, SizeOf(TMatrix4));
  120. end;
  121. //---------------------------------------------------------------------------
  122. procedure TAsphyreMatrix.LoadZero();
  123. begin
  124.  FillChar(FRawMtx^, SizeOf(TMatrix4), 0);
  125. end;
  126. //---------------------------------------------------------------------------
  127. procedure TAsphyreMatrix.LoadMtx(Source: PMatrix4);
  128. begin
  129.  Move(Source^, FRawMtx^, SizeOf(TMatrix4));
  130. end;
  131. //---------------------------------------------------------------------------
  132. procedure TAsphyreMatrix.Translate(dx, dy, dz: Single);
  133. begin
  134.  FRawMtx^:= FRawMtx^ * TranslateMtx4(Vector3(dx, dy, dz));
  135. end;
  136. //---------------------------------------------------------------------------
  137. procedure TAsphyreMatrix.Translate(const v: TVector3);
  138. begin
  139.  FRawMtx^:= FRawMtx^ * TranslateMtx4(v);
  140. end;
  141. //---------------------------------------------------------------------------
  142. procedure TAsphyreMatrix.RotateX(Phi: Single);
  143. begin
  144.  FRawMtx^:= FRawMtx^ * RotateXMtx4(Phi);
  145. end;
  146. //---------------------------------------------------------------------------
  147. procedure TAsphyreMatrix.RotateY(Phi: Single);
  148. begin
  149.  FRawMtx^:= FRawMtx^ * RotateYMtx4(Phi);
  150. end;
  151. //---------------------------------------------------------------------------
  152. procedure TAsphyreMatrix.RotateZ(Phi: Single);
  153. begin
  154.  FRawMtx^:= FRawMtx^ * RotateZMtx4(Phi);
  155. end;
  156. //---------------------------------------------------------------------------
  157. procedure TAsphyreMatrix.Scale(const v: TVector3);
  158. begin
  159.  FRawMtx^:= FRawMtx^ * ScaleMtx4(v);
  160. end;
  161. //---------------------------------------------------------------------------
  162. procedure TAsphyreMatrix.Scale(dx, dy, dz: Single);
  163. begin
  164.  FRawMtx^:= FRawMtx^ * ScaleMtx4(Vector3(dx, dy, dz));
  165. end;
  166. //---------------------------------------------------------------------------
  167. procedure TAsphyreMatrix.Scale(Delta: Single);
  168. begin
  169.  FRawMtx^:= FRawMtx^ * ScaleMtx4(Vector3(Delta, Delta, Delta));
  170. end;
  171. //---------------------------------------------------------------------------
  172. procedure TAsphyreMatrix.RotateXLocal(Phi: Single);
  173. var
  174.  Axis: TVector3;
  175. begin
  176.  Axis.x:= FRawMtx.Data[0, 0];
  177.  Axis.y:= FRawMtx.Data[0, 1];
  178.  Axis.z:= FRawMtx.Data[0, 2];
  179.  FRawMtx^:= FRawMtx^ * RotateMtx4(Axis, Phi);
  180. end;
  181. //---------------------------------------------------------------------------
  182. procedure TAsphyreMatrix.RotateYLocal(Phi: Single);
  183. var
  184.  Axis: TVector3;
  185. begin
  186.  Axis.x:= FRawMtx.Data[1, 0];
  187.  Axis.y:= FRawMtx.Data[1, 1];
  188.  Axis.z:= FRawMtx.Data[1, 2];
  189.  FRawMtx^:= FRawMtx^ * RotateMtx4(Axis, Phi);
  190. end;
  191. //---------------------------------------------------------------------------
  192. procedure TAsphyreMatrix.RotateZLocal(Phi: Single);
  193. var
  194.  Axis: TVector3;
  195. begin
  196.  Axis.x:= FRawMtx.Data[2, 0];
  197.  Axis.y:= FRawMtx.Data[2, 1];
  198.  Axis.z:= FRawMtx.Data[2, 2];
  199.  FRawMtx^:= FRawMtx^ * RotateMtx4(Axis, Phi);
  200. end;
  201. //--------------------------------------------------------------------------
  202. procedure TAsphyreMatrix.Multiply(SrcMtx: PMatrix4);
  203. begin
  204.  {$ifdef SupportD3DX}
  205.  D3DXMatrixMultiply(PD3DXMatrix(FRawMtx)^, PD3DXMatrix(FRawMtx)^,
  206.   PD3DXMatrix(SrcMtx)^);
  207.  {$else}
  208.  FRawMtx^:= FRawMtx^ * SrcMtx^;
  209.  {$endif}
  210. end;
  211. //---------------------------------------------------------------------------
  212. procedure TAsphyreMatrix.Multiply(const SrcMtx: TMatrix4);
  213. begin
  214.  Multiply(@SrcMtx);
  215. end;
  216. //---------------------------------------------------------------------------
  217. procedure TAsphyreMatrix.Multiply(Source: TAsphyreMatrix);
  218. begin
  219.  Multiply(Source.RawMtx);
  220. end;
  221. //--------------------------------------------------------------------------
  222. procedure TAsphyreMatrix.LookAt(const Origin, Target, Roof: TVector3);
  223. var
  224.  Aux: TMatrix4;
  225. begin
  226.  Aux:= LookAtMtx4(Origin, Target, Roof);
  227.  Multiply(@Aux);
  228. end;
  229. //--------------------------------------------------------------------------
  230. procedure TAsphyreMatrix.PerspectiveFovY(FieldOfView, AspectRatio, MinRange,
  231.  MaxRange: Single);
  232. begin
  233.  FRawMtx^:= PerspectiveFOVYMtx4(FieldOfView, AspectRatio, MinRange, MaxRange);
  234. end;
  235. //--------------------------------------------------------------------------
  236. procedure TAsphyreMatrix.PerspectiveFovX(FieldOfView, AspectRatio, MinRange,
  237.  MaxRange: Single);
  238. begin
  239.  FRawMtx^:= PerspectiveFOVXMtx4(FieldOfView, AspectRatio, MinRange, MaxRange);
  240. end;
  241. //--------------------------------------------------------------------------
  242. procedure TAsphyreMatrix.PerspectiveVOL(Width, Height, MinRange,
  243.  MaxRange: Single);
  244. begin
  245.  FRawMtx^:= PerspectiveVOLMtx4(Width, Height, MinRange, MaxRange);
  246. end;
  247. //--------------------------------------------------------------------------
  248. procedure TAsphyreMatrix.PerspectiveBDS(Left, Right, Top, Bottom, MinRange,
  249.  MaxRange: Single);
  250. begin
  251.  FRawMtx^:= PerspectiveBDSMtx4(Left, Right, Top, Bottom, MinRange, MaxRange);
  252. end;
  253. //--------------------------------------------------------------------------
  254. procedure TAsphyreMatrix.OrthogonalVOL(Width, Height, MinRange,
  255.  MaxRange: Single);
  256. begin
  257.  FRawMtx^:= OrthogonalVOLMtx4(Width, Height, MinRange, MaxRange);
  258. end;
  259. //--------------------------------------------------------------------------
  260. procedure TAsphyreMatrix.OrthogonalBDS(Left, Right, Top, Bottom, MinRange,
  261.  MaxRange: Single);
  262. begin
  263.  FRawMtx^:= OrthogonalBDSMtx4(Left, Right, Top, Bottom, MinRange, MaxRange);
  264. end;
  265. //---------------------------------------------------------------------------
  266. procedure TAsphyreMatrix.LoadRotation(SrcMtx: PMatrix4);
  267. var
  268.  i: Integer;
  269. begin
  270.  Move(SrcMtx^, FRawMtx^, SizeOf(TMatrix4));
  271.  for i:= 0 to 3 do
  272.   begin
  273.    FRawMtx.Data[3, i]:= 0.0;
  274.    FRawMtx.Data[i, 3]:= 0.0;
  275.   end;
  276.  FRawMtx.Data[3, 3]:= 1.0;
  277. end;
  278. //---------------------------------------------------------------------------
  279. procedure TAsphyreMatrix.HeadingPitchBank(Heading, Pitch, Bank: Single);
  280. var
  281.  Aux: TMatrix4;
  282. begin
  283.  Aux:= HeadingPitchBankMtx4(Heading, Pitch, Bank);
  284.  Multiply(@Aux);
  285. end;
  286. //---------------------------------------------------------------------------
  287. procedure TAsphyreMatrix.HeadingPitchBank(const v: TVector3);
  288. var
  289.  Aux: TMatrix4;
  290. begin
  291.  Aux:= HeadingPitchBankMtx4(v);
  292.  Multiply(@Aux);
  293. end;
  294. //---------------------------------------------------------------------------
  295. {$ifdef SupportD3DX}
  296. procedure TAsphyreMatrix.YawPitchRoll(Yaw, Pitch, Roll: Single);
  297. var
  298.  Aux: TMatrix4;
  299. begin
  300.  D3DXMatrixRotationYawPitchRoll(TD3DXMatrix(Aux), Yaw, Pitch, Roll);
  301.  Multiply(@Aux);
  302. end;
  303. //---------------------------------------------------------------------------
  304. procedure TAsphyreMatrix.YawPitchRoll(const v: TVector3);
  305. begin
  306.  YawPitchRoll(v.y, v.x, v.z);
  307. end;
  308. {$endif}
  309. //---------------------------------------------------------------------------
  310. end.