//Direct3Dお便利ルーチンず
unit dddd3dut;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   d3d,d3dcaps,d3dtypes, d3drm,d3drmobj,d3drmwin,d3drmdef;


(******************************************************************************
  ベクトル関連
******************************************************************************)
//ベクトルを作る
function Vector(const a,b,c:D3DValue):D3DVector;
//ベクトル加算
function VecAdd(const a,b:D3DVector):D3DVector;
//ベクトル減算
function VecSub(const a,b:D3DVector):D3DVector;
//ベクトルの大きさを一に
function VecNormalize(const a:D3DVector):D3DVector;
//ベクトルをk倍に
function VecScale(const a:D3DVector; const k:D3DValue):D3DVector;
//ベクトルの長さ
function VecModulus(const a:D3DVector):D3DVALUE;
//ランダムなベクトル
function VecRandom:D3DVector;

//X軸回りの回転
function VecRotX(const v:D3DVector; const t:D3DValue):D3DVector;
//Y軸回りの回転
function VecRotY(const v:D3DVector; const t:D3DValue):D3DVector;
//Z軸回りの回転
function VecRotZ(const v:D3DVector; const t:D3DValue):D3DVector;

(******************************************************************************
  ボックス関連
******************************************************************************)
//箱の拡大･縮小を行う
function BoxScale(const box:D3DRMBox; scale:D3DVALUE):D3DRMBox;
//三次元の当たり判定
function isTouch3D(a,b:D3DRMBox):Boolean;

(******************************************************************************
  IM関連
******************************************************************************)
//TLVertexを作る
function makeTLV(xsx,xsy,xsz, xrhw:D3DVALUE; col,sp:DWORD; xtu,xtv:D3DValue):D3DTLVERTEX;
//LVertexを作る
function makeLV(xsx,xsy,xsz:D3DValue; col,sp:DWORD; xtu,xtv:D3DValue):D3DLVERTEX;
//Vertexを作る
function makeV(xsx,xsy,xsz, xnx,xny,xnz, xtu,xtv:D3DValue):D3DVERTEX;



implementation



(******************************************************************************
  ベクトル関連
******************************************************************************)
//ベクトルを作る
function Vector(const a,b,c:D3DValue):D3DVector;
begin
  with result do begin
    x:=a;
    y:=b;
    z:=c;
  end;
end;

//ベクトル加算
function VecAdd(const a,b:D3DVector):D3DVector;
begin
  D3DRMVectorAdd(@result,@a,@b);
end;

//ベクトル減算
function VecSub(const a,b:D3DVector):D3DVector;
begin
  D3DRMVectorSubtract(@result,@a,@b);
end;

//ベクトルの大きさを一に
function VecNormalize(const a:D3DVector):D3DVector;
begin
  D3DRMVectorNormalize(@a);
  result:=a;
end;

//ベクトルをk倍に
function VecScale(const a:D3DVector; const k:D3DValue):D3DVector;
begin
  D3DRMVectorScale(@result,@a,k);
end;

//ベクトルの長さ
function VecModulus(const a:D3DVector):D3DVALUE;
begin
  result:=D3DRMVectorModulus(@a);
end;

//ランダムベクトル
function VecRandom:D3DVector;
begin
  D3DRMVectorRandom(@result);
end;

//X軸回りの回転
function VecRotX(const v:D3DVector; const t:D3DValue):D3DVector;
begin
  with result do begin
    x:=v.x;
    y:=v.y*cos(t) - v.z*sin(t);
    z:=v.y*sin(t) + v.z*cos(t);
  end;
end;

//Y軸回りの回転
function VecRotY(const v:D3DVector; const t:D3DValue):D3DVector;
begin
  with result do begin
    x:=v.x*cos(t) + v.z*sin(t);
    y:=v.y;
    z:= -v.x*sin(t) + v.z*cos(t);
  end;
end;

//Z軸回りの回転
function VecRotZ(const v:D3DVector; const t:D3DValue):D3DVector;
begin
  with result do begin
    x:=v.x*cos(t) - v.y*sin(t);
    y:=v.x*sin(t) + v.y*cos(t);
    z:=v.z;
  end;
end;


(******************************************************************************
  ボックス関連
******************************************************************************)
//箱の拡大･縮小を行う
function BoxScale(const box:D3DRMBox; scale:D3DVALUE):D3DRMBox;
begin

  with box.max do begin
    result.max.x:=x*scale;
    result.max.y:=y*scale;
    result.max.z:=z*scale;
  end;
  with box.min do begin
    result.min.x:=x*scale;
    result.min.y:=y*scale;
    result.min.z:=z*scale;
  end;
end;

//aがbとcの間に存在するならTrue
function withIn(a,b,c:D3DVALUE):Boolean;
begin
  result:=False;
  if (b<a) And (a<c) then begin
    result:=True;
    Exit;
  end;
  if (b>a) And (a>c) then
    result:=True;
end;

//一次元の当たり判定
function isTouch1D(s1,e1,s2,e2:D3DVALUE):Boolean;
begin
  result:=False;

  if withIn(s1,s2,e2) then begin
    result:=True;
    Exit;
  end;
  if withIn(e1,s2,e2) then begin
    result:=True;
    Exit;
  end;
  if withIn(s2,s1,e1) then begin
    result:=True;
    Exit;
  end;
end;

//三次元の当たり判定
function isTouch3D(a,b:D3DRMBox):Boolean;
begin
  result:=True;

  if not isTouch1D(a.max.x,a.min.x, b.max.x,b.min.x) then begin
    result:=False;
    Exit;
  end;
  if not isTouch1D(a.max.y,a.min.y, b.max.y,b.min.y) then begin
    result:=False;
    Exit;
  end;
  if not isTouch1D(a.max.z,a.min.z, b.max.z,b.min.z) then begin
    result:=False;
    Exit;
  end;
end;


(******************************************************************************
  IM関連
******************************************************************************)
function makeTLV(xsx,xsy,xsz, xrhw:D3DVALUE; col,sp:DWORD; xtu,xtv:D3DValue):D3DTLVERTEX;
begin
  with result do begin
    sx:=xsx;
    sy:=xsy;
    sz:=xsz;
    dvRHW:=xrhw;
    color:=col;
    specular:=sp;
    tu:=xtu;
    tv:=xtv;
  end;
end;

//LVertexを作る
function makeLV(xsx,xsy,xsz:D3DValue; col,sp:DWORD; xtu,xtv:D3DValue):D3DLVERTEX;
begin
  with result do begin
    x:=xsx;
    y:=xsy;
    z:=xsz;
    dwReserved:=0;
    color:=col;
    specular:=sp;
    tu:=xtu;
    tv:=xtv;
  end;
end;

//Vertexを作る
function makeV(xsx,xsy,xsz, xnx,xny,xnz, xtu,xtv:D3DValue):D3DVERTEX;
begin
  with result do begin
    x:=xsx;
    y:=xsy;
    z:=xsz;
    nx:=xnx;
    ny:=xny;
    nz:=xnz;
    tu:=xtu;
    tv:=xtv;
  end;
end;

end.
