diff --git a/2.10/Source/Main.pas b/2.10/Source/Main.pas
index 8e8f751..a94363c 100644
--- a/2.10/Source/Main.pas
+++ b/2.10/Source/Main.pas
@@ -1,5 +1,6 @@
{
Apophysis Copyright (C) 2001-2004 Mark Townsend
+ Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Boris, Peter Sdobnov
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
@@ -36,7 +37,7 @@ const
RS_XO = 2;
RS_VO = 3;
- AppVersionString = 'Apophysis 2.03c';
+ AppVersionString = 'Apophysis 2.03d pre-release 1';
type
TMouseMoveState = (msUsual, msZoomWindow, msZoomOutWindow, msZoomWindowMove, msZoomOutWindowMove, msDrag, msDragMove, msRotate, msRotateMove);
@@ -358,6 +359,7 @@ var
MainForm: TMainForm;
pname, ptime: string;
nxform: integer;
+ FinalXformLoaded: boolean;
ParseCp: TControlPoint; // For parsing;
MainCp: TControlPoint;
@@ -1312,10 +1314,11 @@ begin
Result := ' ';
end;
@@ -1375,33 +1378,15 @@ begin
{ Write transform parameters }
t := NumXForms(cp1);
- for i := 0 to t - 1 do begin
+ for i := 0 to t - 1 do
FileList.Add(cp1.xform[i].ToXMLString);
-// with cp1.xform[i] do
-// begin
-// a := c[0][0];
-// b := c[1][0];
-// cc := c[0][1];
-// d := c[1][1];
-// e := c[2][0];
-// f := c[2][1];
-// varlist := '';
-// for j := 0 to NRVAR - 1 do
-// begin
-// if vars[j] <> 0 then
-// begin
-// varlist := varlist + varnames(j) + format('="%f" ', [vars[j]]);
-// end;
-// end;
-// FileList.Add(Format(' ', [a, cc, b, d, e, f]));
-// end;
- end;
+// if cp1.HasFinalXForm then FileList.Add(cp1.finalxform.FinalToXMLString(cp1.finalXformEnabled));
+ if cp1.HasFinalXForm then FileList.Add(cp1.xform[t].FinalToXMLString(cp1.finalXformEnabled));
{ Write palette data }
if not sheep then begin
- if not compact then
- FileList.Add(ColorToXml(cp1));
- FileList.Add(ColorToXmlcompact(cp1));
+ if compact then // say no to duplicated data! (?)
+ FileList.Add(ColorToXmlCompact(cp1))
+ else FileList.Add(ColorToXml(cp1));
end;
FileList.Add('');
@@ -1562,7 +1547,7 @@ begin
until (Pos('<' + Tag + '>', FileList[FileList.count - 1]) <> 0) or
(Pos('', FileList[FileList.count - 1]) <> 0);
- FileList.Add(Trim(FlameToXML(cp1, false)));
+ FileList.Add(Trim(FlameToXML(cp1, false, true)));
FileList.Add('');
FileList.SaveToFile(filename);
@@ -1576,7 +1561,7 @@ begin
AssignFile(IFile, filename);
ReWrite(IFile);
Writeln(IFile, '');
- Write(IFile, FlameToXML(cp1, false));
+ Write(IFile, FlameToXML(cp1, false, true));
Writeln(IFile, '');
CloseFile(IFile);
end;
@@ -1894,7 +1879,7 @@ begin
*)
MainCp.name := RandomPrefix + RandomDate + '-' +
IntToStr(RandomIndex);
- Write(F, FlameToXML(MainCp, False));
+ Write(F, FlameToXML(MainCp, False, true));
// Write(F, FlameToString(Title));
// WriteLn(F, ' ');
end;
@@ -2619,6 +2604,7 @@ begin
time := -1;
FileStrings := TStringList.Create;
ParamStrings := TStringList.Create;
+
if pos('*untitled', name) <> 0 then
begin
Tokens := TStringList.Create;
@@ -2684,7 +2670,7 @@ begin
RedrawTimer.Enabled := True;
Application.ProcessMessages;
- EditForm.SelectedTriangle := 1; // --Z--
+ EditForm.SelectedTriangle := 0; // (?)
UpdateWindows;
finally
@@ -3578,8 +3564,10 @@ begin
ScriptEditor.Stopped := True;
StopThread;
nxform := 0;
+ FinalXformLoaded := false;
Parsecp.cmapindex := -2; // generate pallet from cmapindex and hue (apo 1 and earlier)
ParseCp.symmetry := 0;
+ ParseCP.finalXformEnabled := false;
XMLScanner.LoadFromBuffer(params);
XMLScanner.Execute;
cp1.copy(ParseCp);
@@ -3600,6 +3588,11 @@ begin
end;
end;
+ if FinalXformLoaded = false then begin
+ MainCP.xform[nxform].Clear;
+ MainCP.xform[nxform].symmetry := 1;
+ end;
+
if nxform < NXFORMS then
for i := nxform to NXFORMS - 1 do
cp1.xform[i].density := 0;
@@ -3987,77 +3980,83 @@ var
begin
Tokens := TStringList.Create;
try
- if TagName = 'xform' then
+ if (TagName = 'xform') or (TagName = 'finalxform') then
+ if (TagName = 'finalxform') and (FinalXformLoaded) then ShowMessage('ERROR: No xforms allowed after FinalXform!')
+ else
begin
- Parsecp.xform[nxform].Clear;
+ if (TagName = 'finalxform') then FinalXformLoaded := true;
+
+ with ParseCP.xform[nXform] do begin
+ Clear;
v := Attributes.Value('weight');
- if v <> '' then ParseCp.xform[nxform].density := StrToFloat(v);
+ if (v <> '') and (TagName = 'xform') then density := StrToFloat(v);
+ if (TagName = 'finalxform') then
+ begin
+ v := Attributes.Value('enabled');
+ if v <> '' then ParseCP.finalXformEnabled := (StrToInt(v) <> 0)
+ else ParseCP.finalXformEnabled := false;
+ end;
v := Attributes.Value('color');
- if v <> '' then Parsecp.xform[nxform].color := StrToFloat(v);
+ if v <> '' then color := StrToFloat(v);
v := Attributes.Value('symmetry');
- if v <> '' then Parsecp.xform[nxform].symmetry := StrToFloat(v);
+ if v <> '' then symmetry := StrToFloat(v);
v := Attributes.Value('coefs');
GetTokens(v, tokens);
if Tokens.Count < 6 then ShowMessage('Not enough cooeficients...crash?');
- with Parsecp.xform[nxform] do
- begin
- c[0][0] := StrToFloat(Tokens[0]);
- c[0][1] := StrToFloat(Tokens[1]);
- c[1][0] := StrToFloat(Tokens[2]);
- c[1][1] := StrToFloat(Tokens[3]);
- c[2][0] := StrToFloat(Tokens[4]);
- c[2][1] := StrToFloat(Tokens[5]);
- end;
+ c[0][0] := StrToFloat(Tokens[0]);
+ c[0][1] := StrToFloat(Tokens[1]);
+ c[1][0] := StrToFloat(Tokens[2]);
+ c[1][1] := StrToFloat(Tokens[3]);
+ c[2][0] := StrToFloat(Tokens[4]);
+ c[2][1] := StrToFloat(Tokens[5]);
+
v := Attributes.Value('post');
if v <> '' then begin
GetTokens(v, tokens);
if Tokens.Count < 6 then ShowMessage('Not enough post-cooeficients...crash?');
- with Parsecp.xform[nxform] do
- begin
- p[0][0] := StrToFloat(Tokens[0]);
- p[0][1] := StrToFloat(Tokens[1]);
- p[1][0] := StrToFloat(Tokens[2]);
- p[1][1] := StrToFloat(Tokens[3]);
- p[2][0] := StrToFloat(Tokens[4]);
- p[2][1] := StrToFloat(Tokens[5]);
- end;
+ p[0][0] := StrToFloat(Tokens[0]);
+ p[0][1] := StrToFloat(Tokens[1]);
+ p[1][0] := StrToFloat(Tokens[2]);
+ p[1][1] := StrToFloat(Tokens[3]);
+ p[2][0] := StrToFloat(Tokens[4]);
+ p[2][1] := StrToFloat(Tokens[5]);
end;
for i := 0 to NRVAR - 1 do
begin
- Parsecp.xform[nxform].vars[i] := 0;
+ vars[i] := 0;
v := Attributes.Value(varnames(i));
if v <> '' then
- Parsecp.xform[nxform].vars[i] := StrToFloat(v);
+ vars[i] := StrToFloat(v);
end;
v := Attributes.Value('var1');
if v <> '' then
begin
for i := 0 to NRVAR - 1 do
- Parsecp.xform[nxform].vars[i] := 0;
- Parsecp.xform[nxform].vars[StrToInt(v)] := 1;
+ vars[i] := 0;
+ vars[StrToInt(v)] := 1;
end;
v := Attributes.Value('var');
if v <> '' then
begin
for i := 0 to NRVAR - 1 do
- Parsecp.xform[nxform].vars[i] := 0;
+ vars[i] := 0;
GetTokens(v, tokens);
if Tokens.Count > NRVAR then ShowMessage('To many vars..crash?');
for i := 0 to Tokens.Count - 1 do
- Parsecp.xform[nxform].vars[i] := StrToFloat(Tokens[i]);
+ vars[i] := StrToFloat(Tokens[i]);
end;
for i := 0 to GetNrVariableNames - 1 do begin
v := Attributes.Value(GetVariableNameAt(i));
if v <> '' then begin
d := StrToFloat(v);
- Parsecp.xform[nxform].SetVariable(GetVariableNameAt(i), d);
+ SetVariable(GetVariableNameAt(i), d);
end;
end;
-
- inc(nxform);
+ end;
+ Inc(nXform);
end;
if TagName = 'color' then
begin
diff --git a/2.10/Source/Render64.pas b/2.10/Source/Render64.pas
index 82df848..2901742 100644
--- a/2.10/Source/Render64.pas
+++ b/2.10/Source/Render64.pas
@@ -22,16 +22,16 @@ interface
uses
Windows, Graphics, ImageMaker,
- Render, Controlpoint;
+ Render, xform, Controlpoint;
type
TRenderer64 = class(TBaseRenderer)
private
- oversample: Int64;
+ oversample: integer;
+
+ BucketWidth, BucketHeight: integer;
+ BucketSize: integer;
- BucketWidth: Int64;
- BucketHeight: Int64;
- BucketSize: Int64;
gutter_width: Integer;
max_gutter_width: Integer;
@@ -40,8 +40,12 @@ type
Buckets: TBucketArray;
ColorMap: TColorMapArray;
- bounds: array[0..3] of extended;
- size: array[0..1] of extended;
+ FinalXform: ^TXform;
+ UseFinalXform: boolean;
+
+ camX0, camX1, camY0, camY1, // camera bounds
+ camW, camH, // camera sizes
+ bws, bhs, cosa, sina, rcX, rcY: double;
ppux, ppuy: extended;
FImageMaker: TImageMaker;
@@ -53,8 +57,10 @@ type
procedure CreateColorMap;
procedure CreateCamera;
- procedure AddPointsToBuckets(const points: TPointsArray); overload;
- procedure AddPointsToBucketsAngle(const points: TPointsArray); overload;
+ procedure AddPointsToBuckets(const points: TPointsArray);
+ procedure AddPointsToBucketsAngle(const points: TPointsArray);
+ procedure AddPointsWithFX(const points: TPointsArray);
+ procedure AddPointsWithAngleFX(const points: TPointsArray);
procedure SetPixels;
public
@@ -117,7 +123,7 @@ var
scale: double;
t0, t1: double;
t2, t3: double;
- corner0, corner1: double;
+ corner_x, corner_y, Xsize, Ysize: double;
shift: Integer;
begin
scale := power(2, fcp.zoom);
@@ -131,20 +137,32 @@ begin
t1 := (gutter_width) / (oversample * ppuy);
t2 := (2 * max_gutter_width - gutter_width) / (oversample * ppux);
t3 := (2 * max_gutter_width - gutter_width) / (oversample * ppuy);
- corner0 := fcp.center[0] - fcp.Width / ppux / 2.0;
- corner1 := fcp.center[1] - fcp.Height / ppuy / 2.0;
- bounds[0] := corner0 - t0;
- bounds[1] := corner1 - t1 + shift;
- bounds[2] := corner0 + fcp.Width / ppux + t2;
- bounds[3] := corner1 + fcp.Height / ppuy + t3; //+ shift;
- if abs(bounds[2] - bounds[0]) > 0.01 then
- size[0] := 1.0 / (bounds[2] - bounds[0])
+ corner_x := fcp.center[0] - fcp.Width / ppux / 2.0;
+ corner_y := fcp.center[1] - fcp.Height / ppuy / 2.0;
+ camX0 := corner_x - t0;
+ camY0 := corner_y - t1 + shift;
+ camX1 := corner_x + fcp.Width / ppux + t2;
+ camY1 := corner_y + fcp.Height / ppuy + t3; //+ shift;
+ camW := camX1 - camX0;
+ if abs(camW) > 0.01 then
+ Xsize := 1.0 / camW
else
- size[0] := 1;
- if abs(bounds[3] - bounds[1]) > 0.01 then
- size[1] := 1.0 / (bounds[3] - bounds[1])
+ Xsize := 1;
+ camH := camY1 - camY0;
+ if abs(camH) > 0.01 then
+ Ysize := 1.0 / camH
else
- size[1] := 1;
+ Ysize := 1;
+ bws := (BucketWidth - 0.5) * Xsize;
+ bhs := (BucketHeight - 0.5) * Ysize;
+
+ if FCP.FAngle <> 0 then
+ begin
+ cosa := cos(FCP.FAngle);
+ sina := sin(FCP.FAngle);
+ rcX := FCP.Center[0]*(1 - cosa) - FCP.Center[1]*sina - camX0;
+ rcY := FCP.Center[1]*(1 - cosa) + FCP.Center[0]*sina - camY0;
+ end;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -202,6 +220,9 @@ begin
CreateCamera;
CreateColorMap;
+
+ FinalXForm := @fcp.xform[fcp.NumXForms];
+ UseFinalXForm := fcp.finalXformEnabled and fcp.HasFinalXform;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -209,32 +230,19 @@ procedure TRenderer64.AddPointsToBuckets(const points: TPointsArray);
var
i: integer;
px, py: double;
- bws, bhs: double;
- bx, by: double;
- wx, wy: double;
Bucket: PBucket;
MapColor: PColorMapColor;
begin
- bws := (BucketWidth - 0.5) * size[0];
- bhs := (BucketHeight - 0.5) * size[1];
- bx := bounds[0];
- by := bounds[1];
- wx := bounds[2] - bounds[0];
- wy := bounds[3] - bounds[1];
-
for i := SUB_BATCH_SIZE - 1 downto 0 do begin
- if FStop then
- Exit;
+// if FStop then Exit;
- px := points[i].x - bx;
- py := points[i].y - by;
+ px := points[i].x - camX0;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y - camY0;
+ if (py < 0) or (py > camH) then continue;
- if ((px < 0) or (px > wx) or
- (py < 0) or (py > wy)) then
- continue;
-
- MapColor := @ColorMap[Round(points[i].c * 255)];
Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
Inc(Bucket.Red, MapColor.Red);
Inc(Bucket.Green, MapColor.Green);
@@ -243,49 +251,104 @@ begin
end;
end;
+procedure TRenderer64.AddPointsWithFX(const points: TPointsArray);
+const
+ const255: single = 255;
+var
+ i: integer;
+ px, py: double;
+ Bucket: PBucket;
+ MapColor: PColorMapColor;
+begin
+ try
+ for i := SUB_BATCH_SIZE - 1 downto 0 do begin
+// if FStop then Exit;
+
+ FinalXform.NextPoint(points[i]);
+
+{$if true}
+ px := points[i].x - camX0;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y - camY0;
+ if (py < 0) or (py > camH) then continue;
+
+ Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
+
+ Inc(Bucket.Red, MapColor.Red);
+ Inc(Bucket.Green, MapColor.Green);
+ Inc(Bucket.Blue, MapColor.Blue);
+ Inc(Bucket.Count);
+{$else}
+asm
+ mov eax, [points]
+ lea edx, [eax + edi*8] // assert: "i" in edi
+// fld qword ptr [edx + edi*8] // assert: "i" in edi
+ fld qword ptr [edx]
+ fsub qword ptr [bx]
+ fldz
+ fcomp st(1), st
+ fnstsw ax
+ sahf
+ jb @skip1
+ fld qword ptr [wx]
+ fcomp
+ fnstsw ax
+ sahf
+ jnbe @skip1
+
+ fld qword ptr [edx + 8]
+ fsub qword ptr [by]
+ fldz
+ fcomp
+ fnstsw ax
+ sahf
+ jb @skip2
+ fld qword ptr [wy]
+ fcomp
+ fnstsw ax
+ sahf
+ jnbe @skip2
+
+ fmul qword ptr [bhs]
+ fimul [BucketWidth]
+
+ fld qword ptr [edx + 16]
+ fmul dword ptr [const255]
+ sub esp, 4
+ fistp dword ptr [esp]
+ pop eax
+
+@skip2:
+ fstp st
+@skip1:
+ fstp st
+@continue:
+end;
+{$ifend}
+ end
+ except
+ end
+end;
+
///////////////////////////////////////////////////////////////////////////////
procedure TRenderer64.AddPointsToBucketsAngle(const points: TPointsArray);
var
i: integer;
px, py: double;
- ca,sa: double;
- nx, ny: double;
- bws, bhs: double;
- bx, by: double;
- wx, wy: double;
Bucket: PBucket;
MapColor: PColorMapColor;
begin
-
- bws := (BucketWidth - 0.5) * size[0];
- bhs := (BucketHeight - 0.5) * size[1];
- bx := bounds[0];
- by := bounds[1];
- wx := bounds[2] - bounds[0];
- wy := bounds[3] - bounds[1];
-
- ca := cos(FCP.FAngle);
- sa := sin(FCP.FAngle);
-
for i := SUB_BATCH_SIZE - 1 downto 0 do begin
- if FStop then
- Exit;
+// if FStop then Exit;
- px := points[i].x - FCP.Center[0];
- py := points[i].y - FCP.Center[1];
+ px := points[i].x * cosa + points[i].y * sina + rcX;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y * cosa - points[i].x * sina + rcY;
+ if (py < 0) or (py > camH) then continue;
- nx := px * ca + py * sa;
- ny := -px * sa + py * ca;
-
- px := nx + FCP.Center[0] - bx;
- py := ny + FCP.Center[1] - by;
-
- if ((px < 0) or (px > wx) or
- (py < 0) or (py > wy)) then
- continue;
-
- MapColor := @ColorMap[Round(points[i].c * 255)];
Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
Inc(Bucket.Red, MapColor.Red);
Inc(Bucket.Green, MapColor.Green);
@@ -294,6 +357,36 @@ begin
end;
end;
+procedure TRenderer64.AddPointsWithAngleFX(const points: TPointsArray);
+var
+ i: integer;
+ px, py: double;
+ Bucket: PBucket;
+ MapColor: PColorMapColor;
+begin
+ try
+ for i := SUB_BATCH_SIZE - 1 downto 0 do
+ begin
+// if FStop then Exit;
+ FinalXform.NextPoint(points[i]);
+
+ px := points[i].x * cosa + points[i].y * sina + rcX;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y * cosa - points[i].x * sina + rcY;
+ if (py < 0) or (py > camH) then continue;
+
+ Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
+
+ Inc(Bucket.Red, MapColor.Red);
+ Inc(Bucket.Green, MapColor.Green);
+ Inc(Bucket.Blue, MapColor.Blue);
+ Inc(Bucket.Count);
+ end;
+ except
+ end
+end;
+
///////////////////////////////////////////////////////////////////////////////
procedure TRenderer64.SetPixels;
var
@@ -301,12 +394,25 @@ var
nsamples: Int64;
nrbatches: Integer;
points: TPointsArray;
+ AddPointsProc: procedure (const points: TPointsArray) of object;
begin
// if FileExists('c:\temp\flame.txt') then
// Deletefile('c:\temp\flame.txt');
// AssignFile(F, 'c:\temp\flame.txt');
// Rewrite(F);
+ if FCP.FAngle = 0 then begin
+ if UseFinalXForm then
+ AddPointsProc := AddPointsWithFX
+ else
+ AddPointsProc := AddPointsToBuckets;
+ end
+ else begin
+ if UseFinalXForm then
+ AddPointsProc := AddPointsWithAngleFX
+ else
+ AddPointsProc := AddPointsToBucketsAngle;
+ end;
SetLength(Points, SUB_BATCH_SIZE);
@@ -330,19 +436,19 @@ begin
// break;
fcp.Testiterate(SUB_BATCH_SIZE, points);
{$ELSE}
+{
case Compatibility of
0: fcp.iterate_Old(SUB_BATCH_SIZE, points);
1: fcp.iterateXYC(SUB_BATCH_SIZE, points);
end;
+}
+ fcp.IterateXYC(SUB_BATCH_SIZE, points);
{$ENDIF}
// for j := SUB_BATCH_SIZE - 1 downto 0 do
// Writeln(f, FloatTostr(points[j].x) + #9 + FloatTostr(points[j].y) + #9 + FloatTostr(points[j].c));
- if FCP.FAngle = 0 then
- AddPointsToBuckets(points)
- else
- AddPointsToBucketsAngle(points);
+ AddPointsProc(points);
end;
// closefile(f);
diff --git a/2.10/Source/Render64MT.pas b/2.10/Source/Render64MT.pas
index 5231d26..581cf00 100644
--- a/2.10/Source/Render64MT.pas
+++ b/2.10/Source/Render64MT.pas
@@ -42,8 +42,15 @@ type
Buckets: TBucketArray;
ColorMap: TColorMapArray;
- bounds: array[0..3] of extended;
- size: array[0..1] of extended;
+ FinalXform: ^TXform;
+ UseFinalXform: boolean;
+
+ camX0, camX1, camY0, camY1, // camera bounds
+ camW, camH, // camera sizes
+ Xsize, Ysize: double;
+ bws, bhs, cosa, sina, rcX, rcY: double;
+// bounds: array[0..3] of extended;
+// size: array[0..1] of extended;
ppux, ppuy: extended;
FNrOfTreads: integer;
WorkingThreads: array of TBucketFillerThread;
@@ -113,7 +120,7 @@ var
scale: double;
t0, t1: double;
t2, t3: double;
- corner0, corner1: double;
+ corner_x, corner_y: double;
shift: Integer;
begin
scale := power(2, fcp.zoom);
@@ -127,8 +134,9 @@ begin
t1 := (gutter_width) / (oversample * ppuy);
t2 := (2 * max_gutter_width - gutter_width) / (oversample * ppux);
t3 := (2 * max_gutter_width - gutter_width) / (oversample * ppuy);
- corner0 := fcp.center[0] - fcp.Width / ppux / 2.0;
- corner1 := fcp.center[1] - fcp.Height / ppuy / 2.0;
+ corner_x := fcp.center[0] - fcp.Width / ppux / 2.0;
+ corner_y := fcp.center[1] - fcp.Height / ppuy / 2.0;
+{
bounds[0] := corner0 - t0;
bounds[1] := corner1 - t1 + shift;
bounds[2] := corner0 + fcp.Width / ppux + t2;
@@ -141,6 +149,31 @@ begin
size[1] := 1.0 / (bounds[3] - bounds[1])
else
size[1] := 1;
+}
+ camX0 := corner_x - t0;
+ camY0 := corner_y - t1 + shift;
+ camX1 := corner_x + fcp.Width / ppux + t2;
+ camY1 := corner_y + fcp.Height / ppuy + t3; //+ shift;
+ camW := camX1 - camX0;
+ if abs(camW) > 0.01 then
+ Xsize := 1.0 / camW
+ else
+ Xsize := 1;
+ camH := camY1 - camY0;
+ if abs(camH) > 0.01 then
+ Ysize := 1.0 / camH
+ else
+ Ysize := 1;
+ bws := (BucketWidth - 0.5) * Xsize;
+ bhs := (BucketHeight - 0.5) * Ysize;
+
+ if FCP.FAngle <> 0 then
+ begin
+ cosa := cos(FCP.FAngle);
+ sina := sin(FCP.FAngle);
+ rcX := FCP.Center[0]*(1 - cosa) - FCP.Center[1]*sina - camX0;
+ rcY := FCP.Center[1]*(1 - cosa) + FCP.Center[0]*sina - camY0;
+ end;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -317,6 +350,7 @@ begin
Result.BucketWidth := BucketWidth;
Result.BucketHeight := BucketHeight;
Result.Buckets := @Buckets;
+{
Result.size[0] := size[0];
Result.size[1] := size[1];
Result.bounds[0] := Bounds[0];
@@ -325,6 +359,18 @@ begin
Result.bounds[3] := Bounds[3];
Result.RotationCenter[0] := FCP.Center[0];
Result.RotationCenter[1] := FCP.Center[1];
+}
+ Result.camX0 := camX0;
+ Result.camY0 := camY0;
+ Result.camW := camW;
+ Result.camH := camH;
+ Result.bws := bws;
+ Result.bhs := bhs;
+ Result.cosa := cosa;
+ Result.sina := sina;
+ Result.rcX := rcX;
+ Result.rcY := rcY;
+
Result.ColorMap := colorMap;
Result.CriticalSection := CriticalSection;
Result.Nrbatches := FNrBatches;
diff --git a/2.10/Source/RenderMM.pas b/2.10/Source/RenderMM.pas
index 6859934..f3e4a3e 100644
--- a/2.10/Source/RenderMM.pas
+++ b/2.10/Source/RenderMM.pas
@@ -22,7 +22,7 @@ interface
uses
Windows, Graphics,
- Render, Controlpoint, ImageMaker;
+ Render, Controlpoint, ImageMaker, XForm;
type
TRendererMM64 = class(TBaseRenderer)
@@ -41,9 +41,15 @@ type
Buckets: TBucketArray;
ColorMap: TColorMapArray;
- bounds: array[0..3] of extended;
- size: array[0..1] of extended;
- FRotationCenter: array[0..1] of extended;
+ FinalXform: ^TXform;
+ UseFinalXform: boolean;
+
+ camX0, camX1, camY0, camY1, // camera bounds
+ camW, camH, // camera sizes
+ bws, bhs, cosa, sina, rcX, rcY: double;
+// bounds: array[0..3] of extended;
+// size: array[0..1] of extended;
+// FRotationCenter: array[0..1] of extended;
ppux, ppuy: extended;
nrSlices: int64;
Slice: int64;
@@ -56,8 +62,10 @@ type
procedure CreateColorMap;
procedure CreateCamera;
- procedure AddPointsToBuckets(const points: TPointsArray); overload;
- procedure AddPointsToBucketsAngle(const points: TPointsArray); overload;
+ procedure AddPointsToBuckets(const points: TPointsArray);
+ procedure AddPointsToBucketsAngle(const points: TPointsArray);
+ procedure AddPointsWithFX(const points: TPointsArray);
+ procedure AddPointsWithAngleFX(const points: TPointsArray);
procedure SetPixels;
protected
@@ -106,7 +114,7 @@ procedure TRendererMM64.CreateCamera;
var
scale: double;
t0, t1: double;
- corner0, corner1: double;
+ corner_x, corner_y, Xsize, Ysize: double;
shift: Integer;
begin
scale := power(2, fcp.zoom);
@@ -117,8 +125,9 @@ begin
shift := 0;
t0 := gutter_width / (oversample * ppux);
t1 := gutter_width / (oversample * ppuy);
- corner0 := fcp.center[0] - image_width / ppux / 2.0;
- corner1 := fcp.center[1] - image_height / ppuy / 2.0;
+ corner_x := fcp.center[0] - image_width / ppux / 2.0;
+ corner_y := fcp.center[1] - image_height / ppuy / 2.0;
+{
bounds[0] := corner0 - t0;
bounds[1] := corner1 - t1 + shift;
bounds[2] := corner0 + image_width / ppux + t0;
@@ -131,6 +140,31 @@ begin
size[1] := 1.0 / (bounds[3] - bounds[1])
else
size[1] := 1;
+}
+ camX0 := corner_x - t0;
+ camY0 := corner_y - t1 + shift;
+ camX1 := corner_x + image_width / ppux / 2.0;
+ camY1 := corner_y + image_height / ppuy + t1; //+ shift;
+ camW := camX1 - camX0;
+ if abs(camW) > 0.01 then
+ Xsize := 1.0 / camW
+ else
+ Xsize := 1;
+ camH := camY1 - camY0;
+ if abs(camH) > 0.01 then
+ Ysize := 1.0 / camH
+ else
+ Ysize := 1;
+ bws := (BucketWidth - 0.5) * Xsize;
+ bhs := (BucketHeight - 0.5) * Ysize;
+
+ if FCP.FAngle <> 0 then
+ begin
+ cosa := cos(FCP.FAngle);
+ sina := sin(FCP.FAngle);
+ rcX := FCP.Center[0]*(1 - cosa) - FCP.Center[1]*sina - camX0;
+ rcY := FCP.Center[1]*(1 - cosa) + FCP.Center[0]*sina - camY0;
+ end;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -188,6 +222,9 @@ begin
InitBuffers;
CreateColorMap;
+
+ FinalXForm := @fcp.xform[fcp.NumXForms];
+ UseFinalXForm := fcp.finalXformEnabled and fcp.HasFinalXform;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -195,34 +232,21 @@ procedure TRendererMM64.AddPointsToBuckets(const points: TPointsArray);
var
i: integer;
px, py: double;
- bws, bhs: double;
- bx, by: double;
- wx, wy: double;
// R: double;
// V1, v2, v3: integer;
Bucket: PBucket;
MapColor: PColorMapColor;
begin
- bws := (BucketWidth - 0.5) * size[0];
- bhs := (BucketHeight - 0.5) * size[1];
- bx := bounds[0];
- by := bounds[1];
- wx := bounds[2] - bounds[0];
- wy := bounds[3] - bounds[1];
-
for i := SUB_BATCH_SIZE - 1 downto 0 do begin
- if FStop then
- Exit;
+// if FStop then Exit;
- px := points[i].x - bx;
- py := points[i].y - by;
+ px := points[i].x - camX0;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y - camY0;
+ if (py < 0) or (py > camH) then continue;
- if ((px < 0) or (px > wx) or
- (py < 0) or (py > wy)) then
- continue;
-
- MapColor := @ColorMap[Round(points[i].c * 255)];
Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
Inc(Bucket.Red, MapColor.Red);
Inc(Bucket.Green, MapColor.Green);
@@ -231,57 +255,90 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
-procedure TRendererMM64.AddPointsToBucketsAngle(const points: TPointsArray);
+procedure TRendererMM64.AddPointsWithFX(const points: TPointsArray);
var
i: integer;
px, py: double;
- ca,sa: double;
- nx, ny: double;
- bws, bhs: double;
- bx, by: double;
- wx, wy: double;
-// R: double;
-// V1, v2, v3: integer;
Bucket: PBucket;
MapColor: PColorMapColor;
begin
-
- bws := (BucketWidth - 0.5) * size[0];
- bhs := (BucketHeight - 0.5) * size[1];
- bx := bounds[0];
- by := bounds[1];
- wx := bounds[2] - bounds[0];
- wy := bounds[3] - bounds[1];
-
- ca := cos(FCP.FAngle);
- sa := sin(FCP.FAngle);
-
+ try
for i := SUB_BATCH_SIZE - 1 downto 0 do begin
- if FStop then
- Exit;
+// if FStop then Exit;
- px := points[i].x - FRotationCenter[0];
- py := points[i].y - FRotationCenter[1];
+ FinalXform.NextPoint(points[i]);
- nx := px * ca + py * sa;
- ny := -px * sa + py * ca;
+ px := points[i].x - camX0;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y - camY0;
+ if (py < 0) or (py > camH) then continue;
- px := nx + FRotationCenter[0] - bx;
- py := ny + FRotationCenter[1] - by;
-
- if ((px < 0) or (px > wx) or
- (py < 0) or (py > wy)) then
- continue;
-
- MapColor := @ColorMap[Round(points[i].c * 255)];
Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
Inc(Bucket.Red, MapColor.Red);
Inc(Bucket.Green, MapColor.Green);
Inc(Bucket.Blue, MapColor.Blue);
Inc(Bucket.Count);
end;
+ except
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+procedure TRendererMM64.AddPointsToBucketsAngle(const points: TPointsArray);
+var
+ i: integer;
+ px, py: double;
+ Bucket: PBucket;
+ MapColor: PColorMapColor;
+begin
+ for i := SUB_BATCH_SIZE - 1 downto 0 do begin
+// if FStop then Exit;
+
+ px := points[i].x * cosa + points[i].y * sina + rcX;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y * cosa - points[i].x * sina + rcY;
+ if (py < 0) or (py > camH) then continue;
+
+ Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
+
+ Inc(Bucket.Red, MapColor.Red);
+ Inc(Bucket.Green, MapColor.Green);
+ Inc(Bucket.Blue, MapColor.Blue);
+ Inc(Bucket.Count);
+ end;
+end;
+
+procedure TRendererMM64.AddPointsWithAngleFX(const points: TPointsArray);
+var
+ i: integer;
+ px, py: double;
+ Bucket: PBucket;
+ MapColor: PColorMapColor;
+begin
+ try
+ for i := SUB_BATCH_SIZE - 1 downto 0 do
+ begin
+// if FStop then Exit;
+ FinalXform.NextPoint(points[i]);
+
+ px := points[i].x * cosa + points[i].y * sina + rcX;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y * cosa - points[i].x * sina + rcY;
+ if (py < 0) or (py > camH) then continue;
+
+ Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
+
+ Inc(Bucket.Red, MapColor.Red);
+ Inc(Bucket.Green, MapColor.Green);
+ Inc(Bucket.Blue, MapColor.Blue);
+ Inc(Bucket.Count);
+ end;
+ except
+ end
end;
///////////////////////////////////////////////////////////////////////////////
@@ -309,10 +366,13 @@ begin
Progress(0);
// generate points
+{
case Compatibility of
0: fcp.iterate_Old(SUB_BATCH_SIZE, points);
1: fcp.iterateXYC(SUB_BATCH_SIZE, points);
end;
+}
+ fcp.IterateXYC(SUB_BATCH_SIZE, points);
if FCP.FAngle = 0 then
AddPointsToBuckets(points)
@@ -343,8 +403,8 @@ var
begin
FStop := False;
- FRotationCenter[0] := fcp.center[0];
- FRotationCenter[1] := fcp.center[1];
+// FRotationCenter[0] := fcp.center[0];
+// FRotationCenter[1] := fcp.center[1];
image_height := fcp.Height;
image_Width := fcp.Width;
diff --git a/2.10/Source/RenderMM_MT.pas b/2.10/Source/RenderMM_MT.pas
index 4f8de76..11de4bc 100644
--- a/2.10/Source/RenderMM_MT.pas
+++ b/2.10/Source/RenderMM_MT.pas
@@ -22,17 +22,15 @@ interface
uses
Windows, Graphics,
- Render, Controlpoint, ImageMaker, BucketFillerThread;
+ Render, Controlpoint, ImageMaker, BucketFillerThread, XForm;
type
TRendererMM64_MT = class(TBaseRenderer)
private
oversample: Integer;
- image_Width: Int64;
- image_Height: Int64;
- BucketWidth: Integer;
- BucketHeight: Integer;
+ image_Width, image_Height: integer; // we're not going to render images
+ BucketWidth, BucketHeight: integer; // more then 2^32 pixels wide, are we? :)
BucketSize: Integer;
gutter_width: Integer;
@@ -41,9 +39,16 @@ type
Buckets: TBucketArray;
ColorMap: TColorMapArray;
- bounds: array[0..3] of extended;
- size: array[0..1] of extended;
- FRotationCenter: array[0..1] of extended;
+ FinalXform: ^TXform;
+ UseFinalXform: boolean;
+
+ camX0, camX1, camY0, camY1, // camera bounds
+ camW, camH, // camera sizes
+ bws, bhs, cosa, sina, rcX, rcY: double;
+// bounds: array[0..3] of extended;
+// size: array[0..1] of extended;
+// FRotationCenter: array[0..1] of extended;
+
ppux, ppuy: extended;
nrSlices: int64;
Slice: int64;
@@ -62,8 +67,10 @@ type
procedure CreateColorMap;
procedure CreateCamera;
- procedure AddPointsToBuckets(const points: TPointsArray); overload;
- procedure AddPointsToBucketsAngle(const points: TPointsArray); overload;
+ procedure AddPointsToBuckets(const points: TPointsArray);
+ procedure AddPointsToBucketsAngle(const points: TPointsArray);
+ procedure AddPointsWithFX(const points: TPointsArray);
+ procedure AddPointsWithAngleFX(const points: TPointsArray);
procedure SetPixels;
procedure SetPixelsMT;
@@ -119,7 +126,7 @@ procedure TRendererMM64_MT.CreateCamera;
var
scale: double;
t0, t1: double;
- corner0, corner1: double;
+ corner_x, corner_y, Xsize, Ysize: double;
shift: Integer;
begin
scale := power(2, fcp.zoom);
@@ -130,8 +137,9 @@ begin
shift := 0;
t0 := gutter_width / (oversample * ppux);
t1 := gutter_width / (oversample * ppuy);
- corner0 := fcp.center[0] - image_width / ppux / 2.0;
- corner1 := fcp.center[1] - image_height / ppuy / 2.0;
+ corner_x := fcp.center[0] - image_width / ppux / 2.0;
+ corner_y := fcp.center[1] - image_height / ppuy / 2.0;
+{
bounds[0] := corner0 - t0;
bounds[1] := corner1 - t1 + shift;
bounds[2] := corner0 + image_width / ppux + t0;
@@ -144,6 +152,31 @@ begin
size[1] := 1.0 / (bounds[3] - bounds[1])
else
size[1] := 1;
+}
+ camX0 := corner_x - t0;
+ camY0 := corner_y - t1 + shift;
+ camX1 := corner_x + image_width / ppux + t0;
+ camY1 := corner_y + image_height / ppuy + t1; //+ shift;
+ camW := camX1 - camX0;
+ if abs(camW) > 0.01 then
+ Xsize := 1.0 / camW
+ else
+ Xsize := 1;
+ camH := camY1 - camY0;
+ if abs(camH) > 0.01 then
+ Ysize := 1.0 / camH
+ else
+ Ysize := 1;
+ bws := (BucketWidth - 0.5) * Xsize;
+ bhs := (BucketHeight - 0.5) * Ysize;
+
+ if FCP.FAngle <> 0 then
+ begin
+ cosa := cos(FCP.FAngle);
+ sina := sin(FCP.FAngle);
+ rcX := FCP.Center[0]*(1 - cosa) - FCP.Center[1]*sina - camX0;
+ rcY := FCP.Center[1]*(1 - cosa) + FCP.Center[0]*sina - camY0;
+ end;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -201,6 +234,9 @@ begin
InitBuffers;
CreateColorMap;
+
+ FinalXForm := @fcp.xform[fcp.NumXForms];
+ UseFinalXForm := fcp.finalXformEnabled and fcp.HasFinalXform;
end;
///////////////////////////////////////////////////////////////////////////////
@@ -208,34 +244,21 @@ procedure TRendererMM64_MT.AddPointsToBuckets(const points: TPointsArray);
var
i: integer;
px, py: double;
- bws, bhs: double;
- bx, by: double;
- wx, wy: double;
// R: double;
// V1, v2, v3: integer;
Bucket: PBucket;
MapColor: PColorMapColor;
begin
- bws := (BucketWidth - 0.5) * size[0];
- bhs := (BucketHeight - 0.5) * size[1];
- bx := bounds[0];
- by := bounds[1];
- wx := bounds[2] - bounds[0];
- wy := bounds[3] - bounds[1];
-
for i := SUB_BATCH_SIZE - 1 downto 0 do begin
- if FStop then
- Exit;
+// if FStop then Exit;
- px := points[i].x - bx;
- py := points[i].y - by;
+ px := points[i].x - camX0;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y - camY0;
+ if (py < 0) or (py > camH) then continue;
- if ((px < 0) or (px > wx) or
- (py < 0) or (py > wy)) then
- continue;
-
- MapColor := @ColorMap[Round(points[i].c * 255)];
Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
Inc(Bucket.Red, MapColor.Red);
Inc(Bucket.Green, MapColor.Green);
@@ -244,57 +267,90 @@ begin
end;
end;
-///////////////////////////////////////////////////////////////////////////////
-procedure TRendererMM64_MT.AddPointsToBucketsAngle(const points: TPointsArray);
+procedure TRendererMM64_MT.AddPointsWithFX(const points: TPointsArray);
var
i: integer;
px, py: double;
- ca,sa: double;
- nx, ny: double;
- bws, bhs: double;
- bx, by: double;
- wx, wy: double;
-// R: double;
-// V1, v2, v3: integer;
Bucket: PBucket;
MapColor: PColorMapColor;
begin
-
- bws := (BucketWidth - 0.5) * size[0];
- bhs := (BucketHeight - 0.5) * size[1];
- bx := bounds[0];
- by := bounds[1];
- wx := bounds[2] - bounds[0];
- wy := bounds[3] - bounds[1];
-
- ca := cos(FCP.FAngle);
- sa := sin(FCP.FAngle);
-
+ try
for i := SUB_BATCH_SIZE - 1 downto 0 do begin
- if FStop then
- Exit;
+// if FStop then Exit;
- px := points[i].x - FRotationCenter[0];
- py := points[i].y - FRotationCenter[1];
+ FinalXform.NextPoint(points[i]);
- nx := px * ca + py * sa;
- ny := -px * sa + py * ca;
+ px := points[i].x - camX0;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y - camY0;
+ if (py < 0) or (py > camH) then continue;
- px := nx + FRotationCenter[0] - bx;
- py := ny + FRotationCenter[1] - by;
-
- if ((px < 0) or (px > wx) or
- (py < 0) or (py > wy)) then
- continue;
-
- MapColor := @ColorMap[Round(points[i].c * 255)];
Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
Inc(Bucket.Red, MapColor.Red);
Inc(Bucket.Green, MapColor.Green);
Inc(Bucket.Blue, MapColor.Blue);
Inc(Bucket.Count);
end;
+ except
+ end
+end;
+
+///////////////////////////////////////////////////////////////////////////////
+procedure TRendererMM64_MT.AddPointsToBucketsAngle(const points: TPointsArray);
+var
+ i: integer;
+ px, py: double;
+ Bucket: PBucket;
+ MapColor: PColorMapColor;
+begin
+ for i := SUB_BATCH_SIZE - 1 downto 0 do begin
+// if FStop then Exit;
+
+ px := points[i].x * cosa + points[i].y * sina + rcX;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y * cosa - points[i].x * sina + rcY;
+ if (py < 0) or (py > camH) then continue;
+
+ Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
+
+ Inc(Bucket.Red, MapColor.Red);
+ Inc(Bucket.Green, MapColor.Green);
+ Inc(Bucket.Blue, MapColor.Blue);
+ Inc(Bucket.Count);
+ end;
+end;
+
+procedure TRendererMM64_MT.AddPointsWithAngleFX(const points: TPointsArray);
+var
+ i: integer;
+ px, py: double;
+ Bucket: PBucket;
+ MapColor: PColorMapColor;
+begin
+ try
+ for i := SUB_BATCH_SIZE - 1 downto 0 do
+ begin
+// if FStop then Exit;
+ FinalXform.NextPoint(points[i]);
+
+ px := points[i].x * cosa + points[i].y * sina + rcX;
+ if (px < 0) or (px > camW) then continue;
+ py := points[i].y * cosa - points[i].x * sina + rcY;
+ if (py < 0) or (py > camH) then continue;
+
+ Bucket := @buckets[Round(bws * px) + Round(bhs * py) * BucketWidth];
+ MapColor := @ColorMap[Round(points[i].c * 255)];
+
+ Inc(Bucket.Red, MapColor.Red);
+ Inc(Bucket.Green, MapColor.Green);
+ Inc(Bucket.Blue, MapColor.Blue);
+ Inc(Bucket.Count);
+ end;
+ except
+ end
end;
///////////////////////////////////////////////////////////////////////////////
@@ -304,7 +360,21 @@ var
nsamples: Int64;
nrbatches: Integer;
points: TPointsArray;
+ AddPointsProc: procedure (const points: TPointsArray) of object;
begin
+ if FCP.FAngle = 0 then begin
+ if UseFinalXForm then
+ AddPointsProc := AddPointsWithFX
+ else
+ AddPointsProc := AddPointsToBuckets;
+ end
+ else begin
+ if UseFinalXForm then
+ AddPointsProc := AddPointsWithAngleFX
+ else
+ AddPointsProc := AddPointsToBucketsAngle;
+ end;
+
SetLength(Points, SUB_BATCH_SIZE);
nsamples := Round(sample_density * bucketSize / (oversample * oversample));
@@ -322,15 +392,14 @@ begin
Progress(0);
// generate points
- case Compatibility of
+{ case Compatibility of
0: fcp.iterate_Old(SUB_BATCH_SIZE, points);
1: fcp.iterateXYC(SUB_BATCH_SIZE, points);
end;
+}
+ fcp.IterateXYC(SUB_BATCH_SIZE, points);
- if FCP.FAngle = 0 then
- AddPointsToBuckets(points)
- else
- AddPointsToBucketsAngle(points);
+ AddPointsProc(points)
end;
Progress(1);
@@ -355,8 +424,8 @@ var
begin
FStop := False;
- FRotationCenter[0] := fcp.center[0];
- FRotationCenter[1] := fcp.center[1];
+// FRotationCenter[0] := fcp.center[0];
+// FRotationCenter[1] := fcp.center[1];
image_height := fcp.Height;
image_Width := fcp.Width;
@@ -493,6 +562,7 @@ begin
Result.BucketWidth := BucketWidth;
Result.BucketHeight := BucketHeight;
Result.Buckets := @Buckets;
+{
Result.size[0] := size[0];
Result.size[1] := size[1];
Result.bounds[0] := Bounds[0];
@@ -501,6 +571,18 @@ begin
Result.bounds[3] := Bounds[3];
Result.RotationCenter[0] := FRotationCenter[0];
Result.RotationCenter[1] := FRotationCenter[1];
+}
+ Result.camX0 := camX0;
+ Result.camY0 := camY0;
+ Result.camW := camW;
+ Result.camH := camH;
+ Result.bws := bws;
+ Result.bhs := bhs;
+ Result.cosa := cosa;
+ Result.sina := sina;
+ Result.rcX := rcX;
+ Result.rcY := rcY;
+
Result.ColorMap := colorMap;
Result.CriticalSection := CriticalSection;
Result.Nrbatches := FNrBatches;
diff --git a/2.10/Source/RndFlame.pas b/2.10/Source/RndFlame.pas
index bb85dd1..323dfe1 100644
--- a/2.10/Source/RndFlame.pas
+++ b/2.10/Source/RndFlame.pas
@@ -432,6 +432,9 @@ begin
Result.zoom := 0;
Result.Nick := SheepNick;
Result.URl := SheepURL;
+
+ Result.xform[Result.NumXForms].Clear;
+ Result.xform[Result.NumXForms].symmetry := 1;
end;
end.
diff --git a/2.10/Source/XForm.pas b/2.10/Source/XForm.pas
index b06749d..9243e08 100644
--- a/2.10/Source/XForm.pas
+++ b/2.10/Source/XForm.pas
@@ -78,6 +78,7 @@ type
procedure Bubble; // var[24]
procedure Cylinder; // var[25]
procedure Smoke; // var[26]
+ procedure Noise; // var[27]
function Mul33(const M1, M2: TMatrix): TMatrix;
function Identity: TMatrix;
@@ -123,6 +124,7 @@ type
procedure GetVariable(const name: string; var Value: double);
function ToXMLString: string;
+ function FinalToXMLString(IsEnabled: boolean): string;
end;
implementation
@@ -131,7 +133,7 @@ uses
SysUtils, Math;
const
- EPS: double = 1E-10;
+ EPS: double = 1E-6;
procedure SinCos(const Theta: double; var Sin, Cos: double); // I'm not sure, but maybe it'll help...
asm
@@ -1488,6 +1490,39 @@ asm
{$endif}
end;
+//--27--///////////////////////////////////////////////////////////////////////
+procedure TXForm.Noise;
+{$ifndef _ASM_}
+var
+ r, sinr, cosr: double;
+begin
+ SinCos(random * 2*pi, sinr, cosr);
+ r := vars[27]*random;//(sqrt(sqr(ftx)+sqr(fty)) + eps);
+ FPx := FPx + {FTx*}r*cosr;
+ FPy := FPy + {FTy*}r*sinr;
+{$else}
+asm
+ mov edx, [ebx + vars]
+ fld qword ptr [edx + 27*8]
+ call System.@RandExt
+ fmulp
+ call System.@RandExt
+ fadd st, st
+ fldpi
+ fmulp
+ fsincos
+ fmul st, st(2)
+ fmul qword ptr [ebx + FTx]
+ fadd qword ptr [ebx + FPx]
+ fstp qword ptr [ebx + FPx]
+ fmulp
+ fmul qword ptr [ebx + FTy]
+ fadd qword ptr [ebx + FPy]
+ fstp qword ptr [ebx + FPy]
+ fwait
+{$endif}
+end;
+
//***************************************************************************//
procedure TXForm.NextPoint(var px, py, pc: double);
@@ -1849,6 +1884,7 @@ begin
FFunctionList[24] := Bubble;
FFunctionList[25] := Cylinder;
FFunctionList[26] := Smoke;
+ FFunctionList[27] := Noise;
//registered
for i := 0 to High(FRegVariations) do
@@ -1924,6 +1960,34 @@ begin
Result := Result + '/>';
end;
+function TXForm.FinalToXMLString(IsEnabled: boolean): string;
+var
+ i, j: integer;
+ Name: string;
+ Value: double;
+begin
+ result := Format(' 0 then
+ Result := Result + varnames(i) + format('="%g" ', [vars[i]]);
+ 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);
+ FRegVariations[i].GetVariable(Name,Value);
+ Result := Result + Format('%s="%g" ', [name, value]);
+ end;
+ end;
+
+ Result := Result + '/>';
+end;
+
///////////////////////////////////////////////////////////////////////////////
procedure TXForm.SetVariable(const name: string; var Value: double);
var
diff --git a/2.10/Source/XFormMan.pas b/2.10/Source/XFormMan.pas
index 33a102e..ab22682 100644
--- a/2.10/Source/XFormMan.pas
+++ b/2.10/Source/XFormMan.pas
@@ -6,7 +6,7 @@ uses
BaseVariation;
const
- NRLOCVAR = 26;
+ NRLOCVAR = 28;
function NrVar: integer;
function Varnames(const index: integer): String;
@@ -60,8 +60,9 @@ const
'fan',
'eyefish',
'bubble',
- 'cylinder'
-// 'smoke' - variation disabled... for now :)
+ 'cylinder',
+ 'smoke',
+ 'noise'
);
begin
if Index < NRLOCVAR then