public static Vector2[] PlanarMap(Vector3[] verts, pb_UV uvSettings, Vector3?nrm) { Vector2[] uvs = pb_Math.PlanarProject(verts, nrm == null ? pb_Math.Normal(verts[0], verts[1], verts[2]) : (Vector3)nrm); uvs = ApplyUVSettings(uvs, uvSettings); return(uvs); }
// The pb_SerializedMesh constructor is used to deserialize values. public pb_SerializableFace(SerializationInfo info, StreamingContext context) { this.indices = (int[]) info.GetValue( "indices", typeof(int[])); this.distinctIndices = (int[]) info.GetValue( "distinctIndices", typeof(int[])); pb_SerializableEdge[] sedges = (pb_SerializableEdge[]) info.GetValue("edges", typeof(pb_SerializableEdge[])); this.edges = System.Array.ConvertAll(sedges, x => (pb_Edge)x); this.smoothingGroup = (int) info.GetValue( "smoothingGroup", typeof(int)); pb_SerializableUV suv = (pb_SerializableUV) info.GetValue("uv", typeof(pb_SerializableUV)); this.uv = (pb_UV) suv; // this.uv = (pb_UV) info.GetValue( "uv", typeof(pb_SerializableUV)); this.manualUV = (bool) info.GetValue( "manualUV", typeof(bool)); this.elementGroup = (int) info.GetValue( "elementGroup", typeof(int)); this.textureGroup = (int) info.GetValue( "textureGroup", typeof(int)); this.material = pb_UpgradeKitUtils.GetDefaultMaterial(); string matName = (string)info.GetValue("material", typeof(string)); foreach(Material mat in Resources.FindObjectsOfTypeAll(typeof(Material))) { if(mat.name.Equals(matName)) { this.material = mat; break; } } }
public static Vector2[] PlanarMap(Vector3[] verts, pb_UV uvSettings, Vector3? nrm) { Vector2[] uvs = pb_Math.PlanarProject(verts, nrm == null ? pb_Math.Normal(verts[0], verts[1], verts[2]) : (Vector3)nrm); uvs = ApplyUVSettings(uvs, uvSettings); return uvs; }
public static Vector2[] PlanarMap(Vector3[] verts, pb_UV uvSettings, Vector3? nrm) { Vector2[] uvs = PlanarProject(verts, nrm == null ? pb_Math.Normal(verts[0], verts[1], verts[2]) : (Vector3)nrm); if(!uvSettings.useWorldSpace) uvs = ShiftToPositive(uvs); uvs = ApplyUVSettings(uvs, uvSettings); return uvs; }
public pb_Face(int[] i) { SetIndices(i); _uv = new pb_UV(); _mat = pb_Constant.DefaultMaterial; _smoothingGroup = 0; elementGroup = 0; RebuildCaches(); }
// public void SetNudgeValue(float nudge) // { // EditorPrefs.SetFloat("pbNudgeValue", nudge); // NudgeValueX = new Vector2(nudge, 0f); // NudgeValueY = new Vector2(0f, nudge); // } // public float GetNudgeValue() // { // if(EditorPrefs.HasKey("pbNudgeValue")) // return EditorPrefs.GetFloat("pbNudgeValue"); // else // return .25f; // } public void SnapUVSettings(ref pb_UV uvs, float snapValue) { uvs.scale = new Vector2( snapValue * Mathf.Round(uvs.scale.x / snapValue), snapValue * Mathf.Round(uvs.scale.y / snapValue)); uvs.offset = new Vector2( snapValue * Mathf.Round(uvs.offset.x / snapValue), snapValue * Mathf.Round(uvs.offset.y / snapValue)); uvs.rotation = snapValue * Mathf.Round(uvs.rotation / snapValue); }
public pb_Face(int[] i) { SetIndices(i); _uv = new pb_UV(); _mat = pb_Constant.DefaultMaterial; _smoothingGroup = 0; elementGroup = 0; _colors = pbUtil.FilledArray((Color32)Color.white, indices.Length); RebuildCaches(); }
public pb_Face(int[] i, Material m, pb_UV u, int smoothingGroup, int textureGroup, int elementGroup, Color32 c) { this._indices = i; this._uv = u; this._mat = m; this._smoothingGroup = smoothingGroup; this.textureGroup = textureGroup; this.elementGroup = elementGroup; this._colors = pbUtil.FilledArray(c, i.Length); RebuildCaches(); }
public static void InitProjAxisUV() { foreach (pb_Object pb in Resources.FindObjectsOfTypeAll(typeof(pb_Object))) { foreach (pb_Face face in pb.faces) { pb_UV uv = face.uv; uv.projectionAxis = pb_UV.ProjectionAxis.AUTO; } pb.RefreshUV(); } }
public pb_Face(int[] i, Material m, pb_UV u, int smoothingGroup, int textureGroup, int elementGroup, bool manualUV) { this._indices = i; this._uv = u; this._mat = m; this._smoothingGroup = smoothingGroup; this.textureGroup = textureGroup; this.elementGroup = elementGroup; this.manualUV = manualUV; RebuildCaches(); }
public pb_SerializableUV(pb_UV uv) { this.useWorldSpace = uv.useWorldSpace; this.flipU = uv.flipU; this.flipV = uv.flipV; this.swapUV = uv.swapUV; this.fill = uv.fill; this.scale = uv.scale; this.offset = uv.offset; this.rotation = uv.rotation; this.justify = uv.justify; }
public static Vector2[] PlanarMap(Vector3[] verts, pb_UV uvSettings, Vector3?nrm) { Vector2[] uvs = PlanarProject(verts, nrm == null ? pb_Math.Normal(verts[0], verts[1], verts[2]) : (Vector3)nrm); if (!uvSettings.useWorldSpace) { uvs = ShiftToPositive(uvs); } uvs = ApplyUVSettings(uvs, uvSettings); return(uvs); }
public pb_UV(pb_UV uvs) { useWorldSpace = uvs.useWorldSpace; flipU = uvs.flipU; flipV = uvs.flipV; swapUV = uvs.swapUV; fill = uvs.fill; scale = uvs.scale; offset = uvs.offset; rotation = uvs.rotation; justify = uvs.justify; }
public pb_UV(pb_UV uvs) { projectionAxis = uvs.projectionAxis; useWorldSpace = uvs.useWorldSpace; flipU = uvs.flipU; flipV = uvs.flipV; swapUV = uvs.swapUV; fill = uvs.fill; scale = uvs.scale; offset = uvs.offset; rotation = uvs.rotation; justify = uvs.justify; }
public pb_SerializableFace(pb_Face face) { this.indices = face.indices; this.distinctIndices = face.distinctIndices; this.edges = face.edges; this.smoothingGroup = face.smoothingGroup; this.uv = face.uv; this.material = face.material; this.manualUV = false; pb_UpgradeKitUtils.TryGetField(face, "manualUV", ref this.manualUV); this.elementGroup = -1; pb_UpgradeKitUtils.TryGetField(face, "elementGroup", ref this.elementGroup); this.textureGroup = -1; pb_UpgradeKitUtils.TryGetField(face, "textureGroup", ref this.textureGroup); }
/** * Deep copy constructor. */ public pb_Face(pb_Face face) { _indices = new int[face.indices.Length]; System.Array.Copy(face.indices, _indices, face.indices.Length); _uv = new pb_UV(face.uv); _mat = face.material; _smoothingGroup = face.smoothingGroup; textureGroup = face.textureGroup; elementGroup = face.elementGroup; manualUV = face.manualUV; RebuildCaches(); }
public void OnSelectionUpdate(pb_Object[] sel) { uv_selection.Clear(); // Cache all selected UV settings for (int i = 0; i < sel.Length; i++) { foreach (pb_Face q in sel[i].SelectedFaces) { uv_selection.Add(q.uv); } } UpdateDiffDictionary(); if (selection != null && selection.Length > 0) { if (selection[0].SelectedFaces.Length > 0) { uv_gui = selection[0].SelectedFaces[0].uv; currentMat = selection[0].SelectedFaces[0].material; if (queuedMat == null) { queuedMat = currentMat; } } } else { currentMat = null; } selection = sel; if (pb_Editor.instanceIfExists) { SelectedFacesInEditZone = pb_Editor.instanceIfExists.SelectedFacesInEditZone; } if (smoothingEditor) { smoothingEditor.UpdateSelection(selection); } }
/** * \brief Sets the pb_Face uvSettings param to match the passed #pv_UV _uv */ public void SetFaceUV(pb_Face face, pb_UV _uv) { face.SetUV(_uv); if (face.uv.useWorldSpace) { Vector3[] v = new Vector3[face.distinctIndices.Length]; for (int i = 0; i < v.Length; i++) { v[i] = _vertices[face.distinctIndices[i]]; } SetUVs(face, pb_UV_Utility.PlanarMap(v, face.uv)); } else { SetUVs(face, pb_UV_Utility.PlanarMap(face.GetDistinctVertices(_vertices), face.uv)); } }
private void TextureGroupSelectedFaces(pb_Object pb) //, pb_Face face) { if (pb.SelectedFaces.Length < 1) { return; } pb_UV cont_uv = pb.SelectedFaces[0].uv; int texGroup = pb.UnusedTextureGroup(); foreach (pb_Face f in pb.SelectedFaces) { f.SetUV(new pb_UV(cont_uv)); f.textureGroup = texGroup; } pb.RefreshUV(pb.SelectedFaces); SceneView.RepaintAll(); }
/** * Deep copy constructor. */ public pb_Face(pb_Face face) { _indices = new int[face.indices.Length]; System.Array.Copy(face.indices, _indices, face.indices.Length); _uv = new pb_UV(face.uv); _mat = face.material; _smoothingGroup = face.smoothingGroup; textureGroup = face.textureGroup; elementGroup = face.elementGroup; _colors = new Color32[face.colors.Length]; System.Array.Copy(face.colors, _colors, colors.Length); manualUV = face.manualUV; RebuildCaches(); }
private static void TextureGroupSelectedFaces(pb_Object pb) //, pb_Face face) { if (pb.SelectedFaceIndices.Length < 1) { return; } pb_Face[] faces = pb.SelectedFaces; pb_UV cont_uv = faces[0].uv; int texGroup = pb.UnusedTextureGroup(); pbUndo.RecordObject(pb, "Create Texture Group" + textureGroup); foreach (pb_Face f in faces) { f.SetUV(new pb_UV(cont_uv)); f.textureGroup = texGroup; } }
private static void SetTextureGroup(pb_Object[] selection, int tex) { pbUndo.RecordObjects(selection, "Set Texture Group " + textureGroup); foreach (pb_Object pb in selection) { if (pb.SelectedFaceIndices.Length < 1) { continue; } pb_Face[] faces = pb.SelectedFaces; pb_UV cuv = faces[0].uv; foreach (pb_Face f in faces) { f.textureGroup = tex; f.SetUV(new pb_UV(cuv)); } } }
private static Vector2[] JustifyUVs(Vector2[] uvs, pb_UV.Justify j) { Vector2 amt = new Vector2(0f, 0f); switch(j) { case pb_UV.Justify.Left: amt = new Vector2(SmallestVector2(uvs).x, 0f); break; case pb_UV.Justify.Right: amt = new Vector2(LargestVector2(uvs).x - 1f, 0f); break; case pb_UV.Justify.Top: amt = new Vector2(0f, LargestVector2(uvs).y - 1f); break; case pb_UV.Justify.Bottom: amt = new Vector2(0f, SmallestVector2(uvs).y); break; case pb_UV.Justify.Center: amt = pb_Math.Average(uvs) - (new Vector2(.5f, .5f)); break; } for(int i = 0; i < uvs.Length; i++) uvs[i] -= amt; return uvs; }
public void UpdateDiffDictionary() { // Clear values for each iteration foreach (string key in uv_diff.Keys.ToList()) { uv_diff[key] = false; } if (uv_selection.Count < 1) { return; } pb_UV sample = uv_selection[0]; foreach (pb_UV u in uv_selection) { if (u.projectionAxis != sample.projectionAxis) { uv_diff["projectionAxis"] = true; } if (u.useWorldSpace != sample.useWorldSpace) { uv_diff["useWorldSpace"] = true; } if (u.flipU != sample.flipU) { uv_diff["flipU"] = true; } if (u.flipV != sample.flipV) { uv_diff["flipV"] = true; } if (u.swapUV != sample.swapUV) { uv_diff["swapUV"] = true; } if (u.fill != sample.fill) { uv_diff["fill"] = true; } if (u.scale.x != sample.scale.x) { uv_diff["scalex"] = true; } if (u.scale.y != sample.scale.y) { uv_diff["scaley"] = true; } if (u.offset.x != sample.offset.x) { uv_diff["offsetx"] = true; } if (u.offset.y != sample.offset.y) { uv_diff["offsety"] = true; } if (u.rotation != sample.rotation) { uv_diff["rotation"] = true; } if (u.justify != sample.justify) { uv_diff["justify"] = true; } } // Debug.Log(pbUtil.StringWithDictionary<string, bool>(uv_diff)); }
private static Vector2[] ApplyUVSettings(Vector2[] uvs, pb_UV uvSettings) { Vector2 cen = pb_Math.Average(uvs); int len = uvs.Length; switch(uvSettings.fill) { case pb_UV.Fill.Tile: break; case pb_UV.Fill.Normalize: uvs = NormalizeUVs(uvs); break; case pb_UV.Fill.Stretch: uvs = StretchUVs(uvs); break; } if(uvSettings.justify != pb_UV.Justify.None) uvs = JustifyUVs(uvs, uvSettings.justify); // Apply offset last, so that fill and justify don't override it. uvs = OffsetUVs(uvs, -uvSettings.offset); Vector2 cen2 = Vector2.zero; for(int i = 0; i < len; i++) { Vector2 zeroed = uvs[i]-cen; if(uvSettings.useWorldSpace) uvs[i] = new Vector2(uvs[i].x / uvSettings.scale.x, uvs[i].y / uvSettings.scale.y); else uvs[i] = new Vector2(zeroed.x / uvSettings.scale.x, zeroed.y / uvSettings.scale.y) + cen; cen2 += uvs[i]; } cen = cen2/(float)len; for(int i = 0; i < len; i++) uvs[i] = uvs[i].RotateAroundPoint(cen, uvSettings.rotation); for(int i = 0; i < len; i++) { float u = uvs[i].x, v = uvs[i].y; if(uvSettings.flipU) u = -u; if(uvSettings.flipV) v = -v; if(!uvSettings.swapUV) uvs[i] = new Vector2(u, v); else uvs[i] = new Vector2(v, u); } return uvs; }
private static void SetJustify(pb_UV.Justify justify, pb_Object[] sel) { pbUndo.RecordObjects(sel, "Justify UVs"); for(int i = 0; i < sel.Length; i++) { foreach(pb_Face q in sel[i].SelectedFaces) { q.uv.justify = justify; } } }
private static Vector2[] ApplyUVSettings(Vector2[] uvs, pb_UV uvSettings) { int len = uvs.Length; switch (uvSettings.fill) { case pb_UV.Fill.Tile: break; case pb_UV.Fill.Fit: uvs = NormalizeUVs(uvs); break; case pb_UV.Fill.Stretch: uvs = StretchUVs(uvs); break; } // if(uvSettings.justify != pb_UV.Justify.None) // uvs = JustifyUVs(uvs, uvSettings.justify); // Apply transform last, so that fill and justify don't override it. pb_Bounds2D bounds = new pb_Bounds2D(uvs); if (!uvSettings.useWorldSpace) { for (int i = 0; i < uvs.Length; i++) { uvs[i] -= (bounds.center - bounds.extents); } } bounds = new pb_Bounds2D(uvs); for (int i = 0; i < uvs.Length; i++) { uvs[i] = uvs[i].ScaleAroundPoint(bounds.center, uvSettings.scale); uvs[i] = uvs[i].RotateAroundPoint(bounds.center, uvSettings.rotation); } for (int i = 0; i < len; i++) { float u = uvs[i].x, v = uvs[i].y; if (uvSettings.flipU) { u = -u; } if (uvSettings.flipV) { v = -v; } if (!uvSettings.swapUV) { uvs[i] = new Vector2(u, v); } else { uvs[i] = new Vector2(v, u); } } bounds = new pb_Bounds2D(uvs); uvSettings.localPivot = bounds.center; // uvSettings.useWorldSpace ? bounds.center : bounds.extents; uvSettings.localSize = bounds.size; for (int i = 0; i < uvs.Length; i++) { uvs[i] -= uvSettings.offset; } return(uvs); }
/** * Sets the pb_UV list and diff tables. */ static void UpdateDiffDictionary(pb_Object[] selection) { uv_selection.Clear(); if(selection == null || selection.Length < 1) return; uv_selection = selection.SelectMany(x => x.SelectedFaces).Where(x => !x.manualUV).Select(x => x.uv).ToList(); // Clear values for each iteration foreach(string key in uv_diff.Keys.ToList()) uv_diff[key] = false; if(uv_selection.Count < 1) return; uv_gui = new pb_UV(uv_selection[0]); foreach(pb_UV u in uv_selection) { // if(u.projectionAxis != uv_gui.projectionAxis) // uv_diff["projectionAxis"] = true; if(u.useWorldSpace != uv_gui.useWorldSpace) uv_diff["useWorldSpace"] = true; if(u.flipU != uv_gui.flipU) uv_diff["flipU"] = true; if(u.flipV != uv_gui.flipV) uv_diff["flipV"] = true; if(u.swapUV != uv_gui.swapUV) uv_diff["swapUV"] = true; if(u.fill != uv_gui.fill) uv_diff["fill"] = true; if(u.scale.x != uv_gui.scale.x) uv_diff["scalex"] = true; if(u.scale.y != uv_gui.scale.y) uv_diff["scaley"] = true; if(u.offset.x != uv_gui.offset.x) uv_diff["offsetx"] = true; if(u.offset.y != uv_gui.offset.y) uv_diff["offsety"] = true; if(u.rotation != uv_gui.rotation) uv_diff["rotation"] = true; if(u.justify != uv_gui.justify) uv_diff["justify"] = true; } foreach(pb_Object pb in selection) { if(uv_diff["manualUV"] && uv_diff["textureGroup"]) break; pb_Face[] selFaces = pb.SelectedFaces; if(!uv_diff["manualUV"]) uv_diff["manualUV"] = System.Array.Exists(selFaces, x => x.manualUV); List<int> texGroups = selFaces.Select(x => x.textureGroup).Distinct().ToList(); textureGroup = texGroups.FirstOrDefault(x => x > -1); if(!uv_diff["textureGroup"]) uv_diff["textureGroup"] = texGroups.Count() > 1; } }
public static Vector2[] PlanarMap(Vector3[] verts, pb_UV uvSettings) { return(PlanarMap(verts, uvSettings, null)); }
private static void SetFill(pb_UV.Fill fill, pb_Object[] sel) { pbUndo.RecordObjects(sel, "Fill UVs"); for(int i = 0; i < sel.Length; i++) { foreach(pb_Face q in sel[i].SelectedFaces) { q.uv.fill = fill; } } }
public void OnSelectionUpdate(pb_Object[] sel) { uv_selection.Clear(); // Cache all selected UV settings for(int i = 0; i < sel.Length; i++) { foreach(pb_Face q in sel[i].SelectedFaces) { uv_selection.Add(q.uv); } } UpdateDiffDictionary(); if(selection != null && selection.Length > 0) { if(selection[0].SelectedFaces.Length > 0) { uv_gui = selection[0].SelectedFaces[0].uv; currentMat = selection[0].SelectedFaces[0].material; if(queuedMat == null) queuedMat = currentMat; } } else { currentMat = null; } selection = sel; if(pb_Editor.instanceIfExists) SelectedFacesInEditZone = pb_Editor.instanceIfExists.SelectedFacesInEditZone; if(smoothingEditor) smoothingEditor.UpdateSelection(selection); }
private void SetProjectionAxis(pb_UV.ProjectionAxis projectionAxis, pb_Object[] sel) { for(int i = 0; i < sel.Length; i++) { foreach(pb_Face q in sel[i].SelectedFaces) { q.uv.projectionAxis = projectionAxis; } sel[i].RefreshUV( SelectedFacesInEditZone[i] ); } }
private void SetJustify(pb_UV.Justify justify, pb_Object[] sel) { for(int i = 0; i < sel.Length; i++) { foreach(pb_Face q in sel[i].SelectedFaces) { q.uv.justify = justify; } sel[i].RefreshUV( SelectedFacesInEditZone[i] ); } }
public void SetUV(pb_UV u) { _uv = u; }
public static bool Bridge(this pb_Object pb, pb_Edge a, pb_Edge b, bool enforcePerimiterEdgesOnly) { pb_IntArray[] sharedIndices = pb.GetSharedIndices(); // Check to see if a face already exists if (enforcePerimiterEdgesOnly) { if (pbMeshUtils.GetConnectedFaces(pb, a).Count > 1 || pbMeshUtils.GetConnectedFaces(pb, b).Count > 1) { Debug.LogWarning("Both edges are not on perimeter! You may turn off this Bridging restriction in Preferences/ProBuilder/Bridge Perimiter Edges Only"); return(false); } } else { foreach (pb_Face face in pb.faces) { if (face.edges.IndexOf(a, sharedIndices) >= 0 && face.edges.IndexOf(b, sharedIndices) >= 0) { Debug.LogWarning("Face already exists between these two edges!"); return(false); } } } Vector3[] verts = pb.vertices; Vector3[] v; int[] s; pb_UV uvs = new pb_UV(); Color32 color = (Color32)Color.white; Material mat = pb_Constant.DefaultMaterial; // Get material and UV stuff from the first edge face foreach (pb_Face face in pb.faces) { if (face.edges.Contains(a)) { uvs = new pb_UV(face.uv); mat = face.material; color = face.colors[0]; break; } } // Bridge will form a triangle if (a.Contains(b.x, sharedIndices) || a.Contains(b.y, sharedIndices)) { v = new Vector3[3]; s = new int[3]; bool axbx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.x) > -1; bool axby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.y) > -1; bool aybx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.x) > -1; bool ayby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.y) > -1; if (axbx) { v[0] = verts[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if (axby) { v[0] = verts[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.x]; s[2] = sharedIndices.IndexOf(b.x); } else if (aybx) { v[0] = verts[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if (ayby) { v[0] = verts[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.x]; s[2] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, new pb_Face(axbx || axby ? new int[3] { 2, 1, 0 } : new int[3] { 0, 1, 2 }, mat, uvs, 0, -1, -1, color), s); pb.RebuildFaceCaches(); pb.Refresh(); return(true); } // Else, bridge will form a quad v = new Vector3[4]; s = new int[4]; // shared indices index to add to v[0] = verts[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; s[1] = sharedIndices.IndexOf(a.y); Vector3 nrm = Vector3.Cross(verts[b.x] - verts[a.x], verts[a.y] - verts[a.x]).normalized; Vector2[] planed = pb_Math.VerticesTo2DPoints(new Vector3[4] { verts[a.x], verts[a.y], verts[b.x], verts[b.y] }, nrm); Vector2 ipoint = Vector2.zero; bool interescts = pb_Math.GetLineSegmentIntersect(planed[0], planed[2], planed[1], planed[3], ref ipoint); if (!interescts) { v[2] = verts[b.x]; s[2] = sharedIndices.IndexOf(b.x); v[3] = verts[b.y]; s[3] = sharedIndices.IndexOf(b.y); } else { v[2] = verts[b.y]; s[2] = sharedIndices.IndexOf(b.y); v[3] = verts[b.x]; s[3] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, new pb_Face(new int[6] { 2, 1, 0, 2, 3, 1 }, mat, uvs, 0, -1, -1, color), s); pb.RebuildFaceCaches(); return(true); }
private static Vector2[] ApplyUVSettings(Vector2[] uvs, pb_UV uvSettings) { Vector2 cen = pb_Math.Average(uvs); int len = uvs.Length; switch (uvSettings.fill) { case pb_UV.Fill.Tile: break; case pb_UV.Fill.Normalize: uvs = NormalizeUVs(uvs); break; case pb_UV.Fill.Stretch: uvs = StretchUVs(uvs); break; } if (uvSettings.justify != pb_UV.Justify.None) { uvs = JustifyUVs(uvs, uvSettings.justify); } // Apply offset last, so that fill and justify don't override it. uvs = OffsetUVs(uvs, -uvSettings.offset); Vector2 cen2 = Vector2.zero; for (int i = 0; i < len; i++) { Vector2 zeroed = uvs[i] - cen; if (uvSettings.useWorldSpace) { uvs[i] = new Vector2(uvs[i].x / uvSettings.scale.x, uvs[i].y / uvSettings.scale.y); } else { uvs[i] = new Vector2(zeroed.x / uvSettings.scale.x, zeroed.y / uvSettings.scale.y) + cen; } cen2 += uvs[i]; } cen = cen2 / (float)len; for (int i = 0; i < len; i++) { uvs[i] = uvs[i].RotateAroundPoint(cen, uvSettings.rotation); } for (int i = 0; i < len; i++) { float u = uvs[i].x, v = uvs[i].y; if (uvSettings.flipU) { u = -u; } if (uvSettings.flipV) { v = -v; } if (!uvSettings.swapUV) { uvs[i] = new Vector2(u, v); } else { uvs[i] = new Vector2(v, u); } } return(uvs); }
/** * wtf is this */ public static Vector2[] PlanarMap(Vector3[] verts, pb_UV uvSettings) { return PlanarMap(verts, uvSettings, null); }
public static bool Bridge(this pb_Object pb, pb_Edge a, pb_Edge b, bool enforcePerimiterEdgesOnly) { pb_IntArray[] sharedIndices = pb.GetSharedIndices(); Dictionary <int, int> lookup = sharedIndices.ToDictionary(); // Check to see if a face already exists if (enforcePerimiterEdgesOnly) { if (pbMeshUtils.GetNeighborFaces(pb, a).Count > 1 || pbMeshUtils.GetNeighborFaces(pb, b).Count > 1) { return(false); } } foreach (pb_Face face in pb.faces) { if (face.edges.IndexOf(a, lookup) >= 0 && face.edges.IndexOf(b, lookup) >= 0) { Debug.LogWarning("Face already exists between these two edges!"); return(false); } } Vector3[] verts = pb.vertices; Vector3[] v; Color[] c; int[] s; pb_UV uvs = new pb_UV(); Material mat = pb_Constant.DefaultMaterial; // Get material and UV stuff from the first edge face foreach (pb_Face face in pb.faces) { if (face.edges.Contains(a)) { uvs = new pb_UV(face.uv); mat = face.material; break; } } // Bridge will form a triangle if (a.Contains(b.x, sharedIndices) || a.Contains(b.y, sharedIndices)) { v = new Vector3[3]; c = new Color[3]; s = new int[3]; bool axbx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.x) > -1; bool axby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.y) > -1; bool aybx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.x) > -1; bool ayby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.y) > -1; if (axbx) { v[0] = verts[a.x]; c[0] = pb.colors[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; c[1] = pb.colors[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.y]; c[2] = pb.colors[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if (axby) { v[0] = verts[a.x]; c[0] = pb.colors[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; c[1] = pb.colors[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.x]; c[2] = pb.colors[b.x]; s[2] = sharedIndices.IndexOf(b.x); } else if (aybx) { v[0] = verts[a.y]; c[0] = pb.colors[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; c[1] = pb.colors[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.y]; c[2] = pb.colors[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if (ayby) { v[0] = verts[a.y]; c[0] = pb.colors[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; c[1] = pb.colors[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.x]; c[2] = pb.colors[b.x]; s[2] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, c, new Vector2[v.Length], new pb_Face(axbx || axby ? new int[3] { 2, 1, 0 } : new int[3] { 0, 1, 2 }, mat, uvs, 0, -1, -1, false), s); return(true); } // Else, bridge will form a quad v = new Vector3[4]; c = new Color[4]; s = new int[4]; // shared indices index to add to v[0] = verts[a.x]; c[0] = pb.colors[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; c[1] = pb.colors[a.y]; s[1] = sharedIndices.IndexOf(a.y); Vector3 nrm = Vector3.Cross(verts[b.x] - verts[a.x], verts[a.y] - verts[a.x]).normalized; Vector2[] planed = pb_Math.PlanarProject(new Vector3[4] { verts[a.x], verts[a.y], verts[b.x], verts[b.y] }, nrm); Vector2 ipoint = Vector2.zero; bool interescts = pb_Math.GetLineSegmentIntersect(planed[0], planed[2], planed[1], planed[3], ref ipoint); if (!interescts) { v[2] = verts[b.x]; c[2] = pb.colors[b.x]; s[2] = sharedIndices.IndexOf(b.x); v[3] = verts[b.y]; c[3] = pb.colors[b.y]; s[3] = sharedIndices.IndexOf(b.y); } else { v[2] = verts[b.y]; c[2] = pb.colors[b.y]; s[2] = sharedIndices.IndexOf(b.y); v[3] = verts[b.x]; c[3] = pb.colors[b.x]; s[3] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, c, new Vector2[v.Length], new pb_Face(new int[6] { 2, 1, 0, 2, 3, 1 }, mat, uvs, 0, -1, -1, false), s); return(true); }
/** * Sets the pb_UV list and diff tables. */ static void UpdateDiffDictionary(pb_Object[] selection) { uv_selection.Clear(); if (selection == null || selection.Length < 1) { return; } uv_selection = selection.SelectMany(x => x.SelectedFaces).Where(x => !x.manualUV).Select(x => x.uv).ToList(); // Clear values for each iteration foreach (string key in uv_diff.Keys.ToList()) { uv_diff[key] = false; } if (uv_selection.Count < 1) { return; } uv_gui = new pb_UV(uv_selection[0]); foreach (pb_UV u in uv_selection) { // if(u.projectionAxis != uv_gui.projectionAxis) // uv_diff["projectionAxis"] = true; if (u.useWorldSpace != uv_gui.useWorldSpace) { uv_diff["useWorldSpace"] = true; } if (u.flipU != uv_gui.flipU) { uv_diff["flipU"] = true; } if (u.flipV != uv_gui.flipV) { uv_diff["flipV"] = true; } if (u.swapUV != uv_gui.swapUV) { uv_diff["swapUV"] = true; } if (u.fill != uv_gui.fill) { uv_diff["fill"] = true; } if (u.scale.x != uv_gui.scale.x) { uv_diff["scalex"] = true; } if (u.scale.y != uv_gui.scale.y) { uv_diff["scaley"] = true; } if (u.offset.x != uv_gui.offset.x) { uv_diff["offsetx"] = true; } if (u.offset.y != uv_gui.offset.y) { uv_diff["offsety"] = true; } if (u.rotation != uv_gui.rotation) { uv_diff["rotation"] = true; } if (u.justify != uv_gui.justify) { uv_diff["justify"] = true; } } foreach (pb_Object pb in selection) { if (uv_diff["manualUV"] && uv_diff["textureGroup"]) { break; } pb_Face[] selFaces = pb.SelectedFaces; if (!uv_diff["manualUV"]) { uv_diff["manualUV"] = System.Array.Exists(selFaces, x => x.manualUV); } List <int> texGroups = selFaces.Select(x => x.textureGroup).Distinct().ToList(); textureGroup = texGroups.FirstOrDefault(x => x > -1); if (!uv_diff["textureGroup"]) { uv_diff["textureGroup"] = texGroups.Count() > 1; } } }
private static Vector2[] ApplyUVSettings(Vector2[] uvs, pb_UV uvSettings) { int len = uvs.Length; switch(uvSettings.fill) { case pb_UV.Fill.Tile: break; case pb_UV.Fill.Fit: uvs = NormalizeUVs(uvs); break; case pb_UV.Fill.Stretch: uvs = StretchUVs(uvs); break; } // if(uvSettings.justify != pb_UV.Justify.None) // uvs = JustifyUVs(uvs, uvSettings.justify); // Apply transform last, so that fill and justify don't override it. pb_Bounds2D bounds = new pb_Bounds2D(uvs); if(!uvSettings.useWorldSpace) for(int i = 0; i < uvs.Length; i++) uvs[i] -= (bounds.center - bounds.extents); bounds = new pb_Bounds2D(uvs); for(int i = 0; i < uvs.Length; i++) { uvs[i] = uvs[i].ScaleAroundPoint(bounds.center, uvSettings.scale); uvs[i] = uvs[i].RotateAroundPoint(bounds.center, uvSettings.rotation); } for(int i = 0; i < len; i++) { float u = uvs[i].x, v = uvs[i].y; if(uvSettings.flipU) u = -u; if(uvSettings.flipV) v = -v; if(!uvSettings.swapUV) uvs[i] = new Vector2(u, v); else uvs[i] = new Vector2(v, u); } bounds = new pb_Bounds2D(uvs); uvSettings.localPivot = bounds.center;// uvSettings.useWorldSpace ? bounds.center : bounds.extents; uvSettings.localSize = bounds.size; for(int i = 0; i < uvs.Length; i++) uvs[i] -= uvSettings.offset; return uvs; }
public static bool Bridge(this pb_Object pb, pb_Edge a, pb_Edge b, bool enforcePerimiterEdgesOnly) { pb_IntArray[] sharedIndices = pb.GetSharedIndices(); Dictionary<int, int> lookup = sharedIndices.ToDictionary(); // Check to see if a face already exists if(enforcePerimiterEdgesOnly) { if( pbMeshUtils.GetNeighborFaces(pb, a).Count > 1 || pbMeshUtils.GetNeighborFaces(pb, b).Count > 1 ) { return false; } } foreach(pb_Face face in pb.faces) { if(face.edges.IndexOf(a, lookup) >= 0 && face.edges.IndexOf(b, lookup) >= 0) { Debug.LogWarning("Face already exists between these two edges!"); return false; } } Vector3[] verts = pb.vertices; Vector3[] v; Color[] c; int[] s; pb_UV uvs = new pb_UV(); Material mat = pb_Constant.DefaultMaterial; // Get material and UV stuff from the first edge face foreach(pb_Face face in pb.faces) { if(face.edges.Contains(a)) { uvs = new pb_UV(face.uv); mat = face.material; break; } } // Bridge will form a triangle if( a.Contains(b.x, sharedIndices) || a.Contains(b.y, sharedIndices) ) { v = new Vector3[3]; c = new Color[3]; s = new int[3]; bool axbx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.x) > -1; bool axby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.y) > -1; bool aybx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.x) > -1; bool ayby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.y) > -1; if(axbx) { v[0] = verts[a.x]; c[0] = pb.colors[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; c[1] = pb.colors[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.y]; c[2] = pb.colors[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if(axby) { v[0] = verts[a.x]; c[0] = pb.colors[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; c[1] = pb.colors[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.x]; c[2] = pb.colors[b.x]; s[2] = sharedIndices.IndexOf(b.x); } else if(aybx) { v[0] = verts[a.y]; c[0] = pb.colors[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; c[1] = pb.colors[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.y]; c[2] = pb.colors[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if(ayby) { v[0] = verts[a.y]; c[0] = pb.colors[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; c[1] = pb.colors[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.x]; c[2] = pb.colors[b.x]; s[2] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, c, new Vector2[v.Length], new pb_Face( axbx || axby ? new int[3] {2, 1, 0} : new int[3] {0, 1, 2}, mat, uvs, 0, -1, -1, false ), s); return true; } // Else, bridge will form a quad v = new Vector3[4]; c = new Color[4]; s = new int[4]; // shared indices index to add to v[0] = verts[a.x]; c[0] = pb.colors[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; c[1] = pb.colors[a.y]; s[1] = sharedIndices.IndexOf(a.y); Vector3 nrm = Vector3.Cross( verts[b.x]-verts[a.x], verts[a.y]-verts[a.x] ).normalized; Vector2[] planed = pb_Math.PlanarProject( new Vector3[4] {verts[a.x], verts[a.y], verts[b.x], verts[b.y] }, nrm ); Vector2 ipoint = Vector2.zero; bool interescts = pb_Math.GetLineSegmentIntersect(planed[0], planed[2], planed[1], planed[3], ref ipoint); if(!interescts) { v[2] = verts[b.x]; c[2] = pb.colors[b.x]; s[2] = sharedIndices.IndexOf(b.x); v[3] = verts[b.y]; c[3] = pb.colors[b.y]; s[3] = sharedIndices.IndexOf(b.y); } else { v[2] = verts[b.y]; c[2] = pb.colors[b.y]; s[2] = sharedIndices.IndexOf(b.y); v[3] = verts[b.x]; c[3] = pb.colors[b.x]; s[3] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, c, new Vector2[v.Length], new pb_Face( new int[6] {2, 1, 0, 2, 3, 1 }, mat, uvs, 0, -1, -1, false ), s); return true; }
/** * \brief Sets the pb_Face uvSettings param to match the passed #pv_UV _uv */ public void SetFaceUV(pb_Face face, pb_UV uvParams) { face.SetUV(uvParams); if(face.uv.useWorldSpace) { Vector3[] v = new Vector3[face.distinctIndices.Length]; for(int i = 0; i < v.Length; i++) v[i] = _vertices[face.distinctIndices[i]]; SetUVs(face, pb_UVUtility.PlanarMap( v, face.uv) ); } else SetUVs(face, pb_UVUtility.PlanarMap( face.GetDistinctVertices(_vertices), face.uv) ); }
public static bool Bridge(this pb_Object pb, pb_Edge a, pb_Edge b, bool enforcePerimiterEdgesOnly) { pb_IntArray[] sharedIndices = pb.GetSharedIndices(); // Check to see if a face already exists if(enforcePerimiterEdgesOnly) { if( pbMeshUtils.GetConnectedFaces(pb, a).Count > 1 || pbMeshUtils.GetConnectedFaces(pb, b).Count > 1 ) { Debug.LogWarning("Both edges are not on perimeter! You may turn off this Bridging restriction in Preferences/ProBuilder/Bridge Perimiter Edges Only"); return false; } } else { foreach(pb_Face face in pb.faces) { if(face.edges.IndexOf(a, sharedIndices) >= 0 && face.edges.IndexOf(b, sharedIndices) >= 0) { Debug.LogWarning("Face already exists between these two edges!"); return false; } } } Vector3[] verts = pb.vertices; Vector3[] v; int[] s; pb_UV uvs = new pb_UV(); Color32 color = (Color32)Color.white; Material mat = pb_Constant.DefaultMaterial; // Get material and UV stuff from the first edge face foreach(pb_Face face in pb.faces) { if(face.edges.Contains(a)) { uvs = new pb_UV(face.uv); mat = face.material; color = face.colors[0]; break; } } // Bridge will form a triangle if( a.Contains(b.x, sharedIndices) || a.Contains(b.y, sharedIndices) ) { v = new Vector3[3]; s = new int[3]; bool axbx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.x) > -1; bool axby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.x)], b.y) > -1; bool aybx = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.x) > -1; bool ayby = System.Array.IndexOf(sharedIndices[sharedIndices.IndexOf(a.y)], b.y) > -1; if(axbx) { v[0] = verts[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if(axby) { v[0] = verts[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; s[1] = sharedIndices.IndexOf(a.y); v[2] = verts[b.x]; s[2] = sharedIndices.IndexOf(b.x); } else if(aybx) { v[0] = verts[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.y]; s[2] = sharedIndices.IndexOf(b.y); } else if(ayby) { v[0] = verts[a.y]; s[0] = sharedIndices.IndexOf(a.y); v[1] = verts[a.x]; s[1] = sharedIndices.IndexOf(a.x); v[2] = verts[b.x]; s[2] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, new pb_Face( axbx || axby ? new int[3] {2, 1, 0} : new int[3] {0, 1, 2}, mat, uvs, 0, -1, -1, color ), s); pb.RebuildFaceCaches(); pb.Refresh(); return true; } // Else, bridge will form a quad v = new Vector3[4]; s = new int[4]; // shared indices index to add to v[0] = verts[a.x]; s[0] = sharedIndices.IndexOf(a.x); v[1] = verts[a.y]; s[1] = sharedIndices.IndexOf(a.y); Vector3 nrm = Vector3.Cross( verts[b.x]-verts[a.x], verts[a.y]-verts[a.x] ).normalized; Vector2[] planed = pb_Math.VerticesTo2DPoints( new Vector3[4] {verts[a.x], verts[a.y], verts[b.x], verts[b.y] }, nrm ); Vector2 ipoint = Vector2.zero; bool interescts = pb_Math.GetLineSegmentIntersect(planed[0], planed[2], planed[1], planed[3], ref ipoint); if(!interescts) { v[2] = verts[b.x]; s[2] = sharedIndices.IndexOf(b.x); v[3] = verts[b.y]; s[3] = sharedIndices.IndexOf(b.y); } else { v[2] = verts[b.y]; s[2] = sharedIndices.IndexOf(b.y); v[3] = verts[b.x]; s[3] = sharedIndices.IndexOf(b.x); } pb.AppendFace( v, new pb_Face( new int[6] {2, 1, 0, 2, 3, 1 }, mat, uvs, 0, -1, -1, color ), s); pb.RebuildFaceCaches(); return true; }
private void SetFill(pb_UV.Fill fill, pb_Object[] sel) { for(int i = 0; i < sel.Length; i++) { foreach(pb_Face q in sel[i].SelectedFaces) { q.uv.fill = fill; } sel[i].RefreshUV( SelectedFacesInEditZone[i] ); } }