├── Assets ├── MagicaVoxel │ ├── Vox │ │ ├── chr_knight.vox │ │ └── chr_knight.vox.meta │ ├── Textures │ │ ├── MV_DefaultPalette.png │ │ └── MV_DefaultPalette.png.meta │ ├── Scenes │ │ └── Example.unity.meta │ ├── Vox.meta │ ├── Materials.meta │ ├── Scenes.meta │ ├── Scripts.meta │ ├── Textures.meta │ ├── Scripts │ │ ├── Editor.meta │ │ ├── Utilities.meta │ │ ├── Utilities │ │ │ ├── AU.meta │ │ │ └── AU │ │ │ │ ├── EditorUtility.cs.meta │ │ │ │ ├── PrefabUtility.cs.meta │ │ │ │ ├── PrefabUtility.cs │ │ │ │ └── EditorUtility.cs │ │ ├── MVImporter.cs.meta │ │ ├── MVVoxModel.cs.meta │ │ ├── MVVoxModelVoxel.cs │ │ ├── MVVoxModelMesh.cs.meta │ │ ├── MVVoxModelVoxel.cs.meta │ │ ├── Editor │ │ │ ├── MVEditorUtilities.cs.meta │ │ │ ├── MVVoxModelInspector.cs.meta │ │ │ ├── MVVoxModelMeshInspector.cs.meta │ │ │ ├── MVVoxModelVoxelInspector.cs.meta │ │ │ ├── MVEditorUtilities.cs │ │ │ ├── MVVoxModelInspector.cs │ │ │ ├── MVVoxModelMeshInspector.cs │ │ │ └── MVVoxModelVoxelInspector.cs │ │ ├── MVVoxModelMesh.cs │ │ ├── MVVoxModel.cs │ │ └── MVImporter.cs │ └── Materials │ │ ├── Default.mat.meta │ │ └── Default.mat └── MagicaVoxel.meta ├── LICENSE ├── readme.md └── .gitignore /Assets/MagicaVoxel/Vox/chr_knight.vox: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkfall/MagicaVoxelUnity/HEAD/Assets/MagicaVoxel/Vox/chr_knight.vox -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Textures/MV_DefaultPalette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkfall/MagicaVoxelUnity/HEAD/Assets/MagicaVoxel/Textures/MV_DefaultPalette.png -------------------------------------------------------------------------------- /Assets/MagicaVoxel.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa1677c77ee5d2b43a4d25b1017487e9 3 | folderAsset: yes 4 | timeCreated: 1512477840 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scenes/Example.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 21eaa88e26269b045b59da5ce149e317 3 | timeCreated: 1512861486 4 | licenseType: Free 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Vox/chr_knight.vox.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f33a642e7b1820c429f450048c3b84ad 3 | timeCreated: 1513117010 4 | licenseType: Free 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Vox.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa172591b56f7da4780e2f75eb28ba61 3 | folderAsset: yes 4 | timeCreated: 1512944362 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b307d5d8bace94447a1526a749e548a6 3 | folderAsset: yes 4 | timeCreated: 1512477841 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4fd9a5a95acf8f64292f6e9fac36dcf8 3 | folderAsset: yes 4 | timeCreated: 1512477841 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc29dcacedb23df48877ad370700c5a7 3 | folderAsset: yes 4 | timeCreated: 1512477841 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 933bd5c75d44c7848abf80c713592509 3 | folderAsset: yes 4 | timeCreated: 1512684699 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27fbf09ec944f5449a06133b6f5af14b 3 | folderAsset: yes 4 | timeCreated: 1512477841 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Utilities.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 016a36b2c1be2814891b773b1c619e3f 3 | folderAsset: yes 4 | timeCreated: 1512477841 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Utilities/AU.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 93e318006e58b46418dadc0ed5a24020 3 | folderAsset: yes 4 | timeCreated: 1512601516 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Materials/Default.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79dfd23aacc6a484fa4627c732c38d37 3 | timeCreated: 1512684657 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 2100000 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVImporter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6af20b47675d67345bedc6acaa0055b8 3 | timeCreated: 1512477844 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVVoxModel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c272a3d4811fa324cb965d495ca75c19 3 | timeCreated: 1512477844 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVVoxModelVoxel.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | // stub class for editor 5 | public class MVVoxModelVoxel : MonoBehaviour { 6 | 7 | #if UNITY_EDITOR 8 | 9 | public MVVoxel voxel; 10 | 11 | public MVVoxModel parentVoxModel { 12 | get { return GetComponentInParent (); } 13 | } 14 | 15 | #endif 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVVoxModelMesh.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a81370f406adaa44a1616b5759af668 3 | timeCreated: 1512477844 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVVoxModelVoxel.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 073a1281be2032d4fb97c17a9f6fd933 3 | timeCreated: 1512477843 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVEditorUtilities.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c0bf0b22d8a9864c8f44a2e281fcb4f 3 | timeCreated: 1512477844 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVVoxModelInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20778cb5f02e42544a9c67436de29a65 3 | timeCreated: 1512477843 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Utilities/AU/EditorUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 767326ef34745bc44b9efea703a2e875 3 | timeCreated: 1512601518 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Utilities/AU/PrefabUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 28a0b9406de028246bdc43e1425247a0 3 | timeCreated: 1512683966 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVVoxModelMeshInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 681b7789ba9ee664da7bc58198ef9c67 3 | timeCreated: 1512477844 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVVoxModelVoxelInspector.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24a9d6a755852d1479c855fc8478f526 3 | timeCreated: 1512477844 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVVoxModelMesh.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | // mainly a sub class for editor 5 | // incase there are other subobjects that don't want to be removed when reimporting 6 | public class MVVoxModelMesh : MonoBehaviour { 7 | 8 | #if UNITY_EDITOR 9 | 10 | // when using individual voxel import & then combinaning voxels, stores an array of voxels for undo 11 | public MVVoxel[] voxels; 12 | 13 | public MVVoxModel parentVoxModel { 14 | get { return GetComponentInParent (); } 15 | } 16 | 17 | #endif 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVEditorUtilities.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | 6 | public static class MVEditorUtilities { 7 | 8 | [MenuItem("Tools/MagicaVoxel/Load")] 9 | static void Load() { 10 | string path = EditorUtility.OpenFilePanel( 11 | "Open VOX model", 12 | "Assets/MagicaVoxel/Vox", 13 | "vox" 14 | ); 15 | 16 | if (path != null && path.Length > 0) 17 | { 18 | GameObject go = new GameObject (); 19 | go.name = System.IO.Path.GetFileNameWithoutExtension (path); 20 | 21 | MVVoxModel voxModel = go.AddComponent (); 22 | voxModel.ed_filePath = path; 23 | voxModel.LoadVOXFile (path, voxModel.ed_importAsIndividualVoxels); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ruiwei Bu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVVoxModelInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | [CustomEditor(typeof(MVVoxModel))] 6 | public class MVVoxModelInspector : Editor { 7 | 8 | public override void OnInspectorGUI () 9 | { 10 | base.OnInspectorGUI (); 11 | 12 | MVVoxModel voxModel = this.target as MVVoxModel; 13 | 14 | if(voxModel.vox != null) 15 | AU.AUEditorUtility.ColoredLabel (string.Format("Controls ({3}: {0}x{1}x{2})", voxModel.vox.sizeX, voxModel.vox.sizeY, voxModel.vox.sizeZ, System.IO.Path.GetFileNameWithoutExtension(voxModel.ed_filePath)), Color.green); 16 | else 17 | AU.AUEditorUtility.ColoredLabel ("Controls", Color.green); 18 | 19 | AU.AUEditorUtility.ColoredHelpBox (Color.yellow, "Enabling this may create lots of GameObjects, careful when the vox model is big"); 20 | voxModel.ed_importAsIndividualVoxels = EditorGUILayout.Toggle ("Import as Individual Voxels", voxModel.ed_importAsIndividualVoxels); 21 | 22 | EditorGUILayout.BeginHorizontal (); 23 | if (GUILayout.Button ("Load")) { 24 | 25 | string path = EditorUtility.OpenFilePanel( 26 | "Open VOX model", 27 | "Assets/MagicaVoxel/Vox", 28 | "vox" 29 | ); 30 | 31 | voxModel.ed_filePath = path; 32 | voxModel.LoadVOXFile(path, voxModel.ed_importAsIndividualVoxels); 33 | } 34 | if (GUILayout.Button ("Reimport")) { 35 | 36 | voxModel.LoadVOXFile (voxModel.ed_filePath, voxModel.ed_importAsIndividualVoxels); 37 | } 38 | 39 | if (GUILayout.Button ("Clear")) { 40 | 41 | voxModel.ClearVoxMeshes (); 42 | 43 | } 44 | EditorGUILayout.EndHorizontal (); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVVoxModelMeshInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | [CustomEditor(typeof(MVVoxModelMesh))] 7 | public class MVVoxModelMeshInspector : Editor { 8 | 9 | public override void OnInspectorGUI () 10 | { 11 | MVVoxModelMesh m = this.target as MVVoxModelMesh; 12 | if (m.voxels != null && m.voxels.Length > 1) { 13 | if (GUILayout.Button ("Convert to Voxels")) { 14 | 15 | CreateVoxels (m.voxels, m.parentVoxModel); 16 | 17 | GameObject.DestroyImmediate (m.gameObject); 18 | } 19 | } 20 | } 21 | 22 | public static void CreateVoxels(MVVoxel[] voxels, MVVoxModel voxModel) { 23 | MVVoxelChunk chunk = voxModel.vox.voxelChunk; 24 | 25 | float sizePerVox = voxModel.sizePerVox; 26 | 27 | float cx = sizePerVox * chunk.sizeX / 2; 28 | float cy = sizePerVox * chunk.sizeY / 2; 29 | float cz = sizePerVox * chunk.sizeZ / 2; 30 | 31 | Material mat = (voxModel.voxMaterial != null) ? voxModel.voxMaterial : MVImporter.DefaultMaterial; 32 | 33 | List objects = new List (); 34 | foreach (MVVoxel voxel in voxels) { 35 | float px = voxel.x * sizePerVox - cx, py = voxel.y * sizePerVox - cy, pz = voxel.z * sizePerVox - cz; 36 | int cidx = chunk.voxels[voxel.x, voxel.y, voxel.z]; 37 | 38 | GameObject go = MVImporter.CreateGameObject (voxModel.gameObject.gameObject.transform, 39 | new Vector3 (px, py, pz), 40 | string.Format ("Voxel ({0}, {1}, {2})", voxel.x, voxel.y, voxel.z), 41 | MVImporter.CubeMeshWithColor (sizePerVox, voxModel.vox.palatte [cidx - 1], cidx), 42 | mat); 43 | 44 | MVVoxModelVoxel v = go.AddComponent (); 45 | v.voxel = new MVVoxel () { x = voxel.x, y = voxel.y, z = voxel.z, colorIndex = chunk.voxels [voxel.x, voxel.y, voxel.z] }; 46 | 47 | objects.Add (go); 48 | } 49 | 50 | Selection.objects = objects.ToArray (); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Textures/MV_DefaultPalette.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d72a9dff43ddb14a97b72618047486c 3 | timeCreated: 1512684720 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | externalObjects: {} 8 | serializedVersion: 4 9 | mipmaps: 10 | mipMapMode: 0 11 | enableMipMap: 0 12 | sRGBTexture: 1 13 | linearTexture: 0 14 | fadeOut: 0 15 | borderMipMap: 0 16 | mipMapsPreserveCoverage: 0 17 | alphaTestReferenceValue: 0.5 18 | mipMapFadeDistanceStart: 1 19 | mipMapFadeDistanceEnd: 3 20 | bumpmap: 21 | convertToNormalMap: 0 22 | externalNormalMap: 0 23 | heightScale: 0.25 24 | normalMapFilter: 0 25 | isReadable: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 0 35 | aniso: -1 36 | mipBias: -1 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 49 | spritePixelsToUnits: 100 50 | alphaUsage: 1 51 | alphaIsTransparency: 0 52 | spriteTessellationDetail: -1 53 | textureType: 0 54 | textureShape: 1 55 | maxTextureSizeSet: 0 56 | compressionQualitySet: 0 57 | textureFormatSet: 0 58 | platformSettings: 59 | - buildTarget: DefaultTexturePlatform 60 | maxTextureSize: 256 61 | resizeAlgorithm: 1 62 | textureFormat: -1 63 | textureCompression: 0 64 | compressionQuality: 50 65 | crunchedCompression: 0 66 | allowsAlphaSplitting: 0 67 | overridden: 0 68 | - buildTarget: Standalone 69 | maxTextureSize: 256 70 | resizeAlgorithm: 1 71 | textureFormat: -1 72 | textureCompression: 0 73 | compressionQuality: 50 74 | crunchedCompression: 0 75 | allowsAlphaSplitting: 0 76 | overridden: 0 77 | spriteSheet: 78 | serializedVersion: 2 79 | sprites: [] 80 | outline: [] 81 | physicsShape: [] 82 | spritePackingTag: 83 | userData: 84 | assetBundleName: 85 | assetBundleVariant: 86 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ### Note 2 | 3 | This project is somewhat old and doesn't support parsing the new features added in the newer .vox format. Though it should still be able to load it. 4 | Due to constraints from my current employer, sadly I cannot directly work on this for now. I'll be glad to merge PRs : ) 5 | 6 | 7 | ### MagicaVoxelUnity 8 | 9 | Unity3D plugin for MagicaVoxel's "vox" format 10 | 11 | #### Features 12 | * Import "vox" files as meshes (faces combined if possible) 13 | * Import "vox" files as individual voxels (GameObjects) 14 | * Voxels can be combined into a single GameObject, so you can cut the voxel model into several GameObjects (meshes) for animation purposes 15 | 16 | #### How To 17 | * Use __Tools/MagicaVoxel/Load__ on the menubar to load and create a GameObject with a voxel model directly 18 | 19 | * Add __MVVoxelModel__ script to your component 20 | * Use editor controls to load "vox" files onto the object 21 | 22 | * Or use MVVoxelModel's member methods 23 | 24 | LoadVOXFile(filePath, importAsIndividualVoxels) 25 | LoadVOXData(data, importAsIndividualVoxels) 26 | 27 | MVVoxelModel.sizePerVoxel, MVVoxelModel.voxMaterial and MVVoxelModel.meshOrigin can be configured before loading the file/data 28 | 29 | * When imported as separate voxels, selecting multiple voxels in the editor will give you a control to combine the selected voxels into a single mesh 30 | * The mesh can be divided into separate voxels again 31 | 32 | * Use static methods in __MVImporter__ 33 | 34 | Load main chunk: 35 | 36 | LoadVOX(file) 37 | LoadVOXFromData(data) 38 | 39 | Create meshes from main chunk: 40 | 41 | CreateMeshes(mainChunk, sizePerVox) 42 | 43 | Or create meshes and GameObjects from main chunk: 44 | 45 | CreateVoxelGameObjects(mainChunk, parentTransform, material, sizePerVox) 46 | CreateIndividualVoxelGameObjects(mainChunk, parentTransform, material, sizePerVox) 47 | 48 | 49 | #### Todo 50 | 51 | * T-junction problems (intersections) 52 | * Optional disable face combining 53 | 54 | #### License 55 | 56 | MIT 57 | 58 | #### Contact 59 | * darkfall3 at gmail.com ([http://darkfall.me](http://darkfall.me)) 60 | 61 | #### Thanks 62 | * barraudf ([https://github.com/barraudf](https://github.com/barraudf)) 63 | * Stefano Cecere ([https://github.com/StefanoCecere](https://github.com/StefanoCecere)) 64 | * jonaskivi ([https://github.com/jonaskivi](https://github.com/jonaskivi)) 65 | 66 | And all other contributors 67 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Materials/Default.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Default 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _GLOSSYREFLECTIONS_OFF _SPECULARHIGHLIGHTS_OFF 12 | m_LightmapFlags: 4 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 2800000, guid: 8d72a9dff43ddb14a97b72618047486c, type: 3} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | - _SpecGlossMap: 58 | m_Texture: {fileID: 0} 59 | m_Scale: {x: 1, y: 1} 60 | m_Offset: {x: 0, y: 0} 61 | m_Floats: 62 | - _BumpScale: 1 63 | - _Cutoff: 0.5 64 | - _DetailNormalMapScale: 1 65 | - _DstBlend: 0 66 | - _GlossMapScale: 0 67 | - _Glossiness: 0 68 | - _GlossyReflections: 0 69 | - _Metallic: 0 70 | - _Mode: 0 71 | - _OcclusionStrength: 1 72 | - _Parallax: 0.02 73 | - _SmoothnessTextureChannel: 0 74 | - _SpecularHighlights: 0 75 | - _SrcBlend: 1 76 | - _UVSec: 0 77 | - _ZWrite: 1 78 | m_Colors: 79 | - _Color: {r: 1, g: 1, b: 1, a: 1} 80 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 81 | - _SpecColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 82 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Editor/MVVoxModelVoxelInspector.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | 7 | [CustomEditor(typeof(MVVoxModelVoxel))] 8 | [CanEditMultipleObjects] 9 | public class MVVoxModelVoxelInspector : Editor { 10 | 11 | public override void OnInspectorGUI () 12 | { 13 | 14 | AU.AUEditorUtility.ColoredHelpBox (Color.yellow, "Combining multiple voxels into one"); 15 | 16 | GUILayout.BeginHorizontal (); 17 | 18 | if (GUILayout.Button ("Combine Selected")) { 19 | if (this.targets != null && this.targets.Length > 1) 20 | CombineVoxels (System.Array.ConvertAll(this.targets, item => (MVVoxModelVoxel)item)); 21 | } 22 | 23 | if (GUILayout.Button ("Combine All")) { 24 | MVVoxModel voxModel = (this.target as MVVoxModelVoxel).parentVoxModel; 25 | MVVoxModelVoxel[] allVoxels = voxModel.GetComponentsInChildren (); 26 | CombineVoxels (allVoxels); 27 | } 28 | 29 | GUILayout.EndHorizontal (); 30 | } 31 | 32 | public static void CombineVoxels(MVVoxModelVoxel[] voxels) { 33 | if (voxels != null && voxels.Length > 0) { 34 | MVVoxelChunk chunk = new MVVoxelChunk (); 35 | MVVoxModel model = voxels [0].parentVoxModel; 36 | MVVoxelChunk origChunk = model.vox.voxelChunk; 37 | 38 | chunk.voxels = new byte[origChunk.sizeX, origChunk.sizeY, origChunk.sizeZ]; 39 | foreach (MVVoxModelVoxel v in voxels) { 40 | chunk.voxels [v.voxel.x, v.voxel.y, v.voxel.z] = v.voxel.colorIndex; 41 | } 42 | 43 | MVImporter.GenerateFaces(chunk); 44 | Mesh[] meshes = MVImporter.CreateMeshesFromChunk(chunk, model.vox.palatte, model.sizePerVox); 45 | 46 | if (meshes.Length > 1) { 47 | Debug.LogError ("[MVCombine] Currently does not support combining voxels into multiple meshes, please reduce the number of voxels you are trying to combine"); 48 | return; 49 | } 50 | 51 | Material mat = (model.voxMaterial != null) ? model.voxMaterial : MVImporter.DefaultMaterial; 52 | 53 | int index = 0; 54 | foreach (Mesh mesh in meshes) { 55 | GameObject go = MVImporter.CreateGameObject (model.gameObject.transform, Vector3.zero, string.Format ("VoxMesh ({0})", index), mesh, mat); 56 | 57 | MVVoxModelMesh voxMesh = go.AddComponent (); 58 | voxMesh.voxels = voxels.Select( o => o.voxel ).ToArray(); 59 | 60 | Selection.activeGameObject = go; 61 | 62 | index++; 63 | } 64 | 65 | foreach (MVVoxModelVoxel v in voxels) { 66 | GameObject.DestroyImmediate (v.gameObject); 67 | } 68 | } 69 | else { 70 | Debug.LogError("[MVCombine] Invalid voxels"); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVVoxModel.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class MVVoxModel : MonoBehaviour { 5 | 6 | // for animations, voxels can later be combined into individual layers 7 | [HideInInspector] 8 | public bool ed_importAsIndividualVoxels = false; 9 | 10 | // actually requred for instantiation 11 | public string ed_filePath = ""; 12 | 13 | [HideInInspector] 14 | public MVMainChunk vox; 15 | 16 | [Range(0.01f, 5.0f)] 17 | public float sizePerVox = 1.0f; 18 | 19 | public Material voxMaterial = null; 20 | 21 | public Transform meshOrigin = null; 22 | 23 | [Tooltip("If the vox file contains a palette, should it be converted to a texture?")] 24 | public bool paletteToTex = false; 25 | 26 | public void ClearVoxMeshes() { 27 | MVVoxModelMesh[] subMeshes = this.gameObject.GetComponentsInChildren (); 28 | foreach (MVVoxModelMesh subMesh in subMeshes) 29 | GameObject.DestroyImmediate (subMesh.gameObject); 30 | 31 | MVVoxModelVoxel[] subVoxels = this.gameObject.GetComponentsInChildren (); 32 | foreach (MVVoxModelVoxel v in subVoxels) 33 | GameObject.DestroyImmediate (v.gameObject); 34 | 35 | } 36 | 37 | public void LoadVOXFile(string path, bool asIndividualVoxels) { 38 | ClearVoxMeshes (); 39 | 40 | if (path != null && path.Length > 0) 41 | { 42 | MVMainChunk v = MVImporter.LoadVOX (path); 43 | 44 | if (v != null) { 45 | Material mat = (this.voxMaterial != null) ? this.voxMaterial : MVImporter.DefaultMaterial; 46 | if (paletteToTex) 47 | mat.mainTexture = v.PaletteToTexture(); 48 | 49 | if (!asIndividualVoxels) { 50 | 51 | if (meshOrigin != null) 52 | MVImporter.CreateVoxelGameObjects(v, this.gameObject.transform, mat, sizePerVox, meshOrigin.localPosition); 53 | else 54 | MVImporter.CreateVoxelGameObjects (v, this.gameObject.transform, mat, sizePerVox); 55 | 56 | } else { 57 | 58 | if (meshOrigin != null) 59 | MVImporter.CreateIndividualVoxelGameObjects(v, this.gameObject.transform, mat, sizePerVox, meshOrigin.localPosition); 60 | else 61 | MVImporter.CreateIndividualVoxelGameObjects (v, this.gameObject.transform, mat, sizePerVox); 62 | 63 | } 64 | 65 | this.vox = v; 66 | } 67 | 68 | 69 | } else { 70 | Debug.LogError ("[MVVoxModel] Invalid file path"); 71 | } 72 | } 73 | 74 | public void LoadVOXData(byte[] data, bool asIndividualVoxels) { 75 | ClearVoxMeshes (); 76 | 77 | MVMainChunk v = MVImporter.LoadVOXFromData(data); 78 | 79 | if (v != null) { 80 | Material mat = (this.voxMaterial != null) ? this.voxMaterial : MVImporter.DefaultMaterial; 81 | 82 | if (paletteToTex) 83 | mat.mainTexture = v.PaletteToTexture(); 84 | 85 | if (!asIndividualVoxels) { 86 | 87 | MVImporter.CreateVoxelGameObjects (v, this.gameObject.transform, mat, sizePerVox); 88 | 89 | } else { 90 | 91 | MVImporter.CreateIndividualVoxelGameObjects (v, this.gameObject.transform, mat, sizePerVox); 92 | 93 | } 94 | 95 | this.vox = v; 96 | } 97 | 98 | } 99 | 100 | public bool reimportOnStart = true; 101 | void Start() 102 | { 103 | if (reimportOnStart) { 104 | LoadVOXFile (ed_filePath, ed_importAsIndividualVoxels); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # our stuff 2 | _OUTPUT_/ 3 | _DELETE_/ 4 | _INTERMIDIATE_/ 5 | 6 | # Xcode/OSX 7 | DerivedData 8 | xcuserdata 9 | .xcuserstate 10 | .DS_Store 11 | ._DS_Store 12 | 13 | ## Ignore Visual Studio temporary files, build results, and 14 | ## files generated by popular Visual Studio add-ons. 15 | 16 | # User-specific files 17 | *.suo 18 | *.user 19 | *.sln.docstates 20 | 21 | # Build results 22 | [Dd]ebug/ 23 | [Dd]ebugPublic/ 24 | [Rr]elease/ 25 | x64/ 26 | build/ 27 | bld/ 28 | #[Bb]in/ 29 | [Oo]bj/ 30 | 31 | PSVita_Debug/ 32 | PS3_Debug/ 33 | PS4_Debug/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | #NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | *_i.c 44 | *_p.c 45 | *_i.h 46 | *.ilk 47 | *.meta 48 | #*.obj 49 | *.pch 50 | *.pdb 51 | *.pgc 52 | *.pgd 53 | *.rsp 54 | *.sbr 55 | *.tlb 56 | *.tli 57 | *.tlh 58 | *.tmp 59 | *.tmp_proj 60 | *.log 61 | *.vspscc 62 | *.vssscc 63 | .builds 64 | *.pidb 65 | *.svclog 66 | *.scc 67 | *.tlog 68 | 69 | # Chutzpah Test files 70 | _Chutzpah* 71 | 72 | # Visual C++ cache files 73 | ipch/ 74 | *.aps 75 | *.ncb 76 | *.opensdf 77 | *.sdf 78 | *.cachefile 79 | 80 | # Visual Studio profiler 81 | *.psess 82 | *.vsp 83 | *.vspx 84 | 85 | # TFS 2012 Local Workspace 86 | $tf/ 87 | 88 | # Guidance Automation Toolkit 89 | *.gpState 90 | 91 | # ReSharper is a .NET coding add-in 92 | _ReSharper*/ 93 | *.[Rr]e[Ss]harper 94 | *.DotSettings.user 95 | 96 | # JustCode is a .NET coding addin-in 97 | .JustCode 98 | 99 | # TeamCity is a build add-in 100 | _TeamCity* 101 | 102 | # DotCover is a Code Coverage Tool 103 | *.dotCover 104 | 105 | # NCrunch 106 | *.ncrunch* 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Installshield output folder 115 | [Ee]xpress/ 116 | 117 | # DocProject is a documentation generator add-in 118 | DocProject/buildhelp/ 119 | DocProject/Help/*.HxT 120 | DocProject/Help/*.HxC 121 | DocProject/Help/*.hhc 122 | DocProject/Help/*.hhk 123 | DocProject/Help/*.hhp 124 | DocProject/Help/Html2 125 | DocProject/Help/html 126 | 127 | # Click-Once directory 128 | publish/ 129 | 130 | # Publish Web Output 131 | *.[Pp]ublish.xml 132 | *.azurePubxml 133 | 134 | # NuGet Packages Directory 135 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 136 | #packages/* 137 | ## TODO: If the tool you use requires repositories.config, also uncomment the next line 138 | #!packages/repositories.config 139 | 140 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 141 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) 142 | !packages/build/ 143 | 144 | # Windows Azure Build Output 145 | csx/ 146 | *.build.csdef 147 | 148 | # Windows Store app package directory 149 | AppPackages/ 150 | 151 | # Others 152 | sql/ 153 | *.Cache 154 | ClientBin/ 155 | [Ss]tyle[Cc]op.* 156 | ~$* 157 | *~ 158 | *.dbmdl 159 | *.dbproj.schemaview 160 | *.pfx 161 | *.publishsettings 162 | node_modules/ 163 | 164 | # RIA/Silverlight projects 165 | Generated_Code/ 166 | 167 | # Backup & report files from converting an old project file to a newer 168 | # Visual Studio version. Backup files are not needed, because we have git ;-) 169 | _UpgradeReport_Files/ 170 | Backup*/ 171 | UpgradeLog*.XML 172 | UpgradeLog*.htm 173 | 174 | # SQL Server files 175 | App_Data/*.mdf 176 | App_Data/*.ldf 177 | 178 | # Business Intelligence projects 179 | *.rdl.data 180 | *.bim.layout 181 | *.bim_*.settings 182 | 183 | # Microsoft Fakes 184 | FakesAssemblies/ 185 | 186 | # ========================= 187 | # Windows detritus 188 | # ========================= 189 | 190 | # Windows image file caches 191 | Thumbs.db 192 | ehthumbs.db 193 | 194 | # Folder config file 195 | Desktop.ini 196 | 197 | # Recycle Bin used on file shares 198 | $RECYCLE.BIN/ -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Utilities/AU/PrefabUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Reflection; 4 | using UnityEngine; 5 | using Object = System.Object; 6 | #if UNITY_EDITOR 7 | using UnityEditor; 8 | #endif 9 | 10 | namespace AU 11 | { 12 | public static class AssetUtility 13 | { 14 | public static Transform FindTransformInChildren(Transform parent, String name, Transform d = null) 15 | { 16 | Transform trans = parent.GetComponentsInChildren().FirstOrDefault(t => t.name == name); 17 | if (trans == null) return d; 18 | return trans; 19 | } 20 | 21 | public static T GetCopyOf(this Object comp, T other) where T : class 22 | { 23 | Type type = comp.GetType(); 24 | if (type != other.GetType()) return null; // type mis-match 25 | BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default | BindingFlags.DeclaredOnly; 26 | PropertyInfo[] pinfos = type.GetProperties(flags); 27 | foreach (var pinfo in pinfos) 28 | { 29 | if (pinfo.CanWrite) 30 | { 31 | try 32 | { 33 | pinfo.SetValue(comp, pinfo.GetValue(other, null), null); 34 | } 35 | catch { } 36 | } 37 | } 38 | FieldInfo[] finfos = type.GetFields(flags); 39 | foreach (var finfo in finfos) 40 | { 41 | finfo.SetValue(comp, finfo.GetValue(other)); 42 | } 43 | return comp as T; 44 | } 45 | 46 | #if UNITY_EDITOR 47 | public static string GetAssetPath(UnityEngine.Object rsrc) 48 | { 49 | if (rsrc == null) 50 | { 51 | return ""; 52 | } 53 | var path = AssetDatabase.GetAssetPath(rsrc); 54 | 55 | while (String.IsNullOrEmpty(path)) 56 | { 57 | var parent = PrefabUtility.GetPrefabParent(rsrc); 58 | 59 | if (parent == null) 60 | { 61 | break; 62 | } 63 | 64 | path = AssetDatabase.GetAssetPath(parent); 65 | 66 | rsrc = parent; 67 | } 68 | 69 | int index = path.IndexOf("Resources"); 70 | if(index != -1) 71 | { 72 | path = path.Substring(index + 10); 73 | return path.Split(new char[] { '.' })[0]; 74 | } 75 | return ""; 76 | } 77 | 78 | public static string GetAssetPathNonResource(UnityEngine.Object rsrc) 79 | { 80 | if (rsrc == null) 81 | { 82 | return ""; 83 | } 84 | var path = AssetDatabase.GetAssetPath(rsrc); 85 | 86 | while (String.IsNullOrEmpty(path)) 87 | { 88 | var parent = PrefabUtility.GetPrefabParent(rsrc); 89 | 90 | if (parent == null) 91 | { 92 | break; 93 | } 94 | 95 | path = AssetDatabase.GetAssetPath(parent); 96 | 97 | rsrc = parent; 98 | } 99 | return path; 100 | } 101 | 102 | public static void SavePrefab(GameObject obj) 103 | { 104 | try 105 | { 106 | UnityEngine.Object parent = PrefabUtility.GetPrefabParent(obj); 107 | if (parent != null) 108 | PrefabUtility.ReplacePrefab(parent as GameObject, parent, ReplacePrefabOptions.ConnectToPrefab); 109 | } 110 | catch 111 | { 112 | 113 | } 114 | } 115 | 116 | #else 117 | 118 | // placeholder, this should not be called in runtime 119 | public static string GetAssetPath(UnityEngine.Object rsrc) 120 | { 121 | return rsrc.name; 122 | } 123 | 124 | public static void SavePrefab(GameObject obj) 125 | { 126 | } 127 | 128 | #endif 129 | 130 | 131 | public static T LoadAsset(string path) where T: UnityEngine.Object 132 | { 133 | if(path.Length == 0) 134 | { 135 | return null; 136 | } 137 | T r = Resources.Load(path, typeof(T)) as T; 138 | if(r == null) 139 | Debug.LogError("[AssetUtility] Failed to load " + path); 140 | return r; 141 | } 142 | 143 | #if UNITY_EDITOR 144 | // this guy uses relative path of the unity project 145 | // use only in editor please 146 | public static T LoadAssetAtPath(string path) where T : UnityEngine.Object 147 | { 148 | if (path.Length == 0) 149 | { 150 | return null; 151 | } 152 | 153 | int asIndex = path.IndexOf ("Assets"); 154 | if (asIndex > 0) 155 | path = path.Substring (asIndex); 156 | 157 | T r = AssetDatabase.LoadAssetAtPath(path, typeof(T)) as T; 158 | if (r == null) 159 | Debug.LogError("[AssetUtility] Failed to load " + path); 160 | return r; 161 | } 162 | #endif 163 | 164 | public static bool TryLoadAsset(string path, out T v) where T: UnityEngine.Object 165 | { 166 | if (path.Length == 0) 167 | { 168 | v = null; 169 | return false; 170 | } 171 | T r = Resources.Load(path, typeof(T)) as T; 172 | if (r == null) 173 | { 174 | v = null; 175 | return false; 176 | } 177 | v = r; 178 | return true; 179 | } 180 | 181 | public static bool AssetExists(string p) 182 | { 183 | if (Resources.Load(p) == null) 184 | return false; 185 | return true; 186 | } 187 | } 188 | } -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/Utilities/AU/EditorUtility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | using UnityEngine; 7 | 8 | #if UNITY_EDITOR 9 | using UnityEditorInternal; 10 | using UnityEditor; 11 | #endif 12 | 13 | namespace AU 14 | { 15 | public class ReadOnlyAttribute : PropertyAttribute 16 | { 17 | } 18 | 19 | public class ObjectInfoNameSelector : PropertyAttribute 20 | { 21 | } 22 | 23 | public class TypeNameAttribute : PropertyAttribute 24 | { 25 | 26 | } 27 | 28 | public class FabricAudioSelector : PropertyAttribute 29 | { 30 | 31 | } 32 | 33 | public class AssetStringField : PropertyAttribute 34 | { 35 | public Type typeOfObject = typeof(UnityEngine.Object); 36 | } 37 | 38 | public static class AUEditorUtility 39 | { 40 | public static List ResizeList(List list, int newSize) where T : new() 41 | { 42 | List newList = new List(); 43 | int maxLen = Mathf.Min(newSize, list.Count); 44 | for (int i = 0; i < maxLen; ++i) 45 | { 46 | newList.Add(list[i]); 47 | } 48 | for (int i = 0; i < newSize - maxLen; ++i) 49 | newList.Add(new T()); 50 | return newList; 51 | } 52 | 53 | public static void DestroyAllChild(GameObject go) 54 | { 55 | Transform t = go.transform; 56 | while (t.childCount > 0) 57 | { 58 | GameObject.DestroyImmediate(t.GetChild(0).gameObject); 59 | } 60 | } 61 | 62 | public static Mesh CreatePlaneMesh(float width, float height, int widthSegments, int heightSegments) 63 | { 64 | Mesh m = new Mesh(); 65 | m.name = string.Format("PLANE_{0}x{1}", (int)width, (int)height); 66 | 67 | int hCount2 = widthSegments + 1; 68 | int vCount2 = heightSegments + 1; 69 | int numTriangles = widthSegments * heightSegments * 6; 70 | int numVertices = hCount2 * vCount2; 71 | 72 | Vector3[] vertices = new Vector3[numVertices]; 73 | Vector2[] uvs = new Vector2[numVertices]; 74 | int[] triangles = new int[numTriangles]; 75 | 76 | int index = 0; 77 | float uvFactorX = 1.0f / widthSegments; 78 | float uvFactorY = 1.0f / heightSegments; 79 | float scaleX = width / widthSegments; 80 | float scaleY = height / heightSegments; 81 | for (float y = 0.0f; y < vCount2; y++) 82 | { 83 | for (float x = 0.0f; x < hCount2; x++) 84 | { 85 | vertices[index] = new Vector3(x * scaleX - width / 2f, 0.0f, y * scaleY - height / 2f); 86 | uvs[index++] = new Vector2(x * uvFactorX, y * uvFactorY); 87 | } 88 | } 89 | 90 | index = 0; 91 | for (int y = 0; y < heightSegments; y++) 92 | { 93 | for (int x = 0; x < widthSegments; x++) 94 | { 95 | triangles[index] = (y * hCount2) + x; 96 | triangles[index + 1] = ((y + 1) * hCount2) + x; 97 | triangles[index + 2] = (y * hCount2) + x + 1; 98 | 99 | triangles[index + 3] = ((y + 1) * hCount2) + x; 100 | triangles[index + 4] = ((y + 1) * hCount2) + x + 1; 101 | triangles[index + 5] = (y * hCount2) + x + 1; 102 | index += 6; 103 | } 104 | } 105 | 106 | m.vertices = vertices; 107 | m.uv = uvs; 108 | m.triangles = triangles; 109 | m.RecalculateNormals(); 110 | 111 | return m; 112 | } 113 | 114 | #if UNITY_EDITOR 115 | 116 | static List colorStack = new List(); 117 | static List labelWidthStack = new List(); 118 | 119 | public static string ReadOnlyTextField(string label, string k) 120 | { 121 | GUI.enabled = false; 122 | string x = EditorGUILayout.TextField(label, k); 123 | GUI.enabled = true; 124 | return x; 125 | } 126 | 127 | public static Color EditorYellowColor() 128 | { 129 | if (!InternalEditorUtility.HasPro()) 130 | return new Color(208.0f / 255.0f, 199.0f / 255.0f, 98.0f / 255.0f, 1.0f); 131 | else 132 | return Color.yellow; 133 | } 134 | 135 | public static void PushGUIColor(Color c) 136 | { 137 | colorStack.Add(GUI.color); 138 | GUI.color = c; 139 | } 140 | 141 | public static void PopGUIColor(int c = 1) 142 | { 143 | for (int i = 0; i < c; ++i) 144 | { 145 | if (colorStack.Count == 0) 146 | { 147 | Debug.LogError("[EditorUtility] Color stack empty, cannot pop color, make sure PushColor and PopColor are balanced"); 148 | return; 149 | } 150 | 151 | GUI.color = colorStack.Last(); 152 | colorStack.RemoveAt(colorStack.Count - 1); 153 | } 154 | } 155 | 156 | public static void PushLabelWidth(float w) 157 | { 158 | labelWidthStack.Add(EditorGUIUtility.labelWidth); 159 | EditorGUIUtility.labelWidth = w; 160 | } 161 | 162 | public static void PopLabelWidth(int c = 1) 163 | { 164 | for (int i = 0; i < c; ++i) 165 | { 166 | if (labelWidthStack.Count == 0) 167 | { 168 | Debug.LogError("[EditorUtility] LabelWidth stack empty, cannot pop color, make sure PushColor and PopColor are balanced"); 169 | return; 170 | } 171 | 172 | EditorGUIUtility.labelWidth = labelWidthStack.Last(); 173 | labelWidthStack.RemoveAt(labelWidthStack.Count - 1); 174 | } 175 | } 176 | 177 | public static void ColoredLabel(string t, Color c, TextAnchor anchor = TextAnchor.MiddleLeft) 178 | { 179 | Color o = GUI.color; 180 | GUI.color = c; 181 | TextAnchor prevAnchor = GUI.skin.label.alignment; 182 | EditorStyles.label.alignment = anchor; 183 | EditorGUILayout.LabelField(t); 184 | EditorStyles.label.alignment = prevAnchor; 185 | GUI.color = o; 186 | } 187 | 188 | public static void ColoredLabel(string t, Color c, TextAnchor anchor, params GUILayoutOption[] options) 189 | { 190 | Color o = GUI.color; 191 | GUI.color = c; 192 | TextAnchor prevAnchor = GUI.skin.label.alignment; 193 | EditorStyles.label.alignment = anchor; 194 | EditorGUILayout.LabelField(t, options); 195 | EditorStyles.label.alignment = prevAnchor; 196 | GUI.color = o; 197 | } 198 | 199 | public static void SectionTitle(string title, Color c) 200 | { 201 | EditorGUILayout.Space(); 202 | ColoredLabel(title, c); 203 | } 204 | 205 | public static void AssetField(string label, ref T obj, ref string path) where T : UnityEngine.Object 206 | { 207 | if (path.Length > 0) 208 | { 209 | PushGUIColor(Color.yellow); 210 | EditorGUILayout.HelpBox("Path: " + path, MessageType.None); 211 | PopGUIColor(); 212 | 213 | if (obj == null) 214 | { 215 | obj = AssetUtility.LoadAsset(path); 216 | if (obj == null) 217 | { 218 | path = ""; 219 | } 220 | } 221 | } 222 | 223 | obj = EditorGUILayout.ObjectField(label, obj, typeof(T), false) as T; 224 | if (GUI.changed) 225 | { 226 | if (obj != null) 227 | { 228 | path = AssetUtility.GetAssetPath(obj); 229 | if (path.Length == 0) 230 | { 231 | Debug.LogError("Prefab must be in [Resources] directory due to Unity runtime requirement"); 232 | obj = null; 233 | } 234 | } 235 | else 236 | { 237 | path = ""; 238 | } 239 | } 240 | } 241 | 242 | 243 | public static void ColoredHelpBox(Color c, string text, MessageType mt = MessageType.None) 244 | { 245 | PushGUIColor(c); 246 | EditorGUILayout.HelpBox(text, mt); 247 | PopGUIColor(); 248 | } 249 | 250 | public static void LayoutPushIndentLevel() 251 | { 252 | EditorGUILayout.BeginVertical(); 253 | EditorGUI.indentLevel += 1; 254 | } 255 | 256 | public static void LayoutPopIndentLevel() 257 | { 258 | EditorGUI.indentLevel -= 1; 259 | EditorGUILayout.EndVertical(); 260 | } 261 | 262 | 263 | 264 | public static string GetSelectedPath() 265 | { 266 | string path = ""; 267 | 268 | foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) 269 | { 270 | path = AssetDatabase.GetAssetPath(obj); 271 | if (!string.IsNullOrEmpty(path) && File.Exists(path)) 272 | { 273 | path = Path.GetDirectoryName(path); 274 | break; 275 | } 276 | } 277 | return path; 278 | } 279 | 280 | #endif 281 | } 282 | 283 | #if UNITY_EDITOR 284 | [CustomPropertyDrawer(typeof(ReadOnlyAttribute))] 285 | public class ReadOnlyDrawer : PropertyDrawer 286 | { 287 | public override float GetPropertyHeight(SerializedProperty property, 288 | GUIContent label) 289 | { 290 | return EditorGUI.GetPropertyHeight(property, label, true); 291 | } 292 | 293 | public override void OnGUI(Rect position, 294 | SerializedProperty property, 295 | GUIContent label) 296 | { 297 | GUI.enabled = false; 298 | EditorGUI.PropertyField(position, property, label, true); 299 | GUI.enabled = true; 300 | } 301 | } 302 | 303 | [CustomPropertyDrawer(typeof(AssetStringField))] 304 | public class AssetStringFieldDrawer : PropertyDrawer 305 | { 306 | UnityEngine.Object o = null; 307 | 308 | public override float GetPropertyHeight(SerializedProperty property, 309 | GUIContent label) 310 | { 311 | return EditorGUI.GetPropertyHeight(property, label, true); 312 | } 313 | 314 | public override void OnGUI(Rect position, 315 | SerializedProperty property, 316 | GUIContent label) 317 | { 318 | EditorGUI.BeginChangeCheck(); 319 | EditorGUI.ObjectField(position, property.name, o, (this.attribute as AssetStringField).typeOfObject, false); 320 | if (EditorGUI.EndChangeCheck()) 321 | { 322 | property.stringValue = AssetUtility.GetAssetPath(o); 323 | } 324 | } 325 | } 326 | 327 | [CustomPropertyDrawer(typeof(TypeNameAttribute))] 328 | public class TypeNameDrawer : PropertyDrawer 329 | { 330 | public UnityEngine.Object cacheObject; 331 | 332 | public override float GetPropertyHeight(SerializedProperty property, 333 | GUIContent label) 334 | { 335 | return EditorGUI.GetPropertyHeight(property, label, true) * 2; 336 | } 337 | 338 | public override void OnGUI(Rect position, 339 | SerializedProperty property, 340 | GUIContent label) 341 | { 342 | position.height /= 2; 343 | 344 | EditorGUI.BeginChangeCheck(); 345 | cacheObject = EditorGUI.ObjectField(position, "Type Obj", cacheObject, typeof(UnityEngine.Object), true); 346 | if (EditorGUI.EndChangeCheck()) 347 | { 348 | if (cacheObject != null) 349 | { 350 | if (cacheObject.GetType() == typeof(MonoScript)) 351 | { 352 | MonoScript script = cacheObject as MonoScript; 353 | property.stringValue = script.GetClass().FullName; 354 | } 355 | else 356 | { 357 | property.stringValue = cacheObject.GetType().FullName; 358 | } 359 | } 360 | } 361 | 362 | position.y += position.height; 363 | 364 | GUI.enabled = false; 365 | EditorGUI.LabelField(position, "Type Name", property.stringValue.Length > 0 ? property.stringValue : "(none)"); 366 | GUI.enabled = true; 367 | } 368 | } 369 | 370 | 371 | #endif 372 | 373 | } -------------------------------------------------------------------------------- /Assets/MagicaVoxel/Scripts/MVImporter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.IO; 4 | using System.Collections.Generic; 5 | 6 | [System.Serializable] 7 | public struct MVFaceCollection 8 | { 9 | public byte[,,] colorIndices; 10 | } 11 | 12 | [System.Serializable] 13 | public struct MVVoxel { 14 | public byte x, y, z, colorIndex; 15 | } 16 | 17 | [System.Serializable] 18 | public class MVVoxelChunk 19 | { 20 | // all voxels 21 | public byte[,,] voxels; 22 | 23 | // 6 dir, x+. x-, y+, y-, z+, z- 24 | public MVFaceCollection[] faces; 25 | 26 | public int x = 0, y = 0, z = 0; 27 | 28 | public int sizeX { get { return voxels.GetLength (0); } } 29 | public int sizeY { get { return voxels.GetLength (1); } } 30 | public int sizeZ { get { return voxels.GetLength (2); } } 31 | } 32 | 33 | public enum MVFaceDir 34 | { 35 | XPos = 0, 36 | XNeg = 1, 37 | YPos = 2, 38 | YNeg = 3, 39 | ZPos = 4, 40 | ZNeg = 5 41 | } 42 | 43 | [System.Serializable] 44 | public class MVMainChunk 45 | { 46 | public MVVoxelChunk voxelChunk; 47 | 48 | public Color[] palatte; 49 | 50 | public int sizeX, sizeY, sizeZ; 51 | 52 | public byte[] version; 53 | 54 | #region default_palatte 55 | public static Color[] defaultPalatte = new Color[] { 56 | new Color(1.000000f, 1.000000f, 1.000000f), 57 | new Color(1.000000f, 1.000000f, 0.800000f), 58 | new Color(1.000000f, 1.000000f, 0.600000f), 59 | new Color(1.000000f, 1.000000f, 0.400000f), 60 | new Color(1.000000f, 1.000000f, 0.200000f), 61 | new Color(1.000000f, 1.000000f, 0.000000f), 62 | new Color(1.000000f, 0.800000f, 1.000000f), 63 | new Color(1.000000f, 0.800000f, 0.800000f), 64 | new Color(1.000000f, 0.800000f, 0.600000f), 65 | new Color(1.000000f, 0.800000f, 0.400000f), 66 | new Color(1.000000f, 0.800000f, 0.200000f), 67 | new Color(1.000000f, 0.800000f, 0.000000f), 68 | new Color(1.000000f, 0.600000f, 1.000000f), 69 | new Color(1.000000f, 0.600000f, 0.800000f), 70 | new Color(1.000000f, 0.600000f, 0.600000f), 71 | new Color(1.000000f, 0.600000f, 0.400000f), 72 | new Color(1.000000f, 0.600000f, 0.200000f), 73 | new Color(1.000000f, 0.600000f, 0.000000f), 74 | new Color(1.000000f, 0.400000f, 1.000000f), 75 | new Color(1.000000f, 0.400000f, 0.800000f), 76 | new Color(1.000000f, 0.400000f, 0.600000f), 77 | new Color(1.000000f, 0.400000f, 0.400000f), 78 | new Color(1.000000f, 0.400000f, 0.200000f), 79 | new Color(1.000000f, 0.400000f, 0.000000f), 80 | new Color(1.000000f, 0.200000f, 1.000000f), 81 | new Color(1.000000f, 0.200000f, 0.800000f), 82 | new Color(1.000000f, 0.200000f, 0.600000f), 83 | new Color(1.000000f, 0.200000f, 0.400000f), 84 | new Color(1.000000f, 0.200000f, 0.200000f), 85 | new Color(1.000000f, 0.200000f, 0.000000f), 86 | new Color(1.000000f, 0.000000f, 1.000000f), 87 | new Color(1.000000f, 0.000000f, 0.800000f), 88 | new Color(1.000000f, 0.000000f, 0.600000f), 89 | new Color(1.000000f, 0.000000f, 0.400000f), 90 | new Color(1.000000f, 0.000000f, 0.200000f), 91 | new Color(1.000000f, 0.000000f, 0.000000f), 92 | new Color(0.800000f, 1.000000f, 1.000000f), 93 | new Color(0.800000f, 1.000000f, 0.800000f), 94 | new Color(0.800000f, 1.000000f, 0.600000f), 95 | new Color(0.800000f, 1.000000f, 0.400000f), 96 | new Color(0.800000f, 1.000000f, 0.200000f), 97 | new Color(0.800000f, 1.000000f, 0.000000f), 98 | new Color(0.800000f, 0.800000f, 1.000000f), 99 | new Color(0.800000f, 0.800000f, 0.800000f), 100 | new Color(0.800000f, 0.800000f, 0.600000f), 101 | new Color(0.800000f, 0.800000f, 0.400000f), 102 | new Color(0.800000f, 0.800000f, 0.200000f), 103 | new Color(0.800000f, 0.800000f, 0.000000f), 104 | new Color(0.800000f, 0.600000f, 1.000000f), 105 | new Color(0.800000f, 0.600000f, 0.800000f), 106 | new Color(0.800000f, 0.600000f, 0.600000f), 107 | new Color(0.800000f, 0.600000f, 0.400000f), 108 | new Color(0.800000f, 0.600000f, 0.200000f), 109 | new Color(0.800000f, 0.600000f, 0.000000f), 110 | new Color(0.800000f, 0.400000f, 1.000000f), 111 | new Color(0.800000f, 0.400000f, 0.800000f), 112 | new Color(0.800000f, 0.400000f, 0.600000f), 113 | new Color(0.800000f, 0.400000f, 0.400000f), 114 | new Color(0.800000f, 0.400000f, 0.200000f), 115 | new Color(0.800000f, 0.400000f, 0.000000f), 116 | new Color(0.800000f, 0.200000f, 1.000000f), 117 | new Color(0.800000f, 0.200000f, 0.800000f), 118 | new Color(0.800000f, 0.200000f, 0.600000f), 119 | new Color(0.800000f, 0.200000f, 0.400000f), 120 | new Color(0.800000f, 0.200000f, 0.200000f), 121 | new Color(0.800000f, 0.200000f, 0.000000f), 122 | new Color(0.800000f, 0.000000f, 1.000000f), 123 | new Color(0.800000f, 0.000000f, 0.800000f), 124 | new Color(0.800000f, 0.000000f, 0.600000f), 125 | new Color(0.800000f, 0.000000f, 0.400000f), 126 | new Color(0.800000f, 0.000000f, 0.200000f), 127 | new Color(0.800000f, 0.000000f, 0.000000f), 128 | new Color(0.600000f, 1.000000f, 1.000000f), 129 | new Color(0.600000f, 1.000000f, 0.800000f), 130 | new Color(0.600000f, 1.000000f, 0.600000f), 131 | new Color(0.600000f, 1.000000f, 0.400000f), 132 | new Color(0.600000f, 1.000000f, 0.200000f), 133 | new Color(0.600000f, 1.000000f, 0.000000f), 134 | new Color(0.600000f, 0.800000f, 1.000000f), 135 | new Color(0.600000f, 0.800000f, 0.800000f), 136 | new Color(0.600000f, 0.800000f, 0.600000f), 137 | new Color(0.600000f, 0.800000f, 0.400000f), 138 | new Color(0.600000f, 0.800000f, 0.200000f), 139 | new Color(0.600000f, 0.800000f, 0.000000f), 140 | new Color(0.600000f, 0.600000f, 1.000000f), 141 | new Color(0.600000f, 0.600000f, 0.800000f), 142 | new Color(0.600000f, 0.600000f, 0.600000f), 143 | new Color(0.600000f, 0.600000f, 0.400000f), 144 | new Color(0.600000f, 0.600000f, 0.200000f), 145 | new Color(0.600000f, 0.600000f, 0.000000f), 146 | new Color(0.600000f, 0.400000f, 1.000000f), 147 | new Color(0.600000f, 0.400000f, 0.800000f), 148 | new Color(0.600000f, 0.400000f, 0.600000f), 149 | new Color(0.600000f, 0.400000f, 0.400000f), 150 | new Color(0.600000f, 0.400000f, 0.200000f), 151 | new Color(0.600000f, 0.400000f, 0.000000f), 152 | new Color(0.600000f, 0.200000f, 1.000000f), 153 | new Color(0.600000f, 0.200000f, 0.800000f), 154 | new Color(0.600000f, 0.200000f, 0.600000f), 155 | new Color(0.600000f, 0.200000f, 0.400000f), 156 | new Color(0.600000f, 0.200000f, 0.200000f), 157 | new Color(0.600000f, 0.200000f, 0.000000f), 158 | new Color(0.600000f, 0.000000f, 1.000000f), 159 | new Color(0.600000f, 0.000000f, 0.800000f), 160 | new Color(0.600000f, 0.000000f, 0.600000f), 161 | new Color(0.600000f, 0.000000f, 0.400000f), 162 | new Color(0.600000f, 0.000000f, 0.200000f), 163 | new Color(0.600000f, 0.000000f, 0.000000f), 164 | new Color(0.400000f, 1.000000f, 1.000000f), 165 | new Color(0.400000f, 1.000000f, 0.800000f), 166 | new Color(0.400000f, 1.000000f, 0.600000f), 167 | new Color(0.400000f, 1.000000f, 0.400000f), 168 | new Color(0.400000f, 1.000000f, 0.200000f), 169 | new Color(0.400000f, 1.000000f, 0.000000f), 170 | new Color(0.400000f, 0.800000f, 1.000000f), 171 | new Color(0.400000f, 0.800000f, 0.800000f), 172 | new Color(0.400000f, 0.800000f, 0.600000f), 173 | new Color(0.400000f, 0.800000f, 0.400000f), 174 | new Color(0.400000f, 0.800000f, 0.200000f), 175 | new Color(0.400000f, 0.800000f, 0.000000f), 176 | new Color(0.400000f, 0.600000f, 1.000000f), 177 | new Color(0.400000f, 0.600000f, 0.800000f), 178 | new Color(0.400000f, 0.600000f, 0.600000f), 179 | new Color(0.400000f, 0.600000f, 0.400000f), 180 | new Color(0.400000f, 0.600000f, 0.200000f), 181 | new Color(0.400000f, 0.600000f, 0.000000f), 182 | new Color(0.400000f, 0.400000f, 1.000000f), 183 | new Color(0.400000f, 0.400000f, 0.800000f), 184 | new Color(0.400000f, 0.400000f, 0.600000f), 185 | new Color(0.400000f, 0.400000f, 0.400000f), 186 | new Color(0.400000f, 0.400000f, 0.200000f), 187 | new Color(0.400000f, 0.400000f, 0.000000f), 188 | new Color(0.400000f, 0.200000f, 1.000000f), 189 | new Color(0.400000f, 0.200000f, 0.800000f), 190 | new Color(0.400000f, 0.200000f, 0.600000f), 191 | new Color(0.400000f, 0.200000f, 0.400000f), 192 | new Color(0.400000f, 0.200000f, 0.200000f), 193 | new Color(0.400000f, 0.200000f, 0.000000f), 194 | new Color(0.400000f, 0.000000f, 1.000000f), 195 | new Color(0.400000f, 0.000000f, 0.800000f), 196 | new Color(0.400000f, 0.000000f, 0.600000f), 197 | new Color(0.400000f, 0.000000f, 0.400000f), 198 | new Color(0.400000f, 0.000000f, 0.200000f), 199 | new Color(0.400000f, 0.000000f, 0.000000f), 200 | new Color(0.200000f, 1.000000f, 1.000000f), 201 | new Color(0.200000f, 1.000000f, 0.800000f), 202 | new Color(0.200000f, 1.000000f, 0.600000f), 203 | new Color(0.200000f, 1.000000f, 0.400000f), 204 | new Color(0.200000f, 1.000000f, 0.200000f), 205 | new Color(0.200000f, 1.000000f, 0.000000f), 206 | new Color(0.200000f, 0.800000f, 1.000000f), 207 | new Color(0.200000f, 0.800000f, 0.800000f), 208 | new Color(0.200000f, 0.800000f, 0.600000f), 209 | new Color(0.200000f, 0.800000f, 0.400000f), 210 | new Color(0.200000f, 0.800000f, 0.200000f), 211 | new Color(0.200000f, 0.800000f, 0.000000f), 212 | new Color(0.200000f, 0.600000f, 1.000000f), 213 | new Color(0.200000f, 0.600000f, 0.800000f), 214 | new Color(0.200000f, 0.600000f, 0.600000f), 215 | new Color(0.200000f, 0.600000f, 0.400000f), 216 | new Color(0.200000f, 0.600000f, 0.200000f), 217 | new Color(0.200000f, 0.600000f, 0.000000f), 218 | new Color(0.200000f, 0.400000f, 1.000000f), 219 | new Color(0.200000f, 0.400000f, 0.800000f), 220 | new Color(0.200000f, 0.400000f, 0.600000f), 221 | new Color(0.200000f, 0.400000f, 0.400000f), 222 | new Color(0.200000f, 0.400000f, 0.200000f), 223 | new Color(0.200000f, 0.400000f, 0.000000f), 224 | new Color(0.200000f, 0.200000f, 1.000000f), 225 | new Color(0.200000f, 0.200000f, 0.800000f), 226 | new Color(0.200000f, 0.200000f, 0.600000f), 227 | new Color(0.200000f, 0.200000f, 0.400000f), 228 | new Color(0.200000f, 0.200000f, 0.200000f), 229 | new Color(0.200000f, 0.200000f, 0.000000f), 230 | new Color(0.200000f, 0.000000f, 1.000000f), 231 | new Color(0.200000f, 0.000000f, 0.800000f), 232 | new Color(0.200000f, 0.000000f, 0.600000f), 233 | new Color(0.200000f, 0.000000f, 0.400000f), 234 | new Color(0.200000f, 0.000000f, 0.200000f), 235 | new Color(0.200000f, 0.000000f, 0.000000f), 236 | new Color(0.000000f, 1.000000f, 1.000000f), 237 | new Color(0.000000f, 1.000000f, 0.800000f), 238 | new Color(0.000000f, 1.000000f, 0.600000f), 239 | new Color(0.000000f, 1.000000f, 0.400000f), 240 | new Color(0.000000f, 1.000000f, 0.200000f), 241 | new Color(0.000000f, 1.000000f, 0.000000f), 242 | new Color(0.000000f, 0.800000f, 1.000000f), 243 | new Color(0.000000f, 0.800000f, 0.800000f), 244 | new Color(0.000000f, 0.800000f, 0.600000f), 245 | new Color(0.000000f, 0.800000f, 0.400000f), 246 | new Color(0.000000f, 0.800000f, 0.200000f), 247 | new Color(0.000000f, 0.800000f, 0.000000f), 248 | new Color(0.000000f, 0.600000f, 1.000000f), 249 | new Color(0.000000f, 0.600000f, 0.800000f), 250 | new Color(0.000000f, 0.600000f, 0.600000f), 251 | new Color(0.000000f, 0.600000f, 0.400000f), 252 | new Color(0.000000f, 0.600000f, 0.200000f), 253 | new Color(0.000000f, 0.600000f, 0.000000f), 254 | new Color(0.000000f, 0.400000f, 1.000000f), 255 | new Color(0.000000f, 0.400000f, 0.800000f), 256 | new Color(0.000000f, 0.400000f, 0.600000f), 257 | new Color(0.000000f, 0.400000f, 0.400000f), 258 | new Color(0.000000f, 0.400000f, 0.200000f), 259 | new Color(0.000000f, 0.400000f, 0.000000f), 260 | new Color(0.000000f, 0.200000f, 1.000000f), 261 | new Color(0.000000f, 0.200000f, 0.800000f), 262 | new Color(0.000000f, 0.200000f, 0.600000f), 263 | new Color(0.000000f, 0.200000f, 0.400000f), 264 | new Color(0.000000f, 0.200000f, 0.200000f), 265 | new Color(0.000000f, 0.200000f, 0.000000f), 266 | new Color(0.000000f, 0.000000f, 1.000000f), 267 | new Color(0.000000f, 0.000000f, 0.800000f), 268 | new Color(0.000000f, 0.000000f, 0.600000f), 269 | new Color(0.000000f, 0.000000f, 0.400000f), 270 | new Color(0.000000f, 0.000000f, 0.200000f), 271 | new Color(0.933333f, 0.000000f, 0.000000f), 272 | new Color(0.866667f, 0.000000f, 0.000000f), 273 | new Color(0.733333f, 0.000000f, 0.000000f), 274 | new Color(0.666667f, 0.000000f, 0.000000f), 275 | new Color(0.533333f, 0.000000f, 0.000000f), 276 | new Color(0.466667f, 0.000000f, 0.000000f), 277 | new Color(0.333333f, 0.000000f, 0.000000f), 278 | new Color(0.266667f, 0.000000f, 0.000000f), 279 | new Color(0.133333f, 0.000000f, 0.000000f), 280 | new Color(0.066667f, 0.000000f, 0.000000f), 281 | new Color(0.000000f, 0.933333f, 0.000000f), 282 | new Color(0.000000f, 0.866667f, 0.000000f), 283 | new Color(0.000000f, 0.733333f, 0.000000f), 284 | new Color(0.000000f, 0.666667f, 0.000000f), 285 | new Color(0.000000f, 0.533333f, 0.000000f), 286 | new Color(0.000000f, 0.466667f, 0.000000f), 287 | new Color(0.000000f, 0.333333f, 0.000000f), 288 | new Color(0.000000f, 0.266667f, 0.000000f), 289 | new Color(0.000000f, 0.133333f, 0.000000f), 290 | new Color(0.000000f, 0.066667f, 0.000000f), 291 | new Color(0.000000f, 0.000000f, 0.933333f), 292 | new Color(0.000000f, 0.000000f, 0.866667f), 293 | new Color(0.000000f, 0.000000f, 0.733333f), 294 | new Color(0.000000f, 0.000000f, 0.666667f), 295 | new Color(0.000000f, 0.000000f, 0.533333f), 296 | new Color(0.000000f, 0.000000f, 0.466667f), 297 | new Color(0.000000f, 0.000000f, 0.333333f), 298 | new Color(0.000000f, 0.000000f, 0.266667f), 299 | new Color(0.000000f, 0.000000f, 0.133333f), 300 | new Color(0.000000f, 0.000000f, 0.066667f), 301 | new Color(0.933333f, 0.933333f, 0.933333f), 302 | new Color(0.866667f, 0.866667f, 0.866667f), 303 | new Color(0.733333f, 0.733333f, 0.733333f), 304 | new Color(0.666667f, 0.666667f, 0.666667f), 305 | new Color(0.533333f, 0.533333f, 0.533333f), 306 | new Color(0.466667f, 0.466667f, 0.466667f), 307 | new Color(0.333333f, 0.333333f, 0.333333f), 308 | new Color(0.266667f, 0.266667f, 0.266667f), 309 | new Color(0.133333f, 0.133333f, 0.133333f), 310 | new Color(0.066667f, 0.066667f, 0.066667f), 311 | new Color(0.000000f, 0.000000f, 0.000000f) 312 | }; 313 | #endregion 314 | 315 | public Texture2D PaletteToTexture() 316 | { 317 | if (palatte == null) 318 | return null; 319 | 320 | Texture2D tex = new Texture2D(palatte.Length, 1, TextureFormat.RGBA32, false); 321 | tex.SetPixels(palatte); 322 | tex.Apply(false); 323 | tex.filterMode = FilterMode.Point; 324 | tex.wrapMode = TextureWrapMode.Clamp; 325 | return tex; 326 | } 327 | } 328 | 329 | public static class MVImporter 330 | { 331 | public static Material DefaultMaterial { 332 | get { 333 | return new Material (Shader.Find ("Diffuse")); 334 | } 335 | } 336 | 337 | public static MVMainChunk LoadVOXFromData(byte[] data, bool generateFaces = true) { 338 | using (MemoryStream ms = new MemoryStream (data)) { 339 | using (BinaryReader br = new BinaryReader (ms)) { 340 | MVMainChunk mainChunk = new MVMainChunk (); 341 | 342 | // "VOX " 343 | br.ReadInt32 (); 344 | // "VERSION " 345 | mainChunk.version = br.ReadBytes(4); 346 | 347 | byte[] chunkId = br.ReadBytes (4); 348 | if (chunkId [0] != 'M' || 349 | chunkId [1] != 'A' || 350 | chunkId [2] != 'I' || 351 | chunkId [3] != 'N') { 352 | Debug.LogError ("[MVImport] Invalid MainChunk ID, main chunk expected"); 353 | return null; 354 | } 355 | 356 | int chunkSize = br.ReadInt32 (); 357 | int childrenSize = br.ReadInt32 (); 358 | 359 | // main chunk should have nothing... skip 360 | br.ReadBytes (chunkSize); 361 | 362 | int readSize = 0; 363 | while (readSize < childrenSize) { 364 | 365 | chunkId = br.ReadBytes (4); 366 | 367 | if (chunkId [0] == 'P' && 368 | chunkId [1] == 'A' && 369 | chunkId [2] == 'C' && 370 | chunkId [3] == 'K') { 371 | 372 | int chunkContentBytes = br.ReadInt32 (); 373 | int childrenBytes = br.ReadInt32 (); 374 | 375 | br.ReadInt32 (); 376 | 377 | readSize += chunkContentBytes + childrenBytes + 4 * 3; 378 | } 379 | else if (chunkId [0] == 'S' && 380 | chunkId [1] == 'I' && 381 | chunkId [2] == 'Z' && 382 | chunkId [3] == 'E') { 383 | 384 | readSize += ReadSizeChunk (br, mainChunk); 385 | 386 | } else if (chunkId [0] == 'X' && 387 | chunkId [1] == 'Y' && 388 | chunkId [2] == 'Z' && 389 | chunkId [3] == 'I') { 390 | 391 | readSize += ReadVoxelChunk (br, mainChunk.voxelChunk); 392 | 393 | } else if (chunkId [0] == 'R' && 394 | chunkId [1] == 'G' && 395 | chunkId [2] == 'B' && 396 | chunkId [3] == 'A') { 397 | 398 | mainChunk.palatte = new Color[256]; 399 | readSize += ReadPalattee (br, mainChunk.palatte); 400 | 401 | } 402 | else { 403 | Debug.LogWarning ("[MVImport] Chunk ID not recognized, got " + System.Text.Encoding.ASCII.GetString(chunkId)); 404 | int chunkContentBytes = br.ReadInt32(); 405 | int childrenBytes = br.ReadInt32(); 406 | br.ReadBytes(chunkContentBytes + childrenBytes); 407 | readSize += chunkContentBytes + childrenBytes + 12; 408 | } 409 | } 410 | 411 | if (generateFaces) 412 | GenerateFaces(mainChunk.voxelChunk); 413 | 414 | if (mainChunk.palatte == null) 415 | mainChunk.palatte = MVMainChunk.defaultPalatte; 416 | 417 | return mainChunk; 418 | } 419 | } 420 | } 421 | 422 | public static MVMainChunk LoadVOX(string path, bool generateFaces = true) 423 | { 424 | byte[] bytes = File.ReadAllBytes (path); 425 | if (bytes [0] != 'V' || 426 | bytes [1] != 'O' || 427 | bytes [2] != 'X' || 428 | bytes [3] != ' ') { 429 | Debug.LogError ("Invalid VOX file, magic number mismatch"); 430 | return null; 431 | } 432 | 433 | return LoadVOXFromData (bytes, generateFaces); 434 | } 435 | 436 | public static void GenerateFaces(MVVoxelChunk voxelChunk) 437 | { 438 | voxelChunk.faces = new MVFaceCollection[6]; 439 | for (int i = 0; i < 6; ++i) { 440 | voxelChunk.faces [i].colorIndices = new byte[voxelChunk.sizeX, voxelChunk.sizeY, voxelChunk.sizeZ]; 441 | } 442 | 443 | for (int x = 0; x < voxelChunk.sizeX; ++x) { 444 | for (int y = 0; y < voxelChunk.sizeY; ++y) { 445 | for (int z = 0; z < voxelChunk.sizeZ; ++z) { 446 | 447 | // left right 448 | if (x == 0 || voxelChunk.voxels[x - 1, y, z] == 0) 449 | voxelChunk.faces [(int)MVFaceDir.XNeg].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; 450 | 451 | if (x == voxelChunk.sizeX - 1 || voxelChunk.voxels[x + 1, y, z] == 0) 452 | voxelChunk.faces [(int)MVFaceDir.XPos].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; 453 | 454 | // up down 455 | if (y == 0 || voxelChunk.voxels[x, y - 1, z] == 0) 456 | voxelChunk.faces [(int)MVFaceDir.YNeg].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; 457 | 458 | if (y == voxelChunk.sizeY - 1 || voxelChunk.voxels[x, y + 1, z] == 0) 459 | voxelChunk.faces [(int)MVFaceDir.YPos].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; 460 | 461 | // forward backward 462 | if (z == 0 || voxelChunk.voxels[x, y, z - 1] == 0) 463 | voxelChunk.faces [(int)MVFaceDir.ZNeg].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; 464 | 465 | if (z == voxelChunk.sizeZ - 1 || voxelChunk.voxels[x, y, z + 1] == 0) 466 | voxelChunk.faces [(int)MVFaceDir.ZPos].colorIndices [x, y, z] = voxelChunk.voxels [x, y, z]; 467 | } 468 | } 469 | } 470 | } 471 | 472 | static int ReadSizeChunk(BinaryReader br, MVMainChunk mainChunk) 473 | { 474 | int chunkSize = br.ReadInt32 (); 475 | int childrenSize = br.ReadInt32 (); 476 | 477 | mainChunk.sizeX = br.ReadInt32 (); 478 | mainChunk.sizeZ = br.ReadInt32 (); 479 | mainChunk.sizeY = br.ReadInt32 (); 480 | 481 | mainChunk.voxelChunk = new MVVoxelChunk (); 482 | mainChunk.voxelChunk.voxels = new byte[mainChunk.sizeX, mainChunk.sizeY, mainChunk.sizeZ]; 483 | 484 | Debug.Log (string.Format ("[MVImporter] Voxel Size {0}x{1}x{2}", mainChunk.sizeX, mainChunk.sizeY, mainChunk.sizeZ)); 485 | 486 | if (childrenSize > 0) { 487 | br.ReadBytes (childrenSize); 488 | Debug.LogWarning ("[MVImporter] Nested chunk not supported"); 489 | } 490 | 491 | return chunkSize + childrenSize + 4 * 3; 492 | } 493 | 494 | static int ReadVoxelChunk(BinaryReader br, MVVoxelChunk chunk) 495 | { 496 | int chunkSize = br.ReadInt32 (); 497 | int childrenSize = br.ReadInt32 (); 498 | int numVoxels = br.ReadInt32 (); 499 | 500 | for (int i = 0; i < numVoxels; ++i) { 501 | int x = (int)br.ReadByte (); 502 | int z = (int)br.ReadByte (); 503 | int y = (int)br.ReadByte (); 504 | 505 | chunk.voxels [x, y, z] = br.ReadByte(); 506 | } 507 | 508 | if (childrenSize > 0) { 509 | br.ReadBytes (childrenSize); 510 | Debug.LogWarning ("[MVImporter] Nested chunk not supported"); 511 | } 512 | 513 | return chunkSize + childrenSize + 4 * 3; 514 | } 515 | 516 | static int ReadPalattee(BinaryReader br, Color[] colors) 517 | { 518 | int chunkSize = br.ReadInt32 (); 519 | int childrenSize = br.ReadInt32 (); 520 | 521 | for (int i = 0; i < 256; ++i) { 522 | colors [i] = new Color ((float)br.ReadByte () / 255.0f, (float)br.ReadByte () / 255.0f, (float)br.ReadByte () / 255.0f, (float)br.ReadByte () / 255.0f); 523 | } 524 | 525 | if (childrenSize > 0) { 526 | br.ReadBytes (childrenSize); 527 | Debug.LogWarning ("[MVImporter] Nested chunk not supported"); 528 | } 529 | 530 | return chunkSize + childrenSize + 4 * 3; 531 | } 532 | 533 | public static Mesh[] CreateMeshes(MVMainChunk chunk, float sizePerVox) 534 | { 535 | return CreateMeshesFromChunk(chunk.voxelChunk, chunk.palatte, sizePerVox); 536 | } 537 | 538 | public static GameObject[] CreateVoxelGameObjects(MVMainChunk chunk, Transform parent, Material mat, float sizePerVox) 539 | { 540 | return CreateVoxelGameObjectsForChunk(chunk.voxelChunk, chunk.palatte, parent, mat, sizePerVox); 541 | } 542 | 543 | public static GameObject[] CreateVoxelGameObjects(MVMainChunk chunk, Transform parent, Material mat, float sizePerVox, Vector3 origin) 544 | { 545 | return CreateVoxelGameObjectsForChunk(chunk.voxelChunk, chunk.palatte, parent, mat, sizePerVox, origin); 546 | } 547 | 548 | public static GameObject[] CreateIndividualVoxelGameObjects(MVMainChunk chunk, Transform parent, Material mat, float sizePerVox) 549 | { 550 | return CreateIndividualVoxelGameObjectsForChunk(chunk.voxelChunk, chunk.palatte, parent, mat, sizePerVox); 551 | } 552 | 553 | public static GameObject[] CreateIndividualVoxelGameObjects(MVMainChunk chunk, Transform parent, Material mat, float sizePerVox, Vector3 origin) 554 | { 555 | return CreateIndividualVoxelGameObjectsForChunk(chunk.voxelChunk, chunk.palatte, parent, mat, sizePerVox, origin); 556 | } 557 | 558 | public static Mesh CubeMeshWithColor(float size, Color c, int cidx) { 559 | float halfSize = size / 2; 560 | 561 | Vector3[] verts = new Vector3[] { 562 | new Vector3 (-halfSize, -halfSize, -halfSize), 563 | new Vector3 (-halfSize, halfSize, -halfSize), 564 | new Vector3 (halfSize, halfSize, -halfSize), 565 | new Vector3 (halfSize, -halfSize, -halfSize), 566 | new Vector3 (halfSize, -halfSize, halfSize), 567 | new Vector3 (halfSize, halfSize, halfSize), 568 | new Vector3 (-halfSize, halfSize, halfSize), 569 | new Vector3 (-halfSize, -halfSize, halfSize) 570 | }; 571 | 572 | int[] indicies = new int[] { 573 | 0, 1, 2, // 1 574 | 0, 2, 3, 575 | 3, 2, 5, // 2 576 | 3, 5, 4, 577 | 5, 2, 1, // 3 578 | 5, 1, 6, 579 | 3, 4, 7, // 4 580 | 3, 7, 0, 581 | 0, 7, 6, // 5 582 | 0, 6, 1, 583 | 4, 5, 6, // 6 584 | 4, 6, 7 585 | }; 586 | 587 | Color[] colors = new Color[] { 588 | c, 589 | c, 590 | c, 591 | c, 592 | c, 593 | c, 594 | c, 595 | c 596 | }; 597 | 598 | Vector2[] uvs = new Vector2[] { 599 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 600 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 601 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 602 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 603 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 604 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 605 | new Vector2((cidx - 0.5f) / 256f, 0.5f), 606 | new Vector2((cidx - 0.5f) / 256f, 0.5f) 607 | }; 608 | 609 | Mesh mesh = new Mesh (); 610 | mesh.vertices = verts; 611 | mesh.uv = uvs; 612 | mesh.colors = colors; 613 | mesh.triangles = indicies; 614 | mesh.RecalculateNormals (); 615 | return mesh; 616 | } 617 | 618 | 619 | public static GameObject CreateGameObject(Transform parent, Vector3 pos, string name, Mesh mesh, Material mat) { 620 | GameObject go = new GameObject (); 621 | go.name = name; 622 | go.transform.SetParent (parent); 623 | go.transform.localPosition = pos; 624 | 625 | MeshFilter mf = go.AddComponent (); 626 | mf.mesh = mesh; 627 | 628 | MeshRenderer mr = go.AddComponent (); 629 | mr.material = mat; 630 | 631 | return go; 632 | } 633 | 634 | public static GameObject[] CreateIndividualVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox) 635 | { 636 | Vector3 origin = new Vector3( 637 | (float)chunk.sizeX / 2, 638 | (float)chunk.sizeY / 2, 639 | (float)chunk.sizeZ / 2); 640 | 641 | return CreateIndividualVoxelGameObjectsForChunk(chunk, palatte, parent, mat, sizePerVox, origin); 642 | } 643 | 644 | public static GameObject[] CreateIndividualVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, Vector3 origin) { 645 | List result = new List (); 646 | 647 | for (int x = 0; x < chunk.sizeX; ++x) { 648 | for (int y = 0; y < chunk.sizeY; ++y) { 649 | for (int z = 0; z < chunk.sizeZ; ++z) { 650 | 651 | if (chunk.voxels [x, y, z] != 0) { 652 | float px = (x - origin.x + 0.5f) * sizePerVox, py = (y - origin.y + 0.5f) * sizePerVox, pz = (z - origin.z + 0.5f) * sizePerVox; 653 | int cidx = chunk.voxels[x, y, z]; 654 | 655 | GameObject go = CreateGameObject ( 656 | parent, 657 | new Vector3 (px, py, pz), 658 | string.Format ("Voxel ({0}, {1}, {2})", x, y, z), 659 | MVImporter.CubeMeshWithColor (sizePerVox, palatte[cidx - 1], cidx), 660 | mat); 661 | 662 | #if UNITY_EDITOR 663 | MVVoxModelVoxel v = go.AddComponent (); 664 | v.voxel = new MVVoxel () { x = (byte)x, y = (byte)y, z = (byte)z, colorIndex = chunk.voxels [x, y, z] }; 665 | #endif 666 | 667 | result.Add (go); 668 | } 669 | } 670 | } 671 | } 672 | 673 | return result.ToArray(); 674 | } 675 | 676 | public static GameObject[] CreateVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox) 677 | { 678 | Vector3 origin = new Vector3( 679 | (float)chunk.sizeX / 2, 680 | (float)chunk.sizeY / 2, 681 | (float)chunk.sizeZ / 2); 682 | 683 | return CreateVoxelGameObjectsForChunk(chunk, palatte, parent, mat, sizePerVox, origin); 684 | } 685 | 686 | public static GameObject[] CreateVoxelGameObjectsForChunk(MVVoxelChunk chunk, Color[] palatte, Transform parent, Material mat, float sizePerVox, Vector3 origin) { 687 | List result = new List (); 688 | 689 | Mesh[] meshes = CreateMeshesFromChunk (chunk, palatte, sizePerVox, origin); 690 | 691 | int index = 0; 692 | foreach (Mesh mesh in meshes) { 693 | GameObject go = new GameObject (); 694 | go.name = string.Format ("VoxelMesh ({0})", index); 695 | go.transform.SetParent (parent); 696 | go.transform.localPosition = Vector3.zero; 697 | go.transform.localRotation = Quaternion.Euler (Vector3.zero); 698 | go.transform.localScale = Vector3.one; 699 | 700 | MeshFilter mf = go.AddComponent (); 701 | mf.mesh = mesh; 702 | 703 | MeshRenderer mr = go.AddComponent (); 704 | mr.material = mat; 705 | 706 | go.AddComponent (); 707 | result.Add (go); 708 | index++; 709 | } 710 | 711 | return result.ToArray (); 712 | } 713 | 714 | public static Mesh[] CreateMeshesFromChunk(MVVoxelChunk chunk, Color[] palatte, float sizePerVox) 715 | { 716 | Vector3 origin = new Vector3( 717 | (float)chunk.sizeX / 2, 718 | (float)chunk.sizeY / 2, 719 | (float)chunk.sizeZ / 2); 720 | 721 | return CreateMeshesFromChunk(chunk, palatte, sizePerVox, origin); 722 | } 723 | 724 | public static Mesh[] CreateMeshesFromChunk(MVVoxelChunk chunk, Color[] palatte, float sizePerVox, Vector3 origin) 725 | { 726 | List verts = new List (); 727 | List normals = new List (); 728 | List colors = new List (); 729 | List indicies = new List (); 730 | List uvs = new List(); 731 | 732 | Vector3[] faceNormals = new Vector3[] { 733 | Vector3.right, 734 | Vector3.left, 735 | Vector3.up, 736 | Vector3.down, 737 | Vector3.forward, 738 | Vector3.back 739 | }; 740 | 741 | List result = new List (); 742 | 743 | if (sizePerVox <= 0.0f) 744 | sizePerVox = 0.1f; 745 | 746 | float halfSize = sizePerVox / 2.0f; 747 | 748 | int currentQuadCount = 0; 749 | int totalQuadCount = 0; 750 | for (int f = 0; f < 6; ++f) { 751 | for (int x = 0; x < chunk.sizeX; ++x) { 752 | for (int y = 0; y < chunk.sizeY; ++y) { 753 | for (int z = 0; z < chunk.sizeZ; ++z) { 754 | 755 | int cidx = chunk.faces [f].colorIndices [x, y, z]; 756 | 757 | 758 | if (cidx != 0) { 759 | float px = (x - origin.x + 0.5f) * sizePerVox, py = (y - origin.y + 0.5f) * sizePerVox, pz = (z - origin.z + 0.5f) * sizePerVox; 760 | 761 | int rx = x, ry = y, rz = z; 762 | switch (f) { 763 | case 1: 764 | case 0: 765 | { 766 | ry = y + 1; 767 | while (ry < chunk.sizeY && chunk.faces [f].colorIndices [x, ry, z] == cidx) 768 | ry++; 769 | ry--; 770 | 771 | rz = z + 1; 772 | while (rz < chunk.sizeZ) { 773 | bool inc = true; 774 | for (int k = y; k <= ry; ++k) { 775 | inc = inc & (chunk.faces [f].colorIndices [x, k, rz] == cidx); 776 | } 777 | 778 | if (inc) 779 | rz++; 780 | else 781 | break; 782 | } 783 | rz--; 784 | break; 785 | } 786 | 787 | case 3: 788 | case 2: 789 | { 790 | rx = x + 1; 791 | while (rx < chunk.sizeX && chunk.faces [f].colorIndices [rx, y, z] == cidx) 792 | rx++; 793 | rx--; 794 | 795 | rz = z + 1; 796 | while (rz < chunk.sizeZ) { 797 | bool inc = true; 798 | for (int k = x; k <= rx; ++k) { 799 | inc = inc & (chunk.faces [f].colorIndices [k, y, rz] == cidx); 800 | } 801 | 802 | if (inc) 803 | rz++; 804 | else 805 | break; 806 | } 807 | rz--; 808 | break; 809 | } 810 | 811 | case 5: 812 | case 4: 813 | { 814 | rx = x + 1; 815 | while (rx < chunk.sizeX && chunk.faces [f].colorIndices [rx, y, z] == cidx) 816 | rx++; 817 | rx--; 818 | 819 | ry = y + 1; 820 | while (ry < chunk.sizeY) { 821 | bool inc = true; 822 | for (int k = x; k <= rx; ++k) { 823 | inc = inc & (chunk.faces [f].colorIndices [k, ry, z] == cidx); 824 | } 825 | 826 | if (inc) 827 | ry++; 828 | else 829 | break; 830 | } 831 | ry--; 832 | break; 833 | } 834 | } 835 | 836 | 837 | for (int kx = x; kx <= rx; ++kx) { 838 | for (int ky = y; ky <= ry; ++ky) { 839 | for (int kz = z; kz <= rz; ++kz) { 840 | if(kx != x || ky != y || kz != z) 841 | chunk.faces [f].colorIndices [kx, ky, kz] = 0; 842 | } 843 | } 844 | } 845 | 846 | int dx = rx - x; 847 | int dy = ry - y; 848 | int dz = rz - z; 849 | 850 | switch (f) { 851 | case 1: 852 | verts.Add (new Vector3 (px - halfSize, py - halfSize, pz - halfSize)); 853 | verts.Add (new Vector3 (px - halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); 854 | verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz + halfSize + sizePerVox * dz)); 855 | verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); 856 | break; 857 | 858 | case 0: 859 | verts.Add (new Vector3 (px + halfSize, py - halfSize, pz - halfSize)); 860 | verts.Add (new Vector3 (px + halfSize, py + halfSize + sizePerVox * dy, pz - halfSize)); 861 | verts.Add (new Vector3 (px + halfSize, py + halfSize + sizePerVox * dy, pz + halfSize + sizePerVox * dz)); 862 | verts.Add (new Vector3 (px + halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); 863 | break; 864 | 865 | case 3: 866 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz - halfSize)); 867 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz + halfSize + sizePerVox * dz)); 868 | verts.Add (new Vector3 (px - halfSize, py - halfSize, pz + halfSize + sizePerVox * dz)); 869 | verts.Add (new Vector3 (px - halfSize, py - halfSize, pz - halfSize)); 870 | break; 871 | 872 | case 2: 873 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize, pz - halfSize)); 874 | verts.Add (new Vector3 (px - halfSize, py + halfSize, pz - halfSize)); 875 | verts.Add (new Vector3 (px - halfSize, py + halfSize, pz + halfSize + sizePerVox * dz)); 876 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize, pz + halfSize + sizePerVox * dz)); 877 | break; 878 | 879 | case 5: 880 | verts.Add (new Vector3 (px - halfSize , py + halfSize + sizePerVox * dy , pz - halfSize)); 881 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx , py + halfSize + sizePerVox * dy , pz - halfSize)); 882 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx , py - halfSize , pz - halfSize)); 883 | verts.Add (new Vector3 (px - halfSize , py - halfSize , pz - halfSize)); 884 | break; 885 | 886 | case 4: 887 | verts.Add (new Vector3 (px - halfSize, py + halfSize + sizePerVox * dy, pz + halfSize)); 888 | verts.Add (new Vector3 (px - halfSize, py - halfSize, pz + halfSize)); 889 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py - halfSize, pz + halfSize)); 890 | verts.Add (new Vector3 (px + halfSize + sizePerVox * dx, py + halfSize + sizePerVox * dy, pz + halfSize)); 891 | break; 892 | } 893 | 894 | normals.Add (faceNormals [f]); 895 | normals.Add (faceNormals [f]); 896 | normals.Add (faceNormals [f]); 897 | normals.Add (faceNormals [f]); 898 | 899 | // color index starts with 1 900 | Color c = palatte [cidx - 1]; 901 | 902 | colors.Add (c); 903 | colors.Add (c); 904 | colors.Add (c); 905 | colors.Add (c); 906 | 907 | indicies.Add (currentQuadCount * 4 + 0); 908 | indicies.Add (currentQuadCount * 4 + 1); 909 | indicies.Add (currentQuadCount * 4 + 2); 910 | indicies.Add (currentQuadCount * 4 + 2); 911 | indicies.Add (currentQuadCount * 4 + 3); 912 | indicies.Add (currentQuadCount * 4 + 0); 913 | 914 | 915 | uvs.Add(new Vector2((cidx - 1f) / 256f , 0f)); 916 | uvs.Add(new Vector2(cidx / 256f , 0f)); 917 | uvs.Add(new Vector2(cidx / 256f , 1f)); 918 | uvs.Add(new Vector2((cidx - 1f) / 256f , 1f)); 919 | 920 | currentQuadCount += 1; 921 | 922 | // u3d max 923 | if (verts.Count + 4 >= 65000) { 924 | Mesh mesh = new Mesh (); 925 | mesh.vertices = verts.ToArray(); 926 | mesh.colors = colors.ToArray(); 927 | mesh.normals = normals.ToArray(); 928 | mesh.triangles = indicies.ToArray (); 929 | 930 | mesh.uv = uvs.ToArray(); 931 | 932 | result.Add (mesh); 933 | 934 | uvs.Clear(); 935 | verts.Clear (); 936 | colors.Clear (); 937 | normals.Clear (); 938 | indicies.Clear (); 939 | 940 | totalQuadCount += currentQuadCount; 941 | currentQuadCount = 0; 942 | } 943 | } 944 | } 945 | } 946 | } 947 | } 948 | 949 | if (verts.Count > 0) { 950 | Mesh mesh = new Mesh (); 951 | mesh.vertices = verts.ToArray(); 952 | mesh.colors = colors.ToArray(); 953 | mesh.normals = normals.ToArray(); 954 | mesh.triangles = indicies.ToArray (); 955 | mesh.uv = uvs.ToArray(); 956 | 957 | result.Add (mesh); 958 | 959 | totalQuadCount += currentQuadCount; 960 | } 961 | 962 | Debug.Log (string.Format ("[MVImport] Mesh generated, total quads {0}", totalQuadCount)); 963 | 964 | return result.ToArray(); 965 | } 966 | } 967 | --------------------------------------------------------------------------------