private void CreateScreenShot() { string path = Util.FixPath(EditorUtility.SaveFilePanel("Select Export Path", "Assets", Util.GetNameWithoutExtension(VoxelFilePath) + "_screenShot", "png")); if (!string.IsNullOrEmpty(path)) { path = Util.FixedRelativePath(path); if (!string.IsNullOrEmpty(path)) { bool oldShow = ShowBackgroundBox; CubeTF.gameObject.SetActive(false); SetBoxBackgroundActive(false); var texture = Util.RenderTextureToTexture2D(Camera); if (texture) { texture = Util.TrimTexture(texture, 0.01f, 12); Util.ByteToFile(texture.EncodeToPNG(), path); VoxelPostprocessor.AddScreenshot(path); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; } CubeTF.gameObject.SetActive(true); SetBoxBackgroundActive(oldShow); } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } }
private void CreateSprite(Core_Sprite.SpriteType type) { if (!Data) { return; } string path = Util.FixPath(EditorUtility.SaveFilePanel("Select Export Path", "Assets", Util.GetNameWithoutExtension(VoxelFilePath) + type.ToString(), "png")); if (!string.IsNullOrEmpty(path)) { path = Util.FixedRelativePath(path); if (!string.IsNullOrEmpty(path)) { bool oldShow = ShowBackgroundBox; CubeTF.gameObject.SetActive(false); SetBoxBackgroundActive(false); var result = Core_Sprite.CreateSprite( Data, CurrentModelIndex, type, GetSpriteNum(type), GetSpriteLight(type), GetSpritePivot(type), Camera, Sprite25DCameraScale ); CubeTF.gameObject.SetActive(true); SetBoxBackgroundActive(oldShow); if (result.Texture) { Util.ByteToFile(result.Texture.EncodeToPNG(), path); VoxelPostprocessor.AddSprite(path, new VoxelPostprocessor.SpriteConfig() { width = result.Width, height = result.Height, Pivots = result.Pivots, spriteRects = result.Rects, Names = result.NameFixes, }); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; } } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } }
private static bool BrowseExportPath() { string newPath = Util.FixPath(EditorUtility.OpenFolderPanel("Select Export Path", ExportPath, "")); if (!string.IsNullOrEmpty(newPath)) { newPath = Util.FixedRelativePath(newPath); if (!string.IsNullOrEmpty(newPath)) { ExportPath.Value = newPath; return(true); } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } return(false); }
// Data #endregion #region --- TSK --- private void CreateSprite(bool _8bit) { if (!Data) { return; } string path = Util.FixPath(EditorUtility.SaveFilePanel("Select Export Path", "Assets", Util.GetNameWithoutExtension(VoxelFilePath) + (_8bit ? "_8bit" : "_2D"), "png")); if (!string.IsNullOrEmpty(path)) { path = Util.FixedRelativePath(path); if (!string.IsNullOrEmpty(path)) { var result = _8bit ? EditorSpriteCore.Create8bitSprite(Data, CurrentModelIndex) : EditorSpriteCore.Create2DSprite(Data, CurrentModelIndex); if (result.Texture) { Util.ByteToFile(result.Texture.EncodeToPNG(), path); VoxelPostprocessor.AddSprite(path, new VoxelPostprocessor.SpriteConfig() { width = result.Width, height = result.Height, Pivots = result.Pivots, spriteRects = result.Rects, Names = result.NameFixes, }); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); EditorApplication.delayCall += VoxelPostprocessor.ClearAsset; } } else { Util.Dialog("Warning", "Export path must in Assets folder.", "OK"); } } }
private void CombinerGUI() { const int ITEM_SIZE = 72; const int ITEM_GAP = 4; const int CONTENT_WIDTH = 536; const int COUNT_X = (CONTENT_WIDTH - ITEM_GAP) / (ITEM_SIZE + ITEM_GAP); // Prefabs LayoutH(() => { // Content LayoutV(() => { Space(8); var style = new GUIStyle() { fixedWidth = ITEM_SIZE, }; int currentIndex = 0; while (currentIndex < CombineList.Count) { LayoutH(() => { Space(ITEM_GAP); for (int x = 0; x < COUNT_X && currentIndex < CombineList.Count; x++) { bool continueFlag = false; // Item LayoutV(() => { var prefab = CombineList[currentIndex]; if (prefab.Prefab) { // Preview var rect = GUIRect(ITEM_SIZE, ITEM_SIZE); var preview = prefab.Preview ?? (prefab.Preview = AssetPreview.GetAssetPreview(prefab.Prefab.gameObject)); GUI.DrawTexture(rect, preview ?? Texture2D.whiteTexture, ScaleMode.ScaleToFit); // Name GUI.Label(GUIRect(ITEM_SIZE, 18), prefab.Prefab.name); // Highlight if (currentIndex == SelectingPrefabIndex) { var oldColor = GUI.color; GUI.color = Color.green; GUI.Box(rect, GUIContent.none); GUI.color = oldColor; } // Click if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)) { SelectingPrefabIndex = currentIndex; Event.current.Use(); } currentIndex++; } else { CombineList.RemoveAt(currentIndex); currentIndex--; continueFlag = true; } }, false, style); Space(ITEM_GAP); if (continueFlag) { continue; } } }); Space(ITEM_GAP); } if (CombineList.Count == 0) { Space(4); LayoutH(() => { GUIRect(12, 36); EditorGUI.HelpBox(GUIRect(420, 36), "No prefab in list.\nClick \"+ Prefab\" button or drag prefab into this window to add prefab.", MessageType.Info); }); Space(4); } Space(4); // Add Button var _rect = GUIRect(82, 24); _rect.x = 0; if (GUI.Button(_rect, "+ Prefab", EditorStyles.miniButtonRight)) { AddCombinePrefab( Util.FixedRelativePath(EditorUtility.OpenFilePanel("Pick Prefab", "Assets", "prefab")) ); } // Clear Button Space(2); _rect = GUIRect(82, 24); _rect.x = 0; if (GUI.Button(_rect, "Clear", EditorStyles.miniButtonRight)) { if (Util.Dialog("", "Remove all prefabs in the list?", "Remove All", "Cancel")) { ClearScene(); CombineList.Clear(); SelectingPrefabIndex = -1; Repaint(); } } Space(8); }, false, new GUIStyle() { fixedWidth = CONTENT_WIDTH, }); // Panel if (SelectingPrefabIndex >= 0 && SelectingPrefabIndex < CombineList.Count) { LayoutV(() => { var prefab = CombineList[SelectingPrefabIndex]; if (prefab.Prefab) { // Name GUI.Label(GUIRect(0, 18), SelectingPrefabIndex + ", " + prefab.Prefab.name); Space(6); // Transform LayoutH(() => { GUI.Label(GUIRect(67, 18), "Position"); prefab.Object.localPosition = EditorGUI.Vector3Field(GUIRect(0, 18), "", prefab.Object.localPosition); }); LayoutH(() => { GUI.Label(GUIRect(67, 18), "Rotation"); prefab.Rotation = EditorGUI.Vector3Field(GUIRect(0, 18), "", prefab.Rotation); prefab.Object.localRotation = Quaternion.Euler(prefab.Rotation); }); LayoutH(() => { GUI.Label(GUIRect(67, 18), "Scale"); prefab.Object.localScale = EditorGUI.Vector3Field(GUIRect(0, 18), "", prefab.Object.localScale); }); Space(8); // Delete Button LayoutH(() => { GUIRect(0, 1); if (GUI.Button(GUIRect(72, 18), "Remove") && Util.Dialog("", "Remove prefab" + prefab.Prefab.name + " from list?", "Remove", "Cancel")) { if (prefab.Object) { DestroyImmediate(prefab.Object.gameObject, false); } CombineList.RemoveAt(SelectingPrefabIndex); SelectingPrefabIndex = CombineList.Count == 0 ? -1 : Mathf.Clamp(SelectingPrefabIndex, 0, CombineList.Count - 1); Repaint(); } }); Space(8); } }, true); } else { LayoutV(() => { GUIRect(0, 1); }); } }); }
private static Color[][] GetColorss( Voxel[,,] voxels, Color[] palette, Vector3 mainPivot, int spriteNum, float lightIntensity, out int[] widths, out int[] heights, out Vector2[] pivots ) { int voxelSizeX = voxels.GetLength(0); int voxelSizeY = voxels.GetLength(1); int voxelSizeZ = voxels.GetLength(2); widths = new int[spriteNum]; heights = new int[spriteNum]; pivots = new Vector2[spriteNum]; if (voxelSizeX * voxelSizeY * voxelSizeZ > MAX_ROOM_NUM) { if (!Util.Dialog( "Warning", "Model Is Too Large !\nIt may takes very long time to create this sprite.\nAre you sure to do that?", "Just Go ahead!", "Cancel" )) { return(null); } } Color[][] colorss = new Color[spriteNum][]; Vector3 pivotOffset = new Vector3( voxelSizeX * mainPivot.x, voxelSizeZ * mainPivot.y, voxelSizeY * mainPivot.z ); for (int index = 0; index < spriteNum; index++) { float angleY = SPRITE_ANGLE_SIMPLE[index]; Quaternion cameraRot = Quaternion.Inverse(Quaternion.Euler(CAMERA_ANGLE, angleY, 0f)); Vector3 minPos; Vector3 maxPos; // Get faces List <VoxelFace> faces = GetFaces( voxels, palette, new Vector3(voxelSizeX, voxelSizeY, voxelSizeZ), mainPivot, cameraRot, pivotOffset, index, lightIntensity, out minPos, out maxPos ); // Get Pivot01 Vector3 pivot = new Vector3( Mathf.LerpUnclamped(0f, voxelSizeX, mainPivot.x), Mathf.LerpUnclamped(0f, voxelSizeZ, mainPivot.y), Mathf.LerpUnclamped(0f, voxelSizeY, mainPivot.z) ); pivot = cameraRot * new Vector3( pivot.x - voxelSizeX * mainPivot.x, pivot.y - voxelSizeZ * mainPivot.y, pivot.z - voxelSizeY * mainPivot.z ) + pivotOffset; pivot = new Vector3( (pivot.x - minPos.x) / (maxPos.x - minPos.x), (pivot.y - minPos.y) / (maxPos.y - minPos.y), (pivot.z - minPos.z) / (maxPos.z - minPos.z) ); // Get Pixels int minPixelX; int minPixelY; int maxPixelX; int maxPixelY; // Get Pixels List <Pixel> pixels = GetPixels( faces, out minPixelX, out minPixelY, out maxPixelX, out maxPixelY ); // W and H int width = maxPixelX - minPixelX + 1 + 2; int height = maxPixelY - minPixelY + 1 + 2; // Get Colorss colorss[index] = new Color[width * height]; int len = pixels.Count; for (int i = 0; i < len; i++) { int id = (pixels[i].Y - minPixelY + 1) * width + (pixels[i].X - minPixelX + 1); colorss[index][id] = pixels[i].Color; } // Cheat { List <int> cheatPixels = new List <int>(); List <Color> cheatColors = new List <Color>(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Color c = CheckPixelsAround_Cheat(colorss[index], x, y, width, height); if (c != Color.clear) { cheatPixels.Add(y * width + x); cheatColors.Add(c); } } } int cheatCount = cheatPixels.Count; for (int i = 0; i < cheatCount; i++) { colorss[index][cheatPixels[i]] = cheatColors[i]; } } // Final widths[index] = width; heights[index] = height; pivots[index] = pivot; } return(colorss); }
private static Color[][] Get25DColorss( Voxel[,,] voxels, Color[] palette, Camera camera, int spriteNum, float lightIntensity, float cameraScale, out int[] widths, out int[] heights ) { int voxelSizeX = voxels.GetLength(0); int voxelSizeY = voxels.GetLength(1); int voxelSizeZ = voxels.GetLength(2); widths = new int[spriteNum]; heights = new int[spriteNum]; if (!camera) { return(null); } if (voxelSizeX * voxelSizeY * voxelSizeZ > MAX_ROOM_NUM) { if (!Util.Dialog( "Warning", "Model Is Too Large !\nIt may takes very long time to create this sprite.\nAre you sure to do that?", "Just Go ahead!", "Cancel" )) { return(null); } } Color[][] colorss = new Color[spriteNum][]; Transform cameraRoot = camera.transform.parent; Quaternion oldRot = cameraRoot.rotation; float oldSize = camera.orthographicSize; camera.orthographicSize = (11f - cameraScale) * Mathf.Max(voxelSizeX, voxelSizeY, voxelSizeZ); for (int index = 0; index < spriteNum; index++) { float angleY = FIXED_SPRITE_ANGLE[index]; Quaternion cameraRot = Quaternion.Euler( CAMERA_ANGLE, angleY, 0f ); cameraRoot.rotation = cameraRot; var texture = Util.RenderTextureToTexture2D(camera); texture = Util.TrimTexture(texture); int width = texture.width; int height = texture.height; colorss[index] = texture.GetPixels(); // Cheat { List <int> cheatPixels = new List <int>(); List <Color> cheatColors = new List <Color>(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Color c = CheckPixelsAround_Cheat(colorss[index], x, y, width, height); if (c != Color.clear) { cheatPixels.Add(y * width + x); cheatColors.Add(c); } } } int cheatCount = cheatPixels.Count; for (int i = 0; i < cheatCount; i++) { colorss[index][cheatPixels[i]] = cheatColors[i]; } } // Alpha Fix for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Color c = colorss[index][y * width + x]; if (c.a < 0.8f) { colorss[index][y * width + x] = Color.clear; } } } // Final widths[index] = width; heights[index] = height; } cameraRoot.rotation = oldRot; camera.orthographicSize = oldSize; return(colorss); }
private bool SpawnVoxelFaces() { // Faces if (!Data) { return(false); } int[,,] voxels = Data.Voxels[CurrentModelIndex]; bool tooLargeAsked = false; int sizeX = voxels.GetLength(0); int sizeY = voxels.GetLength(1); int sizeZ = voxels.GetLength(2); float maxSize = Mathf.Max(sizeX, sizeY, sizeZ, 12); CameraSizeMin = 5f; CameraSizeMax = maxSize * 2f; SetCameraSize((CameraSizeMin + CameraSizeMax) * 0.5f); SetCameraFarClip(maxSize * 4f); SetCameraPosition(new Vector3(0f, 0f, -maxSize * 2f)); ContainerTF.localPosition = -new Vector3(sizeX / 2f, sizeY / 2f, sizeZ / 2f); switch (CurrentEditorMode) { case EditorMode.Rigging: // Quads for (int x = 0; x < sizeX; x++) { Util.ProgressBar("", "Importing...", ((float)x / (sizeX - 1)) * 0.5f + 0.5f); for (int y = 0; y < sizeY; y++) { for (int z = 0; z < sizeZ; z++) { if (voxels[x, y, z] == 0) { continue; } AddQuad(x, y, z, voxels[x, y, z], sizeX, sizeY, sizeZ); if (!tooLargeAsked && ContainerTF.childCount > MAX_QUAD_COUNT) { Util.ClearProgressBar(); bool go = Util.Dialog("", "This model is too large. Still want to edit it ?", "Yes", "Cancel"); tooLargeAsked = true; if (!go) { return(false); } } } } } break; case EditorMode.Sprite: case EditorMode.MapGenerator: case EditorMode.CharacterGenerator: bool allInOne = CurrentEditorMode == EditorMode.CharacterGenerator; // Mesh var result = Core_Voxel.CreateModel(Data, 1f, false, Core_Voxel.LightMapSupportType.SmallTextureButNoLightmap, false, Vector3.one * 0.5f); var vModel = result.VoxelModels != null && result.VoxelModels.Length > 0 ? result.VoxelModels[0] : null; for (int modelIndex = allInOne ? 0 : CurrentModelIndex; modelIndex < (allInOne ? vModel.Meshs.Length : CurrentModelIndex + 1); modelIndex++) { var vMesh = vModel != null && vModel.Meshs != null && vModel.Meshs.Length > modelIndex ? vModel.Meshs[modelIndex] : null; if (vMesh == null) { break; } for (int i = 0; i < vMesh.Count; i++) { var mesh = vMesh.GetMeshAt(i); Texture2D texture; if (IsSpriting) { texture = vModel != null && vModel.Textures != null && vModel.Textures.Length > CurrentModelIndex ? vModel.Textures[CurrentModelIndex] : null; } else { texture = CurrentModelIndex == 0 && vModel != null && vModel.Textures != null && vModel.Textures.Length > 0 ? vModel.Textures[0] : null; } if (!mesh) { break; } FixMeshColorByNormal(mesh); var meshTF = new GameObject("_mesh", typeof(MeshRenderer), typeof(MeshFilter)).transform; meshTF.SetParent(ContainerTF); meshTF.localPosition = new Vector3(sizeX / 2f, sizeY / 2f, sizeZ / 2f); meshTF.localScale = Vector3.one; meshTF.localRotation = Quaternion.identity; meshTF.gameObject.layer = LAYER_ID; var mf = meshTF.GetComponent <MeshFilter>(); mf.mesh = mesh; var mr = meshTF.GetComponent <MeshRenderer>(); var mat = new Material(MESH_SHADER); mat.SetColor(COLOR_SHADER_ID, Color.white); mat.mainTexture = texture ? texture : Texture2D.blackTexture; mr.material = mat; mr.receiveShadows = false; mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; } } break; } return(true); }
private static void DoTask(Task task) { if (TaskMap.Count == 0) { return; } if (TheExportMod == ExportMod.AskEverytime && !BrowseExportPath()) { return; } RefreshMergeSetting(); string failMessage = "[Voxel] Failed to create model for {0} model{1}."; int successedNum = 0; int failedNum = 0; int taskCount = TaskMap.Count; var resultList = new List <Core_Voxel.Result>(); Util.ProgressBar("Creating", "Starting task...", 0f); Util.StartWatch(); ForAllSelection((pathData) => { try { string fileName = Util.GetNameWithoutExtension(pathData.Path); Util.ProgressBar("Creating", string.Format("[{1}/{2}] Creating {0}", fileName, successedNum + failedNum + 1, taskCount), (float)(successedNum + failedNum + 1) / (taskCount + 1)); VoxelData voxelData = null; switch (task) { case Task.Prefab: case Task.Lod: case Task.Obj: // Model voxelData = VoxelFile.GetVoxelData(Util.FileToByte(pathData.Path), pathData.Extension == ".vox"); if (pathData.Extension == ".vox" || pathData.Extension == ".qb") { var result = Core_Voxel.CreateLodModel( voxelData, ModelScale, task == Task.Lod ? LodNum : 1, LightMapSupportMode, ModelPivot ); if (TheExportMod == ExportMod.OriginalPath) { result.ExportRoot = Util.GetParentPath(pathData.Path); result.ExportSubRoot = ""; } else { result.ExportRoot = ExportPath; result.ExportSubRoot = pathData.Root; } result.FileName = fileName; result.Extension = task == Task.Obj ? ".obj" : ".prefab"; result.IsRigged = false; result.WithAvatar = false; resultList.Add(result); } break; case Task.ToJson: if (pathData.Extension == ".vox" || pathData.Extension == ".qb") { // Voxel To Json voxelData = VoxelFile.GetVoxelData(Util.FileToByte(pathData.Path), pathData.Extension == ".vox"); var json = Core_Voxel.VoxelToJson(voxelData); string path = TheExportMod == ExportMod.OriginalPath ? Util.ChangeExtension(pathData.Path, ".json") : Util.CombinePaths(ExportPath, pathData.Root, fileName + ".json"); Util.CreateFolder(Util.GetParentPath(path)); Util.Write(json, path); } break; case Task.ToVox: case Task.ToQb: // Json To Voxel string aimEx = task == Task.ToVox ? ".vox" : ".qb"; if (pathData.Extension == ".json") { voxelData = Core_Voxel.JsonToVoxel(Util.Read(pathData.Path)); } else if (pathData.Extension == ".vox" || pathData.Extension == ".qb") { if (aimEx != pathData.Extension) { voxelData = VoxelFile.GetVoxelData(Util.FileToByte(pathData.Path), pathData.Extension == ".vox"); } } if (voxelData) { string aimPath = TheExportMod == ExportMod.OriginalPath ? Util.ChangeExtension(pathData.Path, aimEx) : Util.CombinePaths(ExportPath, pathData.Root, fileName + aimEx); Util.ByteToFile( VoxelFile.GetVoxelByte(voxelData, task == Task.ToVox), aimPath ); } break; } successedNum++; } catch (System.Exception ex) { failMessage += "\n" + ex.Message; failedNum++; } }); // File try { Core_File.CreateFileForResult(resultList, TheShader, ModelScale, ModelPivot); double taskTime = Util.StopWatchAndGetTime(); // Log Messages if (successedNum > 0) { string msg = string.Format("[Voxel] {0} model{1} created in {2}sec.", successedNum, (successedNum > 1 ? "s" : ""), taskTime.ToString("0.00")); if (LogMessage) { Debug.Log(msg); } if (ShowDialog) { Util.Dialog("Success", msg, "OK"); } } if (failedNum > 0) { string msg = string.Format(failMessage, failedNum.ToString(), (failedNum > 1 ? "s" : "")); if (LogMessage) { Debug.LogWarning(msg); } if (ShowDialog) { Util.Dialog("Warning", msg, "OK"); } } } catch (System.Exception ex) { Debug.LogError(ex.Message); } Util.ClearProgressBar(); }