/** * \brief Given an array of "donors", this method returns a merged #pb_Object. */ public static bool CombineObjects(pb_Object[] pbs, out pb_Object combined) { combined = null; if (pbs.Length < 1) { return(false); } List <Vector3> v = new List <Vector3>(); List <pb_Face> f = new List <pb_Face>(); List <pb_IntArray> s = new List <pb_IntArray>(); foreach (pb_Object pb in pbs) { int vertexCount = v.Count; // Vertices { v.AddRange(pb.VerticesInWorldSpace()); } // Faces { pb_Face[] faces = new pb_Face[pb.faces.Length]; for (int i = 0; i < faces.Length; i++) { faces[i] = new pb_Face(pb.faces[i]); faces[i].ShiftIndices(vertexCount); faces[i].RebuildCaches(); } f.AddRange(faces); } // Shared Indices { pb_IntArray[] si = pb.GetSharedIndices(); for (int i = 0; i < si.Length; i++) { for (int n = 0; n < si[i].Length; n++) { si[i][n] += vertexCount; } } s.AddRange(si); } } combined = pb_Object.CreateInstanceWithVerticesFacesSharedIndices(v.ToArray(), f.ToArray(), s.ToArray()); combined.CenterPivot(new int[1] { 0 }); return(true); }
/** * If EditorPrefs say to set pivot to corner and ProGrids or PB pref says snap to grid, do it. * @param indicesToCenterPivot If any values are passed here, the pivot is set to an average of all vertices at indices. If null, the first vertex is used as the pivot. */ public static void SetPivotAndSnapWithPref(pb_Object pb, int[] indicesToCenterPivot) { if (pb_Preferences_Internal.GetBool(pb_Constant.pbForceGridPivot)) { pb.CenterPivot(indicesToCenterPivot == null ? new int[1] { 0 } : indicesToCenterPivot); } else { pb.CenterPivot(indicesToCenterPivot == null ? pb.uniqueIndices : indicesToCenterPivot); } if (pbUtil.SharedSnapEnabled) { pb.transform.position = pbUtil.SnapValue(pb.transform.position, pbUtil.SharedSnapValue); } else if (pb_Preferences_Internal.GetBool(pb_Constant.pbForceVertexPivot)) { pb.transform.position = pbUtil.SnapValue(pb.transform.position, 1f); } }
private void SetPreviewObject(pb_Object pb, int[] indicesToCenterPivotOn) { pb.isSelectable = false; initPreview = false; bool prevTransform = false; if (previewObject != null) { prevTransform = true; RegisterPreviewObjectTransform(); } DestroyPreviewObject(); previewObject = pb; previewObject.SetName("Preview"); previewObject.SetFaceMaterial(previewObject.faces, previewMat); if (pb_Preferences_Internal.GetBool(pb_Constant.pbForceGridPivot)) { previewObject.CenterPivot(indicesToCenterPivotOn == null ? new int[1] { 0 } : indicesToCenterPivotOn); } if (prevTransform) { previewObject.transform.position = m_pos; previewObject.transform.rotation = m_rot; previewObject.transform.localScale = m_scale; } else { pb_Editor_Utility.ScreenCenter(previewObject.gameObject); } if (pbUtil.SharedSnapEnabled) { pb.transform.position = pbUtil.SnapValue(pb.transform.position, pbUtil.SharedSnapValue); } else if (pb_Preferences_Internal.GetBool(pb_Constant.pbForceVertexPivot)) { pb.transform.position = pbUtil.SnapValue(pb.transform.position, 1f); } Selection.activeTransform = pb.transform; }
/** * \brief Given an array of "donors", this method returns a merged #pb_Object. */ public static bool CombineObjects(pb_Object[] pbs, out pb_Object combined) { combined = null; if(pbs.Length < 1) return false; List<Vector3> v = new List<Vector3>(); List<pb_Face> f = new List<pb_Face>(); List<pb_IntArray> s = new List<pb_IntArray>(); foreach(pb_Object pb in pbs) { int vertexCount = v.Count; // Vertices { v.AddRange(pb.VerticesInWorldSpace()); } // Faces { pb_Face[] faces = new pb_Face[pb.faces.Length]; for(int i = 0; i < faces.Length; i++) { faces[i] = new pb_Face(pb.faces[i]); faces[i].ShiftIndices(vertexCount); faces[i].RebuildCaches(); } f.AddRange(faces); } // Shared Indices { pb_IntArray[] si = pb.GetSharedIndices(); for(int i = 0; i < si.Length; i++) { for(int n = 0; n < si[i].Length; n++) si[i][n] += vertexCount; } s.AddRange(si); } } combined = pb_Object.CreateInstanceWithVerticesFacesSharedIndices(v.ToArray(), f.ToArray(), s.ToArray()); combined.CenterPivot(new int[1]{0}); return true; }
private void SetPreviewObject(pb_Object pb, int[] indicesToCenterPivotOn) { pb.isSelectable = false; initPreview = false; bool prevTransform = false; if(previewObject != null) { prevTransform = true; RegisterPreviewObjectTransform(); } DestroyPreviewObject(); previewObject = pb; previewObject.SetName("Preview"); previewObject.SetFaceMaterial(previewObject.faces, previewMat); if(pb_Preferences_Internal.GetBool(pb_Constant.pbForceGridPivot)) previewObject.CenterPivot(indicesToCenterPivotOn == null ? new int[1]{0} : indicesToCenterPivotOn); if(prevTransform) { previewObject.transform.position = m_pos; previewObject.transform.rotation = m_rot; previewObject.transform.localScale = m_scale; } else { pb_Editor_Utility.ScreenCenter(previewObject.gameObject); } if(pbUtil.SharedSnapEnabled) pb.transform.position = pbUtil.SnapValue(pb.transform.position, pbUtil.SharedSnapValue); else if(pb_Preferences_Internal.GetBool(pb_Constant.pbForceVertexPivot)) pb.transform.position = pbUtil.SnapValue(pb.transform.position, 1f); Selection.activeTransform = pb.transform; }
private void SetPreviewObject(pb_Object pb, int[] indicesToCenterPivotOn) { pb.isSelectable = false; initPreview = false; bool prevTransform = false; if (previewObject != null) { prevTransform = true; RegisterPreviewObjectTransform(); } DestroyPreviewObject(); previewObject = pb.gameObject; if (pb_Preferences_Internal.GetBool(pb_Constant.pbForceGridPivot)) { pb.CenterPivot(indicesToCenterPivotOn == null ? new int[1] { 0 } : indicesToCenterPivotOn); } if (prevTransform) { previewObject.transform.position = m_pos; previewObject.transform.rotation = m_rot; previewObject.transform.localScale = m_scale; } else { pb_Editor_Utility.ScreenCenter(previewObject.gameObject); } if (pb_ProGrids_Interface.SnapEnabled()) { pb.transform.position = pbUtil.SnapValue(pb.transform.position, pb_ProGrids_Interface.SnapValue()); } else if (pb_Preferences_Internal.GetBool(pb_Constant.pbForceVertexPivot)) { pb.transform.position = pbUtil.SnapValue(pb.transform.position, 1f); } // Remove pb_Object Mesh m = pbUtil.DeepCopyMesh(pb.msh); GameObject.DestroyImmediate(pb.msh); GameObject.DestroyImmediate(pb); if (previewObject.GetComponent <pb_Entity>()) { GameObject.DestroyImmediate(previewObject.GetComponent <pb_Entity>()); } HideFlags flags = HideFlags.DontSave; m.hideFlags = flags; previewMat.hideFlags = flags; previewObject.hideFlags = flags; previewObject.GetComponent <MeshFilter>().sharedMesh = m; previewObject.GetComponent <MeshRenderer>().sharedMaterial = previewMat; Selection.activeTransform = previewObject.transform; }
/** * If EditorPrefs say to set pivot to corner and ProGrids or PB pref says snap to grid, do it. * @param indicesToCenterPivot If any values are passed here, the pivot is set to an average of all vertices at indices. If null, the first vertex is used as the pivot. */ public static void SetPivotAndSnapWithPref(pb_Object pb, int[] indicesToCenterPivot) { if(pb_Preferences_Internal.GetBool(pb_Constant.pbForceGridPivot)) pb.CenterPivot( indicesToCenterPivot == null ? new int[1]{0} : indicesToCenterPivot ); else pb.CenterPivot(indicesToCenterPivot == null ? pb.uniqueIndices : indicesToCenterPivot ); if(pbUtil.SharedSnapEnabled) pb.transform.position = pbUtil.SnapValue(pb.transform.position, pbUtil.SharedSnapValue); else if(pb_Preferences_Internal.GetBool(pb_Constant.pbForceVertexPivot)) pb.transform.position = pbUtil.SnapValue(pb.transform.position, 1f); }
private void SetPreviewObject(pb_Object pb, int[] indicesToCenterPivotOn) { pb.isSelectable = false; initPreview = false; bool prevTransform = false; if(previewObject != null) { prevTransform = true; RegisterPreviewObjectTransform(); } DestroyPreviewObject(); previewObject = pb.gameObject; if(pb_Preferences_Internal.GetBool(pb_Constant.pbForceGridPivot)) pb.CenterPivot(indicesToCenterPivotOn == null ? new int[1]{0} : indicesToCenterPivotOn); if(prevTransform) { previewObject.transform.position = m_pos; previewObject.transform.rotation = m_rot; previewObject.transform.localScale = m_scale; } else { pb_Editor_Utility.ScreenCenter(previewObject.gameObject); } if(pb_ProGrids_Interface.SnapEnabled()) pb.transform.position = pbUtil.SnapValue(pb.transform.position, pb_ProGrids_Interface.SnapValue()); else if(pb_Preferences_Internal.GetBool(pb_Constant.pbForceVertexPivot)) pb.transform.position = pbUtil.SnapValue(pb.transform.position, 1f); // Remove pb_Object Mesh m = pbUtil.DeepCopyMesh( pb.msh ); GameObject.DestroyImmediate(pb.msh); GameObject.DestroyImmediate(pb); if(previewObject.GetComponent<pb_Entity>()) GameObject.DestroyImmediate(previewObject.GetComponent<pb_Entity>()); HideFlags flags = HideFlags.DontSave; m.hideFlags = flags; previewMat.hideFlags = flags; previewObject.hideFlags = flags; previewObject.GetComponent<MeshFilter>().sharedMesh = m; previewObject.GetComponent<MeshRenderer>().sharedMaterial = previewMat; Selection.activeTransform = previewObject.transform; }
/** * \brief Given an array of "donors", this method returns a merged #pb_Object. */ public static bool CombineObjects(pb_Object[] pbs, out pb_Object combined) { combined = null; if(pbs.Length < 1) return false; List<Vector3> v = new List<Vector3>(); List<Vector2> u = new List<Vector2>(); List<Color> c = new List<Color>(); List<pb_Face> f = new List<pb_Face>(); List<pb_IntArray> s = new List<pb_IntArray>(); List<pb_IntArray> suv = new List<pb_IntArray>(); foreach(pb_Object pb in pbs) { int vertexCount = v.Count; // Vertices v.AddRange(pb.VerticesInWorldSpace()); // UVs u.AddRange(pb.uv); // Colors c.AddRange(pb.colors); // Faces pb_Face[] faces = new pb_Face[pb.faces.Length]; for(int i = 0; i < faces.Length; i++) { faces[i] = new pb_Face(pb.faces[i]); faces[i].manualUV = true; faces[i].ShiftIndices(vertexCount); faces[i].RebuildCaches(); } f.AddRange(faces); // Shared Indices pb_IntArray[] si = pb.GetSharedIndices(); for(int i = 0; i < si.Length; i++) { for(int n = 0; n < si[i].Length; n++) si[i][n] += vertexCount; } s.AddRange(si); // Shared Indices UV { pb_IntArray[] si_uv = pb.GetSharedIndicesUV(); for(int i = 0; i < si_uv.Length; i++) { for(int n = 0; n < si_uv[i].Length; n++) si_uv[i][n] += vertexCount; } suv.AddRange(si_uv); } } GameObject go = (GameObject)GameObject.Instantiate(pbs[0].gameObject); go.transform.position = Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; // Destroy the children foreach(Transform t in go.transform) GameObject.DestroyImmediate(t.gameObject); if(go.GetComponent<pb_Object>()) GameObject.DestroyImmediate(go.GetComponent<pb_Object>()); if(go.GetComponent<pb_Entity>()) GameObject.DestroyImmediate(go.GetComponent<pb_Entity>()); combined = go.AddComponent<pb_Object>(); combined.SetVertices(v.ToArray()); combined.SetUV(u.ToArray()); combined.SetColors(c.ToArray()); combined.SetFaces(f.ToArray()); combined.SetSharedIndices( s.ToArray() ?? pb_IntArrayUtility.ExtractSharedIndices(v.ToArray()) ); combined.SetSharedIndicesUV( suv.ToArray() ?? new pb_IntArray[0] {}); combined.ToMesh(); combined.GetComponent<pb_Entity>().SetEntity( pbs[0].GetComponent<pb_Entity>().entityType ); combined.CenterPivot( pbs[0].transform.position ); combined.Refresh(); // refresh donors since deleting the children of the instantiated object could cause them to lose references foreach(pb_Object pb in pbs) pb.Verify(); return true; }
/** * "ProBuilder-ize function" */ public static pb_Object CreatePbObjectWithTransform(Transform t, bool preserveFaces) { Mesh m = t.GetComponent <MeshFilter>().sharedMesh; Vector3[] m_vertices = m.vertices; Color[] m_colors = m.colors ?? new Color[m_vertices.Length]; Vector2[] m_uvs = m.uv; List <Vector3> verts = preserveFaces ? new List <Vector3>(m.vertices) : new List <Vector3>(); List <Color> cols = preserveFaces ? new List <Color>(m.colors) : new List <Color>(); List <Vector2> uvs = preserveFaces ? new List <Vector2>(m.uv) : new List <Vector2>(); List <pb_Face> faces = new List <pb_Face>(); for (int n = 0; n < m.subMeshCount; n++) { int[] tris = m.GetTriangles(n); for (int i = 0; i < tris.Length; i += 3) { int index = -1; if (preserveFaces) { for (int j = 0; j < faces.Count; j++) { if (faces[j].distinctIndices.Contains(tris[i + 0]) || faces[j].distinctIndices.Contains(tris[i + 1]) || faces[j].distinctIndices.Contains(tris[i + 2])) { index = j; break; } } } if (index > -1 && preserveFaces) { int len = faces[index].indices.Length; int[] arr = new int[len + 3]; System.Array.Copy(faces[index].indices, 0, arr, 0, len); arr[len + 0] = tris[i + 0]; arr[len + 1] = tris[i + 1]; arr[len + 2] = tris[i + 2]; faces[index].SetIndices(arr); faces[index].RebuildCaches(); } else { int[] faceTris; if (preserveFaces) { faceTris = new int[3] { tris[i + 0], tris[i + 1], tris[i + 2] }; } else { verts.Add(m_vertices[tris[i + 0]]); verts.Add(m_vertices[tris[i + 1]]); verts.Add(m_vertices[tris[i + 2]]); cols.Add(m_colors != null ? m_colors[tris[i + 0]] : Color.white); cols.Add(m_colors != null ? m_colors[tris[i + 1]] : Color.white); cols.Add(m_colors != null ? m_colors[tris[i + 2]] : Color.white); uvs.Add(m_uvs[tris[i + 0]]); uvs.Add(m_uvs[tris[i + 1]]); uvs.Add(m_uvs[tris[i + 2]]); faceTris = new int[3] { i + 0, i + 1, i + 2 }; } faces.Add( new pb_Face( faceTris, t.GetComponent <MeshRenderer>().sharedMaterials[n], new pb_UV(), 0, // smoothing group -1, // texture group -1, // element group true // manualUV )); } } } GameObject go = (GameObject)GameObject.Instantiate(t.gameObject); go.GetComponent <MeshFilter>().sharedMesh = null; pb_Object pb = go.AddComponent <pb_Object>(); pb.GeometryWithVerticesFaces(verts.ToArray(), faces.ToArray()); pb.SetColors(cols.ToArray()); pb.SetUV(uvs.ToArray()); pb.SetName(t.name); go.transform.position = t.position; go.transform.localRotation = t.localRotation; go.transform.localScale = t.localScale; pb.CenterPivot(null); return(pb); }
/** * \brief Given an array of "donors", this method returns a merged #pb_Object. */ public static bool CombineObjects(pb_Object[] pbs, out pb_Object combined) { combined = null; if (pbs.Length < 1) { return(false); } List <Vector3> v = new List <Vector3>(); List <Vector2> u = new List <Vector2>(); List <Color> c = new List <Color>(); List <pb_Face> f = new List <pb_Face>(); List <pb_IntArray> s = new List <pb_IntArray>(); List <pb_IntArray> suv = new List <pb_IntArray>(); foreach (pb_Object pb in pbs) { int vertexCount = v.Count; // Vertices v.AddRange(pb.VerticesInWorldSpace()); // UVs u.AddRange(pb.uv); // Colors c.AddRange(pb.colors); // Faces pb_Face[] faces = new pb_Face[pb.faces.Length]; for (int i = 0; i < faces.Length; i++) { faces[i] = new pb_Face(pb.faces[i]); faces[i].manualUV = true; faces[i].ShiftIndices(vertexCount); faces[i].RebuildCaches(); } f.AddRange(faces); // Shared Indices pb_IntArray[] si = pb.GetSharedIndices(); for (int i = 0; i < si.Length; i++) { for (int n = 0; n < si[i].Length; n++) { si[i][n] += vertexCount; } } s.AddRange(si); // Shared Indices UV { pb_IntArray[] si_uv = pb.GetSharedIndicesUV(); for (int i = 0; i < si_uv.Length; i++) { for (int n = 0; n < si_uv[i].Length; n++) { si_uv[i][n] += vertexCount; } } suv.AddRange(si_uv); } } GameObject go = (GameObject)GameObject.Instantiate(pbs[0].gameObject); go.transform.position = Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; // Destroy the children foreach (Transform t in go.transform) { GameObject.DestroyImmediate(t.gameObject); } if (go.GetComponent <pb_Object>()) { GameObject.DestroyImmediate(go.GetComponent <pb_Object>()); } if (go.GetComponent <pb_Entity>()) { GameObject.DestroyImmediate(go.GetComponent <pb_Entity>()); } combined = go.AddComponent <pb_Object>(); combined.SetVertices(v.ToArray()); combined.SetUV(u.ToArray()); combined.SetColors(c.ToArray()); combined.SetFaces(f.ToArray()); combined.SetSharedIndices(s.ToArray() ?? pb_IntArrayUtility.ExtractSharedIndices(v.ToArray())); combined.SetSharedIndicesUV(suv.ToArray() ?? new pb_IntArray[0] { }); combined.ToMesh(); combined.GetComponent <pb_Entity>().SetEntity(pbs[0].GetComponent <pb_Entity>().entityType); combined.CenterPivot(pbs[0].transform.position); combined.Refresh(); // refresh donors since deleting the children of the instantiated object could cause them to lose references foreach (pb_Object pb in pbs) { pb.Verify(); } return(true); }