tonihele / OpenKeeper

Dungeon Keeper II remake
GNU General Public License v3.0
435 stars 41 forks source link

Implement minimap #219

Open ufdada opened 8 years ago

ufdada commented 8 years ago

The minimap has several function we have to consider:

They also have different functions, like:

Small mini map (one the bottom left):

Big Map (pressing M):

Possession Map:

tonihele commented 8 years ago

Thorough specs, nice :) We can draw the minimap in another thread, a 3rd thread perhaps, and just queue it to be drawn to UI. 3rd thread since this can be nicely isolated and scheduled at a different rate. If it flickers, the user can also poll the changes.

We could just extend the map thumbnail drawing class. What we are lacking big time is the player map. But the implementation doesn't need to wait for this, the real map can be used instead.

ufdada commented 8 years ago

Well i actually have several ideas how we could implement this.

First one is to use the map thumbnail drawing class like you said. Plain image so nothing fancy about it. And of course we have to redraw everything on every change or animation. Probably a reason they had such a low refresh rate. Since we already have something, probably the easiest task in the short run.

Second we could create a mesh map like we are doing with the current map, just 2d. Then batching it up. When a tile changes we could update it like we are doing on the map itself. If creatures are moving we can just move the dot instead of regenerating the whole map. Even storing positional information (if needed) shouldn't be a big deal. Contra is definitely the higher poly count.

Third one is using an svg. Good at debugging (easy exporting and file format) and interaction should also be no problem. But the support of displaying it is not that good, so i guess this is not a preferred way.

I took a closer look at the map and saw by hovering an owned room the room icon was below the creature dots. Well there might be 2 reasons for that: They draw the icon directly to the map image or they had at least 3 layers.

What do you think?

tonihele commented 8 years ago

I'd say we could go with the first one. We can improve the implementation later. The performance on the thumbnail creator is non-optimal. It draws one pixel at a time, a simple optimization would be to at least draw rectangles where available (one tile is bigger than one pixel) or totally draw the rectangles by the XInstances (bigger rectangle than one tile). But this is again also just polishing, not critical.

We can have it listen to the tile changes, and those tile changes would just set flag that on next draw cycle also draw the BG again (BG = map). And if the flag is not set, just draw the creature dots (and all the other blings) in a loop, it shouldn't be a big task. Maybe heavier to see if they have moved, so always redraw this layer. Combine the layers and done, set as a texture etc. A layer means separate BufferedImage, since there really are no layers as far as I know.

About the second one, I don't know how easy it is, or possible. But since we already have the scene graph.. I wonder can we just write a "renderer" that renders it in a pixelly way. Other thing, in the big map, we could use the orthogonal projection (I hope I got the term right) on the scene. That would look cool, but it is not as clear as the pixel map of course.

SVG is a bit difficult. We would need external libraries (Batik etc.), and it is slow. As you said, maybe not the preferred way.

ArchDemons commented 8 years ago

I vote for multiple overlaid layers with an alpha channel image

tonihele commented 8 years ago

I vote for multiple overlaid layers with an alpha channel image

Oh yeah, that way it would be a bit hardware accelerated

ufdada commented 8 years ago

I vote for multiple overlaid layers with an alpha channel image

That's what i also would do, like:

This way we could save on redrawing the image and even use different image sizes (bigger one for map, smaller one for the creatures). We just need to set the MagFilter to Nearest.

tonihele commented 8 years ago

Yeah, I had a feeling you were trying to imply this with layers, but I didn't understand it on the first time. 3D...

ufdada commented 8 years ago

Well not exactly, what i actually meant was more something like that: http://blog.theknightsofunity.com/implementing-minimap-unity/ . Building a map with simplified meshes and just RenderToTexture from another cam (top view).

It's probably way more expensive, but it would be nice to debug. And changing the position of the target the cam should focus should also be easier (fixed, pov).

tonihele commented 8 years ago

Unity makes it look easy :) Well it is not that hard manually, I assume...

Nifty-wise this means an object per layer, and each change updates the texture atlas. I don't remember was it possible to disable the batching/atlassing for a single geometry. So in that way I don't know would caching a BufferedImage and adding them together in CPU be faster after all.

Super manual way would be our own quad in the GUI node with a custom material. A material that takes these layers as a texture and handles all, handy and fast.

I don't know how the zooming and moving the map is possible, just changing texture coordinates (UV)?

tonihele commented 8 years ago

And our custom quad in GUI node I assume can be attached to a Control. So it actually would be quite handy to manage all the actions an states. No Nifty.