1 /**
2 Copyright: Copyright (c) 2016-2018 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 module voxelman.model.utils;
7 
8 import voxelman.container.buffer : Buffer;
9 import voxelman.model.mesh : Face3, Faces;
10 
11 // Doesn't mark with GC.addRange. T cannot contain pointers
12 T[] allocate(T)(size_t size) {
13 	import std.experimental.allocator.gc_allocator;
14 	alias allocator = GCAllocator.instance;
15 	return cast(T[])allocator.allocate(T.sizeof * size);
16 }
17 
18 V[] unrollFaces(V)(V[] vertices, Face3[] faces)
19 {
20 	int[] indexes = cast(int[])faces;
21 	V[] result = allocate!(V)(indexes.length);
22 
23 	foreach(i, index; indexes)
24 	{
25 		result[i] = vertices[index];
26 	}
27 
28 	return result;
29 }
30 
31 V[] unrollFaces(V)(V[] vertices, Faces faces)
32 {
33 	if (faces.isTriangulated)
34 	{
35 		V[] result = allocate!(V)(faces.numFaces * 3);
36 
37 		size_t i;
38 		foreach(face; faces[])
39 		{
40 			result[i  ] = vertices[face[i  ]];
41 			result[i+1] = vertices[face[i+1]];
42 			result[i+2] = vertices[face[i+2]];
43 			i += 3;
44 		}
45 
46 		return result;
47 	}
48 	else
49 	{
50 		return unrollFaces(vertices, triangulateFaces(faces));
51 	}
52 }
53 
54 Face3[] triangulateFaces(Faces faces)
55 {
56 	Buffer!int triFaces;
57 	foreach(faceVertices; faces[])
58 	{
59 		triFaces.put(faceVertices[0], faceVertices[1], faceVertices[2]);
60 		for(size_t i = 3; i < faceVertices.length; ++i)
61 		{
62 			triFaces.put(faceVertices[0], faceVertices[i-1], faceVertices[i]);
63 		}
64 	}
65 	return cast(Face3[])triFaces.data;
66 }