<commit_before>#pragma once

#include <map>
#include <unordered_map>
#include <functional>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/mat4x4.hpp>

// assimp::Importer
#include <assimp/Importer.hpp>
// aiPostProcessSteps for assimp::Importer::ReadFile
#include <assimp/postprocess.h>
// aiScene, aiNode
#include <assimp/scene.h>

//#include "glew.detail/c.hxx"
//#include "glew.detail/gl_type.hxx"

#include "helper.hxx"
#include "material.hxx"
#include "mesh.hxx"
#include "node.hxx"
#include "bone.hxx"
#include "animation_data.hxx"

namespace wonder_rabbit_project
{
  namespace wonderland
  {
    namespace renderer
    {
      namespace model
      {
        class model_t
        {
          // アニメーションデータ
          std::unordered_map< std::string, animation_t > _animations;
          
          // ボーン名 -> ボーンID
          std::unordered_map< std::string, unsigned > _bone_name_to_bone_index_mapping;
          
          // ボーンオフセット群
          std::vector< glm::mat4 > _bone_offsets;
          
          // アニメーション名
          std::vector< std::string > _animation_names;
          
          // モデルデータに含まれるマテリアル群を格納
          std::vector< material_t > _materials;
          
          // モデルデータに含まれるメッシュ群を格納
          std::vector< mesh_t > _meshes;
          
          // ノード
          node_t _node;
          
          // ルートノードの変形行列の逆行列（アニメーション適用で使用）
          glm::mat4 _global_inverse_transformation;
          
          inline auto apply_animation_recursive
          ( const animation_states_t& animation_states
          , const node_t& node
          , std::vector< glm::mat4 >& bone_animation_transformations
          , const glm::mat4& parent_transformation
          )
            -> void
          {
            for ( auto& animation_state : animation_states )
            {
              glm::mat4 node_transformation( node.transformation() );
              
              auto animation_iterator = _animations.find( animation_state.name );
              
              if( animation_iterator not_eq _animations.end() )
                node_transformation = animation_iterator -> second.transformation( node.name(), animation_state.time );
              else
                continue;
              
              const auto global_transformation = parent_transformation * node_transformation;
              
              const auto bone_name_to_index_iterator = _bone_name_to_bone_index_mapping.find( node.name() );
              if( bone_name_to_index_iterator not_eq _bone_name_to_bone_index_mapping.end() )
              {<commit_msg>related #24 throw exception if animation name is not found, but continue if name is empty string.<commit_after>#pragma once

#include <map>
#include <unordered_map>
#include <functional>

#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/mat4x4.hpp>

// assimp::Importer
#include <assimp/Importer.hpp>
// aiPostProcessSteps for assimp::Importer::ReadFile
#include <assimp/postprocess.h>
// aiScene, aiNode
#include <assimp/scene.h>

//#include "glew.detail/c.hxx"
//#include "glew.detail/gl_type.hxx"

#include "helper.hxx"
#include "material.hxx"
#include "mesh.hxx"
#include "node.hxx"
#include "bone.hxx"
#include "animation_data.hxx"

namespace wonder_rabbit_project
{
  namespace wonderland
  {
    namespace renderer
    {
      namespace model
      {
        class model_t
        {
          // アニメーションデータ
          std::unordered_map< std::string, animation_t > _animations;
          
          // ボーン名 -> ボーンID
          std::unordered_map< std::string, unsigned > _bone_name_to_bone_index_mapping;
          
          // ボーンオフセット群
          std::vector< glm::mat4 > _bone_offsets;
          
          // アニメーション名
          std::vector< std::string > _animation_names;
          
          // モデルデータに含まれるマテリアル群を格納
          std::vector< material_t > _materials;
          
          // モデルデータに含まれるメッシュ群を格納
          std::vector< mesh_t > _meshes;
          
          // ノード
          node_t _node;
          
          // ルートノードの変形行列の逆行列（アニメーション適用で使用）
          glm::mat4 _global_inverse_transformation;
          
          inline auto apply_animation_recursive
          ( const animation_states_t& animation_states
          , const node_t& node
          , std::vector< glm::mat4 >& bone_animation_transformations
          , const glm::mat4& parent_transformation
          )
            -> void
          {
            for ( auto& animation_state : animation_states )
            {
              glm::mat4 node_transformation( node.transformation() );
              
              if ( animation_state.name == "" )
              {
                //std::cerr << "warn: empty animation name.\n";
                continue;
              }
              
              auto animation_iterator = _animations.find( animation_state.name );
              
              if( animation_iterator not_eq _animations.end() )
                node_transformation = animation_iterator -> second.transformation( node.name(), animation_state.time );
              else
                throw std::runtime_error( std::string( "animation_state.name " ) + animation_state.name + " is not found." );
              
              const auto global_transformation = parent_transformation * node_transformation;
              
              const auto bone_name_to_index_iterator = _bone_name_to_bone_index_mapping.find( node.name() );
              if( bone_name_to_index_iterator not_eq _bone_name_to_bone_index_mapping.end() )
              {
{'fraction_non_alphanumeric': 0.09375559134013241, 'fraction_numerical': 0.0028627661477903022, 'mean_word_length': 2.0232558139534884, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '682439', 'n_tokens_mistral': 1795, 'n_tokens_neox': 1793, 'n_words': 305}