/// <summary> /// Copy constructor. /// </summary> /// <param name="other">The copied SplatSet</param> internal SplatSet(SplatSet other) { int attribCount = other.attributeCount; this.attributeLayout = new AttributeLayout[attribCount]; System.Array.Copy(other.attributeLayout, 0, this.attributeLayout, 0, attribCount); this.channelMap = new Dictionary <MeshChannel, int>(); foreach (var kvp in other.channelMap) { this.channelMap.Add(kvp.Key, kvp.Value); } int channelCount = other.channelMap.Count; this.weightCount = other.weightCount; this.weights = new Vector4[channelCount][]; for (int i = 0; i < channelCount; i++) { if (other.weights[i] != null) { this.weights[i] = new Vector4[weightCount]; System.Array.Copy(other.weights[i], this.weights[i], weightCount); } } }
/// <summary> /// Lerp weights between lhs and rhs for value at the given index. /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <param name="strength"></param> /// <param name="index"></param> internal void LerpWeightOnSingleChannel(SplatSet lhs, SplatWeight rhs, float strength, MeshChannel channel, int index, int baseTexIndex) { if (!channelMap.ContainsKey(channel)) { return; } var channelIndex = channelMap[channel]; for (int i = 0; i < weightCount; i++) { float lerpedValue = Mathf.LerpUnclamped(lhs.weights[channelIndex][i][index], rhs[channel][index], strength); // replace the original value at index with the lerped value var newWeightVector = lhs.weights[channelIndex][i]; newWeightVector[index] = lerpedValue; if (baseTexIndex > -1) { newWeightVector[baseTexIndex] += (lhs.weights[channelIndex][i][index] - newWeightVector[index]); } this.weights[channelIndex][i] = newWeightVector; } }
/// <summary> /// Lerp weights between lhs and rhs /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <param name="strength"></param> internal void LerpWeights(SplatSet lhs, SplatWeight rhs, float strength) { for (int i = 0; i < weightCount; i++) { foreach (var cm in channelMap) { this.weights[cm.Value][i] = Vector4.LerpUnclamped(lhs.weights[cm.Value][i], rhs[cm.Key], strength); } } }
/// <summary> /// Copy values to another SplatSet /// </summary> /// <param name="other">The other SplatSet we want to copy our values to</param> internal void CopyTo(SplatSet other) { if (other.weightCount != weightCount) { Debug.LogError("Copying splat set to mis-matched container length"); return; } for (int i = 0; i < channelMap.Count; i++) { System.Array.Copy(this.weights[i], other.weights[i], weightCount); } }
/// <summary> /// Lerp weights between lhs and rhs for value at the given index. /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <param name="strength"></param> /// <param name="index"></param> internal void LerpWeightOnSingleChannel(SplatSet lhs, SplatWeight rhs, float strength, int index) { for (int i = 0; i < weightCount; i++) { foreach (var cm in channelMap) { float lerpedValue = Mathf.LerpUnclamped(lhs.weights[cm.Value][i][index], rhs[cm.Key][index], strength); // replace the original value at index with the lerped value var newWeightVector = lhs.weights[cm.Value][i]; newWeightVector[index] = lerpedValue; this.weights[cm.Value][i] = newWeightVector; } } }
/// <summary> /// Lerp each attribute value with matching `mask` to `rhs`. /// weights, lhs, and rhs must have matching layout attributes. /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <param name="mask"></param> /// <param name="strength"></param> internal void LerpWeights(SplatSet lhs, SplatSet rhs, int mask, float[] strength) { Dictionary <int, uint> affected = new Dictionary <int, uint>(); foreach (AttributeLayout al in attributeLayout) { int mapIndex = channelMap[al.channel]; if (al.mask == mask) { if (!affected.ContainsKey(mapIndex)) { affected.Add(mapIndex, al.index.ToFlag()); } else { affected[mapIndex] |= al.index.ToFlag(); } } } foreach (var v in affected) { Vector4[] a = lhs.weights[v.Key]; Vector4[] b = rhs.weights[v.Key]; Vector4[] c = weights[v.Key]; for (int i = 0; i < weightCount; i++) { if ((v.Value & 1) != 0) { c[i].x = Mathf.Lerp(a[i].x, b[i].x, strength[i]); } if ((v.Value & 2) != 0) { c[i].y = Mathf.Lerp(a[i].y, b[i].y, strength[i]); } if ((v.Value & 4) != 0) { c[i].z = Mathf.Lerp(a[i].z, b[i].z, strength[i]); } if ((v.Value & 8) != 0) { c[i].w = Mathf.Lerp(a[i].w, b[i].w, strength[i]); } } } }