Added transform syncronization, an animation module and made the app work faster
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@
|
||||
|
||||
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
|
||||
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
|
||||
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
|
||||
Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -26,9 +26,13 @@ unit RndFlame;
|
||||
interface
|
||||
|
||||
uses
|
||||
ControlPoint, Xform;
|
||||
ControlPoint;
|
||||
|
||||
function RandomFlame(SourceCP: TControlPoint= nil; algorithm: integer = 0): TControlPoint;
|
||||
function RandomFlame(SourceCP: TControlPoint = nil; algorithm: integer = 0): TControlPoint;
|
||||
|
||||
// AV: made the following public to get rid of duplicated code
|
||||
procedure SetVariation(cp: TControlPoint);
|
||||
procedure RandomVariation(cp: TControlPoint);
|
||||
|
||||
implementation
|
||||
|
||||
@ -75,83 +79,6 @@ begin
|
||||
end;
|
||||
end; *)
|
||||
|
||||
function CreatePalette(strng: string): TColorMap;
|
||||
{ Loads a palette from a gradient string }
|
||||
var
|
||||
Strings: TStringList;
|
||||
index, i: integer;
|
||||
Tokens: TStringList;
|
||||
Indices, Colors: TStringList;
|
||||
a, b: integer;
|
||||
begin
|
||||
Strings := TStringList.Create;
|
||||
Tokens := TStringList.Create;
|
||||
Indices := TStringList.Create;
|
||||
Colors := TStringList.Create;
|
||||
try
|
||||
try
|
||||
Strings.Text := strng;
|
||||
if Pos('}', Strings.Text) = 0 then raise EFormatInvalid.Create('No closing brace');
|
||||
if Pos('{', Strings[0]) = 0 then raise EFormatInvalid.Create('No opening brace.');
|
||||
GetTokens(ReplaceTabs(strings.text), tokens);
|
||||
Tokens.Text := Trim(Tokens.text);
|
||||
i := 0;
|
||||
while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do
|
||||
begin
|
||||
if Pos('index=', LowerCase(Tokens[i])) <> 0 then
|
||||
Indices.Add(GetVal(Tokens[i]))
|
||||
else if Pos('color=', LowerCase(Tokens[i])) <> 0 then
|
||||
Colors.Add(GetVal(Tokens[i]));
|
||||
inc(i)
|
||||
end;
|
||||
for i := 0 to 255 do
|
||||
begin
|
||||
Result[i][0] := 0;
|
||||
Result[i][1] := 0;
|
||||
Result[i][2] := 0;
|
||||
end;
|
||||
if Indices.Count = 0 then raise EFormatInvalid.Create('No color info');
|
||||
for i := 0 to Indices.Count - 1 do
|
||||
begin
|
||||
try
|
||||
index := StrToInt(Indices[i]);
|
||||
while index < 0 do inc(index, 400);
|
||||
index := Round(Index * (255 / 399));
|
||||
indices[i] := IntToStr(index);
|
||||
assert(index>=0);
|
||||
assert(index<256);
|
||||
Result[index][0] := StrToInt(Colors[i]) mod 256;
|
||||
Result[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256;
|
||||
Result[index][2] := trunc(StrToInt(Colors[i]) / 65536);
|
||||
except
|
||||
end;
|
||||
end;
|
||||
i := 1;
|
||||
repeat
|
||||
a := StrToInt(Trim(Indices[i - 1]));
|
||||
b := StrToInt(Trim(Indices[i]));
|
||||
RGBBlend(a, b, Result);
|
||||
inc(i);
|
||||
until i = Indices.Count;
|
||||
if (Indices[0] <> '0') or (Indices[Indices.Count - 1] <> '255') then
|
||||
begin
|
||||
a := StrToInt(Trim(Indices[Indices.Count - 1]));
|
||||
b := StrToInt(Trim(Indices[0])) + 256;
|
||||
RGBBlend(a, b, Result);
|
||||
end;
|
||||
except on EFormatInvalid do
|
||||
begin
|
||||
// Result := False;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
Tokens.Free;
|
||||
Strings.Free;
|
||||
Indices.Free;
|
||||
Colors.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure GetGradientFileGradientsNames(const filename: string; var NamesList: TStringList);
|
||||
var
|
||||
i, p: integer;
|
||||
@ -225,7 +152,53 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
{ ****************** Triangle transformations ******************************* }
|
||||
|
||||
function transform_affine(const t: TTriangle; const Triangles: TTriangles): boolean;
|
||||
var
|
||||
ra, rb, rc, a, b, c: double;
|
||||
begin
|
||||
Result := True;
|
||||
ra := dist(Triangles[-1].y[0], Triangles[-1].x[0],
|
||||
Triangles[-1].y[1], Triangles[-1].x[1]);
|
||||
rb := dist(Triangles[-1].y[1], Triangles[-1].x[1],
|
||||
Triangles[-1].y[2], Triangles[-1].x[2]);
|
||||
rc := dist(Triangles[-1].y[2], Triangles[-1].x[2],
|
||||
Triangles[-1].y[0], Triangles[-1].x[0]);
|
||||
a := dist(t.y[0], t.x[0], t.y[1], t.x[1]);
|
||||
b := dist(t.y[1], t.x[1], t.y[2], t.x[2]);
|
||||
c := dist(t.y[2], t.x[2], t.y[0], t.x[0]);
|
||||
if (a > ra) then
|
||||
Result := False
|
||||
else if (b > rb) then
|
||||
Result := False
|
||||
else if (c > rc) then
|
||||
Result := False
|
||||
else if ((a = ra) and (b = rb) and (c = rc)) then
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function triangle_area(t: TTriangle): double;
|
||||
var
|
||||
base, height: double;
|
||||
begin
|
||||
try
|
||||
base := dist(t.x[0], t.y[0], t.x[1], t.y[1]);
|
||||
height := line_dist(t.x[2], t.y[2], t.x[1], t.y[1],
|
||||
t.x[0], t.y[0]);
|
||||
if (base < 1.0) then
|
||||
Result := height
|
||||
else if (height < 1.0) then
|
||||
Result := base
|
||||
else
|
||||
Result := 0.5 * base * height;
|
||||
except on E: EMathError do
|
||||
Result := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ ************************************************************************** }
|
||||
|
||||
procedure RandomVariation(cp: TControlPoint);
|
||||
{ Randomise variation parameters }
|
||||
var
|
||||
@ -236,26 +209,23 @@ begin
|
||||
RandSeed := MainSeed;
|
||||
|
||||
VarPossible := false;
|
||||
for j := 0 to NRVAR - 1 do begin
|
||||
VarPossible := VarPossible or Variations[j];
|
||||
end;
|
||||
for j := 0 to NRVAR - 1 do
|
||||
if Variations[j] then begin // AV: make it faster!
|
||||
VarPossible := True;
|
||||
break;
|
||||
end;
|
||||
if not VarPossible then Variations[0] := True; // AV
|
||||
|
||||
for i := 0 to cp.NumXForms - 1 do begin
|
||||
for j := 0 to NRVAR - 1 do
|
||||
cp.xform[i].SetVariation(j, 0);
|
||||
|
||||
if VarPossible then begin
|
||||
repeat
|
||||
a := random(NRVAR);
|
||||
until Variations[a];
|
||||
|
||||
repeat
|
||||
b := random(NRVAR);
|
||||
until Variations[b];
|
||||
end else begin
|
||||
a := 0;
|
||||
b := 0;
|
||||
end;
|
||||
repeat
|
||||
a := random(NRVAR);
|
||||
until Variations[a];
|
||||
repeat
|
||||
b := random(NRVAR);
|
||||
until Variations[b];
|
||||
|
||||
if (a = b) then begin
|
||||
cp.xform[i].SetVariation(a, 1);
|
||||
@ -278,7 +248,7 @@ begin
|
||||
for i := 0 to cp.NumXForms - 1 do begin
|
||||
for j := 0 to NRVAR - 1 do
|
||||
cp.xform[i].SetVariation(j, 0);
|
||||
cp.xform[i].SetVariation(integer(Variation), 1);
|
||||
cp.xform[i].SetVariation(Variation, 1);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -414,16 +384,17 @@ begin
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
(*
|
||||
procedure RandomWeights(var cp1: TControlPoint);
|
||||
{ Randomizes xform weights }
|
||||
var
|
||||
i: integer;
|
||||
begin
|
||||
for i := 0 to Transforms - 1 do
|
||||
for i := 0 to cp1.NumXForms - 1 do // AV: was Transforms - 1
|
||||
cp1.xform[i].Density := random;
|
||||
NormalizeWeights(cp1);
|
||||
end;
|
||||
|
||||
*)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
function RandomFlame(SourceCP: TControlPoint; algorithm: integer): TControlPoint;
|
||||
var
|
||||
@ -444,22 +415,25 @@ begin
|
||||
inc(MainSeed);
|
||||
RandSeed := MainSeed;
|
||||
transforms := random(Max - (Min - 1)) + Min;
|
||||
|
||||
repeat
|
||||
try
|
||||
inc(MainSeed);
|
||||
RandSeed := MainSeed;
|
||||
Result.clear;
|
||||
Result.RandomCP(transforms, transforms, false);
|
||||
Result.SetVariation(Variation);
|
||||
inc(MainSeed);
|
||||
RandSeed := MainSeed;
|
||||
Result.Clear;
|
||||
for i := 0 to Transforms - 1 do // AV: set starting non-zero weights...
|
||||
Result.xform[i].density := 0.5;
|
||||
// AV: we don't really need to randomize the same flame twice...
|
||||
//Result.RandomCP(transforms, transforms, false);
|
||||
//Result.SetVariation(Variation); // AV: deprecated!
|
||||
SetVariation(Result); // AV: replaced old method from ControlPoint
|
||||
|
||||
case algorithm of
|
||||
1: rnd := 0;
|
||||
2: rnd := 7;
|
||||
3: rnd := 9;
|
||||
else
|
||||
if (Variation = vLinear) or (Variation = vRandom) then
|
||||
if (Variation = 0 {vLinear}) or (Variation = vRandom) then
|
||||
rnd := random(10)
|
||||
else
|
||||
rnd := 9;
|
||||
@ -479,11 +453,11 @@ begin
|
||||
Result.xform[i].c[1, 1] := 1;
|
||||
Result.xform[i].c[2, 0] := 0;
|
||||
Result.xform[i].c[2, 1] := 0;
|
||||
Result.xform[i].color := 0; }
|
||||
Result.xform[i].symmetry := 0;
|
||||
Result.xform[i].color := 0;
|
||||
// AV: this will be done with SetVariation method!
|
||||
Result.xform[i].SetVariation(0, 1);
|
||||
for j := 1 to NRVAR - 1 do
|
||||
Result.xform[i].SetVariation(j, 0);
|
||||
Result.xform[i].SetVariation(j, 0); }
|
||||
// AV: hundred of useless calculations
|
||||
{Result.xform[i].Translate(random * 2 - 1, random * 2 - 1);
|
||||
Result.xform[i].Rotate(random * 360);
|
||||
@ -491,6 +465,7 @@ begin
|
||||
Result.xform[i].Scale(random * 0.8 + 0.2)
|
||||
else
|
||||
Result.xform[i].Scale(random * 0.4 + 0.6); }
|
||||
Result.xform[i].symmetry := 0;
|
||||
if i > 0 then
|
||||
s := random * 0.8 + 0.2
|
||||
else
|
||||
@ -512,7 +487,8 @@ begin
|
||||
Result.xform[i].c[2, 0] := random * 2 - 1;
|
||||
Result.xform[i].c[2, 1] := random * 2 - 1;
|
||||
if Random(2) = 0 then
|
||||
Result.xform[i].Multiply(1, random - 0.5, random - 0.5, 1);
|
||||
Result.xform[i].Multiply(Result.xform[i].c,
|
||||
1, random - 0.5, random - 0.5, 1);
|
||||
|
||||
if Random(2) = 1 then
|
||||
begin
|
||||
@ -529,7 +505,7 @@ begin
|
||||
Result.xform[i].p[2,1] := random * 2 - 1;
|
||||
end;
|
||||
end;
|
||||
SetVariation(Result);
|
||||
//SetVariation(Result);
|
||||
end;
|
||||
7, 8:
|
||||
begin
|
||||
@ -559,20 +535,31 @@ begin
|
||||
Result.xform[i].c[2][0] := random * 2 - 1;
|
||||
Result.xform[i].c[2][1] := random * 2 - 1;
|
||||
end;
|
||||
|
||||
{ // AV: the following was (or will be) done!
|
||||
for i := 0 to NXFORMS-1 do
|
||||
Result.xform[i].density := 0;
|
||||
for i := 0 to Transforms - 1 do
|
||||
Result.xform[i].density := 1 / Transforms;
|
||||
SetVariation(Result);
|
||||
}
|
||||
end;
|
||||
9: begin
|
||||
for i := 0 to NXFORMS-1 do
|
||||
{ // AV: the following was (or will be) done!
|
||||
for i := 0 to NXFORMS-1 do
|
||||
Result.xform[i].density := 0;
|
||||
for i := 0 to Transforms - 1 do
|
||||
Result.xform[i].density := 1 / Transforms;
|
||||
}
|
||||
for i := 0 to Transforms - 1 do begin // AV
|
||||
Result.xform[i].RandomizeCoefs(Result.xform[i].c);
|
||||
if Random(4) = 1 then
|
||||
Result.xform[i].RandomizeCoefs(Result.xform[i].p);
|
||||
end;
|
||||
end;
|
||||
end; // case
|
||||
Result.TrianglesFromCp(Triangles);
|
||||
|
||||
if Random(2) > 0 then
|
||||
ComputeWeights(Result, Triangles, transforms)
|
||||
else
|
||||
@ -628,8 +615,6 @@ begin
|
||||
Result.background[2] := 0;
|
||||
end;
|
||||
Result.zoom := 0;
|
||||
//Result.Nick := SheepNick;
|
||||
//Result.URl := SheepURL;
|
||||
|
||||
Result.xform[Result.NumXForms].Clear;
|
||||
Result.xform[Result.NumXForms].symmetry := 1;
|
||||
|
262
Flame/XForm.pas
262
Flame/XForm.pas
@ -5,7 +5,7 @@
|
||||
|
||||
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
|
||||
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
|
||||
Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina
|
||||
Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -31,8 +31,7 @@ unit XForm;
|
||||
interface
|
||||
|
||||
uses
|
||||
{$ifdef Apo7X64}
|
||||
{$else}
|
||||
{$ifdef CPUX86}
|
||||
AsmRandom,
|
||||
{$endif}
|
||||
XFormMan, BaseVariation, Classes;
|
||||
@ -60,27 +59,33 @@ type
|
||||
end;
|
||||
PXYpoint = ^TXYpoint;
|
||||
|
||||
{
|
||||
T2Cpoint = record
|
||||
x, y, c1, c2: double;
|
||||
end;
|
||||
P2Cpoint = ^T2Cpoint;
|
||||
|
||||
TMatrix = array[0..2, 0..2] of double;
|
||||
}
|
||||
|
||||
{$ifdef Apo7X64}
|
||||
{$else}
|
||||
// AV: rewrote all asm-code from Apo7X to make it work properly again
|
||||
{$ifdef CPUX86}
|
||||
{$define _ASM_}
|
||||
{$endif}
|
||||
|
||||
type
|
||||
TCoefsArray = array[0..2, 0..1] of double; // AV: moved from ControlPoint
|
||||
//pCoefsArray = ^TCoefsArray;
|
||||
|
||||
TXForm = class
|
||||
public
|
||||
|
||||
c: array[0..2, 0..1] of double; // the coefs to the affine part of the function
|
||||
p: array[0..2, 0..1] of double; // post-transform coefs!
|
||||
density: double; // prob is this function is chosen
|
||||
color: double; // color coord for this function. 0 - 1
|
||||
color2: double; // Second color coord for this function. 0 - 1
|
||||
vc: double; // Calculated color to be passed to the plugin
|
||||
c: TCoefsArray; // the coefs to the affine part of the function
|
||||
p: TCoefsArray; // post-transform coefs!
|
||||
density: double; // prob is this function is chosen
|
||||
color: double; // color coord for this function. 0 - 1
|
||||
color2: double; // Second color coord for this function. 0 - 1
|
||||
vc: double; // Calculated color to be passed to the plugin
|
||||
symmetry: double;
|
||||
c00, c01, c10, c11, c20, c21: double; // unnecessary duplicated variables
|
||||
p00, p01, p10, p11, p20, p21: double; // :-)
|
||||
@ -104,7 +109,6 @@ type
|
||||
|
||||
FTx, FTy: double; // must remain in this order
|
||||
FPx, FPy: double; // some asm code relies on this
|
||||
|
||||
FTz, FPz: double; // 3d hack
|
||||
|
||||
FAngle: double;
|
||||
@ -153,7 +157,7 @@ type
|
||||
procedure Blur3D; // vars[18]
|
||||
|
||||
procedure PreBlur; // vars[19]
|
||||
procedure PreZScale; // vars[2]
|
||||
procedure PreZScale; // vars[20]
|
||||
procedure PreZTranslate; // vars[21]
|
||||
procedure PreRotateX; // vars[22]
|
||||
procedure PreRotateY; // vars[23]
|
||||
@ -175,8 +179,8 @@ type
|
||||
procedure Pyramid; // vars[34]
|
||||
procedure Polar2; // vars[35]
|
||||
|
||||
function Mul33(const M1, M2: TMatrix): TMatrix;
|
||||
function Identity: TMatrix;
|
||||
//function Mul33(const M1, M2: TMatrix): TMatrix;
|
||||
//function Identity: TMatrix;
|
||||
|
||||
procedure BuildFunctionlist;
|
||||
procedure AddRegVariations;
|
||||
@ -193,12 +197,16 @@ type
|
||||
procedure NextPoint(var CPpoint: TCPpoint);
|
||||
procedure NextPointTo(var CPpoint, ToPoint: TCPpoint);
|
||||
procedure NextPointXY(var px, py: double);
|
||||
procedure NextPoint2C(var p: T2CPoint);
|
||||
//procedure NextPoint2C(var p: T2CPoint);
|
||||
|
||||
procedure Rotate(const degrees: double);
|
||||
procedure Translate(const x, y: double);
|
||||
procedure Multiply(const a, b, c, d: double);
|
||||
procedure Scale(const s: double);
|
||||
// AV: extended all following methods for post-coefs support
|
||||
procedure Rotate(var t: TCoefsArray; const degrees: double);
|
||||
procedure Translate(var t: TCoefsArray; const x, y: double);
|
||||
procedure Multiply(var t: TCoefsArray; const k, l, m, n: double);
|
||||
procedure Scale(var t: TCoefsArray; const s: double);
|
||||
procedure RandomizeCoefs(var t: TCoefsArray); // AV: for random flames
|
||||
function detC: double; inline;
|
||||
function detP: double; inline;
|
||||
|
||||
procedure GetVariable(const name: string; var Value: double);
|
||||
procedure SetVariable(const name: string; var Value: double);
|
||||
@ -254,7 +262,7 @@ var i: Integer;
|
||||
begin
|
||||
AddRegVariations;
|
||||
BuildFunctionlist;
|
||||
SetLength(vars, NRLOCVAR + Length(FRegVariations));
|
||||
SetLength(vars, NrVar); // <-- AV // NRLOCVAR + Length(FRegVariations));
|
||||
// AV: set default variations order
|
||||
ifs := TStringList.Create;
|
||||
for i := 0 to NrVar-1 do ifs.Add(Varnames(i));
|
||||
@ -308,6 +316,7 @@ var
|
||||
CalculateAngle, CalculateSinCos, CalculateLength: boolean;
|
||||
mode: double;
|
||||
vn: string;
|
||||
UsedVars: TStringList;
|
||||
begin
|
||||
c00 := c[0][0];
|
||||
c01 := c[0][1];
|
||||
@ -347,31 +356,33 @@ begin
|
||||
// CalculateLength := False;
|
||||
CalculateSinCos := (vars[8] <> 0.0) or (vars[10] <> 0.0);
|
||||
|
||||
UsedVars := TStringList.Create;
|
||||
|
||||
// Pre- variations
|
||||
for i := 0 to NrVar - 1 do
|
||||
for vn in ifs do
|
||||
begin
|
||||
v := GetVariationIndex(vn);
|
||||
if (vars[v] <> 0.0) then
|
||||
begin
|
||||
v := GetVariationIndex(ifs[i]);
|
||||
if (vars[v] <> 0.0) then
|
||||
UsedVars.Add(vn); // AV: remember all used variations in the right order
|
||||
if (LeftStr(vn, 4) = 'pre_') or (vn = 'flatten') then // AV: flatten became pre_
|
||||
begin
|
||||
vn := ifs[i];
|
||||
if (LeftStr(vn, 4) = 'pre_') or (vn = 'flatten') then // AV: flatten became pre_
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end
|
||||
// AV: added some universal variations
|
||||
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
|
||||
or (vn = 'spherecrop') then
|
||||
begin
|
||||
GetVariable(vn + '_mode', mode);
|
||||
if (mode = 0) then
|
||||
begin
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end
|
||||
// AV: added some universal variations
|
||||
else if (vn = 'affine3D') or (vn = 'trianglecrop')
|
||||
or (vn = 'projective') or (vn = 'spherecrop') then
|
||||
begin
|
||||
GetVariable(vn + '_mode', mode);
|
||||
if (mode = 0) then
|
||||
begin
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Precalc must be called after pre- vars
|
||||
if CalculateAngle or CalculateSinCos then
|
||||
@ -386,53 +397,47 @@ begin
|
||||
end;
|
||||
|
||||
// Normal variations
|
||||
for i := 0 to NrVar - 1 do
|
||||
for vn in UsedVars do // AV: iterate through used variations only
|
||||
begin
|
||||
v := GetVariationIndex(ifs[i]);
|
||||
if (vars[v] <> 0.0) then
|
||||
if (LeftStr(vn, 4) = 'pre_') or (LeftStr(vn, 5) = 'post_') or (vn = 'flatten')
|
||||
then continue
|
||||
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
|
||||
or (vn = 'spherecrop') then
|
||||
begin
|
||||
vn := ifs[i];
|
||||
if (LeftStr(vn, 4) = 'pre_') or
|
||||
(LeftStr(vn, 5) = 'post_') or
|
||||
(vn = 'flatten') then continue;
|
||||
if (vn = 'affine3D') or (vn = 'trianglecrop')
|
||||
or (vn = 'projective') or (vn = 'spherecrop') then
|
||||
begin
|
||||
GetVariable(vn + '_mode', mode);
|
||||
if (mode <> 1) then continue;
|
||||
end;
|
||||
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
GetVariable(vn + '_mode', mode);
|
||||
if (mode <> 1) then continue;
|
||||
end;
|
||||
|
||||
v := GetVariationIndex(vn);
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end;
|
||||
|
||||
// Post- variations
|
||||
for i := 0 to NrVar - 1 do
|
||||
for vn in UsedVars do // AV: iterate through used variations only
|
||||
begin
|
||||
v := GetVariationIndex(ifs[i]);
|
||||
if (vars[v] <> 0.0) then
|
||||
if (LeftStr(vn, 5) = 'post_') then
|
||||
begin
|
||||
v := GetVariationIndex(vn);
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end
|
||||
// AV: added some universal variations
|
||||
else if (vn = 'affine3D') or (vn = 'trianglecrop') or (vn = 'projective')
|
||||
or (vn = 'spherecrop') then
|
||||
begin
|
||||
GetVariable(vn + '_mode', mode);
|
||||
if (mode = 2) then
|
||||
begin
|
||||
vn := ifs[i];
|
||||
if (LeftStr(vn, 5) = 'post_') then
|
||||
begin
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end
|
||||
// AV: added some universal variations
|
||||
else if (vn = 'affine3D') or (vn = 'trianglecrop')
|
||||
or (vn = 'projective') or (vn = 'spherecrop') then
|
||||
begin
|
||||
GetVariable(ifs[i] + '_mode', mode);
|
||||
if (mode = 2) then
|
||||
begin
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end;
|
||||
end;
|
||||
v := GetVariationIndex(vn);
|
||||
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
||||
Inc(FNrFunctions);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
UsedVars.Free;
|
||||
|
||||
polar_vpi := vars[6]/pi;
|
||||
disc_vpi := vars[7]/pi;
|
||||
polar2_vpi := vars[35]/pi;
|
||||
@ -624,7 +629,7 @@ end;
|
||||
procedure TXForm.Flatten;
|
||||
begin
|
||||
// FPz := 0;
|
||||
// AV: changed to pre_mode
|
||||
// AV: changed to pre_mode for compatibility with "3D-Hack" flames
|
||||
FTz := 0;
|
||||
end;
|
||||
|
||||
@ -1607,10 +1612,11 @@ begin
|
||||
ToPoint.c := ToPoint.c + pluginColor * (vc - ToPoint.c);
|
||||
ToPoint.x := FPx;
|
||||
ToPoint.y := FPy;
|
||||
ToPoint.z := FPz; //?
|
||||
ToPoint.z := FPz;
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
(*
|
||||
procedure TXForm.NextPoint2C(var p: T2CPoint);
|
||||
var
|
||||
i: Integer;
|
||||
@ -1631,7 +1637,7 @@ begin
|
||||
p.x := FPx;
|
||||
p.y := FPy;
|
||||
end;
|
||||
|
||||
*)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
procedure TXForm.NextPointXY(var px, py: double);
|
||||
var
|
||||
@ -1651,6 +1657,75 @@ begin
|
||||
py := FPy;
|
||||
end;
|
||||
|
||||
//************ Math utils ***************************************//
|
||||
|
||||
function TXForm.detC;
|
||||
begin
|
||||
Result := c[0,0] * c[1,1] - c[0,1] * c[1,0];
|
||||
end;
|
||||
|
||||
function TXForm.detP;
|
||||
begin
|
||||
Result := p[0,0] * p[1,1] - p[0,1] * p[1,0];
|
||||
end;
|
||||
|
||||
//************ Matrix multiplication ***************************************//
|
||||
|
||||
procedure TXForm.Multiply(var t: TCoefsArray; const k, l, m, n: double); // AV
|
||||
var
|
||||
ta, tb, tc, td: double;
|
||||
begin
|
||||
ta := t[0, 0];
|
||||
tb := -t[1, 0];
|
||||
tc := -t[0, 1];
|
||||
td := t[1, 1];
|
||||
|
||||
{
|
||||
[a, b][e ,f] [a*e+b*g, a*f+b*h]
|
||||
[ ][ ] = [ ]
|
||||
[c, d][g, h] [c*e+d*g, c*f+d*h]
|
||||
}
|
||||
|
||||
t[0, 0] := ta * k + tc * l;
|
||||
t[0, 1] := -(ta * m + tc * n);
|
||||
t[1, 0] := -(tb * k + td * l);
|
||||
t[1, 1] := tb * m + td * n;
|
||||
end;
|
||||
|
||||
procedure TXForm.Rotate(var t: TCoefsArray; const degrees: double); // AV
|
||||
var
|
||||
v, sv, cv: double;
|
||||
begin
|
||||
v := DegToRad(degrees);
|
||||
SinCos(v, sv, cv);
|
||||
Multiply(t, cv, -sv, sv, cv);
|
||||
end;
|
||||
|
||||
procedure TXForm.Scale(var t: TCoefsArray; const s: double);
|
||||
begin
|
||||
t[0, 0] := t[0, 0] * s;
|
||||
t[0, 1] := t[0, 1] * s;
|
||||
t[1, 0] := t[1, 0] * s;
|
||||
t[1, 1] := t[1, 1] * s;
|
||||
end;
|
||||
|
||||
procedure TXForm.Translate(var t: TCoefsArray; const x, y: double);
|
||||
begin
|
||||
t[2,0] := t[2,0] + x;
|
||||
t[2,1] := t[2,1] - y; // AV: notice the sign here
|
||||
end;
|
||||
|
||||
procedure TXForm.RandomizeCoefs(var t: TCoefsArray); // AV
|
||||
begin
|
||||
t[0][0] := 2 * random - 1;
|
||||
t[0][1] := 2 * random - 1;
|
||||
t[1][0] := 2 * random - 1;
|
||||
t[1][1] := 2 * random - 1;
|
||||
t[2][0] := 4 * random - 2;
|
||||
t[2][1] := 4 * random - 2;
|
||||
end;
|
||||
|
||||
(*
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
@ -1676,7 +1751,6 @@ begin
|
||||
result[2, 2] := M1[2][0] * M2[0][2] + M1[2][1] * M2[1][2] + M1[2][2] * M2[2][2]; // AV: fixed indices
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
function TXForm.Identity: TMatrix;
|
||||
var
|
||||
i, j: integer;
|
||||
@ -1690,6 +1764,7 @@ begin
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
procedure TXForm.Rotate(const degrees: double);
|
||||
var
|
||||
r: double;
|
||||
@ -1718,7 +1793,6 @@ begin
|
||||
c[2, 1] := Matrix[1][2];
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
procedure TXForm.Translate(const x, y: double);
|
||||
var
|
||||
Matrix, M1: TMatrix;
|
||||
@ -1743,7 +1817,6 @@ begin
|
||||
c[2, 1] := Matrix[1][2];
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
procedure TXForm.Multiply(const a, b, c, d: double);
|
||||
var
|
||||
Matrix, M1: TMatrix;
|
||||
@ -1769,7 +1842,6 @@ begin
|
||||
Self.c[2, 1] := Matrix[1][2];
|
||||
end;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
procedure TXForm.Scale(const s: double);
|
||||
var
|
||||
Matrix, M1: TMatrix;
|
||||
@ -1792,7 +1864,7 @@ begin
|
||||
c[2, 0] := Matrix[0][2];
|
||||
c[2, 1] := Matrix[1][2];
|
||||
end;
|
||||
|
||||
*)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
destructor TXForm.Destroy;
|
||||
var
|
||||
@ -1811,7 +1883,9 @@ end;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
procedure TXForm.BuildFunctionlist;
|
||||
begin
|
||||
SetLength(FFunctionList, NrVar + Length(FRegVariations));
|
||||
// AV: why NRVAR is used here? maybe NRLOCVAR instead?
|
||||
//SetLength(FFunctionList, NrVar + Length(FRegVariations));
|
||||
SetLength(FFunctionList, NrVar); // <-- AV: reduced the length to actually used
|
||||
|
||||
//fixed
|
||||
FFunctionList[0] := Linear3D;
|
||||
@ -1835,7 +1909,7 @@ begin
|
||||
FFunctionList[18] := Blur3D;
|
||||
|
||||
FFunctionList[19] := PreBlur;
|
||||
FFunctionList[20] := PreZScale; // AV: index 20 is used by auto_pre_zscale option
|
||||
FFunctionList[20] := PreZScale; // AV: index is used by auto-pre_zscale option
|
||||
FFunctionList[21] := PreZTranslate;
|
||||
FFunctionList[22] := PreRotateX;
|
||||
FFunctionList[23] := PreRotateY;
|
||||
@ -1922,11 +1996,11 @@ begin
|
||||
result := Format(' <xform weight="%g" color="%g" ', [density, color]);
|
||||
if symmetry <> 0 then result := result + format('symmetry="%g" ', [symmetry]);
|
||||
|
||||
////// AV: write variation order
|
||||
// AV: write variation order
|
||||
strvar := '';
|
||||
for i := 0 to nrvar - 1 do begin
|
||||
if vars[GetVariationIndex(ifs[i])] <> 0 then
|
||||
strvar := strvar + ifs[i] + #32;
|
||||
for Name in ifs do begin
|
||||
if vars[GetVariationIndex(Name)] <> 0 then
|
||||
strvar := strvar + Name + #32;
|
||||
end;
|
||||
if (strvar <> '') and (pos(#32, strvar) < length(strvar)) then
|
||||
Result := Result + format('var_order="%s" ', [strvar]);
|
||||
@ -1937,9 +2011,8 @@ begin
|
||||
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
|
||||
end;
|
||||
*)
|
||||
for i := 0 to nrvar - 1 do // AV: write in correct order
|
||||
for Name in ifs do // AV: write in correct order
|
||||
begin
|
||||
Name := ifs[i];
|
||||
Value := vars[GetVariationIndex(Name)];
|
||||
if Value <> 0 then
|
||||
Result := Result + Name + format('="%g" ', [Value]);
|
||||
@ -1993,11 +2066,11 @@ begin
|
||||
result := Format(' <finalxform color="%g" ', [color]);
|
||||
if symmetry <> 0 then result := result + format('symmetry="%g" ', [symmetry]);
|
||||
|
||||
////// AV: write variation order
|
||||
// AV: write variation order
|
||||
strvar := '';
|
||||
for i := 0 to nrvar - 1 do begin
|
||||
if vars[GetVariationIndex(ifs[i])] <> 0 then
|
||||
strvar := strvar + ifs[i] + #32;
|
||||
for Name in ifs do begin
|
||||
if vars[GetVariationIndex(Name)] <> 0 then
|
||||
strvar := strvar + Name + #32;
|
||||
end;
|
||||
if (strvar <> '') and (pos(#32, strvar) < length(strvar)) then
|
||||
Result := Result + format('var_order="%s" ', [strvar]);
|
||||
@ -2008,9 +2081,8 @@ begin
|
||||
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
|
||||
end;
|
||||
*)
|
||||
for i := 0 to nrvar - 1 do // AV: write in correct order
|
||||
for Name in ifs do // AV: write in correct order
|
||||
begin
|
||||
Name := ifs[i];
|
||||
Value := vars[GetVariationIndex(Name)];
|
||||
if Value <> 0 then
|
||||
Result := Result + Name + format('="%g" ', [Value]);
|
||||
|
Reference in New Issue
Block a user