m34tcode
2012-03-20 20:51:34
I've been working on a new PixelShift function that, while similar to the SRL PixelShift, should be much more accurate.
The basic procedure is this:
After a few repetitions inside of the PixelShift loop, You should be left with all the pixels in the box that your character animated over.
The tolerance is used to make sure that a small color in your surroundings does not throw the entire function off, and return a very low pixelshift.
I have not tested and fully worked the bugs out of this yet, and any help with that would be appreciated ;)
Here is the code so far:
EDIT2: seems to work now. Need some help with efficiency though. A 15x15 pixel square, takes about half a second to complete each repetition. Need to cut that time down to less than 300ms for a 75x150 square…
EDIT3: still working out the bug(s). Flipped the result so it now returns the number of pixels that changed, instead of those that remained the same.
EDIT4: Iv replaced the pixel intersect function, and it is now over 1k times faster. Still getting no pixel-shift every time, even when there is an obvious shift though…
EDIT5: Rewrote to use a boolean array, and it is up to speed.
The basic procedure is this:
- Capture all the pixel colors within a specified bow
- Capture all the pixels in the specified box again, and any pixels that have changed, are removed from the array
- Repeat until we have run out of time(specified in paramaters) or have looped x number of times
- This resulting array will contain all pixels whose colors changed beyond a specified tolerance
After a few repetitions inside of the PixelShift loop, You should be left with all the pixels in the box that your character animated over.
The tolerance is used to make sure that a small color in your surroundings does not throw the entire function off, and return a very low pixelshift.
I have not tested and fully worked the bugs out of this yet, and any help with that would be appreciated ;)
Here is the code so far:
{$DEFINE SMART}
{$i srl/srl.simba}
{$i srl/srl/misc/paintsmart.simba}
function GetColArr (Box : TBox) : T2DIntegerArray;
var
x,y : Integer;
begin
SetArrayLength(Result,box.X2-box.X1);
for x := 0 to box.X2-box.X1-1 do
begin
SetArrayLength(Result[x],box.Y2-box.Y1);
for y := 0 to box.Y2-box.Y1-1 do
begin
Result[x][y] := GetColor(x+box.X1,y+box.Y1);
end;
end;
end;
procedure ValidatePixels(Box : TBox; OrigCols : T2DIntegerArray; BoolArr : array of TBoolArray; Tolerance : Integer);
var
X,Y : Integer;
NewCols : T2DIntegerArray;
begin
NewCols := GetColArr(Box);
for X := 0 to Box.X2 - Box.X1-1 do
for Y := 0 to Box.Y2 - Box.Y1-1 do
begin
if not BoolArr[x][y] then
continue;
boolArr[x][y] := SimilarColors(origCols[x][y],NewCols[x][y],Tolerance);
end;
end;
function InitBoolArr(Width,Height : Integer) : array of TBoolArray;
var x,y : Integer;
begin
SetArrayLength(Result,Width);
for x := 0 to Width-1 do
begin
SetArrayLength(Result[x],Height);
for Y := 0 to Height-1 do
begin
Result[x][y] := True;
end;
end;
end;
function countBools(BoolArr : Array of TBoolArray; CountTrues : Boolean) : Integer;
var
X,Y,W,H,C : Integer;
begin
W := GetArrayLength(BoolArr);
H := GetArrayLength(BoolArr[0]);
For X := 0 to W-1 do
for Y := 0 to H-2 do
if BoolArr[X][Y] = CountTrues then
Inc(C);
Result := C;
end;
function CalculateNewPixelShift(Box : TBox; ShiftInterval, Repetitions, Tolerance : Integer) : Integer;
var
I,X,Y : Integer;
T,TT : LongInt;
OrigColArr : T2DIntegerArray;
BoolArr : array of TBoolArray;
begin
OrigColArr := GetColArr(Box);
BoolArr := initBoolArr(Box.X2-Box.X1,Box.Y2-Box.Y1);
MarkTime(T);
MarkTime(TT);
for I := 0 to Repetitions-1 do
begin
if (TimeFromMark(T) > (Repetitions*ShiftInterval)) then
begin
writeln('Completed only ' + IntToStr(I) + ' of '
+ IntToStr(Repetitions) + '. Try increasing the interval');
break;
end;
wait(Max(0,ShiftInterval-TimeFromMark(TT)));
MarkTime(TT);
validatePixels(Box,OrigColArr,BoolArr,Tolerance);
end;
for x := 0 to box.x2-box.x1-1 do
for y := 0 to box.y2-box.y1-1 do
if boolArr[x][y] then
SMART_DrawDot(false,Point(x+box.x1,box.y1+y),clRed);
Result := countBools(BoolArr,False);
end;
var
T : Longint;
Box : TBox;
begin
{$ifdef SMART}
Smart_Members := True;
Smart_Server := 100;
Smart_Signed := False;
Smart_SuperDetail := False;
{$endif}
SetupSRL;
SMART_ClearCanvas;
MarkTime(T);
box := IntToBox(236,97,271,175);
writeln(CalculateNewPixelShift(box,300,4,2));
writeln('executed in ' + FloatToStr(TimeFromMark(T)/1000.0));
end.EDIT1: found a bug, fixed it, but still only ever get a pixelshift of 0… hmmEDIT2: seems to work now. Need some help with efficiency though. A 15x15 pixel square, takes about half a second to complete each repetition. Need to cut that time down to less than 300ms for a 75x150 square…
EDIT3: still working out the bug(s). Flipped the result so it now returns the number of pixels that changed, instead of those that remained the same.
EDIT4: Iv replaced the pixel intersect function, and it is now over 1k times faster. Still getting no pixel-shift every time, even when there is an obvious shift though…
EDIT5: Rewrote to use a boolean array, and it is up to speed.