adonthell-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Adonthell-devel] Mapedit filtering


From: Kai Sterker
Subject: Re: [Adonthell-devel] Mapedit filtering
Date: Thu, 2 Jun 2011 14:11:29 +0200

On Wed, Jun 1, 2011 at 11:44 PM, James Nash <address@hidden> wrote:

In general, I like your idea quite well, but it appears quite
difficult to implement. I had hoped for something that fits quite well
into the existing framework. So let me start by explaining what is
currently there, and then think about how something like your idea
could be added on top of it without a year of coding :-).

There are two ways to pick mapobjects for placing on the map:

1. Click on an object in the mapview.
2. Click on an object in the entity list.

Once picked, you can place that object down as often as you want,
unless you release it by right clicking or pressing ESC.

The problem is that objects not present on the map or at the current
location can only be selected from the entity list. And that contains
all available mapobjects. Thus, the idea is to filter that list in
some fashion.


Placing objects itself is aided by a dynamic grid. This works very
well for objects of the same size (or multiples of that size), but
requires manual adjustment for objects of different sizes. Like a
straight wall and a corner part.

The idea here is, that in almost all cases, a tile has 4 sides to
which other tiles can connect. And if regarding a single side, in
almost all cases an adjusting tile will be either centered or aligned
to one of the outer edges. The grid controls work under that
assumption. See here:
http://adonthell.berlios.de/doc/index.php/Tools:Mapedit:Grid

The problem, of course, is that you will have to switch back and forth
between the grid controls and the main window often as right now there
is no information how two tiles are connected and therefore the grid
cannot adapt automatically.

That is where I thought your idea could help in two ways:

1. By indicating matching tiles, the entity list can be filtered to
only show tiles that can be attached to the selected object. (But it's
less suited to filter for pieces of matching furniture, for example.
That's why I still see the tag based filtering as a worthwhile
alternative.)

2. By specifying how any two tiles are aligned, the grid can be
automatically set accordingly, so that the picked mapobject can be
placed directly on the map without the need for manual adjustments.


I'm not as good as you in providing mockups, so I have to do with a
simple description of the sequence I would envision.

1. Pick a horizontal wall piece.
2. Enable "matching filter" (hopefully with a simple key shortcut)
3. The entity view shows a number of matching horizontal and corner pieces.
4. Place a line of wall pieces (left click), then release the current
piece (right click)
5. Pick a corner piece from the entity list
6. The filter changes to show mapobjects matching this new piece.
7. The grid changes so the corner can be placed seamlessly next to the
last horizontal wall piece. (left click)
8. Release the corner piece (right click), select a vertical wall
piece from the entity list.
9. The filter changes
10. The grid changes.
11. (and so on) ...


The advantage I see here is that the amount of work required to get
this working is very small. Filtering a listview in GTK+ is trivial.
The grid and alignment stuff is already there, it just needs to be
toggled via a function call instead of a button press. No need for
extra highlighting, edge detection, showing "drop down" lists of
matching mapobjects (although I would quite like the latter, so maybe
at a later point it could be added as an alternative for picking from
the entity list.).


There is a second part to all that, and that is defining the meta-data
required by the above. I do like your general idea here, as it seems
much more convenient than what I had in mind. But instead of adding a
special "connector" shape, perhaps we could just stick to the four
edges (back, front, left, right) of a tile (I'd rather not worry about
top and bottom). Consider the following ASCII art

Let that be a horizontal wall piece. You'd have connecting edges on
the left and right.

  ,-----------,
A '-----------' A

Since you want to be able to add that same wall piece on either side,
your connecting edges would have to have the same id.

Now let there be a matching corner tile.

   ,-----,
A '---, |
      | |
      |_|
       B

The left side would have the same id as the horizontal wall above. The
front side would have a different id, equal to that of matching
vertical wall pieces.

When the horizontal piece is selected, the filter would show the
corner since one of its sides has the same id. We could even improve
the code and only consider ids of facing sides. (I.e. object A left id
== object B right id would be a match whereas object A left id ==
object B left id would not result in a match).


A ground tile OTOH would usually have the same id on all four sides. A
transition tile between different types of ground would have different
ids. The auto-filtering would then work well for those too.


For most decoration, ids for the sides would not make sense. But there
might be exceptions, for example if you have a middle part of a table
or bench and two corner parts.


In addition to the side ids, we'd need to specify the alignment meta
data. I don't think we can get away with a simplistic
center/left/right scheme. We may need something similar to what you
proposed: the area where the connection is made. Again, I would keep
it simple and just specify one such "connector" per side, with a start
and end position. Initially those would be the corner points of that
side, so for a lot of tiles no change to the values would be required.
For L, T, or X shapes, you could adapt them as needed,

In theory, it would be nice to specify the "length" once for each id,
because matching "connectors" should be the same size on every shape.
Then you would just adapt the starting point of the connector, if
necessary. But in practice, the implementation would be more difficult
without much added benefit.

The grid can then be positioned such that the connectors on facing
sides line up, which is simple math.


Implementation wise, a "connector" object would have a side, an id,
and two integers for start and end position. (Since we already know
the side, we only need one coordinate for each). Each model then
simply gets a list of connectors. That way, if we want to get fancy,
you could have multiple connectors per side. For now, I can't think of
a case where this would be needed. A GUI for editing these four
properties would be easy to add to modeller and I wouldn't even mind
saving the connector data in the actual model. In addition, the
selected connector could be displayed on the model, so it would be
easier to set start and end.

OTOH, maybe keeping connector data separate from the model would allow
to "pick" from a list of existing connectors. That might make adding
connectors to a model easier, as you do not have to type the id every
time. I'm certainly open to suggestions here.


As for the other meta-data fields you suggested:

* Tags: my idea is that you can add additional tags in mapedit,
together with the "automatic", directory based tags. There's already a
tab in the entity property dialog for that purpose, it just has no
logic implemented yet. The property dialog shows the first time you
add a new object to the map, and it can be brought up any time later
by hovering over an object and pressing enter. My idea was, that the
tag list for that mapobject would have the same functionality as the
tag list in the filter dialog, so that you can bring that up instead
to filter for similar objects without the need to know which tags
might be assigned to any specific object.

* Description: not sure if this should go into modeller or mapedit.
But I assume you'd want to be able to see it in mapedit.

Maybe I've got an idea here: would it be helpful if the entity
property dialog had a button that would open the current mapobject in
modeller? Then you could edit description and tags and stuff in
modeller (where it would seem to belong more naturally) and only have
a readonly display in mapedit, Don't expect fancy stuff like automatic
synchronisation when saving in modeller, however! But it's only a
single button click to reload the entity list anyway.


Okay, this was kinda long, so lets hear your opinion first. I admit
that it's not as fancy as what you had in mind (shows I'm no artist,
just a lazy programmer), but it should come close in functionality and
require only a little bit of additional coding to make it work. So
what do you say?

Kai

> My 2p on the filtering:
>
> Perhaps it's better to reflect the directory structure of the models in 
> mapedit for now. Related wall parts and suchlike are already grouped in a 
> single directory, so we can exploit that. Perhaps have one 
> pane/dialog/whatever with collapsible directories (like Windows Explorer) and 
> another which then shows a list of mapobjects within the currently selected 
> directory.

> As far as the templates go, there are a few simple options for hiding them:
> - We just move them out of the gfx48/models48 directory trees and keep them 
> separately somewhere else.
> - Or: In mapedit we just hide any directory whose name matches *template* 
> (possibly this can be enabled/disabled via a tickbox somewhere).
>
> Ultimately though, I think meta-data that describes which mapobjects fit 
> together and user-defined tags are the way to go. Once we have a format for 
> such data and have augmented the mapobjects with it we can do much better 
> filtering. IMHO, finding mapobjects that way will ultimately be the default, 
> so users don't need to know or care about the directory structure.
>
> I think the meta-data topic deserves a bit more discussion first though. Off 
> the top of my head, I'd like support for stuff like:
>
> - User-defined keywords (aka tags) to help categorise the mapobjects
> - Descriptions: I'm thinking a free text field where designers can put 
> comments about intended usage, tips, instructions etc.
>
> As for describing how objects fit together, I'd propose something like the 
> following:
>
> - We have something that describes the surfaces where two related objects 
> touch. E.g. the left & right vertical sides of a facing wall piece. When 
> tiling that piece, the left side of one touches the right of the other. Let's 
> call it a "connecting surface" for now (can't think of a snappier name right 
> now).
>        - This connecting surface would most likely be created in the modeller 
> as a special kind of shape. It is saved as an individual file though.
>        - It gets a unique ID assigned to it (probably automatically)
>        - Possibly it has an optional, user-friendly display name too
>
> - Then, when creating actual object in the modeller you can import relevant 
> connecting surfaces and position them on the model. The idea is that you 
> describe where any other object that contains the a connecting surface with 
> the same ID can connect.
>
> I think this is preferable to, for example, explicitly linking from one 
> object to another since that can quickly become a maintenance nightmare when 
> you get lots of objects.
>
>
> Later on, the mapeditor can use this meta-data to suggest the next object to 
> place on the map. I imagine this to be a bit like auto-complete in an IDE or 
> browser address bar. E.g. I put an object on the map and as I move the mouse 
> cursor near one of its connecting surfaces I get some kind of indication that 
> there is a connecting surface (maybe it lights up or I get a different 
> cursor). Some key or button press then displays a new object that is 
> connected to the previous one (maybe it's duplicate of the one I just placed 
> initially) and using some other button I can cycle through other available 
> objects until I find the one I want.
>
> Hmm... this'll be a lot easier to describe in picture. I'll make a quick UI 
> mock-up. brb!
>
>
>        - James
>
>
>
>
> On 1 Jun 2011, at 19:49, Kai Sterker wrote:
>
>> Seems I've ran into a bit of trouble with my tag based filtering idea
>> for mapedit. I've attached the filter dialog I've implemented so far,
>> but I'd like to get some input on the underlying logic.
>>
>> Basically, there are two ways to filter the list of map objects: show
>> only objects that "match" the current object, i.e. all objects that
>> could possibly be placed seamlessly next to the current object. Since
>> the meta-data for this feature would have to be supplied by the user,
>> I did not start on this type of filter yet. I've got some concept in
>> mind and I don't expect much trouble there.
>>
>> I did start with the supposedly easier, tag based filtering, where the
>> components of the model path make up the tags attached to each model.
>> (In the future, this might be extended with user-supplied tags, too).
>> The result of the current model48/ content is shown in the filter
>> dialog screenshot (The Count column gives the number of models with
>> the given tag).
>>
>> My idea was, to automatically exclude the "template" stuff from the
>> model list, but in a way that would be obvious to the user. So it's in
>> the list like a regular tag, but unchecked by default. Going with
>> that, the filter logic would have to be "hide all objects that contain
>> 'template/' in their file path". But then I thought, when editing a
>> map, I might want to see all "inside" "walls". And it would be easier
>> if I could just check those two tags to narrow down the list. But that
>> would also include all the inside wall templates. And now I am stuck,
>> not really able to decide which route to go.
>>
>> Maybe just hardcode the template stuff filtering and otherwise go with
>> the latter filtering logic?
>>
>> Or there could be two columns of checkboxes, one for inclusion and the
>> other for exclusion. Then I could include "inside" "wall"s and exclude
>> "templates" at the same time (and "stone" and "mine" and "cave" walls
>> too, if I wanted), OTOH, perhaps I'd be better of to just filter for
>> "plaster" "walls" then.
>>
>> Anyone got a better idea?
>>
>>
>> I've got some stuff to work on besides the filtering, so I'll let that
>> sit for a little and wait for your suggestions.
>>
>> Kai
>> <filter.png>_______________________________________________
>> Adonthell-devel mailing list
>> address@hidden
>> https://lists.nongnu.org/mailman/listinfo/adonthell-devel
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]