GameObject BuildLODGroup(MeshLODs list, MeshSelector selector, VoxModel model, GameObject modelGO, string name, Material material) { var go = new GameObject(name); go.transform.SetParent(modelGO.transform); var g = go.AddComponent <LODGroup>(); g.SetLODs(list.LODs.Select((m, l) => selector(list.LODs[l])).Select((m, l) => { var goLOD = new GameObject(l.ToString(), typeof(MeshFilter), typeof(MeshRenderer)); goLOD.transform.SetParent(go.transform); var h = Mathf.Pow(2 - (model.Settings.LODBias / 16f), -l); //Debug.Log(h); var r = new[] { goLOD.GetComponent <MeshRenderer>(), }; r[0].material = material; var mf = goLOD.GetComponent <MeshFilter>(); mf.mesh = m; return(new LOD(h, r)); }).ToArray()); g.RecalculateBounds(); return(go); }
public bool LoadModel(string absolutePath, VoxModel output, Logger logger) { var name = Path.GetFileNameWithoutExtension(absolutePath); logger?.Invoke("load: " + name); //Load the whole file using (var reader = new BinaryReader(new MemoryStream(File.ReadAllBytes(absolutePath)))) { var head = new string(reader.ReadChars(4)); if (!head.Equals(HEADER)) { Debug.LogError("Not a MagicaVoxel File!", output); return(false); } int version = reader.ReadInt32(); if (version != VERSION) { Debug.LogWarning("Version number:" + version + " Was designed for " + VERSION); } ResetModel(output); childCount = 0; while (reader.BaseStream.Position != reader.BaseStream.Length) { ReadChunk(reader, output); } } if (output.palette == null) { output.palette = LoadDefaultPalette(); } output.SetAlphaFromTranparency(); var mesher = new VoxMesher(); for (int i = 0; i < output.voxelFrames.Count; i++) { var frame = output.voxelFrames[i]; logger?.Invoke($"frame={i}/{output.voxelFrames.Count}: {name}"); if (!output.Settings.EnablesTransparent || !frame.Any(output.palette, c => c.a < 1)) { var list = new MeshLODs(new Mesh { name = $"{i}.opaque" }); mesher.MeshVoxelData(output, frame, list.LODs[0].opaque); output.meshes.Add(list); } else { var list = new MeshLODs( new Mesh { name = $"{i}.opaque", }, new Mesh { name = $"{i}.tranparent" }); mesher.MeshVoxelData(output, frame.Where(output.palette, c => c.a >= 1), list.LODs[0].opaque); mesher.MeshVoxelData(output, frame.Where(output.palette, c => c.a < 1), list.LODs[0].transparent); output.meshes.Add(list); } } #region LOD supports: added by XELF var dataList = output.voxelFrames.ToArray(); var sizeList = output.voxelFrames.Select(d => new Int3(d.VoxelsWide, d.VoxelsTall, d.VoxelsDeep)).ToArray(); for (int l = 1; l < output.Settings.maxLOD; l++) { for (int i = 0; i < output.voxelFrames.Count; i++) { logger?.Invoke($"frame={i}/{output.voxelFrames.Count}, lod={l}/{output.Settings.maxLOD}: {name}"); var previous = dataList[i]; var size = sizeList[i]; size.X = (size.X + 1) >> 1; size.Y = (size.Y + 1) >> 1; size.Z = (size.Z + 1) >> 1; sizeList[i] = size; var scale = new Vector3( output.Settings.modelScale * output.voxelFrames[i].VoxelsWide / size.X, output.Settings.modelScale * output.voxelFrames[i].VoxelsTall / size.Y, output.Settings.modelScale * output.voxelFrames[i].VoxelsDeep / size.Z); var current = previous.ToSmaller(); if (!output.Settings.EnablesTransparent || !current.Any(output.palette, c => c.a < 1)) { var m = new MeshSet { opaque = new Mesh(), }; var materials = VoxMesher.MaterialChunkToVector4(output.materialChunks); mesher.MeshVoxelData(scale, current, output.palette, materials, output.Settings.origin, m.opaque); output.meshes[i].LODs.Add(m); } else { var m = new MeshSet { opaque = new Mesh(), transparent = new Mesh(), }; var materials = VoxMesher.MaterialChunkToVector4(output.materialChunks); mesher.MeshVoxelData(scale, current.Where(output.palette, c => c.a >= 1), output.palette, materials, output.Settings.origin, m.opaque); mesher.MeshVoxelData(scale, current.Where(output.palette, c => c.a < 1), output.palette, materials, output.Settings.origin, m.transparent); output.meshes[i].LODs.Add(m); } dataList[i] = current; } } #endregion return(true); }