PDA

View Full Version : [Committed] Rotated SPS once again



J J
12-16-2012, 10:55 PM
Hi

Working on making SPS work at any angle.

16/12/2012 made a snippet to rotate the minimap:
// Returns an image of the minimap in a TMufasaBitmap
function SPS_GatherMinimap: TMufasaBitmap;
var
NormalMM, w, h, x, y: Integer;
rsAngle: Extended;
NormalDetails: T2DIntegerArray;
RotatedDetails: Array[0..149] of Array[0..149] of Integer;
P: TPoint;

begin
try
// Grabbing the minimap and converting it to a 2d array
GetClientDimensions(w, h);
NormalMM := BitmapFromString(w, h, '');
CopyClientToBitmap(NormalMM, 0, 0, w, h);
NormalDetails := GetBitmapAreaColors(NormalMM, 0, 0, w, h);
FreeBitmap(NormalMM);

// Rotating the minimap based on the angle and details we have
rsAngle := 0 - rs_GetCompassAngleRadians;
writeln('Rads: ' + ToStr(rsAngle));

for x:=0 to High(RotatedDetails) do
for y:=0 to High(RotatedDetails[x]) do
begin
P := RotatePoint(Point(X+MMCX-75, Y+MMCY-75), rsAngle, MMCX, MMCY);
if P.y < 0 then P.y := 0;
//writeln('P.x: ' + ToStr(P.x) + ' P.y: ' + ToStr(P.y));
RotatedDetails[x][y] := NormalDetails[P.x][P.y];
//Wait(5);
end;

// Creating the Result
Result := TMufasaBitmap.Create;
Result.SetSize(150, 150);

// Putting the colors based on our array filled with details on the result
for x:=0 to Result.Width-1 do
for y:=0 to Result.Height-1 do
Result.FastSetPixel(x, y, RotatedDetails[x][y]);
except
Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;
It is pretty slow so I"ll work on something better.

17/12/2012 made it a lot faster:
function SPS_GatherMinimap: TMufasaBitmap;
var
mmBmp, rBmp, w, h, x, y: Integer;
Details: T2DIntegerArray;

begin
try
// Getting the world map and rotating it
mmBmp := BitmapFromClient(MMCX-75, MMCY-75, MMCX+75, MMCY+75);
rBmp := RotateBitmap(mmBmp, 0-rs_GetCompassAngleRadians);
FreeBitmap(mmBmp);

// Getting the new width/height
GetBitmapSize(rBmp, w, h);
Details := GetBitmapAreaColors(rBmp, w/2-75, h/2-75, w/2+75, w/2+75);
FreeBitmap(rBmp);

// Creating the result
Result := TMufasaBitmap.Create;
Result.SetSize(150, 150);

// Putting the colors based on our array filled with details on the result
for x:=0 to 149 do
for y:=0 to 149 do
Result.FastSetPixel(x, y, Details[x][y]);
except
Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

Added rotation support to SPS functions. Added example script & new SPS file as attachment. Please test it with some walking just like you normally would. It automatically rotates everything etc. just let it run like normal. Let me know how it runs!

Olly
12-16-2012, 10:56 PM
what a beast :d

Kasi
12-16-2012, 11:15 PM
does RotateBitmap not work?

Olly
12-17-2012, 12:21 AM
does RotateBitmap not work?

It works fine, but it changes the size of the bitmap: http://i.imgur.com/5zD1C.png
and the bitmap needs to be 150x150, if there's a way to the bounds of the minimap and crop the bitmap to fit it it would work (lol if you understand).

DannyRS
12-17-2012, 12:27 AM
Goodjob Olly and JJ are SPS experts, its been really lacking some love lately, all for the additional options and features you guys can create :)

King
12-17-2012, 12:27 AM
That is sexy! I cant wait to see this finish and use it :spot:

Flight
12-17-2012, 12:39 AM
Yep, someone else has already been trying to do the same thing since early 2012. You can check it out here (http://villavu.com/forum/showthread.php?t=81213). For what it's worth, the basic idea that Ixilisi was using works just fine on all 4 major angles with a (10, -10) degree tolerance to each. But angles halfway between two major angles, like 45* and such won't work simply because of the problem you're running into now: Simba-rotated bitmaps are too distorted at that point.

Olly
12-17-2012, 03:20 AM
Worked on this late into the night, and i got it working decently but still improving can be done, i couldnt figure out a way to directly load it so I had to save the rotated minimap then load it again lol (damn TMufasa bitmaps) which costs at least 30ms, also debugging takes an extra 20ms. and for some reason it only works once per run haha, to late to figure out though.

http://i.imgur.com/jLxOJ.png


cross on paint is the location where sps_getmypos thinks we are (like 100% correct lol)
debugimgform is debugging us rotating it back to 0
and obviously the rs screen is me live in the game.


sadly compass readings can be a good 5 degrees +/- off so that doesn't help..(it perfectly read in the picture above so thats why it rotation looks very good) and I have a feeling this will only work on small custom maps, but regardless its better than nothing.

even more if we could get 100% perfect compass readings every time I think this would work alot better :p *waits for ogl*

regardless its way to late peace.

Coh3n
12-17-2012, 06:36 AM
You can increase the speed by setting variable here instead of calling high() each iteration of the loop:

for x:=0 to High(RotatedDetails) do
for y:=0 to High(RotatedDetails[x]) do
The rotated images are distorted, yes, but from what I can see it doesn't effect the accuracy, so that's a good sign.

E: Someone said TMufasaBitmap.RotateBitmap should work. That would also likely increase the speed as it's an internal Simba function.

E2: I wouldn't mind seeing an image of the too distorted images Flight is talking about.

J J
12-17-2012, 12:47 PM
Yep, someone else has already been trying to do the same thing since early 2012. You can check it out here (http://villavu.com/forum/showthread.php?t=81213). For what it's worth, the basic idea that Ixilisi was using works just fine on all 4 major angles with a (10, -10) degree tolerance to each. But angles halfway between two major angles, like 45* and such won't work simply because of the problem you're running into now: Simba-rotated bitmaps are too distorted at that point.
I don't think it's too distorted, especially because it gets converted to 5x5 color boxes. To the human eye there might be some disortion but when we are looking at a 25 pixel area it won't affect the end result too much.


You can increase the speed by setting variable here instead of calling high() each iteration of the loop:

for x:=0 to High(RotatedDetails) do
for y:=0 to High(RotatedDetails[x]) do
The rotated images are distorted, yes, but from what I can see it doesn't effect the accuracy, so that's a good sign.

E: Someone said TMufasaBitmap.RotateBitmap should work. That would also likely increase the speed as it's an internal Simba function.

E2: I wouldn't mind seeing an image of the too distorted images Flight is talking about.
Thanks for that tip, I'll play around with some stuff. TMufasaBitmap.Rotatebitmap doesn't work properly at angles other than 90/180/270/360. It messes up everything. Normal bitmap rotation doesn't work properly either as it makes the bitmap larger. Might be able to do something with that rotated bitmap though, I'll test it when I'm back from college.

xtrapsp
12-17-2012, 02:15 PM
I don't think it's too distorted, especially because it gets converted to 5x5 color boxes. To the human eye there might be some disortion but when we are looking at a 25 pixel area it won't affect the end result too much.


Thanks for that tip, I'll play around with some stuff. TMufasaBitmap.Rotatebitmap doesn't work properly at angles other than 90/180/270/360. It messes up everything. Normal bitmap rotation doesn't work properly either as it makes the bitmap larger. Might be able to do something with that rotated bitmap though, I'll test it when I'm back from college.

Is the bitmap size increase the same Each time? If so, why not do a % shrink on it?

Coh3n
12-17-2012, 03:05 PM
I don't think it's too distorted, especially because it gets converted to 5x5 color boxes. To the human eye there might be some disortion but when we are looking at a 25 pixel area it won't affect the end result too much.


Thanks for that tip, I'll play around with some stuff. TMufasaBitmap.Rotatebitmap doesn't work properly at angles other than 90/180/270/360. It messes up everything. Normal bitmap rotation doesn't work properly either as it makes the bitmap larger. Might be able to do something with that rotated bitmap though, I'll test it when I'm back from college.That doesn't seem right. I feel like RotateBitmap should work like you want. What exactly happens when you try to use it?

Olly
12-17-2012, 04:09 PM
Rotate bitmap does this, it wont keep the bitmap 150x150 which is what's needed for sps.

http://i.imgur.com/5zD1C.png


also i think TMufasaBitmap.Rotatebitmap does this, regardless rotatebitmap takes 15ms so speed isnt a issue with rotating :p

http://puu.sh/1BHv8.png

xtrapsp
12-17-2012, 04:43 PM
May sound stupid but how do I open the Tmufasalib ... I can't find it xD

Brandon
12-17-2012, 04:55 PM
May sound stupid but how do I open the Tmufasalib ... I can't find it xD

https://github.com/MerlijnWajer/Simba/blob/master/Units/MMLCore/bitmaps.pas


TMufasaBitmap is built in. Declare a variable:


var
BMP: TMufasaBitmap;

begin
BMP := TMufasaBitmap.Create; //Call the constructor.
//Call destructor when finished.

//See SmartGraphics for example.
end.

Olly
12-17-2012, 05:02 PM
Ive done my version

rotating map took: 31 ms
rotating map took: 15 ms
rotating map took: 16 ms
rotating map took: 32 ms

code:

function test: TMufasaBitmap;
var
t, bmpw, bmph:integer;
bmp, rotated: TMufasaBitmap;
amount:extended;
tpa, notpts : tpointarray;
box: tbox;
c: TClient;
sc: integer;
begin
//ClearDebugImg;
MarkTime(t);
SC := Smart_CurrentClient; //get current id of smart client
BMP := SPS_GatherMinimap; //gather the minimap image
SPS_FilterMinimap(bmp);

Amount := 0 - rs_GetCompassAngleRadians; //get the amount we need to rotate it by
Rotated := rotatebitmap(bmp.index,amount); //rotate the bitmap
GetBitmapSize(rotated, BMPW, BMPH);

SetTargetBitmap(Rotated); //set our target to the bitmap
FindColors(TPA, 0, 1, 1, bmpw-1, bmph-1); //find soild black (0) colors
ReturnPointsNotInTPAWrap(TPA, IntToBox(1, 1, bmpw-1, bmph-1), notpts); //return the points that arent black
Box := GetTPABounds(notpts); //get the bounds of the poits that arent black (the minimap circle)
BMP.free

Result := TMufasaBitmap.Create; //create a tmufasa bmp
Result.SetSize(150, 150); //set the size so no out of range stuff
c := getTClient; //get the client to copy from
Result.CopyClientToBitmap(
c.IOManager, false, 0, 0, Box.X1, Box.Y1, Box.X2, Box.Y2); //copy from the client onto the tmufasa

SetEIOSTarget('libsmartremote', ToStr(sc)); //re target to smart
FreeBitmap(Rotated);
Writeln('Rotating map took: '+tostr(timefrommark(t))+' ms');

//DrawBitmapDebugImg(result.index);
//DisplayDebugImgWindow(150, 150);
end;

Google
12-17-2012, 05:28 PM
If the bitmap is constantly getting rotated will it continue to get even more distorted? An example could be started walking at west angle then change the angle to south during mid-path?

Olly
12-17-2012, 05:29 PM
If the bitmap is constantly getting rotated will it continue to get even more distorted? An example could be started walking at west angle then change the angle to south during mid-path?

Well it grabs the minimap every time you want to walk, so yeah you can change angle mid path, im not sure how accurate it will be over large maps/distances though due to us not being able to read the compass 100%.

Mat
12-17-2012, 05:30 PM
@ Google, Your not turning the large map, its the mini map, so it just gets rotated to north to work out the pos.
Ninjaed by Olly,,,

DannyRS
12-17-2012, 06:58 PM
How you planning to adjust the clicking of the mm, or are you trying to set it up so that it would work the way it is?

J J
12-17-2012, 10:07 PM
How you planning to adjust the clicking of the mm, or are you trying to set it up so that it would work the way it is?
I've now edited SPS to work with any angle.
I'm not sure about the accuracy but Blindwalk worked well at like 83 degrees from Falador east bank to the west bank using four area's. Will add an example script and SPS file to the mainpost. Experimentate and let me know how well it works.

Olly
12-17-2012, 11:41 PM
JJ worked out the the centre of the rotated bitmap will always be the middle of the minimap (obviously), so I went ahead and threw this together. I believe this is near enough the fastest it will get this rotate bitmap on its own takes 15ms-16ms

video - Video (http://tinypic.com/r/346t941/6)


Rotating map took 16 ms.
Rotating map took 15 ms.

function SPS_RotateMinimap: TMufasaBitmap;
var
w, h, x, y, t: Integer;
mmBMP, rBMP: TMufasaBitmap;
c: TClient;
sc: integer;
MiddleBMP: tpoint;
begin
try
t := getSystemTime();
SC := Smart_CurrentClient;

//gathering minimap and rotateing it
mmBMP := SPS_GatherMinimapO;
rBMP := RotateBitmap(mmBMP.index, 0-rs_GetCompassAngleRadians);

//getting the middle of the bitmap
GetBitmapSize(rBMP, w, h);
MiddleBMP := Point(w/2, h/2);

//creating the bitmap by using the middle point
SetTargetBitmap(rBMP);
Result := TMufasaBitmap.Create;
Result.SetSize(150, 150);
c := getTClient;
Result.CopyClientToBitmap(
c.IOManager, False, 0, 0, MiddleBMP.x-75, MiddleBMP.y-75, MiddleBMP.x+75, MiddleBMP.x+75);

//re setting target back to smart / navbar
SetEIOSTarget('libsmartremote', ToStr(sc));
SRL_ResetNavBar;

//freeing un-needed data
mmBMP.Free
FreeBitmap(rBMP);

//debug
ClearDebugImg;
DrawBitmapDebugImg(Result.Index);
DisplayDebugImgWindow(150, 150);
Writeln('Rotating map took '+toStr(getSystemTime - t)+' ms.');
except
Writeln('SPS_GatherMinimap ERROR: '+ExceptionToString(ExceptionType, ExceptionParam));
end;
end;

Coh3n
12-18-2012, 06:51 AM
Very nice work, guys! I haven't looked into it, but shouldn't there be a way to do it with out resetting the client? Doesn't TMufasaBitmap have a function that can draw to another bitmap? So instead of calling CopyClientToBitmap, you'd just copy rBMP to result?

E: Would TMufasaBitmap.Copy not work?

Justin
12-18-2012, 06:56 AM
Wow, impressed with the work here guys!

Mat
12-18-2012, 07:14 AM
Very Nice Olly/JJ.
Going to test soon :)

Justin
12-18-2012, 07:29 AM
Would this work with normally custom maps?

euphemism
12-18-2012, 09:30 AM
ustin;1144184']Would this work with normally custom maps?

Yes, this has nothing to do with whether a map is 'custom' or not. This is implementing rotation of the minimap image grabbed from the client in order to match it up with the maps being used in a script.

Justin
12-18-2012, 09:31 AM
Yes, this has nothing to do with whether a map is 'custom' or not. This is implementing rotation of the minimap image grabbed from the client in order to match it up with the maps being used in a script.

Oh right, silly me, I had a brain-fart and was thinking it was rotating the loaded sps map :redface: