What's the usecases for firstEntityIndex in IJobChunk?

The execute method for IJobChunk interface has a parameter named firstEntityIndex however, the documentation doesn’t say anything about it. I would like to know more information about this parameter and its use cases.

public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
   {
       //...
   }

Used for some very specialized/optimized solutions. An example is in the Unity.Physics system merging merging 2 different queries, dynamic and static rigidbodies, into a single array.

For example

            [BurstCompile]
            internal struct CreateRigidBodies : IJobChunk
            {
                [ReadOnly] public ArchetypeChunkEntityType EntityType;
                [ReadOnly] public ArchetypeChunkComponentType<Translation> PositionType;
                [ReadOnly] public ArchetypeChunkComponentType<Rotation> RotationType;
                [ReadOnly] public ArchetypeChunkComponentType<PhysicsCollider> PhysicsColliderType;
                [ReadOnly] public ArchetypeChunkComponentType<PhysicsCustomData> PhysicsCustomDataType;
                [ReadOnly] public int FirstBodyIndex;

                [NativeDisableContainerSafetyRestriction] public NativeSlice<RigidBody> RigidBodies;

                public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
                {
                    var chunkColliders = chunk.GetNativeArray(PhysicsColliderType);
                    var chunkPositions = chunk.GetNativeArray(PositionType);
                    var chunkRotations = chunk.GetNativeArray(RotationType);
                    var chunkEntities = chunk.GetNativeArray(EntityType);
                    var chunkCustomDatas = chunk.GetNativeArray(PhysicsCustomDataType);

                    int instanceCount = chunk.Count;
                    int rbIndex = FirstBodyIndex + firstEntityIndex;

                    bool hasChunkPhysicsColliderType = chunk.Has(PhysicsColliderType);
                    bool hasChunkPhysicsCustomDataType = chunk.Has(PhysicsCustomDataType);

                    for (int i = 0; i < instanceCount; i++, rbIndex++)
                    {
                        RigidBodies[rbIndex] = new RigidBody
                        {
                            WorldFromBody = new RigidTransform(chunkRotations[i].Value, chunkPositions[i].Value),
                            Collider = hasChunkPhysicsColliderType ? chunkColliders[i].ColliderPtr : null,
                            Entity = chunkEntities[i],
                            CustomData = hasChunkPhysicsCustomDataType ? chunkCustomDatas[i].Value : (byte)0,
                        };
                    }
                }
            }
jobHandles.Add(new Jobs.CreateRigidBodies
{
    EntityType = entityType,
    PositionType = positionType,
    RotationType = rotationType,
    PhysicsColliderType = physicsColliderType,
    PhysicsCustomDataType = physicsCustomDataType,

    FirstBodyIndex = 0,
    RigidBodies = PhysicsWorld.Bodies
}.Schedule(DynamicEntityGroup, inputDeps));

// ..

if (numStaticBodies > 0)
{
    jobHandles.Add(new Jobs.CreateRigidBodies
    {
        EntityType = entityType,
        PositionType = positionType,
        RotationType = rotationType,
        PhysicsColliderType = physicsColliderType,
        PhysicsCustomDataType = physicsCustomDataType,

        FirstBodyIndex = numDynamicBodies,
        RigidBodies = PhysicsWorld.Bodies
    }.Schedule(StaticEntityGroup, inputDeps));
}

You really won’t use it much, just there if you need.

1 Like