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

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(CAST II Engine miscellaneous visual items unit)
  3.  (C) 2006-2008 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 some useful visual items
  6. *)
  7. {$Include GDefines.inc}
  8. {$Include C2Defines.inc}
  9. unit C2VisItems;
  10. interface
  11. uses
  12.   TextFile,
  13.   SysUtils,
  14.   BaseTypes, BaseMsg, Basics, Props, Base3D, BaseClasses, Resources,
  15.   C2Types, CAST2, C2Visual, C2Res, C2Core;
  16. type
  17.   TMeshTesselator = class(TTesselator)
  18.     Vertices, Indices: Pointer;
  19.     NumberOfVertices, NumberOfIndices: Integer;
  20.     constructor Create; override;
  21.     procedure Init; override;
  22.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  23.     function GetMaxVertices: Integer; override;
  24.     function GetMaxIndices: Integer; override;
  25.     function GetBoundingBox: TBoundingBox; override;
  26.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  27.     function SetIndices(IBPTR: Pointer): Integer; override;
  28.   protected
  29.     FVertices, FIndices: Pointer;
  30.   end;
  31.   TMesh = class(TVisible)
  32.     function GetTesselatorClass: CTesselator; override;
  33.     procedure OnSceneLoaded; override;
  34.     procedure AddProperties(const Result: Props.TProperties); override;
  35.     procedure SetProperties(Properties: Props.TProperties); override;
  36.   private
  37.     function GetVerticesRes: TVerticesResource;
  38.     function GetIndicesRes: TIndicesResource;
  39.   protected
  40.     procedure SetMesh; override;
  41.   public
  42.     procedure HandleMessage(const Msg: TMessage); override;
  43.     property Vertices: TVerticesResource read GetVerticesRes;
  44.     property Indices:  TIndicesResource  read GetIndicesRes;
  45.   end;
  46.   TPlaneTesselator = class(TTesselator)
  47.   protected
  48.     FColor: BaseTypes.TColor;
  49.     FWidth, FHeight: Single;
  50.   public  
  51.     Color: BaseTypes.TColor;
  52.     Width, Height: Single;
  53.     constructor Create; override;
  54.     function GetBoundingBox: TBoundingBox; override;
  55.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  56.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  57.   end;
  58.   TPlane = class(TVisible)
  59.   public
  60.     TexScaleU, TexScaleV, TexMoveU, TexMoveV: Single;
  61.     constructor Create(AManager: TItemsManager); override;
  62.     function GetTesselatorClass: CTesselator; override;
  63.     procedure AddProperties(const Result: Props.TProperties); override;
  64.     procedure SetProperties(Properties: Props.TProperties); override;
  65.   end;
  66.   TMirrorPlaneTesselator = class(TTesselator)
  67.   private
  68.     vel, arr: array of single;
  69.   protected
  70.     FColor: BaseTypes.TColor;
  71.     FWidth, FHeight: Single;
  72.     FRows, FCols: Integer;
  73.   public
  74.     Color: BaseTypes.TColor;
  75.     Width, Height: Single;
  76.     Rows, Cols: Integer;
  77.     constructor Create; override;
  78.     procedure Init; override;
  79.     function GetBoundingBox: TBoundingBox; override;
  80.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  81.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  82.     function SetIndices(IBPTR: Pointer): Integer; override;
  83.     procedure Iterate;
  84.   end;
  85.   TMirrorPlane = class(TVisible)
  86.   private
  87.     TexMat: TMatrix4s;
  88.   protected
  89.     procedure RetrieveTexMat(TextureStage: Integer; out Mat: TMatrix4s);
  90.   public
  91.     constructor Create(AManager: TItemsManager); override;
  92.     function VisibilityCheck(const Camera: TCamera): Boolean; override;
  93.     function GetTesselatorClass: CTesselator; override;
  94.     procedure AddProperties(const Result: Props.TProperties); override;
  95.     procedure SetProperties(Properties: Props.TProperties); override;
  96.     procedure Process(const DeltaTime: Single); override;
  97.   end;
  98.   TCircleTesselator = class(TTesselator)
  99.   protected
  100.     FCenterColor, FSideColor: BaseTypes.TColor;
  101.     FRadius: Single;
  102.     FSectors: Integer;
  103.   public  
  104.     CenterColor, SideColor: BaseTypes.TColor;
  105.     Radius: Single;
  106.     Sectors: Integer;
  107.     constructor Create; override;
  108.     procedure Init; override;
  109.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  110.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  111.     function GetBoundingBox: TBoundingBox; override;
  112.   end;
  113.   TCircle = class(TVisible)
  114.   private
  115.     function GetCenterColor: BaseTypes.TColor;
  116.     function GetSideColor: BaseTypes.TColor;
  117.     procedure SetCenterColor(const Value: BaseTypes.TColor);
  118.     procedure SetSideColor(const Value: BaseTypes.TColor);
  119.   public
  120.     AttachedToCamera, FixedY: Boolean;
  121.     TexScaleU, TexScaleV, TexMoveU, TexMoveV: Single;
  122.     function GetTesselatorClass: CTesselator; override;
  123.     procedure AddProperties(const Result: Props.TProperties); override;
  124.     procedure SetProperties(Properties: Props.TProperties); override;
  125.     procedure Process(const DeltaT: Float); override;
  126.   
  127.     property CenterColor: BaseTypes.TColor read GetCenterColor write SetCenterColor;
  128.     property SideColor:   BaseTypes.TColor read GetSideColor   write SetSideColor;
  129.   end;
  130.   TDomeTesselator = class(TTesselator)
  131.   protected
  132.     FSectors, FSegments: Integer;
  133.     FRadius, FHeight, FTexScale: Single;
  134.     FColor: BaseTypes.TColor;
  135.     FSkyMap: BaseTypes.PImageBuffer;
  136.   public  
  137.     // Parameters
  138.     Sectors, Segments: Integer;
  139.     Radius, Height, TexScale: Single;
  140.     Color: BaseTypes.TColor;
  141.     SkyMap: BaseTypes.PImageBuffer;
  142.     // Other
  143.     SMWidth, SMHeight: Integer;
  144.     constructor Create; override;
  145.     procedure Init; override;
  146.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  147.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  148.     function SetIndices(IBPTR: Pointer): Integer; override;
  149.     function GetBoundingBox: TBoundingBox; override;
  150.   end;
  151.   TDome = class(TVisible)
  152.     function GetTesselatorClass: CTesselator; override;
  153.     procedure AddProperties(const Result: Props.TProperties); override;
  154.     procedure SetProperties(Properties: Props.TProperties); override;
  155.   end;
  156.   TSky = class(TDome)
  157.   protected
  158.     procedure ResolveLinks; override;
  159.   public  
  160.     procedure AddProperties(const Result: Props.TProperties); override;
  161.     procedure SetProperties(Properties: Props.TProperties); override;
  162.   end;
  163.   TRingMesh = class(TTesselator)
  164.   protected
  165.     FInnerRadius, FOuterRadius, FFactor: Single;
  166.     FSmoothing: Integer;
  167.     FColor1, FColor2: BaseTypes.TColor;
  168.     FUVMapType: Longword;
  169.   public  
  170.     InnerRadius, OuterRadius, Factor: Single;
  171.     Smoothing: Integer;
  172.     Color1, Color2: BaseTypes.TColor;
  173.     UVMapType: Longword;
  174.     UVFrame: TUV;
  175.     constructor Create; override;
  176.     procedure Init; override;
  177.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  178.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  179.     function GetBoundingBox: TBoundingBox; override;
  180.   end;
  181.   TRing = class(TVisible)
  182.   private
  183.     function GetColor: BaseTypes.TColor;
  184.     procedure SetColor(const Value: BaseTypes.TColor);
  185.   public
  186.     YAngle: Single;
  187.     constructor Create(AManager: TItemsManager); override;
  188.     function VisibilityCheck(const Camera: TCamera): Boolean; override;
  189.     function GetTesselatorClass: CTesselator; override;
  190.     procedure AddProperties(const Result: Props.TProperties); override;
  191.     procedure SetProperties(Properties: Props.TProperties); override;
  192.     property Color: BaseTypes.TColor read GetColor write SetColor;
  193.   end;
  194.   // Returns list of classes introduced by the unit
  195.   function GetUnitClassList: TClassArray;
  196. implementation
  197. function GetUnitClassList: TClassArray;
  198. begin
  199.   Result := GetClassList([TVisible, TMappedItem, TMesh, TPlane, TCircle, TDome, TSky]);
  200. end;
  201. { TMeshTesselator }
  202. constructor TMeshTesselator.Create;
  203. begin
  204.   inherited;
  205.   PrimitiveType := ptTRIANGLELIST;
  206.   Vertices      := nil;
  207.   Indices       := nil;
  208.   FVertices     := nil;
  209.   FIndices      := nil;
  210.   InitVertexFormat(GetVertexFormat(False, True, False, False, False, 0, [2]));
  211.   Init;
  212. end;
  213. procedure TMeshTesselator.Init;
  214. begin
  215.   inherited;
  216.   Invalidate([tbVertex, tbIndex], (TotalVertices <> NumberOfVertices) or (TotalIndices <> NumberOfIndices));
  217.   TotalVertices    := NumberOfVertices;
  218.   TotalIndices     := NumberOfIndices;
  219.   IndexingVertices := TotalVertices;
  220.   TotalPrimitives  := TotalIndices div 3;
  221.   FVertices        := Vertices;
  222.   FIndices         := Indices;
  223. end;
  224. function TMeshTesselator.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  225. begin
  226.   Result := (2*SizeOf(Pointer)) div 4;
  227.   if Internal then Parameters := @FVertices else Parameters := @Vertices;
  228. end;
  229. function TMeshTesselator.GetMaxVertices: Integer;
  230. begin
  231.   Result := NumberOfVertices;
  232. end;
  233. function TMeshTesselator.GetMaxIndices: Integer;
  234. begin
  235.   Result := NumberOfIndices;
  236. end;
  237. function TMeshTesselator.GetBoundingBox: TBoundingBox;
  238. var i: Integer;
  239. begin
  240.   if FVertices = nil then Exit;
  241.   Result.P1 := GetVector3s(100000, 100000, 100000); Result.P2 := GetVector3s(-100000, -100000, -100000);
  242.   for i := 0 to TotalVertices-1 do with TVector3s((@TByteBuffer(FVertices^)[i*Integer(FVertexSize)])^), Result do begin
  243.     if X < P1.X then P1.X := X; if Y < P1.Y then P1.Y := Y; if Z < P1.Z then P1.Z := Z;
  244.     if X > P2.X then P2.X := X; if Y > P2.Y then P2.Y := Y; if Z > P2.Z then P2.Z := Z;
  245.   end;
  246. end;
  247. function TMeshTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  248. var i: Integer;
  249. begin
  250.   Result := 0;
  251.   if FVertices = nil then Exit;
  252.   if not CompositeMember then begin
  253.     Move(FVertices^, VBPTR^, TotalVertices * FVertexSize);
  254.   end else begin
  255.     Assert(CompositeOffset <> nil, 'Composite object''s offset is nil');
  256.     for i := 0 to TotalVertices-1 do begin
  257.       Move(TByteBuffer(FVertices^)[i*FVertexSize + SizeOf(TVector3s)], TByteBuffer(VBPTR^)[i*FVertexSize + SizeOf(TVector3s)], FVertexSize - SizeOf(TVector3s));
  258.       TVector3s((@TByteBuffer(VBPTR^)[i*FVertexSize])^).X := TVector3s((@TByteBuffer(FVertices^)[i*FVertexSize])^).X + CompositeOffset^.X;
  259.       TVector3s((@TByteBuffer(VBPTR^)[i*FVertexSize])^).Y := TVector3s((@TByteBuffer(FVertices^)[i*FVertexSize])^).Y + CompositeOffset^.Y;
  260.       TVector3s((@TByteBuffer(VBPTR^)[i*FVertexSize])^).Z := TVector3s((@TByteBuffer(FVertices^)[i*FVertexSize])^).Z + CompositeOffset^.Z;
  261.     end;
  262.   end;
  263.   TesselationStatus[tbVertex].Status := tsTesselated;
  264. //  Status := tsChanged;
  265.   LastTotalIndices := TotalIndices;
  266.   LastTotalVertices := TotalVertices;
  267.   Result := LastTotalVertices;
  268. end;
  269. function TMeshTesselator.SetIndices(IBPTR: Pointer): Integer;
  270. begin
  271.   Result := 0;
  272.   if FIndices = nil then Exit;
  273.   Move(TWordBuffer(FIndices^)[0], TWordBuffer(IBPTR^)[0], TotalIndices * IndexSize);
  274.   LastTotalIndices := TotalIndices;
  275.   TesselationStatus[tbIndex].Status := tsTesselated;
  276.   Result := TotalIndices;
  277. end;
  278. { TPlaneTesselator }
  279. constructor TPlaneTesselator.Create;
  280. begin
  281.   inherited;
  282.   PrimitiveType    := ptTRIANGLESTRIP;
  283.   InitVertexFormat(GetVertexFormat(False, False, True, False, False, 0, [2]));
  284.   TotalVertices    := 4;
  285.   TotalPrimitives  := 2;
  286.   Color.C  := $80808080;
  287.   Width  := 1;
  288.   Height := 1;
  289.   Init;
  290. end;
  291. function TPlaneTesselator.GetBoundingBox: TBoundingBox;
  292. begin
  293.   Result.P1 := GetVector3s(-Width, -Height, 0);
  294.   Result.P2 := GetVector3s( Width,  Height, 0);
  295. end;
  296. function TPlaneTesselator.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  297. begin
  298.   Result := (1*SizeOf(Longword) + 2*SizeOf(Single)) div 4;
  299.   if Internal then Parameters := @FColor else Parameters := @Color;
  300. end;
  301. function TPlaneTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  302. begin
  303.   SetVertexDataC(-FWidth, FHeight, 0, 0, VBPTR);
  304.   SetVertexDataUV(0, 0, 0, VBPTR);
  305.   SetVertexDataD(FColor, 0, VBPTR);
  306.   SetVertexDataC(FWidth, FHeight, 0, 1, VBPTR);
  307.   SetVertexDataUV(1, 0, 1, VBPTR);
  308.   SetVertexDataD(FColor, 1, VBPTR);
  309.   SetVertexDataC(-FWidth, -FHeight, 0, 2, VBPTR);
  310.   SetVertexDataUV(0, 1, 2, VBPTR);
  311.   SetVertexDataD(FColor, 2, VBPTR);
  312.   SetVertexDataC(FWidth, -FHeight, 0, 3, VBPTR);
  313.   SetVertexDataUV(1, 1, 3, VBPTR);
  314.   SetVertexDataD(FColor, 3, VBPTR);
  315.   TesselationStatus[tbVertex].Status := tsTesselated;
  316.   LastTotalVertices := TotalVertices;
  317.   Result            := TotalVertices;
  318. end;
  319. { TPlane }
  320. constructor TPlane.Create(AManager: TItemsManager);
  321. begin
  322.   inherited;
  323.   TexScaleU := 1; TexScaleV := 1; TexMoveU := 1; TexMoveV := 1;
  324. end;
  325. function TPlane.GetTesselatorClass: CTesselator; begin Result := TPlaneTesselator; end;
  326. procedure TPlane.AddProperties(const Result: Props.TProperties);
  327. var Tesselator: TPlaneTesselator;
  328. begin
  329.   inherited;
  330.   if not Assigned(Result) then Exit;
  331.   Result.Add('Texturescale U', vtSingle, [], FloatToStr(TexScaleU), '');
  332.   Result.Add('Texturescale V', vtSingle, [], FloatToStr(TexScaleV), '');
  333.   Result.Add('Texturemove U',  vtSingle, [], FloatToStr(TexMoveU),  '');
  334.   Result.Add('Texturemove V',  vtSingle, [], FloatToStr(TexMoveV),  '');
  335.   if not (CurrentTesselator is TPlaneTesselator) then Exit;
  336.   Tesselator := CurrentTesselator as TPlaneTesselator;
  337.   AddColorProperty(Result, 'Color', Tesselator.Color);
  338.   Result.Add('GeometryWidth',  vtSingle, [],       FloatToStr(Tesselator.Width),   '');
  339.   Result.Add('GeometryHeight', vtSingle, [],       FloatToStr(Tesselator.Height),  '');
  340. end;
  341. procedure TPlane.SetProperties(Properties: Props.TProperties);
  342. var Tesselator: TPlaneTesselator;
  343. begin
  344.   inherited;
  345.   if Properties.Valid('Texturescale U') then TexScaleU := StrToFloatDef(Properties['Texturescale U'], 1);
  346.   if Properties.Valid('Texturescale V') then TexScaleV := StrToFloatDef(Properties['Texturescale V'], 1);
  347.   if Properties.Valid('Texturemove U')  then TexMoveU  := StrToFloatDef(Properties['Texturemove U'],  1);
  348.   if Properties.Valid('Texturemove V')  then TexMoveV  := StrToFloatDef(Properties['Texturemove V'],  1);
  349.   if not (CurrentTesselator is TPlaneTesselator) then Exit;
  350.   Tesselator := CurrentTesselator as TPlaneTesselator;
  351.   SetColorProperty(Properties, 'Color', Tesselator.Color);
  352.   if Properties.Valid('GeometryWidth')  then Tesselator.Width  := StrToFloatDef(Properties['GeometryWidth'],  1);
  353.   if Properties.Valid('GeometryHeight') then Tesselator.Height := StrToFloatDef(Properties['GeometryHeight'], 1);
  354.   SetMesh;
  355. end;
  356. { TMirrorPlaneTesselator }
  357. constructor TMirrorPlaneTesselator.Create;
  358. begin
  359.   inherited;
  360.   Cols := 1; Rows := 1;
  361.   Color.C  := $80808080;
  362.   Width    := 1;
  363.   Height   := 1;
  364.   Init;
  365. end;
  366. function TMirrorPlaneTesselator.GetBoundingBox: TBoundingBox;
  367. begin
  368.   Result.P1 := GetVector3s(-Width, -Height, 0);
  369.   Result.P2 := GetVector3s( Width,  Height, 0);
  370. end;
  371. procedure TMirrorPlaneTesselator.Init;
  372. begin
  373.   inherited;
  374.   TotalVertices   := (FRows+1)*(FCols+1);
  375.   TotalIndices    :=  FRows * FCols * 6;
  376.   TotalPrimitives :=  FRows * FCols * 2;
  377.   IndexingVertices := TotalVertices;
  378.   PrimitiveType    := ptTRIANGLELIST;
  379.   InitVertexFormat(GetVertexFormat(False, True, True, False, False, 0, []));
  380.   SetLength(arr, TotalVertices);
  381.   SetLength(Vel, TotalVertices);
  382.   FillChar(arr[0], TotalVertices*4, 0);
  383.   FillChar(vel[0], TotalVertices*4, 0);
  384.   arr[Random(FRows) * FCols + Random(FCols)] := 1550;
  385. end;
  386. procedure TMirrorPlaneTesselator.Iterate;
  387. var i, j: Integer;
  388. begin
  389.   arr[Random(FRows) * FCols + Random(FCols)] := 1550;
  390.   for j := 1 to FRows-2 do begin
  391.     for i := 1 to FCols-2 do begin
  392.       vel[j * FCols + i] := vel[j * FCols + i] - arr[j * FCols + i]*4 +
  393.                             arr[(j+1) * FCols + i] + arr[(j-1) * FCols + i] +
  394.                             arr[j * FCols + i + 1] + arr[j * FCols + i - 1];
  395.     end;
  396.   end;
  397.   for j := 0 to FRows-1 do begin
  398.     for i := 0 to FCols-1 do begin
  399.       arr[j * FCols + i] := arr[j * FCols + i] + Vel[j * FCols + i] * 0.5;
  400. //      arr[j * FCols + i] := MinS(255, MaxS(0, arr[j * FCols + i]));
  401.       if arr[j * FCols + i]>255 then arr[j * FCols + i] := 255;
  402.       if arr[j * FCols + i]<0 then arr[j * FCols + i] := 0;
  403.     end;
  404.   end;
  405. end;
  406. function TMirrorPlaneTesselator.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  407. begin
  408.   Result := (1*SizeOf(FColor) + 4*SizeOf(FWidth)) div 4;
  409.   if Internal then Parameters := @FColor else Parameters := @Color;
  410. end;
  411. function TMirrorPlaneTesselator.SetIndices(IBPTR: Pointer): Integer;
  412. var i, j: Integer;
  413. begin
  414.   TotalPrimitives := 0;
  415.   for j := 0 to FRows-1 do for i := 0 to FCols-1 do begin
  416.     TWordBuffer(IBPTR^)[TotalPrimitives*3+0] :=  j    * (FCols+1) + i;
  417.     TWordBuffer(IBPTR^)[TotalPrimitives*3+1] := (j+1) * (FCols+1) + i;
  418.     TWordBuffer(IBPTR^)[TotalPrimitives*3+2] := (j+1) * (FCols+1) + i+1;
  419.     TWordBuffer(IBPTR^)[TotalPrimitives*3+3] :=  j    * (FCols+1) + i;
  420.     TWordBuffer(IBPTR^)[TotalPrimitives*3+4] := (j+1) * (FCols+1) + i+1;
  421.     TWordBuffer(IBPTR^)[TotalPrimitives*3+5] :=  j    * (FCols+1) + i+1;
  422.     Inc(TotalPrimitives, 2);
  423.   end;
  424.   TesselationStatus[tbIndex].Status := tsTesselated;
  425.   Result  := TotalIndices;
  426.   LastTotalIndices := TotalIndices;
  427. end;
  428. function TMirrorPlaneTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  429. var i, j: Integer;
  430. begin
  431. {  SetVertexDataC(  -FWidth, FHeight, 0, 0, VBPTR);
  432.   SetVertexDataD(FColor, 0, VBPTR);
  433.   SetVertexDataC(  FWidth, FHeight, 0, 1, VBPTR);
  434.   SetVertexDataD(FColor, 1, VBPTR);
  435.   SetVertexDataC(  -FWidth, -FHeight, 0, 2, VBPTR);
  436.   SetVertexDataD(FColor, 2, VBPTR);
  437.   SetVertexDataC(  FWidth, -FHeight, 0, 3, VBPTR);
  438.   SetVertexDataD(FColor, 3, VBPTR);}
  439.   for j := 0 to FRows do for i := 0 to FCols do begin
  440.     SetVertexDataC((0.5 - i / FCols) * FWidth,
  441.                    Arr[j * FCols + i]/250,
  442.                    (0.5 - j / FRows) * FHeight,
  443.                    j * (FCols+1) + i, VBPTR);
  444.     SetVertexDataD(FColor, j * (FCols+1) + i, VBPTR);
  445.     SetVertexDataN(0, 0, -1, j * (FCols+1) + i, VBPTR);
  446.   end;
  447.   TesselationStatus[tbVertex].Status := tsTesselated;
  448.   Result  := TotalVertices;
  449.   IndexingVertices  := TotalVertices;
  450.   LastTotalVertices := TotalVertices;
  451. end;
  452. { TMirrorPlane }
  453. function TMirrorPlane.VisibilityCheck(const Camera: TCamera): Boolean;
  454. var
  455. //  BiasMat,
  456.   Mat: TMatrix4s; Cam: TCamera;
  457. //  Light: TLight;
  458. //  offset: Single; t: Cardinal;
  459. begin
  460.   Result := inherited VisibilityCheck(Camera);
  461.   Exit;
  462.   // Adjust texture matrix
  463. //  Light := FManager.Root.GetChildByPath('Root itemLight1') as TLight;
  464. //  Cam := Light.Childs[0] as TCamera;
  465. //  Cam := TCore(FManager).Renderer.MainCamera;
  466.   Cam := Childs[0] as TCamera;
  467.   Mat := IdentityMatrix4s;
  468. //  Mat := FTransform;
  469. {//  Mat := MulMatrix4s(Mat, InvertAffineMatrix4s(Camera.ViewMatrix));
  470.   Mat := MulMatrix4s(Mat, Cam.ViewMatrix);
  471.   Mat := MulMatrix4s(Mat, Cam.ProjMatrix);}
  472. //    Mat := MulMatrix4s(Mat, InvertAffineMatrix4s(Cam.ViewMatrix));
  473. //    Mat := MulMatrix4s(Mat, Cam.ViewMatrix);
  474.     Mat := MulMatrix4s(Mat, Cam.ProjMatrix);
  475. (*  offset := 0.5 + (0.5 / Cam.RenderTargetWidth);                                 // +Height ?
  476.   t := 1 shl 24-1;
  477.   biasMat._11:=0.5; biasMat._12:=0.0; biasMat._13:=0.0; biasMat._14:=0.0;
  478.   biasMat._21:=0.0; biasMat._22:=-0.5; biasMat._23:=0.0; biasMat._24:=0.0;
  479.   biasMat._31:=0.0; biasMat._32:=0.0; biasMat._33:=1 shl 24-1{Single((@t)^)}; biasMat._34:=0.0;
  480.   biasMat._41:=offset; biasMat._42:=offset; biasMat._43:=5.00400000; biasMat._44:=1.0;
  481.   Mat := MulMatrix4s(Mat, BiasMat);*)
  482.   Mat := MulMatrix4s(Mat, ScaleMatrix4s(0.5, -0.5, 1));
  483.   Mat := MulMatrix4s(Mat, TranslationMatrix4s(0.5, 0.5, 0));
  484.   TexMat := Mat;
  485. end;
  486. constructor TMirrorPlane.Create(AManager: TItemsManager);
  487. begin
  488.   inherited;
  489. end;
  490. function TMirrorPlane.GetTesselatorClass: CTesselator; begin Result := TMirrorPlaneTesselator; end;
  491. procedure TMirrorPlane.AddProperties(const Result: TProperties);
  492. var Tesselator: TMirrorPlaneTesselator;
  493. begin
  494.   inherited;
  495.   if not Assigned(Result) then Exit;
  496.   if not (CurrentTesselator is TMirrorPlaneTesselator) then Exit;
  497.   Tesselator := CurrentTesselator as TMirrorPlaneTesselator;
  498.   AddColorProperty(Result, 'Color', Tesselator.Color);
  499.   Result.Add('GeometryWidth',  vtSingle, [], FloatToStr(Tesselator.Width),  '');
  500.   Result.Add('GeometryHeight', vtSingle, [], FloatToStr(Tesselator.Height), '');
  501.   Result.Add('GeometryRows',   vtInt,    [], IntToStr(Tesselator.Rows),     '');
  502.   Result.Add('GeometryCols',   vtInt,    [], IntToStr(Tesselator.Cols),     '');
  503. end;
  504. procedure TMirrorPlane.SetProperties(Properties: TProperties);
  505. var Tesselator: TMirrorPlaneTesselator;
  506. begin
  507.   inherited;
  508.   if not (CurrentTesselator is TMirrorPlaneTesselator) then Exit;
  509.   Tesselator := CurrentTesselator as TMirrorPlaneTesselator;
  510.   SetColorProperty(Properties, 'Color', Tesselator.Color);
  511.   if Properties.Valid('GeometryWidth')  then Tesselator.Width  := StrToFloatDef(Properties['GeometryWidth'],  1);
  512.   if Properties.Valid('GeometryHeight') then Tesselator.Height := StrToFloatDef(Properties['GeometryHeight'], 1);
  513.   if Properties.Valid('GeometryRows')   then Tesselator.Rows   := StrToIntDef(Properties['GeometryRows'],     1);
  514.   if Properties.Valid('GeometryCols')   then Tesselator.Cols   := StrToIntDef(Properties['GeometryCols'],     1);
  515.   SetMesh;
  516.   RetrieveTextureMatrix := {$IFDEF OBJFPCEnable}@{$ENDIF}RetrieveTexMat;
  517. end;
  518. procedure TMirrorPlane.RetrieveTexMat(TextureStage: Integer; out Mat: TMatrix4s);
  519. begin
  520.   Mat := TexMat;
  521. end;
  522. procedure TMirrorPlane.Process(const DeltaTime: Single);
  523. begin
  524.   inherited;
  525.   (CurrentTesselator as TMirrorPlaneTesselator).Iterate;
  526. end;
  527. { TCircleTesselator }
  528. constructor TCircleTesselator.Create;
  529. begin
  530.   inherited;
  531.   PrimitiveType := ptTRIANGLEFAN;
  532.   InitVertexFormat(GetVertexFormat(False, False, True, False, False, 0, [2]));
  533.   CenterColor.C := $80808080;
  534.   SideColor.C   := $80808080;
  535.   Sectors       := 6;
  536.   Radius        := 1;
  537.   Init;
  538. end;
  539. procedure TCircleTesselator.Init;
  540. begin
  541.   inherited;
  542.   Invalidate([tbVertex, tbIndex], TotalPrimitives <> FSectors);
  543.   TotalVertices   := 1+FSectors+1;
  544.   TotalPrimitives := FSectors;  
  545. end;
  546. function TCircleTesselator.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  547. begin
  548.   Result := (2*SizeOf(Longword) + 1*SizeOf(Integer) + 1*SizeOf(Single)) div 4;
  549.   if Internal then Parameters := @FCenterColor else Parameters := @CenterColor;
  550. end;
  551. function TCircleTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  552. var i: Integer;
  553. begin
  554.   SetVertexDataC(0, 0, 0, 0, VBPTR);
  555.   SetVertexDataUV(0.5, 0.5, 0, VBPTR);
  556.   SetVertexDataD(FCenterColor, 0, VBPTR);
  557.   for i := 0 to FSectors do begin
  558.     SetVertexDataC(FRadius*Cos(i/FSectors*2*pi), 0, FRadius*Sin(i/FSectors*2*pi), i+1, VBPTR);
  559.     SetVertexDataUV(0.5 + 0.5*Cos(i/FSectors*2*pi*1), 0.5 + 0.5*Sin(i/FSectors*2*pi*1), i+1, VBPTR);
  560.     SetVertexDataD(FSideColor, i+1, VBPTR);
  561.   end;
  562.   TesselationStatus[tbVertex].Status := tsTesselated;
  563.   Result            := TotalVertices;
  564.   LastTotalVertices := TotalVertices;
  565. end;
  566. function TCircleTesselator.GetBoundingBox: TBoundingBox;
  567. begin
  568.   Result.P1 := GetVector3s(-Radius, 0, -Radius);
  569.   Result.P2 := GetVector3s( Radius, 0,  Radius);
  570. end;
  571. { TCircle }
  572. function TCircle.GetTesselatorClass: CTesselator; begin Result := TCircleTesselator; end;
  573. procedure TCircle.AddProperties(const Result: Props.TProperties);
  574. var Tesselator: TCircleTesselator;
  575. begin
  576.   inherited;
  577.   if not Assigned(Result) then Exit;
  578.   AddColorProperty(Result, 'ColorCenter', CenterColor);
  579.   AddColorProperty(Result, 'ColorSide',   SideColor);
  580.   Result.Add('TextureScale U', vtSingle, [], FloatToStr(TexScaleU), '');
  581.   Result.Add('TextureScale V', vtSingle, [], FloatToStr(TexScaleV), '');
  582.   Result.Add('TextureMove U',  vtSingle, [], FloatToStr(TexMoveU),  '');
  583.   Result.Add('TextureMove V',  vtSingle, [], FloatToStr(TexMoveV),  '');
  584.   if not (CurrentTesselator is TCircleTesselator) then Exit;
  585.   Tesselator := CurrentTesselator as TCircleTesselator;
  586.   Result.Add('GeometryRadius',  vtSingle, [], FloatToStr(Tesselator.Radius), '');
  587.   Result.Add('GeometrySectors', vtInt,    [], IntToStr(Tesselator.Sectors), '');
  588. end;
  589. procedure TCircle.SetProperties(Properties: Props.TProperties);
  590. var Tesselator: TCircleTesselator; C: BaseTypes.TColor;
  591. begin
  592.   inherited;
  593.   C := CenterColor;
  594.   SetColorProperty(Properties, 'ColorCenter', C);
  595.   CenterColor := C;
  596.   C := SideColor;
  597.   SetColorProperty(Properties, 'ColorSide',   C);
  598.   SideColor := C;
  599.   if Properties.Valid('TextureScale U') then TexScaleU := StrToFloatDef(Properties['TextureScale U'], 1.00);
  600.   if Properties.Valid('TextureScale V') then TexScaleV := StrToFloatDef(Properties['TextureScale V'], 1.00);
  601.   if Properties.Valid('TextureMove U')  then TexMoveU  := StrToFloatDef(Properties['TextureMove U'],  0.01);
  602.   if Properties.Valid('TextureMove V')  then TexMoveV  := StrToFloatDef(Properties['TextureMove V'],  0.00);
  603.   if not (CurrentTesselator is TCircleTesselator) then Exit;
  604.   Tesselator := CurrentTesselator as TCircleTesselator;
  605.   if Properties.Valid('GeometryRadius')  then Tesselator.Radius  := StrToFloatDef(Properties['GeometryRadius'], 1);
  606.   if Properties.Valid('GeometrySectors') then Tesselator.Sectors := StrToIntDef(Properties['GeometrySectors'], 6);
  607.   SetMesh;
  608. end;
  609. procedure TCircle.Process(const DeltaT: Float);
  610. begin
  611.   inherited;
  612. {  Mesh.UOfs := BasicUOfs + CurUOfs;
  613.   CurUOfs := CurUOfs + Mesh.UShift;
  614.   if Mesh.UOfs > 2 then CurUOfs := CurUOfs-2;
  615.   Mesh.VOfs := BasicVOfs + CurVOfs;
  616.   CurVOfs := CurVOfs + Mesh.VShift;
  617.   if Mesh.VOfs > 2 then CurVOfs := CurVOfs-2;}
  618. end;
  619. function TCircle.GetCenterColor: BaseTypes.TColor;
  620. begin
  621.   if CurrentTesselator is TCircleTesselator then
  622.    Result := TCircleTesselator(CurrentTesselator).CenterColor else
  623.     Result.C := 0;
  624. end;
  625. function TCircle.GetSideColor: BaseTypes.TColor;
  626. begin
  627.   if CurrentTesselator is TCircleTesselator then
  628.    Result := TCircleTesselator(CurrentTesselator).SideColor else
  629.     Result.C := 0;
  630. end;
  631. procedure TCircle.SetCenterColor(const Value: BaseTypes.TColor);
  632. begin
  633.   if not (CurrentTesselator is TCircleTesselator) then Exit;
  634.   TCircleTesselator(CurrentTesselator).CenterColor := Value;
  635.   CurrentTesselator.Invalidate([tbVertex], False);
  636. end;
  637. procedure TCircle.SetSideColor(const Value: BaseTypes.TColor);
  638. begin
  639.   if not (CurrentTesselator is TCircleTesselator) then Exit;
  640.   TCircleTesselator(CurrentTesselator).SideColor := Value;
  641.   CurrentTesselator.Invalidate([tbVertex], False);
  642. end;
  643. { TDomeTesselator }
  644. constructor TDomeTesselator.Create;
  645. begin
  646.   inherited;
  647. //  PrimitiveType    := ptTRIANGLESTRIP;
  648.   InitVertexFormat(GetVertexFormat(False, False, True, False, False, 0, [2]));
  649.   Sectors  := 8;
  650.   Segments := 4;
  651.   Radius   := 1;
  652.   Height   := 1;
  653.   TexScale := 1;
  654.   Color.C  := $FF808080;
  655.   SkyMap   := nil;
  656.   Init;
  657.   SMWidth  := 0;
  658.   SMHeight := 0;
  659. end;
  660. procedure TDomeTesselator.Init;
  661. begin
  662.   inherited;
  663.   Invalidate([tbVertex, tbIndex], TotalVertices <> (FSegments+1) * (FSectors+1));
  664.   TotalVertices    := (FSegments+1) * (FSectors+1);
  665.   TotalIndices     := (FSegments  ) * (FSectors  )*2*3;
  666.   TotalPrimitives  := (FSegments  ) * (FSectors  )*2+0*2*(FSegments-1);
  667.   IndexingVertices := TotalVertices;
  668. end;
  669. function TDomeTesselator.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  670. begin
  671.   Result := (1*SizeOf(Longword) + 2*SizeOf(Integer) + 3*SizeOf(Single) + 1*SizeOf(Pointer)) div 4;
  672.   if Internal then Parameters := @FSectors else Parameters := @Sectors;
  673. end;
  674. function TDomeTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  675. var i, j, si, sj, SMXI, SMYI: Integer; U, V, SMYO: Single;
  676. begin
  677.   Result := 0;
  678.   if FSegments = 0 then Exit;
  679.   for j := 0 to FSegments do for i := 0 to FSectors do begin
  680. //    X := Radius*Cos(i/Sectors*2*pi)*Cos(j/(Segments)*pi/2);
  681.     si := i*(SinTableSize) div FSectors;
  682.     sj := j*(SinTableSize) div FSegments shr 2;
  683.     SetVertexDataC(FRadius*SinTable[si+CosTabOffs]*SinTable[sj+CosTabOffs],
  684.                    SinTable[sj] * FHeight,
  685.                    FRadius*SinTable[si] * SinTable[sj + CosTabOffs],
  686.                    j*(FSectors+1)+i, VBPTR);
  687.     U := 0.5 + 0.5*(FSegments-j)/FSegments*SinTable[si + CosTabOffs];
  688.     V := 0.5 + 0.5*(FSegments-j)/FSegments*SinTable[si];
  689.     SetVertexDataUV(U * FTexScale, V * FTexScale, j*(FSectors+1)+i, VBPTR);
  690.     if FSkyMap <> nil then begin
  691.       SMXI := Trunc(U * (SMWidth-1));
  692.       SMYI := Trunc(V * (SMHeight-1));
  693.       SMYO := Frac(V * (SMHeight-1));
  694.       SetVertexDataD(BlendColor(BlendColor(FSkyMap^[SMYI*SMWidth+SMXI], FSkyMap^[((SMYI+1) and (SMHeight-1))*SMWidth+SMXI], SMYO),
  695.                                 BlendColor(FSkyMap^[SMYI*SMWidth+(SMXI+1) and (SMWidth-1)], FSkyMap^[((SMYI+1) and (SMHeight-1))*SMWidth+(SMXI+1) and (SMWidth-1)], SMYO),
  696.                                 Frac (U * (SMWidth-1))), j*(FSectors+1)+i, VBPTR);
  697.     end else SetVertexDataD(FColor, j*(FSectors+1)+i, VBPTR);
  698.   end;
  699.   TesselationStatus[tbVertex].Status := tsTesselated;
  700.   Result            := TotalVertices;
  701.   LastTotalVertices := TotalVertices;
  702. end;
  703. function TDomeTesselator.SetIndices(IBPTR: Pointer): Integer;
  704. var i, j: Integer;
  705. begin
  706.   for j := 0 to FSegments-1 do begin
  707.     for i := 0 to FSectors-1 do begin
  708.       TWordBuffer(IBPTR^)[(j*(FSectors+0)+i)*6+0] := (j+0)*(FSectors+1)+i;
  709.       TWordBuffer(IBPTR^)[(j*(FSectors+0)+i)*6+1] := (j+1)*(FSectors+1)+i;
  710.       TWordBuffer(IBPTR^)[(j*(FSectors+0)+i)*6+2] := (j+0)*(FSectors+1)+i+1;
  711.       TWordBuffer(IBPTR^)[(j*(FSectors+0)+i)*6+3] := (j+1)*(FSectors+1)+i;
  712.       TWordBuffer(IBPTR^)[(j*(FSectors+0)+i)*6+4] := (j+1)*(FSectors+1)+i+1;
  713.       TWordBuffer(IBPTR^)[(j*(FSectors+0)+i)*6+5] := (j+0)*(FSectors+1)+i+1
  714.     end;
  715.   end;
  716.   TesselationStatus[tbIndex].Status := tsTesselated;
  717.   Result  := TotalIndices;
  718. end;
  719. function TDomeTesselator.GetBoundingBox: TBoundingBox;
  720. begin
  721.   Result.P1 := GetVector3s(-Radius, 0,      -Radius);
  722.   Result.P2 := GetVector3s( Radius, Height,  Radius);
  723. end;
  724. { TDome }
  725. procedure TDome.AddProperties(const Result: Props.TProperties);
  726. var Tesselator: TDomeTesselator;
  727. begin
  728.   inherited;
  729.   if not Assigned(Result) then Exit;
  730.   if not (CurrentTesselator is TDomeTesselator) then Exit;
  731.   Tesselator := CurrentTesselator as TDomeTesselator;
  732.   AddColorProperty(Result, 'Color', Tesselator.Color);
  733.   Result.Add('GeometrySectors',       vtInt,    [],       IntToStr(Tesselator.Sectors),   '3-256');
  734.   Result.Add('GeometrySegments',      vtInt,    [],       IntToStr(Tesselator.Segments),  '1-16');
  735.   Result.Add('GeometryRadius',        vtSingle, [],       FloatToStr(Tesselator.Radius),   '');
  736.   Result.Add('GeometryHeight',        vtSingle, [],       FloatToStr(Tesselator.Height),   '');
  737.   Result.Add('TextureScale',          vtSingle, [],       FloatToStr(Tesselator.TexScale), '');
  738. end;
  739. function TDome.GetTesselatorClass: CTesselator; begin Result := TDomeTesselator; end;
  740. procedure TDome.SetProperties(Properties: Props.TProperties);
  741. var Tesselator: TDomeTesselator;
  742. begin
  743.   inherited;
  744.   if not (CurrentTesselator is TDomeTesselator) then Exit;
  745.   Tesselator := CurrentTesselator as TDomeTesselator;
  746.   SetColorProperty(Properties, 'Color', Tesselator.Color);
  747.   if Properties.Valid('GeometrySectors')  then Tesselator.Sectors  := StrToIntDef(Properties['GeometrySectors'],        8);
  748.   if Properties.Valid('GeometrySegments') then Tesselator.Segments := StrToIntDef(Properties['GeometrySegments'],       4);
  749.   if Properties.Valid('GeometryRadius')   then Tesselator.Radius   := StrToFloatDef(Properties['GeometryRadius'],        1);
  750.   if Properties.Valid('GeometryHeight')   then Tesselator.Height   := StrToFloatDef(Properties['GeometryHeight'],        1);
  751.   if Properties.Valid('TextureScale')     then Tesselator.TexScale := StrToFloatDef(Properties['TextureScale'],          1);
  752.   SetMesh;
  753. end;
  754. { TSky }
  755. procedure TSky.ResolveLinks;
  756. var Tesselator: TDomeTesselator; SMRes: TItem;
  757. begin
  758.   if not (CurrentTesselator is TDomeTesselator) then Exit;
  759.   Tesselator := CurrentTesselator as TDomeTesselator;
  760.   if ResolveLink('ColorSky map', SMRes) then begin
  761.     Tesselator.SkyMap   := (SMRes as TImageResource).Data;
  762.     Tesselator.SMWidth  := (SMRes as TImageResource).Width;
  763.     Tesselator.SMHeight := (SMRes as TImageResource).Height;
  764.     SetMesh;
  765.   end;
  766.   if SMRes = nil then Tesselator.SkyMap := nil;
  767. end;
  768. procedure TSky.AddProperties(const Result: Props.TProperties);
  769. begin
  770.   inherited;
  771.   AddItemLink(Result, 'ColorSky map', [], 'TImageResource');
  772. end;
  773. procedure TSky.SetProperties(Properties: Props.TProperties);
  774. begin
  775.   inherited;
  776.   if Properties.Valid('ColorSky map') then SetLinkProperty('ColorSky map', Properties['ColorSky map']);
  777.   ResolveLinks;
  778.   SetMesh;
  779. end;
  780. { TMesh }
  781. function TMesh.GetTesselatorClass: CTesselator; begin Result := TMeshTesselator end;
  782. procedure TMesh.OnSceneLoaded;
  783. begin
  784.   inherited;
  785.   SetMesh;
  786. end;
  787. procedure TMesh.SetMesh;
  788. var Tesselator: TMeshTesselator;
  789.   procedure ResetMesh;
  790.   begin
  791.     Tesselator.Vertices         := nil;
  792.     Tesselator.NumberOfVertices := 0;
  793.     Tesselator.Indices          := nil;
  794.     Tesselator.NumberOfIndices  := 0;
  795.   end;
  796. begin
  797.   if (CurrentTesselator is TMeshTesselator) then begin
  798.     Tesselator := CurrentTesselator as TMeshTesselator;
  799.     ResetMesh;
  800.     if Vertices <> nil then begin
  801.       if (Integer(GetVertexSize(Vertices.Format)) * Vertices.TotalElements = Vertices.DataSize) then begin   // Simple validity check
  802.         Tesselator.Vertices         := Vertices.Data;
  803.         Tesselator.VertexFormat     := Vertices.Format;
  804.         Tesselator.NumberOfVertices := Vertices.TotalElements;
  805.       end else Log.Log('TMesh("' + Name + '").SetMesh: Invalid vertices resource "' + Vertices.Name + '"', lkError);
  806.     end;
  807.     if Indices <> nil then begin
  808.       Tesselator.Indices         := Indices.Data;
  809.       Tesselator.NumberOfIndices := Indices.TotalElements;
  810.     end;
  811. (*    if not Tesselator.Validate then begin
  812.       ResetMesh;
  813.       Log.Log(Format('%S("%S").%S: The mesh did not pass validation', [ClassName, Name, 'ResetIndices']), lkError); 
  814.     end;*)
  815.   end;
  816.   inherited;
  817. end;
  818. procedure TMesh.AddProperties(const Result: Props.TProperties);
  819. begin
  820.   inherited;
  821.   AddItemLink(Result, 'GeometryVertices', [], 'TVerticesResource');
  822.   AddItemLink(Result, 'GeometryIndices',  [], 'TIndicesResource');
  823. end;
  824. procedure TMesh.SetProperties(Properties: Props.TProperties);
  825. begin
  826.   inherited;
  827.   if Properties.Valid('GeometryVertices') then SetLinkProperty('GeometryVertices', Properties['GeometryVertices']);
  828.   if Properties.Valid('GeometryIndices')  then SetLinkProperty('GeometryIndices',  Properties['GeometryIndices']);
  829.   SetMesh;
  830. end;
  831. function TMesh.GetVerticesRes: TVerticesResource;
  832. var Item: TItem;
  833. begin
  834.   if ResolveLink('GeometryVertices', Item) then
  835.     Result := Item as TVerticesResource else
  836.       if Item is TVerticesResource then
  837.         Result := Item as TVerticesResource else
  838.           Result := nil;
  839. end;
  840. function TMesh.GetIndicesRes: TIndicesResource;
  841. var Item: TItem;
  842. begin
  843.   if ResolveLink('GeometryIndices', Item) then
  844.     Result := Item as TIndicesResource else
  845.       if Item is TIndicesResource then
  846.         Result := Item as TIndicesResource else
  847.           Result := nil;
  848. end;
  849. procedure TMesh.HandleMessage(const Msg: TMessage);
  850. begin
  851.   inherited;
  852.   if Msg.ClassType = TDataAdressChangeMsg then
  853.     with TDataAdressChangeMsg(Msg) do SetMesh;
  854. end;
  855. { TRingMesh }
  856. const uvtPlanar = 0; uvtRadial = 1;    // Ring UV mapping types
  857. constructor TRingMesh.Create;
  858. begin
  859.   inherited;
  860.   PrimitiveType := ptTRIANGLESTRIP;
  861.   InitVertexFormat(GetVertexFormat(False, False, True, False, False, 0, [2]));
  862.   InnerRadius := 0.8;
  863.   OuterRadius := 1;
  864.   Factor      := 0.5;
  865.   Smoothing   := 8;
  866.   Color1.C    := $80FF0000;
  867.   Color2.C    := $800000FF;
  868.   UVMapType   := uvtPlanar;
  869.   UVFrame.U := 0; UVFrame.V := 0; UVFrame.W := 1; UVFrame.H := 1;
  870.   Init;
  871. end;
  872. procedure TRingMesh.Init;
  873. begin
  874.   inherited;
  875.   Invalidate([tbVertex, tbIndex], TotalVertices <> (Smoothing+1)*2);
  876.   TotalVertices   := (Smoothing+1)*2;
  877.   TotalIndices    := 0;
  878.   TotalPrimitives := Smoothing*2;
  879.   IndexingVertices := TotalVertices;
  880. end;
  881. function TRingMesh.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  882. begin
  883.   Result := (3*SizeOf(Longword) + 1*SizeOf(Integer) + 3*SizeOf(Single)) div 4;
  884.   if Internal then Parameters := @FInnerRadius else Parameters := @InnerRadius;
  885. end;
  886. function TRingMesh.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  887. var i: Integer; t, t1, t2, w, oos, sw, f: Single; Col: BaseTypes.TColor;
  888. begin
  889.   oos := 1/FSmoothing;
  890.   if FFactor < 1 then begin
  891.     sw := 1 - FFactor;
  892.     f  := 1 / FFactor;
  893.   end else begin
  894.     sw := 0;
  895.     f  := FFactor;
  896.   end;
  897.   if Abs(FOuterRadius) > Epsilon then t := 0.5 / FOuterRadius else t := 0;
  898.   for i := 0 to Smoothing do begin              // Outer edge
  899. //    w := Abs(Smoothing*0.5 - i)*2*oos * Factor;
  900.     w := (Abs(FSmoothing*0.5 - i)*2*oos  - sw) * f;
  901.     Col := BlendColor(FColor2, FColor1, w);
  902. //   c1 --------- c2 --------- c1
  903.     t1 := Cos(i/180*pi*360*oos); t2 := Sin(i/180*pi*360*oos);
  904.     SetVertexDataC(t1*FOuterRadius, 0, t2*FOuterRadius, i*2, VBPTR);
  905.     SetVertexDataD(Col, i*2, VBPTR);
  906.     SetVertexDataC(t1*FInnerRadius, 0, t2*FInnerRadius, i*2+1, VBPTR);
  907.     SetVertexDataD(Col, i*2+1, VBPTR);
  908.     if FUVMapType = uvtPlanar then begin
  909.       SetVertexDataUV(UVFrame.U + (i * oos) * UVFrame.W, UVFrame.V, i*2, VBPTR);
  910.       SetVertexDataUV(UVFrame.U + (i * oos) * UVFrame.W, UVFrame.V + UVFrame.H, i*2+1, VBPTR);
  911.     end else begin
  912.       SetVertexDataUV(0.5 + t1 * FOuterRadius * t, 0.5 - t2 * FOuterRadius * t, i*2, VBPTR);
  913.       SetVertexDataUV(0.5 + t1 * FInnerRadius * t, 0.5 - t2 * FInnerRadius * t, i*2+1, VBPTR);
  914.     end;
  915.   end;
  916.   TesselationStatus[tbVertex].Status := tsTesselated;
  917.   Result := TotalVertices;
  918.   LastTotalVertices := TotalVertices;
  919. end;
  920. function TRingMesh.GetBoundingBox: TBoundingBox;
  921. begin
  922.   Result.P1 := GetVector3s(-OuterRadius, 0, -OuterRadius);
  923.   Result.P2 := GetVector3s( OuterRadius, 0,  OuterRadius);
  924. end;
  925. { TRing }
  926. function TRing.GetTesselatorClass: CTesselator; begin Result := TRingMesh; end;
  927. constructor TRing.Create(AManager: TItemsManager);
  928. begin
  929.   inherited;
  930.   YAngle := 0+pi/4;
  931. end;
  932. procedure TRing.AddProperties(const Result: Props.TProperties);
  933. var Mesh: TRingMesh;
  934. begin
  935.   inherited;
  936.   if not Assigned(Result) or not (CurrentTesselator is TRingMesh) then Exit;
  937.   Mesh := CurrentTesselator as TRingMesh;
  938.   AddColorProperty(Result, 'Color1', Mesh.Color1);
  939.   AddColorProperty(Result, 'Color2', Mesh.Color2);
  940.   Result.Add('ColorFactor',          vtSingle, [], FloatToStr(Mesh.Factor),        '0-1');
  941.   Result.Add('GeometrySmoothing',    vtInt,    [], IntToStr(Mesh.Smoothing),       '3-32');
  942.   Result.Add('GeometryInner radius', vtSingle, [], FloatToStr(Mesh.InnerRadius),   '');
  943.   Result.Add('GeometryOuter radius', vtSingle, [], FloatToStr(Mesh.OuterRadius),   '');
  944.   Result.AddEnumerated('TextureMap type',  [], Mesh.UVMapType, 'Planar&Radial');
  945. end;
  946. procedure TRing.SetProperties(Properties: Props.TProperties);
  947. var Mesh: TRingMesh;
  948. begin
  949.   inherited;
  950.   if not (CurrentTesselator is TRingMesh) then Exit;
  951.   Mesh := CurrentTesselator as TRingMesh;
  952.   SetColorProperty(Properties, 'Color1', Mesh.Color1);
  953.   SetColorProperty(Properties, 'Color2', Mesh.Color2);
  954.   if Properties.Valid('ColorFactor')          then Mesh.Factor      := StrToFloatDef(Properties['ColorFactor'],          0);
  955.   if Properties.Valid('GeometrySmoothing')    then Mesh.Smoothing   := StrToIntDef(Properties['GeometrySmoothing'],     0);
  956.   if Properties.Valid('GeometryInner radius') then Mesh.InnerRadius := StrToFloatDef(Properties['GeometryInner radius'], 0);
  957.   if Properties.Valid('GeometryOuter radius') then Mesh.OuterRadius := StrToFloatDef(Properties['GeometryOuter radius'], 0);
  958.   if Properties.Valid('TextureMap type')      then Mesh.UVMapType   := Properties.GetAsInteger('TextureMap type');
  959.   SetMesh;
  960. end;
  961. function TRing.GetColor: BaseTypes.TColor;
  962. begin
  963.   Result := TRingMesh(CurrentTesselator).Color1;
  964. end;
  965. procedure TRing.SetColor(const Value: BaseTypes.TColor);
  966. var Mesh: TRingMesh;
  967. begin
  968.   if CurrentTesselator is TRingMesh then Mesh := CurrentTesselator as TRingMesh else Exit;
  969.   Mesh.Color1 := Value;
  970.   SetMesh;
  971. end;
  972. function TRing.VisibilityCheck(const Camera: TCamera): Boolean;
  973. var CameraForward, Axis: TVector3s; Angle: Single;
  974. begin
  975.   Result := inherited VisibilityCheck(Camera);
  976.   CameraForward := Transform3Vector3s(GetTransposedMatrix3s(CutMatrix3s(Camera.ViewMatrix)), GetVector3s(0, 0, 1));
  977.   Axis := NormalizeVector3s(CrossProductVector3s(CameraForward, GetVector3s(0, 1, 0)));
  978. //  Axis := Transform3Vector3s({TransposeMatrix3s(}CutMatrix3s(Transform), Axis);
  979.   Angle := ArcTan2(-sqrt(Sqr(CameraForward.X) + Sqr(CameraForward.Z)), -CameraForward.Y);
  980.   Orientation := MulQuaternion(GetQuaternion(-Angle, Axis), GetQuaternion(YAngle, GetVector3s(0, 1, 0)));
  981. end;
  982. begin
  983.   GlobalClassList.Add('C2VisItems', GetUnitClassList);
  984. end.