public MeshesState(Transform PivotPoint, EditableMesh[] meshes) { EditableMeshes = meshes; Vertices = new Vector3[meshes.Length][]; UV = new Vector2[meshes.Length][]; Normals = new Vector3[meshes.Length][]; Triangles = new int[meshes.Length][]; Descriptors = new Tuple <uint, uint> [meshes.Length][]; for (int i = 0; i < EditableMeshes.Length; ++i) { EditableMesh editableMesh = EditableMeshes[i]; Vertices[i] = editableMesh.Mesh.vertices; UV[i] = editableMesh.Mesh.uv; Normals[i] = editableMesh.Mesh.normals; Triangles[i] = editableMesh.Mesh.triangles; Mesh mesh = editableMesh.Mesh; Descriptors[i] = new Tuple <uint, uint> [mesh.subMeshCount]; for (int s = 0; s < mesh.subMeshCount; ++s) { Descriptors[i][s] = new Tuple <uint, uint>(mesh.GetIndexStart(s), mesh.GetIndexCount(s)); } } this.PivotPoint = PivotPoint; PivotPointPosition = PivotPoint.position; PivotPointRotation = PivotPoint.rotation; PivotPointScale = PivotPoint.localScale; }
public void Apply() { for (int i = 0; i < EditableMeshes.Length; ++i) { EditableMesh editableMesh = EditableMeshes[i]; Mesh mesh = editableMesh.Mesh; int submeshCount = mesh.subMeshCount; mesh.Clear(); mesh.subMeshCount = submeshCount; mesh.vertices = Vertices[i]; mesh.uv = UV[i]; mesh.normals = Normals[i]; mesh = editableMesh.Mesh; for (int s = 0; s < mesh.subMeshCount; ++s) { var desc = mesh.GetSubMesh(s); mesh.SetTriangles(Triangles[i], (int)Descriptors[i][s].Item1, (int)Descriptors[i][s].Item2, s); } } PivotPoint.position = PivotPointPosition; PivotPoint.rotation = PivotPointRotation; PivotPoint.localScale = PivotPointScale; }
private void OnEndDrag(BaseHandle handle) { handle.EnableUndo = m_wasUndoEnabled; SetFaceSelectionVisibility(true); EditableMesh editableMesh = m_editableMeshes.Where(m => m != null).LastOrDefault(); if (editableMesh != null) { m_pivotPoint.transform.position = editableMesh.transform.TransformPoint((m_lastFace.Position)); m_pivotPoint.transform.localScale = Vector3.one; GetTNBBasis(); m_initialRotation = Quaternion.LookRotation( editableMesh.transform.TransformDirection(m_tbn.Normal), editableMesh.transform.TransformDirection(m_tbn.Tangent)); m_pivotPoint.transform.rotation = m_initialRotation; MeshesState prevState = m_prevState; MeshesState newState = new MeshesState(m_pivotPoint.transform, m_editableMeshes.ToArray()); m_editor.Undo.CreateRecord(redoRecord => { newState.Apply(); return(true); }, undoRecord => { prevState.Apply(); return(true); }); } m_faces = null; }
private void OnBeginDrag(BaseHandle handle) { m_wasUndoEnabled = handle.EnableUndo; handle.EnableUndo = false; m_prevState = new MeshesState(m_pivotPoint.transform, m_editableMeshes.ToArray()); SetFaceSelectionVisibility(false); if (m_lastFace != null) { GetTNBBasis(); m_uvPosition = m_objToTBN.MultiplyPoint3x4(m_lastFace.Position); EditableMesh lastMesh = LastMesh; if (lastMesh != null) { Vector3 s = lastMesh.transform.InverseTransformVector(m_pivotPoint.transform.TransformVector(m_pivotPoint.transform.localScale)); m_uvScale = m_objToTBN.MultiplyVector(s); } for (int i = 0; i < m_editableMeshes.Count; ++i) { EditableMesh editableMesh = m_editableMeshes[i]; editableMesh.Separate(editableMesh.SelectedFaces); } m_faces = m_editableMeshes.ToDictionary(k => k, v => v.SelectedFaces.Select(f => new Tuple <Face, Face>(f, new Face(f))).ToArray()); } }
private void OnEditorSelectionChanged(UnityEngine.Object[] unselectedObjects) { if (!m_editor.Selection.IsSelected(m_pivotPoint)) { for (int i = 0; i < m_editableMeshes.Count; ++i) { EditableMesh editableMesh = m_editableMeshes[i]; editableMesh.SelectedFaces = null; } } }
private void SetFaceSelectionVisibility(bool isSelectionVisible) { for (int i = 0; i < m_editableMeshes.Count; ++i) { EditableMesh editableMesh = m_editableMeshes[i]; if (editableMesh != null) { editableMesh.IsSelectionVisible = isSelectionVisible; } } }
protected virtual void LateUpdate() { if (m_scene == null) { return; } if (m_scene.PositionHandle.IsDragging) { EditableMesh lastMesh = LastMesh; if (lastMesh == null) { return; } Vector3 uv = m_objToTBN.MultiplyPoint3x4(lastMesh.transform.InverseTransformPoint(m_pivotPoint.transform.position)); Vector2 deltaUv = m_uvPosition - uv; foreach (var kvp in m_faces) { EditableMesh editableMesh = kvp.Key; if (editableMesh == null) { continue; } foreach (var tuple in kvp.Value) { Face face = tuple.Item1; Face original = tuple.Item2; face.UV0 = original.UV0 + deltaUv; face.UV1 = original.UV1 + deltaUv; face.UV2 = original.UV2 + deltaUv; } editableMesh.RefreshUVs(editableMesh.SelectedFaces); } } else if (m_scene.RotationHandle.IsDragging) { EditableMesh lastMesh = LastMesh; if (lastMesh == null) { return; } foreach (var kvp in m_faces) { EditableMesh editableMesh = kvp.Key; if (editableMesh == null) { continue; } Quaternion tbnRotation = Quaternion.Inverse(QuaternionFromMatrix(editableMesh.transform.worldToLocalMatrix * m_objToTBN)); Quaternion initialRotation = tbnRotation * m_initialRotation; Quaternion rotation = tbnRotation * m_pivotPoint.transform.rotation; Quaternion delta = Quaternion.Inverse(initialRotation) * rotation; foreach (var tuple in kvp.Value) { Face face = tuple.Item1; Face original = tuple.Item2; Vector2 uvPos = (original.UV0 + original.UV1 + original.UV2) / 3; float mag0 = (original.UV0 - uvPos).magnitude; float mag1 = (original.UV1 - uvPos).magnitude; float mag2 = (original.UV2 - uvPos).magnitude; face.UV0 = uvPos + (Vector2)(delta * (original.UV0 - uvPos)).normalized * mag0; face.UV1 = uvPos + (Vector2)(delta * (original.UV1 - uvPos)).normalized * mag1; face.UV2 = uvPos + (Vector2)(delta * (original.UV2 - uvPos)).normalized * mag2; } editableMesh.RefreshUVs(editableMesh.SelectedFaces); } } else if (m_scene.ScaleHandle.IsDragging) { EditableMesh lastMesh = LastMesh; if (lastMesh == null) { return; } Vector3 s = lastMesh.transform.InverseTransformVector(m_pivotPoint.transform.TransformVector(m_pivotPoint.transform.localScale)); Vector3 uvScale = m_objToTBN.MultiplyVector(s); Vector2 scale = new Vector2(m_uvScale.x / uvScale.x, m_uvScale.y / uvScale.y); foreach (var kvp in m_faces) { EditableMesh editableMesh = kvp.Key; if (editableMesh == null) { continue; } foreach (var tuple in kvp.Value) { Face face = tuple.Item1; Face original = tuple.Item2; Vector2 uvPos = (original.UV0 + original.UV1 + original.UV2) / 3; face.UV0 = uvPos + Vector2.Scale((original.UV0 - uvPos), scale); face.UV1 = uvPos + Vector2.Scale((original.UV1 - uvPos), scale); face.UV2 = uvPos + Vector2.Scale((original.UV2 - uvPos), scale); } editableMesh.RefreshUVs(editableMesh.SelectedFaces); } } else { bool select = m_input.GetPointerDown(0); bool multi = m_input.GetKey(KeyCode.LeftShift); if (select) { SelectionState prevState = new SelectionState(this); if (!multi) { for (int i = 0; i < m_editableMeshes.Count; ++i) { EditableMesh editableMesh = m_editableMeshes[i]; editableMesh.UnselectFaces(); } m_editableMeshes.Clear(); } Ray ray = m_scene.Window.Pointer; RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction).OrderBy(d => d.distance).ToArray(); for (int i = 0; i < hits.Length; ++i) { RaycastHit hit = hits[i]; EditableMesh editableMesh = hit.collider.GetComponent <EditableMesh>(); if (editableMesh != null) { if (editableMesh.SelectFace(m_scene.Window.Pointer, out m_lastFace)) { m_pivotPoint.transform.position = editableMesh.transform.TransformPoint((m_lastFace.Position)); GetTNBBasis(); m_initialRotation = Quaternion.LookRotation( editableMesh.transform.TransformDirection(m_tbn.Normal), editableMesh.transform.TransformDirection(m_tbn.Tangent)); m_pivotPoint.transform.rotation = m_initialRotation; m_scene.Selection.Select(m_pivotPoint, new[] { m_pivotPoint }); if (!m_editableMeshes.Contains(editableMesh)) { m_editableMeshes.Add(editableMesh); } else { m_editableMeshes.Remove(editableMesh); m_editableMeshes.Add(editableMesh); } RecordSelection(prevState); break; } } } if (m_editableMeshes.Count == 0 && m_editor.Selection.activeGameObject == m_pivotPoint) { m_editor.Selection.Select(null, null); RecordSelection(prevState); } } } }