/// <summary> /// Translates a set of faces with an offset provided in local (model) coordinates. /// /// This applies the mesh positions to both the <see cref="ProBuilderMesh"/> and the <see cref="UnityEngine.Mesh"/>. /// </summary> /// <param name="mesh">The mesh containing the faces that you want to translate.</param> /// <param name="faces">The set of faces that you want to translate.</param> /// <param name="offset">The offset to apply in local coordinates.</param> public static void TranslateVertices(this ProBuilderMesh mesh, IEnumerable <Face> faces, Vector3 offset) { if (mesh == null) { throw new ArgumentNullException("mesh"); } mesh.GetCoincidentVertices(faces, s_CoincidentVertices); TranslateVerticesInternal(mesh, s_CoincidentVertices, offset); }
/// <summary> /// Translate a set of vertices with a world space offset. /// <br /> /// Unlike most other mesh operations, this function applies the mesh positions to both ProBuilderMesh and the UnityEngine.Mesh. /// </summary> /// <param name="mesh"></param> /// <param name="indexes">A distinct list of vertex indexes.</param> /// <param name="offset">The direction and magnitude to translate selectedTriangles, in world space.</param> /// <param name="snapValue">If > 0 snap each vertex to the nearest on-grid point in world space.</param> /// <param name="snapAxisOnly">If true vertices will only be snapped along the active axis.</param> internal static void TranslateVerticesInWorldSpace(this ProBuilderMesh mesh, int[] indexes, Vector3 offset, float snapValue, bool snapAxisOnly) { if (mesh == null) { throw new ArgumentNullException("mesh"); } int i = 0; mesh.GetCoincidentVertices(indexes, s_CoincidentVertices); Matrix4x4 w2l = mesh.transform.worldToLocalMatrix; Vector3 localOffset = w2l * offset; Vector3[] verts = mesh.positionsInternal; // Snaps to world grid if (Mathf.Abs(snapValue) > Mathf.Epsilon) { Matrix4x4 l2w = mesh.transform.localToWorldMatrix; var mask = snapAxisOnly ? new Vector3Mask(offset, Math.handleEpsilon) : Vector3Mask.XYZ; for (i = 0; i < s_CoincidentVertices.Count; i++) { var v = l2w.MultiplyPoint3x4(verts[s_CoincidentVertices[i]] + localOffset); verts[s_CoincidentVertices[i]] = w2l.MultiplyPoint3x4(ProBuilderSnapping.Snap(v, ((Vector3)mask) * snapValue)); } } else { for (i = 0; i < s_CoincidentVertices.Count; i++) { verts[s_CoincidentVertices[i]] += localOffset; } } // don't bother calling a full ToMesh() here because we know for certain that the vertices and msh.vertices arrays are equal in length mesh.positionsInternal = verts; mesh.mesh.vertices = verts; }