assimpGUtil.cpp
1 /*********************************************************************
2 * Rice University Software Distribution License
3 *
4 * Copyright (c) 2010, Rice University
5 * All Rights Reserved.
6 *
7 * For a full description see the file named LICENSE.
8 *
9 *********************************************************************/
10 
11 /* Author: Mark Moll, Ioan Sucan */
12 
13 #include "omplapp/graphics/detail/assimpGUtil.h"
14 
15 #ifdef __APPLE__
16 #include <OpenGL/gl.h>
17 #else
18 #include <GL/gl.h>
19 #endif
20 
21 
22 // Most of the code below is taken from external/assimp/samples/SimpleOpenGL/Sample_SimpleOpenGL.c
23 namespace ompl
24 {
25  namespace app
26  {
27 
28  namespace scene
29  {
30 
31  void color4_to_float4(const aiColor4D *c, float f[4])
32  {
33  f[0] = c->r;
34  f[1] = c->g;
35  f[2] = c->b;
36  f[3] = c->a;
37  }
38 
39  void set_float4(float f[4], float a, float b, float c, float d)
40  {
41  f[0] = a;
42  f[1] = b;
43  f[2] = c;
44  f[3] = d;
45  }
46 
47  void apply_material(const aiMaterial *mtl)
48  {
49  float c[4];
50  GLenum fill_mode;
51  int ret1, ret2;
52  aiColor4D diffuse;
53  aiColor4D specular;
54  aiColor4D ambient;
55  aiColor4D emission;
56  float shininess, strength;
57  int two_sided;
58  int wireframe;
59  unsigned int max;
60 
61  set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
62  if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
63  color4_to_float4(&diffuse, c);
64  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
65 
66  set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
67  if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
68  color4_to_float4(&specular, c);
69  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
70 
71  set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
72  if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
73  color4_to_float4(&ambient, c);
74  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
75 
76  set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
77  if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
78  color4_to_float4(&emission, c);
79  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
80 
81  max = 1;
82  ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
83  max = 1;
84  ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
85  if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS))
86  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
87  else
88  {
89  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
90  set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
91  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
92  }
93 
94  max = 1;
95  if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
96  fill_mode = wireframe != 0 ? GL_LINE : GL_FILL;
97  else
98  fill_mode = GL_FILL;
99  glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
100 
101  max = 1;
102  if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && (two_sided != 0))
103  glEnable(GL_CULL_FACE);
104  else
105  glDisable(GL_CULL_FACE);
106  }
107 
108  // Can't send color down as a pointer to aiColor4D because AI colors are ABGR.
109  void Color4f(const aiColor4D *color)
110  {
111  glColor4f(color->r, color->g, color->b, color->a);
112  }
113 
114  void recursive_render(const aiScene *scene, const aiNode* nd)
115  {
116  int i;
117  unsigned int n = 0, t;
118  aiMatrix4x4 m = nd->mTransformation;
119 
120  // update transform
121  aiTransposeMatrix4(&m);
122  glPushMatrix();
123  glMultMatrixf((float*)&m);
124 
125  // draw all meshes assigned to this node
126  for (; n < nd->mNumMeshes; ++n) {
127  const aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
128 
129  apply_material(scene->mMaterials[mesh->mMaterialIndex]);
130  if(mesh->mNormals == nullptr)
131  glDisable(GL_LIGHTING);
132  else
133  glEnable(GL_LIGHTING);
134  if(mesh->mColors[0] == nullptr)
135  glDisable(GL_COLOR_MATERIAL);
136  else
137  glEnable(GL_COLOR_MATERIAL);
138 
139  for (t = 0; t < mesh->mNumFaces; ++t)
140  {
141  const aiFace* face = &mesh->mFaces[t];
142  GLenum face_mode;
143 
144  switch(face->mNumIndices)
145  {
146  case 1: face_mode = GL_POINTS; break;
147  case 2: face_mode = GL_LINES; break;
148  case 3: face_mode = GL_TRIANGLES; break;
149  default: face_mode = GL_POLYGON; break;
150  }
151 
152  glBegin(face_mode);
153  for(i = 0; i < (int)face->mNumIndices; i++)
154  {
155  int index = face->mIndices[i];
156  if(mesh->mColors[0] != nullptr)
157  Color4f(&mesh->mColors[0][index]);
158  if(mesh->mNormals != nullptr)
159  glNormal3fv(&mesh->mNormals[index].x);
160  glVertex3fv(&mesh->mVertices[index].x);
161  }
162  glEnd();
163  }
164  }
165  // draw all children
166  for (n = 0; n < nd->mNumChildren; ++n)
167  recursive_render(scene, nd->mChildren[n]);
168  glPopMatrix();
169  }
170 
171  int assimpRender(const std::vector<const aiScene*> &scenes, const std::vector<aiVector3D> &robotCenter)
172  {
173  int result = glGenLists(1);
174 
175  // create display list for robot; we undo the translation of the robot
176  glNewList(result, GL_COMPILE);
177 
178  aiMatrix4x4 t;
179  for (unsigned int i = 0 ; i < scenes.size() ; ++i)
180  {
181  bool tr = robotCenter.size() > i;
182  if (tr)
183  {
184  aiMatrix4x4::Translation(-robotCenter[i], t);
185  aiTransposeMatrix4(&t);
186  glPushMatrix();
187  glMultMatrixf((float*)&t);
188  }
189 
190  recursive_render(scenes[i], scenes[i]->mRootNode);
191 
192  if (tr)
193  glPopMatrix();
194  }
195 
196  glEndList();
197 
198  return result;
199  }
200 
201 
202  int assimpRender(const aiScene* scene, const aiVector3D &robotCenter)
203  {
204  std::vector<const aiScene*> scenes(1, scene);
205  std::vector<aiVector3D> centers(1, robotCenter);
206  return assimpRender(scenes, centers);
207  }
208 
209  int assimpRender(const std::vector<const aiScene*> &scenes)
210  {
211  std::vector<aiVector3D> empty;
212  return assimpRender(scenes, empty);
213  }
214 
215  int assimpRender(const aiScene* scene)
216  {
217  std::vector<const aiScene*> scenes(1, scene);
218  return assimpRender(scenes);
219  }
220 
221  }
222  }
223 }
Main namespace. Contains everything in this library.
Definition: AppBase.h:21