public VoxModel LoadModel(string absolutePath) { VoxModel output = new VoxModel(); string? name = Path.GetFileNameWithoutExtension(absolutePath); LogOutputFile = name + "-" + DateTime.Now.ToString("y-MM-d_HH.m.s") + ".txt"; using (var reader = new BinaryReader(new MemoryStream(File.ReadAllBytes(absolutePath)))) { var head = new string(reader.ReadChars(4)); if (!head.Equals(HEADER)) { Console.WriteLine("Not a Magicavoxel file! " + output); return(null); } int version = reader.ReadInt32(); if (version != VERSION) { Console.WriteLine("Version number: " + version + " Was designed for version: " + VERSION); } ResetModel(output); ChildCount = 0; ChunkCount = 0; while (reader.BaseStream.Position != reader.BaseStream.Length) { ReadChunk(reader, output); } } if (output.Palette == null) { output.Palette = LoadDefaultPalette(); } return(output); }
/// <summary> /// Clear model data /// </summary> /// <param name="model"></param> protected void ResetModel(VoxModel model) { if (model.voxelFrames != null) { model.voxelFrames.Clear(); } else { model.voxelFrames = new List <VoxelData>(); } model.materialChunks.Clear(); model.transformNodeChunks.Clear(); model.groupNodeChunks.Clear(); model.shapeNodeChunks.Clear(); model.layerChunks.Clear(); model.rendererSettingChunks.Clear(); }
/// <summary> /// Clear model data /// </summary> /// <param name="model"></param> protected void ResetModel(VoxModel model) { if (model.VoxelFrames != null) { model.VoxelFrames.Clear(); } else { model.VoxelFrames = new List <VoxelData>(); } model.MaterialChunks.Clear(); model.TransformNodeChunks.Clear(); model.GroupNodeChunks.Clear(); model.ShapeNodeChunks.Clear(); model.LayerChunks.Clear(); model.RendererSettingChunks.Clear(); }
private void ReadChunk(BinaryReader reader, VoxModel output) { string chunkName = new string(reader.ReadChars(4)); int chunkSize = reader.ReadInt32(); int childChunkSize = reader.ReadInt32(); byte[] chunk = reader.ReadBytes(chunkSize); byte[] children = reader.ReadBytes(childChunkSize); ChunkCount++; using (var chunkReader = new BinaryReader(new MemoryStream(chunk))) { switch (chunkName) { case MAIN: break; case SIZE: int w = chunkReader.ReadInt32(); int h = chunkReader.ReadInt32(); int d = chunkReader.ReadInt32(); if (ChildCount >= output.VoxelFrames.Count) { output.VoxelFrames.Add(new VoxelData()); } output.VoxelFrames[ChildCount].Resize(w, d, h); ChildCount++; break; case XYZI: mVoxelCountLastXyziChunk = chunkReader.ReadInt32(); var frame = output.VoxelFrames[ChildCount - 1]; byte x, y, z, color; for (int i = 0; i < mVoxelCountLastXyziChunk; i++) { x = chunkReader.ReadByte(); y = chunkReader.ReadByte(); z = chunkReader.ReadByte(); color = chunkReader.ReadByte(); frame.Set(x, y, z, color); } break; case RGBA: output.Palette = LoadPalette(chunkReader); break; case MATT: break; case PACK: int frameCount = chunkReader.ReadInt32(); for (int i = 0; i < frameCount; i++) { output.VoxelFrames.Add(new VoxelData()); } break; case nTRN: output.TransformNodeChunks.Add(ReadTransformNodeChunk(chunkReader)); break; case nGRP: output.GroupNodeChunks.Add(ReadGroupNodeChunk(chunkReader)); break; case nSHP: output.ShapeNodeChunks.Add(ReadShapeNodeChunk(chunkReader)); break; case LAYR: output.LayerChunks.Add(ReadLayerChunk(chunkReader)); break; case MATL: output.MaterialChunks.Add(ReadMaterialChunk(chunkReader)); break; case rOBJ: output.RendererSettingChunks.Add(ReaddRObjectChunk(chunkReader)); break; default: Console.WriteLine($"Unknown chunk: \"{chunkName}\""); break; } } WriteLogs(chunkName, chunkSize, childChunkSize, output); //read child chunks using (var childReader = new BinaryReader(new MemoryStream(children))) { while (childReader.BaseStream.Position != childReader.BaseStream.Length) { ReadChunk(childReader, output); } } }
private void WriteLogs(string chunkName, int chunkSize, int childChunkSize, VoxModel output) { if (!Directory.Exists("logs")) { Directory.CreateDirectory("logs"); } string path = "logs/" + LogOutputFile; using (var writer = new StreamWriter(path, true)) { writer.WriteLine("CHUNK NAME: " + chunkName + " (" + ChunkCount + ")"); writer.WriteLine("CHUNK SIZE: " + chunkSize + " BYTES"); writer.WriteLine("CHILD CHUNK SIZE: " + childChunkSize); switch (chunkName) { case SIZE: var frame = output.VoxelFrames[ChildCount - 1]; writer.WriteLine("-> SIZE: " + frame.VoxelsWide + " " + frame.VoxelsTall + " " + frame.VoxelsDeep); break; case XYZI: writer.WriteLine("-> XYZI: " + mVoxelCountLastXyziChunk); break; case nTRN: var transform = output.TransformNodeChunks.Last(); writer.WriteLine("-> TRANSFORM NODE: " + transform.Id); writer.WriteLine("--> CHILD ID: " + transform.ChildId); writer.WriteLine("--> RESERVED ID: " + transform.ReservedId); writer.WriteLine("--> LAYER ID: " + transform.LayerId); DisplayAttributes(transform.Attributes, writer); DisplayFrameAttributes(transform.FrameAttributes, writer); break; case nGRP: var group = output.GroupNodeChunks.Last(); writer.WriteLine("-> GROUP NODE: " + group.Id); group.ChildIds.ToList().ForEach(t => writer.WriteLine("--> CHILD ID: " + t)); DisplayAttributes(group.Attributes, writer); break; case nSHP: var shape = output.ShapeNodeChunks.Last(); writer.WriteLine("-> SHAPE NODE: " + shape.Id); DisplayAttributes(shape.Attributes, writer); DisplayModelAttributes(shape.Models, writer); break; case LAYR: var layer = output.LayerChunks.Last(); writer.WriteLine("-> LAYER NODE: " + layer.Id + " " + layer.Name + " " + layer.Hidden + " " + layer.Unknown); DisplayAttributes(layer.Attributes, writer); break; case MATL: var material = output.MaterialChunks.Last(); writer.WriteLine("-> MATERIAL NODE: " + material.Id.ToString("F1")); writer.WriteLine("--> ALPHA: " + material.Alpha.ToString("F1")); writer.WriteLine("--> EMISSION: " + material.Emission.ToString("F1")); writer.WriteLine("--> FLUX: " + material.Flux.ToString("F1")); writer.WriteLine("--> METALLIC: " + material.Metallic.ToString("F1")); writer.WriteLine("--> ROUGH: " + material.Rough.ToString("F1")); writer.WriteLine("--> SMOOTHNESS: " + material.Smoothness.ToString("F1")); writer.WriteLine("--> SPEC: " + material.Spec.ToString("F1")); writer.WriteLine("--> WEIGHT: " + material.Weight.ToString("F1")); DisplayAttributes(material.Properties, writer); break; } writer.WriteLine(""); writer.Close(); } }