Added head mesh, points/directions for hair that follow the Poisson
[hair] / src / mesh.cc
1 #include <GL/glew.h>
2
3 #include <assimp/cimport.h>
4 #include <assimp/postprocess.h>
5 #include <assimp/scene.h>
6 #include <assimp/mesh.h>
7
8 #include <float.h>
9
10 #include "mesh.h"
11
12 Mesh::Mesh()
13 {
14         vbo_vertices = 0;
15         vbo_normals = 0;
16         vbo_colors = 0;
17         ibo = 0;
18
19         num_vertices = 0;
20         num_indices = 0;
21 }
22
23 Mesh::~Mesh()
24 {
25         if(vbo_vertices)
26                 glDeleteBuffers(1, &vbo_vertices);
27         if(vbo_normals)
28                 glDeleteBuffers(1, &vbo_normals);
29         if(vbo_colors)
30                 glDeleteBuffers(1, &vbo_colors);
31         if(ibo)
32                 glDeleteBuffers(1, &ibo);
33
34         vertices.clear();
35         normals.clear();
36         colors.clear();
37 }
38
39 void Mesh::draw() const
40 {
41         glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
42         glVertexPointer(3, GL_FLOAT, 0, 0);
43
44         if(vbo_normals) {
45                 glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
46                 glNormalPointer(GL_FLOAT, 0, 0);
47                 glEnableClientState(GL_NORMAL_ARRAY);
48         }
49
50         if(vbo_colors) {
51                 glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
52                 glColorPointer(3, GL_FLOAT, 0, 0);
53                 glEnableClientState(GL_COLOR_ARRAY);
54         }
55
56         glBindBuffer(GL_ARRAY_BUFFER, 0);
57
58         glEnableClientState(GL_VERTEX_ARRAY);
59
60         if(ibo) {
61                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
62                 glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
63                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
64         } else {
65                 glDrawArrays(GL_TRIANGLES, 0, num_vertices);
66         }
67
68         glDisableClientState(GL_VERTEX_ARRAY);
69         glDisableClientState(GL_NORMAL_ARRAY);
70         glDisableClientState(GL_COLOR_ARRAY);
71 }
72
73 void Mesh::update_vbo(unsigned int which)
74 {
75         if(which & MESH_NORMAL) {
76                 if(!vbo_normals) {
77                         glGenBuffers(1, &vbo_normals);
78                 }
79                 glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
80                 if(num_vertices != (int)normals.size()) {
81                         glBufferData(GL_ARRAY_BUFFER, normals.size() * 3 * sizeof(float),
82                                         &normals[0], GL_STATIC_DRAW);
83                 }
84                 else {
85                         glBufferSubData(GL_ARRAY_BUFFER, 0, normals.size() * 3 * sizeof(float),
86                                         &normals[0]);
87                 }
88         }
89
90         if(which & MESH_COLOR) {
91                 if(!vbo_colors) {
92                         glGenBuffers(1, &vbo_colors);
93                 }
94                 glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
95                 if(num_vertices != (int)colors.size()) {
96                         glBufferData(GL_ARRAY_BUFFER, colors.size() * 3 * sizeof(float),
97                                         &colors[0], GL_STATIC_DRAW);
98                 }
99                 else {
100                         glBufferSubData(GL_ARRAY_BUFFER, 0, colors.size() * 3 * sizeof(float),
101                                         &colors[0]);
102                 }
103         }
104
105
106         if(which & MESH_VERTEX) {
107                 if(!vbo_vertices) {
108                         glGenBuffers(1, &vbo_vertices);
109                 }
110                 glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
111                 if(num_vertices != (int)vertices.size()) {
112                         glBufferData(GL_ARRAY_BUFFER, vertices.size() * 3 * sizeof(float),
113                                         &vertices[0], GL_STATIC_DRAW);
114                 }
115                 else {
116                         glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * 3 * sizeof(float),
117                                         &vertices[0]);
118                 }
119                 num_vertices = vertices.size();
120         }
121
122         if(which & MESH_INDEX) {
123                 if(!ibo) {
124                         glGenBuffers(1, &ibo);
125                 }
126                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
127                 if(num_indices != (int)indices.size()) {
128                         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * 2,
129                                         &indices[0], GL_STATIC_DRAW);
130                 }
131                 else {
132                         glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * 2,
133                                         &indices[0]);
134                 }
135                 num_indices = indices.size();
136         }
137 }
138
139 std::vector<Mesh*> load_meshes(const char *fname)
140 {
141         std::vector<Mesh*> meshes;
142         unsigned int ai_flags = aiProcessPreset_TargetRealtime_Quality;
143         const aiScene *scene = aiImportFile(fname, ai_flags);
144
145         for(unsigned int j=0; j<scene->mNumMeshes; j++) {
146                 aiMesh *amesh = scene->mMeshes[j];
147
148                 if(!amesh->HasPositions() || !amesh->mNumFaces)
149                         continue;
150
151                 Mesh *mesh = new Mesh;
152                 mesh->name = std::string(amesh->mName.C_Str());
153
154                 for(unsigned int i=0; i<amesh->mNumVertices; i++) {
155                         Vec3 vertex = Vec3(amesh->mVertices[i].x,
156                                         amesh->mVertices[i].y,
157                                         amesh->mVertices[i].z);
158                         mesh->vertices.push_back(vertex);
159                 }
160
161                 if(amesh->HasNormals()) {
162                         for(unsigned int i=0; i<amesh->mNumVertices; i++) {
163                                 Vec3 normal = Vec3(amesh->mNormals[i].x,
164                                                            amesh->mNormals[i].y,
165                                                                    amesh->mNormals[i].z);
166                                 mesh->normals.push_back(normal);
167                         }
168                 }
169
170                 if(amesh->HasVertexColors(0)) {
171                         for(unsigned int i=0; i<amesh->mNumVertices; i++) {
172                                 Vec3 color = Vec3(amesh->mColors[0][i].r,
173                                                                   amesh->mColors[0][i].g,
174                                                                   amesh->mColors[0][i].b);
175                                 mesh->colors.push_back(color);
176                         }
177                 }
178
179                 for(unsigned int i=0; i<amesh->mNumFaces; i++) {
180                         for(int j=0; j<3; j++) {
181                                 mesh->indices.push_back(amesh->mFaces[i].mIndices[j]);
182                         }
183                 }
184
185                 meshes.push_back(mesh);
186         }
187
188         return meshes;
189 }
190
191 void Mesh::calc_bbox()
192 {
193         if (vertices.empty()) {
194                 bbox.v0 = Vec3(0, 0, 0);
195                 bbox.v1 = Vec3(0, 0, 0);
196
197                 return;
198         }
199
200         bbox.v0 = Vec3(FLT_MAX, FLT_MAX, FLT_MAX);
201         bbox.v1 = -bbox.v0;
202
203         for(size_t i=0; i<vertices.size(); i++) {
204                 for(int j=0; j<3; j++) {
205                         if(vertices[i][j] < bbox.v0[j])
206                                 bbox.v0[j] = vertices[i][j];
207                         if(vertices[i][j] > bbox.v1[j])
208                                 bbox.v1[j] = vertices[i][j];
209                 }
210         }
211 }