Search Unity

GetBlendShapeFrameVertices() Doesn't work for imported blend shapes !

Discussion in 'Animation' started by CrazyRocksStudios, Oct 27, 2016.

  1. CrazyRocksStudios

    CrazyRocksStudios

    Joined:
    Sep 29, 2015
    Posts:
    15
    Hello,

    We are working on a character customization system and we need to merge several SkinnedMeshRenderers into one.

    Everything is working fine except, we need to copy blend shapes from the head mesh part to our combined mesh and it's just not working.

    There is a method called: GetBlendShapeFrameVertices() that returns a weight and vertex positions, normals, tangents deltas for specified blend shape frame but when I call it on my head mesh with specified blend shape index and frame index - it just returns all zero vectors ...

    Code (CSharp):
    1.  
    2. int shapeID = meshToMerge.GetBlendShapeIndex("all_vertex_move"); // test blend shape - works in editor
    3. int framesCount = meshToMerge.GetBlendShapeFrameCount(shapeID); // returns "1"
    4. float frameWeight = meshToMerge.GetBlendShapeFrameWeight(shapeID,0); // returns 100f
    5.  
    6. Vector3[] deltaVertices = new Vector3[meshToMerge.vertexCount];
    7. meshToMerge.GetBlendShapeFrameVertices(shapeID,0,deltaVertices, null, null);
    8. for(int a=0; a<meshToMerge.vertexCount; a++)
    9. {
    10.      Debug.Log("delta vertex no. "+a+" = "+deltaVertices[a].ToString()); // returns (0.0, 0.0, 0.0) for every element
    11. }
    12.  
    Interestingly - this test blend shape ( "all_vertex_move" ) is visible in the editor and works fine on our head mesh.

    On the other hand when I manually create a new blend shape for my head mesh ( just for test purposes ) - I can successfully retrieve all deltas I specified in the AddBlendShapeFrame() call:

    Code (CSharp):
    1.  
    2. Vector3[] randomDeltas = new Vector3[meshToMerge.vertexCount];
    3. for(int y=0; y<newMeshVertexCount; y++)
    4.      randomVertices[y] = new Vector3(UnityEngine.Random.Range(-10,10), UnityEngine.Random.Range(-10,10), UnityEngine.Random.Range(-10,10));
    5. meshToMerge.AddBlendShapeFrame("random_shape", 100f, randomDeltas, null, null);
    6.  
    For such added blend shape I can use GetBlendShapeFrameVertices() and get all proper deltas.

    Please help. I'm out of ideas :/

    Cheers,
    Stan
     
    Last edited: Oct 28, 2016
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    can you check if you shapeID is different than -1
    If I remember well the name in the editor and internally is not necessary the same one
     
  3. CrazyRocksStudios

    CrazyRocksStudios

    Joined:
    Sep 29, 2015
    Posts:
    15
    shapeID is 20 in this case ( it is due to all previous shapes ). I can retrieve it's frame count and frame 0 weight - "only" deltas are all zero
     
    Last edited: Oct 27, 2016
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It look like a bug then.
    Please log a bug and we will investigate
     
  5. CrazyRocksStudios

    CrazyRocksStudios

    Joined:
    Sep 29, 2015
    Posts:
    15
    Oh i see

    Is there any workaround for this in Your opinion ? We just need to copy blend shape data in any way
     
  6. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    It should work, but for an unknow reason it doesn't seem to be working.

    I don't think there is another way
     
  7. shh_22

    shh_22

    Joined:
    Feb 25, 2017
    Posts:
    1
    In my project I am facing the same problem. I managed to solve this issue by using SkinnedMeshRender's BakeMesh method.First clear all BlendShape weights, Then bake each blend shape by setting its weight to 100. Just like this
    for(int bi = 0; bi < blendShapeCount;bi++)
    {
    clearAllBlendShapeWeight ();
    string shapename = skinnedMesh.GetBlendShapeName (bi);
    int shapeid = skinnedMesh.GetBlendShapeIndex (shapename);
    skinnedMeshRenderer.SetBlendShapeWeight (shapeid, 100.0f);

    //Vector3[] diffvertices = new Vector3[skinnedMesh.vertexCount];

    Mesh tmpmesh = new Mesh ();
    skinnedMeshRenderer.BakeMesh (tmpmesh);//From tmp mesh you can get everything you want
    }
     
  8. YarrySP

    YarrySP

    Joined:
    Sep 20, 2012
    Posts:
    10
    I just encountered the problem you mention, and what you say is partly false for me.

    It seems that deltaVertices[a].ToString() indeed does returns (0,0,0), but the bug is with .ToString(). If I Debug.Log(vert.magnitude) or Debug.Log(vert.x), the data is actually there.

    So everything works as it should, it just looks like .ToString() doesn't return the data correctly with Vector3s?

    Can anyone confirm this is how it is on their side as well?
     
    Beennn likes this.
  9. Monk_y

    Monk_y

    Joined:
    Jan 29, 2020
    Posts:
    1


    I think you are right, I encountered the same situation, it should be the problem of Vector3 precision.