示例#1
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 [] EvaluateTargetTransformations(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.GetNumberOfTranslationMappings(); mapping_nr++) {
					string mapping_target = retargeting.GetTranslationMappingDestination (mapping_nr);
					if (!mapping_target.Equals(tpose_joint.transformName)) {
						continue;
					}
					string mapping_src = retargeting.GetTranslationMappingSource (mapping_nr);
					int src_index = rig.BoneIndex (mapping_src);
					if (src_index >= 0) {
						double mapping_weight = retargeting.GetTranslationMappingWeight (mapping_nr);
						fs_joint_translation_local_from_t_pose += state.BoneTranslation (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.GetNumberOfRotationMappings(); mapping_nr++) {
					string mapping_target = retargeting.GetRotationMappingDestination (mapping_nr);
					if (!mapping_target.Equals (tpose_joint.transformName)) {
						continue;
					}
					string mapping_src = retargeting.GetRotationMappingSource (mapping_nr);
					int src_index = rig.BoneIndex (mapping_src);
					if (src_index >= 0) {
						double mapping_weight = retargeting.GetRotationMappingWeight (mapping_nr);
						
						// use slerp for weighting
						fs_joint_rotation_local_from_t_pose = Quaternion.Slerp (Quaternion.identity, state.BoneRotation (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;
		}
示例#2
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);
        }
		/// <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;
		}