unit _m_MathPack;

interface

uses
  Windows, SysUtils, d3dtypes;

function frnd(lim:single):single;
function D3DF2DW(f:Single):DWord;
function MakeColorValue(_a,_r,_g,_b:single):D3DCOLORVALUE;
function MakeVector(_x,_y,_z:Single):D3DVECTOR;
function MakeVectorPos(_x,_y,_z:single):D3DVECTOR;
function MakeVertex(_x,_y,_z,_nx,_ny,_nz,_tu,_tv:single):D3DVERTEX;
function MakeLVertex(_x,_y,_z:Single;_color,_specular:dword;_tu,_tv:Single):D3DLVERTEX;
function MakeTLVertex(_x,_y,_z,_rhw:Single; _col,_sp:DWord; _tu,_tv:Single):D3DTLVERTEX;
function ModulateMatrix(const m1,m2:D3DMATRIX):D3DMATRIX;
function ModulateVectorMatrix(const v:D3DVECTOR;const m:D3DMATRIX):D3DVECTOR;
function ModulateVectorMatrixRotation(const v:D3DVECTOR;const m:D3DMATRIX):D3DVECTOR;
function ModulateVertexMatrix(const v:D3DVERTEX;const m:D3DMATRIX):D3DVERTEX;
function MakePosMatrix(const x,y,z:single):D3DMATRIX;
function MakeRotxMatrix(r:single):D3DMATRIX;
function MakeRotyMatrix(r:single):D3DMATRIX;
function MakeNormalizeVertex(const v0,v1,v2:D3DVERTEX):D3DVECTOR;
function MakeNormalizeVector(const v0,v1,v2:D3DVECTOR):D3DVECTOR;
function NowNormalizeVertex(const v:D3DVERTEX):D3DVECTOR;
function NowNormalizeVector(const a:D3DVECTOR):D3DVECTOR;

function MinVectors(v0,v1:D3DVector):D3DVector;
function PlusVectors(v0,v1:D3DVector):D3DVector;
function DivVectors(v0,v1:D3DVector):D3DVector;
function DivVector(v:D3DVector;d:single):D3DVector;
function MulVectors(v0,v1:D3DVector):D3DVector;
function MulVector(v:D3DVector;d:single):D3DVector;
function VectorABS(v:D3DVector):single;
function VectorABS2(v:D3DVector):single;

implementation

uses s_MathPack;

function frnd(lim:single):single;
begin
  Result:=random(trunc(lim*10000))/10000;
end;

function D3DF2DW(f:Single):DWord;
  asm mov eax,f;
end;

function MakeVector(_x,_y,_z:Single):D3DVECTOR;
begin
  with result do begin
    x:=_x;
    y:=_y;
    z:=_z;
  end;
end;

function MakeVectorPos(_x,_y,_z:single):D3DVECTOR;
begin
  with result do begin
    x:=_x;
    y:=_y;
    z:=_z;
  end;
end;

function MakeVertex(_x,_y,_z,_nx,_ny,_nz,_tu,_tv:single):D3DVERTEX;
begin
  with result do begin
    x:=_x;
    y:=_y;
    z:=_z;
    nx:=_nx;
    ny:=_ny;
    nz:=_nz;
    tu:=_tu;
    tv:=_tv;
  end;
end;

function MakeLVertex(_x,_y,_z:Single;_color,_specular:dword;_tu,_tv:Single):D3DLVERTEX;
begin
  with result do begin
    x:=_x;
    y:=_y;
    z:=_z;
    color:=_color;
    specular:=_color;//specular;
    tu:=_tu;
    tv:=_tv;
    dwReserved:=0;
  end;
end;

function MakeColorValue(_a,_r,_g,_b:single):D3DCOLORVALUE;
begin
  with result do begin
    a:=_a;
    r:=_r;
    g:=_g;
    b:=_b;
  end;
end;

function MakeTLVertex(_x,_y,_z,_rhw:Single; _col,_sp:DWord; _tu,_tv:Single):D3DTLVERTEX;
begin
  with result do begin
    sx:=_x;
    sy:=_y;
    sz:=_z;
    rhw:=_rhw;
    color:=_col;
    specular:=_sp;
    tu:=_tu;
    tv:=_tv;
  end;
end;

function ModulateMatrix(const m1,m2:D3DMATRIX):D3DMATRIX;
begin
  with result do begin
    _11:=m1._11*m2._11 + m1._12*m2._21 + m1._13*m2._31 + m1._14*m2._41;
    _12:=m1._11*m2._12 + m1._12*m2._22 + m1._13*m2._32 + m1._14*m2._42;
    _13:=m1._11*m2._13 + m1._12*m2._23 + m1._13*m2._33 + m1._14*m2._43;
    _14:=m1._11*m2._14 + m1._12*m2._24 + m1._13*m2._34 + m1._14*m2._44;
    _21:=m1._21*m2._11 + m1._22*m2._21 + m1._23*m2._31 + m1._24*m2._41;
    _22:=m1._21*m2._12 + m1._22*m2._22 + m1._23*m2._32 + m1._24*m2._42;
    _23:=m1._21*m2._13 + m1._22*m2._23 + m1._23*m2._33 + m1._24*m2._43;
    _24:=m1._21*m2._14 + m1._22*m2._24 + m1._23*m2._34 + m1._24*m2._44;
    _31:=m1._31*m2._11 + m1._32*m2._21 + m1._33*m2._31 + m1._34*m2._41;
    _32:=m1._31*m2._12 + m1._32*m2._22 + m1._33*m2._32 + m1._34*m2._42;
    _33:=m1._31*m2._13 + m1._32*m2._23 + m1._33*m2._33 + m1._34*m2._43;
    _34:=m1._31*m2._14 + m1._32*m2._24 + m1._33*m2._34 + m1._34*m2._44;
    _41:=m1._41*m2._11 + m1._42*m2._21 + m1._43*m2._31 + m1._44*m2._41;
    _42:=m1._41*m2._12 + m1._42*m2._22 + m1._43*m2._32 + m1._44*m2._42;
    _43:=m1._41*m2._13 + m1._42*m2._23 + m1._43*m2._33 + m1._44*m2._43;
    _44:=m1._41*m2._14 + m1._42*m2._24 + m1._43*m2._34 + m1._44*m2._44;
  end;
end;

function ModulateVectorMatrix(const v:D3DVECTOR;const m:D3DMATRIX):D3DVECTOR;
begin
  with result do begin
    x:=v.x*m._11 + v.y*m._21 + v.z*m._31 + m._41;
    y:=v.x*m._12 + v.y*m._22 + v.z*m._32 + m._42;
    z:=v.x*m._13 + v.y*m._23 + v.z*m._33 + m._43;
  end;
end;

function ModulateVectorMatrixRotation(const v:D3DVECTOR;const m:D3DMATRIX):D3DVECTOR;
begin
  // 回転軸ｘとｙに特化した行列掛け算
  with result do begin
    x:=v.x*m._11 + v.y*m._21 + v.z*m._31;
    y:=            v.y*m._22 + v.z*m._32;
    z:=v.x*m._13 + v.y*m._23 + v.z*m._33;
  end;
end;

function ModulateVertexMatrix(const v:D3DVERTEX;const m:D3DMATRIX):D3DVERTEX;
begin
  with result do begin
    x:=v.x*m._11 + v.y*m._21 + v.z*m._31 + m._41;
    y:=v.x*m._12 + v.y*m._22 + v.z*m._32 + m._42;
    z:=v.x*m._13 + v.y*m._23 + v.z*m._33 + m._43;
    nx:=v.nx*m._11 + v.ny*m._21 + v.nz*m._31 + m._41;
    ny:=v.nx*m._12 + v.ny*m._22 + v.nz*m._32 + m._42;
    nz:=v.nx*m._13 + v.ny*m._23 + v.nz*m._33 + m._43;
  end;
end;

function MakePosMatrix(const x,y,z:single):D3DMATRIX;
begin
  with result do begin
    _11:=1; _12:=0;   _13:=0;  _14:=0;
    _21:=0; _22:=1;  _23:=0; _24:=0;
    _31:=0; _32:=0; _33:=1; _34:=0;
    _41:=x; _42:=y; _43:=z; _44:=1;
  end;
end;

function MakeRotxMatrix(r:single):D3DMATRIX;
var
  s,c:single;
begin
  s:=Sin(r);
  c:=Cos(r);
  with result do begin
    _11:=1; _12:=0;  _13:=0; _14:=0;
    _21:=0; _22:=c;  _23:=s; _24:=0;
    _31:=0; _32:=-s; _33:=c; _34:=0;
    _41:=0; _42:=0;  _43:=0; _44:=1;
  end;
end;

function MakeRotyMatrix(r:single):D3DMATRIX;
var
  s,c:single;
begin
  s:=Sin(r);
  c:=Cos(r);
  with result do begin
    _11:=c; _12:=0; _13:=-s; _14:=0;
    _21:=0; _22:=1; _23:=0;  _24:=0;
    _31:=s; _32:=0; _33:=c;  _34:=0;
    _41:=0; _42:=0; _43:=0;  _44:=1;
  end;
end;

function MakeNormalizeVertex(const v0,v1,v2:D3DVERTEX):D3DVECTOR;
var
  l:single;
  nx0,ny0,nz0,nx1,ny1,nz1:single;
  ntx,nty,ntz:single;
begin
  nx0:=v1.x-v0.x;
  ny0:=v1.y-v0.y;
  nz0:=v1.z-v0.z;
  nx1:=v2.x-v1.x;
  ny1:=v2.y-v1.y;
  nz1:=v2.z-v1.z;

  ntx:=ny0*nz1 - nz0*ny1;
  nty:=nz0*nx1 - nx0*nz1;
  ntz:=nx0*ny1 - ny0*nx1;

  l:=sqrt(ntx*ntx+nty*nty+ntz*ntz);
  if l=0 then l:=0.001;

  result.x:=ntx/l;
  result.y:=nty/l;
  result.z:=ntz/l;
end;

function MakeNormalizeVector(const v0,v1,v2:D3DVECTOR):D3DVECTOR;
var
  l:single;
  nx0,ny0,nz0,nx1,ny1,nz1:single;
  ntx,nty,ntz:single;
begin
  nx0:=v1.x-v0.x;
  ny0:=v1.y-v0.y;
  nz0:=v1.z-v0.z;
  nx1:=v2.x-v1.x;
  ny1:=v2.y-v1.y;
  nz1:=v2.z-v1.z;

  ntx:=ny0*nz1 - nz0*ny1;
  nty:=nz0*nx1 - nx0*nz1;
  ntz:=nx0*ny1 - ny0*nx1;

  l:=sqrt(ntx*ntx+nty*nty+ntz*ntz);
  if l=0 then l:=0.001;

  result.x:=ntx/l;
  result.y:=nty/l;
  result.z:=ntz/l;
end;

function NowNormalizeVertex(const v:D3DVERTEX):D3DVECTOR;
var
  len:Single;
  a:D3DVECTOR;
begin
  a.x:=v.nx;
  a.y:=v.ny;
  a.z:=v.nz;

  NowLength(len,a);
  if len = 0 then begin
    result:=Vector(0,0,0);
    exit;
  end;

  result.X:=a.X / len;
  result.Y:=a.Y / len;
  result.Z:=a.Z / len;
end;

function NowNormalizeVector(const a:D3DVECTOR):D3DVECTOR;
var
  len:Single;
begin
  NowLength(len,a);
  if len = 0 then begin
    result:=Vector(0,0,0);
    exit;
  end;

  result.X:=a.X / len;
  result.Y:=a.Y / len;
  result.Z:=a.Z / len;
end;

function MinVectors(v0,v1:D3DVector):D3DVector;
begin
  with Result do begin
    x:=v0.x-v1.x;
    y:=v0.y-v1.y;
    z:=v0.z-v1.z;
  end;
end;

function PlusVectors(v0,v1:D3DVector):D3DVector;
begin
  with Result do begin
    x:=v0.x+v1.x;
    y:=v0.y+v1.y;
    z:=v0.z+v1.z;
  end;
end;

function DivVectors(v0,v1:D3DVector):D3DVector;
begin
  with Result do begin
    X:=v0.x/v1.x;
    Y:=v0.y/v1.y;
    Z:=v0.z/v1.z;
  end;
end;

function DivVector(v:D3DVector;d:single):D3DVector;
begin
  with Result do begin
    X:=v.x/d;
    Y:=v.y/d;
    Z:=v.z/d;
  end;
end;

function MulVectors(v0,v1:D3DVector):D3DVector;
begin
  with Result do begin
    X:=v0.x*v1.x;
    Y:=v0.y*v1.y;
    Z:=v0.z*v1.z;
  end;
end;

function MulVector(v:D3DVector;d:single):D3DVector;
begin
  with Result do begin
    X:=v.x*d;
    Y:=v.y*d;
    Z:=v.z*d;
  end;
end;

function VectorABS(v:D3DVector):single;
begin
  Result:=sqrt(VectorABS2(v));
end;

function VectorABS2(v:D3DVector):single;
begin
  with v do begin
    Result:=x*x+y*y+z*z;
  end;
end;

end.
