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 }