Beispiel #1
0
		/**
		 * Adds all possible blendshape targets of the game object
		 * curGameObject and its sub-objects (recursively) to the
		 * list of target blendshapes.
		 */
		public static void GetGameObjectBlendshapes(GameObject curGameObject, ArrayList blendshape_infos) {
		
			if (blendshape_infos != null) blendshape_infos.Clear();

			// Iterate over game object itself and over children and add blendshapes
			Transform [] children = curGameObject.GetComponentsInChildren<Transform>();
			foreach (Transform child in children)
			{
				string transformPath = CalculateTransformPath(child, curGameObject.transform);
				SkinnedMeshRenderer meshRenderer = (SkinnedMeshRenderer)child.GetComponent(typeof(SkinnedMeshRenderer));
				if (meshRenderer != null)
				{
					if (meshRenderer.sharedMesh != null)
					{
						//Debug.Log("Number of blend shapes: " + meshRenderer.sharedMesh.blendShapeCount);
						for (int blend_shape_nr = 0; blend_shape_nr < meshRenderer.sharedMesh.blendShapeCount; blend_shape_nr++) {
							string blend_shape_name = meshRenderer.sharedMesh.GetBlendShapeName(blend_shape_nr);
							//Debug.Log("Path: '" + transformPath + "', blend shape: '" + blend_shape_name + "'");
							if (blendshape_infos != null) {
								BlendshapeInfo blendshape_info = new BlendshapeInfo();
								blendshape_info.m_path = transformPath;
								blendshape_info.m_name = blend_shape_name;
								blendshape_info.m_index = blend_shape_nr;
								blendshape_info.m_mesh_renderer = meshRenderer;
								blendshape_infos.Add (blendshape_info);
							}
						}
					}
				}
			}
		}
        /// <summary>
        /// Applies the blendshapes given an influence factor
        /// </summary>
        /// <returns><c>true</c>, if blendshapes could be applied, <c>false</c> otherwise.</returns>
        /// <param name="transformationsToSet">The set of blendshapes to apply</param>
        /// <param name="influence">The factor to apply the blendshapes. 0.0 means that they are not used at all and the current
        /// animations are not changed. 1.0 means that they are fully used.</param>
        protected bool ApplyBlendshapes(BlendshapeValue [] blendshapesToSetToSet, float influence)
        {
            if (blendshapesToSetToSet.Length != m_GameObjectBlendshapes.Count)
            {
                return(false);
            }

            for (int index = 0; index < m_GameObjectBlendshapes.Count; index++)
            {
                // Apply the value for this target
                if (blendshapesToSetToSet[index] != null)
                {
                    BlendshapeInfo bs_info       = m_GameObjectBlendshapes[index] as BlendshapeInfo;
                    float          originalValue = bs_info.m_mesh_renderer.GetBlendShapeWeight(bs_info.m_index);
                    float          newValue      = (float)blendshapesToSetToSet[index].m_value;
                    bs_info.m_mesh_renderer.SetBlendShapeWeight(bs_info.m_index, influence * newValue + (1.0f - influence) * originalValue);
                }
            }
            return(true);
        }
Beispiel #3
0
 /**
  * Adds all possible blendshape targets of the game object
  * curGameObject and its sub-objects (recursively) to the
  * list of target blendshapes.
  */
 public static void getGameObjectBlendshapes(GameObject curGameObject,
                                             ArrayList blendshape_infos)
 {
     if (blendshape_infos != null)
     {
         blendshape_infos.Clear();
     }
     // Iterate over game object itself and over children and add blendshapes
     Transform [] children = curGameObject.GetComponentsInChildren <Transform>();
     foreach (Transform child in children)
     {
         string transformPath             = calculateTransformPath(child, curGameObject.transform);
         SkinnedMeshRenderer meshRenderer = (SkinnedMeshRenderer)child.GetComponent(typeof(SkinnedMeshRenderer));
         if (meshRenderer != null)
         {
             if (meshRenderer.sharedMesh != null)
             {
                 //Debug.Log("Number of blend shapes: " + meshRenderer.sharedMesh.blendShapeCount);
                 for (int blend_shape_nr = 0; blend_shape_nr < meshRenderer.sharedMesh.blendShapeCount; blend_shape_nr++)
                 {
                     string blend_shape_name = meshRenderer.sharedMesh.GetBlendShapeName(blend_shape_nr);
                     //Debug.Log("Path: '" + transformPath + "', blend shape: '" + blend_shape_name + "'");
                     if (blendshape_infos != null)
                     {
                         BlendshapeInfo blendshape_info = new BlendshapeInfo();
                         blendshape_info.m_path          = transformPath;
                         blendshape_info.m_name          = blend_shape_name;
                         blendshape_info.m_index         = blend_shape_nr;
                         blendshape_info.m_mesh_renderer = meshRenderer;
                         blendshape_infos.Add(blendshape_info);
                     }
                 }
             }
         }
     }
 }
Beispiel #4
0
        /**
         * @brief Stores the current clip into a Unity .anim file
         * Important: If you use your own character with blend shapes, you have to make sure it is
         * set to 'legacy' animation type. You can do this by the following steps in Unity3D:
         * 1. In the 'project' window in the Assets hierarchy, click on your fbx model
         * 2. In the Inspector, you should see now the Import Settings of your model.
         * 3. Select in these Import Settings in the 'Rig' tab for the 'Animation Type' the value 'Legacy'
         */
        public void SaveClipAsAnim(string path)
        {
            bool have_t_pose = false;

            if (m_tpose != null && m_tpose.m_joints != null)
            {
                if (m_tpose.m_joints.Count != targetTransformations.Count)
                {
                    Debug.LogError("tpose and model do not have the same number of transformations (" + m_tpose.m_joints.Count + "!="
                                   + targetTransformations.Count + ")");
                    return;
                }
                have_t_pose = true;
            }
            else
            {
                Debug.LogWarning("tpose missing");
            }


            AnimationClip animation_clip = new AnimationClip();

            // Not all of them might actually be used, since not all of them might be a target
            AnimationCurve [] translation_x_curves = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] translation_y_curves = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] translation_z_curves = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] rotation_x_curves    = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] rotation_y_curves    = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] rotation_z_curves    = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] rotation_w_curves    = new AnimationCurve[targetTransformations.Count];
            AnimationCurve [] bs_curves            = new AnimationCurve[targetBlendShapeInfos.Count];

            Debug.Log("nr of clip states: " + m_clip.num_states());
            for (int frame_nr = 0; frame_nr < m_clip.num_states(); frame_nr++)
            {
                // get frame time
                float time = (float)(m_clip[frame_nr].timestamp() - m_clip[0].timestamp()) * 0.001f;                 // time is in ms

                // evaluate transformation
                TransformationValue [] transformation_values = null;
                if (have_t_pose)
                {
                    transformation_values = Utils.evaluate_target_transformations(m_retargeting, m_fs_Rig, m_clip[frame_nr], m_tpose.m_joints);
                }
                else
                {
                    transformation_values = Utils.evaluate_target_transformations(m_retargeting, m_fs_Rig, m_clip[frame_nr], targetTransformations);
                }

                if (transformation_values.Length == targetTransformations.Count)
                {
                    for (int index = 0; index < transformation_values.Length; index++)
                    {
                        // Apply the value for this target
                        if (transformation_values[index] != null)
                        {
                            // Apply the translation value for this target
                            if (translation_x_curves[index] == null)
                            {
                                translation_x_curves[index] = new AnimationCurve();
                                translation_y_curves[index] = new AnimationCurve();
                                translation_z_curves[index] = new AnimationCurve();
                            }
                            translation_x_curves[index].AddKey(time, transformation_values[index].m_translation.x);
                            translation_y_curves[index].AddKey(time, transformation_values[index].m_translation.y);
                            translation_z_curves[index].AddKey(time, transformation_values[index].m_translation.z);

                            if (rotation_x_curves[index] == null)
                            {
                                rotation_x_curves[index] = new AnimationCurve();
                                rotation_y_curves[index] = new AnimationCurve();
                                rotation_z_curves[index] = new AnimationCurve();
                                rotation_w_curves[index] = new AnimationCurve();
                            }
                            // Add to curve for the animation
                            rotation_x_curves[index].AddKey(time, transformation_values[index].m_rotation.x);
                            rotation_y_curves[index].AddKey(time, transformation_values[index].m_rotation.y);
                            rotation_z_curves[index].AddKey(time, transformation_values[index].m_rotation.z);
                            rotation_w_curves[index].AddKey(time, transformation_values[index].m_rotation.w);
                        }
                    }
                }
                else
                {
                    Debug.LogError("Cannot create transformation as evaluated shape size is incorrect");
                }


                // evaluate blendshapes
                BlendshapeValue [] blendshape_values = Utils.evaluate_target_blendshapes(m_retargeting, m_clip.rig(), m_clip[frame_nr], targetBlendShapeInfos);
                if (blendshape_values.Length == targetBlendShapeInfos.Count)
                {
                    for (int index = 0; index < targetBlendShapeInfos.Count; index++)
                    {
                        // Apply the value for this target
                        if (blendshape_values[index] != null)
                        {
                            if (bs_curves[index] == null)
                            {
                                bs_curves[index] = new AnimationCurve();
                            }
                            bs_curves[index].AddKey(time, (float)blendshape_values[index].m_value);
                        }
                    }
                }
                else
                {
                    Debug.LogError("Cannot create blendshapes as evaluated shape size is incorrect");
                }
            }

            // Set all transformation curves for all transformation that are animated
            for (int target_nr = 0; target_nr < targetTransformations.Count; target_nr++)
            {
                // Extract path:
                string path_to_transformation = ((TransformationInformation)targetTransformations[target_nr]).transformPath;
                // Apply translation curve, if there is one
                if (translation_x_curves[target_nr] != null)
                {
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.x", translation_x_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.y", translation_y_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.z", translation_z_curves[target_nr]);
                }
                // Apply rotation curve, if there is one
                if (rotation_x_curves[target_nr] != null)
                {
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.x", rotation_x_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.y", rotation_y_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.z", rotation_z_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.w", rotation_w_curves[target_nr]);
                }
            }

            // Without this, there are some weird jumps (rotation) in the animation:
            animation_clip.EnsureQuaternionContinuity();

            // Set all blendshape curves for all blendshapes that are animated
            for (int i = 0; i < targetBlendShapeInfos.Count; i++)
            {
                if (bs_curves[i] != null)
                {
                    BlendshapeInfo bs_info = (BlendshapeInfo)(targetBlendShapeInfos[i]);
                    // Debug.Log("bs_curves[" + i + "].length=" + bs_curves[i].length);
                    string bs_path = bs_info.m_path;
                    string bs_name = bs_info.m_name;
                    animation_clip.SetCurve(bs_path, typeof(SkinnedMeshRenderer), "blendShape." + bs_name, bs_curves[i]);
                }
            }

            // animation clip asset
            string animation_name = Path.GetFileNameWithoutExtension(path);

            animation_clip.name = animation_name;
                        #if UNITY_EDITOR
            AssetDatabase.CreateAsset(animation_clip, path);
                        #endif

            // Add the clip to the animations of the attached game object
            Animation my_animation = gameObject.animation;
            if (!my_animation)
            {
                gameObject.AddComponent(typeof(Animation));
                my_animation = gameObject.animation;
            }
            if (my_animation)
            {
                my_animation.AddClip(animation_clip, animation_name);
                my_animation.clip = animation_clip;
                my_animation[animation_name].blendMode = AnimationBlendMode.Blend;
            }
            else
            {
                print("Error: could not get animation object");
            }
            Debug.Log("Wrote animation with length " + (1000.0 * animation_clip.length) + " milliseconds");
        }
Beispiel #5
0
        /**
         * @brief Stores the current clip into a Unity .anim file
         * Important: If you use your own character with blend shapes, you have to make sure it is
         * set to 'legacy' animation type. You can do this by the following steps in Unity3D:
         * 1. In the 'project' window in the Assets hierarchy, click on your fbx model
         * 2. In the Inspector, you should see now the Import Settings of your model.
         * 3. Select in these Import Settings in the 'Rig' tab for the 'Animation Type' the value 'Legacy'
         */
        public AnimationClip GetClipAsAnim(string path)
        {
            bool have_t_pose = false;

            if (m_TPose != null && m_TPose.m_joints != null)
            {
                if (m_TPose.m_joints.Count != m_GameObjectTransformations.Count)
                {
                    Debug.LogError("tpose and model do not have the same number of transformations (" + m_TPose.m_joints.Count + "!="
                                   + m_GameObjectTransformations.Count + ")");
                    return(null);
                }
                have_t_pose = true;
            }
            else
            {
                Debug.LogWarning("tpose missing");
            }

            AnimationClip animation_clip = new AnimationClip();

            // Not all of them might actually be used, since not all of them might be a target
            AnimationCurve [] translation_x_curves = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] translation_y_curves = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] translation_z_curves = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_x_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_y_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_z_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] rotation_w_curves    = new AnimationCurve[m_GameObjectTransformations.Count];
            AnimationCurve [] bs_curves            = new AnimationCurve[m_GameObjectBlendshapes.Count];

            Clip clip = m_clip.Duplicate();

            if (m_normalize_headpose)
            {
                clip.NormalizeHeadPoseAllClip();
            }

            Debug.Log("nr of clip states: " + clip.NumStates());
            for (int frame_nr = 0; frame_nr < clip.NumStates(); frame_nr++)
            {
                if (!clip[frame_nr].TrackingSuccessful())
                {
                    Debug.Log("skipping clip state");
                    continue;
                }

                // get frame time
                float time = (float)(clip[frame_nr].Timestamp() - clip[0].Timestamp()) * 0.001f;                 // time is in ms

                // evaluate transformation
                TransformationValue [] transformation_values = null;
                if (have_t_pose)
                {
                    transformation_values = Utils.EvaluateTargetTransformations(m_Retargeting, clip.Rig(), clip[frame_nr], m_TPose.m_joints);
                }
                else
                {
                    transformation_values = Utils.EvaluateTargetTransformations(m_Retargeting, clip.Rig(), clip[frame_nr], m_GameObjectTransformations);
                }

                int key_index = -1;
                if (transformation_values.Length == m_GameObjectTransformations.Count)
                {
                    for (int index = 0; index < transformation_values.Length; index++)
                    {
                        // Apply the value for this target
                        if (transformation_values[index] != null)
                        {
                            // Apply the translation value for this target
                            if (translation_x_curves[index] == null)
                            {
                                translation_x_curves[index] = new AnimationCurve();
                                translation_y_curves[index] = new AnimationCurve();
                                translation_z_curves[index] = new AnimationCurve();
                            }
                            key_index = translation_x_curves[index].AddKey(time, transformation_values[index].m_translation.x);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = translation_y_curves[index].AddKey(time, transformation_values[index].m_translation.y);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = translation_z_curves[index].AddKey(time, transformation_values[index].m_translation.z);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }

                            if (rotation_x_curves[index] == null)
                            {
                                rotation_x_curves[index] = new AnimationCurve();
                                rotation_y_curves[index] = new AnimationCurve();
                                rotation_z_curves[index] = new AnimationCurve();
                                rotation_w_curves[index] = new AnimationCurve();
                            }
                            // Add to curve for the animation
                            key_index = rotation_x_curves[index].AddKey(time, transformation_values[index].m_rotation.x);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = rotation_y_curves[index].AddKey(time, transformation_values[index].m_rotation.y);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = rotation_z_curves[index].AddKey(time, transformation_values[index].m_rotation.z);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                            key_index = rotation_w_curves[index].AddKey(time, transformation_values[index].m_rotation.w);
                            if (key_index < 0)
                            {
                                Debug.LogError("Could not add key at time " + time);
                            }
                        }
                    }
                }
                else
                {
                    Debug.LogError("Cannot create transformation as evaluated shape size is incorrect");
                }

                // evaluate blendshapes
                BlendshapeValue [] blendshape_values = Utils.EvaluateTargetBlendshapes(m_Retargeting, clip.Rig(), clip[frame_nr], m_GameObjectBlendshapes);

                if (blendshape_values.Length == m_GameObjectBlendshapes.Count)
                {
                    for (int index = 0; index < m_GameObjectBlendshapes.Count; index++)
                    {
                        // Apply the value for this target
                        if (blendshape_values[index] != null)
                        {
                            if (bs_curves[index] == null)
                            {
                                bs_curves[index] = new AnimationCurve();
                            }
                            bs_curves[index].AddKey(time, (float)blendshape_values[index].m_value);
                        }
                    }
                }
                else
                {
                    Debug.LogError("Cannot create blendshapes as evaluated shape size is incorrect");
                }
            }

            // Set all transformation curves for all transformations that are animated
            for (int target_nr = 0; target_nr < m_GameObjectTransformations.Count; target_nr++)
            {
                // Extract path:
                string path_to_transformation = ((TransformationInformation)m_GameObjectTransformations[target_nr]).transformPath;
                // Apply translation curve, if there is one
                if (translation_x_curves[target_nr] != null)
                {
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.x", translation_x_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.y", translation_y_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localPosition.z", translation_z_curves[target_nr]);
                }
                // Apply rotation curve, if there is one
                if (rotation_x_curves[target_nr] != null)
                {
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.x", rotation_x_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.y", rotation_y_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.z", rotation_z_curves[target_nr]);
                    animation_clip.SetCurve(path_to_transformation, typeof(Transform), "localRotation.w", rotation_w_curves[target_nr]);
                }
            }

            // Without this, there are some weird jumps (rotation) in the animation:
            animation_clip.EnsureQuaternionContinuity();

            // Set all blendshape curves for all blendshapes that are animated
            for (int i = 0; i < m_GameObjectBlendshapes.Count; i++)
            {
                if (bs_curves[i] != null)
                {
                    BlendshapeInfo bs_info = (BlendshapeInfo)(m_GameObjectBlendshapes[i]);
                    // Debug.Log("bs_curves[" + i + "].length=" + bs_curves[i].length);
                    string bs_path = bs_info.m_path;
                    string bs_name = bs_info.m_name;
                    animation_clip.SetCurve(bs_path, typeof(SkinnedMeshRenderer), "blendShape." + bs_name, bs_curves[i]);
                }
            }

            Debug.Log("Animation clip = " + animation_clip.length);

            // animation clip asset
            string animation_name = Path.GetFileNameWithoutExtension(path);

            animation_clip.name = animation_name;
            AnimationEvent animation_event = new AnimationEvent();

            animation_event.functionName = "AnimationClipEventCallback";
            animation_event.time         = animation_clip.length;
                        #if UNITY_EDITOR
            AnimationEvent[] animation_events = { animation_event };
            AnimationUtility.SetAnimationEvents(animation_clip, animation_events);
            AssetDatabase.CreateAsset(animation_clip, path);
                        #endif

            Debug.Log("Wrote animation with length " + (1000.0 * animation_clip.length) + " milliseconds");
            return(animation_clip);
        }
Beispiel #6
0
        void Update()
        {
            // ten kod kalkuluje bazowa pozycje glowy
            // trzeba jeszcze dorobic zeby przechwytywal trigerra
            // i wtedy zmieniał isBaseCalculated na false
            // i resetował timer i kalkulował jeszcze raz
            // pozniej trzeba jeszcze dodac zeby kazda metoda zwracała
            // to co zwraca minus base
            if (!isBaseCalculated)
            {
                timer += Time.deltaTime;
                if (timer < baseCalculationTime)
                {
                    if (getXHeadRotation() != -1)
                    {
                        baseX += getXHeadRotation();
                        ticksX++;
                    }

                    if (getYHeadRotation() != -1)
                    {
                        baseY += getYHeadRotation();
                        ticksY++;
                    }
                }
                else
                {
                    baseX           /= ticksX;
                    baseY           /= ticksY;
                    isBaseCalculated = true;
                }
            }


            new_data = false;
            m_mutex.WaitOne();
            // check if there are new blendshape names, and if so update
            if (newBlendShapeNamesArrived())
            {
                m_rig = getRigFromBlendShapeNames(getBlendShapeNames());
            }

            // get most recent tracking data
            while (m_data_parser.CountAvailableTracks() > 0)
            {
                m_current_track = m_data_parser.Dequeue();
                new_data        = true;
            }

            // check that we have a rig (set up from blendshape names) with the same number of blendshapes as what we receive
            if (m_rig != null && m_current_track != null)
            {
                int n_track_coefficients = m_current_track.n_coefficients();
                int n_rig_coefficients   = m_rig.num_shapes();
                if (n_track_coefficients != n_rig_coefficients)
                {
                    Debug.LogWarning("number of coefficients of rig and tracking state have changed: " + n_track_coefficients + " vs " + n_rig_coefficients);
                    // clear the current rig as it is not usable with the data coming from faceshift
                    m_rig           = null;
                    m_current_track = null;
                    // get again the blendshapes from fs studio
                    askForBlendshapeNames();
                }
            }
            m_mutex.ReleaseMutex();

            if (m_rig != null && m_current_track != null && m_retargeting != null)
            {
                if (new_data && m_current_track.TrackSuccess)
                {
                    // create a rig state
                    RigState state = new RigState(m_rig);
                    state.set_timestamp(m_current_track.TimeStamp);
                    state.set_bone_translation(0, m_current_track.HeadTranslation());
                    state.set_bone_rotation(0, m_current_track.HeadRotation());
                    state.set_bone_rotation(1, m_current_track.LeftEyeRotation());
                    state.set_bone_rotation(2, m_current_track.RightEyeRotation());

                    for (int i = 0; i < m_rig.num_shapes(); i++)
                    {
                        state.set_blendshape_coefficient(i, m_current_track.Coefficient [i]);
                    }

                    // evaluate joint transformations
                    TransformationValue [] transformation_values = null;
                    if (m_tpose != null && m_tpose.m_joints.Count == m_game_object_transformations.Count)
                    {
                        // evaluate using tpose
                        transformation_values = Utils.evaluate_target_transformations(m_retargeting, m_rig, state, m_tpose.m_joints);
                    }
                    else
                    {
                        // evaluate using state from start of application
                        transformation_values = Utils.evaluate_target_transformations(m_retargeting, m_rig, state, m_game_object_transformations);
                    }

                    if (transformation_values.Length == m_game_object_transformations.Count)
                    {
                        for (int index = 0; index < transformation_values.Length; index++)
                        {
                            // Apply the value for this target
                            if (transformation_values [index] != null)
                            {
                                TransformationInformation joint = m_game_object_transformations [index] as TransformationInformation;
                                joint.transform.localRotation = transformation_values [index].m_rotation;
                                joint.transform.localPosition = transformation_values [index].m_translation;
                            }
                        }
                    }
                    else
                    {
                        Debug.LogError("Cannot create transformation as evaluated shape size is incorrect");
                    }

                    // evaluate blendshape valuesf
                    BlendshapeValue [] values = Utils.evaluate_target_blendshapes(m_retargeting, m_rig, state, m_game_object_blendshapes);

                    if (values.Length == m_game_object_blendshapes.Count)
                    {
                        for (int index = 0; index < m_game_object_blendshapes.Count; index++)
                        {
                            BlendshapeInfo bs_info = m_game_object_blendshapes [index] as BlendshapeInfo;
                            // Apply the value for this target
                            if (bs_info != null && values [index] != null)
                            {
                                bs_info.m_mesh_renderer.SetBlendShapeWeight(bs_info.m_index, (float)values [index].m_value);
                            }
                        }
                    }
                    else
                    {
                        Debug.LogError("Cannot create blendshapes as evaluated shape size is incorrect");
                    }
                }
            }
        }