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

📄 d3dutils.pas

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

  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_QuaternionMultiply()
// Desc: Mulitples two quaternions together as in {Q} = {A} * {B}.
//-----------------------------------------------------------------------------
procedure D3DMath_QuaternionMultiply(var Qx, Qy, Qz, Qw: Double;
  Ax, Ay, Az, Aw, Bx, By, Bz, Bw: Double);
var
  Dx, Dy, Dz, Dw: Double;
begin
  Dx :=  Ax*Bw + Ay*Bz - Az*By + Aw*Bx;
  Dy := -Ax*Bz + Ay*Bw + Az*Bx + Aw*By;
  Dz :=  Ax*By - Ay*Bx + Az*Bw + Aw*Bz;
  Dw := -Ax*Bx - Ay*By - Az*Bz + Aw*Bw;

  Qx := Dx; Qy := Dy; Qz := Dz; Qw := Dw;
end;

//-----------------------------------------------------------------------------
// Name: D3DMath_SlerpQuaternions()
// Desc: Compute a quaternion which is the spherical linear interpolation
//       between two other quaternions by dvFraction.
//-----------------------------------------------------------------------------
procedure D3DMath_QuaternionSlerp(var Qx, Qy, Qz, Qw: Double;
  Ax, Ay, Az, Aw, Bx, By, Bz, Bw, fAlpha: Double);
var
  fCosTheta: Double;
  fBeta: Double;
  fTheta: Double;
begin
  // Compute dot product (equal to cosine of the angle between quaternions)
  fCosTheta := Ax*Bx + Ay*By + Az*Bz + Aw*Bw;

  // Check angle to see if quaternions are in opposite hemispheres
  if fCosTheta < 0.0 then
  begin
    // If so, flip one of the quaterions
    fCosTheta := -fCosTheta;
    Bx := -Bx; By := -By; Bz := -Bz; Bw := -Bw;
  end;

  // Set factors to do linear interpolation, as a special case where the
  // quaternions are close together.
  fBeta := 1.0 - fAlpha;

  // If the quaternions aren't close, proceed with spherical interpolation
  if 1.0 - fCosTheta > 0.001 then
  begin
    fTheta := arccos( fCosTheta );

    fBeta  := sin( fTheta*fBeta ) / sin( fTheta);
    fAlpha := sin( fTheta*fAlpha ) / sin( fTheta);
  end;

  // Do the interpolation
  Qx := fBeta*Ax + fAlpha*Bx;
  Qy := fBeta*Ay + fAlpha*By;
  Qz := fBeta*Az + fAlpha*Bz;
  Qw := fBeta*Aw + fAlpha*Bw;
end;

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


//-----------------------------------------------------------------------------
// Name: D3DUtil_InitSurfaceDesc()
// Desc: Helper function called to build a DDSURFACEDESC2 structure,
//       typically before calling CreateSurface() or GetSurfaceDesc()
//-----------------------------------------------------------------------------
procedure D3DUtil_InitSurfaceDesc(var ddsd: TDDSurfaceDesc2; dwFlags, dwCaps: DWORD);
begin
  FillChar(ddsd, SizeOf(ddsd), 0);
  ddsd.dwSize                 := SizeOf(ddsd);
  ddsd.dwFlags                := dwFlags;
  ddsd.ddsCaps.dwCaps         := dwCaps;
  ddsd.ddpfPixelFormat.dwSize := SizeOf(ddsd.ddpfPixelFormat);
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_InitMaterial()
// Desc: Helper function called to build a D3DMATERIAL7 structure
//-----------------------------------------------------------------------------
procedure D3DUtil_InitMaterial(var mtrl: TD3DMaterial7; r, g, b, a: Double);
begin
  FillChar(mtrl, SizeOf(mtrl), 0);
  mtrl.dcvDiffuse.r := r; mtrl.dcvAmbient.r := r;
  mtrl.dcvDiffuse.g := g; mtrl.dcvAmbient.g := g;
  mtrl.dcvDiffuse.b := b; mtrl.dcvAmbient.b := b;
  mtrl.dcvDiffuse.a := a; mtrl.dcvAmbient.a := a;
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_InitLight()
// Desc: Initializes a D3DLIGHT7 structure
//-----------------------------------------------------------------------------
procedure D3DUtil_InitLight(var light: TD3DLight7; ltType: TD3DLightType; x, y, z: Double);
begin
  FillChar(light, SizeOf(light), 0);
  light.dltType        := ltType;
  light.dcvDiffuse.r   := 1.0;
  light.dcvDiffuse.g   := 1.0;
  light.dcvDiffuse.b   := 1.0;
  light.dcvSpecular    := light.dcvDiffuse;
  light.dvPosition.x   := x; light.dvDirection.x := x;
  light.dvPosition.y   := y; light.dvDirection.y := y;
  light.dvPosition.z   := z; light.dvDirection.z := z;
  light.dvAttenuation0 := 1.0;
  light.dvRange        := D3DLIGHT_RANGE_MAX;
end;

procedure D3DUtil_SetIdentityMatrix(var m: TD3DMatrix);
begin
  m._12 := 0; m._13 := 0; m._14 := 0; m._21 := 0; m._23 := 0; m._24 := 0;
  m._31 := 0; m._32 := 0; m._34 := 0; m._41 := 0; m._42 := 0; m._43 := 0;
  m._11 := 1; m._22 := 1; m._33 := 1; m._44 := 1;
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_SetViewMatrix()
// Desc: Given an eye point, a lookat point, and an up vector, this
//       function builds a 4x4 view matrix.
//-----------------------------------------------------------------------------
function D3DUtil_SetViewMatrix(var mat: TD3DMatrix;  const vFrom, vAt, vWorldUp: TD3DVector): HResult;
var
  vView: TD3DVector;
  fLength: Double;
  fDotProduct: Double;
  vUp: TD3DVector;
  vRight: TD3DVector;
begin
  // Get the z basis vector, which points straight ahead. This is the
  // difference from the eyepoint to the lookat point.
  vView := VectorSub(vAt, vFrom);

  fLength := VectorMagnitude( vView );
  if fLength < 0.1e-6 then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  // Normalize the z basis vector
  vView := VectorDivS(vView, fLength);

  // Get the dot product, and calculate the projection of the z basis
  // vector onto the up vector. The projection is the y basis vector.
  fDotProduct :=VectorDotProduct( vWorldUp, vView );

  vUp := VectorSub(vWorldUp, VectorMulS(vView, fDotProduct));

  // If this vector has near-zero length because the input specified a
  // bogus up vector, let's try a default up vector
  fLength := VectorMagnitude(vUp);
  if 1e-6 > fLength then
  begin
    vUp := VectorSub(MakeD3DVector(0, 1, 0), VectorMulS(vView, vView.y));

    // If we still have near-zero length, resort to a different axis.
    fLength := VectorMagnitude(vUp);
    if 1e-6 > fLength then
    begin
      vUp := VectorSub(MakeD3DVector(0, 0, 1), VectorMulS(vView, vView.z));

      fLength := VectorMagnitude(vUp);
      if  1e-6 > fLength then
      begin
        Result := E_INVALIDARG;
        Exit;
      end;
    end;
  end;

  // Normalize the y basis vector
  vUp := VectorDivS(vUp, fLength);

  // The x basis vector is found simply with the cross product of the y
  // and z basis vectors
  vRight := VectorCrossProduct( vUp, vView );

  // Start building the matrix. The first three rows contains the basis
  // vectors used to rotate the view to point at the lookat point
  D3DUtil_SetIdentityMatrix( mat );
  mat._11 := vRight.x;    mat._12 := vUp.x;    mat._13 := vView.x;
  mat._21 := vRight.y;    mat._22 := vUp.y;    mat._23 := vView.y;
  mat._31 := vRight.z;    mat._32 := vUp.z;    mat._33 := vView.z;

  // Do the translation values (rotations are still about the eyepoint)
  mat._41 := - VectorDotProduct( vFrom, vRight );
  mat._42 := - VectorDotProduct( vFrom, vUp );
  mat._43 := - VectorDotProduct( vFrom, vView );

  Result := S_OK;
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_SetProjectionMatrix()
// Desc: Sets the passed in 4x4 matrix to a perpsective projection matrix built
//       from the field-of-view (fov, in y), aspect ratio, near plane (D),
//       and far plane (F). Note that the projection matrix is normalized for
//       element [3][4] to be 1.0. This is performed so that W-based range fog
//       will work correctly.
//-----------------------------------------------------------------------------
function D3DUtil_SetProjectionMatrix(var mat: TD3DMatrix; fFOV, fAspect, fNearPlane, fFarPlane: Double): HResult;
var
  w, h, Q: Double;
begin
  if (abs(fFarPlane-fNearPlane)<0.01) or (abs(sin(fFOV/2))<0.01) then
  begin
    Result := E_INVALIDARG;
    Exit;
  end;

  w := fAspect * ( cos(fFOV/2)/sin(fFOV/2) );
  h :=   1.0   * ( cos(fFOV/2)/sin(fFOV/2) );
  Q := fFarPlane / ( fFarPlane - fNearPlane );

  FillChar(mat, SizeOf(mat), 0);
  mat._11 := w;
  mat._22 := h;
  mat._33 := Q;
  mat._34 := 1.0;
  mat._43 := -Q*fNearPlane;

  Result := S_OK;
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotateXMatrix()
// Desc: Create Rotation matrix about X axis
//-----------------------------------------------------------------------------
procedure D3DUtil_SetRotateXMatrix(var mat: TD3DMatrix; fRads: Double);
begin
  D3DUtil_SetIdentityMatrix( mat );
  mat._22 :=  cos( fRads );
  mat._23 :=  sin( fRads );
  mat._32 := -sin( fRads );
  mat._33 :=  cos( fRads );
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotateYMatrix()
// Desc: Create Rotation matrix about Y axis
//-----------------------------------------------------------------------------
procedure D3DUtil_SetRotateYMatrix(var mat: TD3DMatrix; fRads: Double);
begin
  D3DUtil_SetIdentityMatrix( mat );
  mat._11 :=  cos( fRads );
  mat._13 := -sin( fRads );
  mat._31 :=  sin( fRads );
  mat._33 :=  cos( fRads );
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotateZMatrix()
// Desc: Create Rotation matrix about Z axis
//-----------------------------------------------------------------------------
procedure D3DUtil_SetRotateZMatrix(var mat: TD3DMatrix; fRads: Double);
begin
  D3DUtil_SetIdentityMatrix( mat );
  mat._11  :=  cos( fRads );
  mat._12  :=  sin( fRads );
  mat._21  := -sin( fRads );
  mat._22  :=  cos( fRads );
end;

//-----------------------------------------------------------------------------
// Name: D3DUtil_SetRotationMatrix
// Desc: Create a Rotation matrix about vector direction
//-----------------------------------------------------------------------------
procedure D3DUtil_SetRotationMatrix(var mat: TD3DMatrix; var vDir: TD3DVector; fRads: Double);
var
  fCos, fSin: Double;
  v: TD3DVector;
begin
  fCos := cos( fRads );
  fSin := sin( fRads );
  v    := VectorNormalize( vDir );

  mat._11 := ( v.x * v.x ) * ( 1.0 - fCos ) + fCos;
  mat._12 := ( v.x * v.y ) * ( 1.0 - fCos ) - (v.z * fSin);
  mat._13 := ( v.x * v.z ) * ( 1.0 - fCos ) + (v.y * fSin);

  mat._21 := ( v.y * v.x ) * ( 1.0 - fCos ) + (v.z * fSin);
  mat._22 := ( v.y * v.y ) * ( 1.0 - fCos ) + fCos ;
  mat._23 := ( v.y * v.z ) * ( 1.0 - fCos ) - (v.x * fSin);

  mat._31 := ( v.z * v.x ) * ( 1.0 - fCos ) - (v.y * fSin);
  mat._32 := ( v.z * v.y ) * ( 1.0 - fCos ) + (v.x * fSin);
  mat._33 := ( v.z * v.z ) * ( 1.0 - fCos ) + fCos;

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

end.

⌨️ 快捷键说明

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