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

游戏引擎

开发平台:

Delphi

  1. (*
  2.  @Abstract(CAST II Engine special effects 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 item and tesselator classes for basic special effects
  6. *)
  7. {$Include GDefines.inc}
  8. {$Include C2Defines.inc}
  9. unit C2FX;
  10. interface
  11. uses SysUtils, BaseTypes, Basics, BaseCont, Base3D, Props, BaseClasses, C2Types, CAST2, C2Visual, Resources;
  12. const
  13.   // Fade states
  14.   fsNone = 0; fsFadeIn = 1; fsFadeOut = 2;
  15. type
  16.   T3DLineMesh = class(TTesselator)
  17.     Size1, Size2, Len, VScale: Single;
  18.     Color1, Color2: BaseTypes.TColor;
  19.     constructor Create; override;
  20.     procedure Init; override;
  21.     function RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer; override;
  22.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  23.   protected
  24.     Point1, Point2: TVector4s;
  25.     ModelMatrix: ^TMatrix4s;
  26.     FSize1, FSize2, FLen, FVScale: Single;
  27.     FColor1, FColor2: BaseTypes.TColor;
  28.   end;
  29.   T3DLine = class(TVisible)
  30.     function GetTesselatorClass: CTesselator; override;
  31.     procedure AddProperties(const Result: Props.TProperties); override;
  32.     procedure SetProperties(Properties: Props.TProperties); override;
  33.   protected
  34.     function GetColor1: BaseTypes.TColor;
  35.     procedure SetColor1(const Value: BaseTypes.TColor);
  36.     function GetColor2: BaseTypes.TColor;
  37.     procedure SetColor2(const Value: BaseTypes.TColor);
  38.     function GetLength: Single;
  39.     procedure SetLength(const Value: Single);
  40.   public
  41.     constructor Create(AManager: TItemsManager); override;
  42.     function VisibilityCheck(const Camera: TCamera): Boolean; override;
  43.     property Color1: BaseTypes.TColor read GetColor1 write SetColor1;
  44.     property Color2: BaseTypes.TColor read GetColor2 write SetColor2;
  45.     property Len: Single read GetLength write SetLength;
  46.   end;
  47.   TBackgroundTesselator = class(TTesselator)
  48.   protected
  49.     Cols, Rows: Integer;
  50.   public
  51.     Zoom, UOfs, VOfs: Single;
  52.     Angle: Integer;
  53.     Color: BaseTypes.TColor;
  54.     constructor Create; override;
  55.     function IsSameItem(AItem: TReferencedItem): Boolean; override;
  56.     procedure Init; override;
  57.     procedure AddProperties(const Result: Props.TProperties; const PropNamePrefix: TNameString); override;
  58.     procedure SetProperties(Properties: Props.TProperties; const PropNamePrefix: TNameString); override;
  59.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  60.     function SetIndices(IBPTR: Pointer): Integer; override;
  61.   end;
  62.   // Shows a full-screen quad with color depending on processing time.
  63.   // If AutoStop is True processing automatically stops when it reaches half of specified gradient.
  64.   TFader = class(TVisible)
  65.   private
  66.     AutoStopNeeded: Boolean;
  67.     procedure SetColor(const Value: TColor);
  68.   public
  69.     // Color gradient
  70.     Colors: TSampledGradient;
  71.     // Stop at half (probably when full visible) 
  72.     AutoStop: Boolean;
  73.     constructor Create(AManager: TItemsManager); override;
  74.     destructor Destroy; override;
  75.     
  76.     function VisibilityCheck(const Camera: TCamera): Boolean; override;
  77.     function GetTesselatorClass: CTesselator; override;
  78.     procedure Show; override;
  79.     procedure Process(const DeltaT: Single); override;
  80.     procedure AddProperties(const Result: Props.TProperties); override;
  81.     procedure SetProperties(Properties: Props.TProperties); override;
  82.   end;
  83.   TBackground = class(TVisible)
  84.   protected
  85.     function GetAngle: Integer;
  86.     function GetColor: BaseTypes.TColor;
  87.     function GetZoom: Single;
  88.     procedure SetColor(const Value: BaseTypes.TColor);
  89.     procedure SetAngle(const Value: Integer);
  90.     procedure SetZoom(const Value: Single);
  91.   public
  92.     constructor Create(AManager: TItemsManager); override;
  93.     function VisibilityCheck(const Camera: TCamera): Boolean; override;
  94.     function GetTesselatorClass: CTesselator; override;
  95.     procedure AddProperties(const Result: Props.TProperties); override;
  96.     procedure SetProperties(Properties: Props.TProperties); override;
  97.     property Angle: Integer read GetAngle write SetAngle;
  98.     property Zoom: Single read GetZoom write SetZoom;
  99.   end;
  100.   TBillboardMesh = class(TTesselator)
  101.     MaxFrame: Integer;
  102.     UVMap: TUVMap;
  103.     constructor Create; override;
  104.     procedure AddProperties(const Result: Props.TProperties; const PropNamePrefix: TNameString); override;
  105.     procedure SetProperties(Properties: Props.TProperties; const PropNamePrefix: TNameString); override;
  106.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  107.     procedure SetFrame(const Value: Integer); virtual;
  108.     protected
  109.       FColor: TColor;
  110.       FWidth, FHeight: Single;
  111.       FFrame: Integer;
  112.     public
  113.       property Frame: Integer read FFrame write SetFrame;
  114.   end;
  115.   TBillboard = class(TVisible)
  116.   protected
  117.     AnimTime: Single;
  118.   public
  119.     AnimRate: Single;
  120.     AnimRepeat, HideAtEnd: Boolean;
  121.     constructor Create(AManager: TItemsManager); override;
  122.     function VisibilityCheck(const Camera: TCamera): Boolean; override;
  123.     function GetTesselatorClass: CTesselator; override;
  124.     procedure ResolveLinks; override;
  125.     procedure Process(const DeltaT: Single); override;
  126.     procedure AddProperties(const Result: Props.TProperties); override;
  127.     procedure SetProperties(Properties: Props.TProperties); override;
  128.   end;
  129.   TSplashTesselator = class(TTesselator)
  130.   private
  131.   public
  132.     Color: TColor;
  133.     Size: Single;
  134.     constructor Create; override;
  135.     function IsSameItem(AItem: TReferencedItem): Boolean; override;
  136.     function GetBoundingBox: TBoundingBox; override;
  137.     function Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer; override;
  138.   end;
  139.   TSplash = class(TVisible)
  140.   public
  141.     Color: TSampledGradient;
  142.     Size: TSampledFloats;
  143.     constructor Create(AManager: TItemsManager); override;
  144.     destructor Destroy; override;
  145.     function GetTesselatorClass: CTesselator; override;
  146.     procedure AddProperties(const Result: Props.TProperties); override;
  147.     procedure SetProperties(Properties: Props.TProperties); override;
  148.     procedure Process(const DeltaT: Single); override;
  149.   end;
  150.   // Returns list of classes introduced by the unit
  151.   function GetUnitClassList: TClassArray;
  152. implementation
  153. function GetUnitClassList: TClassArray;
  154. begin
  155.   Result := GetClassList([T3DLine, TFader, TBackground, TBillboard, TSplash]);
  156. end;
  157. { T3DLineTesselator }
  158. constructor T3DLineMesh.Create;
  159. begin
  160.   inherited;
  161.   Len      := 1;
  162.   Color1.C := $80808080;
  163.   Color2.C := $80808080;
  164.   Size1    := 0.05;  Size2 := 0.05;
  165.   VScale   := 1;
  166.   Init;
  167.   PrimitiveType := ptTRIANGLEFAN;
  168.   InitVertexFormat(GetVertexFormat(False, False, True, False, False, 0, [2]));
  169.   TotalVertices   := 6;
  170.   TotalPrimitives := 4;
  171. end;
  172. procedure T3DLineMesh.Init;
  173. begin
  174.   inherited;
  175.   Point1 := GetVector4s(0, 0, 0, 1); Point2 := GetVector4s(0, 0, FLen, 1);
  176. end;
  177. function T3DLineMesh.RetrieveParameters(out Parameters: Pointer; Internal: Boolean): Integer;
  178. begin
  179.   Result := 6;
  180.   if Internal then Parameters := @FSize1 else Parameters := @Size1;
  181. end;
  182. function T3DLineMesh.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  183. var
  184.   Trans1, Trans2: TVector4s;
  185.   V, N, Cam: TVector3s;
  186.   l, d, e: Single;
  187. begin
  188. //  Cam := CutVector3s(Transform4Vector4s(ModelMatrix^, ExpandVector3s(Camera.Position)));
  189. //  Cam := GetVector3s(Params.Camera.Location.X, Camera.Location.Y, Camera.Location.Z);
  190.   Cam := Params.Camera.GetAbsLocation;
  191. //  Cam := ScaleVector3s(Camera.ViewOrigin, -1);
  192. //  Cam := ScaleVector3s( Transform3Vector3s(InvertMatrix3s(CutMatrix3s(Params.Camera.ViewMatrix)), Params.Camera.ViewOrigin), -1);
  193.   Trans1 := Transform4Vector4s(ModelMatrix^, Point1);
  194.   Trans2 := Transform4Vector4s(ModelMatrix^, Point2);
  195. //  Trans1 := CutVector3s(Point1); Trans2 := CutVector3s(Point2);
  196.   N := SubVector4s(Trans2, Trans1).XYZ;                                   // Line vector in world
  197.   V := GetVector3s(- Trans1.X + Cam.X, - Trans1.Y + Cam.Y, - Trans1.Z + Cam.Z);    // From Point1 to camera
  198. {  W := N;
  199.   d := DotProductVector3s(N, V);                                                   // V projected to N
  200.   e := DotProductVector3s(N, W);
  201.   I := AddVector3s(Trans1.XYZ, ScaleVector3s(W, d/e));
  202.   N := CrossProductVector3s(GetVector3s(I.X - Cam.X, I.Y - Cam.Y, I.Z - Cam.Z), N);}
  203.   N := CrossProductVector3s(V, N);
  204.   N := Transform3Vector3s(InvertMatrix3s(CutMatrix3s(ModelMatrix^)), N);
  205.   l := InvSqrt(SqrMagnitude(N));
  206. //  N := GetVector3s(1, 0, 0); l := 1;
  207. //  1           2
  208. //        0
  209. //  4           3
  210.   SetVertexDataC((Point1.X + Point2.X) * 0.5, (Point1.Y + Point2.Y) * 0.5, (Point1.Z + Point2.Z) * 0.5, 0, VBPtr);
  211.   SetVertexDataD(BlendColor(FColor1, FColor2, 0.5), 0, VBPtr);
  212.   SetVertexDataUV(0.5, FVScale * 0.5, 0, VBPtr);
  213.   SetVertexDataC(Point1.X - N.X * l * FSize1, Point1.Y - N.Y * l * FSize1, Point1.Z - N.Z * l * FSize1, 1, VBPtr);
  214.   SetVertexDataD(FColor1, 1, VBPtr);
  215.   SetVertexDataUV(0, FVScale, 1, VBPtr);
  216.   SetVertexDataC(Point2.X - N.X * l * FSize2, Point2.Y - N.Y * l * FSize2, Point2.Z - N.Z * l * FSize2, 2, VBPtr);
  217.   SetVertexDataD(FColor2, 2, VBPtr);
  218.   SetVertexDataUV(0, 0 + 0*0.5, 2, VBPtr);
  219.   {  SetVertexDataC(Point2.X, Point2.Y, Point2.Z, 3, VBPtr);
  220.   SetVertexDataD(FColor2*0 + $FF008080, 3, VBPtr);
  221.   SetVertexDataUV(0.5, 0, 3, VBPtr);}
  222.   SetVertexDataC(Point1.X + N.X * l * FSize1, Point1.Y + N.Y * l * FSize1, Point1.Z + N.Z * l * FSize1, 4, VBPtr);
  223.   SetVertexDataD(FColor1, 4, VBPtr);
  224.   SetVertexDataUV(1, FVScale, 4, VBPtr);
  225.   SetVertexDataC(Point2.X + N.X * l * FSize2, Point2.Y + N.Y * l * FSize2, Point2.Z + N.Z * l * FSize2, 3, VBPtr);
  226.   SetVertexDataD(FColor2, 3, VBPtr);
  227.   SetVertexDataUV(1, 0, 3, VBPtr);
  228.   SetVertexDataC(Point1.X - N.X * l * FSize1, Point1.Y - N.Y * l * FSize1, Point1.Z - N.Z * l * FSize1, 5, VBPtr);
  229.   SetVertexDataD(FColor1, 5, VBPtr);
  230.   SetVertexDataUV(0, FVScale, 5, VBPtr);
  231. //  TesselationStatus[tbVertex].Status := tsTesselated;
  232.   LastTotalVertices := TotalVertices;
  233.   Result := LastTotalVertices;
  234. end;
  235. { T3DLine }
  236. function T3DLine.GetTesselatorClass: CTesselator; begin Result := T3DLineMesh; end;
  237. procedure T3DLine.AddProperties(const Result: Props.TProperties);
  238. var Mesh: T3DLineMesh;
  239. begin
  240.   inherited;
  241.   if not Assigned(Result) then Exit;
  242.   if not (CurrentTesselator is T3DLineMesh) then Exit;
  243.   Mesh := CurrentTesselator as T3DLineMesh;
  244.   Result.Add('GeometryLength',    vtSingle, [], FloatToStr(Mesh.Len), '');
  245.   AddColorProperty(Result, 'Color1', Mesh.Color1);
  246.   AddColorProperty(Result, 'Color2', Mesh.Color2);
  247.   Result.Add('GeometrySize near', vtSingle, [], FloatToStr(Mesh.Size1), '');
  248.   Result.Add('GeometrySize far',  vtSingle, [], FloatToStr(Mesh.Size2), '');
  249.   Result.Add('TextureV scale',   vtSingle, [], FloatToStr(Mesh.VScale), '');
  250. end;
  251. procedure T3DLine.SetProperties(Properties: Props.TProperties);
  252. var Mesh: T3DLineMesh;
  253. begin
  254.   inherited;
  255.   if not (CurrentTesselator is T3DLineMesh) then Exit;
  256.   Mesh := CurrentTesselator as T3DLineMesh;
  257.   if Properties.Valid('GeometryLength')    then  Mesh.Len := StrToFloatDef(Properties['GeometryLength'], 0);
  258.   SetColorProperty(Properties, 'Color1', Mesh.Color1);
  259.   SetColorProperty(Properties, 'Color2', Mesh.Color2);
  260.   if Properties.Valid('GeometrySize near') then Mesh.Size1 := StrToFloatDef(Properties['GeometrySize near'], 0);
  261.   if Properties.Valid('GeometrySize far')  then Mesh.Size2 := StrToFloatDef(Properties['GeometrySize far'],  0);
  262.   if Properties.Valid('TextureV scale')   then Mesh.VScale := StrToFloatDef(Properties['TextureV scale'], 0);
  263.   Mesh.ModelMatrix := @FTransform;
  264.   CurrentTesselator.Init;
  265. end;
  266. function T3DLine.VisibilityCheck(const Camera: TCamera): Boolean;
  267. begin
  268.   Result := inherited VisibilityCheck(Camera);
  269.   ComputeTransform;
  270. end;
  271. function T3DLine.GetColor1: BaseTypes.TColor;
  272. begin
  273.   if CurrentTesselator is T3DLineMesh then
  274.    Result := (CurrentTesselator as T3DLineMesh).Color1 else
  275.     Result.C := 0;
  276. end;
  277. procedure T3DLine.SetColor1(const Value: BaseTypes.TColor);
  278. begin
  279.   if not (CurrentTesselator is T3DLineMesh) then Exit;
  280.   (CurrentTesselator as T3DLineMesh).Color1 := Value;
  281.   CurrentTesselator.Init;
  282. end;
  283. function T3DLine.GetColor2: BaseTypes.TColor;
  284. begin
  285.   if CurrentTesselator is T3DLineMesh then
  286.    Result := (CurrentTesselator as T3DLineMesh).Color2 else
  287.     Result.C := 0;
  288. end;
  289. procedure T3DLine.SetColor2(const Value: BaseTypes.TColor);
  290. begin
  291.   if not (CurrentTesselator is T3DLineMesh) then Exit;
  292.   (CurrentTesselator as T3DLineMesh).Color2 := Value;
  293.   CurrentTesselator.Init;
  294. end;
  295. procedure T3DLine.SetLength(const Value: Single);
  296. begin
  297.   if not (CurrentTesselator is T3DLineMesh) then Exit;
  298.   (CurrentTesselator as T3DLineMesh).Len := Value;
  299.   CurrentTesselator.Init;
  300. end;
  301. function T3DLine.GetLength: Single;
  302. begin
  303.   if CurrentTesselator is T3DLineMesh then
  304.    Result := (CurrentTesselator as T3DLineMesh).Len else
  305.     Result := 0;
  306. end;
  307. constructor T3DLine.Create(AManager: TItemsManager);
  308. begin
  309.   inherited;
  310. end;
  311. { TBackgroundTesselator }
  312. constructor TBackgroundTesselator.Create;
  313. begin
  314.   inherited;
  315.   Zoom  := 1;
  316.   Cols  := 2;
  317.   Rows  := 2;
  318.   Angle := 0;
  319.   Color.C := $FF808080;
  320.   UOfs := 0;
  321.   VOfs := 0;
  322.   TesselationStatus[tbVertex].TesselatorType := ttDynamic;
  323.   PrimitiveType := ptTRIANGLELIST;
  324.   InitVertexFormat(GetVertexFormat(True, False, True, False, False, 0, [2]));
  325.   Init;
  326. end;
  327. function TBackgroundTesselator.IsSameItem(AItem: TReferencedItem): Boolean;
  328. begin
  329.   Result := False;
  330. end;
  331. procedure TBackgroundTesselator.Init;
  332. begin
  333.   inherited;
  334.   TotalVertices    := (Cols)*(Rows);
  335.   TotalIndices     := (Rows-1)*(Cols-1)*2*3;
  336.   TotalPrimitives  := (Rows-1)*(Cols-1)*2;
  337.   IndexingVertices := TotalVertices;
  338.   Invalidate([tbVertex, tbIndex], True);
  339. end;
  340. procedure TBackgroundTesselator.AddProperties(const Result: Props.TProperties; const PropNamePrefix: TNameString);
  341. begin
  342.   inherited;
  343.   if not Assigned(Result) then Exit;
  344.   Result.Add(PropNamePrefix + 'Columns',  vtNat,    [], IntToStr(Cols), '');
  345.   Result.Add(PropNamePrefix + 'Rows',     vtNat,    [], IntToStr(Rows), '');
  346.   Result.Add(PropNamePrefix + 'U offset', vtSingle, [], FloatToStr(UOfs), '');
  347.   Result.Add(PropNamePrefix + 'V offset', vtSingle, [], FloatToStr(VOfs), '');
  348. end;
  349. procedure TBackgroundTesselator.SetProperties(Properties: Props.TProperties; const PropNamePrefix: TNameString);
  350. begin
  351.   inherited;
  352.   if Properties.Valid(PropNamePrefix + 'Columns')  then Cols := StrToIntDef(Properties[PropNamePrefix + 'Columns'], 0);
  353.   if Properties.Valid(PropNamePrefix + 'Rows')     then Rows := StrToIntDef(Properties[PropNamePrefix + 'Rows'],    0);
  354.   if Properties.Valid(PropNamePrefix + 'U offset') then UOfs := StrToFloatDef(Properties[PropNamePrefix + 'U offset'], 0);
  355.   if Properties.Valid(PropNamePrefix + 'V offset') then VOfs := StrToFloatDef(Properties[PropNamePrefix + 'V offset'], 0);
  356. end;
  357. function TBackgroundTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  358. var
  359.   i, j: Integer;
  360.   OOZoom, OOCols, OORows: Single;
  361. begin
  362.   Result := 0;
  363.   if (Cols < 2) or (Rows < 2) then Exit;
  364.   OOZoom := 1/Zoom; OOCols := 1/(Cols-1); OORows := 1/(Rows-1);     // Some optimizations
  365.   for j := 0 to Rows-1 do for i := 0 to Cols-1 do begin
  366.     SetVertexDataCRHW((i * OOCols) * Params.Camera.RenderWidth, (j * OORows) * Params.Camera.RenderHeight, 0, 0.001, j*Cols+i, VBPTR);
  367.     SetVertexDataD(Color, j*Cols+i, VBPTR);
  368.     SetVertexDataUV( ( (i * OOCols) * SinTable[(Angle + CosTabOffs) and (SinTableSize-1)] +
  369.                        (j * OORows) * SinTable[(Angle) and (SinTableSize-1)] ) * OOZoom + UOfs,
  370.                      ( (j * OORows) * SinTable[(Angle + CosTabOffs) and (SinTableSize-1)] -
  371.                        (i * OOCols) * SinTable[(Angle) and (SinTableSize-1)] ) * OOZoom + VOfs,
  372.                      j*Cols+i, VBPTR);
  373.   end;
  374.   TesselationStatus[tbVertex].Status := tsTesselated;
  375.   Result := TotalVertices;
  376.   LastTotalVertices := TotalVertices;
  377. end;
  378. function TBackgroundTesselator.SetIndices(IBPTR: Pointer): Integer;
  379. var i, j: Integer;
  380. begin
  381.   for j := 0 to Rows-2 do begin
  382.     for i := 0 to Cols-2 do begin
  383.       TWordBuffer(IBPTR^)[(j*(Cols-1)+i)*6+0] := (j+0)*(Cols)+i;
  384.       TWordBuffer(IBPTR^)[(j*(Cols-1)+i)*6+1] := (j+0)*(Cols)+i+1;
  385.       TWordBuffer(IBPTR^)[(j*(Cols-1)+i)*6+2] := (j+1)*(Cols)+i;
  386.       TWordBuffer(IBPTR^)[(j*(Cols-1)+i)*6+3] := (j+1)*(Cols)+i;
  387.       TWordBuffer(IBPTR^)[(j*(Cols-1)+i)*6+4] := (j+0)*(Cols)+i+1;
  388.       TWordBuffer(IBPTR^)[(j*(Cols-1)+i)*6+5] := (j+1)*(Cols)+i+1
  389.     end;
  390.   end;
  391.   TesselationStatus[tbIndex].Status := tsTesselated;
  392.   Result := TotalIndices;
  393. end;
  394. { TFader }
  395. procedure TFader.SetColor(const Value: BaseTypes.TColor);
  396. var Mesh: TBackgroundTesselator;
  397. begin
  398.   if CurrentTesselator is TBackgroundTesselator then
  399.     Mesh := CurrentTesselator as TBackgroundTesselator
  400.   else
  401.     Exit;
  402.   Mesh.Color := Value;
  403.   Mesh.Invalidate([tbVertex], False);
  404. end;
  405. constructor TFader.Create(AManager: TItemsManager);
  406. begin
  407.   inherited;
  408.   Colors := TSampledGradient.Create;
  409.   Colors.MaxX := 2;
  410. end;
  411. destructor TFader.Destroy;
  412. begin
  413.   FreeAndNil(Colors);
  414.   inherited;
  415. end;
  416. function TFader.GetTesselatorClass: CTesselator; begin Result := TBackgroundTesselator; end;
  417. function TFader.VisibilityCheck(const Camera: TCamera): Boolean;
  418. begin
  419.   Result := True;
  420. end;
  421. procedure TFader.Show;
  422. begin
  423.   inherited;
  424.   ResetProcessedTime();
  425.   Resume();
  426.   AutoStopNeeded := AutoStop;
  427. end;
  428. procedure TFader.AddProperties(const Result: Props.TProperties);
  429. begin
  430.   inherited;
  431.   if not Assigned(Result) then Exit;
  432.   Colors.AddAsProperty(Result, 'Color');
  433.   Result.Add('Auto stop', vtBoolean, [], OnOffStr[AutoStop], '');
  434. end;
  435. procedure TFader.SetProperties(Properties: Props.TProperties);
  436. begin
  437.   inherited;
  438.   Colors.SetFromProperty(Properties, 'Color');
  439.   if Properties.Valid('Auto stop') then AutoStop := Properties.GetAsInteger('Auto stop') > 0;
  440. end;
  441. procedure TFader.Process(const DeltaT: Single);
  442. begin
  443.   inherited;
  444.   SetColor(Colors.Value[TimeProcessed]);
  445.   if AutoStopNeeded and (TimeProcessed > Colors.MaxX * 0.5) then begin
  446.     Pause();
  447.     AutoStopNeeded := False;
  448.   end;
  449. end;
  450. { TBackground }
  451. function TBackground.GetAngle: Integer;
  452. begin
  453.   if CurrentTesselator is TBackgroundTesselator then Result := TBackgroundTesselator(CurrentTesselator).Angle else Result := 0;
  454. end;
  455. function TBackground.GetColor: BaseTypes.TColor;
  456. begin
  457.   if CurrentTesselator is TBackgroundTesselator then Result := TBackgroundTesselator(CurrentTesselator).Color else Result.C := $FF808080;
  458. end;
  459. function TBackground.GetZoom: Single;
  460. begin
  461.   if CurrentTesselator is TBackgroundTesselator then Result := TBackgroundTesselator(CurrentTesselator).Zoom else Result := 1;
  462. end;
  463. procedure TBackground.SetAngle(const Value: Integer);
  464. begin
  465.   if CurrentTesselator is TBackgroundTesselator then (CurrentTesselator as TBackgroundTesselator).Angle := Value;
  466.   CurrentTesselator.Init;
  467. end;
  468. procedure TBackground.SetColor(const Value: BaseTypes.TColor);
  469. begin
  470.   if CurrentTesselator is TBackgroundTesselator then (CurrentTesselator as TBackgroundTesselator).Color := Value;
  471.   CurrentTesselator.Init;
  472. end;
  473. procedure TBackground.SetZoom(const Value: Single);
  474. begin
  475.   if CurrentTesselator is TBackgroundTesselator then (CurrentTesselator as TBackgroundTesselator).Zoom := Value;
  476.   CurrentTesselator.Init;
  477. end;
  478. constructor TBackground.Create(AManager: TItemsManager);
  479. begin
  480.   inherited;
  481. end;
  482. function TBackground.GetTesselatorClass: CTesselator; begin Result := TBackgroundTesselator; end;
  483. function TBackground.VisibilityCheck(const Camera: TCamera): Boolean;
  484. begin
  485.   Result := True;
  486. end;
  487. procedure TBackground.AddProperties(const Result: Props.TProperties);
  488. var Mesh: TBackgroundTesselator;
  489. begin
  490.   inherited;
  491.   if not Assigned(Result) then Exit;
  492.   if CurrentTesselator is TBackgroundTesselator then Mesh := CurrentTesselator as TBackgroundTesselator else begin
  493.     AddErrorProperty(Result, 'Tesselator is undefined');
  494.     Exit;
  495.   end;
  496.   AddColorProperty(Result, 'Color', Mesh.Color);
  497.   Result.Add('Angle',   vtInt,    [], IntToStr(Mesh.Angle), '');
  498.   Result.Add('Zoom',    vtSingle, [], FloatToStr(Mesh.Zoom), '');
  499. end;
  500. procedure TBackground.SetProperties(Properties: Props.TProperties);
  501. var Mesh: TBackgroundTesselator;
  502. begin
  503.   inherited;
  504.   if CurrentTesselator is TBackgroundTesselator then Mesh := CurrentTesselator as TBackgroundTesselator else Exit;
  505.   SetColorProperty(Properties, 'Color', Mesh.Color);
  506.   if Properties.Valid('Angle')   then Mesh.Angle := StrToIntDef(Properties['Angle'],   0);
  507.   if Properties.Valid('Zoom')    then Mesh.Zoom  := StrToFloatDef(Properties['Zoom'],  0);
  508.   Mesh.Init;
  509. end;
  510. { TBillboardMesh }
  511. constructor TBillboardMesh.Create;
  512. begin
  513.   inherited;
  514.   TesselationStatus[tbVertex].TesselatorType := ttDynamic;
  515.   PrimitiveType := ptTRIANGLESTRIP;
  516.   InitVertexFormat(GetVertexFormat(True, False, True, False, False, 0, [2]));
  517.   TotalIndices    := 0;
  518.   TotalVertices   := 4;
  519.   TotalPrimitives := 2;
  520.   IndexingVertices := 4;
  521.   Invalidate([tbVertex, tbIndex], True);
  522.   MaxFrame := 0;
  523.   UVMap := GetDefaultUVMap;
  524. end;
  525. procedure TBillboardMesh.AddProperties(const Result: Props.TProperties; const PropNamePrefix: TNameString);
  526. begin
  527.   inherited;
  528.   if not Assigned(Result) then Exit;
  529.   Result.Add(PropNamePrefix + 'Width',  vtSingle, [], FloatToStr(FWidth), '');
  530.   Result.Add(PropNamePrefix + 'Height', vtSingle, [], FloatToStr(FHeight), '');
  531.   Result.Add('Frame', vtInt, [], IntToStr(FFrame), '0-' + IntToStr(MaxFrame));
  532.   AddColorProperty(Result, PropNamePrefix + 'Color', FColor);
  533. end;
  534. procedure TBillboardMesh.SetProperties(Properties: Props.TProperties; const PropNamePrefix: TNameString);
  535. begin
  536.   inherited;
  537.   if Properties.Valid(PropNamePrefix + 'Width')  then FWidth  := StrToFloatDef(Properties[PropNamePrefix + 'Width'],  0);
  538.   if Properties.Valid(PropNamePrefix + 'Height') then FHeight := StrToFloatDef(Properties[PropNamePrefix + 'Height'], 0);
  539.   if Properties.Valid('Frame') then FFrame := StrToIntDef(Properties['Frame'], 0);
  540.   SetColorProperty(Properties, PropNamePrefix + 'Color', FColor);
  541. end;
  542. function TBillboardMesh.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  543. var Transformed: TVector4s; Location: TVector3s; TRHW, SizeX, SizeY: Single;
  544. begin
  545.   Result := 0;
  546.   LastTotalVertices := 0;
  547.   if FFrame > MaxFrame then Exit;
  548. //  Location := Transform4Vector33s({InvertAffineMatrix4s(} Params.Camera.ViewMatrix, Vec3s(0, 0, 0));
  549.   with Params.ModelMatrix do Location := GetVector3s(_41, _42, _43);
  550.   Transformed := Transform4Vector3s(Params.Camera.TotalMatrix, Location);
  551.   if Transformed.W < epsilon then Exit;
  552.   TRHW := 1/Transformed.W;
  553.   SizeX := Params.Camera.RenderWidth *0.5;
  554.   SizeY := Params.Camera.RenderHeight*0.5;
  555.   Transformed.X := SizeX * (1 + Transformed.X * TRHW);
  556.   Transformed.Y := SizeY * (1 - Transformed.Y * TRHW);
  557.   SizeX := FWidth  * TRHW * SizeX;
  558.   SizeY := FHeight * TRHW * SizeY * Params.Camera.CurrentAspectRatio;
  559.   with Params.Camera do Transformed.Z := 0.002+0*(ZFar/(ZFar-ZNear))*(1-ZNear/(Transformed.Z));
  560.   SetVertexDataCRHW(Transformed.X - SizeX, Transformed.Y - SizeY, Transformed.Z, TRHW, 0, VBPTR);
  561.   SetVertexDataD(FColor, 0, VBPTR);
  562.   SetVertexDataUV(UVMap[FFrame].U, UVMap[FFrame].V, 0, VBPTR);
  563.   SetVertexDataCRHW(Transformed.X + SizeX, Transformed.Y - SizeY, Transformed.Z, TRHW, 1, VBPTR);
  564.   SetVertexDataD(FColor, 1, VBPTR);
  565.   SetVertexDataUV(UVMap[FFrame].U + UVMap[FFrame].W, UVMap[FFrame].V, 1, VBPTR);
  566.   SetVertexDataCRHW(Transformed.X - SizeX, Transformed.Y + SizeY, Transformed.Z, TRHW, 2, VBPTR);
  567.   SetVertexDataD(FColor, 2, VBPTR);
  568.   SetVertexDataUV(UVMap[FFrame].U, UVMap[FFrame].V + UVMap[FFrame].H, 2, VBPTR);
  569.   SetVertexDataCRHW(Transformed.X + SizeX, Transformed.Y + SizeY, Transformed.Z, TRHW, 3, VBPTR);
  570.   SetVertexDataD(FColor, 3, VBPTR);
  571.   SetVertexDataUV(UVMap[FFrame].U + UVMap[FFrame].W, UVMap[FFrame].V + UVMap[FFrame].H, 3, VBPTR);
  572.   TesselationStatus[tbVertex].Status := tsChanged;            // The vertex buffer should be updated every frame
  573.   LastTotalVertices := 4;
  574.   Result := LastTotalVertices;
  575. end;
  576. procedure TBillboardMesh.SetFrame(const Value: Integer);
  577. begin
  578.   if (Value = FFrame) then Exit;
  579.   FFrame := ClampI(Value, 0, MaxFrame);
  580. end;
  581. { TBillboard }
  582. constructor TBillboard.Create(AManager: TItemsManager);
  583. begin
  584.   inherited;
  585. end;
  586. function TBillboard.GetTesselatorClass: CTesselator; begin Result := TBillboardMesh; end;
  587. function TBillboard.VisibilityCheck(const Camera: TCamera): Boolean;
  588. begin
  589.   Result := True;                    // ToFix: cull out when behind camera
  590. end;
  591. procedure TBillboard.ResolveLinks;
  592. var Item: TItem; Mesh: TBillboardMesh;
  593. begin
  594.   inherited;
  595.   if CurrentTesselator is TBillboardMesh then Mesh := CurrentTesselator as TBillboardMesh else Exit;
  596.   ResolveLink('UV map', Item);
  597.   if Assigned(Item) then begin
  598.     Mesh.UVMap    := (Item as TUVMapResource).Data;
  599.     Mesh.MaxFrame := (Item as TUVMapResource).TotalElements-1;
  600.   end;
  601. end;
  602. procedure TBillboard.Process(const DeltaT: Single);
  603. var Mesh: TBillboardMesh; NewFrame: Integer;
  604. begin
  605.   inherited;
  606.   AnimTime := AnimTime + DeltaT;
  607.   if CurrentTesselator is TBillboardMesh then begin
  608.     Mesh := CurrentTesselator as TBillboardMesh;
  609.     NewFrame := Round(AnimTime * AnimRate);
  610.     if (Mesh.MaxFrame >= 0) and (NewFrame > Mesh.MaxFrame) then begin
  611.       if AnimRepeat then Mesh.Frame := NewFrame mod (Mesh.MaxFrame+1);
  612.       if HideAtEnd  then State := State - [isVisible];
  613.     end else Mesh.Frame := NewFrame
  614.   end;
  615. end;
  616. procedure TBillboard.AddProperties(const Result: Props.TProperties);
  617. begin
  618.   inherited;
  619.   AddItemLink(Result, 'UV map',  [], 'TUVMapResource');
  620.   if not Assigned(Result) then Exit;
  621.   if not (CurrentTesselator is TBillboardMesh) then begin
  622.     AddErrorProperty(Result, 'Tesselator is undefined');
  623.     Exit;
  624.   end;
  625.   Result.Add('Animation rate',  vtSingle,  [], FloatToStr(AnimRate), '');
  626.   Result.Add('Animation cycle', vtBoolean, [], OnOffStr[AnimRepeat], '');
  627.   Result.Add('Hide at end',     vtBoolean, [], OnOffStr[HideAtEnd],  '');
  628. end;
  629. procedure TBillboard.SetProperties(Properties: Props.TProperties);
  630. begin
  631.   inherited;
  632.   if Properties.Valid('UV map') then SetLinkProperty('UV map', Properties['UV map']);
  633.   if Properties.Valid('Animation rate')  then begin
  634.     AnimRate := StrToFloatDef(Properties['Animation rate'], 0);
  635.     AnimTime := 0;
  636.   end;  
  637.   if Properties.Valid('Animation cycle') then Animrepeat := Properties.GetAsInteger('Animation cycle') > 0;
  638.   if Properties.Valid('Hide at end')     then HideAtEnd  := Properties.GetAsInteger('Hide at end')     > 0;
  639. end;
  640. { TSplashTesselator }
  641. constructor TSplashTesselator.Create;
  642. begin
  643.   inherited;
  644.   PrimitiveType    := ptTRIANGLESTRIP;
  645.   InitVertexFormat(GetVertexFormat(False, False, True, False, False, 0, [2]));
  646.   TotalVertices    := 4;
  647.   TotalPrimitives  := 2;
  648.   Color.C  := $80808080;
  649.   Size     := 1;
  650. end;
  651. function TSplashTesselator.IsSameItem(AItem: TReferencedItem): Boolean;
  652. begin
  653.   Result := False;
  654. end;
  655. function TSplashTesselator.GetBoundingBox: TBoundingBox;
  656. begin
  657.   Result.P1 := GetVector3s(-Size, -Size, 0);
  658.   Result.P2 := GetVector3s( Size,  Size, 0);
  659. end;
  660. function TSplashTesselator.Tesselate(const Params: TTesselationParameters; VBPTR: Pointer): Integer;
  661. begin
  662.   SetVertexDataC(-Size, Size, 0, 0, VBPTR);
  663.   SetVertexDataUV(0, 0, 0, VBPTR);
  664.   SetVertexDataD(Color, 0, VBPTR);
  665.   SetVertexDataC(Size, Size, 0, 1, VBPTR);
  666.   SetVertexDataUV(1, 0, 1, VBPTR);
  667.   SetVertexDataD(Color, 1, VBPTR);
  668.   SetVertexDataC(-Size, -Size, 0, 2, VBPTR);
  669.   SetVertexDataUV(0, 1, 2, VBPTR);
  670.   SetVertexDataD(Color, 2, VBPTR);
  671.   SetVertexDataC(Size, -Size, 0, 3, VBPTR);
  672.   SetVertexDataUV(1, 1, 3, VBPTR);
  673.   SetVertexDataD(Color, 3, VBPTR);
  674.   TesselationStatus[tbVertex].Status := tsTesselated;
  675.   LastTotalVertices := TotalVertices;
  676.   Result            := TotalVertices;
  677. end;
  678. { TSplash }
  679. constructor TSplash.Create(AManager: TItemsManager);
  680. begin
  681.   inherited;
  682.   Color := TSampledGradient.Create;
  683.   Size  := TSampledFloats.Create;
  684. end;
  685. destructor TSplash.Destroy;
  686. begin
  687.   FreeAndNil(Color);
  688.   FreeAndNil(Size);
  689.   inherited;
  690. end;
  691. function TSplash.GetTesselatorClass: CTesselator; begin Result := TSplashTesselator; end;
  692. procedure TSplash.AddProperties(const Result: Props.TProperties);
  693. begin
  694.   inherited;
  695.   if not Assigned(Result) then Exit;
  696.   Color.AddAsProperty(Result, 'Color');
  697.   Size.AddAsProperty(Result, 'Size');
  698. end;
  699. procedure TSplash.SetProperties(Properties: Props.TProperties);
  700. begin
  701.   inherited;
  702.   Color.SetFromProperty(Properties, 'Color');
  703.   Size.SetFromProperty(Properties, 'Size');
  704.   SetMesh;
  705.   ResetProcessedTime;
  706. end;
  707. procedure TSplash.Process(const DeltaT: Single);
  708. var Tesselator: TSplashTesselator;
  709. begin
  710.   inherited;
  711.   if not (CurrentTesselator is TSplashTesselator) then Exit;
  712.   Tesselator := CurrentTesselator as TSplashTesselator;
  713.   Tesselator.Color := Color.Value[TimeProcessed];
  714.   Tesselator.Size  := Size.Value[TimeProcessed];
  715.   Tesselator.Invalidate([tbVertex], False);
  716. end;
  717. begin
  718.   GlobalClassList.Add('C2FX', GetUnitClassList);
  719. end.