public override bool OffsetAndTileUV(RaycastHit hit, PlaytimePainter p, ref Vector2 uv) { if (p.IsAtlased()) { uv.x = uv.x % 1; uv.y = uv.y % 1; var m = p.GetMesh(); int vert = m.triangles[hit.triangleIndex * 3]; List <Vector4> v4l = new List <Vector4>(); m.GetUVs(0, v4l); if (v4l.Count > vert) { inAtlasIndex = (int)v4l[vert].z; } atlasRows = Mathf.Max(atlasRows, 1); uv = (GetAtlasedSection() + uv) / (float)atlasRows; return(true); } return(false); }
public void UseMeshAsBrush(PlaytimePainter painter) { GameObject go = painter.gameObject; Transform camTransform = PainterCamera.Inst.transform; var skinny = painter.skinnedMeshRendy; if (skinny != null) { UseSkinMeshAsBrush(go, skinny, painter.selectedSubmesh); } else { UseMeshAsBrush(go, painter.GetMesh(), new List <int> { painter.selectedSubmesh }); } }
public void ConvertToAtlased(PlaytimePainter painter) { #if UNITY_EDITOR if (AtlasedMaterial == null) { AtlasedMaterial = painter.InstantiateMaterial(true); } painter.SetOriginalShaderOnThis(); painter.UpdateOrSetTexTarget(TexTarget.Texture2D); Material mat = painter.GetMaterial(false); List <string> tfields = mat.GetTextures(); int index = 0; List <FieldAtlas> passedFields = new List <FieldAtlas>(); List <Texture2D> passedTextures = new List <Texture2D>(); List <Color> passedColors = new List <Color>(); foreach (var f in fields) { if ((f.enabled) && (f.AtlasCreator != null) && (tfields.Contains(originalTextures[f.originField]))) { string original = originalTextures[f.originField]; Texture tex = mat.GetTexture(original); Texture2D texture = null; if (tex == null) { var note = painter.name + " no " + original + " texture. Using Color."; #if PEGI note.showNotification(); #endif Debug.Log(note); } else { if (tex.GetType() != typeof(Texture2D)) { Debug.Log("Not a Texture 2D: " + original); return; } texture = (Texture2D)tex; } var aTexes = f.AtlasCreator.textures; bool added = false; for (int i = index; i < aTexes.Count; i++) { if ((aTexes[i] == null) || (!aTexes[i].used) || (aTexes[i].texture == texture)) { index = i; passedFields.Add(f); passedTextures.Add(texture); passedColors.Add(f.col); added = true; break; } } if (!added) { Debug.Log("Could not find a place for " + original); return; } } } if (passedFields.Count > 0) { bool firstAtlasing = false; var atlPlug = painter.GetPlugin <TileableAtlasingPainterPlugin>(); if (atlPlug.preAtlasingMaterials == null) { atlPlug.preAtlasingMaterials = painter.GetMaterials(); atlPlug.preAtlasingMesh = painter.GetMesh(); firstAtlasing = true; } var MainField = passedFields[0]; atlPlug.atlasRows = MainField.AtlasCreator.Row; Vector2 tyling = mat.GetTextureScale(originalTextures[MainField.originField]); Vector2 offset = mat.GetTextureOffset(originalTextures[MainField.originField]); for (int i = 0; i < passedFields.Count; i++) {// var f in passedFields){ var f = passedFields[i]; var ac = f.AtlasCreator; ac.textures[index] = new AtlasTextureField(passedTextures[i], passedColors[i]); ac.AddTargets(f, originalTextures[f.originField]); ac.ReconstructAsset(); AtlasedMaterial.SetTexture(f.atlasedField, ac.a_texture); } MeshManager.Inst.EditMesh(painter, true); if (firstAtlasing) { atlPlug.preAtlasingSavedMesh = MeshManager.Inst.edMesh.Encode().ToString(); } painter.selectedMeshProfile = matAtlasProfile; if ((tyling != Vector2.one) || (offset != Vector2.zero)) { MeshManager.Inst.edMesh.TileAndOffsetUVs(offset, tyling, 0); Debug.Log("offsetting " + offset + " tyling " + tyling); } TriangleAtlasTool.Inst.SetAllTrianglesTextureTo(index, 0, painter.selectedSubmesh); MeshManager.Inst.Redraw(); MeshManager.Inst.DisconnectMesh(); AtlasedMaterial.SetFloat(PainterDataAndConfig.atlasedTexturesInARow, atlPlug.atlasRows); painter.Material = AtlasedMaterial; if (firstAtlasing) { var m = painter.GetMesh(); m.name = m.name + "_Atlased_" + index; } //painter.getMaterial(false).SetTextureOffset(1,Vector2.zero); AtlasedMaterial.EnableKeyword(PainterDataAndConfig.UV_ATLASED); } #endif }
public bool MeshOptionsInspect() { var changed = false; if (editedMesh != null && "Mesh ".enter(ref PlaytimePainter._inspectedMeshEditorItems, 2).nl()) { if (_inspectedMeshItems == -1) { #if UNITY_EDITOR "Mesh Name:".edit(70, ref editedMesh.meshName).changes(ref changed); var mesh = target.GetMesh(); var exists = !AssetDatabase.GetAssetPath(mesh).IsNullOrEmpty(); if ((exists ? icon.Save : icon.SaveAsNew) .Click("Save Mesh As {0}".F(GenerateMeshSavePath()), 25).nl()) { target.SaveMesh(); } #endif "Save Undo".toggleIcon(ref Cfg.saveMeshUndos).changes(ref changed); if (Cfg.saveMeshUndos) { icon.Warning.write("Can affect peformance"); } pegi.nl(); } editedMesh.Inspect().nl(ref changed); if ("Center".enter(ref _inspectedMeshItems, 2).nl()) { "Offset Center by:".edit(ref _offset).nl(); if ("Modify".Click().nl()) { foreach (var v in EditedMesh.meshPoints) { v.localPos += _offset; } _offset = -_offset; editedMesh.Dirty = true; } if ("Auto Center".Click().nl()) { var avr = Vector3.zero; foreach (var v in EditedMesh.meshPoints) { avr += v.localPos; } _offset = -avr / EditedMesh.meshPoints.Count; } } /* if ("Mirror by Center".Click()) { * GridNavigator.onGridPos = mgm.target.transform.position; * mgm.UpdateLocalSpaceV3s(); * mgm.editedMesh.MirrorVerticlesAgainsThePlane(mgm.onGridLocal); * } * * if (pegi.Click("Mirror by Plane")) { * mgm.UpdateLocalSpaceV3s(); * mgm.editedMesh.MirrorVerticlesAgainsThePlane(mgm.onGridLocal); * } * pegi.newLine(); * * pegi.edit(ref displace); * pegi.newLine(); * * if (pegi.Click("Cancel")) displace = Vector3.zero; * * if (pegi.Click("Apply")) { * mgm.edMesh.Displace(displace); * mgm.edMesh.dirty = true; * displace = Vector3.zero; * } */ if ("Combining meshes".enter(ref _inspectedMeshItems, 3).nl()) { if (!SelectedForMergePainters.Contains(target)) { if ("Add To Group".Click("Add Mesh to the list of meshes to be merged").nl(ref changed)) { SelectedForMergePainters.Add(target); } if (!SelectedForMergePainters.IsNullOrEmpty()) { if (editedMesh.uv2DistributeRow < 2 && "Enable EV2 Distribution".toggleInt("Each mesh's UV2 will be modified to use a unique portion of a texture.", ref editedMesh.uv2DistributeRow).nl(ref changed)) { editedMesh.uv2DistributeRow = Mathf.Max(2, (int)Mathf.Sqrt(SelectedForMergePainters.Count)); } else { if (editedMesh.uv2DistributeCurrent > 0) { ("All added meshes will be distributed in " + editedMesh.uv2DistributeRow + " by " + editedMesh.uv2DistributeRow + " grid. By cancelling this added" + "meshes will have UVs unchanged and may use the same portion of Texture (sampled with UV2) as other meshes.").writeHint(); if ("Cancel Distribution".Click().nl()) { editedMesh.uv2DistributeRow = 0; } } else { "Row:".edit("Will change UV2 so that every mesh will have it's own portion of a texture.", 25, ref editedMesh.uv2DistributeRow, 2, 16).nl(ref changed); "Start from".edit(ref editedMesh.uv2DistributeCurrent).nl(ref changed); } "Using {0} out of {1} spots".F(editedMesh.uv2DistributeCurrent + SelectedForMergePainters.Count + 1, editedMesh.uv2DistributeRow * editedMesh.uv2DistributeRow).nl(); } } } else { if (SelectedForMergePainters.Count > 1 && "Merge!".Click().nl(ref changed)) { MergeSelected(); } if ("Remove from Merge Group".Click().nl(ref changed)) { SelectedForMergePainters.Remove(target); } } if (SelectedForMergePainters.Count > 1) { "Current merging group:".nl(); for (var i = 0; i < SelectedForMergePainters.Count; i++) { if (!SelectedForMergePainters[i] || icon.Delete.Click(25)) { SelectedForMergePainters.RemoveAt(i); i--; } else { SelectedForMergePainters[i].gameObject.name.nl(); } } } } var mats = target.Materials; if ("Combining Sub Meshes".conditional_enter(mats.Length > 1, ref _inspectedMeshItems, 4).nl()) { "Select which materials should transfer color into vertex color".writeHint(); var subMeshCount = target.GetMesh().subMeshCount; for (var i = 0; i < Mathf.Max(subMeshCount, mats.Length); i++) { var m = mats.TryGet(i); if (!m) { "Null".nl(); } else { var md = m.GetMaterialPainterMeta(); "{0} color to vertex color".F(m.name).toggleIcon(ref md.colorToVertexColorOnMerge, true); if (md.colorToVertexColorOnMerge) { var col = m.color; if (pegi.edit(ref col)) { m.color = col; } } if (i >= subMeshCount) { icon.Warning.write("There are more materials then sub meshes on the mesh"); } } pegi.nl(); } if ("Merge All Submeshes".Click()) { MergeSubMeshes(); } } pegi.nl(); if (!Application.isPlaying && "Debug".foldout(ref _inspectedMeshItems, 10).nl()) { "vertexPointMaterial".write(Grid.vertexPointMaterial); pegi.nl(); "vertexPrefab".edit(ref Grid.vertPrefab).nl(); "Max Vertex Markers ".edit(ref verticesShowMax).nl(); "pointedVertex".edit(ref Grid.pointedVertex.go).nl(); "SelectedVertex".edit(ref Grid.selectedVertex.go).nl(); } } return(changed); }
private void ConvertToAtlased(PlaytimePainter painter) { #if UNITY_EDITOR if (!_atlasedMaterial) { _atlasedMaterial = painter.InstantiateMaterial(true); } painter.SetOriginalShaderOnThis(); painter.UpdateOrSetTexTarget(TexTarget.Texture2D); var mat = painter.Material; var texProperties = mat.MyGetTextureProperties_Editor(); var index = 0; var passedFields = new List <FieldAtlas>(); var passedTextures = new List <Texture2D>(); var passedColors = new List <Color>(); foreach (var f in _fields) { if (f.enabled && f.AtlasCreator != null) { var contains = false; foreach (var p in texProperties) { if (p.NameForDisplayPEGI().Equals(originalTextures[f.originField].NameForDisplayPEGI())) { contains = true; break; } } if (!contains) { continue; } var original = originalTextures[f.originField]; var tex = mat.Get(original); Texture2D texture = null; if (!tex) { var note = painter.name + " no " + original + " texture. Using Color."; pegi.GameView.ShowNotification(note); Debug.Log(note); } else { if (tex.GetType() != typeof(Texture2D)) { Debug.Log("Not a Texture 2D: " + original); return; } texture = (Texture2D)tex; } var aTextures = f.AtlasCreator.textures; var added = false; for (var i = index; i < aTextures.Count; i++) { if ((aTextures[i] == null) || (!aTextures[i].used) || (aTextures[i].texture == texture)) { index = i; passedFields.Add(f); passedTextures.Add(texture); passedColors.Add(f.col); added = true; break; } } if (added) { continue; } Debug.Log("Could not find a place for " + original); return; } } if (passedFields.Count <= 0) { return; } var firstAtlasing = false; var atlPlug = painter.GetModule <TileableAtlasingComponentModule>(); if (atlPlug.preAtlasingMaterials == null) { atlPlug.preAtlasingMaterials = painter.Materials.ToList(); atlPlug.preAtlasingMesh = painter.GetMesh(); firstAtlasing = true; } var mainField = passedFields[0]; atlPlug.atlasRows = mainField.AtlasCreator.Row; var tiling = mat.GetTiling(originalTextures[mainField.originField]); var offset = mat.GetOffset(originalTextures[mainField.originField]); for (var i = 0; i < passedFields.Count; i++) { var f = passedFields[i]; var ac = f.AtlasCreator; ac.textures[index] = new AtlasTextureField(passedTextures[i], passedColors[i]); ac.AddTargets(f, originalTextures[f.originField]); ac.ReconstructAsset(); _atlasedMaterial.SetTexture(f.atlasedField, ac.aTexture); } MeshEditorManager.Inst.EditMesh(painter, true); if (firstAtlasing) { atlPlug.preAtlasingSavedMesh = MeshEditorManager.editedMesh.Encode().ToString(); } painter.selectedMeshProfile = _matAtlasProfile; if (tiling != Vector2.one || offset != Vector2.zero) { MeshEditorManager.editedMesh.TileAndOffsetUVs(offset, tiling, 0); Debug.Log("offsetting " + offset + " tiling " + tiling); } TriangleAtlasTool.Inst.SetAllTrianglesTextureTo(index, 0, painter.selectedSubMesh); MeshEditorManager.Inst.Redraw(); MeshEditorManager.Inst.StopEditingMesh(); _atlasedMaterial.SetFloat(PainterShaderVariables.ATLASED_TEXTURES, atlPlug.atlasRows); painter.Material = _atlasedMaterial; if (firstAtlasing) { var m = painter.GetMesh(); m.name = m.name + "_Atlased_" + index; } _atlasedMaterial.EnableKeyword(PainterShaderVariables.UV_ATLASED); #endif }
public bool PEGI() { bool changed = false; EditableMesh.inspected = edMesh; pegi.newLine(); if (edMesh != null) { if ("Mesh ".foldout(ref inspectMesh).nl()) { changed |= edMesh.Nested_Inspect().nl(); } } pegi.Space(); pegi.newLine(); changed |= target.PreviewShaderToggle_PEGI(); if ((!target.IsOriginalShader) && ("preview".select(45, ref meshSHaderMode.selected, meshSHaderMode.allModes).nl())) { meshSHaderMode.selected.Apply(); } pegi.Space(); pegi.newLine(); var previousTool = MeshTool; if ("tool".select(70, ref Cfg._meshTool, MeshToolBase.AllTools).nl()) { Grid.vertexPointMaterial.SetColor("_Color", MeshTool.VertColor); previousTool.OnDeSelectTool(); MeshTool.OnSelectTool(); } pegi.Space(); pegi.newLine(); "Mesh Name:".edit(70, ref target.meshNameHolder); #if UNITY_EDITOR if (((AssetDatabase.GetAssetPath(target.GetMesh()).Length == 0) || (String.Compare(target.meshNameHolder, target.GetMesh().name) != 0)) && (icon.Save.Click("Save Mesh As {0}".F(target.GenerateMeshSavePath()), 25).nl())) { target.SaveMesh(); } #endif pegi.newLine(); pegi.nl(); MeshTool.PEGI(); pegi.newLine(); if ("Hint".foldout(ref showTooltip).nl()) { pegi.writeHint(MeshTool.Tooltip); } if ("Merge Meshes".foldout(ref showCopyOptions).nl()) { if (!selectedPainters.Contains(target)) { if ("Copy Mesh".Click("Add Mesh to the list of meshes to be merged").nl()) { selectedPainters.Add(target); } if (selectedPainters.Count > 0) { if (edMesh.UV2distributeRow < 2 && "Enable EV2 Distribution".toggleInt("Each mesh's UV2 will be modified to use a unique portion of a texture.", ref edMesh.UV2distributeRow).nl()) { edMesh.UV2distributeRow = Mathf.Max(2, (int)Mathf.Sqrt(selectedPainters.Count)); } else { if (edMesh.UV2distributeCurrent > 0) { ("All added meshes will be distributed in " + edMesh.UV2distributeRow + " by " + edMesh.UV2distributeRow + " grid. By cancelling this added" + "meshes will have UVs unchanged and may use the same portion of Texture (sampled with UV2) as other meshes.").writeHint(); if ("Cancel Distribution".Click().nl()) { edMesh.UV2distributeRow = 0; } } else { "Row:".edit("Will change UV2 so that every mesh will have it's own portion of a texture.", 25, ref edMesh.UV2distributeRow, 2, 16).nl(); "Start from".edit(ref edMesh.UV2distributeCurrent).nl(); } pegi.write("Using " + (edMesh.UV2distributeCurrent + selectedPainters.Count + 1) + " out of " + (edMesh.UV2distributeRow * edMesh.UV2distributeRow).ToString() + " spots"); pegi.newLine(); } "Will Merge with the following:".nl(); for (int i = 0; i < selectedPainters.Count; i++) { if (selectedPainters[i] == null) { selectedPainters.RemoveAt(i); i--; } else { if (icon.Delete.Click(25)) { selectedPainters.RemoveAt(i); i--; } else { selectedPainters[i].gameObject.name.nl(); } } } if ("Merge!".Click().nl()) { foreach (var p in selectedPainters) { edMesh.MergeWith(p); } edMesh.Dirty = true; } } } else { if ("Remove from Copy Selection".Click().nl()) { selectedPainters.Remove(target); } } } pegi.newLine(); Grid.vertexPointMaterial.SetColor("_Color", MeshTool.VertColor); if ((!Application.isPlaying) && ("references".foldout(ref showReferences).nl())) { "vertexPointMaterial".write(Grid.vertexPointMaterial); pegi.newLine(); "vertexPrefab".edit(ref Grid.vertPrefab).nl(); "Max Vert Markers ".edit(ref vertsShowMax).nl(); "pointedVertex".edit(ref Grid.pointedVertex.go).nl(); "SelectedVertex".edit(ref Grid.selectedVertex.go).nl(); } EditableMesh.inspected = null; return(changed); }