1 module sbylib.wrapper.assimp.mesh;
2 
3 import bindbc.assimp.types;
4 import sbylib.wrapper.assimp.constants : PrimitiveType;
5 import sbylib.wrapper.assimp.functions : toSbylibVector, toRegularString, toArray;
6 import sbylib.wrapper.assimp.face : Face;
7 import sbylib.wrapper.assimp.bone : Bone;
8 import sbylib.wrapper.assimp.animmesh : AnimMesh;
9 import sbylib.wrapper.assimp.scene : Scene;
10 import sbylib.math : vec3;
11 import std.typecons : BitFlags;
12 
13 struct Mesh {
14 
15     private const(aiMesh)* mesh;
16 
17     BitFlags!PrimitiveType primitiveTypes() {
18         import std.traits : EnumMembers;
19         BitFlags!PrimitiveType result;
20         static foreach (e; EnumMembers!(PrimitiveType)) {
21             if (mesh.mPrimitiveTypes & e)
22                 result |= e;
23         }
24         return result;
25     }
26 
27     auto vertices() {
28         return toArray!((aiVector3D v) => v.toSbylibVector)
29             (mesh.mNumVertices, mesh.mVertices);
30     }
31 
32     auto normals() {
33         return toArray!((aiVector3D v) => v.toSbylibVector)
34             (mesh.mNumVertices, mesh.mNormals);
35     }
36 
37     auto tangents() {
38         return toArray!((aiVector3D v) => v.toSbylibVector)
39             (mesh.mNumVertices, mesh.mTangents);
40     }
41 
42     auto bitangents() {
43         return toArray!((aiVector3D v) => v.toSbylibVector)
44             (mesh.mNumVertices, mesh.mBitangents);
45     }
46 
47     auto colors(size_t i) {
48         return toArray!((aiColor4D v) => v.toSbylibVector)
49             (mesh.mNumVertices, mesh.mColors[i]);
50     }
51 
52     auto textureCoords(size_t i) {
53         return toArray!((aiVector3D v) => v.toSbylibVector)
54             (mesh.mNumVertices, mesh.mTextureCoords[i]);
55     }
56 
57     uint numUVComponents(size_t i) {
58         return mesh.mNumUVComponents[i];
59     }
60 
61     auto faces() {
62         return toArray!((const aiFace f) => Face(f))
63             (mesh.mNumFaces, mesh.mFaces);
64     }
65 
66     auto bones() {
67         return toArray!((const(aiBone)* b) => Bone(b))
68             (mesh.mNumBones, mesh.mBones);
69     }
70 
71     uint materialIndex() {
72         return mesh.mMaterialIndex;
73     }
74 
75     string name() {
76         return mesh.mName.toRegularString;
77     }
78 
79     auto animMeshes() {
80         return toArray!((const(aiAnimMesh)* a) => AnimMesh(a))
81             (mesh.mNumAnimMeshes, mesh.mAnimMeshes);
82     }
83 
84     string toString(Scene scene) {
85         import std.algorithm : map, filter;
86         import std.array : array;
87         import std.conv : to;
88         import std.format : format;
89         import std..string : join;
90         import std.traits : EnumMembers;
91         import sbylib.wrapper.assimp.functions : tree;
92 
93         string[] strs;
94         strs ~= [EnumMembers!PrimitiveType].filter!(p => primitiveTypes & p).map!(p => p.to!string).join(",").format!"[%s](%d)"(vertices.length);
95         strs ~= bones.map!(b => b.toString()).array;
96         if (materialIndex >= 0) strs ~= scene.materials[materialIndex].toString();
97 
98         return tree(format!"Mesh[%s]"(name), strs);
99     }
100 }