C2MiscTess.pas
上传用户:yj_qiu
上传日期:2022-08-08
资源大小:23636k
文件大小:10k
源码类别:

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(CAST II Engine miscellaneous tesselators unit)
  3.  (C) 2006 George "Mirage" Bakhtadze. <a href="http://www.casteng.com">www.casteng.com</a> <br>
  4.  The source code may be used under either MPL 1.1 or LGPL 2.1 license. See included license.txt file <br>
  5.  Unit contains miscellaneous tesselator classes
  6. *)
  7. {$Include GDefines.inc}
  8. {$Include C2Defines.inc}
  9. unit C2MiscTess;
  10. interface
  11. uses
  12.   TextFile,
  13.   BaseTypes, Basics, Base3D, CAST2, C2Types, C2Visual;
  14. type
  15.   TWholeTreeMesh = class(TTesselator)
  16.     LevelHeight, LevelStride, InnerRadius, OuterRadius, IRadiusStep, ORadiusStep, StrideFactor: Single;
  17.     StemLowRadius, StemHighRadius, StemHeight, CrownStart: Single;
  18.     StemUHeight, StemVHeight, CrownUVRadius: Single;
  19.     Smoothing, Levels: Integer;
  20.     Colored, Stem: Boolean;
  21.     StemColor, CrownColor: BaseTypes.TColor;
  22.     constructor Create; override;
  23.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  24.     procedure SetParameters(ALevelHeight, ALevelStride, AInnerRadius, AOuterRadius, AIRadiusStep, AORadiusStep, AStrideFactor: Single;
  25.                             AStem: Boolean;
  26.                             AStemUHeight, AStemVHeight, ACrownUVRadius, AStemLowRadius, AStemHighRadius, AStemHeight, ACrownStart: Single;
  27.                             ASmoothing, ALevels: Integer;
  28.                             AColored: Boolean; AStemColor, ACrownColor: BaseTypes.TColor); virtual;
  29.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  30.     function SetIndices(IBPTR: Pointer): Integer; override;
  31.     function GetBoundingBox: TBoundingBox; override;
  32.   protected
  33.     MaxY: Single;
  34.   end;
  35. implementation
  36. { TWholeTreeMesh }
  37. constructor TWholeTreeMesh.Create;
  38. begin
  39.   inherited;
  40.   PrimitiveType := ptTRIANGLELIST;
  41.   SetParameters(0.200, 0.300, 0.400, 0.800, 0.080, 0.080, 0.9, True, 0.25, 0.25, 1, 0.300, 0.100, 1.000, 0.200, 8, 3, True, GetColor($808020), GetColor($408040));
  42. end;
  43. function TWholeTreeMesh.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  44. begin
  45.   Result     := 20;
  46.   Parameters := @LevelHeight;
  47. end;
  48. procedure TWholeTreeMesh.SetParameters(ALevelHeight, ALevelStride, AInnerRadius, AOuterRadius, AIRadiusStep, AORadiusStep, AStrideFactor: Single;
  49.                                        AStem: Boolean;
  50.                                        AStemUHeight, AStemVHeight, ACrownUVRadius, AStemLowRadius, AStemHighRadius, AStemHeight, ACrownStart: Single;
  51.                                        ASmoothing, ALevels: Integer;
  52.                                        AColored: Boolean; AStemColor, ACrownColor: BaseTypes.TColor);
  53. var i: Integer; LStride: Single;
  54. begin
  55.   InitVertexFormat(GetVertexFormat(False, True, AColored, False, False, 1, [2]));
  56.   Smoothing    := ASmoothing; Levels := ALevels;
  57.   LevelHeight  := ALevelHeight;
  58.   LevelStride  := ALevelStride;
  59.   InnerRadius  := AInnerRadius;
  60.   OuterRadius  := AOuterRadius;
  61.   IRadiusStep  := AIRadiusStep;
  62.   ORadiusStep  := AORadiusStep;
  63.   StrideFactor := AStrideFactor;
  64.   Stem           := AStem;
  65.   StemLowRadius  := AStemLowRadius;
  66.   StemHighRadius := AStemHighRadius;
  67.   StemHeight     := AStemHeight;
  68.   CrownStart     := ACrownStart;
  69.   StemUHeight    := AStemUHeight;
  70.   StemVHeight    := AStemVHeight;
  71.   CrownUVRadius  := ACrownUVRadius;
  72.   Colored        := AColored;
  73.   StemColor      := AStemColor;
  74.   CrownColor     := ACrownColor; 
  75.   TotalVertices   :=   Smoothing*2*Levels +   Smoothing*2 * Byte(Stem);
  76.   TotalPrimitives :=   Smoothing*2*Levels +   Smoothing*2 * Byte(Stem);
  77.   TotalIndices    := 3*Smoothing*2*Levels + 3*Smoothing*2 * Byte(Stem);
  78.   IndexingVertices := TotalVertices;
  79.   TotalStrips := 1;
  80.   StripOffset := 0;
  81.   VerticesRes := -1; IndicesRes := -1;
  82.   // Compute max. Y
  83.   MaxY := CrownStart;
  84.   LStride := LevelStride;
  85.   for i := 0 to Levels-1 do begin
  86.     MaxY := MaxY + LStride;
  87.     LStride := LStride * StrideFactor;
  88.   end;
  89.   if StemHeight > MaxY then MaxY := StemHeight;
  90. end;
  91. function TWholeTreeMesh.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  92. var
  93.   i, j: Integer;
  94.   CurY, CurIR, CurOR, LHeight, LStride, UVNorm: Single;
  95.   Ofs: Cardinal;
  96.   t1, t2: Single;
  97. begin
  98. // ******** Tree stem ************
  99.   if Stem then begin
  100.     for i := 0 to Smoothing-1 do begin
  101.       t1 := Cos(i/180*pi*360/Smoothing); t2 := Sin(i/180*pi*360/Smoothing);
  102.       SetVertexDataC(t1*StemLowRadius, 0, -t2*StemLowRadius, i, VBPTR);
  103.       SetVertexDataW(0, i, VBPTR);
  104.       SetVertexDataN(t1, 0, -t2, i, VBPTR);
  105. //      U := 1-0.15+0.3*i/Smoothing;
  106.       case i and 3 of
  107.         0: t1 := 1 - StemUHeight;
  108.         1: t1 := 1;
  109.         2: t1 := 1 + StemUHeight;
  110.         3: t1 := 1;
  111.       end;
  112.       t2 := 1-StemVHeight;
  113.       SetVertexDataUV(t1, t2, i, VBPTR);
  114.     end;
  115.     for i := 0 to Smoothing-1 do begin
  116.       Ofs := i+Smoothing;
  117.       t1 := Cos(i/180*pi*360/Smoothing); t2 := Sin(i/180*pi*360/Smoothing);
  118.       SetVertexDataC(t1*StemHighRadius, StemHeight, -t2*StemHighRadius, Ofs, VBPTR);
  119.       SetVertexDataW(1 - StemHeight / MaxY, Ofs, VBPTR);
  120.       SetVertexDataN(t1, 0, -t2, Ofs, VBPTR);
  121. //      U := 1-0.15+0.3*i/Smoothing;
  122.       case i and 3 of
  123.         0: t1 := 1 - StemUHeight;
  124.         1: t1 := 1;
  125.         2: t1 := 1 + StemUHeight;
  126.         3: t1 := 1;
  127.       end;
  128.       t2 := 1+StemVHeight;
  129.       SetVertexDataUV(t1, t2, Ofs, VBPTR);
  130.     end;
  131.   end;
  132. // Tree crown
  133.   CurY := CrownStart;
  134.   CurIR := InnerRadius; CurOR := OuterRadius;
  135.   LHeight := LevelHeight; LStride := LevelStride;
  136.   for j := 0 to Levels-1 do begin
  137.     if CurIR > CurOR then begin
  138.       if CurIR = 0 then UVNorm := 0 else UVNorm := CurOR / CurIR;
  139.     end else begin
  140.       if CurOR = 0 then UVNorm := 0 else UVNorm := CurIR / CurOR;
  141.     end;
  142.     for i := 0 to Smoothing-1 do begin              // Outer edge
  143.       Ofs := (j+Ord(Stem))*2*(Smoothing)+i;
  144.       t1 := Cos(i/180*pi*360/Smoothing + j*35/180*pi); t2 := Sin(i/180*pi*360/Smoothing + j*35/180*pi);
  145.       SetVertexDataC(t1*CurOR, CurY, -t2*CurOR, Ofs, VBPTR);
  146.       SetVertexDataW(1 - CurY/ MaxY, Ofs, VBPTR);
  147.       if Abs(CurOR) < 0.001 then begin
  148.         SetVertexDataN(0, 1, 0, Ofs, VBPTR);
  149.       end else begin
  150.         SetVertexDataN(t1, 0, -t2, Ofs, VBPTR);
  151.       end;
  152.       t1 := Cos(i/180*pi*360/Smoothing) * CrownUVRadius; t2 := Sin(i/180*pi*360/Smoothing) * CrownUVRadius;
  153.       if CurIR > CurOR then begin
  154.         SetVertexDataUV(0.5 + t1 * UVNorm * 0.5, 0.5 - t2 * UVNorm * 0.5, Ofs, VBPTR);
  155.       end else begin
  156.         SetVertexDataUV(0.5+t1*0.5, 0.5-t2*0.5, Ofs, VBPTR);
  157.       end;
  158.     end;
  159.     for i := 0 to Smoothing-1 do begin          // Inner edge
  160.       Ofs := ((j+Ord(Stem))*2+1)*(Smoothing)+i;
  161.       t1 := Cos(i/180*pi*360/Smoothing + j*35/180*pi); t2 := Sin(i/180*pi*360/Smoothing + j*35/180*pi);
  162.       SetVertexDataC(t1*CurIR, CurY + LHeight, -t2*CurIR, Ofs, VBPTR);
  163.       SetVertexDataW(1 - (CurY + LHeight)/ MaxY, Ofs, VBPTR);
  164.       if Abs(CurIR) < 0.001 then begin
  165.         SetVertexDataN(0, 1, 0, Ofs, VBPTR);
  166.       end else begin
  167.         SetVertexDataN(t1, 0, -t2, Ofs, VBPTR);
  168.       end;
  169.       t1 := Cos(i/180*pi*360/Smoothing) * CrownUVRadius; t2 := Sin(i/180*pi*360/Smoothing) * CrownUVRadius;
  170.       if CurIR < CurOR then begin                                                    // Inner edge
  171.         SetVertexDataUV(0.5 + t1 * UVNorm * 0.5, 0.5 - t2 * UVNorm * 0.5, Ofs, VBPTR);
  172.       end else begin                                                                 // Outer edge
  173.         SetVertexDataUV(0.5+t1*0.5, 0.5-t2*0.5, Ofs, VBPTR);
  174.       end;
  175.     end;
  176. //    YDec := YDec * (1-0.7/(Levels));
  177.     CurY := CurY + LStride;
  178.     CurIR := CurIR - IRadiusStep;
  179.     CurOR := CurOR - ORadiusStep;
  180.     LStride := LStride * StrideFactor;
  181.     LHeight := LHeight * StrideFactor;
  182.   end;
  183. //  TotalVertices := TotalParticles*12; TotalPrimitives := TotalParticles*2;
  184.   TesselationStatus[tbVertex].Status := tsTesselated;
  185.   Result := TotalVertices;
  186.   LastTotalVertices := TotalVertices;
  187. end;
  188. function TWholeTreeMesh.SetIndices(IBPTR: Pointer): Integer;
  189. var i, j: Integer;
  190. begin
  191. {  for j := 0 to Levels-1 do begin
  192.     for i := 0 to Smoothing-1 do begin
  193.       TWordBuffer(IBPTR^)[(j*Smoothing+i)*3] := j*(Smoothing+1);
  194.       TWordBuffer(IBPTR^)[(j*Smoothing+i)*3+1] := j*(Smoothing+1)+i+1;
  195.       TWordBuffer(IBPTR^)[(j*Smoothing+i)*3+2] := j*(Smoothing+1)+i+2;
  196.     end;
  197.     TWordBuffer(IBPTR^)[(j*Smoothing+Smoothing-1)*3+2] := j*(Smoothing+1)+1;
  198.   end;}
  199.   for j := 0 to Levels-Byte(not Stem) do begin
  200.     for i := 0 to Smoothing-1 do begin
  201.       TWordBuffer(IBPTR^)[(j*Smoothing)*6+i*6+0] := (j*2+0)*(Smoothing+0)+i;
  202.       TWordBuffer(IBPTR^)[(j*Smoothing)*6+i*6+1] := (j*2+0)*(Smoothing+0)+i+1;
  203.       TWordBuffer(IBPTR^)[(j*Smoothing)*6+i*6+2] := (j*2+1)*(Smoothing+0)+i;
  204.       TWordBuffer(IBPTR^)[(j*Smoothing)*6+i*6+3] := (j*2+0)*(Smoothing+0)+i+1;
  205.       TWordBuffer(IBPTR^)[(j*Smoothing)*6+i*6+4] := (j*2+1)*(Smoothing+0)+i+1;
  206.       TWordBuffer(IBPTR^)[(j*Smoothing)*6+i*6+5] := (j*2+1)*(Smoothing+0)+i+0;
  207.     end;
  208.     TWordBuffer(IBPTR^)[(j*Smoothing)*6+(Smoothing-1)*6+1] := (j*2+0)*(Smoothing+0)+0;
  209.     TWordBuffer(IBPTR^)[(j*Smoothing)*6+(Smoothing-1)*6+3] := (j*2+0)*(Smoothing+0)+0;
  210.     TWordBuffer(IBPTR^)[(j*Smoothing)*6+(Smoothing-1)*6+4] := (j*2+1)*(Smoothing+0)+0;
  211.   end;
  212.   TesselationStatus[tbIndex].Status := tsTesselated;
  213.   Result := TotalIndices;
  214.   LastTotalIndices := TotalIndices;
  215. end;
  216. function TWholeTreeMesh.GetBoundingBox: TBoundingBox;
  217. begin
  218.   Result.P1 := GetVector3s(-OuterRadius, 0, -OuterRadius);
  219.   Result.P2 := GetVector3s(OuterRadius, LevelStride*(Levels-1) + LevelHeight, OuterRadius);
  220. end;
  221. end.