/////////////////////////////////////////////////////////////////////////// #region [AttributeLerp] /** * Set all attributes in destination vertex to attr[v1] * (1 - t) + attr[v2] * t * Overriding attributes: all in vertex 'destination', none in others. */ public static void AttributeLerp(BMesh mesh, Vertex destination, Vertex v1, Vertex v2, float t) { foreach (var attr in mesh.vertexAttributes) { if (!v1.attributes.ContainsKey(attr.name) || !v2.attributes.ContainsKey(attr.name)) { continue; } switch (attr.type.baseType) { case AttributeBaseType.Float: { var val1 = v1.attributes[attr.name] as FloatAttributeValue; var val2 = v2.attributes[attr.name] as FloatAttributeValue; int n = val1.data.Length; Debug.Assert(val2.data.Length == n); var val = new FloatAttributeValue { data = new float[n] }; for (int i = 0; i < n; ++i) { val.data[i] = Mathf.Lerp(val1.data[i], val2.data[i], t); } destination.attributes[attr.name] = val; break; } case AttributeBaseType.Int: { var val1 = v1.attributes[attr.name] as IntAttributeValue; var val2 = v2.attributes[attr.name] as IntAttributeValue; int n = val1.data.Length; Debug.Assert(val2.data.Length == n); var val = new IntAttributeValue { data = new int[n] }; for (int i = 0; i < n; ++i) { val.data[i] = (int)Mathf.Round(Mathf.Lerp(val1.data[i], val2.data[i], t)); } destination.attributes[attr.name] = val; break; } default: Debug.Assert(false); break; } } }
public static float Distance(IntAttributeValue value1, IntAttributeValue value2) { int n = value1.data.Length; if (n != value2.data.Length) { return(float.PositiveInfinity); } float s = 0; for (int i = 0; i < n; ++i) { float diff = value1.data[i] - value2.data[i]; s += diff * diff; } return(Mathf.Sqrt(s)); }
/** * Measure the euclidean distance between two attributes, which is set * to infinity if they have different types (int or float / dimension) */ public static float Distance(AttributeValue value1, AttributeValue value2) { if (value1 is IntAttributeValue value1AsInt) { if (value2 is IntAttributeValue value2AsInt) { return(IntAttributeValue.Distance(value1AsInt, value2AsInt)); } } if (value1 is FloatAttributeValue value1AsFloat) { if (value2 is FloatAttributeValue value2AsFloat) { return(FloatAttributeValue.Distance(value1AsFloat, value2AsFloat)); } } return(float.PositiveInfinity); }