// Name        : Lesson 05 - 3 axis / Урок 05 Три оси.
// Version     : 19 dec 2012
// Author      : LODka3D
// Discription : Урок 05 Делаем три оси из одной и той же стрелки поворачивая
//                её в разные стороны.
//

{$INCLUDE 'func-demo1.dws'}
{$INCLUDE 'vectorgeometry.dws'}

procedure LODPCreatePrimitive;
var
  p1, p2,  t1, t2,  i1 : Integer;
  vSc1 : TVector;
begin
      // == Делаем стрелку указывающую по Х ( красная ось ). == 
    // Запоминаем сколько было вершин до добавления стрелки.
  p1  := StrToInt(LOD('GetPPointsCount'));
    // Добавляем стрелку.
  AddArrow;
    // Запоминаем сколько стало вершин после добавления стрелки.
    //  p1 и p2 нужны чтобы двигать вращать и масштабировать только те 
    //  вершины, которые только что добавили, а не все вообще.
  p2  := StrToInt(LOD('GetPPointsCount')) -1;

    // Масштабируем стрелку, делая её вдвое меньше. Масштабирование - это 
    // умножение каждой точки на заданный вектор (0.5;0.5;0.5).
    //  Тут масштабируются только вершины примитива из промежутка [p1..p2].
  LOD('PPtsScaleVector', '(0.5;0.5;0.5)',     IntToStr(p1), IntToStr(p2));
    // Поворачиваем стрелку на матрицу (0;0;1;0; 0;-1;0;0), 
    // Поскольку матрица перед поворотом на неё будет нормализована, 
    //  достаточно указать только первые два вектора, а третий вычислится сам.
  LOD('PPtsTransform', '(0;0;1;0; 0;-1;0;0)', IntToStr(p1), IntToStr(p2));
    // Сдвинуть стрелку на новую позицию. К каждой вершине из промежутка
    //  [p1..p2] прибавляется вектор (0.25;0;0).
  LOD('PPtsAddVector', '(0.25;0;0)',          IntToStr(p1), IntToStr(p2));


      // == Делаем стрелку указывающую по Y ( зелёная ось ). == 
    // Процесс аналогичный, только поворачиваем стрелку в другую сторону.
  p1  := StrToInt(LOD('GetPPointsCount'));
  AddArrow;
  p2  := StrToInt(LOD('GetPPointsCount')) -1;

  LOD('PPtsScaleVector', '(0.5;0.5;0.5)',     IntToStr(p1), IntToStr(p2));
  LOD('PPtsTransform', '(1;0;0;0; 0;0;-1;0)', IntToStr(p1), IntToStr(p2));
  LOD('PPtsAddVector', '(0;0.25;0)',          IntToStr(p1), IntToStr(p2));


      // ==  Делаем стрелку указывающую по Z ( синяя ось ). == 
  p1  := StrToInt(LOD('GetPPointsCount'));
  t1  := StrToInt(LOD('GetPFaceCount'));
  AddArrow;
  p2  := StrToInt(LOD('GetPPointsCount')) -1;
  t2  := StrToInt(LOD('GetPFaceCount')) -1;
  LOD('PPtsScaleVector', '(0.5;0.5;0.5)',     IntToStr(p1), IntToStr(p2));
  LOD('PPtsAddVector', '(0;0;0.25)',          IntToStr(p1), IntToStr(p2));


    // Вывернуть  нормали если галочка Invert включена.
  if LOD('GetPControl', 'Invert') = '1' then begin
      // Выворачиваем нормали всех треугольников.
    LOD('PFaceInvert');
      // Эта функция выворачивает нормали только треугольников последней
      //  добавленной стрелки.
      // Не путать, что диапазон нормалей здесь указывается в 
      //  треугольниках t1,t2, а не в вершина p1, pt2 .
    // LOD('PFaceInvert'), IntToStr(t1), IntToStr(t2));
  end;


    // Игнорировать масштаб модели установленный пользователем.
  if LOD('GetPControl', 'Scale') = '1' then begin
      // Читаем масштаб примитива который установил пользователь.
    vSc1 := StrToVector(LOD('GetPPreviewScale'));
      // Вычисляем на сколько его надо компенсировать.
    for i1 := 0 to 2 do
      if vSc1[i1] <> 0 then vSc1[i1] := 1/vSc1[i1];
      // Ставим всем вершинам модели новый масштаб.
    LOD('PPtsScaleVector', VectorToStr(vSc1));
  end;
end;


procedure LODPCreateControls;
begin
  if LOD('GetLanguage') = '25' then begin
    LOD('AddPControl', 'Invert', 'Bool', '0', 'Изнанка', 
                                                'Вывернуть модель наизнанку.');
    LOD('AddPControl', 'Scale',  'Bool', '0', 'Без масштаба', 
                                                'Не масштабировать.');
  end else begin
    LOD('AddPControl', 'Invert', 'Bool', '0', 'Invert',   'Invert normals');
    LOD('AddPControl', 'Scale',  'Bool', '0', 'No scale', 'Ignore scale.');
  end;
end;