public static void LocalSpaceOffsetAndRotate() { var shape = ShapeGenerator.CreateShape(ShapeType.Stair); foreach (var face in shape.faces) { AutoUnwrapSettings uv = face.uv; uv.offset += new Vector2(.3f, .5f); uv.rotation = 35f; face.uv = uv; } shape.ToMesh(); shape.Refresh(); TestUtility.AssertMeshAttributesValid(shape.mesh); #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(shape.mesh, shape.name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(shape.name); TestUtility.AssertAreEqual(template, shape.mesh, message: shape.name); UObject.DestroyImmediate(shape.gameObject); }
public void ApplySettings(PBAutoUnwrapSettings settings, MeshSelection selection) { if (selection == null) { return; } if (selection.HasVertices) { selection.VerticesToFaces(false); } else if (selection.HasEdges) { selection.EdgesToFaces(false); } AutoUnwrapSettings unwrapSettings = settings; foreach (KeyValuePair <ProBuilderMesh, IList <Face> > kvp in selection.SelectedFaces) { ProBuilderMesh mesh = kvp.Key; IList <Face> faces = kvp.Value; for (int i = 0; i < faces.Count; ++i) { Face face = faces[i]; face.uv = unwrapSettings; } mesh.RefreshUV(faces); } }
public static void Anchor() { var anchors = Enum.GetValues(typeof(AutoUnwrapSettings.Anchor)); foreach (var anchor in anchors) { var shape = ShapeGenerator.CreateShape(ShapeType.Cylinder); foreach (var face in shape.faces) { AutoUnwrapSettings uv = face.uv; uv.anchor = (AutoUnwrapSettings.Anchor)anchor; face.uv = uv; } shape.ToMesh(); shape.Refresh(); var name = shape.name + "-Anchor(" + anchor + ")"; shape.name = name; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(shape.mesh, name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(name); TestUtility.AssertAreEqual(template, shape.mesh, message: name); UObject.DestroyImmediate(shape.gameObject); } }
public static void ComplicatedSettings() { // Stair includes texture groups and non-grouped faces var shape = ShapeGenerator.CreateShape(ShapeType.Stair); foreach (var face in shape.faces) { AutoUnwrapSettings uv = face.uv; uv.anchor = AutoUnwrapSettings.Anchor.LowerCenter; uv.fill = AutoUnwrapSettings.Fill.Fit; uv.offset = new Vector3(.2f, .2f); uv.rotation = 32f; uv.scale = new Vector2(1.2f, 3f); uv.swapUV = true; uv.useWorldSpace = false; face.uv = uv; } shape.ToMesh(); shape.Refresh(); shape.name += "-SettingGumbo"; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(shape.mesh, shape.name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(shape.name); TestUtility.AssertAreEqual(template, shape.mesh, message: shape.name); UObject.DestroyImmediate(shape.gameObject); }
public void ApplySettings(PBAutoUnwrapSettings settings, MeshSelection selection) { if (selection == null) { return; } selection = selection.ToFaces(false, false); AutoUnwrapSettings unwrapSettings = settings; IList <Face> faces = new List <Face>(); foreach (KeyValuePair <GameObject, IList <int> > kvp in selection.SelectedFaces) { ProBuilderMesh mesh = kvp.Key.GetComponent <ProBuilderMesh>(); faces.Clear(); mesh.GetFaces(kvp.Value, faces); for (int i = 0; i < faces.Count; ++i) { Face face = faces[i]; face.uv = unwrapSettings; } mesh.RefreshUV(faces); mesh.ToMesh(); mesh.Refresh(); } }
private static void ImportMesh(MeshFilter filter, ProBuilderMesh mesh, Vector2 uvScale) { MeshImporter importer = new MeshImporter(mesh); Renderer renderer = mesh.GetComponent <Renderer>(); importer.Import(filter.sharedMesh, renderer.sharedMaterials, m_defaultImportSettings); Dictionary <int, List <Face> > submeshIndexToFace = new Dictionary <int, List <Face> >(); int submeshCount = filter.sharedMesh.subMeshCount; for (int i = 0; i < submeshCount; ++i) { submeshIndexToFace.Add(i, new List <Face>()); } IList <Face> faces = mesh.faces; if (uvScale != Vector2.one) { AutoUnwrapSettings uv = AutoUnwrapSettings.defaultAutoUnwrapSettings; uv.scale = uvScale; for (int i = 0; i < mesh.faceCount; ++i) { Face face = faces[i]; face.uv = uv; submeshIndexToFace[face.submeshIndex].Add(face); } } else { for (int i = 0; i < mesh.faceCount; ++i) { Face face = faces[i]; submeshIndexToFace[face.submeshIndex].Add(face); } } filter.sharedMesh = new Mesh(); mesh.ToMesh(); mesh.Refresh(); Material[] materials = renderer.sharedMaterials; for (int i = 0; i < submeshCount && i < materials.Length; ++i) { List <Face> submeshFaces = submeshIndexToFace[i]; Material material = materials[i]; if (material != null) { mesh.SetMaterial(submeshFaces, material); } } mesh.ToMesh(); mesh.Refresh(); }
public static void SetFillMode_IsAppliedToMesh([ValueSource("fillModeValues")] AutoUnwrapSettings.Fill fill) { var shape = ShapeGenerator.CreateShape(ShapeType.Sprite); Assume.That(shape, Is.Not.Null); try { var positions = shape.positionsInternal; // move it off center so that we can be sure fill/scale doesn't change the offset for (int i = 0; i < shape.vertexCount; i++) { var p = positions[i]; p.x *= .7f; p.z *= .4f; p.x += 1.5f; p.z += 1.3f; positions[i] = p; } foreach (var face in shape.faces) { AutoUnwrapSettings uv = face.uv; uv.fill = (AutoUnwrapSettings.Fill)fill; face.uv = uv; } shape.ToMesh(); shape.Refresh(); var name = shape.name + "-Fill(" + fill + ")"; shape.name = name; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(shape.mesh, name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(name); TestUtility.AssertAreEqual(template, shape.mesh, message: name); } catch (System.Exception e) { Debug.LogError(e.ToString()); } finally { UnityEngine.Object.DestroyImmediate(shape.gameObject); } }
public static void SetOffsetAndRotate_InLocalSpace_IsAppliedToMesh( [ValueSource("offsetRotationShapes")] ShapeType shape, [ValueSource("offsetValues")] Vector2 offset, [ValueSource("rotationValues")] float rotation) { var mesh = ShapeGenerator.CreateShape(shape); Assume.That(mesh, Is.Not.Null); try { foreach (var face in mesh.faces) { AutoUnwrapSettings uv = face.uv; uv.offset += new Vector2(.3f, .5f); uv.rotation = 35f; face.uv = uv; } mesh.ToMesh(); mesh.Refresh(); TestUtility.AssertMeshAttributesValid(mesh.mesh); string templateName = shape.ToString() + "offset: " + offset.ToString() + " rotation: " + rotation; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(mesh.mesh, mesh.name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(mesh.name); TestUtility.AssertAreEqual(template, mesh.mesh, message: mesh.name); } catch (System.Exception e) { Debug.LogError(e.ToString()); } finally { UnityEngine.Object.DestroyImmediate(mesh.gameObject); } }
public static void FillMode() { var fillModes = Enum.GetValues(typeof(AutoUnwrapSettings.Fill)); foreach (var fill in fillModes) { var shape = ShapeGenerator.CreateShape(ShapeType.Sprite); var positions = shape.positionsInternal; // move it off center so that we can be sure fill/scale doesn't change the offset for (int i = 0; i < shape.vertexCount; i++) { var p = positions[i]; p.x *= .7f; p.z *= .4f; p.x += 1.5f; p.z += 1.3f; positions[i] = p; } foreach (var face in shape.faces) { AutoUnwrapSettings uv = face.uv; uv.fill = (AutoUnwrapSettings.Fill)fill; face.uv = uv; } shape.ToMesh(); shape.Refresh(); var name = shape.name + "-Fill(" + fill + ")"; shape.name = name; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(shape.mesh, name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(name); TestUtility.AssertAreEqual(template, shape.mesh, message: name); UObject.DestroyImmediate(shape.gameObject); } }
private static void TextureGroupSelectedFaces(ProBuilderMesh pb)//, pb_Face face) { if (pb.selectedFaceCount < 1) { return; } Face[] faces = pb.GetSelectedFaces(); AutoUnwrapSettings cont_uv = faces[0].uv; int texGroup = pb.GetUnusedTextureGroup(); UndoUtility.RecordSelection(pb, "Create Texture Group" + textureGroup); foreach (Face f in faces) { f.uv = new AutoUnwrapSettings(cont_uv); f.textureGroup = texGroup; } }
private static void SetTextureGroup(ProBuilderMesh[] selection, int tex) { UndoUtility.RecordSelection(selection, "Set Texture Group " + textureGroup); foreach (ProBuilderMesh pb in selection) { if (pb.selectedFaceCount < 1) { continue; } Face[] faces = pb.GetSelectedFaces(); AutoUnwrapSettings cuv = faces[0].uv; foreach (Face f in faces) { f.textureGroup = tex; f.uv = new AutoUnwrapSettings(cuv); } } }
public static void SetAnchor_IsAppliedToMesh([ValueSource("anchorValues")] AutoUnwrapSettings.Anchor anchor) { var mesh = ShapeGenerator.CreateShape(ShapeType.Cube); Assume.That(mesh, Is.Not.Null); try { foreach (var face in mesh.faces) { AutoUnwrapSettings uv = face.uv; uv.anchor = anchor; face.uv = uv; } mesh.ToMesh(); mesh.Refresh(); var name = mesh.name + "-Anchor(" + anchor + ")"; mesh.name = name; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(mesh.mesh, name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(name); TestUtility.AssertAreEqual(template, mesh.mesh, message: name); } catch (System.Exception e) { Debug.LogError(e.ToString()); } finally { UnityEngine.Object.DestroyImmediate(mesh.gameObject); } }
public static void SetWorldSpace_IsAppliedToMesh() { // Stair includes texture groups and non-grouped faces var shape = ShapeGenerator.CreateShape(ShapeType.Stair); foreach (var face in shape.faces) { AutoUnwrapSettings uv = face.uv; uv.useWorldSpace = true; face.uv = uv; } shape.ToMesh(); shape.Refresh(); shape.name += "-UV-World-Space"; #if PB_CREATE_TEST_MESH_TEMPLATES TestUtility.SaveAssetTemplate(shape.mesh, shape.name); #endif Mesh template = TestUtility.GetAssetTemplate <Mesh>(shape.name); TestUtility.AssertAreEqual(template, shape.mesh, message: shape.name); UObject.DestroyImmediate(shape.gameObject); }
/// <summary> /// Insert a face between two edges. /// </summary> /// <param name="mesh">The source mesh.</param> /// <param name="a">First edge.</param> /// <param name="b">Second edge</param> /// <param name="allowNonManifoldGeometry">If true, this function will allow edges to be bridged that create overlapping (non-manifold) faces.</param> /// <returns>The new face, or null of the action failed.</returns> public static Face Bridge(this ProBuilderMesh mesh, Edge a, Edge b, bool allowNonManifoldGeometry = false) { if (mesh == null) { throw new ArgumentNullException("mesh"); } SharedVertex[] sharedVertices = mesh.sharedVerticesInternal; Dictionary <int, int> lookup = mesh.sharedVertexLookup; // Check to see if a face already exists if (!allowNonManifoldGeometry) { if (ElementSelection.GetNeighborFaces(mesh, a).Count > 1 || ElementSelection.GetNeighborFaces(mesh, b).Count > 1) { return(null); } } foreach (Face face in mesh.facesInternal) { if (mesh.IndexOf(face.edgesInternal, a) >= 0 && mesh.IndexOf(face.edgesInternal, b) >= 0) { Log.Warning("Face already exists between these two edges!"); return(null); } } Vector3[] positions = mesh.positionsInternal; bool hasColors = mesh.HasArrays(MeshArrays.Color); Color[] colors = hasColors ? mesh.colorsInternal : null; Vector3[] v; Color[] c; int[] s; AutoUnwrapSettings uvs = AutoUnwrapSettings.tile; int submeshIndex = 0; // Get material and UV stuff from the first edge face SimpleTuple <Face, Edge> faceAndEdge; if (EdgeUtility.ValidateEdge(mesh, a, out faceAndEdge) || EdgeUtility.ValidateEdge(mesh, b, out faceAndEdge)) { uvs = new AutoUnwrapSettings(faceAndEdge.item1.uv); submeshIndex = faceAndEdge.item1.submeshIndex; } // Bridge will form a triangle if (a.Contains(b.a, lookup) || a.Contains(b.b, lookup)) { v = new Vector3[3]; c = new Color[3]; s = new int[3]; bool axbx = Array.IndexOf(sharedVertices[mesh.GetSharedVertexHandle(a.a)].arrayInternal, b.a) > -1; bool axby = Array.IndexOf(sharedVertices[mesh.GetSharedVertexHandle(a.a)].arrayInternal, b.b) > -1; bool aybx = Array.IndexOf(sharedVertices[mesh.GetSharedVertexHandle(a.b)].arrayInternal, b.a) > -1; bool ayby = Array.IndexOf(sharedVertices[mesh.GetSharedVertexHandle(a.b)].arrayInternal, b.b) > -1; if (axbx) { v[0] = positions[a.a]; if (hasColors) { c[0] = colors[a.a]; } s[0] = mesh.GetSharedVertexHandle(a.a); v[1] = positions[a.b]; if (hasColors) { c[1] = colors[a.b]; } s[1] = mesh.GetSharedVertexHandle(a.b); v[2] = positions[b.b]; if (hasColors) { c[2] = colors[b.b]; } s[2] = mesh.GetSharedVertexHandle(b.b); } else if (axby) { v[0] = positions[a.a]; if (hasColors) { c[0] = colors[a.a]; } s[0] = mesh.GetSharedVertexHandle(a.a); v[1] = positions[a.b]; if (hasColors) { c[1] = colors[a.b]; } s[1] = mesh.GetSharedVertexHandle(a.b); v[2] = positions[b.a]; if (hasColors) { c[2] = colors[b.a]; } s[2] = mesh.GetSharedVertexHandle(b.a); } else if (aybx) { v[0] = positions[a.b]; if (hasColors) { c[0] = colors[a.b]; } s[0] = mesh.GetSharedVertexHandle(a.b); v[1] = positions[a.a]; if (hasColors) { c[1] = colors[a.a]; } s[1] = mesh.GetSharedVertexHandle(a.a); v[2] = positions[b.b]; if (hasColors) { c[2] = colors[b.b]; } s[2] = mesh.GetSharedVertexHandle(b.b); } else if (ayby) { v[0] = positions[a.b]; if (hasColors) { c[0] = colors[a.b]; } s[0] = mesh.GetSharedVertexHandle(a.b); v[1] = positions[a.a]; if (hasColors) { c[1] = colors[a.a]; } s[1] = mesh.GetSharedVertexHandle(a.a); v[2] = positions[b.a]; if (hasColors) { c[2] = colors[b.a]; } s[2] = mesh.GetSharedVertexHandle(b.a); } return(mesh.AppendFace( v, hasColors ? c : null, new Vector2[v.Length], new Vector4[v.Length], new Vector4[v.Length], new Face(axbx || axby ? new int[3] { 2, 1, 0 } : new int[3] { 0, 1, 2 }, submeshIndex, uvs, 0, -1, -1, false), s)); } // Else, bridge will form a quad v = new Vector3[4]; c = new Color[4]; s = new int[4]; // shared indexes index to add to v[0] = positions[a.a]; if (hasColors) { c[0] = mesh.colorsInternal[a.a]; } s[0] = mesh.GetSharedVertexHandle(a.a); v[1] = positions[a.b]; if (hasColors) { c[1] = mesh.colorsInternal[a.b]; } s[1] = mesh.GetSharedVertexHandle(a.b); Vector3 nrm = Vector3.Cross(positions[b.a] - positions[a.a], positions[a.b] - positions[a.a]).normalized; Vector2[] planed = Projection.PlanarProject( new Vector3[4] { positions[a.a], positions[a.b], positions[b.a], positions[b.b] }, null, nrm); Vector2 ipoint = Vector2.zero; bool intersects = Math.GetLineSegmentIntersect(planed[0], planed[2], planed[1], planed[3], ref ipoint); if (!intersects) { v[2] = positions[b.a]; if (hasColors) { c[2] = mesh.colorsInternal[b.a]; } s[2] = mesh.GetSharedVertexHandle(b.a); v[3] = positions[b.b]; if (hasColors) { c[3] = mesh.colorsInternal[b.b]; } s[3] = mesh.GetSharedVertexHandle(b.b); } else { v[2] = positions[b.b]; if (hasColors) { c[2] = mesh.colorsInternal[b.b]; } s[2] = mesh.GetSharedVertexHandle(b.b); v[3] = positions[b.a]; if (hasColors) { c[3] = mesh.colorsInternal[b.a]; } s[3] = mesh.GetSharedVertexHandle(b.a); } return(mesh.AppendFace( v, hasColors ? c : null, new Vector2[v.Length], new Vector4[v.Length], new Vector4[v.Length], new Face(new int[6] { 2, 1, 0, 2, 3, 1 }, submeshIndex, uvs, 0, -1, -1, false), s)); }
public PBAutoUnwrapSettings(AutoUnwrapSettings unwrapSettings) { m_settings = unwrapSettings; }
public PBAutoUnwrapSettings() { m_settings = AutoUnwrapSettings.defaultAutoUnwrapSettings; }
public void CopyFrom(PBAutoUnwrapSettings settings) { m_settings = settings.m_settings; }
static void UpdateDiffDictionary(ProBuilderMesh[] selection) { s_AutoUVSettingsInSelection.Clear(); if (selection == null || selection.Length < 1) { return; } s_AutoUVSettingsInSelection = selection.SelectMany(x => x.GetSelectedFaces()).Where(x => !x.manualUV).Select(x => x.uv).ToList(); // Clear values for each iteration foreach (string key in s_AutoUVSettingsDiff.Keys.ToList()) { s_AutoUVSettingsDiff[key] = false; } if (s_AutoUVSettingsInSelection.Count < 1) { return; } s_AutoUVSettings = new AutoUnwrapSettings(s_AutoUVSettingsInSelection[0]); foreach (AutoUnwrapSettings u in s_AutoUVSettingsInSelection) { // if(u.projectionAxis != m_AutoUVSettings.projectionAxis) // m_AutoUVSettingsDiff["projectionAxis"] = true; if (u.useWorldSpace != s_AutoUVSettings.useWorldSpace) { s_AutoUVSettingsDiff["useWorldSpace"] = true; } if (u.flipU != s_AutoUVSettings.flipU) { s_AutoUVSettingsDiff["flipU"] = true; } if (u.flipV != s_AutoUVSettings.flipV) { s_AutoUVSettingsDiff["flipV"] = true; } if (u.swapUV != s_AutoUVSettings.swapUV) { s_AutoUVSettingsDiff["swapUV"] = true; } if (u.fill != s_AutoUVSettings.fill) { s_AutoUVSettingsDiff["fill"] = true; } if (!Math.Approx(u.scale.x, s_AutoUVSettings.scale.x)) { s_AutoUVSettingsDiff["scalex"] = true; } if (!Math.Approx(u.scale.y, s_AutoUVSettings.scale.y)) { s_AutoUVSettingsDiff["scaley"] = true; } if (!Math.Approx(u.offset.x, s_AutoUVSettings.offset.x)) { s_AutoUVSettingsDiff["offsetx"] = true; } if (!Math.Approx(u.offset.y, s_AutoUVSettings.offset.y)) { s_AutoUVSettingsDiff["offsety"] = true; } if (!Math.Approx(u.rotation, s_AutoUVSettings.rotation)) { s_AutoUVSettingsDiff["rotation"] = true; } if (u.anchor != s_AutoUVSettings.anchor) { s_AutoUVSettingsDiff["anchor"] = true; } } foreach (ProBuilderMesh pb in selection) { if (s_AutoUVSettingsDiff["manualUV"] && s_AutoUVSettingsDiff["textureGroup"]) { break; } Face[] selFaces = pb.GetSelectedFaces(); if (!s_AutoUVSettingsDiff["manualUV"]) { s_AutoUVSettingsDiff["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 (!s_AutoUVSettingsDiff["textureGroup"]) { s_AutoUVSettingsDiff["textureGroup"] = texGroups.Count() > 1; } } }