हाल ही में मैं हड्डी एनीमेशन आयात पर काम कर रहा हूं, इसलिए मैंने एसिंप एनीमेशन आयात का परीक्षण करने के लिए कुछ आईके तकनीक के साथ 3 डी Minecraft-like मॉडल बनाया। औपुत प्रारूप COLLADA (*। डीएई) है, और मैंने जो टूल इस्तेमाल किया वह ब्लेंडर है। प्रोग्रामिंग पक्ष पर, मेरा पर्यावरण opengl/glm/assimp है। मुझे लगता है कि मेरी समस्या के लिए ये जानकारी पर्याप्त है। एक बात, मॉडल की एनीमेशन, मैं सिर्फ assimp एनीमेशन परीक्षण के लिए 7 unmove keyframe रिकॉर्ड।असंप एनीमेशन हड्डी परिवर्तन
सबसे पहले, मुझे लगता है कि स्थानीय परिवर्तन भाग को छोड़कर मेरा परिवर्तन सही है, इसलिए फ़ंक्शन केवल glm::mat4(1.0f)
लौटाएं, और परिणाम बाइंड पॉज़ (सुनिश्चित नहीं) मॉडल दिखाएं। (नीचे छवि देखें)
दूसरा, मूल्य glm::mat4(1.0f)
से bone->localTransform = transform * scaling * glm::mat4(1.0f);
पर वापस करें, फिर मॉडल विकृति। ब्लेंडर में टेस्ट छवि और मॉडल (छवि नीचे देखें)
: (bone->localTransform = glm::mat4(1.0f) * scaling * rotate;
: इस छवि को जमीन :(किया जा रहा है):
void MeshModel::UpdateAnimations(float time, std::vector<Bone*>& bones)
{
for each (Bone* bone in bones)
{
glm::mat4 rotate = GetInterpolateRotation(time, bone->rotationKeys);
glm::mat4 transform = GetInterpolateTransform(time, bone->transformKeys);
glm::mat4 scaling = GetInterpolateScaling(time, bone->scalingKeys);
//bone->localTransform = transform * scaling * glm::mat4(1.0f);
//bone->localTransform = glm::mat4(1.0f) * scaling * rotate;
//bone->localTransform = glm::translate(glm::mat4(1.0f), glm::vec3(0.5f));
bone->localTransform = glm::mat4(1.0f);
}
}
void MeshModel::UpdateBone(Bone * bone)
{
glm::mat4 parentTransform = bone->getParentTransform();
bone->nodeTransform = parentTransform
* bone->transform // assimp_node->mTransformation
* bone->localTransform; // T S R matrix
bone->finalTransform = globalInverse
* bone->nodeTransform
* bone->inverseBindPoseMatrix; // ai_mesh->mBones[i]->mOffsetMatrix
for (int i = 0; i < (int)bone->children.size(); i++) {
UpdateBone(bone->children[i]);
}
}
glm::mat4 Bone::getParentTransform()
{
if (this->parent != nullptr)
return parent->nodeTransform;
else
return glm::mat4(1.0f);
}
glm::mat4 MeshModel::GetInterpolateRotation(float time, std::vector<BoneKey>& keys)
{
// we need at least two values to interpolate...
if ((int)keys.size() == 0) {
return glm::mat4(1.0f);
}
if ((int)keys.size() == 1) {
return glm::mat4_cast(keys[0].rotation);
}
int rotationIndex = FindBestTimeIndex(time, keys);
int nextRotationIndex = (rotationIndex + 1);
assert(nextRotationIndex < (int)keys.size());
float DeltaTime = (float)(keys[nextRotationIndex].time - keys[rotationIndex].time);
float Factor = (time - (float)keys[rotationIndex].time)/DeltaTime;
if (Factor < 0.0f)
Factor = 0.0f;
if (Factor > 1.0f)
Factor = 1.0f;
assert(Factor >= 0.0f && Factor <= 1.0f);
const glm::quat& startRotationQ = keys[rotationIndex].rotation;
const glm::quat& endRotationQ = keys[nextRotationIndex].rotation;
glm::quat interpolateQ = glm::lerp(endRotationQ, startRotationQ, Factor);
interpolateQ = glm::normalize(interpolateQ);
return glm::mat4_cast(interpolateQ);
}
glm::mat4 MeshModel::GetInterpolateTransform(float time, std::vector<BoneKey>& keys)
{
// we need at least two values to interpolate...
if ((int)keys.size() == 0) {
return glm::mat4(1.0f);
}
if ((int)keys.size() == 1) {
return glm::translate(glm::mat4(1.0f), keys[0].vector);
}
int translateIndex = FindBestTimeIndex(time, keys);
int nextTranslateIndex = (translateIndex + 1);
assert(nextTranslateIndex < (int)keys.size());
float DeltaTime = (float)(keys[nextTranslateIndex].time - keys[translateIndex].time);
float Factor = (time - (float)keys[translateIndex].time)/DeltaTime;
if (Factor < 0.0f)
Factor = 0.0f;
if (Factor > 1.0f)
Factor = 1.0f;
assert(Factor >= 0.0f && Factor <= 1.0f);
const glm::vec3& startTranslate = keys[translateIndex].vector;
const glm::vec3& endTrabslate = keys[nextTranslateIndex].vector;
glm::vec3 delta = endTrabslate - startTranslate;
glm::vec3 resultVec = startTranslate + delta * Factor;
return glm::translate(glm::mat4(1.0f), resultVec);
}
कोड विचार संदर्भित है
यहाँ कोड Matrix calculations for gpu skinning और Skeletal Animation With Assimp से
कुल मिलाकर, मैं assimp से मेशमोडेल तक सभी जानकारी fectch और इसे हड्डी संरचना में बचाने के लिए, तो मुझे लगता है कि जानकारी ठीक है?
आखिरी बात, मेरी शीर्ष शेडर कोड:
#version 330 core
#define MAX_BONES_PER_VERTEX 4
in vec3 position;
in vec2 texCoord;
in vec3 normal;
in ivec4 boneID;
in vec4 boneWeight;
const int MAX_BONES = 100;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform mat4 boneTransform[MAX_BONES];
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoords;
out float Visibility;
const float density = 0.007f;
const float gradient = 1.5f;
void main()
{
mat4 boneTransformation = boneTransform[boneID[0]] * boneWeight[0];
boneTransformation += boneTransform[boneID[1]] * boneWeight[1];
boneTransformation += boneTransform[boneID[2]] * boneWeight[2];
boneTransformation += boneTransform[boneID[3]] * boneWeight[3];
vec3 usingPosition = (boneTransformation * vec4(position, 1.0)).xyz;
vec3 usingNormal = (boneTransformation * vec4(normal, 1.0)).xyz;
vec4 viewPos = view * model * vec4(usingPosition, 1.0);
gl_Position = projection * viewPos;
FragPos = vec3(model * vec4(usingPosition, 1.0f));
Normal = mat3(transpose(inverse(model))) * usingNormal;
TexCoords = texCoord;
float distance = length(viewPos.xyz);
Visibility = exp(-pow(distance * density, gradient));
Visibility = clamp(Visibility, 0.0f, 1.0f);
}
मेरे सवाल इसके बाद के संस्करण, कोड की कमी या अस्पष्ट वर्णन है, तो कृपया मुझे बताएं, तो धन्यवाद!
संपादित करें: (1)
अतिरिक्त में, इस तरह मेरे हड्डी जानकारी (कोड प्राप्त करने में कठिनाई भाग):
for (int i = 0; i < (int)nodeAnim->mNumPositionKeys; i++)
{
BoneKey key;
key.time = nodeAnim->mPositionKeys[i].mTime;
aiVector3D vec = nodeAnim->mPositionKeys[i].mValue;
key.vector = glm::vec3(vec.x, vec.y, vec.z);
currentBone->transformKeys.push_back(key);
}
कुछ परिवर्तन वेक्टर था, तो मेरे कोड glm::mat4 transform = GetInterpolateTransform(time, bone->transformKeys);
ऊपर, Absloutely, मिल उसी मूल्य से। मुझे यकीन नहीं है कि मैंने नामांकित कीफ्रेम एनीमेशन बनाया है जो ट्रांसफॉर्म मान प्रदान करता है या नहीं (बेशक इसमें 7 कीफ्रेम है)।
इस (सिर की हड्डी पर डिबग) की तरह एक-फ़्रेम सामग्री: 7 विभिन्न कीफ़्रेम, एक ही वेक्टर मूल्य।
संपादित करें: (2)
तुम मेरे डे फ़ाइल का परीक्षण करना चाहते हैं, मैं यह jsfiddle में डाल दिया, आते हैं और इसे ले :)। एक और बात, एकता में मेरी फ़ाइल सही तरीके से काम करती है, इसलिए मुझे लगता है कि शायद मेरा स्थानीय परिवर्तन समस्या नहीं होती है, ऐसा लगता है कि समस्या कुछ अन्य माता-पिता ट्रान्सफॉर्म या हड्डी-> ट्रांसफॉर्म ... आदि जैसी हो सकती है? मैं भी सभी हड्डी के साथ स्थानीय ट्रांसफॉर्म मैट्रिक्स जोड़ता हूं, लेकिन यह पता नहीं लगा सकता कि क्यों COLLADA में मेरे अनमोल एनीमेशन के लिए इन मान हैं ...