Number5
Visualisierung 2 Project - Florian Schober (0828151, f.schober@live.com), Andreas Walch (0926780, walch.andreas89@gmail.com)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Scene.cpp
Go to the documentation of this file.
1 #include "Application.hpp"
2 
3 SceneInstance::SceneInstance(Application* app, Scene* parent, bool pickable)
4  : ISceneObject(app, pickable)
5  , m_scene(parent)
6  , m_animation(AnimationStart(-1, 0.0f))
7 {
8  m_state.resize(m_scene->m_drawNodeCount, mat4(1.0f));
9 }
11 {
13 }
14 bool SceneInstance::update(double time, double timeDelta)
15 {
16  float ftime = (float)time;
17 
18  if (!m_animationQueue.empty())
19  {
20  auto& next = m_animationQueue.front();
21 
22  if (next.time <= ftime)
23  {
24  m_animation = next;
25  m_animationQueue.pop();
26  }
27  return true;
28  }
29 
31 }
32 void SceneInstance::queueAnimation(float time, uint animation)
33 {
34  m_animationQueue.push(AnimationStart((int)animation, time));
35 }
36 void SceneInstance::queueAnimation(float time, string animation)
37 {
38  m_animationQueue.push(AnimationStart((int)m_scene->m_animationsByName[animation], time));
39 }
40 
41 
42 
43 
44 
45 Scene::Scene(Application* app, string const & name)
46  : m_app(app)
47  , m_name(name)
48  , m_positionsBuffer(0)
49  , m_uvBuffer(0)
50  , m_normalsBuffer(0)
51  , m_indicesBuffer(0)
52  , m_boneIdBuffer(0)
53  , m_boneWeightBuffer(0)
54  , m_vao(0)
55  , m_instancesInBuffer(0)
56  , m_needToUpdateIdBuffer(true)
57 {
58  Assimp::Importer imp;
59 
60  auto scene = imp.ReadFile(("content\\scenes\\" + name).c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals);
61 
62  if (!scene)
63  {
64  cerr << "ERROR: Failed to load scene '" << name << "'" << endl;
65  exit(EXIT_FAILURE);
66  }
67 
68  string baseDir = "scenes\\" + name;
69  baseDir = baseDir.substr(0, baseDir.find_last_of("\\") + 1);
70 
71  // load materials
72  {
73  aiColor4D color;
74  vec4 ambient;
75  vec4 diffuse;
76  vec4 specular;
77  float shininess;
78  Texture* texture;
79 
80  m_materials.resize(scene->mNumMaterials);
81  for (uint i = 0; i < m_materials.size(); i++)
82  {
83  auto& assimpMtl = scene->mMaterials[i];
84  auto& mtl = m_materials[i];
85 
86 
87  if (AI_SUCCESS == aiGetMaterialColor(assimpMtl, AI_MATKEY_COLOR_AMBIENT, &color))
88  ambient = vec4(color.r, color.g, color.b, color.a);
89  else
90  ambient = vec4(0, 0, 0, 0);
91 
92  if (AI_SUCCESS == aiGetMaterialColor(assimpMtl, AI_MATKEY_COLOR_DIFFUSE, &color))
93  diffuse = vec4(color.r, color.g, color.b, color.a);
94  else
95  diffuse = vec4(0, 0, 0, 0);
96 
97  if (AI_SUCCESS == aiGetMaterialColor(assimpMtl, AI_MATKEY_COLOR_SPECULAR, &color))
98  specular = vec4(color.r, color.g, color.b, color.a);
99  else
100  specular = vec4(0, 0, 0, 0);
101 
102  uint max;
103  shininess = 1.0f;
104  aiGetMaterialFloatArray(assimpMtl, AI_MATKEY_SHININESS, &(shininess), &max);
105 
106 
107  aiString texPath;
108  if (AI_SUCCESS == assimpMtl->GetTexture(aiTextureType_DIFFUSE, 0, &texPath))
109  texture = app->getTextures().get("..\\" + baseDir + texPath.C_Str());
110  else
111  texture = nullptr;
112 
113  mtl.reset(new Material(ambient, diffuse, specular, shininess, texture));
114  }
115  }
116 
117  map<string, uint> bones;
118 
119  // load meshes
120  {
121  vector<vec3> positions;
122  vector<vec2> uvs;
123  vector<vec3> normals;
124  vector<ivec4> boneIds;
125  vector<vec4> boneWeights;
126  vector<uint> indices;
127 
128  vector<uint> boneCount;
129 
130  m_meshes.resize(scene->mNumMeshes);
131  for (uint i = 0; i < m_meshes.size(); i++)
132  {
133  auto& assimpMesh = scene->mMeshes[i];
134  auto& mesh = m_meshes[i];
135 
136  if (!assimpMesh->HasPositions())
137  {
138  cerr << "ERROR: Failed to load scene '" << name << "' (Mesh '" << assimpMesh->mName.C_Str() << "' has no positions)" << endl;
139  exit(EXIT_FAILURE);
140  }
141  if (!assimpMesh->HasNormals())
142  {
143  cerr << "ERROR: Failed to load scene '" << name << "' (Mesh '" << assimpMesh->mName.C_Str() << "' has no normals)" << endl;
144  exit(EXIT_FAILURE);
145  }
146  if (!assimpMesh->HasTextureCoords(0))
147  {
148  cerr << "ERROR: Failed to load scene '" << name << "' (Mesh '" << assimpMesh->mName.C_Str() << "' has no texture-coordinates)" << endl;
149  exit(EXIT_FAILURE);
150  }
151  if (!assimpMesh->HasFaces())
152  {
153  cerr << "ERROR: Failed to load scene '" << name << "' (Mesh '" << assimpMesh->mName.C_Str() << "' has no faces)" << endl;
154  exit(EXIT_FAILURE);
155  }
156  if (!assimpMesh->HasBones())
157  {
158  cerr << "ERROR: Failed to load scene '" << name << "' (Mesh '" << assimpMesh->mName.C_Str() << "' has no bones)" << endl;
159  exit(EXIT_FAILURE);
160  }
161 
162  auto meshBaseVertex = positions.size();
163  auto meshBaseIdx = indices.size();
164  auto meshBaseBone = m_boneOffsets.size();
165 
166  auto meshVertexCount = assimpMesh->mNumVertices;
167  auto meshIndexCount = assimpMesh->mNumFaces * 3;
168  auto meshBoneCount = assimpMesh->mNumBones;
169 
170  auto newVertexCount = meshBaseVertex + meshVertexCount;
171  auto newIndexCount = meshBaseIdx + meshIndexCount;
172  auto newBoneCount = meshBaseBone + meshBoneCount;
173 
174  indices.reserve(newIndexCount);
175  for (uint fid = 0; fid < meshIndexCount/3; fid++)
176  {
177  auto& face = assimpMesh->mFaces[fid];
178 
179  if (face.mNumIndices != 3)
180  {
181  cerr << "ERROR: Failed to load scene '" << name << "' (Mesh '" << assimpMesh->mName.C_Str() << "' has faces with " << face.mNumIndices << " vertices)" << endl;
182  exit(EXIT_FAILURE);
183  }
184 
185  for (size_t iid = 0; iid < 3; iid++)
186  indices.push_back(meshBaseVertex + face.mIndices[iid]);
187  }
188 
189  uvs.reserve(newVertexCount);
190  positions.reserve(newVertexCount);
191  normals.reserve(newVertexCount);
192  for (uint vid = 0; vid < meshVertexCount; vid++)
193  {
194  auto& uv = assimpMesh->mTextureCoords[0][vid];
195  auto& pos = assimpMesh->mVertices[vid];
196  auto& normal = assimpMesh->mNormals[vid];
197 
198  uvs.push_back(vec2(uv.x, uv.y));
199  positions.push_back(vec3(pos.x, pos.y, pos.z));
200  normals.push_back(vec3(normal.x, normal.y, normal.z));
201  }
202 
203  boneIds.resize(newVertexCount);
204  boneWeights.resize(newVertexCount);
205  boneCount.resize(newVertexCount);
206  for (uint vid = 0; vid < meshVertexCount; vid++)
207  {
208  boneIds[meshBaseVertex + vid] = ivec4(0);
209  boneWeights[meshBaseVertex + vid] = vec4(0);
210  boneCount[meshBaseVertex + vid] = 0;
211  }
212 
213  m_boneOffsets.resize(newBoneCount);
214  for (uint bid = 0; bid < assimpMesh->mNumBones; bid++)
215  {
216  auto& bone = assimpMesh->mBones[bid];
217 
218  auto gbid = bones.size();
219 
220  auto found = bones.find(bone->mName.C_Str());
221  if (found != bones.end())
222  {
223  gbid = found->second;
224  }
225  else
226  {
227  bones[bone->mName.C_Str()] = gbid;
228  auto boneMat = bone->mOffsetMatrix;
229  boneMat.Transpose();
230  m_boneOffsets[gbid] = *reinterpret_cast<mat4*>(&boneMat);
231  }
232 
233 
234  for (uint wid = 0; wid < bone->mNumWeights; wid++)
235  {
236  auto& weight = bone->mWeights[wid];
237  auto& vid = weight.mVertexId;
238 
239  auto& count = boneCount[meshBaseVertex + vid];
240 
241  if (count >= 4) continue;
242 
243  auto& v_bid = boneIds[meshBaseVertex + vid];
244  auto& v_bweight = boneWeights[meshBaseVertex + vid];
245 
246  v_bid[count] = gbid;
247  v_bweight[count] = weight.mWeight;
248 
249  count++;
250  }
251  }
252 
253  mesh.reset(new Mesh(this,
254  assimpMesh->mName.C_Str(),
255  meshBaseIdx,
256  meshIndexCount,
257  m_materials[assimpMesh->mMaterialIndex].get()));
258  }
259 
260  auto vertexCount = positions.size();
261  auto indexCount = indices.size();
262 
263  glGenBuffers(1, &m_positionsBuffer);
264  glBindBuffer(GL_ARRAY_BUFFER, m_positionsBuffer);
265  {
266  glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(vec3), &positions[0], GL_STATIC_DRAW);
267  }
268  glBindBuffer(GL_ARRAY_BUFFER, 0);
269 
270  glGenBuffers(1, &m_normalsBuffer);
271  glBindBuffer(GL_ARRAY_BUFFER, m_normalsBuffer);
272  {
273  glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(vec3), &normals[0], GL_STATIC_DRAW);
274  }
275  glBindBuffer(GL_ARRAY_BUFFER, 0);
276 
277  glGenBuffers(1, &m_uvBuffer);
278  glBindBuffer(GL_ARRAY_BUFFER, m_uvBuffer);
279  {
280  glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(vec2), &uvs[0], GL_STATIC_DRAW);
281  }
282  glBindBuffer(GL_ARRAY_BUFFER, 0);
283 
284  glGenBuffers(1, &m_boneIdBuffer);
285  glBindBuffer(GL_ARRAY_BUFFER, m_boneIdBuffer);
286  {
287  glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(ivec4), &boneIds[0], GL_STATIC_DRAW);
288  }
289  glBindBuffer(GL_ARRAY_BUFFER, 0);
290 
291  glGenBuffers(1, &m_boneWeightBuffer);
292  glBindBuffer(GL_ARRAY_BUFFER, m_boneWeightBuffer);
293  {
294  glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(vec4), &boneWeights[0], GL_STATIC_DRAW);
295  }
296  glBindBuffer(GL_ARRAY_BUFFER, 0);
297 
298  glGenBuffers(1, &m_indicesBuffer);
299  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer);
300  {
301  glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(uint), &indices[0], GL_STATIC_DRAW);
302  }
303  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
304 
305 
306  glGenVertexArrays(1, &m_vao);
307  glBindVertexArray(m_vao);
308  {
309  glBindBuffer(GL_ARRAY_BUFFER, m_positionsBuffer);
310  GLint positionIndex = Shader::position;
311  glEnableVertexAttribArray(positionIndex);
312  glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
313 
314  glBindBuffer(GL_ARRAY_BUFFER, m_normalsBuffer);
315  GLint normalIndex = Shader::normal;
316  glEnableVertexAttribArray(normalIndex);
317  glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);
318 
319  glBindBuffer(GL_ARRAY_BUFFER, m_uvBuffer);
320  GLint uvIndex = Shader::uv;
321  glEnableVertexAttribArray(uvIndex);
322  glVertexAttribPointer(uvIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
323 
324  glBindBuffer(GL_ARRAY_BUFFER, m_boneIdBuffer);
325  GLint boneIdIndex = Shader::boneId;
326  glEnableVertexAttribArray(boneIdIndex);
327  glVertexAttribIPointer(boneIdIndex, 4, GL_INT, 0, 0);
328 
329  glBindBuffer(GL_ARRAY_BUFFER, m_boneWeightBuffer);
330  GLint boneWeightIndex = Shader::boneWeight;
331  glEnableVertexAttribArray(boneWeightIndex);
332  glVertexAttribPointer(boneWeightIndex, 4, GL_FLOAT, GL_FALSE, 0, 0);
333 
334  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer);
335  }
336  glBindVertexArray(0);
337  glBindBuffer(GL_ARRAY_BUFFER, 0);
338  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
339  }
340 
341  map<string, Node*> nodesByName;
342  list<pair<int,Node*>> nodes;
343 
344  // load scene
345  {
346  struct create_node
347  {
348  aiNode* assimpNode;
349  function<void(Node*)> storeResult;
350 
351  create_node(aiNode* _assimpNode, function<void(Node*)> _storeResult)
352  : assimpNode(_assimpNode)
353  , storeResult(_storeResult)
354  { }
355  };
356 
357  queue<create_node> todos;
358 
359  todos.push(create_node(scene->mRootNode, [this]
360  (Node* result)
361  {
362  m_root.reset(result);
363  }));
364 
365  {
366  auto temp = scene->mRootNode->mTransformation;
367  temp.Transpose();
368  m_inverseRootTransform = glm::inverse(*reinterpret_cast<mat4*>(&temp));
369  }
370 
371  while (!todos.empty())
372  {
373  auto& todo = todos.front();
374  auto& assimpNode = todo.assimpNode;
375 
376 
377  aiMatrix4x4 assimpLocal = assimpNode->mTransformation;
378  assimpLocal.Transpose();
379  mat4* local = reinterpret_cast<mat4*>(&assimpLocal);
380 
381  Node* node = new Node(this,*local);
382  todo.storeResult(node);
383  nodesByName[assimpNode->mName.C_Str()] = node;
384 
385  auto foundBone = bones.find(assimpNode->mName.C_Str());
386  if (foundBone != bones.end())
387  {
388  node->m_isBone = true;
389  nodes.push_back(pair<int,Node*>(foundBone->second,node));
390  }
391  else if (assimpNode->mNumMeshes != 0)
392  {
393  nodes.push_back(pair<int,Node*>(-1,node));
394  }
395 
396  node->m_meshes.resize(assimpNode->mNumMeshes);
397  for (size_t i = 0; i < assimpNode->mNumMeshes; i++)
398  {
399  node->m_meshes[i] = m_meshes[assimpNode->mMeshes[i]].get();
400  }
401 
402  node->m_children.reserve(assimpNode->mNumChildren);
403  for (size_t i = 0; i < assimpNode->mNumChildren; i++)
404  {
405  todos.push(create_node(assimpNode->mChildren[i], [node]
406  (Node* result)
407  {
408  node->m_children.push_back(unique_ptr<Node>(result));
409  }));
410  }
411 
412  todos.pop();
413  }
414  }
415 
416  // sort nodes
417  {
418  m_boneCount = bones.size();
419 
420  for (auto& node : nodes)
421  if (node.first == -1)
422  node.first = m_boneCount;
423 
424  // sort. first: all bones by their indices. then all others
425  nodes.sort([]
426  (pair<int,Node*> const & left, pair<int,Node*> const & right)
427  {
428  return left.first < right.first;
429  });
430 
431  int i = 0;
432  for (auto& node : nodes)
433  {
434  node.second->m_idx = i;
435 
436  for (auto& mesh : node.second->m_meshes)
437  mesh->m_nodeIndices.push_back(i);
438 
439  i++;
440  }
441 
442  m_drawNodeCount = nodes.size();
443  }
444 
445  // load animations
446  {
447  m_animationsDuration.clear();
448  m_animationsDuration.resize(scene->mNumAnimations);
449  for (size_t aid = 0; aid < scene->mNumAnimations; aid++)
450  {
451  auto& anim = scene->mAnimations[aid];
452 
453  auto ticks = 1.0 / (anim->mTicksPerSecond == 0 ? 25.0 : anim->mTicksPerSecond);
454 
455  m_animationsByName[anim->mName.C_Str()] = aid;
456  m_animationsDuration[aid] = (float)(anim->mDuration * ticks);
457 
458  for (size_t cid = 0; cid < anim->mNumChannels; cid++)
459  {
460  auto& chan = anim->mChannels[cid];
461  auto& node = nodesByName[chan->mNodeName.C_Str()]->m_animations[aid];
462 
463  node.m_positions.resize(chan->mNumPositionKeys);
464  for (size_t kid = 0; kid < chan->mNumPositionKeys; kid++)
465  {
466  auto& assimpKey = chan->mPositionKeys[kid];
467  auto& key = node.m_positions[kid];
468 
469  key.time = (float)(assimpKey.mTime * ticks);
470  key.value = vec3(assimpKey.mValue.x, assimpKey.mValue.y, assimpKey.mValue.z);
471  }
472  sort(node.m_positions.begin(), node.m_positions.end(), []
473  (NodeAnimation::Frame<vec3> const & left, NodeAnimation::Frame<vec3> const & right)
474  {
475  return left.time < right.time;
476  });
477 
478  node.m_rotations.resize(chan->mNumRotationKeys);
479  for (size_t kid = 0; kid < chan->mNumRotationKeys; kid++)
480  {
481  auto& assimpKey = chan->mRotationKeys[kid];
482  auto& key = node.m_rotations[kid];
483 
484  key.time = (float)(assimpKey.mTime * ticks);
485  key.value = quat(assimpKey.mValue.w, assimpKey.mValue.x, assimpKey.mValue.y, assimpKey.mValue.z);
486  }
487  sort(node.m_rotations.begin(), node.m_rotations.end(), []
488  (NodeAnimation::Frame<quat> const & left, NodeAnimation::Frame<quat> const & right)
489  {
490  return left.time < right.time;
491  });
492 
493  node.m_scalings.resize(chan->mNumScalingKeys);
494  for (size_t kid = 0; kid < chan->mNumScalingKeys; kid++)
495  {
496  auto& assimpKey = chan->mScalingKeys[kid];
497  auto& key = node.m_scalings[kid];
498 
499  key.time = (float)(assimpKey.mTime * ticks);
500  key.value = vec3(assimpKey.mValue.x, assimpKey.mValue.y, assimpKey.mValue.z);
501  }
502  sort(node.m_scalings.begin(), node.m_scalings.end(), []
503  (NodeAnimation::Frame<vec3> const & left, NodeAnimation::Frame<vec3> const & right)
504  {
505  return left.time < right.time;
506  });
507  }
508  }
509  }
510 
511 
512  // setup instance-buffers
513  {
514  glGenBuffers(1, &m_stateBuffer);
515  glBindBuffer(GL_TEXTURE_BUFFER, m_stateBuffer);
516  {
517  glBufferData( GL_TEXTURE_BUFFER, m_instancesInBuffer*m_boneCount*sizeof(mat4), nullptr, GL_STREAM_DRAW );
518  }
519  glBindBuffer(GL_TEXTURE_BUFFER, 0);
520 
521  glGenTextures(1, &m_stateTBO);
522  glBindTexture(GL_TEXTURE_BUFFER, m_stateTBO);
523  {
524  glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_stateBuffer);
525  }
526  glBindTexture(GL_TEXTURE_BUFFER, 0);
527 
528 
529  glGenBuffers(1, &m_idBuffer);
530  glBindBuffer(GL_TEXTURE_BUFFER, m_idBuffer);
531  {
532  glBufferData( GL_TEXTURE_BUFFER, m_instancesInBuffer*sizeof(id_t), nullptr, GL_DYNAMIC_DRAW );
533  }
534  glBindBuffer(GL_TEXTURE_BUFFER, 0);
535 
536  glGenTextures(1, &m_idTBO);
537  glBindTexture(GL_TEXTURE_BUFFER, m_idTBO);
538  {
539  glTexBuffer(GL_TEXTURE_BUFFER, GL_ID_FORMAT, m_idBuffer);
540  }
541  glBindTexture(GL_TEXTURE_BUFFER, 0);
542  }
543 }
545 {
546  glDeleteBuffers(1, &m_positionsBuffer);
547  glDeleteBuffers(1, &m_normalsBuffer);
548  glDeleteBuffers(1, &m_uvBuffer);
549  glDeleteBuffers(1, &m_boneIdBuffer);
550  glDeleteBuffers(1, &m_boneWeightBuffer);
551  glDeleteBuffers(1, &m_indicesBuffer);
552  glDeleteVertexArrays(1, &m_vao);
553 
554  glDeleteTextures(1, &m_stateTBO);
555  glDeleteBuffers(1, &m_stateBuffer);
556 }
557 void Scene::updateAllInstances(float const time)
558 {
559  if (m_instances.empty())
560  return;
561 
562  size_t const minInstancesForParallel = 20;
563 
564  if (m_app->getConfig().skinnningMultiThreaded() && (m_instances.size() >= minInstancesForParallel))
565  {
566  for (auto& instance : m_instances)
567  m_app->getTasks().schedule([this, &instance, time]() { updateInstance(instance, time); }, &m_parallelEvent);
568 
569  m_parallelEvent.wait(m_instances.size());
570  }
571  else
572  {
573  for (auto& instance : m_instances)
574  updateInstance(instance, time);
575  }
576 }
577 void Scene::updateInstance(SceneInstance* instance, float const time)
578 {
579  float instanceTime = time;
580  if (instance->m_animation.animation >= 0 && instance->m_animation.animation < (int)m_animationsDuration.size())
581  instanceTime = fmod(instance->m_animation.time + instanceTime, m_animationsDuration[instance->m_animation.animation]);
582 
583  m_root->updateInstance(*instance, instanceTime, instance->getTransform().getMatrix());
584 }
586 {
587  shader->uniform("statesPerInstance", (int)m_boneCount);
588 
589  // Push instance-data to GPU
590  {
591  bool needBufferResize = m_instancesInBuffer != m_instances.size();
593 
594  // push states
595  glBindBuffer(GL_TEXTURE_BUFFER, m_stateBuffer);
596  {
597  if (needBufferResize)
598  glBufferData(GL_TEXTURE_BUFFER, m_boneCount*m_instancesInBuffer*sizeof(mat4), NULL, GL_STREAM_DRAW);
599 
600  mat4 * states = (mat4 *)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY);
601  {
602  size_t instanceIdx = 0;
603  for (auto& instance : m_instances)
604  {
605  for (size_t i = 0; i < m_boneCount; i++)
606  states[instanceIdx*m_boneCount + i] = instance->m_state[i];
607 
608  instanceIdx++;
609  }
610  }
611  glUnmapBuffer(GL_TEXTURE_BUFFER);
612  }
613 
614  // push ids
615  if (m_needToUpdateIdBuffer || needBufferResize)
616  {
617  glBindBuffer(GL_TEXTURE_BUFFER, m_idBuffer);
618  {
619  if (needBufferResize)
620  glBufferData(GL_TEXTURE_BUFFER, m_instancesInBuffer*sizeof(id_t), NULL, GL_STREAM_DRAW);
621 
622  id_t * ids = (id_t *)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY);
623 
624  size_t instanceIdx = 0;
625  for (auto& instance : m_instances)
626  {
627  ids[instanceIdx] = instance->getPickId();
628  instanceIdx++;
629  }
630 
631  glUnmapBuffer(GL_TEXTURE_BUFFER);
632  }
633  glBindBuffer(GL_TEXTURE_BUFFER, 0);
634 
635  m_needToUpdateIdBuffer = false;
636  }
637  }
638 
639  // draw all instances
640  {
641  glActiveTexture(GL_TEXTURE1);
642  glBindTexture(GL_TEXTURE_BUFFER, m_stateTBO);
643  glActiveTexture(GL_TEXTURE2);
644  glBindTexture(GL_TEXTURE_BUFFER, m_idTBO);
645  {
646  glBindVertexArray(m_vao);
647  {
648  for (auto& mesh : m_meshes)
649  mesh->drawInstances(shader, m_instances);
650  }
651  glBindVertexArray(0);
652  }
653  glActiveTexture(GL_TEXTURE1);
654  glBindTexture(GL_TEXTURE_BUFFER, 0);
655  glActiveTexture(GL_TEXTURE2);
656  glBindTexture(GL_TEXTURE_BUFFER, 0);
657  glActiveTexture(GL_TEXTURE0);
658  }
659 }
660 void Scene::updateNdraw(DrawArgs& args, Shader* shader)
661 {
662  updateAllInstances((float)args.time);
663 
664  drawAllInstances(args, shader);
665 }
667 {
668  SceneInstance* instance = new SceneInstance(m_app, this, pickable);
669  m_instances.insert(instance);
670 
671  m_app->getSceneGraph().add(instance);
672 
673  m_needToUpdateIdBuffer = true;
674 
675  return instance;
676 }
678 {
679  m_instances.erase(m_instances.find(obj));
680 
681  m_needToUpdateIdBuffer = true;
682 }
683 
684 
685 
686 
687 
688 
689 Scene::Material::Material(vec4 const & ambient, vec4 const & diffuse, vec4 const & specular, float const shininess, Texture* texture)
690  : m_texture(texture)
691  , m_ubuffer(0)
692 {
693  data buffer_data;
694  buffer_data.ambient = ambient;
695  buffer_data.diffuse = diffuse;
696  buffer_data.specular = specular;
697  buffer_data.shininess = shininess;
698 
699  glGenBuffers(1,&m_ubuffer);
700  glBindBuffer(GL_UNIFORM_BUFFER, m_ubuffer);
701  {
702  glBufferData(GL_UNIFORM_BUFFER, sizeof(data), &buffer_data, GL_STATIC_DRAW);
703  }
704  glBindBuffer(GL_UNIFORM_BUFFER, 0);
705 }
707 {
708  glDeleteBuffers(1, &m_ubuffer);
709 }
710 void Scene::Material::bindTo(Shader * shader, string const uniform)
711 {
712  if (m_texture)
713  m_texture->bind(0);
714  else
715  cerr << "no texture found" << endl;
716 
717  glBindBufferRange(GL_UNIFORM_BUFFER, shader->uniformBlock(uniform), m_ubuffer, 0, sizeof(data));
718 }
719 
720 
721 
722 
723 
724 
725 
726 
727 Scene::Mesh::Mesh(Scene* scene, string const & name, GLuint const baseIdx, GLuint const idxCount, Material* material)
728  : m_scene(scene)
729  , m_name(name)
730  , m_material(material)
731  , m_indexCount(idxCount)
732  , m_baseIndex(baseIdx)
733 { }
734 void Scene::Mesh::drawInstances(Shader* shader, set<SceneInstance*> const & instances)
735 {
736  m_material->bindTo(shader, "material");
737 
738  glDrawElementsInstanced(GL_TRIANGLES,
739  m_indexCount,
740  GL_UNSIGNED_INT,
741  reinterpret_cast<GLuint const*>(0) + m_baseIndex,
742  instances.size());
743 }
744 
745 
746 
747 
748 
749 
750 
751 
752 bool Scene::NodeAnimation::transformationByTime(float const time, OUT mat4& result)
753 {
754  result =
755  glm::translate(mat4(1), interpolate(m_positions, time))
756  * glm::mat4_cast(interpolate(m_rotations, time))
757  * glm::scale(mat4(1), interpolate(m_scalings, time));
758 
759  return true;
760 }
761 
762 
763 
764 
765 
766 
767 
768 
769 Scene::Node::Node(Scene* scene, mat4 const & local)
770  : m_local(local)
771  , m_idx(-1)
772  , m_scene(scene)
773  , m_isBone(false)
774 { }
775 void Scene::Node::updateInstance(SceneInstance& instance, float time, mat4 const & parentTransformation)
776 {
777  auto model = parentTransformation * transformationByTime(instance.m_animation.animation, time);
778 
779  if (m_isBone)
780  {
781  //instance.m_state[m_idx] = m_scene->m_inverseRootTransform * m_scene->m_boneOffsets[m_idx] * model;
782  instance.m_state[m_idx] = model * m_scene->m_boneOffsets[m_idx]; // *m_scene->m_inverseRootTransform* / ;
783  }
784  else if (m_idx != -1)
785  {
786  //instance.m_state[m_idx] = model;
787  }
788 
789  for (auto& child : m_children)
790  child->updateInstance(instance, time, model);
791 }
792 mat4 Scene::Node::transformationByTime(uint const animation, float const time)
793 {
794  auto& found = m_animations.find(animation);
795 
796  if (found == m_animations.end())
797  return m_local;
798 
799  mat4 result;
800  if (!found->second.transformationByTime(time, OUT result))
801  return m_local;
802 
803  return result;
804 }
805 
806 
807 
808 
809 
810 
811 
812 
813 
815  : m_app(app)
816  , m_shader(app->getShaders().get("scene.mesh"))
817 {
818  m_shader->use();
819  m_shader->uniform("texDiffuse", 0);
820  m_shader->uniform("states", 1);
821  m_shader->uniform("ids", 2);
822 
823 
825  cout << "Skinning-Mode: multi-threaded" << endl;
826  else
827  cout << "Skinning-Mode: single-threaded" << endl;
828 }
829 Scene* Scenes::get(string const & name)
830 {
831  auto found = m_scenes.find(name);
832 
833  if (found == m_scenes.end())
834  {
835  auto& instance = m_scenes[name];
836  instance.reset(new Scene(m_app, name));
837  return instance.get();
838  }
839 
840  return found->second.get();
841 }
843 {
844  m_shader->use();
845 
846  m_shader->uniform("proj", *args.projectionMatrix);
847  m_shader->uniform("view", *args.viewMatrix);
848 
849  for(auto& mesh : m_scenes)
850  mesh.second->updateNdraw(args, m_shader);
851 }
void use()
Definition: Shader.cpp:111
GLuint m_vao
Definition: Scene.hpp:328
double time
Definition: SceneFBO.hpp:10
SceneInstance * createInstance(bool pickable=true)
Definition: Scene.cpp:666
uint16 id_t
The data-type used for the id-buffer.
Definition: Util.hpp:6
unique_ptr< Node > m_root
Definition: Scene.hpp:309
TaskManager & getTasks()
Configuration & getConfig()
Definition: Application.hpp:36
vector< unique_ptr< Material > > m_materials
Definition: Scene.hpp:307
#define GL_ID_FORMAT
The OpenGL-format used for the id-buffer (has to match id_t)
Definition: Util.hpp:12
void unregisterInstance(SceneInstance *obj)
Definition: Scene.cpp:677
Application * m_app
Definition: Scene.hpp:311
vector< unique_ptr< Node > > m_children
Definition: Scene.hpp:271
size_t m_instancesInBuffer
Definition: Scene.hpp:319
static const uint boneWeight
Definition: Shader.hpp:126
GLuint m_ubuffer
Definition: Scene.hpp:104
void bindTo(Shader *shader, string const uniform)
Definition: Scene.cpp:710
GLuint m_idTBO
Definition: Scene.hpp:331
bool const needsRecalc()
void drawAll(DrawArgs &args)
Definition: Scene.cpp:842
t_obj & add(t_obj *object)
Definition: SceneGraph.hpp:42
mat4 const & getMatrix()
Transformation m_transformation
Definition: Scene.hpp:33
mesh_map m_scenes
Definition: Scene.hpp:396
Definition: Shader.hpp:8
void updateAllInstances(float const time)
Definition: Scene.cpp:557
mat4 const * viewMatrix
Definition: SceneFBO.hpp:13
Scene(Application *app, string const &name)
Definition: Scene.cpp:45
GLuint m_boneIdBuffer
Definition: Scene.hpp:325
static const uint position
Definition: Shader.hpp:122
vector< float > m_animationsDuration
Definition: Scene.hpp:313
static const uint uv
Definition: Shader.hpp:124
void updateInstance(SceneInstance *instance, float const time)
Definition: Scene.cpp:577
Scene * get(string const &name)
Definition: Scene.cpp:829
Scene * m_scene
Definition: Scene.hpp:32
void schedule(T fnc)
Definition: TaskManager.hpp:86
size_t m_boneCount
Definition: Scene.hpp:314
Material(vec4 const &ambient, vec4 const &diffuse, vec4 const &specular, float const shininess, Texture *texture)
Definition: Scene.cpp:689
bool transformationByTime(float const time, OUT mat4 &result)
Definition: Scene.cpp:752
Application * m_app
Definition: Scene.hpp:397
Transformation & getTransform()
Definition: Scene.hpp:45
GLuint m_indicesBuffer
Definition: Scene.hpp:327
GLuint m_stateTBO
Definition: Scene.hpp:329
SceneInstance(Application *app, Scene *parent, bool pickable=true)
Definition: Scene.cpp:3
Scenes(Application *app)
Definition: Scene.cpp:814
bool m_needToUpdateIdBuffer
Definition: Scene.hpp:320
bool skinnningMultiThreaded() const
Node(Scene *scene, mat4 const &local)
Definition: Scene.cpp:769
vector< unique_ptr< Mesh > > m_meshes
Definition: Scene.hpp:308
Textures & getTextures()
Definition: Application.hpp:46
SceneGraph & getSceneGraph()
Definition: Application.hpp:56
void updateNdraw(DrawArgs &args, Shader *shader)
Definition: Scene.cpp:660
mat4 transformationByTime(uint const animation, float const time)
Definition: Scene.cpp:792
void queueAnimation(float time, uint animation)
Definition: Scene.cpp:32
GLuint m_uvBuffer
Definition: Scene.hpp:323
friend class SceneInstance
Definition: Scene.hpp:334
mat4 const * projectionMatrix
Definition: SceneFBO.hpp:12
mat4 m_inverseRootTransform
Definition: Scene.hpp:317
vector< mat4 > m_boneOffsets
Definition: Scene.hpp:316
~Scene()
Definition: Scene.cpp:544
Shader * m_shader
Definition: Scene.hpp:398
virtual bool update(double time, double timeDelta)
Definition: Scene.cpp:14
void updateInstance(SceneInstance &instance, float time, mat4 const &parentTransformation)
Definition: Scene.cpp:775
virtual ~SceneInstance()
Definition: Scene.cpp:10
Mesh(Scene *scene, string const &name, GLuint const baseIdx, GLuint const idxCount, Material *material)
Definition: Scene.cpp:727
GLuint m_idBuffer
Definition: Scene.hpp:332
vector< Mesh * > m_meshes
Definition: Scene.hpp:272
set< SceneInstance * > m_instances
Definition: Scene.hpp:310
GLint uniformBlock(string const &name)
Definition: Shader.cpp:125
GLuint m_positionsBuffer
Definition: Scene.hpp:322
Definition: Scene.hpp:86
queue< AnimationStart > m_animationQueue
Definition: Scene.hpp:36
GLuint m_normalsBuffer
Definition: Scene.hpp:324
string m_name
Definition: Scene.hpp:306
Texture * get(string const &name)
Definition: Texture.cpp:71
void drawInstances(Shader *shader, set< SceneInstance * > const &instances)
Definition: Scene.cpp:734
size_t m_drawNodeCount
Definition: Scene.hpp:315
void wait(uint nTimes=1)
Wait (block) until the event is set to signaled-mode.
Definition: TaskManager.cpp:61
GLuint m_boneWeightBuffer
Definition: Scene.hpp:326
vector< mat4 > m_state
Definition: Scene.hpp:34
static const uint normal
Definition: Shader.hpp:123
bool m_isBone
Definition: Scene.hpp:275
auto_reset_event m_parallelEvent
Definition: Scene.hpp:305
map< string, int > m_animationsByName
Definition: Scene.hpp:312
AnimationStart m_animation
Definition: Scene.hpp:35
static const uint boneId
Definition: Shader.hpp:125
GLuint m_stateBuffer
Definition: Scene.hpp:330
GLint uniform(string const &name)
Definition: Shader.cpp:115
void drawAllInstances(DrawArgs &args, Shader *shader)
Definition: Scene.cpp:585