/** * 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; }
/** * 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; }