PaintingUtility.PaintLine

jlevet
Member
From: Marseille, France
Registered: 2014-03-31
Posts: 33
Website

Topic

Hello there,

I use during runtime painting the Brush.paint method that return the TileData painted, and i was wondering why PaintingUtility.PaintLine and others PaintingUtility functions don't return the iList/Array of TileData painted? I need that to configure the tiles.

Currently i'm using same code as your PaintingUtility.PaintLine function to retrieves the indexes :

if (from == to)
{
    PaintingUtility.Paint(system, from, args);
}
else
{
    PaintingUtility.NormalizeLineEndPoints(ref from, ref to);
    PaintingUtility.GetLineIndices((IList<TileIndex>) PaintingUtility.s_PaintIndices, from, to);
    PaintingUtility.Paint(system, (IList<TileIndex>) PaintingUtility.s_PaintIndices, args);
}	

But that is just unnecessary / duplicate code running


Game Developper working on Zombie Night Terror.

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 1

jlevet wrote:

I use during runtime painting the Brush.paint method that return the TileData painted, and i was wondering why PaintingUtility.PaintLine and others PaintingUtility functions don't return the iList/Array of TileData painted?

If you need to post-process tiles then you can subscribe to the Brush.TilePainted event.

In order to avoid the oddities of sharing some internal list between invocations of the public API it would become necessary for a fresh list to be allocated each time a line is painted. For instance, there would be an obscure error in the following "user code":

var lineA = PaintingUtility.PaintLine(system, fromA, toA, args);
var lineB = PaintingUtility.PaintLine(system, fromB, toB, args);
foreach (var index in lineA) {
    // We are now enumerating indices in line B!!
}

If you want an implementation which allocates a new list of indices each time then you could implement something like the following (or reuse some custom list to avoid allocations):

public static class YourPaintingUtility {

    public static IList<TileIndex> PaintLine(
        TileSystem system,
        TileIndex from,
        TileIndex to,
        PaintingArgs args
    ) {
        PaintingUtility.NormalizeLineEndPoints(ref from, ref to);

        var indices = new List<TileIndex>();
        PaintingUtility.GetLineIndices(indices, from, to);
        PaintingUtility.Paint(system, indices, args);

        return indices;
    }

}
jlevet wrote:

But that is just unnecessary / duplicate code running

This code is necessary if you require this functionality ;)

Implementation-wise this is fairly straightforward and the three methods required to achieve this are publicly documented:

jlevet wrote:

Currently i'm using same code as your PaintingUtility.PaintLine function to retrieves the indexes :

Please do not decompile the Rotorz Tile System assemblies because the asset store license prohibits this.

I hope that this helps!

jlevet
Member
From: Marseille, France
Registered: 2014-03-31
Posts: 33
Website

Response 2

Hi again,
I certainly wrote my previous message too fast. I'm not using "the same code", I just retrieve the list in TileIndexes painted the same way as the PaintLine method do. Here is how i do :

private List<TileIndex> result = new List<TileIndex>();
result.Clear();
				PaintingUtility.NormalizeLineEndPoints(ref from, ref to);
				PaintingUtility.GetLineIndices(result, from, to);

				foreach(TileIndex ti in result)
				{
					system.EraseTile(ti);
				}

				PaintingUtility.Paint(system,result, new PaintingArgs{brush=element.Brush, fillRatePercentage=100});

				foreach(TileIndex ti in result)
				{
					if (system.BulkEditMode == false)
					{
						var tile = system.GetTile(ti);
						GameObject go = tile.GetGameObject();
						SetBrushObjectData(go, system, element, ti, tile);
					}
				}
				if (refreshSurrounding)
				{
					foreach(TileIndex ti in result)
					{
						system.RefreshSurroundingTiles(ti);
					}
				}
				return result;

About the list of modified TileIndexes, is it planned to change the return type to be consistant with the "regular" paint method in next releases? Or theses void return types are on purpose?

In any case i'll take a look at the TilePainted event if it can fits my needs, thanks for the tip :)


Game Developper working on Zombie Night Terror.

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 3

jlevet wrote:
foreach(TileIndex ti in result)
{
    system.EraseTile(ti);
}

Existing tiles should be erased by PaintingUtility.Paint, so unless I have misunderstood your code, this extra loop should be redundant. Likewise, the painting utility class also deals with RefreshSurroundingTiles for you!

jlevet wrote:

About the list of modified TileIndexes, is it planned to change the return type to be consistant with the "regular" paint method in next releases? Or theses void return types are on purpose?

It is unlikely that these methods will be modified to return collections of the painted tile indices or data since an API is already provided which allows you to achieve this (PaintingUtility.GetLineIndices).

jlevet
Member
From: Marseille, France
Registered: 2014-03-31
Posts: 33
Website

Response 4

Hello,

I've juste removed my useless call to eraseTile without any regression.

Your remark about the refreshsurrounding makes me ask one question :
Is there any difference between the PaintingUtility.Paint function, and the Brush.Paint function? like auto-Bulk edit mode activated, auto-refreshsurrounding ? ...

But I can't use the Brush.TilePainted event right now because of the impossibility to retrieve the TileIndex. I need it when i paint a tile to configure some data into the attached GameObject.

I'll stay with my method :

  • Retrieving the list of TileIndexes

  • Call Paint with that list

  • Loop on the list to configure what i need

Let me know if you plan to add an additional parameter in this event.

Thanks

Last edited by jlevet (2014-06-26 10:32:25)


Game Developper working on Zombie Night Terror.

jlevet
Member
From: Marseille, France
Registered: 2014-03-31
Posts: 33
Website

Response 5

I have just tested this simple example :

  • I have a brush B with variation 0 in 0,0 coordinates into my tilesystem.

  • I call B.Paint (with the same brush B) with variation 1, i finish with variation 1. It works.

  • I call PaintingUtility.Paint with the following PaintingArgs new PaintingArgs{brush=B, fillRatePercentage=100, variation=1}, i finish with variation 0, unchanged, it seems it doesn't work in this case.


Game Developper working on Zombie Night Terror.

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 6

jlevet wrote:

Is there any difference between the PaintingUtility.Paint function, and the Brush.Paint function? like auto-Bulk edit mode activated, auto-refreshsurrounding ?

The painting utility class utilizes bulk editing mode for painting tiles to improve performance (which should also ensure that RefreshSurrounding is used). Since bulk editing mode can be nested it is possible to batch multiple invocations of the painting utility class. For instance,

// I find spacing helpful when using Begin/End style methods:
system.BeginBulkEdit();
    PaintingUtility.PaintLine(system, new TileIndex(0, 4), new TileIndex(0, 8), args); 
    PaintingUtility.PaintRectangle(system, new TileIndex(0, 0), new TileIndex(3, 3), true, args);
    someBrush.Paint(system, new TileIndex(0, 9));
system.EndBulkEdit();
jlevet wrote:

But I can't use the Brush.TilePainted event right now because of the impossibility to retrieve the TileIndex.

I agree, it would be useful to know the tile index in this context.

jlevet wrote:

I have just tested this simple example :

  • I have a brush B with variation 0 in 0,0 coordinates into my tilesystem.

  • I call B.Paint (with the same brush B) with variation 1, i finish with variation 1. It works.

  • I call PaintingUtility.Paint with the following PaintingArgs new PaintingArgs{brush=B, fillRatePercentage=100, variation=1}, i finish with variation 0, unchanged, it seems it doesn't work in this case.

After taking a brief glimpse at the painting utility source code this would appear to be a regression. I will take a closer look into this issue today.

Thanks for reporting this!

Lea Hayes
Rotorz Limited
From: United Kingdom
Registered: 2014-03-04
Posts: 638

Response 7

Lea Hayes wrote:

After taking a brief glimpse at the painting utility source code this would appear to be a regression. I will take a closer look into this issue today.

This issue has been resolved for the next release.