private void DrawContactsOptionsOnRightMenu() { if (contactPointsRL == null || isDataSwitched) { contactPointsRL = new ReorderableList(editedData.contactPoints, typeof(MotionMatchingContact), true, false, true, true); } HandleContactPointsReorderbleList(contactPointsRL, editedData, 2); contactPointsRL.DoLayoutList(); GUILayout.Space(10); GUILayout.BeginHorizontal(); if (GUILayout.Button("Copy Contacts Settings", GUIResources.Button_MD())) { if (dataToCopyOptions != null) { editedData.contactPoints.Clear(); for (int i = 0; i < dataToCopyOptions.contactPoints.Count; i++) { editedData.contactPoints.Add(dataToCopyOptions.contactPoints[i]); } } } dataToCopyOptions = (MotionMatchingData)EditorGUILayout.ObjectField(dataToCopyOptions, typeof(MotionMatchingData), true); GUILayout.EndHorizontal(); GUILayout.Space(10); }
public void EvaluateMotionMatchgData(MotionMatchingData data, float deltaTime, int sequenceUpdateLoops = 4) { if (this.IsValid()) { switch (data.dataType) { case AnimationDataType.SingleAnimation: this.Evaluate(deltaTime); break; case AnimationDataType.BlendTree: this.Evaluate(deltaTime); break; case AnimationDataType.AnimationSequence: float seqDeltaTime = deltaTime / 4f; for (int i = 0; i < sequenceUpdateLoops; i++) { this.Evaluate(seqDeltaTime); asBuffor.Update(this, seqDeltaTime); } break; } } }
private void DrawNeededAssets() { GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); GUILayout.Label("MM Data"); GUILayout.Label("Game object"); GUILayout.EndVertical(); GUILayout.BeginVertical(); MotionMatchingData bufforData = (MotionMatchingData)EditorGUILayout.ObjectField(editedData, typeof(MotionMatchingData), true); if (bufforData != editedData) { isDataSwitched = true; OnAnimationDataSwitched(); editedData = bufforData; this.Repaint(); } else { isDataSwitched = false; } gameObject = (GameObject)EditorGUILayout.ObjectField(gameObject, typeof(GameObject), true); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Space(5); }
private void HandleSectionIntervals(ReorderableList list, MotionMatchingData currentData) { list.headerHeight = 2f; list.elementHeight = 40f; list.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { float numberWidth = 50f; float space = 10f; float VSpace = 10f; float elementHeight = rect.height - 2 * VSpace; Rect r1 = new Rect(rect.x, rect.y + VSpace, 50, elementHeight); Rect r2 = new Rect(r1.x + numberWidth + space, rect.y + VSpace, rect.width - 2 * (numberWidth + space), elementHeight); Rect r3 = new Rect(r2.x + r2.width + space, rect.y + VSpace, 50, elementHeight); float min = ((float2)list.list[index]).x; float max = ((float2)list.list[index]).y; min = EditorGUI.FloatField(r1, min); max = EditorGUI.FloatField(r3, max); EditorGUI.MinMaxSlider(r2, ref min, ref max, 0f, currentData.animationLength); if (index == list.index) { list.list[index] = new float2(min, max); } }; list.onAddCallback = (ReorderableList rlist) => { list.list.Add(new float2(0.0f, currentData.animationLength)); list.index = list.count - 1; }; list.onRemoveCallback = (ReorderableList rlist) => { if (list.index <= list.list.Count && list.index >= 0) { list.list.RemoveAt(list.index); } }; }
public static void PreviewMotionMatchingData( MotionMatchingData data, ref float animationTime, ref float animationTimeBuffor, PreparingDataPlayableGraph animator, float maxDeltaTime = 0.016667f ) { GUILayout.BeginHorizontal(); GUILayout.Space(5); animationTime = EditorGUILayout.Slider(animationTime, 0f, data.animationLength); GUILayout.Space(5); GUILayout.EndHorizontal(); float deltaTime = animationTime - animationTimeBuffor; animationTimeBuffor = animationTime; float deltaTimeModule = Mathf.Abs(deltaTime); if (deltaTime != 0) { if (animator != null && animator.IsValid()) { if (deltaTimeModule > maxDeltaTime) { int counter = Mathf.CeilToInt(deltaTimeModule / maxDeltaTime); deltaTime = deltaTime / counter; for (int i = 0; i < counter; i++) { animator.EvaluateMotionMatchgData(data, deltaTime); } } else { animator.EvaluateMotionMatchgData(data, deltaTime); } } } }
public bool CreateAnimationDataPlayables(MotionMatchingData data, float time = 0f) { currentMMData = data; if (this.IsValid()) { this.ClearMainMixerInput(); switch (data.dataType) { case AnimationDataType.SingleAnimation: AddClipPlayable(data.clips[0], time, 1f); break; case AnimationDataType.BlendTree: for (int i = 0; i < data.blendTreeWeights.Length; i++) { AddClipPlayable(data.clips[i], time, data.blendTreeWeights[i]); } break; case AnimationDataType.AnimationSequence: asBuffor = new AnimationsSequence("seq"); for (int i = 0; i < data.clips.Count; i++) { asBuffor.AddClip(data.clips[i]); asBuffor.neededInfo[i] = data.animationSeqInfos[i]; } asBuffor.CreateAnimationsInTime(time, this); break; } this.Evaluate(0); return(true); } return(false); }
public static void CalculateImpactPoints( MotionMatchingData data, MotionMatchingContact[] contactPoints, PreparingDataPlayableGraph playableGraph, GameObject gameObject ) { // Normalizacja kierunków kontaktów for (int i = 0; i < data.contactPoints.Count; i++) { MotionMatchingContact cp = data.contactPoints[i]; cp.contactNormal = math.normalize(cp.contactNormal); data.contactPoints[i] = cp; } // Pobrani początkowych wartości game objectu Vector3 startPos = gameObject.transform.position; Quaternion startRot = gameObject.transform.rotation; float deltaTime = data.frameTime; Matrix4x4 frameMatrix; NeedValueToCalculateData[] recordedData = new NeedValueToCalculateData[data.numberOfFrames]; Vector3[] cpPos = new Vector3[contactPoints.Length]; Vector3[] cpNormals = new Vector3[contactPoints.Length]; Vector3[] cpForwards = new Vector3[contactPoints.Length]; if (playableGraph != null) { playableGraph.Destroy(); } playableGraph = new PreparingDataPlayableGraph(); playableGraph.Initialize(gameObject); playableGraph.CreateAnimationDataPlayables(data); // RecordingData float currentTime = 0f; float currentDeltaTime = deltaTime; int contactPointIndex = 0; for (int i = 0; i < data.numberOfFrames; i++) { recordedData[i] = new NeedValueToCalculateData( gameObject.transform.position, gameObject.transform.forward, gameObject.transform.rotation ); currentTime += deltaTime; if (contactPointIndex < contactPoints.Length && currentTime >= contactPoints[contactPointIndex].startTime) { float buforDeltaTime = currentTime - contactPoints[contactPointIndex].startTime; currentDeltaTime = deltaTime - buforDeltaTime; playableGraph.EvaluateMotionMatchgData(data, currentDeltaTime); cpPos[contactPointIndex] = gameObject.transform.TransformPoint(contactPoints[contactPointIndex].position); cpNormals[contactPointIndex] = gameObject.transform.TransformDirection(contactPoints[contactPointIndex].contactNormal); cpForwards[contactPointIndex] = gameObject.transform.forward; contactPointIndex++; playableGraph.EvaluateMotionMatchgData(data, buforDeltaTime); currentDeltaTime = deltaTime; } else { playableGraph.EvaluateMotionMatchgData(data, currentDeltaTime); } } // calcualationData for (int i = 0; i < data.numberOfFrames; i++) { frameMatrix = Matrix4x4.TRS( recordedData[i].position, recordedData[i].rotation, Vector3.one ); FrameData currentFrame = data.frames[i]; for (int impactIndex = 0; impactIndex < data.contactPoints.Count; impactIndex++) { if (data.contactPoints[impactIndex].IsContactInTime(currentFrame.localTime)) { currentFrame.contactPoints = new FrameContact[1]; Vector3 pos = frameMatrix.inverse.MultiplyPoint3x4(cpPos[impactIndex]); Vector3 norDir = frameMatrix.inverse.MultiplyVector(cpNormals[impactIndex]); Vector3 forw = frameMatrix.inverse.MultiplyVector(cpForwards[impactIndex]); FrameContact cp = new FrameContact( pos, norDir //forw ); currentFrame.contactPoints[0] = cp; break; } else { currentFrame.contactPoints = new FrameContact[0]; } } if (data.contactPoints.Count == 0) { currentFrame.contactPoints = new FrameContact[0]; } data.frames[i] = currentFrame; } gameObject.transform.position = startPos; gameObject.transform.rotation = startRot; //if (data.contactPoints.Count >= 2) //{ // Vector3 firstPoint = data.GetContactPoint(0, data.contactPoints[0].startTime).position; // Vector3 secondPoint = data.GetContactPoint(1, data.contactPoints[0].startTime).position; // Vector3 dir = secondPoint - firstPoint; // dir.y = 0; // data.fromFirstToSecondContactRot = Quaternion.FromToRotation(dir, Vector3.forward); //} //else //{ // data.fromFirstToSecondContactRot = Quaternion.identity; //} playableGraph.ClearMainMixerInput(); playableGraph.Destroy(); }
private void CalculateNormalClips( PreparingDataPlayableGraph graph, string saveFolder, List <Transform> bonesMask ) { foreach (AnimationClip clip in creator.clips) { if (clip != null) { MotionMatchingData newCreatedAsset = MotionDataCalculator.CalculateNormalData( creator.gameObjectTransform.gameObject, graph, clip, bonesMask, creator.bonesWeights, creator.posesPerSecond, clip.isLooping, creator.gameObjectTransform, creator.trajectoryStepTimes, creator.blendToYourself, creator.findInYourself ); string path = saveFolder.Substring(Application.dataPath.Length - 6) + "/" + newCreatedAsset.name + ".asset"; MotionMatchingData loadedAsset = (MotionMatchingData)AssetDatabase.LoadAssetAtPath(path, typeof(MotionMatchingData)); if (creator.cutTimeFromStart > 0f) { newCreatedAsset.neverChecking.timeIntervals.Add( new float2( 0f, math.clamp(creator.cutTimeFromStart, 0f, newCreatedAsset.animationLength) )); } if (creator.cutTimeToEnd > 0f) { newCreatedAsset.neverChecking.timeIntervals.Add( new float2( math.clamp(newCreatedAsset.animationLength - creator.cutTimeToEnd, 0f, newCreatedAsset.animationLength), newCreatedAsset.animationLength )); } if (loadedAsset == null) { AssetDatabase.CreateAsset(newCreatedAsset, path); } else { loadedAsset.UpdateFromOther(newCreatedAsset, newCreatedAsset.name); if (loadedAsset.contactPoints != null) { if (loadedAsset.contactPoints.Count > 0) { MotionDataCalculator.CalculateContactPoints( loadedAsset, loadedAsset.contactPoints.ToArray(), graph, creator.gameObjectTransform.gameObject ); } } EditorUtility.SetDirty(loadedAsset); //AssetDatabase.SaveAssets(); } } else { Debug.Log("Element is null"); } } Debug.Log("Calculation of normal clips completed!"); }
public static void CalculateTrajectoryPointsFromRecordData( MotionMatchingData clip, NeedValueToCalculateData[] recordData, float recordDataLength, float recordStep, Vector2 startAndStopOfClip, List <float> trajectoryStepTimes ) { Matrix4x4 frameMatrix; int firstFrameIndex = Mathf.FloorToInt(startAndStopOfClip.x / recordStep); //Debug.Log("first frame index "+firstFrameIndex); for (int fIndex = 0; fIndex < clip.frames.Count; fIndex++) { int frameIndexInRecordData = firstFrameIndex + Mathf.FloorToInt(clip.frames[fIndex].localTime / recordStep); frameMatrix = Matrix4x4.TRS( recordData[frameIndexInRecordData].position, recordData[frameIndexInRecordData].rotation, Vector3.one ); FrameData bufforFrame = clip.frames[fIndex]; // Debug.Log(frameIndexInRecordData); for (int i = 0; i < trajectoryStepTimes.Count; i++) { int pointIndex = Mathf.FloorToInt(trajectoryStepTimes[i] / recordStep); //Debug.Log(trajectoryStepTimes[i] + " / " + recordStep + " = " + pointIndex); //Debug.Log(frameIndexInRecordData); //Debug.Log(pointIndex); //Debug.Log(frameIndexInRecordData + pointIndex + " < " + recordData.Length); int recordDataIndex = frameIndexInRecordData + pointIndex; recordDataIndex = recordDataIndex < 0 ? 0 : recordDataIndex; NeedValueToCalculateData n = recordData[recordDataIndex]; Vector3 pointPos = frameMatrix.inverse.MultiplyPoint3x4(n.position); Vector3 pointVel; if (trajectoryStepTimes[i] < 0) { pointVel = frameMatrix.inverse.MultiplyVector( (recordData[frameIndexInRecordData].position - n.position) / Mathf.Abs(trajectoryStepTimes[i]) ); } else { pointVel = frameMatrix.inverse.MultiplyVector( (n.position - recordData[frameIndexInRecordData].position) / Mathf.Abs(trajectoryStepTimes[i]) ); } Vector3 pointOrientation = frameMatrix.inverse.MultiplyVector(n.orientation); bufforFrame.trajectory.SetPoint( new TrajectoryPoint( pointPos, pointVel, pointOrientation ), i ); } clip.frames[fIndex] = bufforFrame; } }
public static void CalculateContactPoints( MotionMatchingData data, MotionMatchingContact[] contactPoints, PreparingDataPlayableGraph playableGraph, GameObject gameObject ) { for (int i = 0; i < data.contactPoints.Count; i++) { MotionMatchingContact cp = data.contactPoints[i]; cp.contactNormal = math.normalize(cp.contactNormal); data.contactPoints[i] = cp; } Vector3 startPos = gameObject.transform.position; Quaternion startRot = gameObject.transform.rotation; float deltaTime = data.frameTime; Matrix4x4 frameMatrix; NeedValueToCalculateData[] recordedData = new NeedValueToCalculateData[data.numberOfFrames]; Vector3[] cpPos = new Vector3[contactPoints.Length]; Vector3[] cpNormals = new Vector3[contactPoints.Length]; Vector3[] cpForwards = new Vector3[contactPoints.Length]; if (playableGraph != null) { playableGraph.Destroy(); } playableGraph = new PreparingDataPlayableGraph(); playableGraph.Initialize(gameObject); playableGraph.CreateAnimationDataPlayables(data); // RecordingData float currentTime = 0f; float currentDeltaTime = deltaTime; int contactPointIndex = 0; for (int i = 0; i < data.numberOfFrames; i++) { recordedData[i] = new NeedValueToCalculateData( gameObject.transform.position, gameObject.transform.forward, gameObject.transform.rotation ); currentTime += deltaTime; if (contactPointIndex < contactPoints.Length && currentTime >= contactPoints[contactPointIndex].startTime) { float buforDeltaTime = currentTime - contactPoints[contactPointIndex].startTime; currentDeltaTime = deltaTime - buforDeltaTime; playableGraph.EvaluateMotionMatchgData(data, currentDeltaTime); cpPos[contactPointIndex] = gameObject.transform.TransformPoint(contactPoints[contactPointIndex].position); cpNormals[contactPointIndex] = gameObject.transform.TransformDirection(contactPoints[contactPointIndex].contactNormal); cpForwards[contactPointIndex] = gameObject.transform.forward; contactPointIndex++; playableGraph.EvaluateMotionMatchgData(data, buforDeltaTime); currentDeltaTime = deltaTime; } else { playableGraph.EvaluateMotionMatchgData(data, currentDeltaTime); } } // calcualationData for (int i = 0; i < data.numberOfFrames; i++) { frameMatrix = Matrix4x4.TRS( recordedData[i].position, recordedData[i].rotation, Vector3.one ); FrameData currentFrame = data.frames[i]; currentFrame.contactPoints = new FrameContact[cpPos.Length]; for (int j = 0; j < cpPos.Length; j++) { Vector3 pos = frameMatrix.inverse.MultiplyPoint3x4(cpPos[j]); Vector3 norDir = frameMatrix.inverse.MultiplyVector(cpNormals[j]); Vector3 forw = frameMatrix.inverse.MultiplyVector(cpForwards[j]); FrameContact cp = new FrameContact( pos, norDir //forw ); currentFrame.contactPoints[j] = cp; } data.frames[i] = currentFrame; } gameObject.transform.position = startPos; gameObject.transform.rotation = startRot; if (data.contactPoints.Count >= 2) { for (int i = 0; i < contactPoints.Length - 1; i++) { Vector3 firstPoint = data.GetContactPointInTime(i, data.contactPoints[i].startTime).position; Vector3 secondPoint = data.GetContactPointInTime(i + 1, data.contactPoints[i].startTime).position; Vector3 dir = secondPoint - firstPoint; dir.y = 0; MotionMatchingContact c = data.contactPoints[i]; c.rotationFromForwardToNextContactDir = Quaternion.FromToRotation(dir, Vector3.forward); data.contactPoints[i] = c; } } if (data.contactPoints.Count >= 2) { Vector3 firstPoint = data.GetContactPointInTime(0, data.contactPoints[0].startTime).position; Vector3 secondPoint = data.GetContactPointInTime(1, data.contactPoints[0].startTime).position; Vector3 dir = secondPoint - firstPoint; dir.y = 0; data.fromFirstToSecondContactRot = Quaternion.FromToRotation( Vector3.ProjectOnPlane(dir, Vector3.up), Vector3.forward ); } else { data.fromFirstToSecondContactRot = Quaternion.identity; } playableGraph.ClearMainMixerInput(); playableGraph.Destroy(); }
public static MotionMatchingData CalculateBlendTreeData( string name, GameObject go, PreparingDataPlayableGraph graph, AnimationClip[] clips, List <Transform> bonesMask, List <Vector2> bonesWeights, Transform root, List <float> trajectoryStepTimes, float[] weightsForClips, int sampling, bool loop, bool blendToYourself, bool findInYourself ) { if (!graph.IsValid()) { graph.Initialize(go); } go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity; #region need floats float frameTime = 1f / (float)sampling; int numberOfFrames = Mathf.FloorToInt(clips[0].length / frameTime) + 1; #endregion float weightSum = 0f; for (int i = 0; i < weightsForClips.Length; i++) { weightSum += weightsForClips[i]; } for (int i = 0; i < weightsForClips.Length; i++) { weightsForClips[i] = weightsForClips[i] / weightSum; } MotionMatchingData data = new MotionMatchingData( clips, weightsForClips, sampling, name, loop, clips[0].length, findInYourself, blendToYourself, AnimationDataType.BlendTree ); FrameData frameBuffer; BoneData boneBuffer; PoseData poseBuffor; Trajectory trajectoryBuffor; NeedValueToCalculateData[] previewBoneData = new NeedValueToCalculateData[bonesMask.Count]; NeedValueToCalculateData[] nextBoneData = new NeedValueToCalculateData[bonesMask.Count]; for (int i = 0; i < clips.Length; i++) { graph.AddClipPlayable(clips[i]); graph.SetMixerInputTime(i, 0f); graph.SetMixerInputWeight(i, weightsForClips[i]); } graph.Evaluate(frameTime); int frameIndex = 0; float currentCheckingTime = 0f; // FramesCalculation for (; frameIndex < numberOfFrames; frameIndex++) { for (int i = 0; i < bonesMask.Count; i++) { previewBoneData[i] = GetValuesFromTransform(bonesMask[i], root); } graph.Evaluate(frameTime); currentCheckingTime = frameIndex * frameTime; for (int i = 0; i < bonesMask.Count; i++) { nextBoneData[i] = GetValuesFromTransform(bonesMask[i], root); } poseBuffor = new PoseData(bonesMask.Count); for (int i = 0; i < bonesMask.Count; i++) { float2 boneWeight = bonesWeights[i]; float3 velocity = BoneData.CalculateVelocity(previewBoneData[i].position, nextBoneData[i].position, frameTime); float3 localPosition = previewBoneData[i].position; quaternion orientation = previewBoneData[i].rotation; boneBuffer = new BoneData(localPosition, velocity); poseBuffor.SetBone(boneBuffer, i); } trajectoryBuffor = new Trajectory(trajectoryStepTimes.Count); frameBuffer = new FrameData( frameIndex, currentCheckingTime, trajectoryBuffor, poseBuffor, new FrameSections(true) ); data.AddFrame(frameBuffer); } // Trajectory calculations float clipGlobalStart; Vector2 clipStartAndStop; float recordingClipTime; if (trajectoryStepTimes[0] < 0) { clipGlobalStart = trajectoryStepTimes[0]; clipStartAndStop = new Vector2(-clipGlobalStart, -clipGlobalStart + clips[0].length); } else { clipGlobalStart = 0; clipStartAndStop = new Vector2(0, clips[0].length); } if (trajectoryStepTimes[trajectoryStepTimes.Count - 1] > 0) { recordingClipTime = clipStartAndStop.y + trajectoryStepTimes[trajectoryStepTimes.Count - 1] + 0.1f; } else { recordingClipTime = clipStartAndStop.y + 0.1f; } int samplesPerSecond = 100; float deltaTime = 1f / (float)samplesPerSecond; int dataCount = Mathf.CeilToInt(recordingClipTime / deltaTime); NeedValueToCalculateData[] recordData = new NeedValueToCalculateData[dataCount]; go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity; for (int i = 0; i < graph.GetMixerInputCount(); i++) { graph.SetMixerInputTimeInPlace(i, clipGlobalStart); } recordData[0] = new NeedValueToCalculateData( go.transform.position, go.transform.forward, go.transform.rotation ); for (int i = 0; i < dataCount; i++) { graph.Evaluate(deltaTime); recordData[i] = new NeedValueToCalculateData( go.transform.position, go.transform.forward, go.transform.rotation ); } //clearing graph from all animations graph.ClearMainMixerInput(); MotionDataCalculator.CalculateTrajectoryPointsFromRecordData( data, recordData, recordingClipTime, deltaTime, clipStartAndStop, trajectoryStepTimes ); data.usedFrameCount = data.numberOfFrames; data.trajectoryPointsTimes = new List <float>(); for (int i = 0; i < trajectoryStepTimes.Count; i++) { data.trajectoryPointsTimes.Add(trajectoryStepTimes[i]); } return(data); }
public static MotionMatchingData CalculateAnimationSequenceData( string name, AnimationsSequence seq, GameObject go, PreparingDataPlayableGraph graph, List <Transform> bonesMask, List <Vector2> bonesWeights, int sampling, bool loop, Transform root, List <float> trajectoryStepTimes, bool blendToYourself, bool findInYourself ) { if (!graph.IsValid()) { graph.Initialize(go); } go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity; seq.CalculateLength(); #region need floats float frameTime = 1f / (float)sampling; int numberOfFrames = Mathf.FloorToInt(seq.length / frameTime) + 1; #endregion MotionMatchingData data = new MotionMatchingData( seq.clips.ToArray(), seq.neededInfo.ToArray(), sampling, name, loop, seq.length, findInYourself, blendToYourself, AnimationDataType.AnimationSequence ); FrameData frameBuffer; BoneData boneBuffer; PoseData poseBuffor; Trajectory trajectoryBuffor; NeedValueToCalculateData[] previuData = new NeedValueToCalculateData[bonesMask.Count]; NeedValueToCalculateData[] nextData = new NeedValueToCalculateData[bonesMask.Count]; int seqDeltaSampling = 3; //seq.CreatePlayableGraph(playableGraph, go); //seq.Update(-frameTime, playableGraph, seqDeltaSampling); seq.CreateAnimationsInTime(0f, graph); graph.Evaluate(frameTime); seq.Update(graph, frameTime); int frameIndex = 0; for (; frameIndex < numberOfFrames; frameIndex++) { for (int i = 0; i < bonesMask.Count; i++) { previuData[i] = GetValuesFromTransform(bonesMask[i], root); } graph.Evaluate(frameTime); seq.Update(graph, frameTime); //Debug.Log((float)animator.GetMixerInputTime(0) - clip.length); for (int i = 0; i < bonesMask.Count; i++) { nextData[i] = GetValuesFromTransform(bonesMask[i], root); } poseBuffor = new PoseData(bonesMask.Count); for (int i = 0; i < bonesMask.Count; i++) { float2 boneWeight = bonesWeights[i]; float3 velocity = BoneData.CalculateVelocity(previuData[i].position, nextData[i].position, frameTime); float3 localPosition = previuData[i].position; quaternion orientation = previuData[i].rotation; boneBuffer = new BoneData(localPosition, velocity); poseBuffor.SetBone(boneBuffer, i); } trajectoryBuffor = new Trajectory(trajectoryStepTimes.Count); frameBuffer = new FrameData( frameIndex, frameIndex * frameTime, trajectoryBuffor, poseBuffor, new FrameSections(true) ); data.AddFrame(frameBuffer); } float clipGlobalStart; Vector2 clipStartAndStop; float recordingClipTime; if (trajectoryStepTimes[0] < 0) { clipGlobalStart = trajectoryStepTimes[0]; clipStartAndStop = new Vector2(-clipGlobalStart, -clipGlobalStart + seq.length); } else { clipGlobalStart = 0; clipStartAndStop = new Vector2(0, seq.length); } if (trajectoryStepTimes[trajectoryStepTimes.Count - 1] > 0) { recordingClipTime = clipStartAndStop.y + trajectoryStepTimes[trajectoryStepTimes.Count - 1] + 0.1f; } else { recordingClipTime = clipStartAndStop.y + 0.1f; } int samplesPerSecond = 100; float deltaTime = 1f / (float)samplesPerSecond; int dataCount = Mathf.CeilToInt(recordingClipTime / deltaTime); NeedValueToCalculateData[] recordData = new NeedValueToCalculateData[dataCount]; go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity; //seq.Update(clipGlobalStart, playableGraph); graph.ClearMainMixerInput(); seq.CreateAnimationsInTime(clipGlobalStart, graph); recordData[0] = new NeedValueToCalculateData( go.transform.position, go.transform.forward, go.transform.rotation ); for (int i = 0; i < dataCount; i++) { graph.Evaluate(deltaTime); seq.Update(graph, deltaTime); recordData[i] = new NeedValueToCalculateData( go.transform.position, go.transform.forward, go.transform.rotation ); } //clearing graph from all animations graph.ClearMainMixerInput(); MotionDataCalculator.CalculateTrajectoryPointsFromRecordData( data, recordData, recordingClipTime, deltaTime, clipStartAndStop, trajectoryStepTimes ); data.usedFrameCount = data.numberOfFrames; data.trajectoryPointsTimes = new List <float>(); for (int i = 0; i < trajectoryStepTimes.Count; i++) { data.trajectoryPointsTimes.Add(trajectoryStepTimes[i]); } return(data); }
private void CalculateAnimationsSequences( PreparingDataPlayableGraph graph, string saveFolder, List <Transform> bonesMask ) { foreach (AnimationsSequence seq in creator.sequences) { if (!seq.IsValid()) { continue; } MotionMatchingData newCreatedAsset = MotionDataCalculator.CalculateAnimationSequenceData( seq.name, seq, creator.gameObjectTransform.gameObject, graph, bonesMask, creator.bonesWeights, creator.posesPerSecond, true, creator.gameObjectTransform, creator.trajectoryStepTimes, seq.blendToYourself, seq.findInYourself ); string path = saveFolder.Substring(Application.dataPath.Length - 6) + "/" + newCreatedAsset.name + ".asset"; MotionMatchingData loadedAsset = (MotionMatchingData)AssetDatabase.LoadAssetAtPath(path, typeof(MotionMatchingData)); float startTime = 0f; float endTime = 0f; float delta = 0.1f; for (int i = 0; i < seq.findPoseInClip.Count; i++) { endTime += (seq.neededInfo[i].y - seq.neededInfo[i].x); if (!seq.findPoseInClip[i]) { float startB = startTime; float endB = endTime; if (i == seq.findPoseInClip.Count - 1) { if (seq.findPoseInClip[0]) { endB = endTime - delta; } if (seq.findPoseInClip[i - 1]) { startB = startTime + delta; } } else if (i == 0) { if (seq.findPoseInClip[i + 1]) { endB = endTime - delta; } if (seq.findPoseInClip[seq.findPoseInClip.Count - 1]) { startB = startTime + delta; } } else { if (seq.findPoseInClip[i + 1]) { endB = endTime - delta; } if (seq.findPoseInClip[i - 1]) { startB = startTime + delta; } } newCreatedAsset.neverChecking.timeIntervals.Add(new Vector2(startB, endB)); } startTime = endTime; } if (loadedAsset == null) { AssetDatabase.CreateAsset(newCreatedAsset, path); //AssetDatabase.SaveAssets(); } else { loadedAsset.UpdateFromOther(newCreatedAsset, newCreatedAsset.name); if (loadedAsset.contactPoints != null) { if (loadedAsset.contactPoints.Count > 0) { MotionDataCalculator.CalculateContactPoints( loadedAsset, loadedAsset.contactPoints.ToArray(), graph, creator.gameObjectTransform.gameObject ); } } EditorUtility.SetDirty(loadedAsset); //AssetDatabase.SaveAssets(); } } Debug.Log("Calculation of sequences completed!"); }
private void OnEnable() { data = (MotionMatchingData)this.target; scroll = Vector2.zero; }
private void DrawSelectedSection(MM_DataSection section) { if (selectedSection != section) { selectedSection = section; sectionIntervalsRL = new ReorderableList(selectedSection.timeIntervals, typeof(float2), true, false, true, true); } HandleSectionIntervals(sectionIntervalsRL, editedData); sectionIntervalsRL.DoLayoutList(); GUILayout.Space(10); GUILayout.BeginHorizontal(); if (GUILayout.Button("Copy Section Settings", GUIResources.Button_MD())) { if (dataToCopyOptions != null) { switch (selectedSectionType) { case SectionSelectedType.NotLookingForNewPoseSection: editedData.notLookingForNewPose.timeIntervals.Clear(); for (int i = 0; i < dataToCopyOptions.notLookingForNewPose.timeIntervals.Count; i++) { editedData.notLookingForNewPose.timeIntervals.Add(new float2( dataToCopyOptions.notLookingForNewPose.timeIntervals[i].x, dataToCopyOptions.notLookingForNewPose.timeIntervals[i].y )); } break; case SectionSelectedType.NeverLookingForNewPoseSection: editedData.neverChecking.timeIntervals.Clear(); for (int i = 0; i < dataToCopyOptions.neverChecking.timeIntervals.Count; i++) { editedData.neverChecking.timeIntervals.Add(new float2( dataToCopyOptions.neverChecking.timeIntervals[i].x, dataToCopyOptions.neverChecking.timeIntervals[i].y )); } break; case SectionSelectedType.NormalSection: if (0 <= selectedSectionIndex && selectedSectionIndex < dataToCopyOptions.sections.Count) { editedData.sections[selectedSectionIndex].timeIntervals.Clear(); for (int i = 0; i < dataToCopyOptions.sections[selectedSectionIndex].timeIntervals.Count; i++) { editedData.AddSectionInterval( selectedSectionIndex, i, dataToCopyOptions.sections[selectedSectionIndex].timeIntervals[i] ); } } break; } } } dataToCopyOptions = (MotionMatchingData)EditorGUILayout.ObjectField(dataToCopyOptions, typeof(MotionMatchingData), true); GUILayout.EndHorizontal(); GUILayout.Space(10); }
private void HandleContactPointsReorderbleList( ReorderableList rList, MotionMatchingData currentData, int elementLines ) { rList.onSelectCallback = (ReorderableList list) => { }; rList.onAddCallback = (ReorderableList list) => { currentData.contactPoints.Add(new MotionMatchingContact(0f)); }; rList.onRemoveCallback = (ReorderableList list) => { currentData.contactPoints.RemoveAt(list.index); list.index = list.count - 1; }; rList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { index = Mathf.Clamp(index, 0, rList.count - 1); MotionMatchingContact cp = currentData.contactPoints[index]; float H = 20f; float space = 5f; float numberL = 50f; Rect startRect = new Rect(rect.x, rect.y + space, numberL, H); Rect sliderRect = new Rect(rect.x + startRect.width + space, rect.y + space, rect.width - 2f * (space + numberL), H); Rect endRect = new Rect(sliderRect.x + sliderRect.width + space, rect.y + space, numberL, H); Rect posRect = new Rect(rect.x, sliderRect.y + H, 0.5f * rect.width, 2 * H); Rect normalRect = new Rect(posRect.x + posRect.width, sliderRect.y + H, 0.5f * rect.width, 2 * H); cp.endTime = Mathf.Clamp(cp.endTime, cp.startTime, currentData.animationLength); float startTime = EditorGUI.FloatField(startRect, cp.startTime); float endTime = EditorGUI.FloatField(endRect, cp.endTime); EditorGUI.MinMaxSlider(sliderRect, ref startTime, ref endTime, 0f, currentData.animationLength); Vector3 position = EditorGUI.Vector3Field(posRect, new GUIContent("Position"), cp.position); string normalName = currentData.contactsType == ContactStateType.Impacts ? "Impact rotation" : "Contact rotation"; Vector4 rotation = new Vector4(cp.rotation.x, cp.rotation.y, cp.rotation.z, cp.rotation.w); rotation = EditorGUI.Vector4Field(normalRect, new GUIContent(normalName), rotation); if (rList.index == index) { cp.startTime = startTime; cp.endTime = endTime; cp.position = position; //cp.contactNormal = normal; } currentData.contactPoints[index] = cp; }; rList.elementHeightCallback = (int index) => { return(elementLines * 40f); }; rList.headerHeight = 5f; rList.drawHeaderCallback = (Rect rect) => { }; }
private void SetAsset(MotionMatchingData asset) { this.editedData = asset; }
public bool IsDataValid(MotionMatchingData data) { return(currentMMData == data); }
private void CalculateBlendTrees( PreparingDataPlayableGraph graph, string saveFolder, List <Transform> bonesMask ) { foreach (BlendTreeInfo info in creator.blendTrees) { if (!info.IsValid()) { continue; } if (info.useSpaces && info.clips.Count == 2) { for (int spaces = 1; spaces <= info.spaces; spaces++) { float currentFactor = (float)spaces / (info.spaces + 1); float[] clipsWeights = new float[info.clips.Count]; clipsWeights[0] = currentFactor; clipsWeights[1] = 1f - currentFactor; //Debug.Log(clipsWeights[0]); //Debug.Log(clipsWeights[1]); MotionMatchingData dataToSave = MotionDataCalculator.CalculateBlendTreeData( info.name + currentFactor.ToString(), creator.gameObjectTransform.gameObject, graph, info.clips.ToArray(), bonesMask, creator.bonesWeights, creator.gameObjectTransform, creator.trajectoryStepTimes, clipsWeights, creator.posesPerSecond, false, info.blendToYourself, info.findInYourself ); string path = saveFolder.Substring(Application.dataPath.Length - 6) + "/" + dataToSave.name + ".asset"; MotionMatchingData loadedAsset = (MotionMatchingData)AssetDatabase.LoadAssetAtPath(path, typeof(MotionMatchingData)); if (loadedAsset == null) { AssetDatabase.CreateAsset(dataToSave, path); //AssetDatabase.SaveAssets(); } else { loadedAsset.UpdateFromOther(dataToSave, dataToSave.name); if (loadedAsset.contactPoints != null) { if (loadedAsset.contactPoints.Count > 0) { MotionDataCalculator.CalculateContactPoints( loadedAsset, loadedAsset.contactPoints.ToArray(), graph, creator.gameObjectTransform.gameObject ); } } EditorUtility.SetDirty(loadedAsset); //AssetDatabase.SaveAssets(); } } } else { MotionMatchingData dataToSave = MotionDataCalculator.CalculateBlendTreeData( info.name, creator.gameObjectTransform.gameObject, graph, info.clips.ToArray(), bonesMask, creator.bonesWeights, creator.gameObjectTransform, creator.trajectoryStepTimes, info.clipsWeights.ToArray(), creator.posesPerSecond, false, info.blendToYourself, info.findInYourself ); string path = saveFolder.Substring(Application.dataPath.Length - 6) + "/" + dataToSave.name + ".asset"; MotionMatchingData loadedAsset = (MotionMatchingData)AssetDatabase.LoadAssetAtPath(path, typeof(MotionMatchingData)); if (loadedAsset == null) { AssetDatabase.CreateAsset(dataToSave, path); //AssetDatabase.SaveAssets(); } else { loadedAsset.UpdateFromOther(dataToSave, dataToSave.name); EditorUtility.SetDirty(loadedAsset); //AssetDatabase.SaveAssets(); } } } Debug.Log("Calculation of Blend trees completed!"); }