Data types and components and burst enabled job systems

Hi.

If IComponentData can’t have NativeArrays, and burst enabled jobs should(?) be passed nativearrays, how exactly is the common way to solve this?

Some context, as I’m hoping for some kick start help to get me rolling:

I’m trying to create my first System. The job is to create many 2d images, and merge them to a final procedural image of given size x,y. The final image will then be used for several purposes, like mesh verticies, texture, normals, etc.

Any pointers to how you would build such a system? Or is it best to keep this one job-only without using system and entities, and just assign to entity as the job(s) is done? I have working PoC job ready, where the array is copied before and after the job is modifying it.

public void Mod_addPerlinNoise(ModificationData modData, ref Vector3[] data)
        {
            NativeArray<float3> jobdata = new NativeArray<float3>(data.Length, Allocator.TempJob);
            for (int i = 0; i < data.Length; i++ )
            {
                jobdata[i] = data[i];
            }

            AddPerlinNoiseJob addPerlinNoiseJob = new AddPerlinNoiseJob
            {
                data = jobdata,
            };
           
            JobHandle jobHandle = addPerlinNoiseJob.Schedule(data.Length, 128);
            jobHandle.Complete();
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = jobdata[i];
            }
            jobdata.Dispose();
        }
        [BurstCompile(FloatPrecision.Low, FloatMode.Fast)] public struct AddPerlinNoiseJob : IJobParallelFor
        {
            public NativeArray<float3> data;
           
            public void Execute(int i)
            {
                data[i] += new float3(0f,
                    100 * noise.cnoise (new float2(0.0008f * data[i].x, 0.0008f * data[i].z ))
                +   10 * noise.cnoise (new float2 ( 0.008f * data[i].x, 0.008f * data[i].z ))
                +   1 * noise.cnoise (new float2 ( 0.08f * data[i].x, 0.08f * data[i].z ))
                , 0f);
            }
        }

Are you aware of dynamic buffers? Basically lists you attach to entities.
https://docs.unity3d.com/Packages/com.unity.entities@0.1/manual/dynamic_buffers.html

Thank you, tertle.

Yes, I saw dynamic buffers mentioned in other thread where someone else had problems with trying to put NativeArray in an entity. Does that mean I should give the entities a dynamic buffer, and then in the system copy the buffer to nativearray before the job, then back after the job has completed, as in my example above?

public struct ImageData2d : IBufferElementData
    {
        // These implicit conversions are optional, but can help reduce typing.
        public static implicit operator float(ImageData2d e) { return e.value; }
        public static implicit operator ImageData2d(float e) { return new ImageData2d { value = e }; }
        public float value;
    }

You don’t need to use a nativearray if you use a dynamic buffer. You can just access that directly in a job.

    public struct Job : IJobForEach_B<ImageData2d>
    {
        public void Execute(DynamicBuffer<ImageData2d> imageData)
        {
           
        }
    }
1 Like

You might be able to create a normal class that held all your native collections, and then use pointers to the arrays inside a job? Maybe just copy the arrays back and forth? I’m definitely unsure about this, but it might be worth a try.

Thank you for the help, guys! DynamicBuffer will indeed solve this.