public void WeightedAverage() { //null checks Assert.DoesNotThrow(() => { PolyMath.WeightedAverage(null, null, null); }); Vector3[] vertices = GetVerticesSample(); //create a list of indexes that will be used List <int> indexes = new List <int>() { 1, 2, 3, 4 }; //create a list of weights, size must be equal to the size of the vertices array float[] weights = new float[] { 0, 1, 1, 1, 1, 0 }; //the weights should not affect the result on this test Vector3 average = PolyMath.WeightedAverage(vertices, indexes, weights); Assert.IsTrue(average == new Vector3(0.5f, 0f, 0.5f)); //this time only the third corner of the square should be returned weights = new float[] { 0, 0, 0, 1, 0, 0 }; average = PolyMath.WeightedAverage(vertices, indexes, weights); Assert.IsTrue(average == new Vector3(1f, 0f, 1f)); //trying with weights higher than 1 weights = new float[] { 0, 0, 1, 3, 0, 0 }; average = PolyMath.WeightedAverage(vertices, indexes, weights); Assert.IsTrue(average == new Vector3(0.75f, 0f, 1f)); }
internal override void OnBrushApply(BrushTarget target, BrushSettings settings) { if (!likelyToSupportVertexSculpt) { return; } int rayCount = target.raycastHits.Count; Vector3[] normals = (s_SmoothDirection == PolyDirection.BrushNormal) ? target.editableObject.editMesh.normals : null; Vector3 v, t, avg, dirVec = s_SmoothDirection.value.ToVector3(); Plane plane = new Plane(Vector3.up, Vector3.zero); PolyMesh mesh = target.editableObject.editMesh; int vertexCount = mesh.vertexCount; // don't use target.GetAllWeights because brush normal needs // to know which ray to use for normal for (int ri = 0; ri < rayCount; ri++) { PolyRaycastHit hit = target.raycastHits[ri]; if (hit.weights == null || hit.weights.Length < vertexCount) { continue; } for (int i = 0; i < commonVertexCount; i++) { int index = commonVertices[i][0]; if (hit.weights[index] < .0001f || (s_IgnoreOpenEdges && nonManifoldIndices.Contains(index))) { continue; } v = vertices[index]; if (s_SmoothDirection == PolyDirection.VertexNormal) { avg = PolyMath.Average(vertices, neighborLookup[index]); } else { avg = PolyMath.WeightedAverage(vertices, neighborLookup[index], hit.weights); if (s_SmoothDirection == PolyDirection.BrushNormal) { if (s_UseFirstNormalVector) { dirVec = brushNormalOnBeginApply[ri]; } else { dirVec = PolyMath.WeightedAverage(normals, neighborLookup[index], hit.weights).normalized; } } plane.SetNormalAndPosition(dirVec, avg); avg = v - dirVec * plane.GetDistanceToPoint(v); } t = Vector3.Lerp(v, avg, hit.weights[index]); List <int> indices = commonVertices[i]; Vector3 pos = v + (t - v) * settings.strength * SMOOTH_STRENGTH_MODIFIER; for (int n = 0; n < indices.Count; n++) { vertices[indices[n]] = pos; } } } mesh.vertices = vertices; if (tempComponent != null) { tempComponent.OnVerticesMoved(mesh); } base.OnBrushApply(target, settings); }