2157 lines
53 KiB
ObjectPascal
2157 lines
53 KiB
ObjectPascal
{
|
|
Apophysis Copyright (C) 2001-2004 Mark Townsend
|
|
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
|
|
Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
|
|
|
|
Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
|
|
Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
|
|
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
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
}
|
|
|
|
// REMOVE COMMENT TO COMPILE T-500
|
|
//{$define T500}
|
|
//{$define Light}
|
|
|
|
unit XForm;
|
|
|
|
interface
|
|
|
|
uses
|
|
{$ifdef CPUX86}
|
|
AsmRandom,
|
|
{$endif}
|
|
XFormMan, BaseVariation, Classes;
|
|
|
|
const
|
|
MAX_WEIGHT = 1000.0;
|
|
{$ifndef Light}
|
|
{$ifndef T500}
|
|
NXFORMS = 100;
|
|
{$else}
|
|
NXFORMS = 250; // 500; // AV: to use 1-byte type
|
|
{$endif}
|
|
{$else}
|
|
NXFORMS = 50;
|
|
{$endif}
|
|
|
|
type
|
|
TCPpoint = record
|
|
x, y, z, c: double;
|
|
end;
|
|
PCPpoint = ^TCPpoint;
|
|
|
|
TXYpoint = record
|
|
x, y: double;
|
|
end;
|
|
PXYpoint = ^TXYpoint;
|
|
|
|
{
|
|
T2Cpoint = record
|
|
x, y, c1, c2: double;
|
|
end;
|
|
P2Cpoint = ^T2Cpoint;
|
|
|
|
TMatrix = array[0..2, 0..2] of double;
|
|
}
|
|
|
|
// 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: 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; // :-)
|
|
postXswap: boolean;
|
|
TransformName : string;
|
|
|
|
autoZscale: boolean; // for 3d editing
|
|
transOpacity: double;
|
|
pluginColor: double;
|
|
|
|
modWeights: array [0..NXFORMS] of double;
|
|
PropTable: array of TXForm;
|
|
|
|
// Orientationtype: integer;
|
|
ifs: TStringList; // AV: to keep custom variation order
|
|
private
|
|
vars: array of double; // {normalized} interp coefs between variations
|
|
FNrFunctions: Integer;
|
|
FFunctionList: array of TCalcFunction;
|
|
FCalcFunctionList: array of TCalcFunction;
|
|
|
|
FTx, FTy: double; // must remain in this order
|
|
FPx, FPy: double; // some asm code relies on this
|
|
FTz, FPz: double; // 3d hack
|
|
|
|
FAngle: double;
|
|
FSinA: double;
|
|
FCosA: double;
|
|
FLength: double;
|
|
colorC1, colorC2: double;
|
|
|
|
// precalculated constants for some variations
|
|
polar_vpi, disc_vpi: double;
|
|
polar2_vpi, p2vv2: double;
|
|
|
|
gauss_rnd: array [0..3] of double;
|
|
gauss_N: integer;
|
|
|
|
rx_sin, rx_cos, ry_sin, ry_cos: double;
|
|
px_sin, px_cos, py_sin, py_cos: double;
|
|
|
|
FRegVariations: array of TBaseVariation;
|
|
|
|
procedure PrecalcAngle;
|
|
procedure PrecalcSinCos;
|
|
procedure PrecalcAll;
|
|
procedure DoPostTransform;
|
|
procedure DoInvalidOperation;
|
|
|
|
procedure Linear3D; // vars[0]
|
|
procedure PreBlur3D; // vars[2]
|
|
procedure Spherical; // vars[3]
|
|
procedure Swirl; // vars[4]
|
|
procedure Horseshoe; // vars[5]
|
|
procedure Polar; // vars[6]
|
|
|
|
procedure Disc; // vars[7]
|
|
procedure Spiral; // vars[8]
|
|
procedure hyperbolic; // vars[9]
|
|
procedure Diamond; // vars[10]
|
|
|
|
procedure Eyefish; // vars[11]
|
|
procedure Bubble; // vars[12]
|
|
procedure Cylinder; // vars[13]
|
|
procedure Noise; // vars[14]
|
|
procedure Blur; // vars[15]
|
|
procedure Gaussian; // vars[16]
|
|
procedure ZBlur; // vars[17]
|
|
procedure Blur3D; // vars[18]
|
|
|
|
procedure PreBlur; // vars[19]
|
|
procedure PreZScale; // vars[20]
|
|
procedure PreZTranslate; // vars[21]
|
|
procedure PreRotateX; // vars[22]
|
|
procedure PreRotateY; // vars[23]
|
|
|
|
procedure Flatten; // vars[1]
|
|
procedure ZScale; // vars[24]
|
|
procedure ZTranslate; // vars[25]
|
|
procedure ZCone; // vars[26]
|
|
|
|
procedure PostRotateX; // vars[27]
|
|
procedure PostRotateY; // vars[28]
|
|
|
|
procedure PostMirrorX; // vars[29]
|
|
procedure PostMirrorY; // vars[30]
|
|
procedure PostMirrorZ; // vars[31]
|
|
|
|
procedure Hemisphere; // vars[32]
|
|
procedure Cross; // vars[33]
|
|
procedure Pyramid; // vars[34]
|
|
procedure Polar2; // vars[35]
|
|
|
|
//function Mul33(const M1, M2: TMatrix): TMatrix;
|
|
//function Identity: TMatrix;
|
|
|
|
procedure BuildFunctionlist;
|
|
procedure AddRegVariations;
|
|
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure Clear(keepXaos: boolean = false);
|
|
procedure Prepare;
|
|
procedure PrepareInvalidXForm;
|
|
|
|
procedure Assign(Xform: TXForm);
|
|
|
|
procedure NextPoint(var CPpoint: TCPpoint);
|
|
procedure NextPointTo(var CPpoint, ToPoint: TCPpoint);
|
|
procedure NextPointXY(var px, py: double);
|
|
//procedure NextPoint2C(var p: T2CPoint);
|
|
|
|
// 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);
|
|
procedure ResetVariable(const name: string);
|
|
|
|
function GetVariableStr(const name: string): string;
|
|
procedure SetVariableStr(const name: string; var Value: string);
|
|
|
|
function ToXMLString: string;
|
|
function FinalToXMLString(IsEnabled: boolean): string;
|
|
|
|
function GetVariation(index : integer) : double;
|
|
procedure SetVariation(index : integer; value : double);
|
|
function NumVariations : integer;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, Math, StrUtils;
|
|
|
|
const
|
|
EPS: double = 1E-300;
|
|
|
|
function TXForm.NumVariations : integer;
|
|
begin
|
|
Result := length(vars);
|
|
end;
|
|
|
|
function TXForm.GetVariation(index : integer) : double;
|
|
begin
|
|
Result := vars[index];
|
|
end;
|
|
|
|
procedure TXForm.SetVariation(index : integer; value : double);
|
|
begin
|
|
{
|
|
if (vars[index] = 0) and (value <> 0) then begin
|
|
// Activate var here
|
|
end else begin
|
|
// Deactivate var here
|
|
end;
|
|
}
|
|
vars[index] := value;
|
|
end;
|
|
|
|
|
|
{ TXForm }
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
constructor TXForm.Create;
|
|
var i: Integer;
|
|
begin
|
|
AddRegVariations;
|
|
BuildFunctionlist;
|
|
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));
|
|
|
|
Clear;
|
|
end;
|
|
|
|
procedure TXForm.Clear(keepXaos: boolean = false);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
density := 0;
|
|
color := 0;
|
|
symmetry := 0;
|
|
postXswap := false;
|
|
autoZscale := false;
|
|
|
|
c[0, 0] := 1;
|
|
c[0, 1] := 0;
|
|
c[1, 0] := 0;
|
|
c[1, 1] := 1;
|
|
c[2, 0] := 0;
|
|
c[2, 1] := 0;
|
|
|
|
p[0, 0] := 1;
|
|
p[0, 1] := 0;
|
|
p[1, 0] := 0;
|
|
p[1, 1] := 1;
|
|
p[2, 0] := 0;
|
|
p[2, 1] := 0;
|
|
|
|
vars[0] := 1;
|
|
for i := 1 to High(vars) do
|
|
vars[i] := 0;
|
|
|
|
if not keepXaos then // AV: for linked xforms
|
|
for i := 0 to NXFORMS do
|
|
modWeights[i] := 1;
|
|
|
|
for i := 0 to NrVar-1 do // restore default order
|
|
ifs.Strings[i] := Varnames(i);
|
|
|
|
transOpacity := 1;
|
|
pluginColor := 1;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Prepare;
|
|
var
|
|
i, v: integer;
|
|
CalculateAngle, CalculateSinCos, CalculateLength: boolean;
|
|
mode: double;
|
|
vn: string;
|
|
UsedVars: TStringList;
|
|
begin
|
|
c00 := c[0][0];
|
|
c01 := c[0][1];
|
|
c10 := c[1][0];
|
|
c11 := c[1][1];
|
|
c20 := c[2][0];
|
|
c21 := c[2][1];
|
|
|
|
colorC1 := (1 + symmetry)/2;
|
|
colorC2 := color*(1 - symmetry)/2;
|
|
|
|
FNrFunctions := 0;
|
|
|
|
for i := 0 to High(FRegVariations) do begin
|
|
FRegVariations[i].FPX := @FPX;
|
|
FRegVariations[i].FPY := @FPY;
|
|
FRegVariations[i].FPz := @FPz;
|
|
FRegVariations[i].FTX := @FTX;
|
|
FRegVariations[i].FTY := @FTY;
|
|
FRegVariations[i].FTz := @FTz;
|
|
FRegVariations[i].a := c00;
|
|
FRegVariations[i].b := c01;
|
|
FRegVariations[i].c := c10;
|
|
FRegVariations[i].d := c11;
|
|
FRegVariations[i].e := c20;
|
|
FRegVariations[i].f := c21;
|
|
FRegVariations[i].color := @vc;
|
|
|
|
FRegVariations[i].vvar := vars[i + NRLOCVAR];
|
|
FRegVariations[i].Prepare;
|
|
FRegVariations[i].GetCalcFunction(FFunctionList[NRLOCVAR + i]);
|
|
end;
|
|
|
|
SetLength(FCalcFunctionList, NrVar + 2);
|
|
|
|
CalculateAngle := (vars[6] <> 0.0) or (vars[7] <> 0.0) or (vars[35] <> 0.0);
|
|
// CalculateLength := False;
|
|
CalculateSinCos := (vars[8] <> 0.0) or (vars[10] <> 0.0);
|
|
|
|
UsedVars := TStringList.Create;
|
|
|
|
// Pre- variations
|
|
for vn in ifs do
|
|
begin
|
|
v := GetVariationIndex(vn);
|
|
if (vars[v] <> 0.0) then
|
|
begin
|
|
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
|
|
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;
|
|
|
|
// Precalc must be called after pre- vars
|
|
if CalculateAngle or CalculateSinCos then
|
|
begin
|
|
if CalculateAngle and CalculateSinCos then
|
|
FCalcFunctionList[FNrFunctions] := PrecalcAll
|
|
else if CalculateAngle then
|
|
FCalcFunctionList[FNrFunctions] := PrecalcAngle
|
|
else //if CalculateSinCos then
|
|
FCalcFunctionList[FNrFunctions] := PrecalcSinCos;
|
|
Inc(FNrFunctions);
|
|
end;
|
|
|
|
// Normal variations
|
|
for vn in UsedVars do // AV: iterate through used variations only
|
|
begin
|
|
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
|
|
GetVariable(vn + '_mode', mode);
|
|
if (mode <> 1) then continue;
|
|
end;
|
|
|
|
v := GetVariationIndex(vn);
|
|
FCalcFunctionList[FNrFunctions] := FFunctionList[v];
|
|
Inc(FNrFunctions);
|
|
end;
|
|
|
|
// Post- variations
|
|
for vn in UsedVars do // AV: iterate through used variations only
|
|
begin
|
|
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
|
|
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;
|
|
p2vv2 := polar2_vpi * 0.5;
|
|
|
|
gauss_rnd[0] := random;
|
|
gauss_rnd[1] := random;
|
|
gauss_rnd[2] := random;
|
|
gauss_rnd[3] := random;
|
|
gauss_N := 0;
|
|
|
|
rx_sin := sin(vars[22] * pi/2);
|
|
rx_cos := cos(vars[22] * pi/2);
|
|
ry_sin := sin(vars[23] * pi/2);
|
|
ry_cos := cos(vars[23] * pi/2);
|
|
|
|
px_sin := sin(vars[27] * pi/2);
|
|
px_cos := cos(vars[27] * pi/2);
|
|
py_sin := sin(vars[28] * pi/2);
|
|
py_cos := cos(vars[28] * pi/2);
|
|
|
|
if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then
|
|
begin
|
|
p00 := p[0][0];
|
|
p01 := p[0][1];
|
|
p10 := p[1][0];
|
|
p11 := p[1][1];
|
|
p20 := p[2][0];
|
|
p21 := p[2][1];
|
|
|
|
FCalcFunctionList[FNrFunctions] := DoPostTransform;
|
|
Inc(FNrFunctions);
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TXForm.PrepareInvalidXForm;
|
|
begin
|
|
c00 := 1;
|
|
c01 := 0;
|
|
c10 := 0;
|
|
c11 := 1;
|
|
c20 := 0;
|
|
c21 := 0;
|
|
|
|
colorC1 := 1;
|
|
colorC2 := 0;
|
|
|
|
FNrFunctions := 1;
|
|
SetLength(FCalcFunctionList, 1);
|
|
FCalcFunctionList[0] := DoInvalidOperation;
|
|
end;
|
|
|
|
procedure TXForm.PrecalcAngle;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FAngle := arctan2(FTx, FTy);
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTx]
|
|
fld qword ptr [eax + FTy]
|
|
fpatan
|
|
fstp qword ptr [eax + FAngle]
|
|
//fwait
|
|
{$endif}
|
|
end;
|
|
|
|
procedure TXForm.PrecalcSinCos;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FLength := sqrt(sqr(FTx) + sqr(FTy)) + EPS;
|
|
FSinA := FTx / FLength;
|
|
FCosA := FTy / FLength;
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTx]
|
|
fld qword ptr [eax + FTy]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fsqrt
|
|
fadd qword ptr [EPS] // avoid divide by zero...(?)
|
|
fdiv st(1), st
|
|
fdiv st(2), st
|
|
fstp qword ptr [eax + FLength]
|
|
fstp qword ptr [eax + FCosA]
|
|
fstp qword ptr [eax + FSinA]
|
|
//fwait
|
|
{$endif}
|
|
end;
|
|
|
|
procedure TXForm.PrecalcAll;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FLength := sqrt(sqr(FTx) + sqr(FTy)) + EPS;
|
|
FSinA := FTx / FLength;
|
|
FCosA := FTy / FLength;
|
|
FAngle := arctan2(FTx, FTy);
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTx]
|
|
fld qword ptr [eax + FTy]
|
|
fld st(1)
|
|
fld st(1)
|
|
fpatan
|
|
fstp qword ptr [eax + FAngle]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fsqrt
|
|
fadd qword ptr [EPS] // avoid divide by zero...(?)
|
|
fdiv st(1), st
|
|
fdiv st(2), st
|
|
fstp qword ptr [eax + FLength]
|
|
fstp qword ptr [eax + FCosA]
|
|
fstp qword ptr [eax + FSinA]
|
|
//fwait
|
|
{$endif}
|
|
end;
|
|
|
|
procedure TXForm.DoPostTransform;
|
|
{$ifndef _ASM_}
|
|
var
|
|
tmp: double;
|
|
begin
|
|
tmp := FPx;
|
|
FPx := p00 * FPx + p10 * FPy + p20;
|
|
FPy := p01 * tmp + p11 * FPy + p21;
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FPy]
|
|
fld qword ptr [eax + FPx]
|
|
fld st(1)
|
|
fmul qword ptr [eax + p10]
|
|
fld st(1)
|
|
fmul qword ptr [eax + p00]
|
|
faddp
|
|
fadd qword ptr [eax + p20]
|
|
fstp qword ptr [eax + FPx]
|
|
fmul qword ptr [eax + p01]
|
|
fld qword ptr [eax + p11]
|
|
fmulp st(2), st
|
|
faddp
|
|
fadd qword ptr [eax + p21]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
procedure TXForm.DoInvalidOperation;
|
|
begin
|
|
raise EMathError.Create('FCalcFunction not initialized!? Probably corrupted flame.');
|
|
end;
|
|
|
|
//--0--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Linear3D;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPx := FPx + vars[0] * FTx;
|
|
FPy := FPy + vars[0] * FTy;
|
|
FPz := FPz + vars[0] * FTz;
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx]
|
|
|
|
fld qword ptr [eax + FTz]
|
|
fmul st, st(1)
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
|
|
fld qword ptr [eax + FTx]
|
|
fmul st, st(1)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fld qword ptr [eax + FTy]
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Flatten;
|
|
begin
|
|
// FPz := 0;
|
|
// AV: changed to pre_mode for compatibility with "3D-Hack" flames
|
|
FTz := 0;
|
|
end;
|
|
|
|
//--1--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PreBlur3D; // AV
|
|
var
|
|
r, sina, cosa, sinb, cosb: double;
|
|
begin
|
|
Randomize;
|
|
SinCos(random * 2 * pi, sina, cosa);
|
|
r := vars[2] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2);
|
|
gauss_rnd[gauss_N] := random;
|
|
gauss_N := (gauss_N+1) and $3;
|
|
|
|
SinCos(random * pi, sinb, cosb);
|
|
FTx := FTx + r * sinb * cosa;
|
|
FTy := FTy + r * sinb * sina;
|
|
FTz := FTz + r * cosb;
|
|
end;
|
|
|
|
//--2--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Spherical;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r: double;
|
|
begin
|
|
r := vars[3] / (sqr(FTx) + sqr(FTy) + EPS);
|
|
FPx := FPx + FTx * r;
|
|
FPy := FPy + FTy * r;
|
|
FPz := FPz + FTz * vars[3];
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fadd qword ptr [EPS]
|
|
mov edx, [eax + vars]
|
|
// AV: for Apo7X.15C compatibility
|
|
fld qword ptr [edx + 3*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main code
|
|
fdivr qword ptr [edx + 3*8]
|
|
fmul st(2), st
|
|
fmulp
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--3--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Swirl;
|
|
{$ifndef _ASM_}
|
|
var
|
|
sinr, cosr: double;
|
|
begin
|
|
SinCos(sqr(FTx) + sqr(FTy), sinr, cosr);
|
|
FPx := FPx + vars[4] * (sinr * FTx - cosr * FTy);
|
|
FPy := FPy + vars[4] * (cosr * FTx + sinr * FTy);
|
|
FPz := FPz + FTz * vars[4];
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 4*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fsincos
|
|
fld st(1)
|
|
fmul st, st(3)
|
|
fld st(1)
|
|
fmul st, st(5)
|
|
fsubp st(1), st
|
|
fmul st, st(5)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp st(2), st
|
|
fmulp st(2), st
|
|
faddp
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--4--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Horseshoe;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r: double;
|
|
begin
|
|
r := vars[5] / (sqrt(sqr(FTx) + sqr(FTy)) + EPS);
|
|
FPx := FPx + (FTx - FTy) * (FTx + FTy) * r;
|
|
FPy := FPy + (2*FTx*FTy) * r;
|
|
FPz := FPz + FTz * vars[5];
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTx]
|
|
fld qword ptr [eax + FTy]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fsqrt
|
|
fadd qword ptr [EPS]
|
|
mov edx, [eax + vars]
|
|
// AV: for Apo7X.15C compatibility
|
|
fld qword ptr [edx + 5*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main code
|
|
fdivr qword ptr [edx + 5*8]
|
|
fld st(2)
|
|
fadd st, st(2)
|
|
fld st(3)
|
|
fsub st, st(3)
|
|
fmulp
|
|
fmul st, st(1)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp
|
|
fmulp
|
|
fadd st, st
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--5--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Polar;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPx := FPx + polar_vpi * FAngle; //vars[5] * FAngle / PI;
|
|
FPy := FPy + vars[6] * (sqrt(sqr(FTx) + sqr(FTy)) - 1.0);
|
|
FPz := FPz + FTz * vars[6];
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FAngle]
|
|
fmul qword ptr [eax + polar_vpi]
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fld qword ptr [eax + FTx]
|
|
fmul st, st
|
|
fld qword ptr [eax + FTy]
|
|
fmul st, st
|
|
faddp
|
|
fsqrt
|
|
fld1
|
|
fsubp st(1), st
|
|
mov edx, [eax + vars]
|
|
// AV: for Apo7X.15C compatibility
|
|
fld qword ptr [edx + 6*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main code
|
|
fmul qword ptr [edx + 6*8]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--6--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Disc;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r, sinr, cosr: double;
|
|
begin
|
|
SinCos(PI * sqrt(sqr(FTx) + sqr(FTy)), sinr, cosr);
|
|
r := disc_vpi * FAngle; //vars[7] * FAngle / PI;
|
|
FPx := FPx + sinr * r;
|
|
FPy := FPy + cosr * r;
|
|
FPz := FPz + FTz * vars[7];
|
|
{$else}
|
|
asm
|
|
// AV: 3D stuff
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 7*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
fld qword ptr [eax + disc_vpi]
|
|
fmul qword ptr [eax + FAngle]
|
|
fld qword ptr [eax + FTx]
|
|
fmul st, st
|
|
fld qword ptr [eax + FTy]
|
|
fmul st, st
|
|
faddp
|
|
fsqrt
|
|
fldpi
|
|
fmulp
|
|
fsincos
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fmulp
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--7--////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Spiral;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r, sinr, cosr: double;
|
|
begin
|
|
r := Flength + EPS; // 1E-6;
|
|
SinCos(r, sinr, cosr);
|
|
r := vars[8] / r;
|
|
FPx := FPx + (FCosA + sinr) * r;
|
|
FPy := FPy + (FsinA - cosr) * r;
|
|
FPz := FPz + FTz * vars[8];
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 8*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
fld qword ptr [eax + FLength]
|
|
fadd qword ptr [EPS]
|
|
fdiv st(1), st
|
|
fsincos
|
|
fsubr qword ptr [eax + FSinA]
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fadd qword ptr [eax + FCosA]
|
|
fmulp
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--10--///////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Hyperbolic;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPx := FPx + vars[9] * FTx / (sqr(FTx) + sqr(FTy) + EPS);
|
|
FPy := FPy + vars[9] * FTy;
|
|
FPz := FPz + FTz * vars[9];
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 9*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fadd qword ptr [EPS]
|
|
fdivp st(1), st
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--11--///////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Diamond; // AV: Diamond, i.e. rotated Square
|
|
{$ifndef _ASM_}
|
|
var
|
|
sinr, cosr: double;
|
|
begin
|
|
SinCos(FLength, sinr, cosr);
|
|
FPx := FPx + vars[10] * FSinA * cosr;
|
|
FPy := FPy + vars[10] * FCosA * sinr;
|
|
FPz := FPz + FTz * vars[10];
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 10*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
fld qword ptr [eax + FLength]
|
|
fsincos
|
|
fmul qword ptr [eax + FSinA]
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmul qword ptr [eax + FCosA]
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//--12--///////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Eyefish;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r: double;
|
|
begin
|
|
r := 2 * vars[11] / (sqrt(sqr(FTx) + sqr(FTy)) + 1);
|
|
FPx := FPx + r * FTx;
|
|
FPy := FPy + r * FTy;
|
|
FPz := FPz + FTz * vars[11];
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 11*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
fadd st, st
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fsqrt
|
|
fld1
|
|
faddp
|
|
fdivp st(3), st
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Bubble;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r: double;
|
|
begin
|
|
r := (sqr(FTx) + sqr(FTy))/4 + 1;
|
|
FPz := FPz + vars[12] * (2 / r - 1);
|
|
|
|
r := vars[12] / r;
|
|
|
|
FPx := FPx + r * FTx;
|
|
FPy := FPy + r * FTy;
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fld1
|
|
fadd st, st
|
|
fadd st, st
|
|
fdivp st(1), st
|
|
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 12*8]
|
|
|
|
fld1
|
|
fadd st(2), st
|
|
fdivr st(2), st
|
|
|
|
fld st(2)
|
|
fadd st, st
|
|
fsubrp st(1), st
|
|
fmul st, st(1)
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
|
|
fmulp
|
|
|
|
fmul st(2), st
|
|
fmulp
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Cylinder;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPx := FPx + vars[13] * sin(FTx);
|
|
FPy := FPy + vars[13] * FTy;
|
|
FPz := FPz + vars[13] * cos(FTx);
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 13*8]
|
|
fld qword ptr [eax + FTx]
|
|
fsincos
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
fld qword ptr [eax + FTy]
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fmulp
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Noise;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r, s, sinr, cosr: double;
|
|
begin
|
|
// Randomize here = HACK! Fix me...
|
|
Randomize; SinCos(random * 2*pi, sinr, cosr);
|
|
s := vars[14];
|
|
r := s * random;
|
|
FPx := FPx + FTx * r * cosr;
|
|
FPy := FPy + FTy * r * sinr;
|
|
FPz := FPz + FTz * s;
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 14*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
call AsmRandExt
|
|
fmulp
|
|
call AsmRandExt
|
|
fadd st, st
|
|
fldpi
|
|
fmulp
|
|
fsincos
|
|
fmul st, st(2)
|
|
fmul qword ptr [eax + FTx]
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp
|
|
fmul qword ptr [eax + FTy]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Blur;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r, sina, cosa: double;
|
|
begin
|
|
// Randomize here = HACK! Fix me...
|
|
Randomize; SinCos(random * 2*pi, sina, cosa);
|
|
r := vars[15] * random;
|
|
FPx := FPx + r * cosa;
|
|
FPy := FPy + r * sina;
|
|
FPz := FPz + vars[15] * FTz;
|
|
{$else}
|
|
asm
|
|
mov edx, [eax + vars]
|
|
fld qword ptr [edx + 15*8]
|
|
// AV: 3D stuff
|
|
fld st
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main calculations
|
|
call AsmRandExt
|
|
fmulp
|
|
call AsmRandExt
|
|
fadd st, st
|
|
fldpi
|
|
fmulp
|
|
fsincos
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Gaussian;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r, sina, cosa: double;
|
|
begin
|
|
// Randomize here = HACK! Fix me...
|
|
Randomize; SinCos(random * 2*pi, sina, cosa);
|
|
r := vars[16] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2);
|
|
gauss_rnd[gauss_N] := random;
|
|
gauss_N := (gauss_N+1) and $3;
|
|
|
|
FPx := FPx + r * cosa;
|
|
FPy := FPy + r * sina;
|
|
//FPz := FPz + vars[16] * FTz; // AV removed
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + gauss_rnd]
|
|
fadd qword ptr [eax + gauss_rnd+8]
|
|
fadd qword ptr [eax + gauss_rnd+16]
|
|
fadd qword ptr [eax + gauss_rnd+24]
|
|
fld1
|
|
fadd st,st
|
|
fsubp st(1),st
|
|
mov edx, [eax + vars]
|
|
// AV: removed 3D-support since we have zcale and blur3D
|
|
{
|
|
fld qword ptr [edx + 16*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
}
|
|
fmul qword ptr [edx + 16*8]
|
|
call AsmRandExt
|
|
mov edx, [eax + gauss_N]
|
|
fst qword ptr [eax + gauss_rnd + edx*8]
|
|
inc edx
|
|
and edx,$03
|
|
mov [eax + gauss_N], edx
|
|
|
|
fadd st, st
|
|
fldpi
|
|
fmulp
|
|
fsincos
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fmulp
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.ZBlur;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPz := FPz + vars[17] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2);
|
|
gauss_rnd[gauss_N] := random;
|
|
gauss_N := (gauss_N+1) and $3;
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + gauss_rnd]
|
|
fadd qword ptr [eax + gauss_rnd+8]
|
|
fadd qword ptr [eax + gauss_rnd+16]
|
|
fadd qword ptr [eax + gauss_rnd+24]
|
|
fld1
|
|
fadd st,st
|
|
fsubp st(1),st
|
|
mov edx, [eax + vars]
|
|
fmul qword ptr [edx + 17*8]
|
|
call AsmRandExt
|
|
mov edx, [eax + gauss_N]
|
|
fstp qword ptr [eax + gauss_rnd + edx*8]
|
|
inc edx
|
|
and edx,$03
|
|
mov [eax + gauss_N], edx
|
|
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Blur3D;
|
|
var
|
|
r, sina, cosa, sinb, cosb: double;
|
|
begin
|
|
// Randomize here = HACK! Fix me...
|
|
Randomize; SinCos(random * 2*pi, sina, cosa);
|
|
r := vars[18] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2);
|
|
gauss_rnd[gauss_N] := random;
|
|
gauss_N := (gauss_N+1) and $3;
|
|
|
|
SinCos(random * pi, sinb, cosb);
|
|
FPx := FPx + r * sinb * cosa;
|
|
FPy := FPy + r * sinb * sina;
|
|
FPz := FPz + r * cosb;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PreBlur;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r, sina, cosa: double;
|
|
begin
|
|
// Randomize here = HACK! Fix me...
|
|
Randomize; SinCos(random * 2*pi, sina, cosa);
|
|
r := vars[19] * (gauss_rnd[0] + gauss_rnd[1] + gauss_rnd[2] + gauss_rnd[3] - 2);
|
|
gauss_rnd[gauss_N] := random;
|
|
gauss_N := (gauss_N+1) and $3;
|
|
|
|
FTx := FTx + r * cosa;
|
|
FTy := FTy + r * sina;
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + gauss_rnd]
|
|
fadd qword ptr [eax + gauss_rnd+8]
|
|
fadd qword ptr [eax + gauss_rnd+16]
|
|
fadd qword ptr [eax + gauss_rnd+24]
|
|
fld1
|
|
fadd st,st
|
|
fsubp st(1),st
|
|
mov edx, [eax + vars]
|
|
fmul qword ptr [edx + 19*8]
|
|
call AsmRandExt
|
|
mov edx, [eax + gauss_N]
|
|
fst qword ptr [eax + gauss_rnd + edx*8]
|
|
inc edx
|
|
and edx,$03
|
|
mov [eax + gauss_N], edx
|
|
|
|
fadd st, st
|
|
fldpi
|
|
fmulp
|
|
fsincos
|
|
fmul st, st(2)
|
|
fadd qword ptr [eax + FTx]
|
|
fstp qword ptr [eax + FTx]
|
|
fmulp
|
|
fadd qword ptr [eax + FTy]
|
|
fstp qword ptr [eax + FTy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PreZScale;
|
|
begin
|
|
FTz := FTz * vars[20];
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PreZTranslate;
|
|
begin
|
|
FTz := FTz + vars[21];
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PreRotateX;
|
|
var
|
|
z: double;
|
|
begin
|
|
z := rx_cos * FTz - rx_sin * FTy;
|
|
FTy := rx_sin * FTz + rx_cos * FTy;
|
|
FTz := z;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PreRotateY;
|
|
var
|
|
x: double;
|
|
begin
|
|
x := ry_cos * FTx - ry_sin * FTz;
|
|
FTz := ry_sin * FTx + ry_cos * FTz;
|
|
FTx := x;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.ZScale;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPz := FPz + vars[24] * FTz;
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTz]
|
|
mov edx, [eax + vars]
|
|
fmul qword ptr [edx + 24*8]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.ZTranslate;
|
|
begin
|
|
FPz := FPz + vars[25];
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.ZCone;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPz := FPz + vars[26] * sqrt(sqr(FTx) + sqr(FTy));
|
|
{$else}
|
|
asm
|
|
fld qword ptr [eax + FTx]
|
|
fmul st,st
|
|
fld qword ptr [eax + FTy]
|
|
fmul st,st
|
|
faddp
|
|
fsqrt
|
|
mov edx, [eax + vars]
|
|
fmul qword ptr [edx + 26*8]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PostRotateX;
|
|
var
|
|
z: double;
|
|
begin
|
|
z := px_cos * FPz - px_sin * FPy;
|
|
FPy := px_sin * FPz + px_cos * FPy;
|
|
FPz := z;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PostRotateY;
|
|
var
|
|
x: double;
|
|
begin
|
|
x := py_cos * FPx - py_sin * FPz;
|
|
FPz := py_sin * FPx + py_cos * FPz;
|
|
FPx := x;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PostMirrorX;
|
|
begin
|
|
FPx := abs(FPx);
|
|
if (random(2) = 1) then FPx := -FPx;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PostMirrorY;
|
|
begin
|
|
FPy := abs(FPy);
|
|
if (random(2) = 1) then FPy := -FPy;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.PostMirrorZ;
|
|
begin
|
|
FPz := abs(FPz);
|
|
if (random(2) = 1) then FPz := -FPz;
|
|
end;
|
|
|
|
/////////////////////////////////
|
|
procedure TXForm.Hemisphere;
|
|
{$ifndef _ASM_}
|
|
var
|
|
t: double;
|
|
begin
|
|
t := vars[32] / sqrt(sqr(FTx) + sqr(FTy) + 1);
|
|
|
|
FPx := FPx + FTx * t;
|
|
FPy := FPy + FTy * t;
|
|
FPz := FPz + t;
|
|
{$else}
|
|
asm // rewritten by AV
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st(1)
|
|
fmul st, st
|
|
fld st(1)
|
|
fmul st, st
|
|
faddp
|
|
fld1
|
|
faddp
|
|
fsqrt
|
|
mov edx, [eax + vars]
|
|
fdivr qword ptr [edx + 32*8]
|
|
fmul st(2), st
|
|
fmul st(1), st
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
//////////////////////////////
|
|
procedure TXForm.Cross;
|
|
const epsv: double = 1.0e-20;
|
|
{$ifndef _ASM_}
|
|
var
|
|
r: double;
|
|
begin
|
|
r := abs((FTx - FTy) * (FTx + FTy)) + epsv; // AV: fixed
|
|
// AV: abs cannot be negative, so it's useless
|
|
//if (r < 0) then r := r * -1.0;
|
|
r := vars[33] / r;
|
|
|
|
FPx := FPx + FTx * r;
|
|
FPy := FPy + FTy * r;
|
|
FPz := FPz + vars[33] * FTz;
|
|
{$else}
|
|
asm //written by AV
|
|
fld qword ptr [eax + FTy]
|
|
fld qword ptr [eax + FTx]
|
|
fld st
|
|
fsub st, st(2)
|
|
fld st(1)
|
|
fadd st, st(3)
|
|
fmulp
|
|
fabs
|
|
fadd epsv
|
|
mov edx, [eax + vars]
|
|
// for Apo7X.15C compatibility
|
|
fld qword ptr [edx + 33*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main code
|
|
fdivr qword ptr [edx + 33*8]
|
|
fmul st(2), st
|
|
fmulp
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
|
|
/////////////////////////////
|
|
procedure TXForm.Pyramid;
|
|
var
|
|
x, y, z, r: double;
|
|
begin
|
|
x := IntPower(FTx, 3);
|
|
y := IntPower(FTy, 3);
|
|
z := IntPower(abs(FTz), 3);
|
|
r := vars[34] / (abs(x) + abs(y) + z + 1E-9);
|
|
FPx := FPx + x * r;
|
|
FPy := FPy + y * r;
|
|
FPz := FPz + z * r;
|
|
end;
|
|
////////////////////////////////////////////////
|
|
|
|
procedure TXForm.Polar2;
|
|
{$ifndef _ASM_}
|
|
begin
|
|
FPx := FPx + polar2_vpi * FAngle;
|
|
FPy := FPy + p2vv2 * Ln(sqr(FTx) + sqr(FTy) + EPS);
|
|
FPz := FPz + FTz * vars[35];
|
|
{$else}
|
|
asm // written by AV
|
|
fld qword ptr [eax + FAngle]
|
|
fmul qword ptr [eax + polar2_vpi]
|
|
fadd qword ptr [eax + FPx]
|
|
fstp qword ptr [eax + FPx]
|
|
|
|
fld qword ptr [eax + FTx]
|
|
fmul st, st
|
|
fld qword ptr [eax + FTy]
|
|
fmul st, st
|
|
faddp
|
|
fadd qword ptr [EPS]
|
|
fldln2
|
|
fxch
|
|
fyl2x
|
|
fmul qword ptr [eax + p2vv2]
|
|
mov edx, [eax + vars]
|
|
// AV: for Apo7X.15C compatibility
|
|
fld qword ptr [edx + 35*8]
|
|
fmul qword ptr [eax + FTz]
|
|
fadd qword ptr [eax + FPz]
|
|
fstp qword ptr [eax + FPz]
|
|
// main code
|
|
fmul qword ptr [edx + 35*8]
|
|
fadd qword ptr [eax + FPy]
|
|
fstp qword ptr [eax + FPy]
|
|
fwait
|
|
{$endif}
|
|
end;
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
procedure TXForm.NextPoint(var CPpoint: TCPpoint);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
// first compute the color coord
|
|
CPpoint.c := CPpoint.c * colorC1 + colorC2;
|
|
vc := CPpoint.c;
|
|
|
|
FTx := c00 * CPpoint.x + c10 * CPpoint.y + c20;
|
|
FTy := c01 * CPpoint.x + c11 * CPpoint.y + c21;
|
|
FTz := CPpoint.z;
|
|
|
|
Fpx := 0;
|
|
Fpy := 0;
|
|
Fpz := 0;
|
|
|
|
for i:= 0 to FNrFunctions-1 do
|
|
FCalcFunctionList[i];
|
|
|
|
CPpoint.c := CPpoint.c + pluginColor * (vc - CPpoint.c);
|
|
CPpoint.x := FPx;
|
|
CPpoint.y := FPy;
|
|
CPPoint.z := FPz;
|
|
end;
|
|
|
|
procedure TXForm.NextPointTo(var CPpoint, ToPoint: TCPpoint);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
ToPoint.c := CPpoint.c * colorC1 + colorC2;
|
|
vc := ToPoint.c;
|
|
|
|
FTx := c00 * CPpoint.x + c10 * CPpoint.y + c20;
|
|
FTy := c01 * CPpoint.x + c11 * CPpoint.y + c21;
|
|
FTz := CPpoint.z;
|
|
|
|
Fpx := 0;
|
|
Fpy := 0;
|
|
Fpz := 0;
|
|
|
|
for i:= 0 to FNrFunctions-1 do
|
|
FCalcFunctionList[i];
|
|
|
|
ToPoint.c := ToPoint.c + pluginColor * (vc - ToPoint.c);
|
|
ToPoint.x := FPx;
|
|
ToPoint.y := FPy;
|
|
ToPoint.z := FPz;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
(*
|
|
procedure TXForm.NextPoint2C(var p: T2CPoint);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
// first compute the color coord
|
|
p.c1 := p.c1 * colorC1 + colorC2;
|
|
p.c2 := p.c2 * colorC1 + colorC2;
|
|
|
|
FTx := c00 * p.x + c10 * p.y + c20;
|
|
FTy := c01 * p.x + c11 * p.y + c21;
|
|
|
|
Fpx := 0;
|
|
Fpy := 0;
|
|
|
|
for i:= 0 to FNrFunctions-1 do
|
|
FCalcFunctionList[i];
|
|
|
|
p.x := FPx;
|
|
p.y := FPy;
|
|
end;
|
|
*)
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.NextPointXY(var px, py: double);
|
|
var
|
|
i: integer;
|
|
begin
|
|
FTx := c00 * px + c10 * py + c20;
|
|
FTy := c01 * px + c11 * py + c21;
|
|
FTz := 0;
|
|
|
|
Fpx := 0;
|
|
Fpy := 0;
|
|
|
|
for i:= 0 to FNrFunctions-1 do
|
|
FCalcFunctionList[i];
|
|
|
|
px := FPx;
|
|
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;
|
|
|
|
(*
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
{
|
|
[00 01 02]
|
|
[10 11 12]
|
|
[20 21 22]
|
|
|
|
[a b e ]
|
|
[c d f ]
|
|
[0 0 1 ]
|
|
}
|
|
|
|
function TXForm.Mul33(const M1, M2: TMatrix): TMatrix;
|
|
begin
|
|
result[0, 0] := M1[0][0] * M2[0][0] + M1[0][1] * M2[1][0] + M1[0][2] * M2[2][0];
|
|
result[0, 1] := M1[0][0] * M2[0][1] + M1[0][1] * M2[1][1] + M1[0][2] * M2[2][1];
|
|
result[0, 2] := M1[0][0] * M2[0][2] + M1[0][1] * M2[1][2] + M1[0][2] * M2[2][2];
|
|
result[1, 0] := M1[1][0] * M2[0][0] + M1[1][1] * M2[1][0] + M1[1][2] * M2[2][0];
|
|
result[1, 1] := M1[1][0] * M2[0][1] + M1[1][1] * M2[1][1] + M1[1][2] * M2[2][1];
|
|
result[1, 2] := M1[1][0] * M2[0][2] + M1[1][1] * M2[1][2] + M1[1][2] * M2[2][2];
|
|
result[2, 0] := M1[2][0] * M2[0][0] + M1[2][1] * M2[1][0] + M1[2][2] * M2[2][0];
|
|
result[2, 1] := M1[2][0] * M2[0][1] + M1[2][1] * M2[1][1] + M1[2][2] * M2[2][1]; // AV: fixed indices
|
|
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;
|
|
begin
|
|
for i := 0 to 2 do
|
|
for j := 0 to 2 do
|
|
Result[i, j] := 0;
|
|
Result[0][0] := 1;
|
|
Result[1][1] := 1;
|
|
Result[2][2] := 1;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
procedure TXForm.Rotate(const degrees: double);
|
|
var
|
|
r: double;
|
|
Matrix, M1: TMatrix;
|
|
begin
|
|
r := degrees * pi / 180;
|
|
M1 := Identity;
|
|
M1[0, 0] := cos(r);
|
|
M1[0, 1] := -sin(r);
|
|
M1[1, 0] := sin(r);
|
|
M1[1, 1] := cos(r);
|
|
Matrix := Identity;
|
|
|
|
Matrix[0][0] := c[0, 0];
|
|
Matrix[0][1] := c[0, 1];
|
|
Matrix[1][0] := c[1, 0];
|
|
Matrix[1][1] := c[1, 1];
|
|
Matrix[0][2] := c[2, 0];
|
|
Matrix[1][2] := c[2, 1];
|
|
Matrix := Mul33(Matrix, M1);
|
|
c[0, 0] := Matrix[0][0];
|
|
c[0, 1] := Matrix[0][1];
|
|
c[1, 0] := Matrix[1][0];
|
|
c[1, 1] := Matrix[1][1];
|
|
c[2, 0] := Matrix[0][2];
|
|
c[2, 1] := Matrix[1][2];
|
|
end;
|
|
|
|
procedure TXForm.Translate(const x, y: double);
|
|
var
|
|
Matrix, M1: TMatrix;
|
|
begin
|
|
M1 := Identity;
|
|
M1[0, 2] := x;
|
|
M1[1, 2] := y;
|
|
Matrix := Identity;
|
|
|
|
Matrix[0][0] := c[0, 0];
|
|
Matrix[0][1] := c[0, 1];
|
|
Matrix[1][0] := c[1, 0];
|
|
Matrix[1][1] := c[1, 1];
|
|
Matrix[0][2] := c[2, 0];
|
|
Matrix[1][2] := c[2, 1];
|
|
Matrix := Mul33(Matrix, M1);
|
|
c[0, 0] := Matrix[0][0];
|
|
c[0, 1] := Matrix[0][1];
|
|
c[1, 0] := Matrix[1][0];
|
|
c[1, 1] := Matrix[1][1];
|
|
c[2, 0] := Matrix[0][2];
|
|
c[2, 1] := Matrix[1][2];
|
|
end;
|
|
|
|
procedure TXForm.Multiply(const a, b, c, d: double);
|
|
var
|
|
Matrix, M1: TMatrix;
|
|
begin
|
|
M1 := Identity;
|
|
M1[0, 0] := a;
|
|
M1[0, 1] := b;
|
|
M1[1, 0] := c;
|
|
M1[1, 1] := d;
|
|
Matrix := Identity;
|
|
Matrix[0][0] := Self.c[0, 0];
|
|
Matrix[0][1] := Self.c[0, 1];
|
|
Matrix[1][0] := Self.c[1, 0];
|
|
Matrix[1][1] := Self.c[1, 1];
|
|
Matrix[0][2] := Self.c[2, 0];
|
|
Matrix[1][2] := Self.c[2, 1];
|
|
Matrix := Mul33(Matrix, M1);
|
|
Self.c[0, 0] := Matrix[0][0];
|
|
Self.c[0, 1] := Matrix[0][1];
|
|
Self.c[1, 0] := Matrix[1][0];
|
|
Self.c[1, 1] := Matrix[1][1];
|
|
Self.c[2, 0] := Matrix[0][2];
|
|
Self.c[2, 1] := Matrix[1][2];
|
|
end;
|
|
|
|
procedure TXForm.Scale(const s: double);
|
|
var
|
|
Matrix, M1: TMatrix;
|
|
begin
|
|
M1 := Identity;
|
|
M1[0, 0] := s;
|
|
M1[1, 1] := s;
|
|
Matrix := Identity;
|
|
Matrix[0][0] := c[0, 0];
|
|
Matrix[0][1] := c[0, 1];
|
|
Matrix[1][0] := c[1, 0];
|
|
Matrix[1][1] := c[1, 1];
|
|
Matrix[0][2] := c[2, 0];
|
|
Matrix[1][2] := c[2, 1];
|
|
Matrix := Mul33(Matrix, M1);
|
|
c[0, 0] := Matrix[0][0];
|
|
c[0, 1] := Matrix[0][1];
|
|
c[1, 0] := Matrix[1][0];
|
|
c[1, 1] := Matrix[1][1];
|
|
c[2, 0] := Matrix[0][2];
|
|
c[2, 1] := Matrix[1][2];
|
|
end;
|
|
*)
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
destructor TXForm.Destroy;
|
|
var
|
|
i: integer;
|
|
begin
|
|
|
|
for i := 0 to High(FRegVariations) do
|
|
FRegVariations[i].Free;
|
|
|
|
if assigned(ifs) then ifs.Clear;
|
|
ifs.Free; // AV
|
|
|
|
inherited;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.BuildFunctionlist;
|
|
begin
|
|
// 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;
|
|
FFunctionList[1] := Flatten; // AV: replased 2D-Linear
|
|
FFunctionList[2] := PreBlur3D; // AV: replaced Sinusoidal
|
|
FFunctionList[3] := Spherical;
|
|
FFunctionList[4] := Swirl;
|
|
FFunctionList[5] := Horseshoe;
|
|
FFunctionList[6] := Polar;
|
|
FFunctionList[7] := Disc;
|
|
FFunctionList[8] := Spiral;
|
|
FFunctionList[9] := Hyperbolic;
|
|
FFunctionList[10] := Diamond; // AV: renamed from Square
|
|
FFunctionList[11] := Eyefish;
|
|
FFunctionList[12] := Bubble;
|
|
FFunctionList[13] := Cylinder;
|
|
FFunctionList[14] := Noise;
|
|
FFunctionList[15] := Blur;
|
|
FFunctionList[16] := Gaussian;
|
|
FFunctionList[17] := ZBlur;
|
|
FFunctionList[18] := Blur3D;
|
|
|
|
FFunctionList[19] := PreBlur;
|
|
FFunctionList[20] := PreZScale; // AV: index is used by auto-pre_zscale option
|
|
FFunctionList[21] := PreZTranslate;
|
|
FFunctionList[22] := PreRotateX;
|
|
FFunctionList[23] := PreRotateY;
|
|
|
|
FFunctionList[24] := ZScale;
|
|
FFunctionList[25] := ZTranslate;
|
|
FFunctionList[26] := ZCone;
|
|
|
|
FFunctionList[27] := PostRotateX;
|
|
FFunctionList[28] := PostRotateY;
|
|
// AV: new local variations
|
|
FFunctionList[29] := PostMirrorX;
|
|
FFunctionList[30] := PostMirrorY;
|
|
FFunctionList[31] := PostMirrorZ;
|
|
|
|
FFunctionList[32] := Hemisphere;
|
|
FFunctionList[33] := Cross;
|
|
FFunctionList[34] := Pyramid;
|
|
FFunctionList[35] := Polar2;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.AddRegVariations;
|
|
var
|
|
i: integer;
|
|
begin
|
|
SetLength(FRegVariations, GetNrRegisteredVariations);
|
|
for i := 0 to GetNrRegisteredVariations - 1 do begin
|
|
FRegVariations[i] := GetRegisteredVariation(i).GetInstance;
|
|
end;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.Assign(XForm: TXForm);
|
|
var
|
|
i,j: integer;
|
|
Name: string;
|
|
Value: double;
|
|
begin
|
|
if Not assigned(XForm) then
|
|
Exit;
|
|
|
|
for i := 0 to High(vars) do
|
|
vars[i] := XForm.vars[i];
|
|
|
|
c := Xform.c;
|
|
p := Xform.p;
|
|
density := XForm.density;
|
|
color := XForm.color;
|
|
color2 := XForm.color2;
|
|
symmetry := XForm.symmetry;
|
|
// Orientationtype := XForm.Orientationtype;
|
|
TransformName := XForm.TransformName;
|
|
|
|
postXswap := Xform.postXswap;
|
|
autoZscale := Xform.autoZscale;
|
|
|
|
for i := 0 to High(FRegVariations) do begin
|
|
for j := 0 to FRegVariations[i].GetNrVariables - 1 do begin
|
|
Name := FRegVariations[i].GetVariableNameAt(j);
|
|
XForm.FRegVariations[i].GetVariable(Name, Value);
|
|
FRegVariations[i].SetVariable(Name, Value);
|
|
end;
|
|
end;
|
|
|
|
for i := 0 to High(modWeights) do
|
|
modWeights[i] := xform.modWeights[i];
|
|
|
|
ifs.Assign(xform.ifs); // AV
|
|
|
|
transOpacity := xform.transOpacity;
|
|
pluginColor := xform.pluginColor;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TXForm.ToXMLString: string;
|
|
var
|
|
i, j: integer;
|
|
Name: string;
|
|
Value: double;
|
|
numChaos: integer;
|
|
strvar: string;
|
|
begin
|
|
result := Format(' <xform weight="%g" color="%g" ', [density, color]);
|
|
if symmetry <> 0 then result := result + format('symmetry="%g" ', [symmetry]);
|
|
|
|
// AV: write variation order
|
|
strvar := '';
|
|
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]);
|
|
///////////////////////
|
|
(*
|
|
for i := 0 to nrvar - 1 do begin
|
|
if vars[i] <> 0 then
|
|
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
|
|
end;
|
|
*)
|
|
for Name in ifs do // AV: write in correct order
|
|
begin
|
|
Value := vars[GetVariationIndex(Name)];
|
|
if Value <> 0 then
|
|
Result := Result + Name + format('="%g" ', [Value]);
|
|
end;
|
|
|
|
Result := Result + Format('coefs="%g %g %g %g %g %g" ', [c[0,0], c[0,1], c[1,0], c[1,1], c[2,0], c[2,1]]);
|
|
if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then
|
|
Result := Result + Format('post="%g %g %g %g %g %g" ', [p[0,0], p[0,1], p[1,0], p[1,1], p[2,0], p[2,1]]);
|
|
|
|
for i := 0 to High(FRegVariations) do begin
|
|
if vars[i+NRLOCVAR] <> 0 then
|
|
for j := 0 to FRegVariations[i].GetNrVariables - 1 do begin
|
|
Name := FRegVariations[i].GetVariableNameAt(j);
|
|
Result := Result + Format('%s="%s" ', [name, FRegVariations[i].GetVariableStr(Name)]);
|
|
end;
|
|
end;
|
|
|
|
numChaos := -1;
|
|
for i := NXFORMS-1 downto 0 do
|
|
if modWeights[i] <> 1 then begin
|
|
numChaos := i;
|
|
break;
|
|
end;
|
|
if numChaos >= 0 then begin
|
|
Result := Result + 'chaos="';
|
|
for i := 0 to numChaos do
|
|
Result := Result + Format('%g ', [modWeights[i]]);
|
|
Result := Result + '" ';
|
|
end;
|
|
|
|
Result := Result + Format('opacity="%g" ', [transOpacity]);
|
|
|
|
if TransformName <> '' then
|
|
Result := Result + 'name="' + TransformName + '"';
|
|
|
|
if pluginColor <> 1 then
|
|
Result := Result + Format('var_color="%g" ', [pluginColor]);
|
|
|
|
Result := Result + '/>';
|
|
end;
|
|
|
|
function TXForm.FinalToXMLString(IsEnabled: boolean): string;
|
|
var
|
|
i, j: integer;
|
|
Name: string;
|
|
Value: double;
|
|
strvar: string;
|
|
begin
|
|
// result := Format(' <finalxform enabled="%d" color="%g" symmetry="%g" ',
|
|
// [ifthen(IsEnabled, 1, 0), color, symmetry]);
|
|
result := Format(' <finalxform color="%g" ', [color]);
|
|
if symmetry <> 0 then result := result + format('symmetry="%g" ', [symmetry]);
|
|
|
|
// AV: write variation order
|
|
strvar := '';
|
|
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]);
|
|
//////////////////////////////////////////
|
|
(*
|
|
for i := 0 to nrvar - 1 do begin
|
|
if vars[i] <> 0 then
|
|
Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
|
|
end;
|
|
*)
|
|
for Name in ifs do // AV: write in correct order
|
|
begin
|
|
Value := vars[GetVariationIndex(Name)];
|
|
if Value <> 0 then
|
|
Result := Result + Name + format('="%g" ', [Value]);
|
|
end;
|
|
|
|
Result := Result + Format('coefs="%g %g %g %g %g %g" ', [c[0,0], c[0,1], c[1,0], c[1,1], c[2,0], c[2,1]]);
|
|
if (p[0,0]<>1) or (p[0,1]<>0) or(p[1,0]<>0) or (p[1,1]<>1) or (p[2,0]<>0) or (p[2,1]<>0) then
|
|
Result := Result + Format('post="%g %g %g %g %g %g" ', [p[0,0], p[0,1], p[1,0], p[1,1], p[2,0], p[2,1]]);
|
|
if pluginColor <> 1 then
|
|
Result := Result + Format('var_color="%g" ', [pluginColor]);
|
|
|
|
for i := 0 to High(FRegVariations) do begin
|
|
if vars[i+NRLOCVAR] <> 0 then
|
|
for j := 0 to FRegVariations[i].GetNrVariables - 1 do begin
|
|
Name := FRegVariations[i].GetVariableNameAt(j);
|
|
Result := Result + Format('%s="%s" ', [name, FRegVariations[i].GetVariableStr(Name)]);
|
|
end;
|
|
end;
|
|
|
|
Result := Result + '/>';
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
procedure TXForm.GetVariable(const name: string; var Value: double);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to High(FRegVariations) do
|
|
if FRegVariations[i].GetVariable(name, value) then
|
|
break;
|
|
end;
|
|
|
|
procedure TXForm.SetVariable(const name: string; var Value: double);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to High(FRegVariations) do
|
|
if FRegVariations[i].SetVariable(name, value) then
|
|
break;
|
|
end;
|
|
|
|
procedure TXForm.ResetVariable(const name: string);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to High(FRegVariations) do
|
|
if FRegVariations[i].ResetVariable(name) then
|
|
break;
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
function TXForm.GetVariableStr(const name: string): string;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to High(FRegVariations) do begin
|
|
Result := FRegVariations[i].GetVariableStr(name);
|
|
if Result <> '' then break;
|
|
end;
|
|
end;
|
|
|
|
procedure TXForm.SetVariableStr(const name: string; var Value: string);
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to High(FRegVariations) do begin
|
|
if FRegVariations[i].SetVariableStr(name, value) then break;
|
|
end;
|
|
end;
|
|
|
|
end.
|