OSDN Git Service

ボーンのトランスフォーム計算機能を追加
authorqw_fuku <fkhideaki@gmail.com>
Mon, 19 Jan 2015 16:08:54 +0000 (01:08 +0900)
committerqw_fuku <fkhideaki@gmail.com>
Mon, 19 Jan 2015 16:08:54 +0000 (01:08 +0900)
Src/LibQtGeoViewerCore/Bone.cpp
Src/LibQtGeoViewerCore/Bone.h
Src/LibQtGeoViewerCore/Format/AssimpReader.cpp
Src/LibQtGeoViewerCore/Format/AssimpReader.h
Src/LibQtGeoViewerCore/SkinningDeformer.cpp [new file with mode: 0644]
Src/LibQtGeoViewerCore/SkinningDeformer.h [new file with mode: 0644]

index b1a5378..c9a324f 100644 (file)
@@ -6,11 +6,36 @@ namespace geom
 {
 
 
+bool Bone::HaSequence(void) const
+{
+       return GetNumFrames() != 0;
+}
+
+int Bone::GetNumFrames(void) const
+{
+       size_t max_frame = 0;
+       max_frame = (std::max)(max_frame, m_Translate.size());
+       max_frame = (std::max)(max_frame, m_Scale.size());
+       max_frame = (std::max)(max_frame, m_Rotate.size());
+
+       return ConvertFrameAbsToPositive(max_frame);
+}
+
 lm::matrix4f Bone::GetFrameMatrix(int frame)
 {
+       // \96¢\92è\8b`\83t\83\8c\81[\83\80\94Ô\8d\86\82ª\8ew\92è\82³\82ê\82½\8fê\8d\87\82Í\83m\81[\83h\82Ì\83g\83\89\83\93\83X\83t\83H\81[\83\80\82ð\95Ô\82·
+       if (frame < 0)
+               return GetNodeTransform();
+
+       // \83V\81[\83P\83\93\83X\82ð\8e\9d\82½\82È\82¢\83{\81[\83\93\82Í\83m\81[\83h\82Ì\83g\83\89\83\93\83X\83t\83H\81[\83\80\82ð\95Ô\82·
+       if (!HaSequence())
+               return GetNodeTransform();
+
        lm::matrix4f mt = lm::matrix4f::get_identity();
 
-       if(!m_Rotate.empty())
+       frame = ConvertFramePositiveToAbs(frame);
+
+       if (!m_Rotate.empty())
        {
                float vel;
                lm::vec3f ax;
@@ -18,13 +43,13 @@ lm::matrix4f Bone::GetFrameMatrix(int frame)
                mt *= lm::matrix4f::get_rotate(ax, vel);
        }
 
-       if(!m_Scale.empty())
+       if (!m_Scale.empty())
        {
-               lm::vec3f s = m_Scale[frame];
+               const lm::vec3f& s = m_Scale[frame];
                mt *= lm::matrix4f::get_scale(s.x, s.y, s.z);
        }
 
-       if(!m_Translate.empty())
+       if (!m_Translate.empty())
        {
                lm::vec3f d = m_Translate[frame];
                mt *= lm::matrix4f::get_translate(d);
@@ -33,5 +58,20 @@ lm::matrix4f Bone::GetFrameMatrix(int frame)
        return mt;
 }
 
+lm::matrix4f Bone::GetNodeTransform(void) const
+{
+       return m_NodeTrans * lm::matrix4f::get_translate(lm::vec3f(0.0f, 0.0f, 0.0f));
+}
+
+int Bone::ConvertFrameAbsToPositive(int f) const
+{
+       return f - m_KeyIdxOffset;
+}
+
+int Bone::ConvertFramePositiveToAbs(int f) const
+{
+       return f + m_KeyIdxOffset;
+}
+
 
 }
index 8a3fdc0..6b8083b 100644 (file)
@@ -24,13 +24,30 @@ public:
 class Bone
 {
 public:
+       Bone(void)
+       {
+               m_Index = -1;
+               m_Parent = NULL;
+               m_KeyIdxOffset = 0;
+       }
+
+       bool HaSequence(void) const;
+       int GetNumFrames(void) const;
+
        lm::matrix4f GetFrameMatrix(int frame);
+       lm::matrix4f GetNodeTransform(void) const;
+
+private:
+       int ConvertFrameAbsToPositive(int f) const;
+       int ConvertFramePositiveToAbs(int f) const;
 
 public:
        int m_Index;
        std::string m_Name;
        Bone* m_Parent;
 
+       int m_KeyIdxOffset;
+
        lm::matrix4f m_NodeTrans;
 
        std::vector<BoneWeight> m_Weights;
index 9803a03..1816e20 100644 (file)
@@ -205,5 +205,22 @@ void AssimpReader::LoadAnimation(const aiScene* ai_scene, BoneMap& bone_map)
                {
                        ae::AiQuatToLmQuat(bone->m_Rotate[k], ch->mRotationKeys[k].mValue);
                }
+
+               bone->m_KeyIdxOffset = GetNumMinusKeyFrames(ch);
+       }
+}
+
+// 0\95b\96¢\96\9e\82Ì\83L\81[\83t\83\8c\81[\83\80\90\94\82ð\90\94\82¦\82é
+int AssimpReader::GetNumMinusKeyFrames(const aiNodeAnim* ch) const
+{
+       for(int i = 0; i < ch->mNumPositionKeys; ++i)
+       {
+               if(ch->mPositionKeys[i].mTime >= 0)
+                       return i;
        }
+
+       // \91S\83t\83\8c\81[\83\80\82ª0\95b\96¢\96\9e
+       assert(false);
+
+       return ch->mNumPositionKeys;
 }
index d8406b2..05127e3 100644 (file)
@@ -10,6 +10,7 @@ class SceneMain;
 class aiScene;
 class aiMesh;
 class aiBone;
+class aiNodeAnim;
 
 
 class AssimpReader
@@ -23,4 +24,5 @@ private:
        void ResetBone(geom::GeomObject* geom, geom::BoneMap& bone_map, aiMesh* mesh);
        void ConvertBoneWeight(const aiBone* s_bone, geom::Bone& d_bone);
        void LoadAnimation(const aiScene* ai_scene, geom::BoneMap& bone_map);
+       int GetNumMinusKeyFrames(const aiNodeAnim* ch) const;
 };
diff --git a/Src/LibQtGeoViewerCore/SkinningDeformer.cpp b/Src/LibQtGeoViewerCore/SkinningDeformer.cpp
new file mode 100644 (file)
index 0000000..fd4f341
--- /dev/null
@@ -0,0 +1 @@
+#include "stdafx.h"
diff --git a/Src/LibQtGeoViewerCore/SkinningDeformer.h b/Src/LibQtGeoViewerCore/SkinningDeformer.h
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once