⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d3dutils.pas

📁 传奇源代码的delphi版本
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit D3DUtils;

interface

uses
  Windows, Math,
{$IfDef StandardDX}
  DirectDraw, Direct3D;
{$Else}
  DirectX;
{$EndIf}


const
  g_PI       =  3.14159265358979323846; // Pi
  g_Uhel       =  g_PI / 180  ;
  g_2_PI     =  6.28318530717958623200; // 2 * Pi
  g_PI_DIV_2 =  1.57079632679489655800; // Pi / 2
  g_PI_DIV_4 =  0.78539816339744827900; // Pi / 4
  g_INV_PI   =  0.31830988618379069122; // 1 / Pi
  g_DEGTORAD =  0.01745329251994329547; // Degrees to Radians
  g_RADTODEG = 57.29577951308232286465; // Radians to Degrees
  g_HUGE     =  1.0e+38;                // Huge number for FLOAT
  g_EPSILON  =  1.0e-5;                 // Tolerance for FLOATs

function ProjectionMatrix( near_plane, far_plane,  fov_horiz,  fov_vert:real): TD3DMatrix ;  
function MakeD3DVector(x, y, z: TD3DValue): TD3DVector;
function MakeD3DVertex(hv, nv: TD3DVector; tu, tv: TD3DValue): TD3DVertex;

function D3DMath_IsZero(a: Double; fTol: Double{ = g_EPSILON}): Boolean;
procedure D3DMath_MatrixMultiply(var q: TD3DMatrix; const a, b: TD3DMatrix);
function D3DMath_MatrixInvert(var q: TD3DMatrix; const a: TD3DMatrix): HResult;
function D3DMath_VectorMatrixMultiply(var vDest: TD3DVector; const vSrc: TD3DVector;
  const mat: TD3DMatrix): HResult;
function D3DMath_VertexMatrixMultiply(var vDest: TD3DVertex; const vSrc: TD3DVertex;
  const mat: TD3DMatrix): HResult;
procedure D3DMath_QuaternionFromRotation(var x, y, z, w: Double;
  const v: TD3DVector; fTheta: Double);
procedure D3DMath_RotationFromQuaternion(var v: TD3DVector; var fTheta: Double;
  x, y, z, w: Double);
procedure D3DMath_QuaternionFromAngles(var x, y, z, w: Double; fYaw, fPitch, fRoll: Double);
procedure D3DMath_MatrixFromQuaternion(var mat: TD3DMatrix; x, y, z, w: Double);
procedure D3DMath_QuaternionFromMatrix(var x, y, z, w: Double; var mat: TD3DMatrix);
procedure D3DMath_QuaternionMultiply(var Qx, Qy, Qz, Qw: Double;
  Ax, Ay, Az, Aw, Bx, By, Bz, Bw: Double);
procedure D3DMath_QuaternionSlerp(var Qx, Qy, Qz, Qw: Double;
  Ax, Ay, Az, Aw, Bx, By, Bz, Bw, fAlpha: Double);

procedure D3DUtil_InitSurfaceDesc(var ddsd: TDDSurfaceDesc2; dwFlags, dwCaps: DWORD);
procedure D3DUtil_InitMaterial(var mtrl: TD3DMaterial7; r, g, b, a: Double);
procedure D3DUtil_InitLight(var light: TD3DLight7; ltType: TD3DLightType; x, y, z: Double);
procedure D3DUtil_SetIdentityMatrix(var m: TD3DMatrix);
function D3DUtil_SetViewMatrix(var mat: TD3DMatrix;  const vFrom, vAt, vWorldUp: TD3DVector): HResult;
function D3DUtil_SetProjectionMatrix(var mat: TD3DMatrix; fFOV, fAspect, fNearPlane, fFarPlane: Double): HResult;
procedure D3DUtil_SetRotateXMatrix(var mat: TD3DMatrix; fRads: Double);
procedure D3DUtil_SetRotateYMatrix(var mat: TD3DMatrix; fRads: Double);
procedure D3DUtil_SetRotateZMatrix(var mat: TD3DMatrix; fRads: Double);
procedure D3DUtil_SetRotationMatrix(var mat: TD3DMatrix; var vDir: TD3DVector; fRads: Double);

implementation

function MakeD3DVector(x, y, z: TD3DValue): TD3DVector;
begin
  Result.x := x;
  Result.y := y;
  Result.z := z;
end;

function MakeD3DVertex(hv, nv: TD3DVector; tu, tv: TD3DValue): TD3DVertex;
begin
  Result.x := hv.x;
  Result.y := hv.y;
  Result.z := hv.z;
  Result.nx := nv.x;
  Result.ny := nv.y;
  Result.nz := nv.z;
  Result.tu := tu;
  Result.tv := tv;
end;


function ProjectionMatrix( near_plane,     // distance to near clipping plane
                           far_plane,     // distance to far clipping plane
                           fov_horiz,     // horizontal field of view angle, in radians
                           fov_vert:real): TD3DMatrix ;    // vertical field of view angle, in radians
var h,w,Q:real;
begin
    Fov_horiz:=g_Uhel * Fov_horiz;
    Fov_Vert:=g_Uhel * Fov_Vert;

    w := cotan(fov_horiz*0.5);
    h := cotan(fov_vert*0.5);
    Q := far_plane/(far_plane - near_plane);

    result._11 := w;
    result._22 := h;
    result._33 := Q;
    result._43 := -Q*near_plane;
    result._34 := 1;
end;
   // end of ProjectionMatrix()

//-----------------------------------------------------------------------------
// File: D3DMath.cpp
//
// Desc: Shortcut macros and functions for using DX objects
//
// Copyright (c) 1997-1999 Microsoft Corporation. All rights reserved
//-----------------------------------------------------------------------------

function D3DMath_IsZero(a: Double; fTol: Double{ = g_EPSILON}): Boolean;
begin
  if a<0 then
    Result := a>=-fTol
  else
    Result := a<=fTol;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_MatrixMultiply()
// Desc: Does the matrix operation: [Q] = [A] * [B]. Note that the order of
//       this operation was changed from the previous version of the DXSDK.
//-----------------------------------------------------------------------------
procedure D3DMath_MatrixMultiply(var q: TD3DMatrix; const a, b: TD3DMatrix);
type
  PArrayD3DValue = ^TArrayD3DValue;
  TArrayD3DValue = array[0..15] of TD3DValue;
var
  pA, pB, pQ: PArrayD3DValue;
  i, j, k: Integer;
begin
  FillChar(q, SizeOf(q), 0);

  pA := @a;
  pB := @b;
  pQ := @q;
  for i:=0 to 3 do
    for j:=0 to 3 do
      for k:=0 to 3 do
        pQ[4*i+j] := pQ[4*i+j] + pA[4*i+k] * pB[4*k+j];
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_MatrixInvert()
// Desc: Does the matrix operation: [Q] = inv[A]. Note: this function only
//       works for matrices with [0 0 0 1] for the 4th column.
//-----------------------------------------------------------------------------
function D3DMath_MatrixInvert(var q: TD3DMatrix; const a: TD3DMatrix): HResult;
var
  fDetInv: Double;
begin
  if (abs(a._44-1.0)>0.001) or (abs(a._14) > 0.001) or (abs(a._24) > 0.001) or (abs(a._34) > 0.001) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  fDetInv := 1.0 / ( a._11 * ( a._22 * a._33 - a._23 * a._32 ) -
                     a._12 * ( a._21 * a._33 - a._23 * a._31 ) +
                     a._13 * ( a._21 * a._32 - a._22 * a._31 ) );

  q._11 :=  fDetInv * ( a._22 * a._33 - a._23 * a._32 );
  q._12 := -fDetInv * ( a._12 * a._33 - a._13 * a._32 );
  q._13 :=  fDetInv * ( a._12 * a._23 - a._13 * a._22 );
  q._14 := 0.0;

  q._21 := -fDetInv * ( a._21 * a._33 - a._23 * a._31 );
  q._22 :=  fDetInv * ( a._11 * a._33 - a._13 * a._31 );
  q._23 := -fDetInv * ( a._11 * a._23 - a._13 * a._21 );
  q._24 := 0.0;

  q._31 :=  fDetInv * ( a._21 * a._32 - a._22 * a._31 );
  q._32 := -fDetInv * ( a._11 * a._32 - a._12 * a._31 );
  q._33 :=  fDetInv * ( a._11 * a._22 - a._12 * a._21 );
  q._34 := 0.0;

  q._41 := -( a._41 * q._11 + a._42 * q._21 + a._43 * q._31 );
  q._42 := -( a._41 * q._12 + a._42 * q._22 + a._43 * q._32 );
  q._43 := -( a._41 * q._13 + a._42 * q._23 + a._43 * q._33 );
  q._44 := 1.0;

  Result := S_OK;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_VectorMatrixMultiply()
// Desc: Multiplies a vector by a matrix
//-----------------------------------------------------------------------------
function D3DMath_VectorMatrixMultiply(var vDest: TD3DVector; const vSrc: TD3DVector;
  const mat: TD3DMatrix): HResult;
var
  x, y, z, w: Double;
begin
  x := vSrc.x*mat._11 + vSrc.y*mat._21 + vSrc.z* mat._31 + mat._41;
  y := vSrc.x*mat._12 + vSrc.y*mat._22 + vSrc.z* mat._32 + mat._42;
  z := vSrc.x*mat._13 + vSrc.y*mat._23 + vSrc.z* mat._33 + mat._43;
  w := vSrc.x*mat._14 + vSrc.y*mat._24 + vSrc.z* mat._34 + mat._44;

  if abs(w) < g_EPSILON then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  vDest.x := x/w;
  vDest.y := y/w;
  vDest.z := z/w;

  Result := S_OK;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_VertexMatrixMultiply()
// Desc: Multiplies a vertex by a matrix
//-----------------------------------------------------------------------------
function D3DMath_VertexMatrixMultiply(var vDest: TD3DVertex; const vSrc: TD3DVertex;
  const mat: TD3DMatrix): HResult;
var
  pSrcVec, pDestVec: PD3DVector;
begin
  pSrcVec := @vSrc.x;
  pDestVec := @vDest.x;

  Result := D3DMath_VectorMatrixMultiply(pDestVec^, pSrcVec^, mat);
  if SUCCEEDED(Result) then
  begin
    pSrcVec  := @vSrc.nx;
    pDestVec := @vDest.nx;
    Result := D3DMath_VectorMatrixMultiply(pDestVec^, pSrcVec^, mat);
  end;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_QuaternionFromRotation()
// Desc: Converts a normalized axis and angle to a unit quaternion.
//-----------------------------------------------------------------------------
procedure D3DMath_QuaternionFromRotation(var x, y, z, w: Double;
  const v: TD3DVector; fTheta: Double);
begin
  x := sin( fTheta/2.0 ) * v.x;
  y := sin( fTheta/2.0 ) * v.y;
  z := sin( fTheta/2.0 ) * v.z;
  w := cos( fTheta/2.0 );
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_RotationFromQuaternion()
// Desc: Converts a normalized axis and angle to a unit quaternion.
//-----------------------------------------------------------------------------
procedure D3DMath_RotationFromQuaternion(var v: TD3DVector; var fTheta: Double;
  x, y, z, w: Double);
begin
  fTheta := arccos(w) * 2.0;
  v.x    := x / sin( fTheta/2.0 );
  v.y    := y / sin( fTheta/2.0 );
  v.z    := z / sin( fTheta/2.0 );
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_QuaternionFromAngles()
// Desc: Converts euler angles to a unit quaternion.
//-----------------------------------------------------------------------------
procedure D3DMath_QuaternionFromAngles(var x, y, z, w: Double; fYaw, fPitch, fRoll: Double);
var
  fSinYaw, fSinPitch, fSinRoll, fCosYaw, fCosPitch, fCosRoll: Double;
begin
  fSinYaw   := sin( fYaw/2.0 );
  fSinPitch := sin( fPitch/2.0 );
  fSinRoll  := sin( fRoll/2.0 );
  fCosYaw   := cos( fYaw/2.0 );
  fCosPitch := cos( fPitch/2.0 );
  fCosRoll  := cos( fRoll/2.0 );

  x := fSinRoll * fCosPitch * fCosYaw - fCosRoll * fSinPitch * fSinYaw;
  y := fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
  z := fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
  w := fCosRoll * fCosPitch * fCosYaw + fSinRoll * fSinPitch * fSinYaw;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_MatrixFromQuaternion()
// Desc: Converts a unit quaternion into a rotation matrix.
//-----------------------------------------------------------------------------
procedure D3DMath_MatrixFromQuaternion(var mat: TD3DMatrix; x, y, z, w: Double);
var
  xx, yy, zz, xy, xz, yz, wx, wy, wz: Double;
begin
  xx := x*x; yy := y*y; zz := z*z;
  xy := x*y; xz := x*z; yz := y*z;
  wx := w*x; wy := w*y; wz := w*z;

  mat._11 := 1 - 2 * ( yy + zz );
  mat._12 :=     2 * ( xy - wz );
  mat._13 :=     2 * ( xz + wy );

  mat._21 :=     2 * ( xy + wz );
  mat._22 := 1 - 2 * ( xx + zz );
  mat._23 :=     2 * ( yz - wx );

  mat._31 :=     2 * ( xz - wy );
  mat._32 :=     2 * ( yz + wx );
  mat._33 := 1 - 2 * ( xx + yy );

  mat._14 := 0.0; mat._24 := 0.0; mat._34 := 0.0;
  mat._41 := 0.0; mat._42 := 0.0; mat._43 := 0.0;
  mat._44 := 1.0;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_QuaternionFromMatrix()
// Desc: Converts a rotation matrix into a unit quaternion.
//-----------------------------------------------------------------------------
procedure D3DMath_QuaternionFromMatrix(var x, y, z, w: Double; var mat: TD3DMatrix);
var
  s: Double;
  xx, yy, zz, xy, xz, yz, wx, wy, wz: Double;
begin
  if( mat._11 + mat._22 + mat._33 > 0.0 )then
  begin
    s := sqrt( mat._11 + mat._22 + mat._33 + mat._44 );

    x := (mat._23-mat._32) / (2*s);
    y := (mat._31-mat._13) / (2*s);
    z := (mat._12-mat._21) / (2*s);
    w := 0.5 * s;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -