void Start() { currentMotionFrameData = new MotionFrameData(); motionOwner = this.transform; currentComputeTime = motionMatcherSettings.ComputeMotionsBestCostGap; motionDebugDataList = new List <MotionDebugData>(); //HumanoidCrouchIdle 动画有问题,只能通过这种方式临时处理一下 for (int i = 0; i < motionsData.motionDataList.Length; i++) { MotionData motionData = motionsData.motionDataList[i]; if (motionData.motionName.Contains("HumanoidCrouchIdle")) { for (int j = 0; j < motionData.motionFrameDataList.Length; j++) { MotionFrameData motionFrameData = motionData.motionFrameDataList[j]; for (int k = 0; k < motionFrameData.motionTrajectoryDataList.Length; k++) { MotionTrajectoryData motionTrajectoryData = motionFrameData.motionTrajectoryDataList[k]; motionTrajectoryData.localPosition = Vector3.zero; } } } } }
private void CapturePlayingMotionSnapShot(PlayerInput playerInput, string motionName, float normalizedTime, MotionMainEntryType motionMainEntryType) { float velocity = playerInput.velocity; float angularVelocity = playerInput.angularVelocity; Vector3 direction = playerInput.direction; float acceleration = playerInput.acceleration; float brake = playerInput.brake; MotionFrameData bakedMotionFrameData = AcquireBakedMotionFrameData(motionName, normalizedTime, motionMainEntryType); currentMotionFrameData.velocity = velocity; currentMotionFrameData.motionBoneDataList = bakedMotionFrameData.motionBoneDataList; currentMotionFrameData.motionTrajectoryDataList = new MotionTrajectoryData[motionMatcherSettings.predictionTrajectoryTimeList.Length]; for (int i = 0; i < motionMatcherSettings.predictionTrajectoryTimeList.Length; i++) { float predictionTrajectoryTime = motionMatcherSettings.predictionTrajectoryTimeList[i]; currentMotionFrameData.motionTrajectoryDataList[i] = new MotionTrajectoryData(); MotionTrajectoryData motionTrajectoryData = currentMotionFrameData.motionTrajectoryDataList[i]; motionTrajectoryData.localPosition = velocity * direction * predictionTrajectoryTime; motionTrajectoryData.velocity = velocity * direction; if (Mathf.Abs(playerInput.angularVelocity) > 0) { motionTrajectoryData.direction = Quaternion.Euler(0, playerInput.angularVelocity * predictionTrajectoryTime, 0) * Vector3.forward; } } }
public void GetPlayerMotion(PlayerInput playerInput, float normalizedTime) { var motionFrame = GetBakedMotionFrame(playerInput, normalizedTime); PlayerMotionFrame.Velocity = PlayerInput.Velocity; //PlayerMotionFrame.Joints = motionFrame.Joints; PlayerMotionFrame.Joints = motionFrame.Joints; PlayerMotionFrame.TrajectoryDatas = new MotionTrajectoryData[MotionTrajectoryData.Length()]; for (var i = 0; i < MotionTrajectoryData.Length(); i++) { //var timeStamp = 1f / (float) (i+1); // it is wired var timeStamp = 1f / (float)(MotionTrajectoryData.Length() - i);//non-linear var trajectoryData = new MotionTrajectoryData(); //?? local = float velocity * (Vector 3) direction?? //player trajectory Data trajectoryData.LocalPosition = PlayerInput.Velocity * PlayerInput.Direction * timeStamp; //mark the localPosition always a straight line trajectoryData.Velocity = PlayerInput.Velocity * PlayerInput.Direction; // velocity for each trajectory is always the same //direction based on AngularyVelocity if (PlayerInput.AngularVelocity != 0f) { trajectoryData.Direction = Quaternion.Euler(0, PlayerInput.AngularVelocity * timeStamp, 0) * Vector3.forward.normalized; } PlayerMotionFrame.TrajectoryDatas[i] = trajectoryData; } }
private void CaptureTrajectorySnapShot(AnimationClip animClip, MotionFrameData motionFrameData, MotionFrameData lastMotionFrameData, GameObject sampleGO, float bakeFrames, float currentFrame) { float lastFrameTime = 0; for (int i = 0; i < predictionTrajectoryTimeList.Length; i++) { float PredictionTrajectoryTime = predictionTrajectoryTimeList[i]; float bakeDelta = currentFrame / bakeFrames; EditorUtility.DisplayProgressBar("Baking Animation", string.Format("Processing: {0} Frame: {1}", animClip.name, i), bakeDelta); float animationTime = bakeDelta * animClip.length + (PredictionTrajectoryTime * fps / bakeFrames) * animClip.length; if (requiresAnimator) { float normalizedTime = animationTime / animClip.length; animator.Play(animClip.name, 0, normalizedTime); if (lastFrameTime == 0) { float nextBakeDelta = Mathf.Clamp01(((float)(PredictionTrajectoryTime * fps / bakeFrames))); float nextAnimationTime = nextBakeDelta * animClip.length; lastFrameTime = animationTime - nextAnimationTime; } animator.Update(animationTime - lastFrameTime); lastFrameTime = animationTime; } else { GameObject sampleObject = sampleGO; Animation legacyAnimation = sampleObject.GetComponentInChildren <Animation>(); if (animator && animator.gameObject != sampleObject) { sampleObject = animator.gameObject; } else if (legacyAnimation && legacyAnimation.gameObject != sampleObject) { sampleObject = legacyAnimation.gameObject; } animClip.SampleAnimation(sampleObject, animationTime); } MotionTrajectoryData motionTrajectoryData = motionFrameData.motionTrajectoryDataList[i]; motionTrajectoryData.position = animator.transform.position; motionTrajectoryData.localPosition = motionTrajectoryData.position; motionTrajectoryData.direction = animator.transform.forward; //TODO motionTrajectoryData.velocity = Vector3.zero; } float currentClipTime = predictionTrajectoryTimeList[predictionTrajectoryTimeList.Length - 1]; MotionTrajectoryData firstMotionTrajectoryData = motionFrameData.motionTrajectoryDataList[0]; MotionTrajectoryData lastMotionTrajectoryData = motionFrameData.motionTrajectoryDataList[motionFrameData.motionTrajectoryDataList.Length - 1]; Vector3 offset = lastMotionTrajectoryData.position - firstMotionTrajectoryData.position; Vector3 velocity = offset / currentClipTime; motionFrameData.velocity = velocity.magnitude; }
protected virtual void OnSceneGUI() { float size = 0.1f; MotionMatcher motionMatcher = (MotionMatcher)target; currentMotionsData = motionMatcher.motionsData; if (currentMotionsData) { Transform child = motionMatcher.transform.Find(MotionMatchingBakeEditor.RootBoneName); Transform[] joints = child.GetComponentsInChildren <Transform>(); for (int i = 0; i < currentMotionsData.motionDataList.Length; i++) { MotionData motionData = currentMotionsData.motionDataList[i]; if (motionData.motionName == motionMatcher.bestMotionName || (string.IsNullOrEmpty(motionMatcher.bestMotionName) && motionData.motionName == defaultMotionName)) { for (int j = 0; j < motionData.motionFrameDataList.Length; j++) { MotionFrameData motionFrameData = motionData.motionFrameDataList[j]; for (int k = 0; k < motionFrameData.motionBoneDataList.Length; k++) { MotionBoneData motionBoneData = motionFrameData.motionBoneDataList[k]; Transform bone = joints[motionBoneData.boneIndex]; if (bone) { Vector3 bonePosition = motionBoneData.position; Handles.color = Color.green; Handles.SphereHandleCap(0, bonePosition, Quaternion.identity, size, EventType.Repaint); } } for (int l = 0; l < motionFrameData.motionTrajectoryDataList.Length; l++) { MotionTrajectoryData motionTrajectoryData = motionFrameData.motionTrajectoryDataList[l]; Handles.color = Color.yellow; Handles.SphereHandleCap(0, motionTrajectoryData.position, Quaternion.identity, size, EventType.Repaint); } } } } } }
public void GetClipTrajectoryData(MotionFrame frame) { frame.TrajectoryDatas = new MotionTrajectoryData[MotionTrajectoryData.Length()]; for (var i = 0; i < MotionTrajectoryData.Length(); i++) { var timeStamp = 1f / (float)(MotionTrajectoryData.Length() - i); var trajectoryData = new MotionTrajectoryData(); //trajectoryData.LocalPosition = 1000000f * frame.Velocity * frame.Direction * timeStamp; //trajectoryData.Velocity = 1000000f * frame.Velocity * frame.Direction; trajectoryData.LocalPosition = 1000f * frame.Velocity * frame.Direction * timeStamp; trajectoryData.Velocity = 1000f * frame.Velocity * frame.Direction; if (frame.AngularVelocity != 0f) { trajectoryData.Direction = (Quaternion.Euler(0, frame.AngularVelocity * timeStamp, 0) * Vector3.forward).normalized; } frame.TrajectoryDatas[i] = trajectoryData; } }
private void CapturePlayingMotionSnapShot(string motionName, float velocity, Vector3 direction, float acceleration, float brake, float normalizedTime, MotionMainEntryType motionMainEntryType) { MotionFrameData bakedMotionFrameData = AcquireBakedMotionFrameData(motionName, normalizedTime, motionMainEntryType); currentMotionFrameData.velocity = velocity; currentMotionFrameData.motionBoneDataList = bakedMotionFrameData.motionBoneDataList; currentMotionFrameData.motionTrajectoryDataList = new MotionTrajectoryData[motionMatcherSettings.predictionTrajectoryTimeList.Length]; float LastPredictionTrajectoryTime = 0; Vector3 LastPredictionPosition = Vector3.zero; for (int i = 0; i < motionMatcherSettings.predictionTrajectoryTimeList.Length; i++) { float predictionTrajectoryTime = motionMatcherSettings.predictionTrajectoryTimeList[i]; float deltaTime = predictionTrajectoryTime - LastPredictionTrajectoryTime; currentMotionFrameData.motionTrajectoryDataList[i] = new MotionTrajectoryData(); MotionTrajectoryData motionTrajectoryData = currentMotionFrameData.motionTrajectoryDataList[i]; motionTrajectoryData.localPosition = LastPredictionPosition + velocity * direction * deltaTime; motionTrajectoryData.velocity = velocity * direction; motionTrajectoryData.direction = direction; LastPredictionTrajectoryTime = predictionTrajectoryTime; LastPredictionPosition = motionTrajectoryData.localPosition; } }
private void OnDrawGizmos() { Vector3 baseLocation = playerMotionMatcher.transform.position; if (currentMotionFrameData != null) { Gizmos.color = Color.yellow; for (int i = 0; i < currentMotionFrameData.motionTrajectoryDataList.Length; i++) { MotionTrajectoryData motionTrajectoryData = currentMotionFrameData.motionTrajectoryDataList[i]; Gizmos.DrawSphere(motionTrajectoryData.localPosition + baseLocation, 0.05f); } } if (targetMotionFrameData != null) { Gizmos.color = Color.red; for (int i = 0; i < targetMotionFrameData.motionTrajectoryDataList.Length; i++) { MotionTrajectoryData motionTrajectoryData = targetMotionFrameData.motionTrajectoryDataList[i]; Gizmos.DrawSphere(motionTrajectoryData.localPosition + baseLocation, 0.05f); } } }
private void ComputeMotionsBestCost() { float bestMotionCost = float.MaxValue; bestMotionName = ""; bestMotionFrameIndex = 0; for (int i = 0; i < motionsData.motionDataList.Length; i++) { MotionData motionData = motionsData.motionDataList[i]; if (motionMatcherSettings.EnableDebugText) { AddDebugContent("motion: " + motionData.motionName); } for (int j = 0; j < motionData.motionFrameDataList.Length; j++) { MotionDebugData motionDebugData = new MotionDebugData(); float motionCost = 0f; float bonesCost = 0f; float bonePosCost = 0f; float boneRotCost = 0f; float trajectoryPosCost = 0f; float trajectoryVelCost = 0f; float trajectoryDirCost = 0f; float trajectorysCost = 0f; float rootMotionCost = 0f; MotionFrameData motionFrameData = motionData.motionFrameDataList[j]; for (int k = 0; k < motionFrameData.motionBoneDataList.Length; k++) { MotionBoneData motionBoneData = motionFrameData.motionBoneDataList[k]; MotionBoneData currentMotionBoneData = currentMotionFrameData.motionBoneDataList[k]; float BonePosCost = Vector3.SqrMagnitude(motionBoneData.localPosition - currentMotionBoneData.localPosition); Quaternion BonePosError = Quaternion.Inverse(motionBoneData.localRotation) * currentMotionBoneData.localRotation; float BoneRotCost = Mathf.Abs(BonePosError.x) + Mathf.Abs(BonePosError.y) + Mathf.Abs(BonePosError.z) + (1 - Mathf.Abs(BonePosError.w)); //float BoneVelocityCost = Vector3.SqrMagnitude(motionBoneData.velocity - currentMotionBoneData.velocity); bonePosCost += BonePosCost * motionCostFactorSettings.bonePosFactor; boneRotCost += BoneRotCost * motionCostFactorSettings.boneRotFactor /* + BoneVelocityCost * motionCostFactorSettings.boneVelFactor*/; //AddDebugContent("BonePosCost: " + BonePosCost); //AddDebugContent("BoneRotCost: " + BoneRotCost); //AddDebugContent("BoneVelocityCost: " + BoneVelocityCost); } bonesCost = bonePosCost + boneRotCost; motionDebugData.bonePosCost = bonePosCost; motionDebugData.boneRotCost = boneRotCost; motionDebugData.bonesCost = bonesCost; if (motionMatcherSettings.EnableDebugText) { AddDebugContent("bonesTotalCost: " + bonesCost); } for (int l = 0; l < motionFrameData.motionTrajectoryDataList.Length; l++) { MotionTrajectoryData motionTrajectoryData = motionFrameData.motionTrajectoryDataList[l]; MotionTrajectoryData currentMotionTrajectoryData = currentMotionFrameData.motionTrajectoryDataList[l]; trajectoryPosCost += Vector3.SqrMagnitude(motionTrajectoryData.localPosition - currentMotionTrajectoryData.localPosition) * motionCostFactorSettings.predictionTrajectoryPosFactor; //trajectoryVelCost += Vector3.SqrMagnitude(motionTrajectoryData.velocity - currentMotionTrajectoryData.velocity) * motionCostFactorSettings.predictionTrajectoryVelFactor; trajectoryDirCost += Vector3.Dot(motionTrajectoryData.direction, currentMotionTrajectoryData.direction) * motionCostFactorSettings.predictionTrajectoryDirFactor; //AddDebugContent("trajectoryPosCost: " + trajectoryPosCost); //AddDebugContent("trajectoryVelCost: " + trajectoryVelCost); //AddDebugContent("trajectoryDirCost: " + trajectoryDirCost); } trajectorysCost = trajectoryPosCost + trajectoryVelCost + trajectoryDirCost; motionDebugData.trajectoryPosCost = trajectoryPosCost; motionDebugData.trajectoryVelCost = trajectoryVelCost; motionDebugData.trajectoryDirCost = trajectoryDirCost; motionDebugData.trajectorysCost = trajectorysCost; if (motionMatcherSettings.EnableDebugText) { AddDebugContent("trajectorysToatalCost: " + trajectorysCost); } rootMotionCost = Mathf.Abs(motionFrameData.velocity - currentMotionFrameData.velocity) * motionCostFactorSettings.rootMotionVelFactor; motionDebugData.rootMotionCost = rootMotionCost; if (motionMatcherSettings.EnableDebugText) { AddDebugContent("rootMotionCost: " + rootMotionCost); } motionCost = bonesCost + trajectorysCost + rootMotionCost; motionDebugData.motionCost = motionCost; if (motionMatcherSettings.EnableDebugText) { AddDebugContent("motionTotalCost: " + motionCost); } //Debug.LogFormat("ComputeMotionsBestCost motionName {0} motionCost {1} ", motionData.motionName, motionCost); if (bestMotionCost > motionCost) { bestMotionCost = motionCost; bestMotionFrameIndex = j; bestMotionName = motionData.motionName; bestMotionDebugData = motionDebugData; motionDebugData.motionName = motionData.motionName; motionDebugData.motionFrameIndex = j; motionDebugDataList.Add(motionDebugData); } } } }
private void onDropdownChanged(int arg0) { costTextContainer.SetActive(true); hideCostTextContainerBtn.gameObject.SetActive(true); MotionData[] motionDataList = playerMotionMatcher.motionsData.motionDataList; MotionData motionData = motionDataList[arg0]; targetMotionFrameData = motionData.motionFrameDataList[0]; currentMotionFrameData = playerMotionMatcher.currentMotionFrameData; MotionDebugData motionDebugData = new MotionDebugData(); AddDebugContent("----------------------" + motionData.motionName); float motionCost = 0f; float bonesCost = 0f; float bonePosCost = 0f; float boneRotCost = 0f; float trajectoryPosCost = 0f; float trajectoryVelCost = 0f; float trajectoryDirCost = 0f; float trajectorysCost = 0f; float rootMotionCost = 0f; for (int k = 0; k < targetMotionFrameData.motionBoneDataList.Length; k++) { MotionBoneData motionBoneData = targetMotionFrameData.motionBoneDataList[k]; MotionBoneData currentMotionBoneData = currentMotionFrameData.motionBoneDataList[k]; float BonePosCost = Vector3.SqrMagnitude(motionBoneData.localPosition - currentMotionBoneData.localPosition); Quaternion BonePosError = Quaternion.Inverse(motionBoneData.localRotation) * currentMotionBoneData.localRotation; float BoneRotCost = Mathf.Abs(BonePosError.x) + Mathf.Abs(BonePosError.y) + Mathf.Abs(BonePosError.z) + (1 - Mathf.Abs(BonePosError.w)); //float BoneVelocityCost = Vector3.SqrMagnitude(motionBoneData.velocity - currentMotionBoneData.velocity); bonePosCost += BonePosCost * playerMotionMatcher.motionCostFactorSettings.bonePosFactor; boneRotCost += BoneRotCost * playerMotionMatcher.motionCostFactorSettings.boneRotFactor /* + BoneVelocityCost * motionCostFactorSettings.boneVelFactor*/; //AddDebugContent("BonePosCost: " + BonePosCost); //AddDebugContent("BoneRotCost: " + BoneRotCost); //AddDebugContent("BoneVelocityCost: " + BoneVelocityCost); } bonesCost = bonePosCost + boneRotCost; motionDebugData.bonePosCost = bonePosCost; motionDebugData.boneRotCost = boneRotCost; motionDebugData.bonesCost = bonesCost; AddDebugContent("bonesTotalCost: " + bonesCost); for (int l = 0; l < targetMotionFrameData.motionTrajectoryDataList.Length; l++) { MotionTrajectoryData motionTrajectoryData = targetMotionFrameData.motionTrajectoryDataList[l]; MotionTrajectoryData currentMotionTrajectoryData = currentMotionFrameData.motionTrajectoryDataList[l]; trajectoryPosCost += Vector3.SqrMagnitude(motionTrajectoryData.localPosition - currentMotionTrajectoryData.localPosition) * playerMotionMatcher.motionCostFactorSettings.predictionTrajectoryPosFactor; //trajectoryVelCost += Vector3.SqrMagnitude(motionTrajectoryData.velocity - currentMotionTrajectoryData.velocity) * motionCostFactorSettings.predictionTrajectoryVelFactor; trajectoryDirCost += Vector3.Dot(motionTrajectoryData.direction, currentMotionTrajectoryData.direction) * playerMotionMatcher.motionCostFactorSettings.predictionTrajectoryDirFactor; //AddDebugContent("trajectoryPosCost: " + trajectoryPosCost); //AddDebugContent("trajectoryVelCost: " + trajectoryVelCost); //AddDebugContent("trajectoryDirCost: " + trajectoryDirCost); } trajectorysCost = trajectoryPosCost + trajectoryVelCost + trajectoryDirCost; motionDebugData.trajectoryPosCost = trajectoryPosCost; motionDebugData.trajectoryVelCost = trajectoryVelCost; motionDebugData.trajectoryDirCost = trajectoryDirCost; motionDebugData.trajectorysCost = trajectorysCost; AddDebugContent("trajectoryPosCost: " + trajectoryPosCost); AddDebugContent("trajectoryVelCost: " + trajectoryVelCost); AddDebugContent("trajectoryDirCost: " + trajectoryDirCost); AddDebugContent("trajectorysToatalCost: " + trajectorysCost); rootMotionCost = Mathf.Abs(targetMotionFrameData.velocity - currentMotionFrameData.velocity) * playerMotionMatcher.motionCostFactorSettings.rootMotionVelFactor; motionDebugData.rootMotionCost = rootMotionCost; AddDebugContent("rootMotionCost: " + rootMotionCost); motionCost = bonesCost + trajectorysCost + rootMotionCost; motionDebugData.motionCost = motionCost; AddDebugContent("motionTotalCost: " + motionCost); }