Search Unity

Some explanations on bindPoses

Discussion in 'Scripting' started by Ippokratis, Apr 18, 2011.

  1. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    I found bind poses quite difficult to understand. After some discussions on #unity3d and some reading, I came up with this simple script. I hope that the comments can be of some help to others.
    Code (csharp):
    1. //The Bind Pose Matrices allow a raw vertex of the mesh (in local coordinates) to be transformed into world-space
    2. // and then to each bone's local coordinate space, after which each bone's animation can be applied to the vertex in question
    3. // (under the influence of the weighting value). The mesh's bind pose takes the vertex from local space to world-space,
    4. // and then each bone's inverse bind pose takes the mesh vertex from world-space to the local space of that bone.
    5. // Once in the bone's local space, the bone's current animated transformation matrix is used to transform (deform)
    6. // the vertex's location. After all the bone influences have been taken into account, the vertex ends up in world-space
    7. // in its final deformed location. In other words, these bind pose matrices relate the location of a vertex in its local mesh space
    8. // to the same location of the vertex relative to each bones' local coordinate systems.
    9.  
    10. // The mesh's Bind Pose Matrix takes its vertices into world-space, to the location at the time of binding,
    11. // and each bones' Bind Pose Matrix takes the bones from local space to world-space at the time of binding.
    12.  
    13. function Start ()
    14. {
    15. gameObject.AddComponent(SkinnedMeshRenderer);
    16. var renderer : SkinnedMeshRenderer = GetComponent(SkinnedMeshRenderer);
    17.  
    18. // Build basic mesh
    19. var mesh : Mesh = new Mesh ();
    20.  
    21. mesh.vertices = [   Vector3(-1, 0, 0),
    22.                     Vector3(1, 0, 0),
    23.                     Vector3(-1, 5, 0),
    24.                     Vector3(1, 5, 0)
    25.                 ];
    26.                
    27. mesh.uv =       [    Vector2(0, 0),
    28.                      Vector2(1, 0),
    29.                      Vector2(0, 1),
    30.                      Vector2(1, 1)
    31.                 ];
    32.            
    33. mesh.triangles = [   0, 1, 2,
    34.                      1, 3, 2,
    35.                      2, 1, 0,
    36.                      2, 3, 1
    37.                  ];
    38.                
    39. mesh.RecalculateNormals();
    40.  
    41. // Assign mesh to mesh filter  renderer
    42.  
    43. renderer.material = new Material (Shader.Find(" Diffuse"));
    44.  
    45. // BoneWeight[4] : 4 = vertices 0 to 3
    46. // weights[0] : first (0) vertice
    47. // boneIndex0 : 0 = first bone
    48. // weight0 = 1 : 1 = how much influence this bone has on the vertice
    49.  
    50. var weights = new BoneWeight[4];
    51.  
    52. weights[0].boneIndex0 = 0;
    53. weights[0].weight0 = 1;
    54.  
    55. weights[1].boneIndex0 = 0;
    56. weights[1].weight0 = 1;
    57.  
    58. weights[2].boneIndex0 = 0;
    59. weights[2].weight0 = 1;
    60.  
    61. weights[3].boneIndex0 = 0;
    62. weights[3].weight0 = 1;
    63.  
    64. mesh.boneWeights = weights;
    65.  
    66. // Create 1 Bone Transform and 1 Bind pose
    67.  
    68. var bones : Transform[] = new Transform[1];
    69. var bindPoses : Matrix4x4[] = new Matrix4x4[1];
    70.  
    71. // Create a new gameObject
    72.  
    73. bones[0] = new GameObject ("Lower").transform;
    74.  
    75. // Make this gameObject's transform the parent of the bone
    76.  
    77. bones[0].parent = transform;
    78.  
    79. // Set the position/rotation of the bone
    80.  
    81. bones[0].localRotation = Quaternion.identity;
    82. bones[0].localPosition = Vector3.zero;
    83.  
    84. // bones[0] is a Transform mapped to world space. We map it to the local space of its parent,
    85. // which is the transform "bones[0].worldToLocalMatrix" and afterwards
    86. // we map it again in world space, keeping the relation child - parent with "* transform.localToWorldMatrix;",
    87. // thus allowing us 1. to move/rotate/scale it freely in space but also
    88. //                            2. make all move/rotate/scaling operations on its parent affect it too
    89.  
    90. bindPoses[0] = bones[0].worldToLocalMatrix * transform.localToWorldMatrix;
    91.  
    92. // Apply bindPoses to the mesh
    93.  
    94. mesh.bindposes = bindPoses;
    95.  
    96. // Assign bones and bind poses to the SkinnedMeshRenderer
    97.  
    98. renderer.bones = bones;
    99. renderer.sharedMesh = mesh;
    100. }
     
    NathBar, _geo__, exitshadow and 9 others like this.
  2. blackpag

    blackpag

    Joined:
    Jul 18, 2012
    Posts:
    4
    Hi I see you understand this subject well,
    I have a problem , I have a SkinnedMeshRenderrer which consist of 3 object and i want to separate them. is it possible?
     
  3. Hamburgert

    Hamburgert

    Joined:
    Feb 14, 2015
    Posts:
    6
    Necro justification: This is the only reasonable explanation I can find regarding bindposes. Well, atleast reasonable to a bindposes noob like myself. This example also looks very tidy and well organized.

    I'm surprised at how hard it was to find any good information on getting started with this.
    This post made me actually understand where to begin experimentation on my own. Will probably master this soon.

    Thank you, guy from the past.
     
    JoeStrout likes this.
  4. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    You just made me realise that it is 10 yrs since I started using Unity !
     
  5. jgp80

    jgp80

    Joined:
    Aug 24, 2012
    Posts:
    23
    lppokratis: would you post an example of the opposite process? how to use the bind poses, root bone and bones matrices to calculate the skinned vertex?

    Would be really helpful to complete your excelent explanatino.
     
    mc-cho likes this.
  6. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi jgp80,
    The projects I work on keep me busy.
    Why don't you give it a try and post back here your findings?
    I might manage to fix some part of your code that doesn't work.
     
  7. Shabih554

    Shabih554

    Joined:
    May 15, 2017
    Posts:
    11
    Hi Ippokratis,
    Can i ask for your help regarding bindposes.
    i am loading a mesh at runtime, then assigning it bindposes that i extract from a text file. Can unity determine the child structure from bindposes. What is the purpose of defining bindposes?
     
  8. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi Shabih554,
    You can use the Transform component to define parent-child relationships in Unity.
    Bind poses is a way - I think - to declare the default transform properties of the root bone and all of its children.
     
    Last edited: Jan 1, 2020
  9. Shabih554

    Shabih554

    Joined:
    May 15, 2017
    Posts:
    11
    So i am working on extracting models from text files that are extracted from an old MMORPG game that was built on an open source DirectX engine. When i just draw the vertices and triangles, the model looks just fine. When i add bones and weights and generate it, again it looks fine but does not morph/move when i move the bone. But as soon as i add bindposes to my mesh, it just morphs into something else.
    I changed the quality from 2 bones to 1 bone and now the mesh generates as it should but when i move a bone it doesn't move accordingly. I am extracting the bone transforms from the transformation matrix in the DirectX model files.
    The mesh and bones and everything is being generated at runtime.
     
  10. GXMark

    GXMark

    Joined:
    Oct 13, 2012
    Posts:
    515
    If you have lets say multiple skinned mesh renderers attached in a skeleton hierarchy each renderer having a different root bone transform reference then how to calculate the bind poses for each renderers shared mesh? What is the gameobject transform for the localtoworld term of the equation?
     
  11. FN_Envenge

    FN_Envenge

    Joined:
    Jul 24, 2020
    Posts:
    1
    Thanks lppokratis! This helped me solve a problem I've been working at for over a week. Thanks for taking the time to make this post, you're investigative work is still very appreciated over a decade later!