public BurstParticleCollisionConstraintsBatch(BatchData batchData) : base() { this.batchData = batchData; }
public unsafe void Execute() { // Initialize batch data array for (int i = 0; i < batchData.Length; ++i) { batchData[i] = new BatchData(i, maxBatches); } // temporary array containing an open work item for each batch. WorkItem *workItems = stackalloc WorkItem[maxBatches]; for (int i = 0; i < maxBatches; i++) { workItems[i] = new WorkItem(); } // find a batch for each constraint: for (int i = 0; i < contacts.Length; ++i) { // OR together the batch masks of all entities involved in the constraint: int batchMask = batchMasks[contacts[i].GetParticle(0)] | batchMasks[contacts[i].GetParticle(1)]; // look up the first free batch index for this constraint: int batchIndex = batchIndices[i] = lut.batchIndex[batchMask]; // update the amount of constraints in the batch: var batch = batchData[batchIndex]; batch.constraintCount++; batchData[batchIndex] = batch; // add the constraint to the last work item of the batch: if (workItems[batchIndex].Add(i)) { // if this work item does not belong to the last batch: if (batchIndex != maxBatches - 1) { // tag all entities in the work item with the batch mask to close it. // this way we know constraints referencing any of these entities can no longer be added to this batch. for (int j = 0; j < workItems[batchIndex].constraintCount; j++) { K contact = contacts[workItems[batchIndex].constraints[j]]; batchMasks[contact.GetParticle(0)] |= batch.batchID; batchMasks[contact.GetParticle(1)] |= batch.batchID; } } // reuse the work item. workItems[batchIndex].constraintCount = 0; } } // fill batch data: activeBatchCount[0] = 0; int numConstraints = 0; for (int i = 0; i < batchData.Length; ++i) { var batch = batchData[i]; // bail out when we find the first empty batch: if (batch.constraintCount == 0) { break; } // calculate work item size, count, and index of the first constraint batch.workItemSize = math.min(minWorkItemSize, batch.constraintCount); batch.workItemCount = (batch.constraintCount + batch.workItemSize - 1) / batch.workItemSize; batch.startIndex = numConstraints; numConstraints += batch.constraintCount; activeBatchCount[0]++; batchData[i] = batch; } // write out constraints, sorted according to batches: for (int i = 0; i < contacts.Length; ++i) { var batch = batchData[batchIndices[i]]; int sortedIndex = batch.startIndex + (batch.activeConstraintCount++); sortedContacts[sortedIndex] = contacts[i]; batchData[batchIndices[i]] = batch; } }