/// <summary> /// Gets camera offsets from viewpoint and returns a SerialTransform /// </summary> /// <returns>SerialTransform only holds values, it doesn't reference a real transform</returns> public static SerialTransform GetOffsetsFromViewpoint(VRC_AvatarDescriptor desc, Camera cam) { SerialTransform offsets = new SerialTransform(); Transform dummy = null; try { dummy = new GameObject("Dummy").transform; dummy.localPosition = desc.ViewPosition + desc.gameObject.transform.position; offsets.localPosition = cam.transform.localPosition - dummy.localPosition; offsets.localEulerAngles = cam.transform.localEulerAngles - dummy.localEulerAngles; } catch (Exception e) { Debug.LogError(e.Message); } finally { if (dummy) { Helpers.DestroyAppropriate(dummy.gameObject); } } return(offsets); }
public bool SetupPreset(string poseName, GameObject avatar, PosePresetMode mode) { if (!avatar) { return(false); } if (mode == PosePresetMode.TransformRotations) { Transform[] trans = avatar.GetComponentsInChildren <Transform>(); transformPaths = new List <string>(trans.Length); transformRotations = new List <Vector3>(trans.Length); for (int i = 0; i < trans.Length; i++) { var t = trans[i]; string path = Helpers.GetTransformPath(t, avatar.transform, true); if (t && !string.IsNullOrEmpty(path)) { transformPaths.Add(path); transformRotations.Add(t.localEulerAngles); } } return(true); } else { Animator anim = avatar.GetComponent <Animator>(); if (!anim) { return(false); } SerialTransform tr = avatar.transform; avatar.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); HumanPose hp = new HumanPose(); try { HumanPoseHandler hph = new HumanPoseHandler(anim.avatar, anim.transform); hph.GetHumanPose(ref hp); } catch { avatar.transform.SetPositionAndRotation(tr.position, tr.rotation); return(false); } finally { avatar.transform.SetPositionAndRotation(tr.position, tr.rotation); SetupPreset(poseName, hp); } return(true); } }
private static void ReloadPoseVariables(GameObject newAvatar) { if (newAvatar) { _avatarAnimator = newAvatar.GetComponent <Animator>(); } else { _avatarAnimator = null; } if (bones == null) { bones = new List <PoseEditorBone>(); } bones.Clear(); if (newAvatar && AvatarAnimator && AvatarAnimator.isHuman) { avatarPose = new HumanPose(); SerialTransform st = newAvatar.transform; Vector3 avatarPos; avatarPoseHandler = new HumanPoseHandler(AvatarAnimator.avatar, AvatarAnimator.transform); avatarPoseHandler.GetHumanPose(ref avatarPose); avatarPos = st.position; newAvatar.transform.position = avatarPos; //Human bone transforms to compare against HashSet <Transform> humanBoneTransforms = new HashSet <Transform>(); for (int i = 0; i < HumanTrait.BoneCount; i++) { humanBoneTransforms.Add(AvatarAnimator.GetBoneTransform((HumanBodyBones)i)); } //Get bone human bone root and tip positions for (int i = 0; i < HumanTrait.BoneCount; i++) { Transform bone = AvatarAnimator.GetBoneTransform((HumanBodyBones)i); if (!bone || bone.childCount == 0) { continue; } for (int j = 0; j < bone.childCount; j++) { Transform child = bone.GetChild(j); if (humanBoneTransforms.Contains(child)) { bones.Add(new PoseEditorBone(bone, child)); } } } } }
/// <summary> /// Gets camera offset from viewpoint and returns a SerialTransform /// </summary> /// <returns>SerialTransform only holds values, it doesn't reference a real transform</returns> public static SerialTransform GetCameraOffsetFromViewpoint(GameObject avatar, Camera cam) { VRC_AvatarDescriptor desc = avatar.GetComponent <VRC_AvatarDescriptor>(); SerialTransform offsets = null; if (desc) { offsets = GetOffsetsFromViewpoint(desc, cam); } return(offsets); }
private void ApplyAnimation() { //Save transform position and rotation to prevent root motion SerialTransform currentTrans = PumkinsAvatarTools.SelectedAvatar.transform; animClip.SampleAnimation(PumkinsAvatarTools.SelectedAvatar, animTimeCurrent); if (currentTrans) //Restore position and rotation of avatar { PumkinsAvatarTools.SelectedAvatar.transform.SetPositionAndRotation(currentTrans.position, currentTrans.rotation); } ReloadPoseVariables(PumkinsAvatarTools.SelectedAvatar); }
private void DrawPoseFromAnimationGUI() { bool applyAnimation = false; EditorGUI.BeginChangeCheck(); { animClip = EditorGUILayout.ObjectField(Strings.PoseEditor.poseFromAnimation, animClip, typeof(AnimationClip), false) as AnimationClip; } if (EditorGUI.EndChangeCheck()) { animTimeCurrent = 0; applyAnimation = true; //playAnimation = false; } if (animClip) { EditorGUI.BeginChangeCheck(); { animTimeCurrent = EditorGUILayout.Slider(Strings.PoseEditor.animationTime, animTimeCurrent, 0, animClip.length); } if (EditorGUI.EndChangeCheck() || applyAnimation) //|| playAnimation) { //Save transform position and rotation to prevent root motion SerialTransform currentTrans = PumkinsAvatarTools.SelectedAvatar.transform; animClip.SampleAnimation(PumkinsAvatarTools.SelectedAvatar, animTimeCurrent); if (currentTrans) //Restore position and rotation of avatar { PumkinsAvatarTools.SelectedAvatar.transform.SetPositionAndRotation(currentTrans.position, currentTrans.rotation); } ReloadPoseVariables(PumkinsAvatarTools.SelectedAvatar); } allowMotion = GUILayout.Toggle(allowMotion, Strings.PoseEditor.allowMotion); //if(GUILayout.Button(playAnimation ? "Pause" : "Play")) // playAnimation = !playAnimation; //if(playAnimation) //{ // animTimeCurrent = animTimeCurrent + (float)deltaTime; // animTimeCurrent = Helpers.WrapToRange(animTimeCurrent, 0, animClip.length); //} } Helpers.DrawGUILine(); }
/// <summary> /// Returns position and rotation offsets from viewpoint to camera /// </summary> public void CalculateOffsets(VRC_AvatarDescriptor desc, Camera cam) { if (!desc || !cam) { return; } SerialTransform offsets = GetOffsetsFromViewpoint(desc, cam); if (offsets) { offsetMode = CameraOffsetMode.Viewpoint; positionOffset = offsets.localPosition; rotationAnglesOffset = offsets.localEulerAngles; } }
/// <summary> /// Gets camera offsets from transform and returns a SerialTransform /// </summary> /// <returns>SerialTransform only holds values, it doesn't reference a real transform</returns> public static SerialTransform GetOffsetsFromTransform(Transform transform, Camera cam) { if (!cam || !transform) { return(null); } Transform oldCamParent = cam.transform.parent; cam.transform.parent = transform; SerialTransform offsets = new SerialTransform() { localPosition = cam.transform.localPosition, localRotation = cam.transform.localRotation, localEulerAngles = cam.transform.localEulerAngles, }; cam.transform.parent = oldCamParent; return(offsets); }
/// <summary> /// Sets camera position and rotation based on position and rotation offsets from transform /// </summary> public static void ApplyTransformWithViewpointFocus(GameObject avatar, Camera cam, SerialTransform trans) { ApplyPositionAndRotationWithViewpointFocus(avatar, cam, trans.position, trans.localEulerAngles); }
private void DrawPoseFromAnimationGUI() { bool applyAnimation = false; EditorGUI.BeginChangeCheck(); { animClip = EditorGUILayout.ObjectField(Strings.PoseEditor.poseFromAnimation, animClip, typeof(AnimationClip), false) as AnimationClip; } if (EditorGUI.EndChangeCheck()) { animTimeCurrent = 0; applyAnimation = true; } if (animClip) { EditorGUI.BeginChangeCheck(); { animTimeCurrent = EditorGUILayout.Slider(Strings.PoseEditor.animationTime, animTimeCurrent, 0, animClip.length); } if (EditorGUI.EndChangeCheck() || applyAnimation) { //Save transform position and rotation to prevent root motion SerialTransform currentTrans = PumkinsAvatarTools.SelectedAvatar.transform; #if UNITY_2017 //For some reason SampleAnimation refuses to work if there's no runtime animation controller set in unity 2017 var tempAnim = AvatarAnimator.runtimeAnimatorController; AvatarAnimator.runtimeAnimatorController = ctrl; #endif animClip.SampleAnimation(PumkinsAvatarTools.SelectedAvatar, animTimeCurrent); #if UNITY_2017 //I really don't like this but it seems to work var serialTransforms = new List <SerialTransform>(); //Save all transform values after sampling animation to prevent reverting var transforms = PumkinsAvatarTools.SelectedAvatar.GetComponentsInChildren <Transform>(); foreach (var t in transforms) { serialTransforms.Add(t); } AvatarAnimator.runtimeAnimatorController = tempAnim; //Apply old animator controller; this reverts pose to first frame of animation for (int i = 0; i < transforms.Length; i++) //Restore pose based on transform rotations { transforms[i].localEulerAngles = serialTransforms[i].localEulerAngles; if (allowMotion) { transforms[i].localPosition = serialTransforms[i].localPosition; } } #endif if (!allowMotion && currentTrans) //Restore position and rotation of avatar itself if no motion allowed { PumkinsAvatarTools.SelectedAvatar.transform.SetPositionAndRotation(currentTrans.position, currentTrans.rotation); } ReloadPoseVariables(PumkinsAvatarTools.SelectedAvatar); } allowMotion = GUILayout.Toggle(allowMotion, Strings.PoseEditor.allowMotion); } Helpers.DrawGUILine(); }