- Home /
Converting a List-Based Function to an Array-Based Job
Hi, I'm currently experimenting with the job system to get highly performant code for a mobile device. The game involves setting pixels on a texture, and I'm in the process of converting the circle brush into a parallel job (which should be much faster). Here's the original function code :
public Tuple<Vector2[], Color[]> SetFilledCircle(int x, int y, Color _color, int _r)
{
List<Vector2> ShapePixCache = new List<Vector2>();
List<Color> ShapeColCache = new List<Color>();
int r2 = _r * _r;
for (int ind1 = -_r; ind1 <= _r; ind1++)
{
for (int ind2 = -_r; ind2 <= _r; ind2++)
{
if (ind1 * ind1 + ind2 * ind2 <= r2)
{
ShapePixCache.Add(new Vector2(x + ind1, y + ind2));
ShapeColCache.Add(_color);
}
}
}
return Tuple.Create(ShapePixCache.ToArray(), ShapeColCache.ToArray());
}
Now, this works great, but also fairly slow since when I draw a lot of the circle I have to loop over and do it over and over. So, I looked at the job system to get a bunch of these to run in parallel. But here's the problem: to return values you can only use NativeArrays and my current system works on lists. Ive tried different ways of indexing to set values of arrays, but nothing seems to be working properly. Can someone please help?
Heres the Job:
public struct CircleGen : IJobParallelFor
{
public NativeArray<Vector2> PixelLocCache;
public NativeArray<Color> PixelColCache;
[ReadOnly] public NativeArray<Vector2> Location;
[ReadOnly] public Color cColor;
[ReadOnly] public int Radius;
public NativeArray<int> index_additive;
public void Execute(int index)
{
int radiusSquared = Radius * Radius;
for (int i = -Radius; i <= Radius; i++)
{
for (int j = -Radius; j <= Radius; j++)
{
if (j * j + i * i <= radiusSquared)
{
int indcalc = index_additive[0];
PixelLocCache[index] = new Vector2(Location[index].x + i, Location[index].y + j);
PixelColCache[index] = cColor;
index_additive[0]++;
}
}
}
}
}
And here's how its being called: public Tuple RunFilledCircleJob(Vector2[] loc, Color col, int radius, int rep) { int indcount = (int)Mathf.Pow(radius, radius) * rep;
var locIndex = new NativeArray<int>(1, Allocator.TempJob);
var locNative = new NativeArray<Vector2>(indcount, Allocator.TempJob);
var colNative = new NativeArray<Color>(indcount, Allocator.TempJob);
var locToNative = new NativeArray<Vector2>(loc.Length, Allocator.TempJob);
locToNative.CopyFrom(loc);
var circle = new CircleGen
{
PixelLocCache = locNative,
PixelColCache = colNative,
Location = locToNative,
cColor = col,
Radius = radius,
index_additive = locIndex
};
JobHandle handle = circle.Schedule(indcount + 1, 256);
handle.Complete();
var locReturn = locNative.ToArray();
var colReturn = colNative.ToArray();
locNative.Dispose();
colNative.Dispose();
locToNative.Dispose();
locIndex.Dispose();
return Tuple.Create(locReturn, colReturn);
}
Any help would be appreciated, since I've been struggling with this for a while.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How to loop an array of 2d sprites 1 Answer
Material Colour Change, Loop 2 Answers