// Name        : Lesson 4 - Double Cone / Двойной конус
// Version     : 19 dec 2012
// Author      : LODka3D
// Discription : Урок 04 о создании тел вращения.
// 

{$I 'vectorgeometry.dws'} // Файл с векторными функциями.


  // Функция добавления двойного конуса с заданным числом сегментов и 
  //  позицией aPos. Позицию aPos, мы просто прибавляем везде к координатам
  //  добавляемой точки.
procedure AddDoubleCone(Cnt1 : Integer; aPos : TVector);
var
  p1, t1, p2, i1 : Integer;
  ang, delta     : Float;
begin
    // Запоминаем сколько ранее было добавлено вершин и текст.коорд, в 
    //  примитив. Чтобы знать насколько увеличивать индексы вершин и 
    //  текст.коорд. в функции добавления треугольников LODPAddFaceInd.
  p1 := StrToInt(LOD('GetPPointsCount'));  
  t1 := StrToInt(LOD('GetPTxCoordCount')); 
    // Добавляем центральную вершину и центральную текстурную координату.
  LODPAddPoint(0 +aPos[0], 0 +aPos[1], 0.5 +aPos[2]);
  LODPAddTxCoord(0.5, 0.5);
      // Добавляем точки и текстурные координаты по окружности.
    // delta1 - угол на который повёрнута точка относительно предыдущей
  delta := 2*Pi / Cnt1; 
  for i1 := 0 to Cnt1 -1 do begin
    ang := -2*Pi +delta*i1; // Угол поворота точки от начала координат.
      // Тригонометрически вычисляем положения вершин и текстурных координат
      //  идущих по кругу.
    LODPAddPoint(  Sin(ang) *0.5 +aPos[0], Cos(ang) *0.5 +aPos[1], 0 +aPos[2]);
    LODPAddTxCoord(Sin(ang) *0.5 +0.5,     Cos(ang) *0.5 +0.5);
  end;
    // Добавляем треугольники по окружности верхнего конуса.
  for i1 := 0 to Cnt1 -1 -1 do
   LODPAddFaceInd(p1 +0, p1 +i1+2, p1 +i1+1,  1,  t1 +0, t1 +i1+2, t1 +i1+1);
  LODPAddFaceInd( p1 +0, p1 +1,    p1 +Cnt1,  1,  t1 +0, t1 +1,    t1 +Cnt1);

    // Запоминаем положение нижней вершины конуса.
  p2 := StrToInt(LOD('GetPPointsCount'));  
    // Добавляем саму вершину.
  LODPAddPoint(0 +aPos[0], 0 +aPos[1], -0.5 +aPos[2]);
    // Добавляем треугольники по окружности нижнего конуса.
  for i1 := 0 to Cnt1 -1 -1 do
   LODPAddFaceInd(p2 +0, p1 +i1+1, p1 +i1+2,  2,  t1 +0, t1 +i1+1, t1 +i1+2);
  LODPAddFaceInd( p2 +0, p1 +Cnt1, p1 +1,     2,  t1 +0, t1 +Cnt1,    t1 +1);
end;


 
  // Создаём два контрола, в одном число сегментов конусов, в другом - число 
  //  самих конусов.
procedure LODPCreateControls;
begin
  if LOD('GetLanguage') = '25' then begin // Русский язык.
    LOD('AddPControl', 'Parts1', 'Int', '24', 'Сегменты', 
          'Из скольких сегментов должен состоять двойной конус.', '3', '1000');
    LOD('AddPControl', 'Cones1', 'Int', '1', 'Конусы', 
                                                'Число конусов.', '1', '1000');
  end else begin // English language.
    LOD('AddPControl', 'Parts1', 'Int', '24', 'Parts', 'Parts of double cone.', 
                                                                  '3', '1000');
    LOD('AddPControl', 'Cones1', 'Int', '1', 'Cones', 'Cones count.', '1', 
                                                                       '1000');
  end;
end;

  // Функция создания примитива.
procedure LODPCreatePrimitive;
var 
  i1 : Integer;
begin
    // Добавляем несколько конусов вызывая одну и ту же функцию AddCone2 но 
    //  задавая в ней разную начальную позицию конуса {VectorMake(0, 0, i1)}.
  for i1 := 0 to StrToInt(LOD('GetPControl', 'Cones1')) -1 do
    AddDoubleCone(StrToInt(LOD('GetPControl', 'Parts1')), VectorMake(0, 0, i1)); 
end;