forked from ClassiCube/MCGalaxy-Plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BinVoxImport.cs
87 lines (74 loc) · 3.09 KB
/
BinVoxImport.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using MCGalaxy;
using MCGalaxy.Levels.IO;
using MCGalaxy.Maths;
namespace PluginBinVoxelImport {
public sealed class Core : Plugin_Simple {
public override string creator { get { return "UnknownShadow200"; } }
public override string name { get { return "BinVoxelImport"; } }
public override string MCGalaxy_Version { get { return "1.8.9.8"; } }
IMapImporter importer;
public override void Load(bool startup) {
importer = new BinVoxImporter();
IMapImporter.Formats.Add(importer);
}
public override void Unload(bool shutdown) {
IMapImporter.Formats.Remove(importer);
}
}
public sealed class BinVoxImporter : IMapImporter {
public override string Extension { get { return ".binvox"; } }
public override Vec3U16 ReadDimensions(Stream src) {
BinaryReader reader = new BinaryReader(src);
return ReadHeader(reader);
}
public override Level Read(Stream src, string name, bool metadata) {
BinaryReader reader = new BinaryReader(src);
Vec3U16 dims = ReadHeader(reader);
Level lvl = new Level(name, dims.X, dims.Y, dims.Z);
lvl.Config.EdgeLevel = 0;
byte[] blocks = lvl.blocks;
int size = dims.X * dims.Y * dims.Z, i = 0;
while (i < size) {
byte value = reader.ReadByte(), count = reader.ReadByte();
if (value == Block.Air) { i += count; continue; } // skip redundantly changing air
for (int j = 0; j < count; j++) {
int index = i + j;
int x = (index / dims.Y) / dims.Z; // need to reorder from X Z Y to Y Z X
int y = (index / dims.Y) % dims.Z;
int z = index % dims.Z;
blocks[(y * dims.Z + z) * dims.X + x] = value;
}
i += count;
}
return lvl;
}
// http://www.patrickmin.com/binvox/binvox.html
// http://www.patrickmin.com/binvox/ReadBinvox.java
static Vec3U16 ReadHeader(BinaryReader reader) {
Vec3U16 dims = default(Vec3U16);
while (reader.BaseStream.Position < reader.BaseStream.Length) {
string line = ReadString(reader);
if (line.CaselessEq("data")) break;
if (!line.CaselessStarts("dim ")) continue;
string[] parts = line.SplitSpaces(4);
dims.Z = ushort.Parse(parts[1]);
dims.Y = ushort.Parse(parts[2]);
dims.X = ushort.Parse(parts[3]);
}
return dims;
}
static string ReadString(BinaryReader reader) {
List<byte> buffer = new List<byte>();
byte value = 0;
do {
value = reader.ReadByte();
buffer.Add(value);
} while (value != '\n');
return Encoding.ASCII.GetString(buffer.ToArray()).Trim('\r', '\n');
}
}
}