unit UtilGL;

interface

uses
  OpenGL;

type
  TVector=TGLArrayf3;
  TPoint3=TGLArrayf3;
  TPoints=array[0..2] of TPoint3;
  TMatrix=array[0..3,0..3] of GLfloat;

procedure CrossProduct2v(const v1,v2:TVector;var dest:TVector);
procedure CrossProduct1v(const source:TPoints;var dest:TVector);
procedure Normalize(var vector:TVector);
function DotProduct2v(const v1,v2:TGLArrayf4): GLfloat;
procedure ProjectToPlane(const plane:TPoints;
  const position:TGLArrayf4;var ProjMat:TMatrix);

implementation

procedure CrossProduct2v(const v1,v2:TVector;var dest:TVector);
begin
  dest[0] := v1[1]*v2[2]-v2[1]*v1[2];
  dest[1] := v1[2]*v2[0]-v2[2]*v1[0];
  dest[2] := v1[0]*v2[1]-v2[0]*v1[1];
end;

procedure CrossProduct1v(const source:TPoints;var dest:TVector);
var
  v1,
  v2: TVector;
  coord: integer;
begin
  {source is three points in CCW order}

  {make two vectors from the three points}
  for coord := 0 to 2 do
  begin
    v1[coord] := source[0][coord]-source[1][coord];
    v2[coord] := source[1][coord]-source[2][coord];
  end;

  {get cross product of the two vectors}
  CrossProduct2v(v1,v2,dest);
end;

procedure Normalize(var vector:TVector);
var
  len: GLfloat;
  coord: integer;
begin
  len := 0.0;
  for coord := 0 to 2 do
    len := len+vector[coord]*vector[coord];
  len := sqrt(len);
  for coord := 0 to 2 do
    vector[coord] := vector[coord]/len;
end;

function DotProduct2v(const v1,v2:TGLArrayf4): GLfloat;
var
  index: integer;
begin
  result := 0.0;
  for index := 0 to 3 do
    result := result+ v1[index]*v2[index];
end;

procedure ProjectToPlane(const plane:TPoints;
  const position:TGLArrayf4;var ProjMat:TMatrix);
var
  Coefficients: TGLArrayf4;
  c3: TVector absolute Coefficients; {first three coefficients}
  dotProd: GLfloat;
  APoint: packed record
    x,y,z: GLfloat;
  end absolute plane; {first point in plane}
  place: TVector absolute position;
begin
  {
  Given three points that define a plane,
  generate the coefficients of the equation of that plane.
  ax+by+cz+d = 0

  Get first three coefficients from the cross product
  }
  crossProduct1v(plane,c3);

  {
  Find fourth coefficient from the other three.
  d = 0-ax-by-cz
  substituting coordinates of first point.
  }
  with APoint do
    Coefficients[3] := -Coefficients[0]*x-Coefficients[1]*y-Coefficients[2]*z;

  dotProd := DotProduct2v(Coefficients,position);

  {Now make projection matrix}
  ProjMat[0][0] := 0.0-position[0]*Coefficients[0];
  ProjMat[1][0] := 0.0-position[0]*Coefficients[1];
  ProjMat[2][0] := 0.0-position[0]*Coefficients[2];
  ProjMat[3][0] := 0.0-position[0]*Coefficients[3];

  ProjMat[0][1] := 0.0-position[1]*Coefficients[0];
  ProjMat[1][1] := 0.0-position[1]*Coefficients[1];
  ProjMat[2][1] := 0.0-position[1]*Coefficients[2];
  ProjMat[3][1] := 0.0-position[1]*Coefficients[3];

  ProjMat[0][2] := 0.0-position[2]*Coefficients[0];
  ProjMat[1][2] := 0.0-position[2]*Coefficients[1];
  ProjMat[2][2] := 0.0-position[2]*Coefficients[2];
  ProjMat[3][2] := 0.0-position[2]*Coefficients[3];

  ProjMat[0][3] := 0.0-position[3]*Coefficients[0];
  ProjMat[1][3] := 0.0-position[3]*Coefficients[1];
  ProjMat[2][3] := 0.0-position[3]*Coefficients[2];
  ProjMat[3][3] := 0.0-position[3]*Coefficients[3];
end;

end.
