Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Sudar-shan · Jun 01, 2020 at 06:26 AM · guimathskinnedmeshrendererskeletonmatrix4x4

How to Calculate BindPoses From My data?

I have Gltf Bone Skeleton Values in json format(PFA):

Bind_Matrix4x4

Bone_Inverses_Matrix4x4 [23]

Bone_Transforms [23]

(The uuid in bone array is just the bone object names i create in unity3d in runtime)

The documentation of this data tells me:

Bind matrix is the initial object world matrix so that if skeleton is offset from object during the time it is bound that relationship is preserved.

Inverse matrices are the inverses of bone world matrix.

In Unity3d i convert these gltf to unity space and while creating SkinnedMeshRenderer I do the following now.

 Matrix4x4[23] bindposes;
 foreach(Bone){
     bindposes[curBoneId]  = Bind_Mat4x4 * Bone_Inverses_Mat4x4[ curBoneId];
 }
     skinnedMeshRenderer.sharedMesh.bindposes = bindposes;
     skinnedMeshRenderer.bones = boneTransforms;
     skinnedMeshRenderer.rootBone = boneTransforms[0];


The way I create Bind Poses Are wrong i think(mesh is skewed).

Need Some Math Help here.

How to calculate Bindpose for each bone if bind matrix4x4 and bone Inverses are given separably like in the attached json?

bonedata.zip (3.8 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Jun 01, 2020 at 08:44 AM

Matrix multiplication is from right to left. So the incoming vertex first has to go though the Bind_Mat4x4 to convert from mesh local space to worldspace. After that you go through the inverse of the bone matrix to convert from worldspace to the local space of the bone. That's the bind pose. At runtime during skinning the last step is to use the current bone transform local to world matrix to calculate the final worldspace position.


So the bind pose has to look like this

 bindposes[curBoneId]  = Bone_Inverses_Mat4x4[ curBoneId] * Bind_Mat4x4;


There's a code example in the documentation. For reference here's my matrix crash course. If you're really want to dig into linear algebra I can highly recommend the 3B1B series "essence of linear algebra"

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Sudar-shan · Jun 02, 2020 at 02:16 PM 0
Share

The mesh is still skewed. But if i do not use the given data and just calculate bindposes using the following

 bindposes[currBoneIdx] = boneTransforms[currBoneIdx].worldToLocal$$anonymous$$atrix * boneTransforms[0].localToWorld$$anonymous$$atrix;

The mesh appears correct .

This is the code that i use to convert the data from gltf space to unity3d space.

 public static readonly Vector3 CoordinateSpaceConversionScale = new Vector3(-1, 1, 1);
     private static $$anonymous$$atrix4x4 ToUnity$$anonymous$$atrix4x4($$anonymous$$atrix4x4 gltf$$anonymous$$at4)
     {
         $$anonymous$$atrix4x4 convert = $$anonymous$$atrix4x4.Scale(CoordinateSpaceConversionScale);
         $$anonymous$$atrix4x4 unity$$anonymous$$at = convert * gltf$$anonymous$$at4 * convert;
         return unity$$anonymous$$at;
     }
     private static $$anonymous$$atrix4x4 CreateGltf$$anonymous$$atrix4x4(List<object> readFloatArray)
     {//loading them in colum major format 
         $$anonymous$$atrix4x4 gltf$$anonymous$$at = new $$anonymous$$atrix4x4();
         gltf$$anonymous$$at.m00 = (float)double.Parse(readFloatArray[0].ToString());
         gltf$$anonymous$$at.m10 = (float)double.Parse(readFloatArray[1].ToString());
         gltf$$anonymous$$at.m20 = (float)double.Parse(readFloatArray[2].ToString());
         gltf$$anonymous$$at.m30 = (float)double.Parse(readFloatArray[3].ToString());
 
         gltf$$anonymous$$at.m01 = (float)double.Parse(readFloatArray[4].ToString());
         gltf$$anonymous$$at.m11 = (float)double.Parse(readFloatArray[5].ToString());
         gltf$$anonymous$$at.m21 = (float)double.Parse(readFloatArray[6].ToString());
         gltf$$anonymous$$at.m31 = (float)double.Parse(readFloatArray[7].ToString());
 
         gltf$$anonymous$$at.m02 = (float)double.Parse(readFloatArray[8].ToString());
         gltf$$anonymous$$at.m12 = (float)double.Parse(readFloatArray[9].ToString());
         gltf$$anonymous$$at.m22 = (float)double.Parse(readFloatArray[10].ToString());
         gltf$$anonymous$$at.m32 = (float)double.Parse(readFloatArray[11].ToString());
 
         gltf$$anonymous$$at.m03 = (float)double.Parse(readFloatArray[12].ToString());
         gltf$$anonymous$$at.m13 = (float)double.Parse(readFloatArray[13].ToString());
         gltf$$anonymous$$at.m23 = (float)double.Parse(readFloatArray[14].ToString());
         gltf$$anonymous$$at.m33 = (float)double.Parse(readFloatArray[15].ToString());
 
         return gltf$$anonymous$$at;
     }

https://docs.unity3d.com/ScriptReference/$$anonymous$$esh-boneWeights.html

"The bone weights should be in descending order (most significant first) and add up to 1." - In some cases this fails for the model that i load. PFA : 1.png,2.png

Could this be the problem?

At runtime during skinning the last step is to use the current bone transform local to world matrix to calculate the final worldspace position

Skinned$$anonymous$$eshRenderer does this right ? ![alt text][1] ![alt text][2] @Bunny83 Thanks for your help and time. [1]: /storage/temp/160981-1.jpg [2]: /storage/temp/160982-2.png
1.jpg (439.1 kB)
2.png (172.7 kB)
avatar image
0

Answer by Sudar-shan · Jun 02, 2020 at 06:55 PM

@Bunny83 Thanks that did the trick. But now The triangles are inverted like this. alt text After id do this they appear correct:

skinnedMeshRenderer.sharedMesh.triangles = skinnedMeshRenderer.sharedMesh.triangles.Reverse().ToArray();

alt text


inverted2.jpg (38.3 kB)
noninverted1.jpg (36.6 kB)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

236 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

NullReferenceException using Matrix4x4? 2 Answers

Taking the user's screen resolution before running a GUI.matrix? 0 Answers

GUI Matrix problem 1 Answer

Detect GUI rotation degree 1 Answer

Unity Reload Bullets left 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges