unit meshes;

interface

uses SysUtils, OpenGL, records, constants, textures, variables;

type
  TMesh = class
    smooth, texturize : boolean;
    vertexes : array[1..max_vertexes] of array[0..max_frames] of RVertex;
    texture_vertexes : array[1..max_vertexes] of RTextureVertex;
    faces : array[1..max_faces] of RFace;
    current_frame : integer;
    total_faces, total_vertexes, total_frames : integer;
    texture : integer;
  public
    procedure Load(file_name: string);
    procedure ReBuild;
  end;

var
  mesh_operators : array[1..max_mesh_operators] of string
    = ('TOTAL_FRAMES','TOTAL_VERTEXES','TOTAL_FACES','V','T','F');
  current_face, current_vertex,
  current_texture_vertex : integer;
  temp_strings : array[1..max_temp_strings] of string;

  all_textures : array[1..max_textures] of TTexture;
  total_textures : integer = 0;

implementation

procedure DivideString(s : string);
var
i, c : integer;
t : string;
begin
c := 1; s := ' ' + s + ' ';
for i := 0 to length(s) do
  if (copy(s,i,1) <> ' ') then
    t := t + copy(s,i,1)
  else
    if (t <> ' ')and(t <> '') then
      begin
        temp_strings[c] := t;
        c := c + 1;
        t := '';
      end;
end;

procedure GetMeshInfo(i : integer; mesh : tmesh);
var
a : integer;
begin
with mesh do
case i of
1 : begin
      total_frames := strtoint(temp_strings[2]);
      if total_frames < 0 then total_frames := 0;
      if total_frames > max_frames then total_frames := max_frames;
    end;
2 : begin
      total_vertexes := strtoint(temp_strings[2]);
      if total_vertexes < 1 then total_vertexes := 1;
      if total_vertexes > max_vertexes then total_vertexes := max_vertexes;
    end;
3 : begin
      total_faces := strtoint(temp_strings[2]);
      if total_faces < 1 then total_faces := 1;
      if total_faces > max_faces then total_faces := max_faces;
    end;
4 : begin
      current_vertex := current_vertex + 1;
      with vertexes[current_vertex][0] do
        begin
          p.x := strtofloat(temp_strings[2]);
          p.y := strtofloat(temp_strings[3]);
          p.z := strtofloat(temp_strings[4]);
          n.x := strtofloat(temp_strings[5]);
          n.y := strtofloat(temp_strings[6]);
          n.z := strtofloat(temp_strings[7]);
        end;
      for a := 1 to total_frames - 1 do
        with vertexes[current_vertex][a] do
          begin
            p.x := strtofloat(temp_strings[5 + a*3]);
            p.y := strtofloat(temp_strings[6 + a*3]);
            p.z := strtofloat(temp_strings[7 + a*3]);
          end;
    end;
5 : begin
      current_texture_vertex := current_texture_vertex + 1;
      with texture_vertexes[current_texture_vertex] do
        begin
          x := strtofloat(temp_strings[2]);
          y := strtofloat(temp_strings[3]);
        end;
     end;
6 : begin
      current_face := current_face + 1;
      with faces[current_face] do
        begin
          v[1] := strtoint(temp_strings[2]);
          v[2] := strtoint(temp_strings[3]);
          v[3] := strtoint(temp_strings[4]);
          n.x := strtofloat(temp_strings[5]);
          n.y := strtofloat(temp_strings[6]);
          n.z := strtofloat(temp_strings[7]);
          t[1] := strtoint(temp_strings[8]);
          t[2] := strtoint(temp_strings[9]);
          t[3] := strtoint(temp_strings[10]);
        end;
     end;
end;
end;

procedure TMesh.Load(file_name: string);
var
f : textfile;
s : string;
i : integer;
begin
current_face := 0; current_vertex := 0; current_texture_vertex := 0;
if not fileexists(file_name) then exit;
assignfile(f,file_name);
reset(f);
while not eof(f) do
  begin
    readln(f, s);
    DivideString(s);
    for i := 1 to max_mesh_operators do
      if temp_strings[1] = mesh_operators[i] then
        GetMeshInfo(i,self);
  end;
closefile(f);
end;

procedure TMesh.ReBuild;
var
i1, i2 : integer;
begin
if texturize then all_textures[texture].Enable else glDisable(GL_TEXTURE_2D);
for i1 := 1 to total_faces do
  begin
    glBegin(GL_POLYGON);
    //with faces[i1].n do glNormal3f(x, y, z);
    for i2 := 1 to 3 do
      with vertexes[faces[i1].v[i2]][current_frame] do
        begin
          //if smooth then with n do glNormal3f(x, y, z);
          with texture_vertexes[faces[i1].t[i2]] do glTexCoord2f(x, 1 - y);
          with p do glVertex3f(x, y, z);
        end;
    glEnd;
    triangles_rendered := triangles_rendered + 1;
  end;
end;

end.
