1 module ws.file.bbatch; 2 3 import 4 std.conv, 5 std.stdio, 6 std.file, 7 std.path, 8 ws.decode, 9 ws.file.obj; 10 11 12 alias Vertex = float[3 + 3 + 2]; 13 14 struct MaterialInfo { 15 string name; 16 string[string] attributes; 17 } 18 19 struct VertMat { 20 Vertex[] vertices; 21 MaterialInfo material; 22 } 23 24 25 class BinaryBatch { 26 27 struct Header { 28 long vers; 29 long count; 30 } 31 32 string path; 33 VertMat[] data; 34 35 private this(){} 36 37 this(string path){ 38 MaterialInfo[string] materials; 39 Decode.file("models/" ~ path.setExtension("bbm"), (name, content, b){ 40 auto m = MaterialInfo(name); 41 Decode.text(content, (attr, val, b){ 42 m.attributes[attr] = val; 43 }); 44 materials[name] = m; 45 }); 46 47 auto file = File("models/" ~ path, "r"); 48 Header[1] header; 49 file.rawRead(header); 50 for(int i=0; i<header[0].count; i++){ 51 long len; 52 VertMat vm; 53 char[] name; 54 // material 55 file.rawRead((&len)[0..1]); 56 assert(name.length < file.size); 57 name.length = cast(size_t)len; 58 file.rawRead(name); 59 vm.material = materials[to!string(name)]; 60 // vertices 61 file.rawRead((&len)[0..1]); 62 assert(len < file.size); 63 vm.vertices.length = cast(size_t)len; 64 file.rawRead(vm.vertices); 65 data ~= vm; 66 } 67 } 68 69 void save(){ 70 auto file = File(path, "wb"); 71 Header[1] header = [Header(1, data.length)]; 72 file.rawWrite(header); 73 foreach(vm; data){ 74 file.rawWrite([cast(long)vm.material.name.length]); 75 file.rawWrite(vm.material.name); 76 file.rawWrite([cast(long)vm.vertices.length]); 77 file.rawWrite(vm.vertices); 78 } 79 } 80 81 static BinaryBatch fromObj(string path){ 82 auto bb = new BinaryBatch; 83 bb.path = "models/" ~ path[0..$-3] ~ "bb"; 84 auto mdl = new OBJ("models/" ~ path); 85 foreach(object; mdl.objects){ 86 foreach(material; object.materials.values){ 87 VertMat vm; 88 vm.material = MaterialInfo(material.name); 89 foreach(polygon; material.polygons){ 90 foreach(vertex; polygon.vertices){ 91 Vertex vert; 92 vert[0..3] = vertex.pos; 93 vert[3..6] = vertex.normal; 94 vert[6..8] = vertex.uvw.data[0..2]; 95 vm.vertices ~= vert; 96 } 97 } 98 bb.data ~= vm; 99 } 100 } 101 return bb; 102 } 103 104 }