Optimizing a Raycasting Engine
OK so I've been working on a raycasting engine, and really the fundamentals of it have been quite easy to get down. I have the entire thing fully functional in MMF1.5 using overlays to copy/paste slices of bitmaps onto the screen. But the devil has been in trying to optimize the thing to run at a decent speed. I've fixed a lot of slowdown problems; I implemented a system to cache/buffer images loaded from outside files, and it only checks collisions on the rays along a predefined grid at the array. So I've gotten it to the point where it can reliably run a display like this:
http://img247.imageshack.us/img247/8687/pixelsmv2.png
Without much slowdown.
The problem instead comes now when the player runs into a wide-open area; where the raycasting engine has to cast all of its rays to their maximum distance. Simple checks, like disabling the draw wall/sprite groups, revealed that the game was running slow just from the ray casting alone, not what was being drawn on screen. And so thats the problem; raycasting itself is too slow in MMF. And I need to find out WHAT is the limiting factor in it, that is keeping it from running fast.
In a normal slowdown, I might be running 200 "rays" (3 pixels wide each), each of which is checking on average 5 collisions; 1000 loops total. It seems that when the game exceeds this 800-1100 threshold, there is significant slowdown. The game is equally slow for a high resolution running few repetitions, and a low resolution running many. The total number of loops runs seems to be the slowdown.
My loop for the raycast looks like this:
http://img111.imageshack.us/img111/38/46272376ib0.png
http://img111.imageshack.us/img111/2104/20038394ur4.png
Theres two separate objects recording horizontal and vertical collisions. Their distances, X & Y velocities, interval, X & Y positions are all passed in, as well as the angle of the ray. Passed out of the procedure is the offset, "color" (type of wall), and distance, as well as flag 5 of the green detector, which records whether the collision was vertical or horizontal. The code roughly follows this sort of raycasting:
http://www.permadi.com/tutorial/raycast/rayc1.html
Now, what inside of that loop is causing such slowdown by being run 1000 times, and what can I do to speed it up? I've tried the obvious loop unwinding and such, to no avail. What the heck is the slowboat
Re: Optimizing a Raycasting Engine
The slowdown is that you have the "On Loop" like a million times.
Re: Optimizing a Raycasting Engine
And probably the pasting a lot of data to an overlay every loop part. Wouldn't it be better to just wait for the raycasting extension instead?
Re: Optimizing a Raycasting Engine
Pasting data to the overlay is not causing any slowdown whatsoever. If I disable the "draw wall" group, it has the same FPS as if it were active. I narrowed down the problem to being this section of code.
And I'm not sure what you mean by having the "On Loop" events; are you saying that each event inside of a loop is eating up massive overhead in the MMF architecture, or what? Like reducing it to as few lines of events as possible would speed it up?
Re: Optimizing a Raycasting Engine
well it would be nice if anyone who had some inside knowledge on the MMF architecture could help out
Re: Optimizing a Raycasting Engine
i don't know if i can help you with the inner workings of mmf, but may i suggest a hack?
Try splitting your rays into even and odd rays (ie, every other ray goes into a separate group)
each time you run through your code, only loop through the even rays one time, then switch to the odd rays. Thus you will cut the number off loops per code pass in half, and the difference will probably not be noticeable.
If you are getting small visual glitches from this, you can "fudge" the change in the uncast rays by averageing the change in the ray on either side of it that WAS calculated (by definition of the alternating odd and even rays...)
Hope this sparks some ideas.
-andy
Re: Optimizing a Raycasting Engine
actually thats a pretty good idea, it should halve the work done. I'll try implementing it.
Re: Optimizing a Raycasting Engine
Quote:
Originally Posted by MechaBowser
The slowdown is that you have the "On Loop" like a million times.
10 times actually XD
Re: Optimizing a Raycasting Engine
When MMF2 makes a loop, it looks for all events containing the "on loop" condition, for every step. If you run 20 loop steps in a fastloop and have 10 "on loop" conditions, MMF2 would work this
loop steps x on loops
times which in this case is 20 x 10, alias 200 times. In one frame.
And that's pretty much.
Re: Optimizing a Raycasting Engine
yah, but when it compiles that into machine code, its going to be the same length as if I had compressed those same actions into a single event, only plus the overhead that MMF uses for loops. And running an empty loop with 100 "on loop" events for X times, will have the same game speed as running a single "on loop" event 100 * X times, so the issue has to be something else inside the loop.
I'd say its either an issue with running a loop from inside a loop, or from the way MMF computers large integers (I assumed it was 32 bit so that shouldn't be an issue, should it?)