/// <summary>
        /// Applies the joint transformations given an influence factor
        /// </summary>
        /// <returns><c>true</c>, if transformations could be applied, <c>false</c> otherwise.</returns>
        /// <param name="transformationsToSet">The set of transformations to apply</param>
        /// <param name="influence">The factor to apply the transformations. 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 ApplyTransformations(TransformationValue [] transformationsToSet, float influence)
        {
            if (transformationsToSet.Length != m_GameObjectTransformations.Count)
            {
                return(false);
            }

            for (int index = 0; index < m_GameObjectTransformations.Count; index++)
            {
                // Apply the value for this target
                if (transformationsToSet[index] != null)
                {
                    TransformationInformation joint = m_GameObjectTransformations[index] as TransformationInformation;
                    joint.transform.localRotation = Quaternion.Slerp(joint.transform.localRotation,
                                                                     transformationsToSet[index].m_rotation, influence);
                    joint.transform.localPosition = (1.0f - influence) * joint.transform.localPosition +
                                                    influence * transformationsToSet[index].m_translation;
                }
            }
            return(true);
        }
예제 #2
0
        /**
         * Adds all possible transformation targets of the game object
         * curGameObject and its sub-objects (recursively) to the
         * list of target transformations.
         */
        public static void getGameObjectTransformations(GameObject curGameObject,
                                                        ArrayList transformations)
        {
            if (transformations != null)
            {
                transformations.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);
                if (transformations != null)
                {
                    TransformationInformation transform_copy = new TransformationInformation();
                    transform_copy.rotation      = new Quaternion(child.rotation.x, child.rotation.y, child.rotation.z, child.rotation.w);
                    transform_copy.localRotation = new Quaternion(child.localRotation.x, child.localRotation.y, child.localRotation.z, child.localRotation.w);
                    transform_copy.position      = new Vector3(child.position.x, child.position.y, child.position.z);
                    transform_copy.localPosition = new Vector3(child.localPosition.x, child.localPosition.y, child.localPosition.z);
                    if (child.parent != null)
                    {
                        transform_copy.parentRotation = new Quaternion(child.parent.rotation.x, child.parent.rotation.y, child.parent.rotation.z, child.parent.rotation.w);
                        //Debug.Log("parent of child " + child.name + " is " + child.parent.name);
                    }
                    else
                    {
                        transform_copy.parentRotation = Quaternion.identity;
                        //Debug.Log("child " + child.name + " has no parent");
                    }

                    transform_copy.transform     = child;
                    transform_copy.transformPath = transformPath;
                    transform_copy.transformName = child.name;
                    transformations.Add(transform_copy);
                }
            }
        }
예제 #3
0
        //! @brief Loads the tpose from a byte array.
        //! @returns True if load was successful, false otherwise.
        public bool LoadFromBytes(byte [] data)
        {
            if (data == null)
            {
                return(false);
            }

            // create 2D grid of the file
            string text = System.Text.Encoding.UTF8.GetString(data);

            string[,] grid = SplitTPoseFile(text);
            //Debug.Log("size = " + grid.GetLength(0) + " , " + grid.GetLength (1));


            // first row contains version, number of joints
            int   row     = 0;
            int   col     = 0;
            Int32 version = 0;

            try {
                Convert.ToInt32(grid[row, col + 0]);
            } catch (Exception) {
                return(false);
            }
            if (version != TPOSE_FILE_VERSION)
            {
                return(false);
            }
            Int32 number_of_joints = Convert.ToInt32(grid[row, col + 1]);

            ArrayList new_joints = new ArrayList();

            for (int i = 0; i < number_of_joints; i++)
            {
                TransformationInformation joint = new TransformationInformation();
                int start_row = 1 + 2 * i;
                joint.rotation.x       = (float)Convert.ToDouble(grid[start_row, 0]);
                joint.rotation.y       = (float)Convert.ToDouble(grid[start_row, 1]);
                joint.rotation.z       = (float)Convert.ToDouble(grid[start_row, 2]);
                joint.rotation.w       = (float)Convert.ToDouble(grid[start_row, 3]);
                joint.localRotation.x  = (float)Convert.ToDouble(grid[start_row, 4]);
                joint.localRotation.y  = (float)Convert.ToDouble(grid[start_row, 5]);
                joint.localRotation.z  = (float)Convert.ToDouble(grid[start_row, 6]);
                joint.localRotation.w  = (float)Convert.ToDouble(grid[start_row, 7]);
                joint.position.x       = (float)Convert.ToDouble(grid[start_row, 8]);
                joint.position.y       = (float)Convert.ToDouble(grid[start_row, 9]);
                joint.position.z       = (float)Convert.ToDouble(grid[start_row, 10]);
                joint.localPosition.x  = (float)Convert.ToDouble(grid[start_row, 11]);
                joint.localPosition.y  = (float)Convert.ToDouble(grid[start_row, 12]);
                joint.localPosition.z  = (float)Convert.ToDouble(grid[start_row, 13]);
                joint.parentRotation.x = (float)Convert.ToDouble(grid[start_row, 14]);
                joint.parentRotation.y = (float)Convert.ToDouble(grid[start_row, 15]);
                joint.parentRotation.z = (float)Convert.ToDouble(grid[start_row, 16]);
                joint.parentRotation.w = (float)Convert.ToDouble(grid[start_row, 17]);
                joint.transformPath    = grid[start_row + 1, 0];
                if (grid[start_row + 1, 1] != null)
                {
                    joint.transformName = grid[start_row + row + 1, 1];
                }
                new_joints.Add(joint);
            }
            // Apply
            m_joints = new_joints;
            return(true);
        }
예제 #4
0
        /**
         *	Evaluates the target transformation based on the state of a rig and a retargeting configuration.
         *  If a transform is not affected by the retargeting then the value of the transform is null.
         */
        public static TransformationValue [] evaluate_target_transformations(ClipRetargeting retargeting,
                                                                             Rig rig,
                                                                             RigState state,
                                                                             ArrayList target_transformations)
        {
            if (retargeting == null || rig == null || state == null || target_transformations == null)
            {
                Debug.LogError("cannot evaluat target transformations as one or more object is null");
                return(null);
            }

            int n_target_transformations = target_transformations.Count;

            TransformationValue [] values = new TransformationValue[n_target_transformations];
            // We iterate over the target transformations and accumulate all sources to them
            for (int target_nr = 0; target_nr < target_transformations.Count; target_nr++)
            {
                // get original rotation and translation from tpose
                TransformationInformation tpose_joint = target_transformations[target_nr] as TransformationInformation;
                if (tpose_joint == null)
                {
                    Debug.LogError("joint " + target_nr + " is null");
                    continue;
                }
                Vector3    tpose_translation            = tpose_joint.localPosition;
                Quaternion tpose_local_rotation         = tpose_joint.localRotation;
                Quaternion tpose_parent_global_rotation = tpose_joint.parentRotation;

                Quaternion fs_joint_rotation_local_from_t_pose    = Quaternion.identity;
                Vector3    fs_joint_translation_local_from_t_pose = new Vector3(0, 0, 0);

                // Sum the translation to apply
                int value_count_trans = 0;
                for (int mapping_nr = 0; mapping_nr < retargeting.get_number_of_translation_mappings(); mapping_nr++)
                {
                    string mapping_target = retargeting.get_translation_mapping_destination(mapping_nr);
                    if (!mapping_target.Equals(tpose_joint.transformName))
                    {
                        continue;
                    }
                    string mapping_src = retargeting.get_translation_mapping_source(mapping_nr);
                    int    src_index   = rig.bone_index(mapping_src);
                    if (src_index >= 0)
                    {
                        double mapping_weight = retargeting.get_translation_mapping_weight(mapping_nr);
                        fs_joint_translation_local_from_t_pose += state.bone_translation(src_index) * (float)mapping_weight;
                        value_count_trans++;
                    }
                    else
                    {
                        Debug.Log("Could not find source index for '" + mapping_src + "'");
                    }
                }

                // Convert translation to global translation
                //Vector3 unity_joint_translation_local = fs_joint_translation_local_from_t_pose + tpose_translation;
                Vector3 unity_joint_translation_local =
                    Quaternion.Inverse(tpose_parent_global_rotation) * fs_joint_translation_local_from_t_pose
                    + tpose_translation;

                // Sum the rotations to apply
                int value_count_rot = 0;
                for (int mapping_nr = 0; mapping_nr < retargeting.get_number_of_rotation_mappings(); mapping_nr++)
                {
                    string mapping_target = retargeting.get_rotation_mapping_destination(mapping_nr);
                    if (!mapping_target.Equals(tpose_joint.transformName))
                    {
                        continue;
                    }
                    string mapping_src = retargeting.get_rotation_mapping_source(mapping_nr);
                    int    src_index   = rig.bone_index(mapping_src);
                    if (src_index >= 0)
                    {
                        double mapping_weight = retargeting.get_rotation_mapping_weight(mapping_nr);

                        // use slerp for weighting
                        fs_joint_rotation_local_from_t_pose = Quaternion.Slerp(Quaternion.identity, state.bone_rotation(src_index), (float)mapping_weight);
                        // TODO: here we should accumulate if there are more than one sources (like with blendshapes)
                        value_count_rot++;
                    }
                    else
                    {
                        Debug.Log("Could not find source rotation for '" + mapping_src);
                    }
                }

                // Convert to local unity rotation
                Quaternion unity_joint_rotation_local =
                    Quaternion.Inverse(tpose_parent_global_rotation)
                    * fs_joint_rotation_local_from_t_pose
                    * tpose_parent_global_rotation
                    * tpose_local_rotation;                                     // The initial local rotation;

                if (value_count_trans > 0 || value_count_rot > 0)
                {
                    values[target_nr] = new TransformationValue(unity_joint_rotation_local, unity_joint_translation_local);
                }
            }

            return(values);
        }
예제 #5
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");
                    }
                }
            }
        }
예제 #6
0
		//! @brief Loads the tpose from a byte array.
		//! @returns True if load was successful, false otherwise.
		public bool LoadFromBytes(byte [] data) {
		
			if (data == null) return false;
			
			// create 2D grid of the file
			string text = System.Text.Encoding.UTF8.GetString(data);			
			string[,] grid = SplitTPoseFile(text);
			//Debug.Log("size = " + grid.GetLength(0) + " , " + grid.GetLength (1)); 
			
			
			// first row contains version, number of joints
			int row = 0;
			int col = 0;
			Int32 version = 0;
			try {
				Convert.ToInt32(grid[row,col+0]);
			} catch (Exception) {
				return false;
			}
			if (version != TPOSE_FILE_VERSION) {
				return false;
			}
			Int32 number_of_joints = Convert.ToInt32(grid[row,col+1]);
			
			ArrayList new_joints = new ArrayList();
			for (int i = 0; i < number_of_joints; i++) {
				TransformationInformation joint = new TransformationInformation();
				int start_row = 1 + 2 * i;
				joint.rotation.x = (float)Convert.ToDouble(grid[start_row, 0]);
				joint.rotation.y = (float)Convert.ToDouble(grid[start_row, 1]);
				joint.rotation.z = (float)Convert.ToDouble(grid[start_row, 2]);
				joint.rotation.w = (float)Convert.ToDouble(grid[start_row, 3]);
				joint.localRotation.x = (float)Convert.ToDouble(grid[start_row, 4]);
				joint.localRotation.y = (float)Convert.ToDouble(grid[start_row, 5]);
				joint.localRotation.z = (float)Convert.ToDouble(grid[start_row, 6]);
				joint.localRotation.w = (float)Convert.ToDouble(grid[start_row, 7]);
				joint.position.x = (float)Convert.ToDouble(grid[start_row, 8]);
				joint.position.y = (float)Convert.ToDouble(grid[start_row, 9]);
				joint.position.z = (float)Convert.ToDouble(grid[start_row, 10]);
				joint.localPosition.x = (float)Convert.ToDouble(grid[start_row, 11]);
				joint.localPosition.y = (float)Convert.ToDouble(grid[start_row, 12]);
				joint.localPosition.z = (float)Convert.ToDouble(grid[start_row, 13]);
				joint.parentRotation.x = (float)Convert.ToDouble(grid[start_row, 14]);
				joint.parentRotation.y = (float)Convert.ToDouble(grid[start_row, 15]);
				joint.parentRotation.z = (float)Convert.ToDouble(grid[start_row, 16]);
				joint.parentRotation.w = (float)Convert.ToDouble(grid[start_row, 17]);
				joint.transformPath = grid[start_row + 1, 0];
				if (grid[start_row+1,1] != null) joint.transformName = grid[start_row+row+1, 1];
				new_joints.Add(joint);
			}
			// Apply
			m_joints = new_joints;
			return true;
		}
예제 #7
0
		/**
		 * Adds all possible transformation targets of the game object
		 * curGameObject and its sub-objects (recursively) to the
		 * list of target transformations.
		 */
		public static void GetGameObjectTransformations(GameObject curGameObject, ArrayList transformations) {
		
			if (transformations != null) transformations.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);
				if (transformations != null) {
					TransformationInformation transform_copy = new TransformationInformation();
					transform_copy.rotation = new Quaternion(child.rotation.x, child.rotation.y, child.rotation.z, child.rotation.w);
					transform_copy.localRotation = new Quaternion(child.localRotation.x, child.localRotation.y, child.localRotation.z, child.localRotation.w);
					transform_copy.position = new Vector3(child.position.x, child.position.y, child.position.z);
					transform_copy.localPosition = new Vector3(child.localPosition.x, child.localPosition.y, child.localPosition.z);
					if (child.parent != null) {
						transform_copy.parentRotation = new Quaternion(child.parent.rotation.x, child.parent.rotation.y, child.parent.rotation.z, child.parent.rotation.w); 
						//Debug.Log("parent of child " + child.name + " is " + child.parent.name);
					} else {
						transform_copy.parentRotation = Quaternion.identity; 
						//Debug.Log("child " + child.name + " has no parent");
					}

					transform_copy.transform = child;
					transform_copy.transformPath = transformPath;
					transform_copy.transformName = child.name;
					transformations.Add(transform_copy);
				}
			}
		}