Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

0 Neutral

About dragon-kurve

  • Rank

Personal Information

  • Role
  • Interests
  1. So I started with `dot(CameraVector, WorldNormal)` in vertex shader: Maybe I can make some progress based on this.
  2. What I'm trying to acheive is: source: https://forums.tigsource.com/index.php?topic=40832.msg1027183#msg1027183 Original author said he combine world normal and world position, but I can't reproduce this - if you have any idea, pleae comment it. It will be really appreciated!!
  3. UPDATE: I found that my method to get vertex skin weight/joint index was completely wrong. // joint index - vertex weight pair // Which is compelety wrong. std::vector<std::vector<std::pair<glm::u8, glm::f32>>> skinData{}; skinData.resize(mesh->GetControlPointsCount()); const auto deformerCount = mesh->GetDeformerCount(FbxDeformer::eSkin); for (int deformerIndex = 0; deformerIndex < deformerCount; ++deformerIndex) { auto skin = FbxCast<FbxSkin>(mesh->GetDeformer(deformerIndex, FbxDeformer::eSkin)); const auto clusterCount = skin->GetClusterCount(); for (int clusterIndex = 0; clusterIndex < clusterCount; ++clusterIndex) { const auto cluster = skin->GetCluster(clusterIndex); const auto link = cluster->GetLink(); const auto linkName = link->GetName(); const auto it = std::find_if(mCvtSkeleton.mJointList.begin(), mCvtSkeleton.mJointList.end(), [linkName](const auto& cvtJoint) { return cvtJoint.name == linkName; }); if (it == mCvtJointList.end()) { continue; // transformation of joint FbxAMatrix transformLinkMatrix{}; cluster->GetTransformLinkMatrix(transformLinkMatrix); // transformation of mesh FbxAMatrix transformMatrix{}; cluster->GetTransformMatrix(transformMatrix) it->invBindPose = makeMat4(transformLinkMatrix.Inverse() * transformMatrix); const auto skinIndicesCount = cluster->GetControlPointIndicesCount(); const auto skinIndices = cluster->GetControlPointIndices(); const auto skinWeights = cluster->GetControlPointWeights(); for (int skinIndex = 0; skinIndex < skinIndicesCount; ++skinIndex) { // This is the wrong part. I should use control point index instead of joint id. skinData[skinIndices[skinIndex]].emplace_back(it->id, makeF32(skinWeights[skinIndex])); } } } Then later, when I call FbxMesh::GetPolygonVertex(int pPolygonIndex, int pPositionInPolygon ) const -> int that returns control point index. That means I need someting like this struct CvtSkinInfo { glm::u8 mJointId; glm::u16 mCpIndex; glm::f32 mCpWeight; }; to correctly get joint id and vertex weight of a control point. I'll fix this and share again.
  4. I'm trying to implement skeletal animation using FBX SDK and OpenGL(with glm). First of all, let me show results. Above is original mesh, without animation. And this is the result. My method to generate matrices is: // joint is ordered by id, root id is 0 for (u8 i = 0; i < jointCount; ++i) { auto track = mCurrAnimation->track(i); // track is a list of key frames, which contains translation(vec3) and rotation(quat) auto& currKey = track->keys[mCurrKeyIndex]; // get current key frame auto& nextKey = track->keys[mNextKeyIndex]; // get next key frame auto& joint = mSkeleton->joints[i]; // get joint by id auto t = glm::mix(currKey.t, nextKey.t, alpha); // lerp translation auto q = glm::slerp(currKey.q, nextKey.q, alpha); // slerp rotation auto skinTransform = glm::translate(glm::mat4{1.0f}, t); skinTransform = skinTransform * glm::mat4_cast(q); glm::mat4 parentSkinTransform{1.0}; if (joint.parentId > 0) { // if not root parentSkinTransform = mJointMatrices[joint.parentId]; } mJointMatrices[i] = parentSkinTransform * skinTransform; // to parent space mSkinMatrices[i] = mJointMatrices[i] * joint.invBindPose; // inverse bind pose } I'm really struggling with this problem. As you can see, also left side of mesh is slightly distorted. For more detail, these are how I got inverse bind pose and key frames from FBX. // get joint inverse bind pose if (const auto attrib = node->GetNodeAttribute(); attrib) { const auto attribType = attrib->GetAttributeType(); if (attribType == FbxNodeAttribute::eSkeleton) { CvtJoint cvtJoint{node->GetName(), id, parentId}; cvtJoint.invBindPose = makeMat4(node->EvaluateGlobalTransform().Inverse()); mCvtJointList.emplace_back(cvtJoint); } } // get key frames for (auto frameIndex = startCount; frameIndex < stopCount; ++frameIndex) { FbxTime time{}; time.SetFrame(frameIndex, timeMode); cvtAnimKey.time = static_cast<f32>(time.GetSecondDouble()); // get time of frame auto transform = node->EvaluateGlobalTransform(time); // get global transform at time if (const auto parent = node->GetParent(); // if node has parent parent) { auto parentTransform = parent->EvaluateGlobalTransform(time); // get parent global transform at time transform = parentTransform.Inverse() * transform; // to local space } cvtAnimKey.t = makeVec3(transform.GetT()); // FbxVector4 -> glm::vec3 cvtAnimKey.q = makeQuat(transform.GetQ()); // FbxQuaternion -> glm::quat cvtAnimTrack.keys.emplace_back(cvtAnimKey); // add key to track } Any suggestion or advice is really appreciated...
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!