private void DrawRightContactsOptionsAboveScrollOptions() { GUILayout.BeginHorizontal(); if (GUILayout.Button("Set Contact Start Time", GUIResources.Button_MD()) && editedData != null) { if (contactPointsRL != null) { if (0 <= contactPointsRL.index && contactPointsRL.index < editedData.contactPoints.Count) { MotionMatchingContact cp = editedData.contactPoints[contactPointsRL.index]; cp.SetStartTime(currentAnimaionTime); editedData.contactPoints[contactPointsRL.index] = cp; } } } if (GUILayout.Button("Set Contact End Time", GUIResources.Button_MD()) && editedData != null) { if (contactPointsRL != null) { if (0 <= contactPointsRL.index && contactPointsRL.index < editedData.contactPoints.Count) { MotionMatchingContact cp = editedData.contactPoints[contactPointsRL.index]; cp.SetEndTime(currentAnimaionTime); editedData.contactPoints[contactPointsRL.index] = cp; } } } GUILayout.EndHorizontal(); }
private void DrawSelectedContactPoint() { if (editedData == null || gameObject == null) { return; } if (contactPointsRL != null) { if (0 <= contactPointsRL.index && contactPointsRL.index < editedData.contactPoints.Count) { Handles.color = Color.green; MotionMatchingContact cp = editedData.contactPoints[contactPointsRL.index]; Vector3 drawPosition = gameObject.transform.TransformPoint(cp.position); Vector3 drawDirection = gameObject.transform.TransformDirection(cp.contactNormal); cp.position = gameObject.transform.TransformPoint(cp.position); // Changing contactPoint position if (drawPositionManipulator) { Vector3 cpPosBuffor = cp.position; Vector3 cpSurNorBuffor = cp.contactNormal; cp.position = Handles.PositionHandle(cp.position, Quaternion.identity); } // Changing contactPoint surface reverse normal if (drawRotationManipuator) { Vector3 contactNormal = gameObject.transform.TransformDirection(cp.contactNormal); //Quaternion rot = Quaternion.FromToRotation(Vector3.forward, dirRSN.normalized); //rot = Handles.RotationHandle(rot, cp.position); if (cp.rotation.x == 0f && cp.rotation.y == 0f && cp.rotation.z == 0f && cp.rotation.w == 0f) { cp.rotation = Quaternion.identity; } cp.rotation = Handles.RotationHandle(cp.rotation, cp.position); contactNormal = cp.rotation * Vector3.forward; cp.contactNormal = contactNormal; cp.contactNormal = gameObject.transform.InverseTransformDirection(cp.contactNormal); } Handles.DrawWireCube(drawPosition, Vector3.one * drawCubeSize); MM_Gizmos.DrawArrowHandles(drawPosition, drawDirection, arrowLength, arrowArmLength); cp.position = gameObject.transform.InverseTransformPoint(cp.position); editedData.contactPoints[contactPointsRL.index] = cp; } } }
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(); }
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(); }
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) => { }; }