{ 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(' 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(' 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.