/// <summary> /// Adds a particle field to this pool with the specified description, or gets an existing one /// </summary> /// <param name="fieldDesc">Description of the field</param> /// <returns>The newly added or already existing field</returns> internal ParticleField AddField(ParticleFieldDescription fieldDesc) { // Fields with a stride of 0 are meaningless and cannot be added or removed if (fieldDesc.FieldSize == 0) { return(new ParticleField()); } ParticleField existingField; if (fields.TryGetValue(fieldDesc, out existingField)) { return(existingField); } var newParticleSize = ParticleSize + fieldDesc.FieldSize; #if PARTICLES_SOA var newField = new ParticleField(fieldDesc.FieldSize, IntPtr.Zero); #else var newField = new ParticleField() { Offset = ParticleSize, Size = fieldDesc.FieldSize }; #endif fieldDescriptions.Add(fieldDesc); fields.Add(fieldDesc, newField); ReallocatePool(newParticleSize, ParticleCapacity, ReallocateForFieldAdded); return(fields[fieldDesc]); }
/// <summary> /// Recalculates the fields' offsets and strides. The methods are different for SoA and AoS policies /// </summary> private void RecalculateFieldsArrays() { #if PARTICLES_SOA var fieldOffset = 0; foreach (var desc in fieldDescriptions) { var fieldSize = fields[desc].Size; fields[desc] = new ParticleField(fieldSize, ParticleData + fieldOffset * ParticleCapacity); fieldOffset += fieldSize; } #else var fieldOffset = 0; foreach (var desc in fieldDescriptions) { fields[desc] = new ParticleField() { Offset = fieldOffset, Size = desc.FieldSize }; fieldOffset += desc.FieldSize; } #endif }
/// <summary> /// Removes a particle field from this pool with the specified description, or gets an existing one /// </summary> /// <param name="fieldDesc">Description of the field</param> /// <returns><c>true</c> if the field was successfully removed, <c>false</c> otherwise</returns> public bool RemoveField(ParticleFieldDescription fieldDesc) { // Fields with a stride of 0 are meaningless and cannot be added or removed if (fieldDesc.FieldSize == 0) { return(false); } // Check if the field exists in this particle pool. If it doesn't, obviously it cannot be removed ParticleField existingField; if (!fields.TryGetValue(fieldDesc, out existingField)) { return(false); } var newParticleSize = ParticleSize - fieldDesc.FieldSize; fieldDescriptions.Remove(fieldDesc); #if PARTICLES_SOA fields[fieldDesc] = new ParticleField(0, IntPtr.Zero); #else fields[fieldDesc] = new ParticleField() { Offset = 0, Size = 0 }; #endif // The field is not removed yet. During relocation it will appear as having Size and Offset of 0, and should be ignored for the purpose of copying memory ReallocatePool(newParticleSize, ParticleCapacity, ReallocateForFieldRemoved); fields.Remove(fieldDesc); return(true); }