#region Using Statements using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; #endregion // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license namespace ANX.Framework.Content.Pipeline.Graphics { public class BoneWeightCollection : Collection { public BoneWeightCollection() : base(new List()) { } /// /// Normalizes the contents of the bone weights list. /// /// /// Normalization does the following: /// /// Sorts weights such that the most significant weight is first. /// Removes zero-value entries. /// Discards weights with the smallest value until there are maxWeights or less in the list. /// Adjusts values so the sum equals one. /// /// /// Gets thrown if all weights are zero. /// Gets thrown if maxWeights less or equal to zero. public void NormalizeWeights() { this.NormalizeWeights(int.MaxValue); } /// /// Normalizes the contents of the bone weights list. /// /// /// Normalization does the following: /// /// Sorts weights such that the most significant weight is first. /// Removes zero-value entries. /// Discards weights with the smallest value until there are maxWeights or less in the list. /// Adjusts values so the sum equals one. /// /// /// Maximum number of weights allowed. /// Gets thrown if all weights are zero. /// Gets thrown if maxWeights less or equal to zero. public void NormalizeWeights(int maxWeights) { if (maxWeights <= 0) throw new ArgumentOutOfRangeException("maxWeights"); ((List)Items).Sort((left, right) => right.Weight.CompareTo(left.Weight)); float accumulatedValue = 0f; for (int i = 0; i < Count; i++) { var weight = Items[i].Weight; if (weight <= 0f || i >= maxWeights) { this.RemoveAt(i); i--; } else { accumulatedValue += weight; } } if (accumulatedValue == 0f) { throw new InvalidContentException(string.Format("All weights are zero.")); } if (accumulatedValue != 0f) { for (int i = 0; i < Count; i++) { this[i] = new BoneWeight(this[i].BoneName, accumulatedValue / this[i].Weight); } } } } }